create-better-t-stack 3.11.0 → 3.11.1
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.mjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{src-XVvJUQ_h.mjs → src-Dc2OdxbP.mjs} +24 -22
- package/package.json +2 -2
- package/templates/addons/turborepo/turbo.json.hbs +5 -0
- package/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs +3 -5
- package/templates/auth/better-auth/convex/backend/convex/privateData.ts.hbs +13 -12
- package/templates/auth/better-auth/convex/web/react/next/src/lib/auth-client.ts.hbs +2 -2
- package/templates/auth/better-auth/convex/web/react/next/src/lib/auth-server.ts.hbs +1 -0
- package/templates/deploy/alchemy/alchemy.run.ts.hbs +2 -2
- package/templates/frontend/react/tanstack-start/src/router.tsx.hbs +17 -29
- package/templates/frontend/react/tanstack-start/src/routes/__root.tsx.hbs +2 -4
package/dist/cli.mjs
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as router, i as init, n as createBtsCli, o as sponsors, r as docs, t as builder } from "./src-
|
|
2
|
+
import { a as router, i as init, n as createBtsCli, o as sponsors, r as docs, t as builder } from "./src-Dc2OdxbP.mjs";
|
|
3
3
|
|
|
4
4
|
export { builder, createBtsCli, docs, init, router, sponsors };
|
|
@@ -64,8 +64,8 @@ function getDefaultConfig() {
|
|
|
64
64
|
const DEFAULT_CONFIG = getDefaultConfig();
|
|
65
65
|
const dependencyVersionMap = {
|
|
66
66
|
typescript: "^5",
|
|
67
|
-
"better-auth": "^1.4.
|
|
68
|
-
"@better-auth/expo": "^1.4.
|
|
67
|
+
"better-auth": "^1.4.9",
|
|
68
|
+
"@better-auth/expo": "^1.4.9",
|
|
69
69
|
"@clerk/nextjs": "^6.31.5",
|
|
70
70
|
"@clerk/clerk-react": "^5.45.0",
|
|
71
71
|
"@clerk/tanstack-react-start": "^0.26.3",
|
|
@@ -138,13 +138,14 @@ const dependencyVersionMap = {
|
|
|
138
138
|
"convex-svelte": "^0.0.12",
|
|
139
139
|
"convex-nuxt": "0.1.5",
|
|
140
140
|
"convex-vue": "^0.1.5",
|
|
141
|
-
"@convex-dev/better-auth": "^0.10.
|
|
141
|
+
"@convex-dev/better-auth": "^0.10.9",
|
|
142
142
|
"@tanstack/svelte-query": "^5.85.3",
|
|
143
143
|
"@tanstack/svelte-query-devtools": "^5.85.3",
|
|
144
144
|
"@tanstack/vue-query-devtools": "^5.90.2",
|
|
145
145
|
"@tanstack/vue-query": "^5.90.2",
|
|
146
146
|
"@tanstack/react-query-devtools": "^5.91.1",
|
|
147
147
|
"@tanstack/react-query": "^5.90.12",
|
|
148
|
+
"@tanstack/react-router-ssr-query": "^1.142.7",
|
|
148
149
|
"@tanstack/solid-query": "^5.87.4",
|
|
149
150
|
"@tanstack/solid-query-devtools": "^5.87.4",
|
|
150
151
|
"@tanstack/solid-router-devtools": "^1.131.44",
|
|
@@ -4171,7 +4172,10 @@ function getConvexDependencies(frontend) {
|
|
|
4171
4172
|
web: { dependencies: ["convex"] },
|
|
4172
4173
|
native: { dependencies: ["convex"] }
|
|
4173
4174
|
};
|
|
4174
|
-
if (frontend.includes("tanstack-start"))
|
|
4175
|
+
if (frontend.includes("tanstack-start")) {
|
|
4176
|
+
deps.web.dependencies.push("@convex-dev/react-query");
|
|
4177
|
+
deps.web.dependencies.push("@tanstack/react-router-ssr-query");
|
|
4178
|
+
}
|
|
4175
4179
|
if (frontend.includes("svelte")) deps.web.dependencies.push("convex-svelte");
|
|
4176
4180
|
if (frontend.includes("nuxt")) deps.web.dependencies.push("convex-nuxt", "convex-vue");
|
|
4177
4181
|
return deps;
|
|
@@ -4367,12 +4371,12 @@ async function setupAuth(config) {
|
|
|
4367
4371
|
if (convexBackendDirExists) {
|
|
4368
4372
|
await addPackageDependency({
|
|
4369
4373
|
dependencies: ["better-auth", "@convex-dev/better-auth"],
|
|
4370
|
-
customDependencies: { "better-auth": "1.4.
|
|
4374
|
+
customDependencies: { "better-auth": "1.4.9" },
|
|
4371
4375
|
projectDir: convexBackendDir
|
|
4372
4376
|
});
|
|
4373
4377
|
if (hasNativeForBA) await addPackageDependency({
|
|
4374
4378
|
dependencies: ["@better-auth/expo"],
|
|
4375
|
-
customDependencies: { "@better-auth/expo": "1.4.
|
|
4379
|
+
customDependencies: { "@better-auth/expo": "1.4.9" },
|
|
4376
4380
|
projectDir: convexBackendDir
|
|
4377
4381
|
});
|
|
4378
4382
|
}
|
|
@@ -4382,17 +4386,17 @@ async function setupAuth(config) {
|
|
|
4382
4386
|
const hasViteReactOther = frontend.some((f) => ["tanstack-router", "react-router"].includes(f));
|
|
4383
4387
|
if (hasNextJs) await addPackageDependency({
|
|
4384
4388
|
dependencies: ["better-auth", "@convex-dev/better-auth"],
|
|
4385
|
-
customDependencies: { "better-auth": "1.4.
|
|
4389
|
+
customDependencies: { "better-auth": "1.4.9" },
|
|
4386
4390
|
projectDir: clientDir
|
|
4387
4391
|
});
|
|
4388
4392
|
else if (hasTanStackStart) await addPackageDependency({
|
|
4389
4393
|
dependencies: ["better-auth", "@convex-dev/better-auth"],
|
|
4390
|
-
customDependencies: { "better-auth": "1.4.
|
|
4394
|
+
customDependencies: { "better-auth": "1.4.9" },
|
|
4391
4395
|
projectDir: clientDir
|
|
4392
4396
|
});
|
|
4393
4397
|
else if (hasViteReactOther) await addPackageDependency({
|
|
4394
4398
|
dependencies: ["better-auth", "@convex-dev/better-auth"],
|
|
4395
|
-
customDependencies: { "better-auth": "1.4.
|
|
4399
|
+
customDependencies: { "better-auth": "1.4.9" },
|
|
4396
4400
|
projectDir: clientDir
|
|
4397
4401
|
});
|
|
4398
4402
|
}
|
|
@@ -4406,8 +4410,8 @@ async function setupAuth(config) {
|
|
|
4406
4410
|
"@convex-dev/better-auth"
|
|
4407
4411
|
],
|
|
4408
4412
|
customDependencies: {
|
|
4409
|
-
"better-auth": "1.4.
|
|
4410
|
-
"@better-auth/expo": "1.4.
|
|
4413
|
+
"better-auth": "1.4.9",
|
|
4414
|
+
"@better-auth/expo": "1.4.9"
|
|
4411
4415
|
},
|
|
4412
4416
|
projectDir: nativeDir
|
|
4413
4417
|
});
|
|
@@ -5944,7 +5948,7 @@ ${generateProjectStructure(projectName, frontend, backend, addons, isConvex, api
|
|
|
5944
5948
|
|
|
5945
5949
|
## Available Scripts
|
|
5946
5950
|
|
|
5947
|
-
${generateScriptsList(packageManagerRunCmd, database, orm, auth, hasNative, addons, backend)}
|
|
5951
|
+
${generateScriptsList(packageManagerRunCmd, database, orm, auth, hasNative, addons, backend, options.dbSetup)}
|
|
5948
5952
|
`;
|
|
5949
5953
|
}
|
|
5950
5954
|
function generateStackDescription(frontend, backend, api, isConvex) {
|
|
@@ -6099,15 +6103,13 @@ function generateDatabaseSetup(database, _auth, packageManagerRunCmd, orm, dbSet
|
|
|
6099
6103
|
if (database === "none") return "";
|
|
6100
6104
|
const isBackendSelf = backend === "self";
|
|
6101
6105
|
const envPath = isBackendSelf ? "apps/web/.env" : "apps/server/.env";
|
|
6102
|
-
const dbLocalPath = "packages/db";
|
|
6103
6106
|
let setup = "## Database Setup\n\n";
|
|
6104
6107
|
if (database === "sqlite") setup += `This project uses SQLite${orm === "drizzle" ? " with Drizzle ORM" : orm === "prisma" ? " with Prisma" : ` with ${orm}`}.
|
|
6105
6108
|
|
|
6106
|
-
1. Start the local SQLite database:
|
|
6109
|
+
1. Start the local SQLite database (optional):
|
|
6107
6110
|
${dbSetup === "d1" ? "D1 local development and migrations are handled automatically by Alchemy during dev and deploy." : `\`\`\`bash
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
`}
|
|
6111
|
+
${packageManagerRunCmd} db:local
|
|
6112
|
+
\`\`\``}
|
|
6111
6113
|
|
|
6112
6114
|
2. Update your \`.env\` file in the \`${isBackendSelf ? "apps/web" : "apps/server"}\` directory with the appropriate connection details if needed.
|
|
6113
6115
|
`;
|
|
@@ -6140,7 +6142,7 @@ ${packageManagerRunCmd} db:push
|
|
|
6140
6142
|
`;
|
|
6141
6143
|
return setup;
|
|
6142
6144
|
}
|
|
6143
|
-
function generateScriptsList(packageManagerRunCmd, database, orm, _auth, hasNative, addons, backend) {
|
|
6145
|
+
function generateScriptsList(packageManagerRunCmd, database, orm, _auth, hasNative, addons, backend, dbSetup) {
|
|
6144
6146
|
const isConvex = backend === "convex";
|
|
6145
6147
|
const isBackendNone = backend === "none";
|
|
6146
6148
|
const isBackendSelf = backend === "self";
|
|
@@ -6160,8 +6162,8 @@ function generateScriptsList(packageManagerRunCmd, database, orm, _auth, hasNati
|
|
|
6160
6162
|
scripts += `
|
|
6161
6163
|
- \`${packageManagerRunCmd} db:push\`: Push schema changes to database
|
|
6162
6164
|
- \`${packageManagerRunCmd} db:studio\`: Open database studio UI`;
|
|
6163
|
-
if (database === "sqlite" &&
|
|
6164
|
-
-
|
|
6165
|
+
if (database === "sqlite" && dbSetup !== "d1") scripts += `
|
|
6166
|
+
- \`${packageManagerRunCmd} db:local\`: Start the local SQLite database`;
|
|
6165
6167
|
}
|
|
6166
6168
|
if (addons.includes("biome")) scripts += `
|
|
6167
6169
|
- \`${packageManagerRunCmd} check\`: Run Biome formatting and linting`;
|
|
@@ -6348,7 +6350,7 @@ async function displayPostInstallInstructions(config) {
|
|
|
6348
6350
|
let output = `${pc.bold("Next steps")}\n${pc.cyan("1.")} ${cdCmd}\n`;
|
|
6349
6351
|
let stepCounter = 2;
|
|
6350
6352
|
if (!depsInstalled) output += `${pc.cyan(`${stepCounter++}.`)} ${packageManager} install\n`;
|
|
6351
|
-
if (database === "sqlite" && dbSetup
|
|
6353
|
+
if (database === "sqlite" && dbSetup !== "d1") output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} db:local\n${pc.dim(" (optional - starts local SQLite database)")}\n`;
|
|
6352
6354
|
if (isConvex) {
|
|
6353
6355
|
output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev:setup\n${pc.dim(" (this will guide you through Convex project setup)")}\n`;
|
|
6354
6356
|
output += `${pc.cyan(`${stepCounter++}.`)} Copy environment variables from\n${pc.white(" packages/backend/.env.local")} to ${pc.white("apps/*/.env")}\n`;
|
|
@@ -6635,7 +6637,7 @@ async function updateRootPackageJson(projectDir, options) {
|
|
|
6635
6637
|
if (!isD1Alchemy) scripts["db:migrate"] = pmConfig.filter(dbPackageName, "db:migrate");
|
|
6636
6638
|
}
|
|
6637
6639
|
}
|
|
6638
|
-
if (database === "sqlite" && dbSetup !== "d1"
|
|
6640
|
+
if (database === "sqlite" && dbSetup !== "d1") scripts["db:local"] = pmConfig.filter(dbPackageName, "db:local");
|
|
6639
6641
|
if (dbSetup === "docker") {
|
|
6640
6642
|
scripts["db:start"] = pmConfig.filter(dbPackageName, "db:start");
|
|
6641
6643
|
scripts["db:watch"] = pmConfig.filter(dbPackageName, "db:watch");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-better-t-stack",
|
|
3
|
-
"version": "3.11.
|
|
3
|
+
"version": "3.11.1",
|
|
4
4
|
"description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"better-auth",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"prepublishOnly": "npm run build"
|
|
68
68
|
},
|
|
69
69
|
"dependencies": {
|
|
70
|
-
"@better-t-stack/types": "^3.11.
|
|
70
|
+
"@better-t-stack/types": "^3.11.1",
|
|
71
71
|
"@clack/prompts": "^1.0.0-alpha.8",
|
|
72
72
|
"@orpc/server": "^1.13.0",
|
|
73
73
|
"consola": "^3.4.2",
|
|
@@ -8,10 +8,9 @@ import { convex, crossDomain } from "@convex-dev/better-auth/plugins";
|
|
|
8
8
|
import { convex } from "@convex-dev/better-auth/plugins";
|
|
9
9
|
{{/if}}
|
|
10
10
|
import { components } from "./_generated/api";
|
|
11
|
-
import { DataModel } from "./_generated/dataModel";
|
|
11
|
+
import type { DataModel } from "./_generated/dataModel";
|
|
12
12
|
import { query } from "./_generated/server";
|
|
13
13
|
import { betterAuth } from "better-auth";
|
|
14
|
-
import { v } from "convex/values";
|
|
15
14
|
import authConfig from "./auth.config";
|
|
16
15
|
|
|
17
16
|
{{#if (or (includes frontend "tanstack-start") (includes frontend "next"))}}
|
|
@@ -63,8 +62,7 @@ export { createAuth };
|
|
|
63
62
|
|
|
64
63
|
export const getCurrentUser = query({
|
|
65
64
|
args: {},
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return authComponent.getAuthUser(ctx);
|
|
65
|
+
handler: async (ctx) => {
|
|
66
|
+
return await authComponent.safeGetAuthUser(ctx);
|
|
69
67
|
},
|
|
70
68
|
});
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { query } from "./_generated/server";
|
|
2
|
+
import { authComponent } from "./auth";
|
|
2
3
|
|
|
3
4
|
export const get = query({
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
5
|
+
args: {},
|
|
6
|
+
handler: async (ctx) => {
|
|
7
|
+
const authUser = await authComponent.safeGetAuthUser(ctx);
|
|
8
|
+
if (!authUser) {
|
|
9
|
+
return {
|
|
10
|
+
message: "Not authenticated",
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
message: "This is private",
|
|
15
|
+
};
|
|
16
|
+
},
|
|
16
17
|
});
|
|
@@ -72,7 +72,7 @@ export const web = await Nextjs("web", {
|
|
|
72
72
|
{{#if (eq auth "clerk")}}
|
|
73
73
|
CLERK_SECRET_KEY: alchemy.secret.env.CLERK_SECRET_KEY,
|
|
74
74
|
{{/if}}
|
|
75
|
-
{{#if (includes examples "ai")}}
|
|
75
|
+
{{#if (and (includes examples "ai") (ne backend "convex"))}}
|
|
76
76
|
GOOGLE_GENERATIVE_AI_API_KEY: alchemy.secret.env.GOOGLE_GENERATIVE_AI_API_KEY,
|
|
77
77
|
{{/if}}
|
|
78
78
|
{{#if (eq payments "polar")}}
|
|
@@ -146,7 +146,7 @@ export const web = await TanStackStart("web", {
|
|
|
146
146
|
{{#if (eq auth "clerk")}}
|
|
147
147
|
CLERK_SECRET_KEY: alchemy.secret.env.CLERK_SECRET_KEY,
|
|
148
148
|
{{/if}}
|
|
149
|
-
{{#if (includes examples "ai")}}
|
|
149
|
+
{{#if (and (includes examples "ai") (ne backend "convex"))}}
|
|
150
150
|
GOOGLE_GENERATIVE_AI_API_KEY: alchemy.secret.env.GOOGLE_GENERATIVE_AI_API_KEY,
|
|
151
151
|
{{/if}}
|
|
152
152
|
{{#if (eq payments "polar")}}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
{{#if (eq backend "convex")}}
|
|
2
2
|
import { createRouter as createTanStackRouter } from "@tanstack/react-router";
|
|
3
3
|
import { QueryClient } from "@tanstack/react-query";
|
|
4
|
-
import {
|
|
4
|
+
import { setupRouterSsrQueryIntegration } from "@tanstack/react-router-ssr-query";
|
|
5
5
|
import { ConvexQueryClient } from "@convex-dev/react-query";
|
|
6
|
-
import { ConvexProvider, ConvexReactClient } from "convex/react";
|
|
7
6
|
import { routeTree } from "./routeTree.gen";
|
|
8
7
|
import Loader from "./components/loader";
|
|
9
8
|
import "./index.css";
|
|
@@ -27,21 +26,12 @@ import { orpc, queryClient } from "./utils/orpc";
|
|
|
27
26
|
|
|
28
27
|
{{#if (eq backend "convex")}}
|
|
29
28
|
export function getRouter() {
|
|
30
|
-
const
|
|
31
|
-
if (!
|
|
32
|
-
|
|
29
|
+
const convexUrl = (import.meta as any).env.VITE_CONVEX_URL!;
|
|
30
|
+
if (!convexUrl) {
|
|
31
|
+
throw new Error("VITE_CONVEX_URL is not set");
|
|
33
32
|
}
|
|
34
|
-
const convex = new ConvexReactClient(CONVEX_URL, {
|
|
35
|
-
unsavedChangesWarning: false,
|
|
36
|
-
});
|
|
37
33
|
|
|
38
|
-
|
|
39
|
-
const convexQueryClient = new ConvexQueryClient(convex, {
|
|
40
|
-
expectAuth: true,
|
|
41
|
-
});
|
|
42
|
-
{{else}}
|
|
43
|
-
const convexQueryClient = new ConvexQueryClient(convex);
|
|
44
|
-
{{/if}}
|
|
34
|
+
const convexQueryClient = new ConvexQueryClient(convexUrl);
|
|
45
35
|
|
|
46
36
|
const queryClient: QueryClient = new QueryClient({
|
|
47
37
|
defaultOptions: {
|
|
@@ -53,21 +43,19 @@ export function getRouter() {
|
|
|
53
43
|
});
|
|
54
44
|
convexQueryClient.connect(queryClient);
|
|
55
45
|
|
|
56
|
-
const router =
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
</ConvexProvider>
|
|
67
|
-
),
|
|
68
|
-
}),
|
|
46
|
+
const router = createTanStackRouter({
|
|
47
|
+
routeTree,
|
|
48
|
+
defaultPreload: "intent",
|
|
49
|
+
defaultPendingComponent: () => <Loader />,
|
|
50
|
+
defaultNotFoundComponent: () => <div>Not Found</div>,
|
|
51
|
+
context: { queryClient, convexQueryClient },
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
setupRouterSsrQueryIntegration({
|
|
55
|
+
router,
|
|
69
56
|
queryClient,
|
|
70
|
-
);
|
|
57
|
+
});
|
|
58
|
+
|
|
71
59
|
return router;
|
|
72
60
|
}
|
|
73
61
|
{{else}}
|
|
@@ -17,7 +17,6 @@ import appCss from "../index.css?url";
|
|
|
17
17
|
{{#if (eq backend "convex")}}
|
|
18
18
|
import type { QueryClient } from "@tanstack/react-query";
|
|
19
19
|
import type { ConvexQueryClient } from "@convex-dev/react-query";
|
|
20
|
-
import type { ConvexReactClient } from "convex/react";
|
|
21
20
|
{{else}}
|
|
22
21
|
{{#if (or (eq api "trpc") (eq api "orpc"))}}
|
|
23
22
|
import type { QueryClient } from "@tanstack/react-query";
|
|
@@ -49,7 +48,6 @@ const getAuth = createServerFn({ method: "GET" }).handler(async () => {
|
|
|
49
48
|
{{#if (eq backend "convex")}}
|
|
50
49
|
export interface RouterAppContext {
|
|
51
50
|
queryClient: QueryClient;
|
|
52
|
-
convexClient: ConvexReactClient;
|
|
53
51
|
convexQueryClient: ConvexQueryClient;
|
|
54
52
|
}
|
|
55
53
|
{{else}}
|
|
@@ -122,7 +120,7 @@ function RootDocument() {
|
|
|
122
120
|
const context = useRouteContext({ from: Route.id });
|
|
123
121
|
return (
|
|
124
122
|
<ClerkProvider>
|
|
125
|
-
<ConvexProviderWithClerk client={context.convexClient} useAuth={useAuth}>
|
|
123
|
+
<ConvexProviderWithClerk client={context.convexQueryClient.convexClient} useAuth={useAuth}>
|
|
126
124
|
<html lang="en" className="dark">
|
|
127
125
|
<head>
|
|
128
126
|
<HeadContent />
|
|
@@ -144,7 +142,7 @@ function RootDocument() {
|
|
|
144
142
|
const context = useRouteContext({ from: Route.id });
|
|
145
143
|
return (
|
|
146
144
|
<ConvexBetterAuthProvider
|
|
147
|
-
client={context.convexClient}
|
|
145
|
+
client={context.convexQueryClient.convexClient}
|
|
148
146
|
authClient={authClient}
|
|
149
147
|
initialToken={context.token}
|
|
150
148
|
>
|