create-better-t-stack 2.46.3-canary.f7f132c8 → 2.46.4
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/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{src-FqipJoqR.js → src-El86OdG5.js} +38 -142
- package/package.json +1 -1
- package/templates/auth/better-auth/web/react/next/src/components/theme-provider.tsx.hbs +11 -0
- package/templates/deploy/alchemy/alchemy.run.ts.hbs +14 -0
- package/templates/frontend/react/next/src/components/providers.tsx.hbs +0 -8
- package/templates/frontend/react/tanstack-router/src/main.tsx.hbs +1 -8
- package/templates/frontend/react/tanstack-start/src/routes/__root.tsx.hbs +0 -47
- package/templates/frontend/react/tanstack-start/src/routes/index.tsx.hbs +2 -2
- package/templates/frontend/react/web-base/src/components/header.tsx.hbs +2 -2
- package/templates/auth/better-auth/convex/backend/convex/auth.config.ts.hbs +0 -8
- package/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs +0 -48
- package/templates/auth/better-auth/convex/backend/convex/convex.config.ts.hbs +0 -7
- package/templates/auth/better-auth/convex/backend/convex/http.ts.hbs +0 -12
- package/templates/auth/better-auth/convex/backend/convex/privateData.ts.hbs +0 -16
- package/templates/auth/better-auth/convex/web/react/next/src/app/api/auth/[...all]/route.ts.hbs +0 -3
- package/templates/auth/better-auth/convex/web/react/next/src/app/dashboard/page.tsx.hbs +0 -40
- package/templates/auth/better-auth/convex/web/react/next/src/components/sign-in-form.tsx.hbs +0 -129
- package/templates/auth/better-auth/convex/web/react/next/src/components/sign-up-form.tsx.hbs +0 -154
- package/templates/auth/better-auth/convex/web/react/next/src/components/user-menu.tsx.hbs +0 -48
- package/templates/auth/better-auth/convex/web/react/next/src/lib/auth-client.ts.hbs +0 -6
- package/templates/auth/better-auth/convex/web/react/next/src/lib/auth-server.ts.hbs +0 -6
- package/templates/auth/better-auth/convex/web/react/tanstack-router/src/components/sign-in-form.tsx.hbs +0 -133
- package/templates/auth/better-auth/convex/web/react/tanstack-router/src/components/sign-up-form.tsx.hbs +0 -158
- package/templates/auth/better-auth/convex/web/react/tanstack-router/src/components/user-menu.tsx.hbs +0 -50
- package/templates/auth/better-auth/convex/web/react/tanstack-router/src/lib/auth-client.ts.hbs +0 -10
- package/templates/auth/better-auth/convex/web/react/tanstack-router/src/routes/dashboard.tsx.hbs +0 -43
- package/templates/auth/better-auth/convex/web/react/tanstack-start/src/components/sign-in-form.tsx.hbs +0 -133
- package/templates/auth/better-auth/convex/web/react/tanstack-start/src/components/sign-up-form.tsx.hbs +0 -158
- package/templates/auth/better-auth/convex/web/react/tanstack-start/src/components/user-menu.tsx.hbs +0 -50
- package/templates/auth/better-auth/convex/web/react/tanstack-start/src/lib/auth-client.ts.hbs +0 -6
- package/templates/auth/better-auth/convex/web/react/tanstack-start/src/lib/auth-server.ts.hbs +0 -5
- package/templates/auth/better-auth/convex/web/react/tanstack-start/src/routes/api/auth/$.ts.hbs +0 -11
- package/templates/auth/better-auth/convex/web/react/tanstack-start/src/routes/dashboard.tsx.hbs +0 -43
- /package/templates/frontend/react/web-base/src/components/{loader.tsx.hbs → loader.tsx} +0 -0
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -122,12 +122,11 @@ const dependencyVersionMap = {
|
|
|
122
122
|
"@trpc/tanstack-react-query": "^11.5.0",
|
|
123
123
|
"@trpc/server": "^11.5.0",
|
|
124
124
|
"@trpc/client": "^11.5.0",
|
|
125
|
-
convex: "^1.
|
|
125
|
+
convex: "^1.25.4",
|
|
126
126
|
"@convex-dev/react-query": "^0.0.0-alpha.8",
|
|
127
127
|
"convex-svelte": "^0.0.11",
|
|
128
128
|
"convex-nuxt": "0.1.5",
|
|
129
129
|
"convex-vue": "^0.1.5",
|
|
130
|
-
"@convex-dev/better-auth": "^0.8.4",
|
|
131
130
|
"@tanstack/svelte-query": "^5.85.3",
|
|
132
131
|
"@tanstack/svelte-query-devtools": "^5.85.3",
|
|
133
132
|
"@tanstack/vue-query-devtools": "^5.83.0",
|
|
@@ -424,10 +423,11 @@ function validateAddonsAgainstFrontends(addons = [], frontends = [], auth) {
|
|
|
424
423
|
if (!isCompatible) exitWithError(`Incompatible addon/frontend combination: ${reason}`);
|
|
425
424
|
}
|
|
426
425
|
}
|
|
427
|
-
function validatePaymentsCompatibility(payments, auth,
|
|
426
|
+
function validatePaymentsCompatibility(payments, auth, backend, frontends = []) {
|
|
428
427
|
if (!payments || payments === "none") return;
|
|
429
428
|
if (payments === "polar") {
|
|
430
429
|
if (!auth || auth === "none" || auth !== "better-auth") exitWithError("Polar payments requires Better Auth. Please use '--auth better-auth' or choose a different payments provider.");
|
|
430
|
+
if (backend === "convex") exitWithError("Polar payments is not compatible with Convex backend. Please use a different backend or choose a different payments provider.");
|
|
431
431
|
const { web } = splitFrontends(frontends);
|
|
432
432
|
if (web.length === 0 && frontends.length > 0) exitWithError("Polar payments requires a web frontend or no frontend. Please select a web frontend or choose a different payments provider.");
|
|
433
433
|
}
|
|
@@ -611,39 +611,23 @@ async function getApiChoice(Api, frontend, backend) {
|
|
|
611
611
|
async function getAuthChoice(auth, hasDatabase, backend, frontend) {
|
|
612
612
|
if (auth !== void 0) return auth;
|
|
613
613
|
if (backend === "convex") {
|
|
614
|
-
const
|
|
615
|
-
"
|
|
616
|
-
"
|
|
617
|
-
"
|
|
618
|
-
].includes(f));
|
|
619
|
-
const hasClerkCompatibleFrontends = frontend?.some((f) => [
|
|
620
|
-
"react-router",
|
|
621
|
-
"tanstack-router",
|
|
622
|
-
"tanstack-start",
|
|
623
|
-
"next",
|
|
624
|
-
"native-nativewind",
|
|
625
|
-
"native-unistyles"
|
|
614
|
+
const unsupportedFrontends = frontend?.filter((f) => [
|
|
615
|
+
"nuxt",
|
|
616
|
+
"svelte",
|
|
617
|
+
"solid"
|
|
626
618
|
].includes(f));
|
|
627
|
-
|
|
628
|
-
if (supportedBetterAuthFrontends) options.push({
|
|
629
|
-
value: "better-auth",
|
|
630
|
-
label: "Better-Auth",
|
|
631
|
-
hint: "comprehensive auth framework for TypeScript"
|
|
632
|
-
});
|
|
633
|
-
if (hasClerkCompatibleFrontends) options.push({
|
|
634
|
-
value: "clerk",
|
|
635
|
-
label: "Clerk",
|
|
636
|
-
hint: "More than auth, Complete User Management"
|
|
637
|
-
});
|
|
638
|
-
options.push({
|
|
639
|
-
value: "none",
|
|
640
|
-
label: "None",
|
|
641
|
-
hint: "No auth"
|
|
642
|
-
});
|
|
619
|
+
if (unsupportedFrontends && unsupportedFrontends.length > 0) return "none";
|
|
643
620
|
const response$1 = await select({
|
|
644
621
|
message: "Select authentication provider",
|
|
645
|
-
options
|
|
646
|
-
|
|
622
|
+
options: [{
|
|
623
|
+
value: "clerk",
|
|
624
|
+
label: "Clerk",
|
|
625
|
+
hint: "More than auth, Complete User Management"
|
|
626
|
+
}, {
|
|
627
|
+
value: "none",
|
|
628
|
+
label: "None"
|
|
629
|
+
}],
|
|
630
|
+
initialValue: "clerk"
|
|
647
631
|
});
|
|
648
632
|
if (isCancel(response$1)) return exitCancelled("Operation cancelled");
|
|
649
633
|
return response$1;
|
|
@@ -1386,7 +1370,7 @@ const getLatestCLIVersion = () => {
|
|
|
1386
1370
|
*/
|
|
1387
1371
|
function isTelemetryEnabled() {
|
|
1388
1372
|
const BTS_TELEMETRY_DISABLED = process.env.BTS_TELEMETRY_DISABLED;
|
|
1389
|
-
const BTS_TELEMETRY = "
|
|
1373
|
+
const BTS_TELEMETRY = "1";
|
|
1390
1374
|
if (BTS_TELEMETRY_DISABLED !== void 0) return BTS_TELEMETRY_DISABLED !== "1";
|
|
1391
1375
|
if (BTS_TELEMETRY !== void 0) return BTS_TELEMETRY === "1";
|
|
1392
1376
|
return true;
|
|
@@ -1394,8 +1378,8 @@ function isTelemetryEnabled() {
|
|
|
1394
1378
|
|
|
1395
1379
|
//#endregion
|
|
1396
1380
|
//#region src/utils/analytics.ts
|
|
1397
|
-
const POSTHOG_API_KEY = "
|
|
1398
|
-
const POSTHOG_HOST = "
|
|
1381
|
+
const POSTHOG_API_KEY = "phc_8ZUxEwwfKMajJLvxz1daGd931dYbQrwKNficBmsdIrs";
|
|
1382
|
+
const POSTHOG_HOST = "https://us.i.posthog.com";
|
|
1399
1383
|
function generateSessionId() {
|
|
1400
1384
|
const rand = Math.random().toString(36).slice(2);
|
|
1401
1385
|
const now = Date.now().toString(36);
|
|
@@ -1749,15 +1733,7 @@ function validateConvexConstraints(config, providedFlags) {
|
|
|
1749
1733
|
if (has("api") && config.api !== "none") exitWithError("Convex backend requires '--api none'. Please remove the --api flag or set it to 'none'.");
|
|
1750
1734
|
if (has("dbSetup") && config.dbSetup !== "none") exitWithError("Convex backend requires '--db-setup none'. Please remove the --db-setup flag or set it to 'none'.");
|
|
1751
1735
|
if (has("serverDeploy") && config.serverDeploy !== "none") exitWithError("Convex backend requires '--server-deploy none'. Please remove the --server-deploy flag or set it to 'none'.");
|
|
1752
|
-
if (has("auth") && config.auth === "better-auth")
|
|
1753
|
-
const supportedFrontends = [
|
|
1754
|
-
"tanstack-router",
|
|
1755
|
-
"tanstack-start",
|
|
1756
|
-
"next"
|
|
1757
|
-
];
|
|
1758
|
-
const hasSupportedFrontend = config.frontend?.some((f) => supportedFrontends.includes(f));
|
|
1759
|
-
if (!hasSupportedFrontend) exitWithError("Better-Auth with Convex backend is only supported with TanStack Router, TanStack Start, or Next.js frontends. Please use '--auth clerk' or '--auth none'.");
|
|
1760
|
-
}
|
|
1736
|
+
if (has("auth") && config.auth === "better-auth") exitWithError("Better-Auth is not compatible with Convex backend. Please use '--auth clerk' or '--auth none'.");
|
|
1761
1737
|
}
|
|
1762
1738
|
function validateBackendNoneConstraints(config, providedFlags) {
|
|
1763
1739
|
const { backend } = config;
|
|
@@ -2004,18 +1980,18 @@ async function updateBtsConfig(projectDir, updates) {
|
|
|
2004
1980
|
//#endregion
|
|
2005
1981
|
//#region src/utils/add-package-deps.ts
|
|
2006
1982
|
const addPackageDependency = async (opts) => {
|
|
2007
|
-
const { dependencies = [], devDependencies = [],
|
|
1983
|
+
const { dependencies = [], devDependencies = [], projectDir } = opts;
|
|
2008
1984
|
const pkgJsonPath = path.join(projectDir, "package.json");
|
|
2009
1985
|
const pkgJson = await fs.readJson(pkgJsonPath);
|
|
2010
1986
|
if (!pkgJson.dependencies) pkgJson.dependencies = {};
|
|
2011
1987
|
if (!pkgJson.devDependencies) pkgJson.devDependencies = {};
|
|
2012
1988
|
for (const pkgName of dependencies) {
|
|
2013
|
-
const version =
|
|
1989
|
+
const version = dependencyVersionMap[pkgName];
|
|
2014
1990
|
if (version) pkgJson.dependencies[pkgName] = version;
|
|
2015
1991
|
else console.warn(`Warning: Dependency ${pkgName} not found in version map.`);
|
|
2016
1992
|
}
|
|
2017
1993
|
for (const pkgName of devDependencies) {
|
|
2018
|
-
const version =
|
|
1994
|
+
const version = dependencyVersionMap[pkgName];
|
|
2019
1995
|
if (version) pkgJson.devDependencies[pkgName] = version;
|
|
2020
1996
|
else console.warn(`Warning: Dev dependency ${pkgName} not found in version map.`);
|
|
2021
1997
|
}
|
|
@@ -2877,29 +2853,6 @@ async function setupAuthTemplate(projectDir, context) {
|
|
|
2877
2853
|
}
|
|
2878
2854
|
return;
|
|
2879
2855
|
}
|
|
2880
|
-
if (context.backend === "convex" && authProvider === "better-auth") {
|
|
2881
|
-
const convexBackendDestDir = path.join(projectDir, "packages/backend");
|
|
2882
|
-
const convexBetterAuthBackendSrc = path.join(PKG_ROOT, "templates/auth/better-auth/convex/backend");
|
|
2883
|
-
if (await fs.pathExists(convexBetterAuthBackendSrc)) {
|
|
2884
|
-
await fs.ensureDir(convexBackendDestDir);
|
|
2885
|
-
await processAndCopyFiles("**/*", convexBetterAuthBackendSrc, convexBackendDestDir, context);
|
|
2886
|
-
}
|
|
2887
|
-
if (webAppDirExists && hasReactWeb) {
|
|
2888
|
-
const convexBetterAuthWebBaseSrc = path.join(PKG_ROOT, "templates/auth/better-auth/convex/web/react/base");
|
|
2889
|
-
if (await fs.pathExists(convexBetterAuthWebBaseSrc)) await processAndCopyFiles("**/*", convexBetterAuthWebBaseSrc, webAppDir, context);
|
|
2890
|
-
const reactFramework = context.frontend.find((f) => [
|
|
2891
|
-
"tanstack-router",
|
|
2892
|
-
"react-router",
|
|
2893
|
-
"tanstack-start",
|
|
2894
|
-
"next"
|
|
2895
|
-
].includes(f));
|
|
2896
|
-
if (reactFramework) {
|
|
2897
|
-
const convexBetterAuthWebSrc = path.join(PKG_ROOT, `templates/auth/better-auth/convex/web/react/${reactFramework}`);
|
|
2898
|
-
if (await fs.pathExists(convexBetterAuthWebSrc)) await processAndCopyFiles("**/*", convexBetterAuthWebSrc, webAppDir, context);
|
|
2899
|
-
}
|
|
2900
|
-
}
|
|
2901
|
-
return;
|
|
2902
|
-
}
|
|
2903
2856
|
if (serverAppDirExists && context.backend !== "convex") {
|
|
2904
2857
|
const authServerBaseSrc = path.join(PKG_ROOT, `templates/auth/${authProvider}/server/base`);
|
|
2905
2858
|
if (await fs.pathExists(authServerBaseSrc)) await processAndCopyFiles("**/*", authServerBaseSrc, serverAppDir, context);
|
|
@@ -4293,35 +4246,6 @@ async function setupAuth(config) {
|
|
|
4293
4246
|
projectDir: clientDir
|
|
4294
4247
|
});
|
|
4295
4248
|
}
|
|
4296
|
-
if (auth === "better-auth") {
|
|
4297
|
-
const convexBackendDir = path.join(projectDir, "packages/backend");
|
|
4298
|
-
const convexBackendDirExists = await fs.pathExists(convexBackendDir);
|
|
4299
|
-
if (convexBackendDirExists) await addPackageDependency({
|
|
4300
|
-
dependencies: ["better-auth", "@convex-dev/better-auth"],
|
|
4301
|
-
customDependencies: { "better-auth": "1.3.8" },
|
|
4302
|
-
projectDir: convexBackendDir
|
|
4303
|
-
});
|
|
4304
|
-
if (clientDirExists) {
|
|
4305
|
-
const hasNextJs = frontend.includes("next");
|
|
4306
|
-
const hasTanStackStart = frontend.includes("tanstack-start");
|
|
4307
|
-
const hasViteReactOther = frontend.some((f) => ["tanstack-router", "react-router"].includes(f));
|
|
4308
|
-
if (hasNextJs) await addPackageDependency({
|
|
4309
|
-
dependencies: ["better-auth", "@convex-dev/better-auth"],
|
|
4310
|
-
customDependencies: { "better-auth": "1.3.8" },
|
|
4311
|
-
projectDir: clientDir
|
|
4312
|
-
});
|
|
4313
|
-
else if (hasTanStackStart) await addPackageDependency({
|
|
4314
|
-
dependencies: ["better-auth", "@convex-dev/better-auth"],
|
|
4315
|
-
customDependencies: { "better-auth": "1.3.8" },
|
|
4316
|
-
projectDir: clientDir
|
|
4317
|
-
});
|
|
4318
|
-
else if (hasViteReactOther) await addPackageDependency({
|
|
4319
|
-
dependencies: ["better-auth", "@convex-dev/better-auth"],
|
|
4320
|
-
customDependencies: { "better-auth": "1.3.8" },
|
|
4321
|
-
projectDir: clientDir
|
|
4322
|
-
});
|
|
4323
|
-
}
|
|
4324
|
-
}
|
|
4325
4249
|
const hasNativeWind = frontend.includes("native-nativewind");
|
|
4326
4250
|
const hasUnistyles = frontend.includes("native-unistyles");
|
|
4327
4251
|
if (auth === "clerk" && nativeDirExists && (hasNativeWind || hasUnistyles)) await addPackageDependency({
|
|
@@ -4383,7 +4307,7 @@ async function addEnvVariablesToFile(filePath, variables) {
|
|
|
4383
4307
|
let modified = false;
|
|
4384
4308
|
let contentToAdd = "";
|
|
4385
4309
|
const exampleVariables = [];
|
|
4386
|
-
for (const { key, value, condition
|
|
4310
|
+
for (const { key, value, condition } of variables) if (condition) {
|
|
4387
4311
|
const regex = new RegExp(`^${key}=.*$`, "m");
|
|
4388
4312
|
const valueToWrite = value ?? "";
|
|
4389
4313
|
exampleVariables.push(`${key}=`);
|
|
@@ -4394,7 +4318,6 @@ async function addEnvVariablesToFile(filePath, variables) {
|
|
|
4394
4318
|
modified = true;
|
|
4395
4319
|
}
|
|
4396
4320
|
} else {
|
|
4397
|
-
if (comment) contentToAdd += `# ${comment}\n`;
|
|
4398
4321
|
contentToAdd += `${key}=${valueToWrite}\n`;
|
|
4399
4322
|
modified = true;
|
|
4400
4323
|
}
|
|
@@ -4480,18 +4403,6 @@ async function setupEnvironmentVariables(config) {
|
|
|
4480
4403
|
});
|
|
4481
4404
|
}
|
|
4482
4405
|
}
|
|
4483
|
-
if (backend === "convex" && auth === "better-auth") {
|
|
4484
|
-
if (hasNextJs) clientVars.push({
|
|
4485
|
-
key: "NEXT_PUBLIC_CONVEX_SITE_URL",
|
|
4486
|
-
value: "https://<YOUR_CONVEX_URL>",
|
|
4487
|
-
condition: true
|
|
4488
|
-
});
|
|
4489
|
-
else if (hasReactRouter || hasTanStackRouter || hasTanStackStart) clientVars.push({
|
|
4490
|
-
key: "VITE_CONVEX_SITE_URL",
|
|
4491
|
-
value: "https://<YOUR_CONVEX_URL>",
|
|
4492
|
-
condition: true
|
|
4493
|
-
});
|
|
4494
|
-
}
|
|
4495
4406
|
await addEnvVariablesToFile(path.join(clientDir, ".env"), clientVars);
|
|
4496
4407
|
}
|
|
4497
4408
|
}
|
|
@@ -4517,34 +4428,7 @@ async function setupEnvironmentVariables(config) {
|
|
|
4517
4428
|
await addEnvVariablesToFile(path.join(nativeDir, ".env"), nativeVars);
|
|
4518
4429
|
}
|
|
4519
4430
|
}
|
|
4520
|
-
if (backend === "convex")
|
|
4521
|
-
if (auth === "better-auth") {
|
|
4522
|
-
const convexBackendDir = path.join(projectDir, "packages/backend");
|
|
4523
|
-
if (await fs.pathExists(convexBackendDir)) {
|
|
4524
|
-
const envLocalPath = path.join(convexBackendDir, ".env.local");
|
|
4525
|
-
if (!await fs.pathExists(envLocalPath) || !(await fs.readFile(envLocalPath, "utf8")).includes("npx convex env set")) {
|
|
4526
|
-
const convexCommands = `# Set Convex environment variables
|
|
4527
|
-
npx convex env set BETTER_AUTH_SECRET=$(openssl rand -base64 32)
|
|
4528
|
-
npx convex env set SITE_URL http://localhost:3001
|
|
4529
|
-
|
|
4530
|
-
`;
|
|
4531
|
-
await fs.appendFile(envLocalPath, convexCommands);
|
|
4532
|
-
}
|
|
4533
|
-
const convexBackendVars = [{
|
|
4534
|
-
key: hasNextJs ? "NEXT_PUBLIC_CONVEX_SITE_URL" : "VITE_CONVEX_SITE_URL",
|
|
4535
|
-
value: "",
|
|
4536
|
-
condition: true,
|
|
4537
|
-
comment: "Same as CONVEX_URL but ends in .site"
|
|
4538
|
-
}, {
|
|
4539
|
-
key: "SITE_URL",
|
|
4540
|
-
value: "http://localhost:3001",
|
|
4541
|
-
condition: true
|
|
4542
|
-
}];
|
|
4543
|
-
await addEnvVariablesToFile(envLocalPath, convexBackendVars);
|
|
4544
|
-
}
|
|
4545
|
-
}
|
|
4546
|
-
return;
|
|
4547
|
-
}
|
|
4431
|
+
if (backend === "convex") return;
|
|
4548
4432
|
const serverDir = path.join(projectDir, "apps/server");
|
|
4549
4433
|
if (!await fs.pathExists(serverDir)) return;
|
|
4550
4434
|
const envPath = path.join(serverDir, ".env");
|
|
@@ -5829,6 +5713,17 @@ async function setupNodeRuntime(serverDir, backend) {
|
|
|
5829
5713
|
});
|
|
5830
5714
|
}
|
|
5831
5715
|
|
|
5716
|
+
//#endregion
|
|
5717
|
+
//#region src/helpers/core/convex-codegen.ts
|
|
5718
|
+
async function runConvexCodegen(projectDir, packageManager) {
|
|
5719
|
+
const backendDir = path.join(projectDir, "packages/backend");
|
|
5720
|
+
const cmd = getPackageExecutionCommand(packageManager, "convex codegen");
|
|
5721
|
+
await execa(cmd, {
|
|
5722
|
+
cwd: backendDir,
|
|
5723
|
+
shell: true
|
|
5724
|
+
});
|
|
5725
|
+
}
|
|
5726
|
+
|
|
5832
5727
|
//#endregion
|
|
5833
5728
|
//#region src/helpers/core/create-readme.ts
|
|
5834
5729
|
async function createReadme(projectDir, options) {
|
|
@@ -6620,6 +6515,7 @@ async function createProject(options, cliInput) {
|
|
|
6620
6515
|
await setupServerDeploy(options);
|
|
6621
6516
|
await createReadme(projectDir, options);
|
|
6622
6517
|
await writeBtsConfig(options);
|
|
6518
|
+
if (isConvex) await runConvexCodegen(projectDir, options.packageManager);
|
|
6623
6519
|
log.success("Project template successfully scaffolded!");
|
|
6624
6520
|
if (options.install) await installDependencies({
|
|
6625
6521
|
projectDir,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-better-t-stack",
|
|
3
|
-
"version": "2.46.
|
|
3
|
+
"version": "2.46.4",
|
|
4
4
|
"description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { ThemeProvider as NextThemesProvider } from "next-themes"
|
|
5
|
+
|
|
6
|
+
export function ThemeProvider({
|
|
7
|
+
children,
|
|
8
|
+
...props
|
|
9
|
+
}: React.ComponentProps<typeof NextThemesProvider>) {
|
|
10
|
+
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
|
|
11
|
+
}
|
|
@@ -172,12 +172,26 @@ export const server = await Worker("server", {
|
|
|
172
172
|
BETTER_AUTH_SECRET: alchemy.secret(process.env.BETTER_AUTH_SECRET),
|
|
173
173
|
BETTER_AUTH_URL: process.env.BETTER_AUTH_URL || "",
|
|
174
174
|
{{/if}}
|
|
175
|
+
{{#if (eq auth "clerk")}}
|
|
176
|
+
CLERK_SECRET_KEY: alchemy.secret(process.env.CLERK_SECRET_KEY),
|
|
177
|
+
{{/if}}
|
|
175
178
|
{{#if (includes examples "ai")}}
|
|
176
179
|
GOOGLE_GENERATIVE_AI_API_KEY: alchemy.secret(process.env.GOOGLE_GENERATIVE_AI_API_KEY),
|
|
177
180
|
{{/if}}
|
|
181
|
+
{{#if (eq payments "polar")}}
|
|
182
|
+
POLAR_ACCESS_TOKEN: alchemy.secret(process.env.POLAR_ACCESS_TOKEN),
|
|
183
|
+
POLAR_SUCCESS_URL: process.env.POLAR_SUCCESS_URL || "",
|
|
184
|
+
{{/if}}
|
|
178
185
|
{{#if (eq dbSetup "turso")}}
|
|
179
186
|
DATABASE_AUTH_TOKEN: alchemy.secret(process.env.DATABASE_AUTH_TOKEN),
|
|
180
187
|
{{/if}}
|
|
188
|
+
{{#if (eq database "mysql")}}
|
|
189
|
+
{{#if (eq orm "drizzle")}}
|
|
190
|
+
DATABASE_HOST: process.env.DATABASE_HOST || "",
|
|
191
|
+
DATABASE_USERNAME: process.env.DATABASE_USERNAME || "",
|
|
192
|
+
DATABASE_PASSWORD: process.env.DATABASE_PASSWORD || "",
|
|
193
|
+
{{/if}}
|
|
194
|
+
{{/if}}
|
|
181
195
|
},
|
|
182
196
|
dev: {
|
|
183
197
|
port: 3000,
|
|
@@ -5,10 +5,6 @@
|
|
|
5
5
|
import { useAuth } from "@clerk/nextjs";
|
|
6
6
|
import { ConvexReactClient } from "convex/react";
|
|
7
7
|
import { ConvexProviderWithClerk } from "convex/react-clerk";
|
|
8
|
-
{{else if (eq auth "better-auth")}}
|
|
9
|
-
import { ConvexProvider, ConvexReactClient } from "convex/react";
|
|
10
|
-
import { ConvexBetterAuthProvider } from "@convex-dev/better-auth/react";
|
|
11
|
-
import { authClient } from "@/lib/auth-client";
|
|
12
8
|
{{else}}
|
|
13
9
|
import { ConvexProvider, ConvexReactClient } from "convex/react";
|
|
14
10
|
{{/if}}
|
|
@@ -48,10 +44,6 @@ export default function Providers({
|
|
|
48
44
|
<ConvexProviderWithClerk client={convex} useAuth={useAuth}>
|
|
49
45
|
{children}
|
|
50
46
|
</ConvexProviderWithClerk>
|
|
51
|
-
{{else if (eq auth "better-auth")}}
|
|
52
|
-
<ConvexBetterAuthProvider client={convex} authClient={authClient}>
|
|
53
|
-
{children}
|
|
54
|
-
</ConvexBetterAuthProvider>
|
|
55
47
|
{{else}}
|
|
56
48
|
<ConvexProvider client={convex}>{children}</ConvexProvider>
|
|
57
49
|
{{/if}}
|
|
@@ -16,15 +16,10 @@ import { routeTree } from "./routeTree.gen";
|
|
|
16
16
|
{{#if (eq auth "clerk")}}
|
|
17
17
|
import { ClerkProvider, useAuth } from "@clerk/clerk-react";
|
|
18
18
|
import { ConvexProviderWithClerk } from "convex/react-clerk";
|
|
19
|
-
{{else if (eq auth "better-auth")}}
|
|
20
|
-
import { ConvexBetterAuthProvider } from "@convex-dev/better-auth/react";
|
|
21
|
-
import { authClient } from "@/lib/auth-client";
|
|
22
19
|
{{else}}
|
|
23
20
|
import { ConvexProvider } from "convex/react";
|
|
24
21
|
{{/if}}
|
|
25
|
-
const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL as string
|
|
26
|
-
expectAuth: true,
|
|
27
|
-
}{{/if}});
|
|
22
|
+
const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL as string);
|
|
28
23
|
{{/if}}
|
|
29
24
|
|
|
30
25
|
const router = createRouter({
|
|
@@ -62,8 +57,6 @@ const router = createRouter({
|
|
|
62
57
|
</ConvexProviderWithClerk>
|
|
63
58
|
</ClerkProvider>
|
|
64
59
|
);
|
|
65
|
-
{{else if (eq auth "better-auth")}}
|
|
66
|
-
return <ConvexBetterAuthProvider client={convex} authClient={authClient}>{children}</ConvexBetterAuthProvider>;
|
|
67
60
|
{{else}}
|
|
68
61
|
return <ConvexProvider client={convex}>{children}</ConvexProvider>;
|
|
69
62
|
{{/if}}
|
|
@@ -8,9 +8,7 @@ import {
|
|
|
8
8
|
Scripts,
|
|
9
9
|
createRootRouteWithContext,
|
|
10
10
|
useRouterState,
|
|
11
|
-
{{#if (and (eq backend "convex") (or (eq auth "clerk") (eq auth "better-auth")))}}
|
|
12
11
|
useRouteContext,
|
|
13
|
-
{{/if}}
|
|
14
12
|
} from "@tanstack/react-router";
|
|
15
13
|
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
|
|
16
14
|
import Header from "../components/header";
|
|
@@ -38,23 +36,6 @@ const fetchClerkAuth = createServerFn({ method: "GET" }).handler(async () => {
|
|
|
38
36
|
const token = await auth.getToken({ template: "convex" });
|
|
39
37
|
return { userId: auth.userId, token };
|
|
40
38
|
});
|
|
41
|
-
{{else if (and (eq backend "convex") (eq auth "better-auth"))}}
|
|
42
|
-
import { createServerFn } from "@tanstack/react-start";
|
|
43
|
-
import { getWebRequest, getCookie } from "@tanstack/react-start/server";
|
|
44
|
-
import { ConvexBetterAuthProvider } from "@convex-dev/better-auth/react";
|
|
45
|
-
import { fetchSession, getCookieName } from "@convex-dev/better-auth/react-start";
|
|
46
|
-
import { authClient } from "@/lib/auth-client";
|
|
47
|
-
import { createAuth } from "@{{projectName}}/backend/convex/auth";
|
|
48
|
-
|
|
49
|
-
const fetchAuth = createServerFn({ method: "GET" }).handler(async () => {
|
|
50
|
-
const { session } = await fetchSession(getWebRequest());
|
|
51
|
-
const sessionCookieName = getCookieName(createAuth);
|
|
52
|
-
const token = getCookie(sessionCookieName);
|
|
53
|
-
return {
|
|
54
|
-
userId: session?.user.id,
|
|
55
|
-
token,
|
|
56
|
-
};
|
|
57
|
-
});
|
|
58
39
|
{{/if}}
|
|
59
40
|
|
|
60
41
|
{{#if (eq backend "convex")}}
|
|
@@ -114,14 +95,6 @@ export const Route = createRootRouteWithContext<RouterAppContext>()({
|
|
|
114
95
|
}
|
|
115
96
|
return { userId, token };
|
|
116
97
|
},
|
|
117
|
-
{{else if (and (eq backend "convex") (eq auth "better-auth"))}}
|
|
118
|
-
beforeLoad: async (ctx) => {
|
|
119
|
-
const { userId, token } = await fetchAuth();
|
|
120
|
-
if (token) {
|
|
121
|
-
ctx.context.convexQueryClient.serverHttpClient?.setAuth(token);
|
|
122
|
-
}
|
|
123
|
-
return { userId, token };
|
|
124
|
-
},
|
|
125
98
|
{{/if}}
|
|
126
99
|
});
|
|
127
100
|
|
|
@@ -149,26 +122,6 @@ function RootDocument() {
|
|
|
149
122
|
</ConvexProviderWithClerk>
|
|
150
123
|
</ClerkProvider>
|
|
151
124
|
);
|
|
152
|
-
{{else if (and (eq backend "convex") (eq auth "better-auth"))}}
|
|
153
|
-
const context = useRouteContext({ from: Route.id });
|
|
154
|
-
return (
|
|
155
|
-
<ConvexBetterAuthProvider client={context.convexClient} authClient={authClient}>
|
|
156
|
-
<html lang="en" className="dark">
|
|
157
|
-
<head>
|
|
158
|
-
<HeadContent />
|
|
159
|
-
</head>
|
|
160
|
-
<body>
|
|
161
|
-
<div className="grid h-svh grid-rows-[auto_1fr]">
|
|
162
|
-
<Header />
|
|
163
|
-
{isFetching ? <Loader /> : <Outlet />}
|
|
164
|
-
</div>
|
|
165
|
-
<Toaster richColors />
|
|
166
|
-
<TanStackRouterDevtools position="bottom-left" />
|
|
167
|
-
<Scripts />
|
|
168
|
-
</body>
|
|
169
|
-
</html>
|
|
170
|
-
</ConvexBetterAuthProvider>
|
|
171
|
-
);
|
|
172
125
|
{{else}}
|
|
173
126
|
return (
|
|
174
127
|
<html lang="en" className="dark">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createFileRoute } from "@tanstack/react-router";
|
|
2
2
|
{{#if (eq backend "convex")}}
|
|
3
3
|
import { convexQuery } from "@convex-dev/react-query";
|
|
4
|
-
import {
|
|
4
|
+
import { useSuspenseQuery } from "@tanstack/react-query";
|
|
5
5
|
import { api } from "@{{projectName}}/backend/convex/_generated/api";
|
|
6
6
|
{{else if (or (eq api "trpc") (eq api "orpc"))}}
|
|
7
7
|
import { useQuery } from "@tanstack/react-query";
|
|
@@ -35,7 +35,7 @@ const TITLE_TEXT = `
|
|
|
35
35
|
|
|
36
36
|
function HomeComponent() {
|
|
37
37
|
{{#if (eq backend "convex")}}
|
|
38
|
-
const healthCheck =
|
|
38
|
+
const healthCheck = useSuspenseQuery(convexQuery(api.healthCheck.get, {}));
|
|
39
39
|
{{else if (eq api "trpc")}}
|
|
40
40
|
const trpc = useTRPC();
|
|
41
41
|
const healthCheck = useQuery(trpc.healthCheck.queryOptions());
|
|
@@ -9,7 +9,7 @@ import { Link } from "@tanstack/react-router";
|
|
|
9
9
|
{{#unless (includes frontend "tanstack-start")}}
|
|
10
10
|
import { ModeToggle } from "./mode-toggle";
|
|
11
11
|
{{/unless}}
|
|
12
|
-
{{#if (
|
|
12
|
+
{{#if (eq auth "better-auth")}}
|
|
13
13
|
import UserMenu from "./user-menu";
|
|
14
14
|
{{/if}}
|
|
15
15
|
|
|
@@ -67,7 +67,7 @@ export default function Header() {
|
|
|
67
67
|
{{#unless (includes frontend "tanstack-start")}}
|
|
68
68
|
<ModeToggle />
|
|
69
69
|
{{/unless}}
|
|
70
|
-
{{#if (
|
|
70
|
+
{{#if (eq auth "better-auth")}}
|
|
71
71
|
<UserMenu />
|
|
72
72
|
{{/if}}
|
|
73
73
|
</div>
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { createClient, type GenericCtx } from "@convex-dev/better-auth";
|
|
2
|
-
{{#if (or (includes frontend "tanstack-start") (includes frontend "next"))}}
|
|
3
|
-
import { convex } from "@convex-dev/better-auth/plugins";
|
|
4
|
-
{{else}}
|
|
5
|
-
import { convex, crossDomain } from "@convex-dev/better-auth/plugins";
|
|
6
|
-
{{/if}}
|
|
7
|
-
import { components } from "./_generated/api";
|
|
8
|
-
import { DataModel } from "./_generated/dataModel";
|
|
9
|
-
import { query } from "./_generated/server";
|
|
10
|
-
import { betterAuth } from "better-auth";
|
|
11
|
-
|
|
12
|
-
const siteUrl = process.env.SITE_URL!;
|
|
13
|
-
|
|
14
|
-
export const authComponent = createClient<DataModel>(components.betterAuth);
|
|
15
|
-
|
|
16
|
-
export const createAuth = (
|
|
17
|
-
ctx: GenericCtx<DataModel>,
|
|
18
|
-
{ optionsOnly } = { optionsOnly: false },
|
|
19
|
-
) => {
|
|
20
|
-
return betterAuth({
|
|
21
|
-
logger: {
|
|
22
|
-
disabled: optionsOnly,
|
|
23
|
-
},
|
|
24
|
-
{{#if (or (includes frontend "tanstack-start") (includes frontend "next"))}}
|
|
25
|
-
baseUrl: siteUrl,
|
|
26
|
-
{{else}}
|
|
27
|
-
trustedOrigins: [siteUrl],
|
|
28
|
-
{{/if}}
|
|
29
|
-
database: authComponent.adapter(ctx),
|
|
30
|
-
emailAndPassword: {
|
|
31
|
-
enabled: true,
|
|
32
|
-
requireEmailVerification: false,
|
|
33
|
-
},
|
|
34
|
-
plugins: [
|
|
35
|
-
{{#unless (or (includes frontend "tanstack-start") (includes frontend "next"))}}
|
|
36
|
-
crossDomain({ siteUrl }),
|
|
37
|
-
{{/unless}}
|
|
38
|
-
convex(),
|
|
39
|
-
],
|
|
40
|
-
});
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export const getCurrentUser = query({
|
|
44
|
-
args: {},
|
|
45
|
-
handler: async (ctx) => {
|
|
46
|
-
return authComponent.getAuthUser(ctx);
|
|
47
|
-
},
|
|
48
|
-
});
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { httpRouter } from "convex/server";
|
|
2
|
-
import { authComponent, createAuth } from "./auth";
|
|
3
|
-
|
|
4
|
-
const http = httpRouter();
|
|
5
|
-
|
|
6
|
-
{{#if (or (includes frontend "tanstack-start") (includes frontend "next"))}}
|
|
7
|
-
authComponent.registerRoutes(http, createAuth);
|
|
8
|
-
{{else}}
|
|
9
|
-
authComponent.registerRoutes(http, createAuth, { cors: true });
|
|
10
|
-
{{/if}}
|
|
11
|
-
|
|
12
|
-
export default http;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { query } from "./_generated/server";
|
|
2
|
-
|
|
3
|
-
export const get = query({
|
|
4
|
-
args: {},
|
|
5
|
-
handler: async (ctx) => {
|
|
6
|
-
const identity = await ctx.auth.getUserIdentity();
|
|
7
|
-
if (identity === null) {
|
|
8
|
-
return {
|
|
9
|
-
message: "Not authenticated",
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
return {
|
|
13
|
-
message: "This is private",
|
|
14
|
-
};
|
|
15
|
-
},
|
|
16
|
-
});
|