@better-t-stack/template-generator 3.26.0 → 3.27.0
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/index.d.mts +12 -12
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1252 -432
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -388,7 +388,7 @@ function updatePackageJsonsWithCatalogs(vfs, packagesInfo, catalog) {
|
|
|
388
388
|
//#endregion
|
|
389
389
|
//#region src/utils/db-scripts.ts
|
|
390
390
|
function getDbScriptSupport(config) {
|
|
391
|
-
const isD1Alchemy = config.dbSetup === "d1" && config.serverDeploy === "cloudflare";
|
|
391
|
+
const isD1Alchemy = config.dbSetup === "d1" && (config.serverDeploy === "cloudflare" || config.backend === "self" && config.webDeploy === "cloudflare");
|
|
392
392
|
if (!(config.backend !== "convex" && config.backend !== "none" && config.database !== "none" && config.orm !== "none" && config.orm !== "mongoose")) return {
|
|
393
393
|
hasDbScripts: false,
|
|
394
394
|
hasDbPush: false,
|
|
@@ -705,8 +705,8 @@ function renameDevScriptsForAlchemy(vfs, config) {
|
|
|
705
705
|
//#region src/utils/add-deps.ts
|
|
706
706
|
const dependencyVersionMap = {
|
|
707
707
|
typescript: "^5",
|
|
708
|
-
"better-auth": "1.5.
|
|
709
|
-
"@better-auth/expo": "1.5.
|
|
708
|
+
"better-auth": "1.5.5",
|
|
709
|
+
"@better-auth/expo": "1.5.5",
|
|
710
710
|
"@clerk/backend": "^3.2.1",
|
|
711
711
|
"@clerk/express": "^2.0.5",
|
|
712
712
|
"@clerk/fastify": "^3.1.3",
|
|
@@ -776,17 +776,17 @@ const dependencyVersionMap = {
|
|
|
776
776
|
"@orpc/openapi": "^1.12.2",
|
|
777
777
|
"@orpc/zod": "^1.12.2",
|
|
778
778
|
"@orpc/tanstack-query": "^1.13.6",
|
|
779
|
-
"@trpc/tanstack-react-query": "^11.
|
|
780
|
-
"@trpc/server": "^11.
|
|
781
|
-
"@trpc/client": "^11.
|
|
779
|
+
"@trpc/tanstack-react-query": "^11.13.4",
|
|
780
|
+
"@trpc/server": "^11.13.4",
|
|
781
|
+
"@trpc/client": "^11.13.4",
|
|
782
782
|
next: "^16.2.0",
|
|
783
|
-
convex: "^1.
|
|
783
|
+
convex: "^1.33.1",
|
|
784
784
|
"@convex-dev/react-query": "^0.1.0",
|
|
785
785
|
"@convex-dev/agent": "^0.3.2",
|
|
786
786
|
"convex-svelte": "^0.0.12",
|
|
787
787
|
"convex-nuxt": "0.1.5",
|
|
788
788
|
"convex-vue": "^0.1.5",
|
|
789
|
-
"@convex-dev/better-auth": "^0.
|
|
789
|
+
"@convex-dev/better-auth": "^0.11.3",
|
|
790
790
|
"@tanstack/svelte-query": "^5.85.3",
|
|
791
791
|
"@tanstack/svelte-query-devtools": "^5.85.3",
|
|
792
792
|
"@tanstack/vue-query-devtools": "^6.1.5",
|
|
@@ -800,22 +800,22 @@ const dependencyVersionMap = {
|
|
|
800
800
|
"@tanstack/solid-query": "^5.87.4",
|
|
801
801
|
"@tanstack/solid-query-devtools": "^5.87.4",
|
|
802
802
|
"@tanstack/solid-router-devtools": "^1.131.44",
|
|
803
|
-
wrangler: "^4.
|
|
803
|
+
wrangler: "^4.77.0",
|
|
804
804
|
"@cloudflare/vite-plugin": "^1.17.1",
|
|
805
|
-
"@opennextjs/cloudflare": "^1.
|
|
805
|
+
"@opennextjs/cloudflare": "^1.17.3",
|
|
806
806
|
"nitro-cloudflare-dev": "^0.2.2",
|
|
807
807
|
"@sveltejs/adapter-cloudflare": "^7.2.4",
|
|
808
808
|
"@cloudflare/workers-types": "^4.20251213.0",
|
|
809
809
|
"@astrojs/cloudflare": "^13.0.1",
|
|
810
810
|
"@astrojs/node": "^10.0.0-beta.9",
|
|
811
|
-
alchemy: "^0.
|
|
811
|
+
alchemy: "^0.90.0",
|
|
812
812
|
dotenv: "^17.2.2",
|
|
813
813
|
tsdown: "^0.16.5",
|
|
814
814
|
zod: "^4.1.13",
|
|
815
815
|
"@t3-oss/env-core": "^0.13.1",
|
|
816
816
|
"@t3-oss/env-nextjs": "^0.13.1",
|
|
817
817
|
"@t3-oss/env-nuxt": "^0.13.1",
|
|
818
|
-
"@polar-sh/better-auth": "^1.
|
|
818
|
+
"@polar-sh/better-auth": "^1.8.3",
|
|
819
819
|
"@polar-sh/sdk": "^0.42.2"
|
|
820
820
|
};
|
|
821
821
|
/**
|
|
@@ -1335,6 +1335,7 @@ function addConvexDeps(vfs, frontend, frontendType) {
|
|
|
1335
1335
|
|
|
1336
1336
|
//#endregion
|
|
1337
1337
|
//#region src/processors/auth-deps.ts
|
|
1338
|
+
const CONVEX_BETTER_AUTH_VERSION = "1.5.3";
|
|
1338
1339
|
function processAuthDeps(vfs, config) {
|
|
1339
1340
|
const { auth, backend } = config;
|
|
1340
1341
|
if (!auth || auth === "none") return;
|
|
@@ -1396,13 +1397,13 @@ function processConvexAuthDeps(vfs, config) {
|
|
|
1396
1397
|
vfs,
|
|
1397
1398
|
packagePath: backendPath,
|
|
1398
1399
|
dependencies: ["better-auth", "@convex-dev/better-auth"],
|
|
1399
|
-
customDependencies: { "better-auth":
|
|
1400
|
+
customDependencies: { "better-auth": CONVEX_BETTER_AUTH_VERSION }
|
|
1400
1401
|
});
|
|
1401
1402
|
if (hasNative) addPackageDependency({
|
|
1402
1403
|
vfs,
|
|
1403
1404
|
packagePath: backendPath,
|
|
1404
1405
|
dependencies: ["@better-auth/expo"],
|
|
1405
|
-
customDependencies: { "@better-auth/expo":
|
|
1406
|
+
customDependencies: { "@better-auth/expo": CONVEX_BETTER_AUTH_VERSION }
|
|
1406
1407
|
});
|
|
1407
1408
|
}
|
|
1408
1409
|
if (webExists) {
|
|
@@ -1410,7 +1411,7 @@ function processConvexAuthDeps(vfs, config) {
|
|
|
1410
1411
|
vfs,
|
|
1411
1412
|
packagePath: webPath,
|
|
1412
1413
|
dependencies: ["better-auth", "@convex-dev/better-auth"],
|
|
1413
|
-
customDependencies: { "better-auth":
|
|
1414
|
+
customDependencies: { "better-auth": CONVEX_BETTER_AUTH_VERSION }
|
|
1414
1415
|
});
|
|
1415
1416
|
if (hasReactWebAuthForms) addPackageDependency({
|
|
1416
1417
|
vfs,
|
|
@@ -1438,8 +1439,8 @@ function processConvexAuthDeps(vfs, config) {
|
|
|
1438
1439
|
"@tanstack/react-form"
|
|
1439
1440
|
],
|
|
1440
1441
|
customDependencies: {
|
|
1441
|
-
"better-auth":
|
|
1442
|
-
"@better-auth/expo":
|
|
1442
|
+
"better-auth": CONVEX_BETTER_AUTH_VERSION,
|
|
1443
|
+
"@better-auth/expo": CONVEX_BETTER_AUTH_VERSION
|
|
1443
1444
|
}
|
|
1444
1445
|
});
|
|
1445
1446
|
}
|
|
@@ -1631,7 +1632,10 @@ function processAuthPlugins(vfs, config) {
|
|
|
1631
1632
|
namedImports: [named]
|
|
1632
1633
|
});
|
|
1633
1634
|
});
|
|
1634
|
-
const betterAuthCall = sourceFile.
|
|
1635
|
+
const betterAuthCall = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).find((callExpression) => {
|
|
1636
|
+
const expression = callExpression.getExpression();
|
|
1637
|
+
return Node.isIdentifier(expression) && expression.getText() === "betterAuth";
|
|
1638
|
+
});
|
|
1635
1639
|
if (betterAuthCall) {
|
|
1636
1640
|
const configObject = betterAuthCall.getArguments()[0]?.asKind(SyntaxKind.ObjectLiteralExpression);
|
|
1637
1641
|
if (configObject) {
|
|
@@ -1876,12 +1880,20 @@ function processDeployDeps(vfs, config) {
|
|
|
1876
1880
|
function processEnvDeps(vfs, config) {
|
|
1877
1881
|
const envPath = "packages/env/package.json";
|
|
1878
1882
|
if (!vfs.exists(envPath)) return;
|
|
1879
|
-
const { frontend, backend, runtime } = config;
|
|
1883
|
+
const { frontend, backend, runtime, webDeploy } = config;
|
|
1880
1884
|
const deps = ["zod"];
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1885
|
+
const hasNative = frontend.some((value) => [
|
|
1886
|
+
"native-bare",
|
|
1887
|
+
"native-uniwind",
|
|
1888
|
+
"native-unistyles"
|
|
1889
|
+
].includes(value));
|
|
1890
|
+
const hasNextJs = frontend.includes("next");
|
|
1891
|
+
const hasNuxt = frontend.includes("nuxt");
|
|
1892
|
+
if (hasNextJs) deps.push("@t3-oss/env-nextjs");
|
|
1893
|
+
else if (hasNuxt) deps.push("@t3-oss/env-nuxt");
|
|
1894
|
+
if (hasNative || !hasNextJs && !hasNuxt) deps.push("@t3-oss/env-core");
|
|
1884
1895
|
if (backend !== "convex" && backend !== "none" && runtime !== "workers" && !deps.includes("@t3-oss/env-core")) deps.push("@t3-oss/env-core");
|
|
1896
|
+
if (backend === "self" && webDeploy === "cloudflare" && hasNextJs) deps.push("@opennextjs/cloudflare");
|
|
1885
1897
|
addPackageDependency({
|
|
1886
1898
|
vfs,
|
|
1887
1899
|
packagePath: envPath,
|
|
@@ -2050,7 +2062,7 @@ function buildConvexBackendVars(frontend, auth, examples) {
|
|
|
2050
2062
|
const hasNextJs = frontend.includes("next");
|
|
2051
2063
|
const hasNative = frontend.includes("native-bare") || frontend.includes("native-uniwind") || frontend.includes("native-unistyles");
|
|
2052
2064
|
const hasWeb = frontend.includes("react-router") || frontend.includes("tanstack-router") || frontend.includes("tanstack-start") || hasNextJs || frontend.includes("nuxt") || frontend.includes("solid") || frontend.includes("svelte") || frontend.includes("astro");
|
|
2053
|
-
const defaultSiteUrl = hasNative && !hasWeb ? "http://localhost:8081" : "http://localhost:3001";
|
|
2065
|
+
const defaultSiteUrl = hasNative && !hasWeb ? "http://localhost:8081" : frontend.includes("react-router") || frontend.includes("tanstack-router") || frontend.includes("svelte") ? "http://localhost:5173" : frontend.includes("astro") ? "http://localhost:4321" : "http://localhost:3001";
|
|
2054
2066
|
const vars = [];
|
|
2055
2067
|
if (examples?.includes("ai")) vars.push({
|
|
2056
2068
|
key: "GOOGLE_GENERATIVE_AI_API_KEY",
|
|
@@ -2088,7 +2100,7 @@ function buildConvexBackendVars(frontend, auth, examples) {
|
|
|
2088
2100
|
function buildConvexCommentBlocks(frontend, auth, examples) {
|
|
2089
2101
|
const hasNative = frontend.includes("native-bare") || frontend.includes("native-uniwind") || frontend.includes("native-unistyles");
|
|
2090
2102
|
const hasWeb = frontend.includes("react-router") || frontend.includes("tanstack-router") || frontend.includes("tanstack-start") || frontend.includes("next") || frontend.includes("nuxt") || frontend.includes("solid") || frontend.includes("svelte") || frontend.includes("astro");
|
|
2091
|
-
const defaultSiteUrl = hasNative && !hasWeb ? "http://localhost:8081" : "http://localhost:3001";
|
|
2103
|
+
const defaultSiteUrl = hasNative && !hasWeb ? "http://localhost:8081" : frontend.includes("react-router") || frontend.includes("tanstack-router") || frontend.includes("svelte") ? "http://localhost:5173" : frontend.includes("astro") ? "http://localhost:4321" : "http://localhost:3001";
|
|
2092
2104
|
let commentBlocks = "";
|
|
2093
2105
|
if (examples?.includes("ai")) commentBlocks += `# Set Google AI API key for AI agent
|
|
2094
2106
|
# npx convex env set GOOGLE_GENERATIVE_AI_API_KEY=your_google_api_key
|
|
@@ -2101,11 +2113,12 @@ ${hasWeb || hasNative ? `# npx convex env set SITE_URL ${defaultSiteUrl}\n` : ""
|
|
|
2101
2113
|
}
|
|
2102
2114
|
function buildServerVars(backend, frontend, auth, api, database, dbSetup, runtime, webDeploy, serverDeploy, payments, examples) {
|
|
2103
2115
|
const hasReactRouter = frontend.includes("react-router");
|
|
2116
|
+
const hasTanStackRouter = frontend.includes("tanstack-router");
|
|
2104
2117
|
const hasSvelte = frontend.includes("svelte");
|
|
2105
2118
|
const hasAstro = frontend.includes("astro");
|
|
2106
2119
|
let corsOrigin = "http://localhost:3001";
|
|
2107
2120
|
if (hasAstro) corsOrigin = "http://localhost:4321";
|
|
2108
|
-
else if (hasReactRouter || hasSvelte) corsOrigin = "http://localhost:5173";
|
|
2121
|
+
else if (hasReactRouter || hasTanStackRouter || hasSvelte) corsOrigin = "http://localhost:5173";
|
|
2109
2122
|
else if (backend === "self") corsOrigin = "http://localhost:3001";
|
|
2110
2123
|
let databaseUrl = null;
|
|
2111
2124
|
if (database !== "none" && dbSetup === "none") switch (database) {
|
|
@@ -2615,6 +2628,7 @@ function generateReadmeContent(options) {
|
|
|
2615
2628
|
const { projectName, packageManager, database, auth, addons = [], orm = "drizzle", runtime = "bun", frontend = ["tanstack-router"], backend = "hono", api = "trpc", webDeploy, serverDeploy } = options;
|
|
2616
2629
|
const isConvex = backend === "convex";
|
|
2617
2630
|
const hasReactRouter = frontend.includes("react-router");
|
|
2631
|
+
const hasTanStackRouter = frontend.includes("tanstack-router");
|
|
2618
2632
|
const hasNative = hasNativeFrontend(frontend);
|
|
2619
2633
|
const hasReactWeb = frontend.some((f) => [
|
|
2620
2634
|
"tanstack-router",
|
|
@@ -2625,7 +2639,7 @@ function generateReadmeContent(options) {
|
|
|
2625
2639
|
const hasSvelte = frontend.includes("svelte");
|
|
2626
2640
|
const hasAstro = frontend.includes("astro");
|
|
2627
2641
|
const packageManagerRunCmd = `${packageManager} run`;
|
|
2628
|
-
const webPort = hasReactRouter || hasSvelte ? "5173" : hasAstro ? "4321" : "3001";
|
|
2642
|
+
const webPort = hasReactRouter || hasTanStackRouter || hasSvelte ? "5173" : hasAstro ? "4321" : "3001";
|
|
2629
2643
|
const stackDescription = generateStackDescription(frontend, backend, api, isConvex);
|
|
2630
2644
|
return `# ${projectName}
|
|
2631
2645
|
|
|
@@ -4513,12 +4527,16 @@ async function authenticateClerkRequest(request: Request): Promise<ClerkContextA
|
|
|
4513
4527
|
{{#if (and (eq backend 'self') (includes frontend "next"))}}
|
|
4514
4528
|
import type { NextRequest } from "next/server";
|
|
4515
4529
|
{{#if (eq auth "better-auth")}}
|
|
4530
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
4531
|
+
import { createAuth } from "@{{projectName}}/auth";
|
|
4532
|
+
{{else}}
|
|
4516
4533
|
import { auth } from "@{{projectName}}/auth";
|
|
4517
4534
|
{{/if}}
|
|
4535
|
+
{{/if}}
|
|
4518
4536
|
|
|
4519
4537
|
export async function createContext(req: NextRequest){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
4520
4538
|
{{#if (eq auth "better-auth")}}
|
|
4521
|
-
const session = await auth.api.getSession({
|
|
4539
|
+
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth(){{else}}auth{{/if}}.api.getSession({
|
|
4522
4540
|
headers: req.headers,
|
|
4523
4541
|
});
|
|
4524
4542
|
return {
|
|
@@ -4541,12 +4559,16 @@ export async function createContext(req: NextRequest){{#if (eq auth "clerk")}}:
|
|
|
4541
4559
|
|
|
4542
4560
|
{{else if (and (eq backend 'self') (includes frontend "tanstack-start"))}}
|
|
4543
4561
|
{{#if (eq auth "better-auth")}}
|
|
4562
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
4563
|
+
import { createAuth } from "@{{projectName}}/auth";
|
|
4564
|
+
{{else}}
|
|
4544
4565
|
import { auth } from "@{{projectName}}/auth";
|
|
4545
4566
|
{{/if}}
|
|
4567
|
+
{{/if}}
|
|
4546
4568
|
|
|
4547
4569
|
export async function createContext({ req }: { req: Request }){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
4548
4570
|
{{#if (eq auth "better-auth")}}
|
|
4549
|
-
const session = await auth.api.getSession({
|
|
4571
|
+
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth(){{else}}auth{{/if}}.api.getSession({
|
|
4550
4572
|
headers: req.headers,
|
|
4551
4573
|
});
|
|
4552
4574
|
return {
|
|
@@ -4569,8 +4591,12 @@ export async function createContext({ req }: { req: Request }){{#if (eq auth "cl
|
|
|
4569
4591
|
|
|
4570
4592
|
{{else if (and (eq backend 'self') (includes frontend "nuxt"))}}
|
|
4571
4593
|
{{#if (eq auth "better-auth")}}
|
|
4594
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
4595
|
+
import { createAuth } from "@{{projectName}}/auth";
|
|
4596
|
+
{{else}}
|
|
4572
4597
|
import { auth } from "@{{projectName}}/auth";
|
|
4573
4598
|
{{/if}}
|
|
4599
|
+
{{/if}}
|
|
4574
4600
|
|
|
4575
4601
|
export type CreateContextOptions = {
|
|
4576
4602
|
headers: Headers;
|
|
@@ -4578,7 +4604,7 @@ export type CreateContextOptions = {
|
|
|
4578
4604
|
|
|
4579
4605
|
export async function createContext({ headers }: CreateContextOptions) {
|
|
4580
4606
|
{{#if (eq auth "better-auth")}}
|
|
4581
|
-
const session = await auth.api.getSession({ headers });
|
|
4607
|
+
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth(){{else}}auth{{/if}}.api.getSession({ headers });
|
|
4582
4608
|
return {
|
|
4583
4609
|
auth: null,
|
|
4584
4610
|
session,
|
|
@@ -4593,8 +4619,12 @@ export async function createContext({ headers }: CreateContextOptions) {
|
|
|
4593
4619
|
|
|
4594
4620
|
{{else if (and (eq backend 'self') (includes frontend "astro"))}}
|
|
4595
4621
|
{{#if (eq auth "better-auth")}}
|
|
4622
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
4623
|
+
import { createAuth } from "@{{projectName}}/auth";
|
|
4624
|
+
{{else}}
|
|
4596
4625
|
import { auth } from "@{{projectName}}/auth";
|
|
4597
4626
|
{{/if}}
|
|
4627
|
+
{{/if}}
|
|
4598
4628
|
|
|
4599
4629
|
export type CreateContextOptions = {
|
|
4600
4630
|
headers: Headers;
|
|
@@ -4602,7 +4632,7 @@ export type CreateContextOptions = {
|
|
|
4602
4632
|
|
|
4603
4633
|
export async function createContext({ headers }: CreateContextOptions) {
|
|
4604
4634
|
{{#if (eq auth "better-auth")}}
|
|
4605
|
-
const session = await auth.api.getSession({ headers });
|
|
4635
|
+
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth(){{else}}auth{{/if}}.api.getSession({ headers });
|
|
4606
4636
|
return {
|
|
4607
4637
|
auth: null,
|
|
4608
4638
|
session,
|
|
@@ -4618,8 +4648,12 @@ export async function createContext({ headers }: CreateContextOptions) {
|
|
|
4618
4648
|
{{else if (eq backend 'hono')}}
|
|
4619
4649
|
import type { Context as HonoContext } from "hono";
|
|
4620
4650
|
{{#if (eq auth "better-auth")}}
|
|
4651
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
4652
|
+
import { createAuth } from "@{{projectName}}/auth";
|
|
4653
|
+
{{else}}
|
|
4621
4654
|
import { auth } from "@{{projectName}}/auth";
|
|
4622
4655
|
{{/if}}
|
|
4656
|
+
{{/if}}
|
|
4623
4657
|
|
|
4624
4658
|
export type CreateContextOptions = {
|
|
4625
4659
|
context: HonoContext;
|
|
@@ -4627,7 +4661,7 @@ export type CreateContextOptions = {
|
|
|
4627
4661
|
|
|
4628
4662
|
export async function createContext({ context }: CreateContextOptions){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
4629
4663
|
{{#if (eq auth "better-auth")}}
|
|
4630
|
-
const session = await auth.api.getSession({
|
|
4664
|
+
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth(){{else}}auth{{/if}}.api.getSession({
|
|
4631
4665
|
headers: context.req.raw.headers,
|
|
4632
4666
|
});
|
|
4633
4667
|
return {
|
|
@@ -5361,12 +5395,16 @@ async function authenticateClerkRequest(request: Request): Promise<ClerkContextA
|
|
|
5361
5395
|
{{#if (and (eq backend 'self') (includes frontend "next"))}}
|
|
5362
5396
|
import type { NextRequest } from "next/server";
|
|
5363
5397
|
{{#if (eq auth "better-auth")}}
|
|
5398
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
5399
|
+
import { createAuth } from "@{{projectName}}/auth";
|
|
5400
|
+
{{else}}
|
|
5364
5401
|
import { auth } from "@{{projectName}}/auth";
|
|
5365
5402
|
{{/if}}
|
|
5403
|
+
{{/if}}
|
|
5366
5404
|
|
|
5367
5405
|
export async function createContext(req: NextRequest){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
5368
5406
|
{{#if (eq auth "better-auth")}}
|
|
5369
|
-
const session = await auth.api.getSession({
|
|
5407
|
+
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth(){{else}}auth{{/if}}.api.getSession({
|
|
5370
5408
|
headers: req.headers,
|
|
5371
5409
|
});
|
|
5372
5410
|
return {
|
|
@@ -5389,12 +5427,16 @@ export async function createContext(req: NextRequest){{#if (eq auth "clerk")}}:
|
|
|
5389
5427
|
|
|
5390
5428
|
{{else if (and (eq backend 'self') (includes frontend "tanstack-start"))}}
|
|
5391
5429
|
{{#if (eq auth "better-auth")}}
|
|
5430
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
5431
|
+
import { createAuth } from "@{{projectName}}/auth";
|
|
5432
|
+
{{else}}
|
|
5392
5433
|
import { auth } from "@{{projectName}}/auth";
|
|
5393
5434
|
{{/if}}
|
|
5435
|
+
{{/if}}
|
|
5394
5436
|
|
|
5395
5437
|
export async function createContext({ req }: { req: Request }){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
5396
5438
|
{{#if (eq auth "better-auth")}}
|
|
5397
|
-
const session = await auth.api.getSession({
|
|
5439
|
+
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth(){{else}}auth{{/if}}.api.getSession({
|
|
5398
5440
|
headers: req.headers,
|
|
5399
5441
|
});
|
|
5400
5442
|
return {
|
|
@@ -5418,8 +5460,12 @@ export async function createContext({ req }: { req: Request }){{#if (eq auth "cl
|
|
|
5418
5460
|
{{else if (eq backend 'hono')}}
|
|
5419
5461
|
import type { Context as HonoContext } from "hono";
|
|
5420
5462
|
{{#if (eq auth "better-auth")}}
|
|
5463
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
5464
|
+
import { createAuth } from "@{{projectName}}/auth";
|
|
5465
|
+
{{else}}
|
|
5421
5466
|
import { auth } from "@{{projectName}}/auth";
|
|
5422
5467
|
{{/if}}
|
|
5468
|
+
{{/if}}
|
|
5423
5469
|
|
|
5424
5470
|
export type CreateContextOptions = {
|
|
5425
5471
|
context: HonoContext;
|
|
@@ -5427,7 +5473,7 @@ export type CreateContextOptions = {
|
|
|
5427
5473
|
|
|
5428
5474
|
export async function createContext({ context }: CreateContextOptions){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
5429
5475
|
{{#if (eq auth "better-auth")}}
|
|
5430
|
-
const session = await auth.api.getSession({
|
|
5476
|
+
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth(){{else}}auth{{/if}}.api.getSession({
|
|
5431
5477
|
headers: context.req.raw.headers,
|
|
5432
5478
|
});
|
|
5433
5479
|
return {
|
|
@@ -5869,7 +5915,14 @@ import { authComponent, createAuth } from "./auth";
|
|
|
5869
5915
|
const http = httpRouter();
|
|
5870
5916
|
|
|
5871
5917
|
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles") (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
|
|
5918
|
+
{{#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
|
|
5919
|
+
authComponent.registerRoutesLazy(http, createAuth, {
|
|
5920
|
+
cors: true,
|
|
5921
|
+
trustedOrigins: [process.env.SITE_URL!],
|
|
5922
|
+
});
|
|
5923
|
+
{{else}}
|
|
5872
5924
|
authComponent.registerRoutes(http, createAuth, { cors: true });
|
|
5925
|
+
{{/if}}
|
|
5873
5926
|
{{else}}
|
|
5874
5927
|
authComponent.registerRoutes(http, createAuth);
|
|
5875
5928
|
{{/if}}
|
|
@@ -7585,6 +7638,402 @@ export const {
|
|
|
7585
7638
|
convexUrl: env.NEXT_PUBLIC_CONVEX_URL,
|
|
7586
7639
|
convexSiteUrl: env.NEXT_PUBLIC_CONVEX_SITE_URL,
|
|
7587
7640
|
});
|
|
7641
|
+
`],
|
|
7642
|
+
["auth/better-auth/convex/web/react/react-router/src/components/sign-in-form.tsx.hbs", `import { authClient } from "@/lib/auth-client";
|
|
7643
|
+
import { useForm } from "@tanstack/react-form";
|
|
7644
|
+
import { useNavigate } from "react-router";
|
|
7645
|
+
import { toast } from "sonner";
|
|
7646
|
+
import z from "zod";
|
|
7647
|
+
import { Button } from "@{{projectName}}/ui/components/button";
|
|
7648
|
+
import { Input } from "@{{projectName}}/ui/components/input";
|
|
7649
|
+
import { Label } from "@{{projectName}}/ui/components/label";
|
|
7650
|
+
|
|
7651
|
+
export default function SignInForm({
|
|
7652
|
+
onSwitchToSignUp,
|
|
7653
|
+
}: {
|
|
7654
|
+
onSwitchToSignUp: () => void;
|
|
7655
|
+
}) {
|
|
7656
|
+
const navigate = useNavigate();
|
|
7657
|
+
|
|
7658
|
+
const form = useForm({
|
|
7659
|
+
defaultValues: {
|
|
7660
|
+
email: "",
|
|
7661
|
+
password: "",
|
|
7662
|
+
},
|
|
7663
|
+
onSubmit: async ({ value }) => {
|
|
7664
|
+
await authClient.signIn.email(
|
|
7665
|
+
{
|
|
7666
|
+
email: value.email,
|
|
7667
|
+
password: value.password,
|
|
7668
|
+
},
|
|
7669
|
+
{
|
|
7670
|
+
onSuccess: () => {
|
|
7671
|
+
navigate("/dashboard");
|
|
7672
|
+
toast.success("Sign in successful");
|
|
7673
|
+
},
|
|
7674
|
+
onError: (error) => {
|
|
7675
|
+
toast.error(error.error.message || error.error.statusText);
|
|
7676
|
+
},
|
|
7677
|
+
},
|
|
7678
|
+
);
|
|
7679
|
+
},
|
|
7680
|
+
validators: {
|
|
7681
|
+
onSubmit: z.object({
|
|
7682
|
+
email: z.email("Invalid email address"),
|
|
7683
|
+
password: z.string().min(8, "Password must be at least 8 characters"),
|
|
7684
|
+
}),
|
|
7685
|
+
},
|
|
7686
|
+
});
|
|
7687
|
+
|
|
7688
|
+
return (
|
|
7689
|
+
<div className="mx-auto mt-10 w-full max-w-md p-6">
|
|
7690
|
+
<h1 className="mb-6 text-center text-3xl font-bold">Welcome Back</h1>
|
|
7691
|
+
|
|
7692
|
+
<form
|
|
7693
|
+
onSubmit={(e) => {
|
|
7694
|
+
e.preventDefault();
|
|
7695
|
+
e.stopPropagation();
|
|
7696
|
+
form.handleSubmit();
|
|
7697
|
+
}}
|
|
7698
|
+
className="space-y-4"
|
|
7699
|
+
>
|
|
7700
|
+
<div>
|
|
7701
|
+
<form.Field name="email">
|
|
7702
|
+
{(field) => (
|
|
7703
|
+
<div className="space-y-2">
|
|
7704
|
+
<Label htmlFor={field.name}>Email</Label>
|
|
7705
|
+
<Input
|
|
7706
|
+
id={field.name}
|
|
7707
|
+
name={field.name}
|
|
7708
|
+
type="email"
|
|
7709
|
+
value={field.state.value}
|
|
7710
|
+
onBlur={field.handleBlur}
|
|
7711
|
+
onChange={(e) => field.handleChange(e.target.value)}
|
|
7712
|
+
/>
|
|
7713
|
+
{field.state.meta.errors.map((error, index) => (
|
|
7714
|
+
<p key={\`\${field.name}-error-\${index}\`} className="text-red-500">
|
|
7715
|
+
{error?.message}
|
|
7716
|
+
</p>
|
|
7717
|
+
))}
|
|
7718
|
+
</div>
|
|
7719
|
+
)}
|
|
7720
|
+
</form.Field>
|
|
7721
|
+
</div>
|
|
7722
|
+
|
|
7723
|
+
<div>
|
|
7724
|
+
<form.Field name="password">
|
|
7725
|
+
{(field) => (
|
|
7726
|
+
<div className="space-y-2">
|
|
7727
|
+
<Label htmlFor={field.name}>Password</Label>
|
|
7728
|
+
<Input
|
|
7729
|
+
id={field.name}
|
|
7730
|
+
name={field.name}
|
|
7731
|
+
type="password"
|
|
7732
|
+
value={field.state.value}
|
|
7733
|
+
onBlur={field.handleBlur}
|
|
7734
|
+
onChange={(e) => field.handleChange(e.target.value)}
|
|
7735
|
+
/>
|
|
7736
|
+
{field.state.meta.errors.map((error, index) => (
|
|
7737
|
+
<p key={\`\${field.name}-error-\${index}\`} className="text-red-500">
|
|
7738
|
+
{error?.message}
|
|
7739
|
+
</p>
|
|
7740
|
+
))}
|
|
7741
|
+
</div>
|
|
7742
|
+
)}
|
|
7743
|
+
</form.Field>
|
|
7744
|
+
</div>
|
|
7745
|
+
|
|
7746
|
+
<form.Subscribe
|
|
7747
|
+
selector={(state) => ({
|
|
7748
|
+
canSubmit: state.canSubmit,
|
|
7749
|
+
isSubmitting: state.isSubmitting,
|
|
7750
|
+
})}
|
|
7751
|
+
>
|
|
7752
|
+
{({ canSubmit, isSubmitting }) => (
|
|
7753
|
+
<Button type="submit" className="w-full" disabled={!canSubmit || isSubmitting}>
|
|
7754
|
+
{isSubmitting ? "Submitting..." : "Sign In"}
|
|
7755
|
+
</Button>
|
|
7756
|
+
)}
|
|
7757
|
+
</form.Subscribe>
|
|
7758
|
+
</form>
|
|
7759
|
+
|
|
7760
|
+
<div className="mt-4 text-center">
|
|
7761
|
+
<Button
|
|
7762
|
+
variant="link"
|
|
7763
|
+
onClick={onSwitchToSignUp}
|
|
7764
|
+
className="text-indigo-600 hover:text-indigo-800"
|
|
7765
|
+
>
|
|
7766
|
+
Need an account? Sign Up
|
|
7767
|
+
</Button>
|
|
7768
|
+
</div>
|
|
7769
|
+
</div>
|
|
7770
|
+
);
|
|
7771
|
+
}
|
|
7772
|
+
`],
|
|
7773
|
+
["auth/better-auth/convex/web/react/react-router/src/components/sign-up-form.tsx.hbs", `import { authClient } from "@/lib/auth-client";
|
|
7774
|
+
import { useForm } from "@tanstack/react-form";
|
|
7775
|
+
import { useNavigate } from "react-router";
|
|
7776
|
+
import { toast } from "sonner";
|
|
7777
|
+
import z from "zod";
|
|
7778
|
+
import { Button } from "@{{projectName}}/ui/components/button";
|
|
7779
|
+
import { Input } from "@{{projectName}}/ui/components/input";
|
|
7780
|
+
import { Label } from "@{{projectName}}/ui/components/label";
|
|
7781
|
+
|
|
7782
|
+
export default function SignUpForm({
|
|
7783
|
+
onSwitchToSignIn,
|
|
7784
|
+
}: {
|
|
7785
|
+
onSwitchToSignIn: () => void;
|
|
7786
|
+
}) {
|
|
7787
|
+
const navigate = useNavigate();
|
|
7788
|
+
|
|
7789
|
+
const form = useForm({
|
|
7790
|
+
defaultValues: {
|
|
7791
|
+
email: "",
|
|
7792
|
+
password: "",
|
|
7793
|
+
name: "",
|
|
7794
|
+
},
|
|
7795
|
+
onSubmit: async ({ value }) => {
|
|
7796
|
+
await authClient.signUp.email(
|
|
7797
|
+
{
|
|
7798
|
+
email: value.email,
|
|
7799
|
+
password: value.password,
|
|
7800
|
+
name: value.name,
|
|
7801
|
+
},
|
|
7802
|
+
{
|
|
7803
|
+
onSuccess: () => {
|
|
7804
|
+
navigate("/dashboard");
|
|
7805
|
+
toast.success("Sign up successful");
|
|
7806
|
+
},
|
|
7807
|
+
onError: (error) => {
|
|
7808
|
+
toast.error(error.error.message || error.error.statusText);
|
|
7809
|
+
},
|
|
7810
|
+
},
|
|
7811
|
+
);
|
|
7812
|
+
},
|
|
7813
|
+
validators: {
|
|
7814
|
+
onSubmit: z.object({
|
|
7815
|
+
name: z.string().min(2, "Name must be at least 2 characters"),
|
|
7816
|
+
email: z.email("Invalid email address"),
|
|
7817
|
+
password: z.string().min(8, "Password must be at least 8 characters"),
|
|
7818
|
+
}),
|
|
7819
|
+
},
|
|
7820
|
+
});
|
|
7821
|
+
|
|
7822
|
+
return (
|
|
7823
|
+
<div className="mx-auto mt-10 w-full max-w-md p-6">
|
|
7824
|
+
<h1 className="mb-6 text-center text-3xl font-bold">Create Account</h1>
|
|
7825
|
+
|
|
7826
|
+
<form
|
|
7827
|
+
onSubmit={(e) => {
|
|
7828
|
+
e.preventDefault();
|
|
7829
|
+
e.stopPropagation();
|
|
7830
|
+
form.handleSubmit();
|
|
7831
|
+
}}
|
|
7832
|
+
className="space-y-4"
|
|
7833
|
+
>
|
|
7834
|
+
<div>
|
|
7835
|
+
<form.Field name="name">
|
|
7836
|
+
{(field) => (
|
|
7837
|
+
<div className="space-y-2">
|
|
7838
|
+
<Label htmlFor={field.name}>Name</Label>
|
|
7839
|
+
<Input
|
|
7840
|
+
id={field.name}
|
|
7841
|
+
name={field.name}
|
|
7842
|
+
value={field.state.value}
|
|
7843
|
+
onBlur={field.handleBlur}
|
|
7844
|
+
onChange={(e) => field.handleChange(e.target.value)}
|
|
7845
|
+
/>
|
|
7846
|
+
{field.state.meta.errors.map((error, index) => (
|
|
7847
|
+
<p key={\`\${field.name}-error-\${index}\`} className="text-red-500">
|
|
7848
|
+
{error?.message}
|
|
7849
|
+
</p>
|
|
7850
|
+
))}
|
|
7851
|
+
</div>
|
|
7852
|
+
)}
|
|
7853
|
+
</form.Field>
|
|
7854
|
+
</div>
|
|
7855
|
+
|
|
7856
|
+
<div>
|
|
7857
|
+
<form.Field name="email">
|
|
7858
|
+
{(field) => (
|
|
7859
|
+
<div className="space-y-2">
|
|
7860
|
+
<Label htmlFor={field.name}>Email</Label>
|
|
7861
|
+
<Input
|
|
7862
|
+
id={field.name}
|
|
7863
|
+
name={field.name}
|
|
7864
|
+
type="email"
|
|
7865
|
+
value={field.state.value}
|
|
7866
|
+
onBlur={field.handleBlur}
|
|
7867
|
+
onChange={(e) => field.handleChange(e.target.value)}
|
|
7868
|
+
/>
|
|
7869
|
+
{field.state.meta.errors.map((error, index) => (
|
|
7870
|
+
<p key={\`\${field.name}-error-\${index}\`} className="text-red-500">
|
|
7871
|
+
{error?.message}
|
|
7872
|
+
</p>
|
|
7873
|
+
))}
|
|
7874
|
+
</div>
|
|
7875
|
+
)}
|
|
7876
|
+
</form.Field>
|
|
7877
|
+
</div>
|
|
7878
|
+
|
|
7879
|
+
<div>
|
|
7880
|
+
<form.Field name="password">
|
|
7881
|
+
{(field) => (
|
|
7882
|
+
<div className="space-y-2">
|
|
7883
|
+
<Label htmlFor={field.name}>Password</Label>
|
|
7884
|
+
<Input
|
|
7885
|
+
id={field.name}
|
|
7886
|
+
name={field.name}
|
|
7887
|
+
type="password"
|
|
7888
|
+
value={field.state.value}
|
|
7889
|
+
onBlur={field.handleBlur}
|
|
7890
|
+
onChange={(e) => field.handleChange(e.target.value)}
|
|
7891
|
+
/>
|
|
7892
|
+
{field.state.meta.errors.map((error, index) => (
|
|
7893
|
+
<p key={\`\${field.name}-error-\${index}\`} className="text-red-500">
|
|
7894
|
+
{error?.message}
|
|
7895
|
+
</p>
|
|
7896
|
+
))}
|
|
7897
|
+
</div>
|
|
7898
|
+
)}
|
|
7899
|
+
</form.Field>
|
|
7900
|
+
</div>
|
|
7901
|
+
|
|
7902
|
+
<form.Subscribe
|
|
7903
|
+
selector={(state) => ({
|
|
7904
|
+
canSubmit: state.canSubmit,
|
|
7905
|
+
isSubmitting: state.isSubmitting,
|
|
7906
|
+
})}
|
|
7907
|
+
>
|
|
7908
|
+
{({ canSubmit, isSubmitting }) => (
|
|
7909
|
+
<Button type="submit" className="w-full" disabled={!canSubmit || isSubmitting}>
|
|
7910
|
+
{isSubmitting ? "Submitting..." : "Sign Up"}
|
|
7911
|
+
</Button>
|
|
7912
|
+
)}
|
|
7913
|
+
</form.Subscribe>
|
|
7914
|
+
</form>
|
|
7915
|
+
|
|
7916
|
+
<div className="mt-4 text-center">
|
|
7917
|
+
<Button
|
|
7918
|
+
variant="link"
|
|
7919
|
+
onClick={onSwitchToSignIn}
|
|
7920
|
+
className="text-indigo-600 hover:text-indigo-800"
|
|
7921
|
+
>
|
|
7922
|
+
Already have an account? Sign In
|
|
7923
|
+
</Button>
|
|
7924
|
+
</div>
|
|
7925
|
+
</div>
|
|
7926
|
+
);
|
|
7927
|
+
}
|
|
7928
|
+
`],
|
|
7929
|
+
["auth/better-auth/convex/web/react/react-router/src/components/user-menu.tsx.hbs", `import { useNavigate } from "react-router";
|
|
7930
|
+
|
|
7931
|
+
import {
|
|
7932
|
+
DropdownMenu,
|
|
7933
|
+
DropdownMenuContent,
|
|
7934
|
+
DropdownMenuGroup,
|
|
7935
|
+
DropdownMenuItem,
|
|
7936
|
+
DropdownMenuLabel,
|
|
7937
|
+
DropdownMenuSeparator,
|
|
7938
|
+
DropdownMenuTrigger,
|
|
7939
|
+
} from "@{{projectName}}/ui/components/dropdown-menu";
|
|
7940
|
+
import { authClient } from "@/lib/auth-client";
|
|
7941
|
+
import { useQuery } from "convex/react";
|
|
7942
|
+
import { api } from "@{{projectName}}/backend/convex/_generated/api";
|
|
7943
|
+
|
|
7944
|
+
import { Button } from "@{{projectName}}/ui/components/button";
|
|
7945
|
+
|
|
7946
|
+
export default function UserMenu() {
|
|
7947
|
+
const navigate = useNavigate();
|
|
7948
|
+
const user = useQuery(api.auth.getCurrentUser);
|
|
7949
|
+
|
|
7950
|
+
return (
|
|
7951
|
+
<DropdownMenu>
|
|
7952
|
+
<DropdownMenuTrigger render={<Button variant="outline" />}>
|
|
7953
|
+
{user?.name}
|
|
7954
|
+
</DropdownMenuTrigger>
|
|
7955
|
+
<DropdownMenuContent className="bg-card">
|
|
7956
|
+
<DropdownMenuGroup>
|
|
7957
|
+
<DropdownMenuLabel>My Account</DropdownMenuLabel>
|
|
7958
|
+
<DropdownMenuSeparator />
|
|
7959
|
+
<DropdownMenuItem>{user?.email}</DropdownMenuItem>
|
|
7960
|
+
<DropdownMenuItem
|
|
7961
|
+
variant="destructive"
|
|
7962
|
+
onClick={() => {
|
|
7963
|
+
authClient.signOut({
|
|
7964
|
+
fetchOptions: {
|
|
7965
|
+
onSuccess: () => {
|
|
7966
|
+
navigate("/dashboard");
|
|
7967
|
+
},
|
|
7968
|
+
},
|
|
7969
|
+
});
|
|
7970
|
+
}}
|
|
7971
|
+
>
|
|
7972
|
+
Sign Out
|
|
7973
|
+
</DropdownMenuItem>
|
|
7974
|
+
</DropdownMenuGroup>
|
|
7975
|
+
</DropdownMenuContent>
|
|
7976
|
+
</DropdownMenu>
|
|
7977
|
+
);
|
|
7978
|
+
}
|
|
7979
|
+
`],
|
|
7980
|
+
["auth/better-auth/convex/web/react/react-router/src/lib/auth-client.ts.hbs", `import { createAuthClient } from "better-auth/react";
|
|
7981
|
+
import {
|
|
7982
|
+
convexClient,
|
|
7983
|
+
crossDomainClient,
|
|
7984
|
+
} from "@convex-dev/better-auth/client/plugins";
|
|
7985
|
+
import { env } from "@{{projectName}}/env/web";
|
|
7986
|
+
|
|
7987
|
+
export const authClient = createAuthClient({
|
|
7988
|
+
baseURL: env.VITE_CONVEX_SITE_URL,
|
|
7989
|
+
plugins: [crossDomainClient(), convexClient()],
|
|
7990
|
+
});
|
|
7991
|
+
`],
|
|
7992
|
+
["auth/better-auth/convex/web/react/react-router/src/routes/dashboard.tsx.hbs", `import SignInForm from "@/components/sign-in-form";
|
|
7993
|
+
import SignUpForm from "@/components/sign-up-form";
|
|
7994
|
+
import UserMenu from "@/components/user-menu";
|
|
7995
|
+
import { api } from "@{{projectName}}/backend/convex/_generated/api";
|
|
7996
|
+
import {
|
|
7997
|
+
Authenticated,
|
|
7998
|
+
AuthLoading,
|
|
7999
|
+
Unauthenticated,
|
|
8000
|
+
useQuery,
|
|
8001
|
+
} from "convex/react";
|
|
8002
|
+
import { useState } from "react";
|
|
8003
|
+
|
|
8004
|
+
function PrivateDashboardContent() {
|
|
8005
|
+
const privateData = useQuery(api.privateData.get);
|
|
8006
|
+
|
|
8007
|
+
return (
|
|
8008
|
+
<div>
|
|
8009
|
+
<h1>Dashboard</h1>
|
|
8010
|
+
<p>privateData: {privateData?.message}</p>
|
|
8011
|
+
<UserMenu />
|
|
8012
|
+
</div>
|
|
8013
|
+
);
|
|
8014
|
+
}
|
|
8015
|
+
|
|
8016
|
+
export default function Dashboard() {
|
|
8017
|
+
const [showSignIn, setShowSignIn] = useState(false);
|
|
8018
|
+
|
|
8019
|
+
return (
|
|
8020
|
+
<>
|
|
8021
|
+
<Authenticated>
|
|
8022
|
+
<PrivateDashboardContent />
|
|
8023
|
+
</Authenticated>
|
|
8024
|
+
<Unauthenticated>
|
|
8025
|
+
{showSignIn ? (
|
|
8026
|
+
<SignInForm onSwitchToSignUp={() => setShowSignIn(false)} />
|
|
8027
|
+
) : (
|
|
8028
|
+
<SignUpForm onSwitchToSignIn={() => setShowSignIn(true)} />
|
|
8029
|
+
)}
|
|
8030
|
+
</Unauthenticated>
|
|
8031
|
+
<AuthLoading>
|
|
8032
|
+
<div>Loading...</div>
|
|
8033
|
+
</AuthLoading>
|
|
8034
|
+
</>
|
|
8035
|
+
);
|
|
8036
|
+
}
|
|
7588
8037
|
`],
|
|
7589
8038
|
["auth/better-auth/convex/web/react/tanstack-router/src/components/sign-in-form.tsx.hbs", `import { authClient } from "@/lib/auth-client";
|
|
7590
8039
|
import { useForm } from "@tanstack/react-form";
|
|
@@ -7661,8 +8110,8 @@ export default function SignInForm({
|
|
|
7661
8110
|
onBlur={field.handleBlur}
|
|
7662
8111
|
onChange={(e) => field.handleChange(e.target.value)}
|
|
7663
8112
|
/>
|
|
7664
|
-
{field.state.meta.errors.map((error) => (
|
|
7665
|
-
<p key={error
|
|
8113
|
+
{field.state.meta.errors.map((error, index) => (
|
|
8114
|
+
<p key={\`\${field.name}-error-\${index}\`} className="text-red-500">
|
|
7666
8115
|
{error?.message}
|
|
7667
8116
|
</p>
|
|
7668
8117
|
))}
|
|
@@ -7684,8 +8133,8 @@ export default function SignInForm({
|
|
|
7684
8133
|
onBlur={field.handleBlur}
|
|
7685
8134
|
onChange={(e) => field.handleChange(e.target.value)}
|
|
7686
8135
|
/>
|
|
7687
|
-
{field.state.meta.errors.map((error) => (
|
|
7688
|
-
<p key={error
|
|
8136
|
+
{field.state.meta.errors.map((error, index) => (
|
|
8137
|
+
<p key={\`\${field.name}-error-\${index}\`} className="text-red-500">
|
|
7689
8138
|
{error?.message}
|
|
7690
8139
|
</p>
|
|
7691
8140
|
))}
|
|
@@ -7797,8 +8246,8 @@ export default function SignUpForm({
|
|
|
7797
8246
|
onBlur={field.handleBlur}
|
|
7798
8247
|
onChange={(e) => field.handleChange(e.target.value)}
|
|
7799
8248
|
/>
|
|
7800
|
-
{field.state.meta.errors.map((error) => (
|
|
7801
|
-
<p key={error
|
|
8249
|
+
{field.state.meta.errors.map((error, index) => (
|
|
8250
|
+
<p key={\`\${field.name}-error-\${index}\`} className="text-red-500">
|
|
7802
8251
|
{error?.message}
|
|
7803
8252
|
</p>
|
|
7804
8253
|
))}
|
|
@@ -7820,8 +8269,8 @@ export default function SignUpForm({
|
|
|
7820
8269
|
onBlur={field.handleBlur}
|
|
7821
8270
|
onChange={(e) => field.handleChange(e.target.value)}
|
|
7822
8271
|
/>
|
|
7823
|
-
{field.state.meta.errors.map((error) => (
|
|
7824
|
-
<p key={error
|
|
8272
|
+
{field.state.meta.errors.map((error, index) => (
|
|
8273
|
+
<p key={\`\${field.name}-error-\${index}\`} className="text-red-500">
|
|
7825
8274
|
{error?.message}
|
|
7826
8275
|
</p>
|
|
7827
8276
|
))}
|
|
@@ -7843,8 +8292,8 @@ export default function SignUpForm({
|
|
|
7843
8292
|
onBlur={field.handleBlur}
|
|
7844
8293
|
onChange={(e) => field.handleChange(e.target.value)}
|
|
7845
8294
|
/>
|
|
7846
|
-
{field.state.meta.errors.map((error) => (
|
|
7847
|
-
<p key={error
|
|
8295
|
+
{field.state.meta.errors.map((error, index) => (
|
|
8296
|
+
<p key={\`\${field.name}-error-\${index}\`} className="text-red-500">
|
|
7848
8297
|
{error?.message}
|
|
7849
8298
|
</p>
|
|
7850
8299
|
))}
|
|
@@ -7961,18 +8410,25 @@ export const Route = createFileRoute("/dashboard")({
|
|
|
7961
8410
|
component: RouteComponent,
|
|
7962
8411
|
});
|
|
7963
8412
|
|
|
8413
|
+
function PrivateDashboardContent() {
|
|
8414
|
+
const privateData = useQuery(api.privateData.get);
|
|
8415
|
+
|
|
8416
|
+
return (
|
|
8417
|
+
<div>
|
|
8418
|
+
<h1>Dashboard</h1>
|
|
8419
|
+
<p>privateData: {privateData?.message}</p>
|
|
8420
|
+
<UserMenu />
|
|
8421
|
+
</div>
|
|
8422
|
+
);
|
|
8423
|
+
}
|
|
8424
|
+
|
|
7964
8425
|
function RouteComponent() {
|
|
7965
8426
|
const [showSignIn, setShowSignIn] = useState(false);
|
|
7966
|
-
const privateData = useQuery(api.privateData.get);
|
|
7967
8427
|
|
|
7968
8428
|
return (
|
|
7969
8429
|
<>
|
|
7970
8430
|
<Authenticated>
|
|
7971
|
-
<
|
|
7972
|
-
<h1>Dashboard</h1>
|
|
7973
|
-
<p>privateData: {privateData?.message}</p>
|
|
7974
|
-
<UserMenu />
|
|
7975
|
-
</div>
|
|
8431
|
+
<PrivateDashboardContent />
|
|
7976
8432
|
</Authenticated>
|
|
7977
8433
|
<Unauthenticated>
|
|
7978
8434
|
{showSignIn ? (
|
|
@@ -8414,10 +8870,17 @@ declare namespace App {
|
|
|
8414
8870
|
}
|
|
8415
8871
|
}
|
|
8416
8872
|
`],
|
|
8417
|
-
["auth/better-auth/fullstack/astro/src/middleware.ts.hbs", `
|
|
8873
|
+
["auth/better-auth/fullstack/astro/src/middleware.ts.hbs", `{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
8874
|
+
import { createAuth } from "@{{projectName}}/auth";
|
|
8875
|
+
{{else}}
|
|
8876
|
+
import { auth } from "@{{projectName}}/auth";
|
|
8877
|
+
{{/if}}
|
|
8418
8878
|
import { defineMiddleware } from "astro:middleware";
|
|
8419
8879
|
|
|
8420
8880
|
export const onRequest = defineMiddleware(async (context, next) => {
|
|
8881
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
8882
|
+
const auth = createAuth();
|
|
8883
|
+
{{/if}}
|
|
8421
8884
|
const isAuthed = await auth.api.getSession({
|
|
8422
8885
|
headers: context.request.headers,
|
|
8423
8886
|
});
|
|
@@ -8433,34 +8896,72 @@ export const onRequest = defineMiddleware(async (context, next) => {
|
|
|
8433
8896
|
return next();
|
|
8434
8897
|
});
|
|
8435
8898
|
`],
|
|
8436
|
-
["auth/better-auth/fullstack/astro/src/pages/api/auth/[...all].ts.hbs", `
|
|
8899
|
+
["auth/better-auth/fullstack/astro/src/pages/api/auth/[...all].ts.hbs", `{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
8900
|
+
import { createAuth } from "@{{projectName}}/auth";
|
|
8901
|
+
{{else}}
|
|
8902
|
+
import { auth } from "@{{projectName}}/auth";
|
|
8903
|
+
{{/if}}
|
|
8437
8904
|
import type { APIRoute } from "astro";
|
|
8438
8905
|
|
|
8439
8906
|
export const ALL: APIRoute = async (ctx) => {
|
|
8907
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
8908
|
+
const auth = createAuth();
|
|
8909
|
+
{{/if}}
|
|
8440
8910
|
return auth.handler(ctx.request);
|
|
8441
8911
|
};
|
|
8442
8912
|
`],
|
|
8443
|
-
["auth/better-auth/fullstack/next/src/app/api/auth/[...all]/route.ts.hbs", `
|
|
8913
|
+
["auth/better-auth/fullstack/next/src/app/api/auth/[...all]/route.ts.hbs", `{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
8914
|
+
import { createAuth } from "@{{projectName}}/auth";
|
|
8915
|
+
{{else}}
|
|
8916
|
+
import { auth } from "@{{projectName}}/auth";
|
|
8917
|
+
{{/if}}
|
|
8444
8918
|
import { toNextJsHandler } from "better-auth/next-js";
|
|
8445
8919
|
|
|
8446
|
-
|
|
8920
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
8921
|
+
export async function GET(request: Request) {
|
|
8922
|
+
return toNextJsHandler(createAuth()).GET(request);
|
|
8923
|
+
}
|
|
8924
|
+
|
|
8925
|
+
export async function POST(request: Request) {
|
|
8926
|
+
return toNextJsHandler(createAuth()).POST(request);
|
|
8927
|
+
}
|
|
8928
|
+
{{else}}
|
|
8929
|
+
export const { GET, POST } = toNextJsHandler(auth);
|
|
8930
|
+
{{/if}}
|
|
8447
8931
|
`],
|
|
8448
|
-
["auth/better-auth/fullstack/nuxt/server/api/auth/[...all].ts.hbs", `
|
|
8932
|
+
["auth/better-auth/fullstack/nuxt/server/api/auth/[...all].ts.hbs", `{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
8933
|
+
import { createAuth } from "@{{projectName}}/auth";
|
|
8934
|
+
{{else}}
|
|
8935
|
+
import { auth } from "@{{projectName}}/auth";
|
|
8936
|
+
{{/if}}
|
|
8449
8937
|
|
|
8450
8938
|
export default defineEventHandler((event) => {
|
|
8939
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
8940
|
+
const auth = createAuth();
|
|
8941
|
+
{{/if}}
|
|
8451
8942
|
return auth.handler(toWebRequest(event));
|
|
8452
8943
|
});
|
|
8453
8944
|
`],
|
|
8454
|
-
["auth/better-auth/fullstack/tanstack-start/src/routes/api/auth/$.ts.hbs", `
|
|
8945
|
+
["auth/better-auth/fullstack/tanstack-start/src/routes/api/auth/$.ts.hbs", `{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
8946
|
+
import { createAuth } from '@{{projectName}}/auth'
|
|
8947
|
+
{{else}}
|
|
8948
|
+
import { auth } from '@{{projectName}}/auth'
|
|
8949
|
+
{{/if}}
|
|
8455
8950
|
import { createFileRoute } from '@tanstack/react-router'
|
|
8456
8951
|
|
|
8457
8952
|
export const Route = createFileRoute('/api/auth/$')({
|
|
8458
8953
|
server: {
|
|
8459
8954
|
handlers: {
|
|
8460
8955
|
GET: ({ request }) => {
|
|
8956
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
8957
|
+
const auth = createAuth()
|
|
8958
|
+
{{/if}}
|
|
8461
8959
|
return auth.handler(request)
|
|
8462
8960
|
},
|
|
8463
8961
|
POST: ({ request }) => {
|
|
8962
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
8963
|
+
const auth = createAuth()
|
|
8964
|
+
{{/if}}
|
|
8464
8965
|
return auth.handler(request)
|
|
8465
8966
|
},
|
|
8466
8967
|
},
|
|
@@ -10380,67 +10881,75 @@ import { env } from "@{{projectName}}/env/server";
|
|
|
10380
10881
|
import { polar, checkout, portal } from "@polar-sh/better-auth";
|
|
10381
10882
|
import { polarClient } from "./lib/payments";
|
|
10382
10883
|
{{/if}}
|
|
10383
|
-
import
|
|
10884
|
+
import { createPrismaClient } from "@{{projectName}}/db";
|
|
10885
|
+
|
|
10886
|
+
export function createAuth() {
|
|
10887
|
+
const prisma = createPrismaClient();
|
|
10384
10888
|
|
|
10385
|
-
|
|
10386
|
-
|
|
10889
|
+
return betterAuth({
|
|
10890
|
+
database: prismaAdapter(prisma, {
|
|
10387
10891
|
{{#if (eq database "postgres")}}provider: "postgresql",{{/if}}
|
|
10388
10892
|
{{#if (eq database "sqlite")}}provider: "sqlite",{{/if}}
|
|
10389
10893
|
{{#if (eq database "mysql")}}provider: "mysql",{{/if}}
|
|
10390
10894
|
{{#if (eq database "mongodb")}}provider: "mongodb",{{/if}}
|
|
10391
|
-
|
|
10895
|
+
}),
|
|
10392
10896
|
|
|
10393
|
-
|
|
10394
|
-
|
|
10897
|
+
trustedOrigins: [
|
|
10898
|
+
env.CORS_ORIGIN,
|
|
10395
10899
|
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
10396
|
-
|
|
10397
|
-
|
|
10398
|
-
|
|
10399
|
-
|
|
10400
|
-
|
|
10401
|
-
|
|
10402
|
-
|
|
10403
|
-
|
|
10404
|
-
|
|
10900
|
+
"{{projectName}}://",
|
|
10901
|
+
...(env.NODE_ENV === "development"
|
|
10902
|
+
? [
|
|
10903
|
+
"exp://",
|
|
10904
|
+
"exp://**",
|
|
10905
|
+
"exp://192.168.*.*:*/**",
|
|
10906
|
+
"http://localhost:8081",
|
|
10907
|
+
]
|
|
10908
|
+
: []),
|
|
10405
10909
|
{{/if}}
|
|
10406
|
-
|
|
10407
|
-
|
|
10408
|
-
|
|
10409
|
-
|
|
10410
|
-
|
|
10411
|
-
|
|
10910
|
+
],
|
|
10911
|
+
emailAndPassword: {
|
|
10912
|
+
enabled: true,
|
|
10913
|
+
},
|
|
10914
|
+
secret: env.BETTER_AUTH_SECRET,
|
|
10915
|
+
baseURL: env.BETTER_AUTH_URL,
|
|
10412
10916
|
{{#if (ne backend "self")}}
|
|
10413
|
-
|
|
10414
|
-
|
|
10415
|
-
|
|
10416
|
-
|
|
10417
|
-
|
|
10917
|
+
advanced: {
|
|
10918
|
+
defaultCookieAttributes: {
|
|
10919
|
+
sameSite: "none",
|
|
10920
|
+
secure: true,
|
|
10921
|
+
httpOnly: true,
|
|
10922
|
+
},
|
|
10418
10923
|
},
|
|
10419
|
-
},
|
|
10420
10924
|
{{/if}}
|
|
10421
|
-
|
|
10925
|
+
plugins: [
|
|
10422
10926
|
{{#if (eq payments "polar")}}
|
|
10423
|
-
|
|
10424
|
-
|
|
10425
|
-
|
|
10426
|
-
|
|
10427
|
-
|
|
10428
|
-
|
|
10429
|
-
|
|
10430
|
-
|
|
10431
|
-
|
|
10432
|
-
|
|
10433
|
-
|
|
10434
|
-
|
|
10435
|
-
|
|
10436
|
-
|
|
10437
|
-
|
|
10438
|
-
|
|
10439
|
-
|
|
10440
|
-
|
|
10927
|
+
polar({
|
|
10928
|
+
client: polarClient,
|
|
10929
|
+
createCustomerOnSignUp: true,
|
|
10930
|
+
enableCustomerPortal: true,
|
|
10931
|
+
use: [
|
|
10932
|
+
checkout({
|
|
10933
|
+
products: [
|
|
10934
|
+
{
|
|
10935
|
+
productId: "your-product-id",
|
|
10936
|
+
slug: "pro",
|
|
10937
|
+
},
|
|
10938
|
+
],
|
|
10939
|
+
successUrl: env.POLAR_SUCCESS_URL,
|
|
10940
|
+
authenticatedUsersOnly: true,
|
|
10941
|
+
}),
|
|
10942
|
+
portal(),
|
|
10943
|
+
],
|
|
10944
|
+
}),
|
|
10945
|
+
{{/if}}
|
|
10946
|
+
],
|
|
10947
|
+
});
|
|
10948
|
+
}
|
|
10949
|
+
|
|
10950
|
+
{{#if (and (ne runtime "workers") (ne serverDeploy "cloudflare") (or (ne backend "self") (ne webDeploy "cloudflare")))}}
|
|
10951
|
+
export const auth = createAuth();
|
|
10441
10952
|
{{/if}}
|
|
10442
|
-
],
|
|
10443
|
-
});
|
|
10444
10953
|
{{/if}}
|
|
10445
10954
|
|
|
10446
10955
|
{{#if (eq orm "drizzle")}}
|
|
@@ -10452,68 +10961,76 @@ import { env } from "@{{projectName}}/env/server";
|
|
|
10452
10961
|
import { polar, checkout, portal } from "@polar-sh/better-auth";
|
|
10453
10962
|
import { polarClient } from "./lib/payments";
|
|
10454
10963
|
{{/if}}
|
|
10455
|
-
import {
|
|
10964
|
+
import { createDb } from "@{{projectName}}/db";
|
|
10456
10965
|
import * as schema from "@{{projectName}}/db/schema/auth";
|
|
10457
10966
|
|
|
10458
10967
|
|
|
10459
|
-
export
|
|
10460
|
-
|
|
10968
|
+
export function createAuth() {
|
|
10969
|
+
const db = createDb();
|
|
10970
|
+
|
|
10971
|
+
return betterAuth({
|
|
10972
|
+
database: drizzleAdapter(db, {
|
|
10461
10973
|
{{#if (eq database "postgres")}}provider: "pg",{{/if}}
|
|
10462
10974
|
{{#if (eq database "sqlite")}}provider: "sqlite",{{/if}}
|
|
10463
10975
|
{{#if (eq database "mysql")}}provider: "mysql",{{/if}}
|
|
10464
|
-
|
|
10465
|
-
|
|
10466
|
-
|
|
10467
|
-
|
|
10976
|
+
schema: schema,
|
|
10977
|
+
}),
|
|
10978
|
+
trustedOrigins: [
|
|
10979
|
+
env.CORS_ORIGIN,
|
|
10468
10980
|
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
10469
|
-
|
|
10470
|
-
|
|
10471
|
-
|
|
10472
|
-
|
|
10473
|
-
|
|
10474
|
-
|
|
10475
|
-
|
|
10476
|
-
|
|
10477
|
-
|
|
10981
|
+
"{{projectName}}://",
|
|
10982
|
+
...(env.NODE_ENV === "development"
|
|
10983
|
+
? [
|
|
10984
|
+
"exp://",
|
|
10985
|
+
"exp://**",
|
|
10986
|
+
"exp://192.168.*.*:*/**",
|
|
10987
|
+
"http://localhost:8081",
|
|
10988
|
+
]
|
|
10989
|
+
: []),
|
|
10478
10990
|
{{/if}}
|
|
10479
|
-
|
|
10480
|
-
|
|
10481
|
-
|
|
10482
|
-
|
|
10483
|
-
|
|
10484
|
-
|
|
10991
|
+
],
|
|
10992
|
+
emailAndPassword: {
|
|
10993
|
+
enabled: true,
|
|
10994
|
+
},
|
|
10995
|
+
secret: env.BETTER_AUTH_SECRET,
|
|
10996
|
+
baseURL: env.BETTER_AUTH_URL,
|
|
10485
10997
|
{{#if (ne backend "self")}}
|
|
10486
|
-
|
|
10487
|
-
|
|
10488
|
-
|
|
10489
|
-
|
|
10490
|
-
|
|
10998
|
+
advanced: {
|
|
10999
|
+
defaultCookieAttributes: {
|
|
11000
|
+
sameSite: "none",
|
|
11001
|
+
secure: true,
|
|
11002
|
+
httpOnly: true,
|
|
11003
|
+
},
|
|
10491
11004
|
},
|
|
10492
|
-
},
|
|
10493
11005
|
{{/if}}
|
|
10494
|
-
|
|
11006
|
+
plugins: [
|
|
10495
11007
|
{{#if (eq payments "polar")}}
|
|
10496
|
-
|
|
10497
|
-
|
|
10498
|
-
|
|
10499
|
-
|
|
10500
|
-
|
|
10501
|
-
|
|
10502
|
-
|
|
10503
|
-
|
|
10504
|
-
|
|
10505
|
-
|
|
10506
|
-
|
|
10507
|
-
|
|
10508
|
-
|
|
10509
|
-
|
|
10510
|
-
|
|
10511
|
-
|
|
10512
|
-
|
|
10513
|
-
|
|
11008
|
+
polar({
|
|
11009
|
+
client: polarClient,
|
|
11010
|
+
createCustomerOnSignUp: true,
|
|
11011
|
+
enableCustomerPortal: true,
|
|
11012
|
+
use: [
|
|
11013
|
+
checkout({
|
|
11014
|
+
products: [
|
|
11015
|
+
{
|
|
11016
|
+
productId: "your-product-id",
|
|
11017
|
+
slug: "pro",
|
|
11018
|
+
},
|
|
11019
|
+
],
|
|
11020
|
+
successUrl: env.POLAR_SUCCESS_URL,
|
|
11021
|
+
authenticatedUsersOnly: true,
|
|
11022
|
+
}),
|
|
11023
|
+
portal(),
|
|
11024
|
+
],
|
|
11025
|
+
}),
|
|
11026
|
+
{{/if}}
|
|
11027
|
+
],
|
|
11028
|
+
});
|
|
11029
|
+
}
|
|
11030
|
+
|
|
11031
|
+
{{#if (and (ne runtime "workers") (ne serverDeploy "cloudflare") (or (ne backend "self") (ne webDeploy "cloudflare")))}}
|
|
11032
|
+
export const auth = createAuth();
|
|
10514
11033
|
{{/if}}
|
|
10515
|
-
],
|
|
10516
|
-
});
|
|
10517
11034
|
{{/if}}
|
|
10518
11035
|
|
|
10519
11036
|
{{#if (eq runtime "workers")}}
|
|
@@ -10524,79 +11041,83 @@ import { env } from "@{{projectName}}/env/server";
|
|
|
10524
11041
|
import { polar, checkout, portal } from "@polar-sh/better-auth";
|
|
10525
11042
|
import { polarClient } from "./lib/payments";
|
|
10526
11043
|
{{/if}}
|
|
10527
|
-
import {
|
|
11044
|
+
import { createDb } from "@{{projectName}}/db";
|
|
10528
11045
|
import * as schema from "@{{projectName}}/db/schema/auth";
|
|
10529
11046
|
|
|
10530
11047
|
|
|
10531
|
-
export
|
|
10532
|
-
|
|
11048
|
+
export function createAuth() {
|
|
11049
|
+
const db = createDb();
|
|
11050
|
+
|
|
11051
|
+
return betterAuth({
|
|
11052
|
+
database: drizzleAdapter(db, {
|
|
10533
11053
|
{{#if (eq database "postgres")}}provider: "pg",{{/if}}
|
|
10534
11054
|
{{#if (eq database "sqlite")}}provider: "sqlite",{{/if}}
|
|
10535
11055
|
{{#if (eq database "mysql")}}provider: "mysql",{{/if}}
|
|
10536
|
-
|
|
10537
|
-
|
|
10538
|
-
|
|
10539
|
-
|
|
11056
|
+
schema: schema,
|
|
11057
|
+
}),
|
|
11058
|
+
trustedOrigins: [
|
|
11059
|
+
env.CORS_ORIGIN,
|
|
10540
11060
|
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
10541
|
-
|
|
10542
|
-
|
|
10543
|
-
|
|
10544
|
-
|
|
10545
|
-
|
|
10546
|
-
|
|
10547
|
-
|
|
10548
|
-
|
|
10549
|
-
|
|
11061
|
+
"{{projectName}}://",
|
|
11062
|
+
...(env.NODE_ENV === "development"
|
|
11063
|
+
? [
|
|
11064
|
+
"exp://",
|
|
11065
|
+
"exp://**",
|
|
11066
|
+
"exp://192.168.*.*:*/**",
|
|
11067
|
+
"http://localhost:8081",
|
|
11068
|
+
]
|
|
11069
|
+
: []),
|
|
10550
11070
|
{{/if}}
|
|
10551
|
-
|
|
10552
|
-
|
|
10553
|
-
|
|
10554
|
-
},
|
|
10555
|
-
// uncomment cookieCache setting when ready to deploy to Cloudflare using *.workers.dev domains
|
|
10556
|
-
// session: {
|
|
10557
|
-
// cookieCache: {
|
|
10558
|
-
// enabled: true,
|
|
10559
|
-
// maxAge: 60,
|
|
10560
|
-
// },
|
|
10561
|
-
// },
|
|
10562
|
-
secret: env.BETTER_AUTH_SECRET,
|
|
10563
|
-
baseURL: env.BETTER_AUTH_URL,
|
|
10564
|
-
advanced: {
|
|
10565
|
-
defaultCookieAttributes: {
|
|
10566
|
-
sameSite: "none",
|
|
10567
|
-
secure: true,
|
|
10568
|
-
httpOnly: true,
|
|
11071
|
+
],
|
|
11072
|
+
emailAndPassword: {
|
|
11073
|
+
enabled: true,
|
|
10569
11074
|
},
|
|
10570
|
-
// uncomment
|
|
10571
|
-
//
|
|
10572
|
-
//
|
|
10573
|
-
//
|
|
10574
|
-
//
|
|
11075
|
+
// uncomment cookieCache setting when ready to deploy to Cloudflare using *.workers.dev domains
|
|
11076
|
+
// session: {
|
|
11077
|
+
// cookieCache: {
|
|
11078
|
+
// enabled: true,
|
|
11079
|
+
// maxAge: 60,
|
|
11080
|
+
// },
|
|
10575
11081
|
// },
|
|
10576
|
-
|
|
11082
|
+
secret: env.BETTER_AUTH_SECRET,
|
|
11083
|
+
baseURL: env.BETTER_AUTH_URL,
|
|
11084
|
+
advanced: {
|
|
11085
|
+
defaultCookieAttributes: {
|
|
11086
|
+
sameSite: "none",
|
|
11087
|
+
secure: true,
|
|
11088
|
+
httpOnly: true,
|
|
11089
|
+
},
|
|
11090
|
+
// uncomment crossSubDomainCookies setting when ready to deploy and replace <your-workers-subdomain> with your actual workers subdomain
|
|
11091
|
+
// https://developers.cloudflare.com/workers/wrangler/configuration/#workersdev
|
|
11092
|
+
// crossSubDomainCookies: {
|
|
11093
|
+
// enabled: true,
|
|
11094
|
+
// domain: "<your-workers-subdomain>",
|
|
11095
|
+
// },
|
|
11096
|
+
},
|
|
10577
11097
|
{{#if (eq payments "polar")}}
|
|
10578
|
-
|
|
10579
|
-
|
|
10580
|
-
|
|
10581
|
-
|
|
10582
|
-
|
|
10583
|
-
|
|
10584
|
-
|
|
10585
|
-
|
|
10586
|
-
|
|
10587
|
-
|
|
10588
|
-
|
|
10589
|
-
|
|
10590
|
-
|
|
10591
|
-
|
|
10592
|
-
|
|
10593
|
-
|
|
10594
|
-
|
|
10595
|
-
|
|
10596
|
-
|
|
10597
|
-
|
|
11098
|
+
plugins: [
|
|
11099
|
+
polar({
|
|
11100
|
+
client: polarClient,
|
|
11101
|
+
createCustomerOnSignUp: true,
|
|
11102
|
+
enableCustomerPortal: true,
|
|
11103
|
+
use: [
|
|
11104
|
+
checkout({
|
|
11105
|
+
products: [
|
|
11106
|
+
{
|
|
11107
|
+
productId: "your-product-id",
|
|
11108
|
+
slug: "pro",
|
|
11109
|
+
},
|
|
11110
|
+
],
|
|
11111
|
+
successUrl: env.POLAR_SUCCESS_URL,
|
|
11112
|
+
authenticatedUsersOnly: true,
|
|
11113
|
+
}),
|
|
11114
|
+
portal(),
|
|
11115
|
+
],
|
|
11116
|
+
}),
|
|
11117
|
+
],
|
|
10598
11118
|
{{/if}}
|
|
10599
|
-
});
|
|
11119
|
+
});
|
|
11120
|
+
}
|
|
10600
11121
|
{{/if}}
|
|
10601
11122
|
{{/if}}
|
|
10602
11123
|
|
|
@@ -10610,59 +11131,65 @@ import { polarClient } from "./lib/payments";
|
|
|
10610
11131
|
{{/if}}
|
|
10611
11132
|
import { client } from "@{{projectName}}/db";
|
|
10612
11133
|
|
|
10613
|
-
export
|
|
10614
|
-
|
|
10615
|
-
|
|
10616
|
-
|
|
11134
|
+
export function createAuth() {
|
|
11135
|
+
return betterAuth({
|
|
11136
|
+
database: mongodbAdapter(client),
|
|
11137
|
+
trustedOrigins: [
|
|
11138
|
+
env.CORS_ORIGIN,
|
|
10617
11139
|
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
10618
|
-
|
|
10619
|
-
|
|
10620
|
-
|
|
10621
|
-
|
|
10622
|
-
|
|
10623
|
-
|
|
10624
|
-
|
|
10625
|
-
|
|
10626
|
-
|
|
11140
|
+
"{{projectName}}://",
|
|
11141
|
+
...(env.NODE_ENV === "development"
|
|
11142
|
+
? [
|
|
11143
|
+
"exp://",
|
|
11144
|
+
"exp://**",
|
|
11145
|
+
"exp://192.168.*.*:*/**",
|
|
11146
|
+
"http://localhost:8081",
|
|
11147
|
+
]
|
|
11148
|
+
: []),
|
|
10627
11149
|
{{/if}}
|
|
10628
|
-
|
|
10629
|
-
|
|
10630
|
-
|
|
10631
|
-
|
|
10632
|
-
|
|
10633
|
-
|
|
11150
|
+
],
|
|
11151
|
+
emailAndPassword: {
|
|
11152
|
+
enabled: true,
|
|
11153
|
+
},
|
|
11154
|
+
secret: env.BETTER_AUTH_SECRET,
|
|
11155
|
+
baseURL: env.BETTER_AUTH_URL,
|
|
10634
11156
|
{{#if (ne backend "self")}}
|
|
10635
|
-
|
|
10636
|
-
|
|
10637
|
-
|
|
10638
|
-
|
|
10639
|
-
|
|
11157
|
+
advanced: {
|
|
11158
|
+
defaultCookieAttributes: {
|
|
11159
|
+
sameSite: "none",
|
|
11160
|
+
secure: true,
|
|
11161
|
+
httpOnly: true,
|
|
11162
|
+
},
|
|
10640
11163
|
},
|
|
10641
|
-
},
|
|
10642
11164
|
{{/if}}
|
|
10643
11165
|
{{#if (eq payments "polar")}}
|
|
10644
|
-
|
|
10645
|
-
|
|
10646
|
-
|
|
10647
|
-
|
|
10648
|
-
|
|
10649
|
-
|
|
10650
|
-
|
|
10651
|
-
|
|
10652
|
-
|
|
10653
|
-
|
|
10654
|
-
|
|
10655
|
-
|
|
10656
|
-
|
|
10657
|
-
|
|
10658
|
-
|
|
10659
|
-
|
|
10660
|
-
|
|
10661
|
-
|
|
10662
|
-
|
|
10663
|
-
|
|
11166
|
+
plugins: [
|
|
11167
|
+
polar({
|
|
11168
|
+
client: polarClient,
|
|
11169
|
+
createCustomerOnSignUp: true,
|
|
11170
|
+
enableCustomerPortal: true,
|
|
11171
|
+
use: [
|
|
11172
|
+
checkout({
|
|
11173
|
+
products: [
|
|
11174
|
+
{
|
|
11175
|
+
productId: "your-product-id",
|
|
11176
|
+
slug: "pro",
|
|
11177
|
+
},
|
|
11178
|
+
],
|
|
11179
|
+
successUrl: env.POLAR_SUCCESS_URL,
|
|
11180
|
+
authenticatedUsersOnly: true,
|
|
11181
|
+
}),
|
|
11182
|
+
portal(),
|
|
11183
|
+
],
|
|
11184
|
+
}),
|
|
11185
|
+
],
|
|
11186
|
+
{{/if}}
|
|
11187
|
+
});
|
|
11188
|
+
}
|
|
11189
|
+
|
|
11190
|
+
{{#if (and (ne runtime "workers") (ne serverDeploy "cloudflare") (or (ne backend "self") (ne webDeploy "cloudflare")))}}
|
|
11191
|
+
export const auth = createAuth();
|
|
10664
11192
|
{{/if}}
|
|
10665
|
-
});
|
|
10666
11193
|
{{/if}}
|
|
10667
11194
|
|
|
10668
11195
|
{{#if (eq orm "none")}}
|
|
@@ -10674,59 +11201,65 @@ import { polarClient } from "./lib/payments";
|
|
|
10674
11201
|
{{/if}}
|
|
10675
11202
|
|
|
10676
11203
|
|
|
10677
|
-
export
|
|
10678
|
-
|
|
10679
|
-
|
|
10680
|
-
|
|
11204
|
+
export function createAuth() {
|
|
11205
|
+
return betterAuth({
|
|
11206
|
+
database: "", // Invalid configuration
|
|
11207
|
+
trustedOrigins: [
|
|
11208
|
+
env.CORS_ORIGIN,
|
|
10681
11209
|
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
10682
|
-
|
|
10683
|
-
|
|
10684
|
-
|
|
10685
|
-
|
|
10686
|
-
|
|
10687
|
-
|
|
10688
|
-
|
|
10689
|
-
|
|
10690
|
-
|
|
11210
|
+
"{{projectName}}://",
|
|
11211
|
+
...(env.NODE_ENV === "development"
|
|
11212
|
+
? [
|
|
11213
|
+
"exp://",
|
|
11214
|
+
"exp://**",
|
|
11215
|
+
"exp://192.168.*.*:*/**",
|
|
11216
|
+
"http://localhost:8081",
|
|
11217
|
+
]
|
|
11218
|
+
: []),
|
|
10691
11219
|
{{/if}}
|
|
10692
|
-
|
|
10693
|
-
|
|
10694
|
-
|
|
10695
|
-
|
|
10696
|
-
|
|
10697
|
-
|
|
11220
|
+
],
|
|
11221
|
+
emailAndPassword: {
|
|
11222
|
+
enabled: true,
|
|
11223
|
+
},
|
|
11224
|
+
secret: env.BETTER_AUTH_SECRET,
|
|
11225
|
+
baseURL: env.BETTER_AUTH_URL,
|
|
10698
11226
|
{{#if (ne backend "self")}}
|
|
10699
|
-
|
|
10700
|
-
|
|
10701
|
-
|
|
10702
|
-
|
|
10703
|
-
|
|
11227
|
+
advanced: {
|
|
11228
|
+
defaultCookieAttributes: {
|
|
11229
|
+
sameSite: "none",
|
|
11230
|
+
secure: true,
|
|
11231
|
+
httpOnly: true,
|
|
11232
|
+
},
|
|
10704
11233
|
},
|
|
10705
|
-
},
|
|
10706
11234
|
{{/if}}
|
|
10707
11235
|
{{#if (eq payments "polar")}}
|
|
10708
|
-
|
|
10709
|
-
|
|
10710
|
-
|
|
10711
|
-
|
|
10712
|
-
|
|
10713
|
-
|
|
10714
|
-
|
|
10715
|
-
|
|
10716
|
-
|
|
10717
|
-
|
|
10718
|
-
|
|
10719
|
-
|
|
10720
|
-
|
|
10721
|
-
|
|
10722
|
-
|
|
10723
|
-
|
|
10724
|
-
|
|
10725
|
-
|
|
10726
|
-
|
|
10727
|
-
|
|
11236
|
+
plugins: [
|
|
11237
|
+
polar({
|
|
11238
|
+
client: polarClient,
|
|
11239
|
+
createCustomerOnSignUp: true,
|
|
11240
|
+
enableCustomerPortal: true,
|
|
11241
|
+
use: [
|
|
11242
|
+
checkout({
|
|
11243
|
+
products: [
|
|
11244
|
+
{
|
|
11245
|
+
productId: "your-product-id",
|
|
11246
|
+
slug: "pro",
|
|
11247
|
+
},
|
|
11248
|
+
],
|
|
11249
|
+
successUrl: env.POLAR_SUCCESS_URL,
|
|
11250
|
+
authenticatedUsersOnly: true,
|
|
11251
|
+
}),
|
|
11252
|
+
portal(),
|
|
11253
|
+
],
|
|
11254
|
+
}),
|
|
11255
|
+
],
|
|
11256
|
+
{{/if}}
|
|
11257
|
+
});
|
|
11258
|
+
}
|
|
11259
|
+
|
|
11260
|
+
{{#if (and (ne runtime "workers") (ne serverDeploy "cloudflare") (or (ne backend "self") (ne webDeploy "cloudflare")))}}
|
|
11261
|
+
export const auth = createAuth();
|
|
10728
11262
|
{{/if}}
|
|
10729
|
-
});
|
|
10730
11263
|
{{/if}}
|
|
10731
11264
|
`],
|
|
10732
11265
|
["auth/better-auth/server/base/tsconfig.json.hbs", `{
|
|
@@ -12203,13 +12736,19 @@ export default function Dashboard({
|
|
|
12203
12736
|
import Dashboard from "./dashboard";
|
|
12204
12737
|
import { headers } from "next/headers";
|
|
12205
12738
|
{{#if (eq backend "self")}}
|
|
12739
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
12740
|
+
import { createAuth } from "@{{projectName}}/auth";
|
|
12741
|
+
{{else}}
|
|
12206
12742
|
import { auth } from "@{{projectName}}/auth";
|
|
12207
12743
|
{{/if}}
|
|
12744
|
+
{{/if}}
|
|
12745
|
+
{{#if (or (ne backend "self") (eq payments "polar"))}}
|
|
12208
12746
|
import { authClient } from "@/lib/auth-client";
|
|
12747
|
+
{{/if}}
|
|
12209
12748
|
|
|
12210
12749
|
export default async function DashboardPage() {
|
|
12211
12750
|
{{#if (eq backend "self")}}
|
|
12212
|
-
const session = await auth.api.getSession({
|
|
12751
|
+
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth(){{else}}auth{{/if}}.api.getSession({
|
|
12213
12752
|
headers: await headers(),
|
|
12214
12753
|
});
|
|
12215
12754
|
{{else}}
|
|
@@ -13893,12 +14432,16 @@ export const getUser = createServerFn({ method: "GET" }).middleware([authMiddlew
|
|
|
13893
14432
|
return context.session
|
|
13894
14433
|
})`],
|
|
13895
14434
|
["auth/better-auth/web/react/tanstack-start/src/middleware/auth.ts.hbs", `{{#if (eq backend "self")}}
|
|
14435
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
14436
|
+
import { createAuth } from "@{{projectName}}/auth";
|
|
14437
|
+
{{else}}
|
|
13896
14438
|
import { auth } from "@{{projectName}}/auth";
|
|
14439
|
+
{{/if}}
|
|
13897
14440
|
import { createMiddleware } from "@tanstack/react-start";
|
|
13898
14441
|
|
|
13899
14442
|
|
|
13900
14443
|
export const authMiddleware = createMiddleware().server(async ({ next, request }) => {
|
|
13901
|
-
const session = await auth.api.getSession({
|
|
14444
|
+
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth(){{else}}auth{{/if}}.api.getSession({
|
|
13902
14445
|
headers: request.headers,
|
|
13903
14446
|
})
|
|
13904
14447
|
return next({
|
|
@@ -17101,8 +17644,12 @@ import { createContext } from "@{{projectName}}/api/context";
|
|
|
17101
17644
|
import { appRouter } from "@{{projectName}}/api/routers/index";
|
|
17102
17645
|
{{/if}}
|
|
17103
17646
|
{{#if (eq auth "better-auth")}}
|
|
17647
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
17648
|
+
import { createAuth } from "@{{projectName}}/auth";
|
|
17649
|
+
{{else}}
|
|
17104
17650
|
import { auth } from "@{{projectName}}/auth";
|
|
17105
17651
|
{{/if}}
|
|
17652
|
+
{{/if}}
|
|
17106
17653
|
import { Hono } from "hono";
|
|
17107
17654
|
import { cors } from "hono/cors";
|
|
17108
17655
|
import { logger } from "hono/logger";
|
|
@@ -17135,7 +17682,16 @@ app.use(
|
|
|
17135
17682
|
);
|
|
17136
17683
|
|
|
17137
17684
|
{{#if (eq auth "better-auth")}}
|
|
17138
|
-
app.on(
|
|
17685
|
+
app.on(
|
|
17686
|
+
["POST", "GET"],
|
|
17687
|
+
"/api/auth/*",
|
|
17688
|
+
(c) =>
|
|
17689
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
17690
|
+
createAuth().handler(c.req.raw)
|
|
17691
|
+
{{else}}
|
|
17692
|
+
auth.handler(c.req.raw)
|
|
17693
|
+
{{/if}}
|
|
17694
|
+
);
|
|
17139
17695
|
{{/if}}
|
|
17140
17696
|
|
|
17141
17697
|
{{#if (eq api "orpc")}}
|
|
@@ -17490,23 +18046,31 @@ import * as schema from "./schema";
|
|
|
17490
18046
|
{{#if (eq dbSetup "planetscale")}}
|
|
17491
18047
|
import { drizzle } from "drizzle-orm/planetscale-serverless";
|
|
17492
18048
|
|
|
17493
|
-
export
|
|
17494
|
-
|
|
17495
|
-
|
|
17496
|
-
|
|
17497
|
-
|
|
17498
|
-
|
|
17499
|
-
|
|
17500
|
-
|
|
18049
|
+
export function createDb() {
|
|
18050
|
+
return drizzle({
|
|
18051
|
+
connection: {
|
|
18052
|
+
host: env.DATABASE_HOST,
|
|
18053
|
+
username: env.DATABASE_USERNAME,
|
|
18054
|
+
password: env.DATABASE_PASSWORD,
|
|
18055
|
+
},
|
|
18056
|
+
schema,
|
|
18057
|
+
});
|
|
18058
|
+
}
|
|
17501
18059
|
{{else}}
|
|
17502
18060
|
import { drizzle } from "drizzle-orm/mysql2";
|
|
17503
18061
|
|
|
17504
|
-
export
|
|
17505
|
-
|
|
17506
|
-
|
|
17507
|
-
|
|
17508
|
-
|
|
17509
|
-
|
|
18062
|
+
export function createDb() {
|
|
18063
|
+
return drizzle({
|
|
18064
|
+
connection: {
|
|
18065
|
+
uri: env.DATABASE_URL,
|
|
18066
|
+
},
|
|
18067
|
+
schema,
|
|
18068
|
+
});
|
|
18069
|
+
}
|
|
18070
|
+
{{/if}}
|
|
18071
|
+
|
|
18072
|
+
{{#if (and (ne serverDeploy "cloudflare") (or (ne backend "self") (ne webDeploy "cloudflare")))}}
|
|
18073
|
+
export const db = createDb();
|
|
17510
18074
|
{{/if}}
|
|
17511
18075
|
{{/if}}
|
|
17512
18076
|
|
|
@@ -17517,24 +18081,28 @@ import * as schema from "./schema";
|
|
|
17517
18081
|
import { drizzle } from "drizzle-orm/planetscale-serverless";
|
|
17518
18082
|
import { env } from "@{{projectName}}/env/server";
|
|
17519
18083
|
|
|
17520
|
-
export
|
|
17521
|
-
|
|
17522
|
-
|
|
17523
|
-
|
|
17524
|
-
|
|
17525
|
-
|
|
17526
|
-
|
|
17527
|
-
|
|
18084
|
+
export function createDb() {
|
|
18085
|
+
return drizzle({
|
|
18086
|
+
connection: {
|
|
18087
|
+
host: env.DATABASE_HOST,
|
|
18088
|
+
username: env.DATABASE_USERNAME,
|
|
18089
|
+
password: env.DATABASE_PASSWORD,
|
|
18090
|
+
},
|
|
18091
|
+
schema,
|
|
18092
|
+
});
|
|
18093
|
+
}
|
|
17528
18094
|
{{else}}
|
|
17529
18095
|
import { drizzle } from "drizzle-orm/mysql2";
|
|
17530
18096
|
import { env } from "@{{projectName}}/env/server";
|
|
17531
18097
|
|
|
17532
|
-
export
|
|
17533
|
-
|
|
17534
|
-
|
|
17535
|
-
|
|
17536
|
-
|
|
17537
|
-
|
|
18098
|
+
export function createDb() {
|
|
18099
|
+
return drizzle({
|
|
18100
|
+
connection: {
|
|
18101
|
+
uri: env.DATABASE_URL,
|
|
18102
|
+
},
|
|
18103
|
+
schema,
|
|
18104
|
+
});
|
|
18105
|
+
}
|
|
17538
18106
|
{{/if}}
|
|
17539
18107
|
{{/if}}
|
|
17540
18108
|
`],
|
|
@@ -17566,12 +18134,32 @@ import * as schema from "./schema";
|
|
|
17566
18134
|
import { neon } from '@neondatabase/serverless';
|
|
17567
18135
|
import { drizzle } from 'drizzle-orm/neon-http';
|
|
17568
18136
|
|
|
17569
|
-
|
|
17570
|
-
|
|
18137
|
+
export function createDb() {
|
|
18138
|
+
const sql = neon(env.DATABASE_URL);
|
|
18139
|
+
return drizzle(sql, { schema });
|
|
18140
|
+
}
|
|
17571
18141
|
{{else}}
|
|
17572
18142
|
import { drizzle } from "drizzle-orm/node-postgres";
|
|
18143
|
+
{{#if (and (eq backend "self") (eq webDeploy "cloudflare"))}}
|
|
18144
|
+
import { Pool } from "pg";
|
|
18145
|
+
{{/if}}
|
|
18146
|
+
|
|
18147
|
+
export function createDb() {
|
|
18148
|
+
{{#if (and (eq backend "self") (eq webDeploy "cloudflare"))}}
|
|
18149
|
+
const pool = new Pool({
|
|
18150
|
+
connectionString: env.DATABASE_URL,
|
|
18151
|
+
maxUses: 1,
|
|
18152
|
+
});
|
|
18153
|
+
|
|
18154
|
+
return drizzle({ client: pool, schema });
|
|
18155
|
+
{{else}}
|
|
18156
|
+
return drizzle(env.DATABASE_URL, { schema });
|
|
18157
|
+
{{/if}}
|
|
18158
|
+
}
|
|
18159
|
+
{{/if}}
|
|
17573
18160
|
|
|
17574
|
-
|
|
18161
|
+
{{#if (and (ne serverDeploy "cloudflare") (or (ne backend "self") (ne webDeploy "cloudflare")))}}
|
|
18162
|
+
export const db = createDb();
|
|
17575
18163
|
{{/if}}
|
|
17576
18164
|
{{/if}}
|
|
17577
18165
|
|
|
@@ -17583,15 +18171,26 @@ import { neon } from '@neondatabase/serverless';
|
|
|
17583
18171
|
import { drizzle } from 'drizzle-orm/neon-http';
|
|
17584
18172
|
import { env } from "@{{projectName}}/env/server";
|
|
17585
18173
|
|
|
17586
|
-
|
|
17587
|
-
|
|
18174
|
+
export function createDb() {
|
|
18175
|
+
const sql = neon(env.DATABASE_URL || "");
|
|
18176
|
+
return drizzle(sql, { schema });
|
|
18177
|
+
}
|
|
17588
18178
|
{{else}}
|
|
17589
18179
|
import { drizzle } from "drizzle-orm/node-postgres";
|
|
17590
18180
|
import { env } from "@{{projectName}}/env/server";
|
|
18181
|
+
import { Pool } from "pg";
|
|
17591
18182
|
|
|
17592
|
-
export
|
|
18183
|
+
export function createDb() {
|
|
18184
|
+
const pool = new Pool({
|
|
18185
|
+
connectionString: env.DATABASE_URL || "",
|
|
18186
|
+
maxUses: 1,
|
|
18187
|
+
});
|
|
18188
|
+
|
|
18189
|
+
return drizzle({ client: pool, schema });
|
|
18190
|
+
}
|
|
17593
18191
|
{{/if}}
|
|
17594
|
-
{{/if}}
|
|
18192
|
+
{{/if}}
|
|
18193
|
+
`],
|
|
17595
18194
|
["db/drizzle/sqlite/drizzle.config.ts.hbs", `import { defineConfig } from "drizzle-kit";
|
|
17596
18195
|
import dotenv from "dotenv";
|
|
17597
18196
|
|
|
@@ -17621,44 +18220,50 @@ export default defineConfig({
|
|
|
17621
18220
|
{{/if}}
|
|
17622
18221
|
});
|
|
17623
18222
|
`],
|
|
17624
|
-
["db/drizzle/sqlite/src/index.ts.hbs", `{{#if (
|
|
18223
|
+
["db/drizzle/sqlite/src/index.ts.hbs", `{{#if (eq dbSetup "d1")}}
|
|
18224
|
+
import * as schema from "./schema";
|
|
18225
|
+
import { drizzle } from "drizzle-orm/d1";
|
|
18226
|
+
import { env } from "@{{projectName}}/env/server";
|
|
18227
|
+
|
|
18228
|
+
export function createDb() {
|
|
18229
|
+
return drizzle(env.DB, { schema });
|
|
18230
|
+
}
|
|
18231
|
+
{{else if (or (eq runtime "bun") (eq runtime "node") (eq runtime "none"))}}
|
|
17625
18232
|
import { env } from "@{{projectName}}/env/server";
|
|
17626
18233
|
import * as schema from "./schema";
|
|
17627
18234
|
import { drizzle } from "drizzle-orm/libsql";
|
|
17628
18235
|
import { createClient } from "@libsql/client";
|
|
17629
18236
|
|
|
17630
|
-
|
|
17631
|
-
|
|
18237
|
+
export function createDb() {
|
|
18238
|
+
const client = createClient({
|
|
18239
|
+
url: env.DATABASE_URL,
|
|
17632
18240
|
{{#if (eq dbSetup "turso")}}
|
|
17633
|
-
|
|
18241
|
+
authToken: env.DATABASE_AUTH_TOKEN,
|
|
17634
18242
|
{{/if}}
|
|
17635
|
-
});
|
|
18243
|
+
});
|
|
17636
18244
|
|
|
17637
|
-
|
|
17638
|
-
|
|
18245
|
+
return drizzle({ client, schema });
|
|
18246
|
+
}
|
|
17639
18247
|
|
|
17640
|
-
{{#if (
|
|
18248
|
+
{{#if (and (ne serverDeploy "cloudflare") (or (ne backend "self") (ne webDeploy "cloudflare")))}}
|
|
18249
|
+
export const db = createDb();
|
|
18250
|
+
{{/if}}
|
|
18251
|
+
{{else if (eq runtime "workers")}}
|
|
17641
18252
|
import * as schema from "./schema";
|
|
17642
|
-
|
|
17643
|
-
{{#if (eq dbSetup "d1")}}
|
|
17644
|
-
import { drizzle } from "drizzle-orm/d1";
|
|
17645
|
-
import { env } from "@{{projectName}}/env/server";
|
|
17646
|
-
|
|
17647
|
-
export const db = drizzle(env.DB, { schema });
|
|
17648
|
-
{{else}}
|
|
17649
18253
|
import { drizzle } from "drizzle-orm/libsql";
|
|
17650
18254
|
import { env } from "@{{projectName}}/env/server";
|
|
17651
18255
|
import { createClient } from "@libsql/client";
|
|
17652
18256
|
|
|
17653
|
-
|
|
17654
|
-
|
|
18257
|
+
export function createDb() {
|
|
18258
|
+
const client = createClient({
|
|
18259
|
+
url: env.DATABASE_URL || "",
|
|
17655
18260
|
{{#if (eq dbSetup "turso")}}
|
|
17656
|
-
|
|
18261
|
+
authToken: env.DATABASE_AUTH_TOKEN,
|
|
17657
18262
|
{{/if}}
|
|
17658
|
-
});
|
|
18263
|
+
});
|
|
17659
18264
|
|
|
17660
|
-
|
|
17661
|
-
|
|
18265
|
+
return drizzle({ client, schema });
|
|
18266
|
+
}
|
|
17662
18267
|
{{/if}}
|
|
17663
18268
|
`],
|
|
17664
18269
|
["db/mongoose/mongodb/src/index.ts.hbs", `import mongoose from "mongoose";
|
|
@@ -17766,26 +18371,28 @@ import { env } from "@{{projectName}}/env/server";
|
|
|
17766
18371
|
{{#if (eq dbSetup "planetscale")}}
|
|
17767
18372
|
import { PrismaPlanetScale } from "@prisma/adapter-planetscale";
|
|
17768
18373
|
|
|
17769
|
-
|
|
17770
|
-
const
|
|
18374
|
+
export function createPrismaClient() {
|
|
18375
|
+
const adapter = new PrismaPlanetScale({ url: env.DATABASE_URL });
|
|
18376
|
+
return new PrismaClient({ adapter });
|
|
18377
|
+
}
|
|
17771
18378
|
{{else}}
|
|
17772
18379
|
import { PrismaMariaDb } from "@prisma/adapter-mariadb";
|
|
17773
18380
|
|
|
17774
|
-
|
|
17775
|
-
const
|
|
17776
|
-
const
|
|
17777
|
-
|
|
17778
|
-
|
|
17779
|
-
|
|
17780
|
-
|
|
17781
|
-
|
|
17782
|
-
|
|
18381
|
+
export function createPrismaClient() {
|
|
18382
|
+
const databaseUrl: string = env.DATABASE_URL;
|
|
18383
|
+
const url: URL = new URL(databaseUrl);
|
|
18384
|
+
const connectionConfig = {
|
|
18385
|
+
host: url.hostname,
|
|
18386
|
+
port: parseInt(url.port || "3306"),
|
|
18387
|
+
user: url.username,
|
|
18388
|
+
password: url.password,
|
|
18389
|
+
database: url.pathname.slice(1),
|
|
18390
|
+
};
|
|
17783
18391
|
|
|
17784
|
-
const adapter = new PrismaMariaDb(connectionConfig);
|
|
17785
|
-
|
|
18392
|
+
const adapter = new PrismaMariaDb(connectionConfig);
|
|
18393
|
+
return new PrismaClient({ adapter });
|
|
18394
|
+
}
|
|
17786
18395
|
{{/if}}
|
|
17787
|
-
|
|
17788
|
-
export default prisma;
|
|
17789
18396
|
{{else}}
|
|
17790
18397
|
import { PrismaClient } from "../prisma/generated/client";
|
|
17791
18398
|
import { env } from "@{{projectName}}/env/server";
|
|
@@ -17793,27 +18400,35 @@ import { env } from "@{{projectName}}/env/server";
|
|
|
17793
18400
|
{{#if (eq dbSetup "planetscale")}}
|
|
17794
18401
|
import { PrismaPlanetScale } from "@prisma/adapter-planetscale";
|
|
17795
18402
|
|
|
17796
|
-
|
|
17797
|
-
const
|
|
18403
|
+
export function createPrismaClient() {
|
|
18404
|
+
const adapter = new PrismaPlanetScale({ url: env.DATABASE_URL });
|
|
18405
|
+
return new PrismaClient({ adapter });
|
|
18406
|
+
}
|
|
17798
18407
|
{{else}}
|
|
17799
18408
|
import { PrismaMariaDb } from "@prisma/adapter-mariadb";
|
|
17800
18409
|
|
|
17801
|
-
|
|
17802
|
-
const
|
|
17803
|
-
const
|
|
17804
|
-
|
|
17805
|
-
|
|
17806
|
-
|
|
17807
|
-
|
|
17808
|
-
|
|
17809
|
-
|
|
18410
|
+
export function createPrismaClient() {
|
|
18411
|
+
const databaseUrl: string = env.DATABASE_URL;
|
|
18412
|
+
const url: URL = new URL(databaseUrl);
|
|
18413
|
+
const connectionConfig = {
|
|
18414
|
+
host: url.hostname,
|
|
18415
|
+
port: parseInt(url.port || "3306"),
|
|
18416
|
+
user: url.username,
|
|
18417
|
+
password: url.password,
|
|
18418
|
+
database: url.pathname.slice(1),
|
|
18419
|
+
};
|
|
17810
18420
|
|
|
17811
|
-
const adapter = new PrismaMariaDb(connectionConfig);
|
|
17812
|
-
|
|
18421
|
+
const adapter = new PrismaMariaDb(connectionConfig);
|
|
18422
|
+
return new PrismaClient({ adapter });
|
|
18423
|
+
}
|
|
17813
18424
|
{{/if}}
|
|
17814
18425
|
|
|
18426
|
+
{{#if (and (ne serverDeploy "cloudflare") (or (ne backend "self") (ne webDeploy "cloudflare")))}}
|
|
18427
|
+
const prisma = createPrismaClient();
|
|
17815
18428
|
export default prisma;
|
|
17816
|
-
{{/if}}
|
|
18429
|
+
{{/if}}
|
|
18430
|
+
{{/if}}
|
|
18431
|
+
`],
|
|
17817
18432
|
["db/prisma/postgres/prisma.config.ts.hbs", `import path from "node:path";
|
|
17818
18433
|
import { defineConfig, env } from 'prisma/config'
|
|
17819
18434
|
import dotenv from 'dotenv'
|
|
@@ -17867,61 +18482,86 @@ import { neonConfig } from "@neondatabase/serverless";
|
|
|
17867
18482
|
|
|
17868
18483
|
neonConfig.poolQueryViaFetch = true;
|
|
17869
18484
|
|
|
17870
|
-
|
|
17871
|
-
|
|
17872
|
-
|
|
17873
|
-
|
|
17874
|
-
})
|
|
18485
|
+
export function createPrismaClient() {
|
|
18486
|
+
return new PrismaClient({
|
|
18487
|
+
adapter: new PrismaNeon({
|
|
18488
|
+
connectionString: env.DATABASE_URL,
|
|
18489
|
+
}),
|
|
18490
|
+
});
|
|
18491
|
+
}
|
|
17875
18492
|
|
|
17876
18493
|
{{else if (eq dbSetup "prisma-postgres")}}
|
|
17877
18494
|
import { PrismaPg } from "@prisma/adapter-pg";
|
|
17878
18495
|
|
|
17879
|
-
|
|
17880
|
-
|
|
17881
|
-
|
|
18496
|
+
export function createPrismaClient() {
|
|
18497
|
+
const adapter = new PrismaPg({
|
|
18498
|
+
connectionString: env.DATABASE_URL,
|
|
18499
|
+
maxUses: 1,
|
|
18500
|
+
});
|
|
17882
18501
|
|
|
17883
|
-
|
|
18502
|
+
return new PrismaClient({ adapter });
|
|
18503
|
+
}
|
|
17884
18504
|
|
|
17885
18505
|
{{else}}
|
|
17886
18506
|
import { PrismaPg } from "@prisma/adapter-pg";
|
|
17887
18507
|
|
|
17888
|
-
|
|
17889
|
-
const
|
|
18508
|
+
export function createPrismaClient() {
|
|
18509
|
+
const adapter = new PrismaPg({
|
|
18510
|
+
connectionString: env.DATABASE_URL,
|
|
18511
|
+
maxUses: 1,
|
|
18512
|
+
});
|
|
18513
|
+
return new PrismaClient({ adapter });
|
|
18514
|
+
}
|
|
17890
18515
|
|
|
17891
18516
|
{{/if}}
|
|
17892
|
-
|
|
17893
|
-
export default prisma;
|
|
17894
18517
|
{{else}}
|
|
17895
18518
|
import { PrismaClient } from "../prisma/generated/client";
|
|
17896
18519
|
import { env } from "@{{projectName}}/env/server";
|
|
17897
18520
|
{{#if (eq dbSetup "neon")}}
|
|
17898
18521
|
import { PrismaNeon } from "@prisma/adapter-neon";
|
|
17899
18522
|
|
|
17900
|
-
|
|
17901
|
-
|
|
17902
|
-
|
|
18523
|
+
export function createPrismaClient() {
|
|
18524
|
+
const adapter = new PrismaNeon({
|
|
18525
|
+
connectionString: env.DATABASE_URL,
|
|
18526
|
+
});
|
|
17903
18527
|
|
|
17904
|
-
|
|
18528
|
+
return new PrismaClient({ adapter });
|
|
18529
|
+
}
|
|
17905
18530
|
|
|
17906
18531
|
{{else if (eq dbSetup "prisma-postgres")}}
|
|
17907
18532
|
import { PrismaPg } from "@prisma/adapter-pg";
|
|
17908
18533
|
|
|
17909
|
-
|
|
17910
|
-
|
|
17911
|
-
|
|
18534
|
+
export function createPrismaClient() {
|
|
18535
|
+
const adapter = new PrismaPg({
|
|
18536
|
+
connectionString: env.DATABASE_URL,
|
|
18537
|
+
{{#if (and (eq backend "self") (eq webDeploy "cloudflare"))}}
|
|
18538
|
+
maxUses: 1,
|
|
18539
|
+
{{/if}}
|
|
18540
|
+
});
|
|
17912
18541
|
|
|
17913
|
-
|
|
18542
|
+
return new PrismaClient({ adapter });
|
|
18543
|
+
}
|
|
17914
18544
|
|
|
17915
18545
|
{{else}}
|
|
17916
18546
|
import { PrismaPg } from "@prisma/adapter-pg";
|
|
17917
18547
|
|
|
17918
|
-
|
|
17919
|
-
const
|
|
17920
|
-
|
|
18548
|
+
export function createPrismaClient() {
|
|
18549
|
+
const adapter = new PrismaPg({
|
|
18550
|
+
connectionString: env.DATABASE_URL,
|
|
18551
|
+
{{#if (and (eq backend "self") (eq webDeploy "cloudflare"))}}
|
|
18552
|
+
maxUses: 1,
|
|
17921
18553
|
{{/if}}
|
|
18554
|
+
});
|
|
18555
|
+
return new PrismaClient({ adapter });
|
|
18556
|
+
}
|
|
17922
18557
|
|
|
18558
|
+
{{/if}}
|
|
18559
|
+
{{#if (and (ne serverDeploy "cloudflare") (or (ne backend "self") (ne webDeploy "cloudflare")))}}
|
|
18560
|
+
const prisma = createPrismaClient();
|
|
17923
18561
|
export default prisma;
|
|
17924
|
-
{{/if}}
|
|
18562
|
+
{{/if}}
|
|
18563
|
+
{{/if}}
|
|
18564
|
+
`],
|
|
17925
18565
|
["db/prisma/sqlite/prisma.config.ts.hbs", `import path from "node:path";
|
|
17926
18566
|
import { defineConfig, env } from "prisma/config";
|
|
17927
18567
|
import dotenv from "dotenv";
|
|
@@ -17972,25 +18612,36 @@ datasource db {
|
|
|
17972
18612
|
import { PrismaD1 } from "@prisma/adapter-d1";
|
|
17973
18613
|
import { env } from "@{{projectName}}/env/server";
|
|
17974
18614
|
|
|
17975
|
-
|
|
17976
|
-
const
|
|
18615
|
+
export function createPrismaClient() {
|
|
18616
|
+
const adapter = new PrismaD1(env.DB);
|
|
18617
|
+
return new PrismaClient({ adapter });
|
|
18618
|
+
}
|
|
17977
18619
|
|
|
18620
|
+
{{#if (and (ne runtime "workers") (ne serverDeploy "cloudflare") (or (ne backend "self") (ne webDeploy "cloudflare")))}}
|
|
18621
|
+
const prisma = createPrismaClient();
|
|
17978
18622
|
export default prisma;
|
|
18623
|
+
{{/if}}
|
|
17979
18624
|
{{else}}
|
|
17980
18625
|
import { PrismaLibSql } from "@prisma/adapter-libsql";
|
|
17981
18626
|
import { env } from "@{{projectName}}/env/server";
|
|
17982
18627
|
|
|
17983
|
-
|
|
17984
|
-
|
|
18628
|
+
export function createPrismaClient() {
|
|
18629
|
+
const adapter = new PrismaLibSql({
|
|
18630
|
+
url: env.DATABASE_URL,
|
|
17985
18631
|
{{#if (eq dbSetup "turso")}}
|
|
17986
|
-
|
|
18632
|
+
authToken: env.DATABASE_AUTH_TOKEN || "",
|
|
17987
18633
|
{{/if}}
|
|
17988
|
-
});
|
|
18634
|
+
});
|
|
17989
18635
|
|
|
17990
|
-
|
|
18636
|
+
return new PrismaClient({ adapter });
|
|
18637
|
+
}
|
|
17991
18638
|
|
|
18639
|
+
{{#if (and (ne runtime "workers") (ne serverDeploy "cloudflare") (or (ne backend "self") (ne webDeploy "cloudflare")))}}
|
|
18640
|
+
const prisma = createPrismaClient();
|
|
17992
18641
|
export default prisma;
|
|
17993
|
-
{{/if}}
|
|
18642
|
+
{{/if}}
|
|
18643
|
+
{{/if}}
|
|
18644
|
+
`],
|
|
17994
18645
|
["examples/ai/convex/packages/backend/convex/agent.ts.hbs", `import { Agent } from "@convex-dev/agent";
|
|
17995
18646
|
import { google } from "@ai-sdk/google";
|
|
17996
18647
|
import { components } from "./_generated/api";
|
|
@@ -22176,18 +22827,28 @@ export default function TodosScreen() {
|
|
|
22176
22827
|
["examples/todo/server/drizzle/base/src/routers/todo.ts.hbs", `{{#if (eq api "orpc")}}
|
|
22177
22828
|
import { eq } from "drizzle-orm";
|
|
22178
22829
|
import z from "zod";
|
|
22830
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
22831
|
+
import { createDb } from "@{{projectName}}/db";
|
|
22832
|
+
{{else}}
|
|
22179
22833
|
import { db } from "@{{projectName}}/db";
|
|
22834
|
+
{{/if}}
|
|
22180
22835
|
import { todo } from "@{{projectName}}/db/schema/todo";
|
|
22181
22836
|
import { publicProcedure } from "../index";
|
|
22182
22837
|
|
|
22183
22838
|
export const todoRouter = {
|
|
22184
22839
|
getAll: publicProcedure.handler(async () => {
|
|
22840
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
22841
|
+
const db = createDb();
|
|
22842
|
+
{{/if}}
|
|
22185
22843
|
return await db.select().from(todo);
|
|
22186
22844
|
}),
|
|
22187
22845
|
|
|
22188
22846
|
create: publicProcedure
|
|
22189
22847
|
.input(z.object({ text: z.string().min(1) }))
|
|
22190
22848
|
.handler(async ({ input }) => {
|
|
22849
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
22850
|
+
const db = createDb();
|
|
22851
|
+
{{/if}}
|
|
22191
22852
|
return await db
|
|
22192
22853
|
.insert(todo)
|
|
22193
22854
|
.values({
|
|
@@ -22198,6 +22859,9 @@ export const todoRouter = {
|
|
|
22198
22859
|
toggle: publicProcedure
|
|
22199
22860
|
.input(z.object({ id: z.number(), completed: z.boolean() }))
|
|
22200
22861
|
.handler(async ({ input }) => {
|
|
22862
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
22863
|
+
const db = createDb();
|
|
22864
|
+
{{/if}}
|
|
22201
22865
|
return await db
|
|
22202
22866
|
.update(todo)
|
|
22203
22867
|
.set({ completed: input.completed })
|
|
@@ -22207,6 +22871,9 @@ export const todoRouter = {
|
|
|
22207
22871
|
delete: publicProcedure
|
|
22208
22872
|
.input(z.object({ id: z.number() }))
|
|
22209
22873
|
.handler(async ({ input }) => {
|
|
22874
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
22875
|
+
const db = createDb();
|
|
22876
|
+
{{/if}}
|
|
22210
22877
|
return await db.delete(todo).where(eq(todo.id, input.id));
|
|
22211
22878
|
}),
|
|
22212
22879
|
};
|
|
@@ -22217,16 +22884,26 @@ import z from "zod";
|
|
|
22217
22884
|
import { router, publicProcedure } from "../index";
|
|
22218
22885
|
import { todo } from "@{{projectName}}/db/schema/todo";
|
|
22219
22886
|
import { eq } from "drizzle-orm";
|
|
22887
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
22888
|
+
import { createDb } from "@{{projectName}}/db";
|
|
22889
|
+
{{else}}
|
|
22220
22890
|
import { db } from "@{{projectName}}/db";
|
|
22891
|
+
{{/if}}
|
|
22221
22892
|
|
|
22222
22893
|
export const todoRouter = router({
|
|
22223
22894
|
getAll: publicProcedure.query(async () => {
|
|
22895
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
22896
|
+
const db = createDb();
|
|
22897
|
+
{{/if}}
|
|
22224
22898
|
return await db.select().from(todo);
|
|
22225
22899
|
}),
|
|
22226
22900
|
|
|
22227
22901
|
create: publicProcedure
|
|
22228
22902
|
.input(z.object({ text: z.string().min(1) }))
|
|
22229
22903
|
.mutation(async ({ input }) => {
|
|
22904
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
22905
|
+
const db = createDb();
|
|
22906
|
+
{{/if}}
|
|
22230
22907
|
return await db.insert(todo).values({
|
|
22231
22908
|
text: input.text,
|
|
22232
22909
|
});
|
|
@@ -22235,6 +22912,9 @@ export const todoRouter = router({
|
|
|
22235
22912
|
toggle: publicProcedure
|
|
22236
22913
|
.input(z.object({ id: z.number(), completed: z.boolean() }))
|
|
22237
22914
|
.mutation(async ({ input }) => {
|
|
22915
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
22916
|
+
const db = createDb();
|
|
22917
|
+
{{/if}}
|
|
22238
22918
|
return await db
|
|
22239
22919
|
.update(todo)
|
|
22240
22920
|
.set({ completed: input.completed })
|
|
@@ -22244,6 +22924,9 @@ export const todoRouter = router({
|
|
|
22244
22924
|
delete: publicProcedure
|
|
22245
22925
|
.input(z.object({ id: z.number() }))
|
|
22246
22926
|
.mutation(async ({ input }) => {
|
|
22927
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
22928
|
+
const db = createDb();
|
|
22929
|
+
{{/if}}
|
|
22247
22930
|
return await db.delete(todo).where(eq(todo.id, input.id));
|
|
22248
22931
|
}),
|
|
22249
22932
|
});
|
|
@@ -22367,11 +23050,18 @@ export { Todo };
|
|
|
22367
23050
|
`],
|
|
22368
23051
|
["examples/todo/server/prisma/base/src/routers/todo.ts.hbs", `{{#if (eq api "orpc")}}
|
|
22369
23052
|
import z from "zod";
|
|
23053
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
23054
|
+
import { createPrismaClient } from "@{{projectName}}/db";
|
|
23055
|
+
{{else}}
|
|
22370
23056
|
import prisma from "@{{projectName}}/db";
|
|
23057
|
+
{{/if}}
|
|
22371
23058
|
import { publicProcedure } from "../index";
|
|
22372
23059
|
|
|
22373
23060
|
export const todoRouter = {
|
|
22374
23061
|
getAll: publicProcedure.handler(async () => {
|
|
23062
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
23063
|
+
const prisma = createPrismaClient();
|
|
23064
|
+
{{/if}}
|
|
22375
23065
|
return await prisma.todo.findMany({
|
|
22376
23066
|
orderBy: {
|
|
22377
23067
|
id: "asc",
|
|
@@ -22382,6 +23072,9 @@ export const todoRouter = {
|
|
|
22382
23072
|
create: publicProcedure
|
|
22383
23073
|
.input(z.object({ text: z.string().min(1) }))
|
|
22384
23074
|
.handler(async ({ input }) => {
|
|
23075
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
23076
|
+
const prisma = createPrismaClient();
|
|
23077
|
+
{{/if}}
|
|
22385
23078
|
return await prisma.todo.create({
|
|
22386
23079
|
data: {
|
|
22387
23080
|
text: input.text,
|
|
@@ -22396,6 +23089,9 @@ export const todoRouter = {
|
|
|
22396
23089
|
.input(z.object({ id: z.number(), completed: z.boolean() }))
|
|
22397
23090
|
{{/if}}
|
|
22398
23091
|
.handler(async ({ input }) => {
|
|
23092
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
23093
|
+
const prisma = createPrismaClient();
|
|
23094
|
+
{{/if}}
|
|
22399
23095
|
return await prisma.todo.update({
|
|
22400
23096
|
where: { id: input.id },
|
|
22401
23097
|
data: { completed: input.completed },
|
|
@@ -22409,6 +23105,9 @@ export const todoRouter = {
|
|
|
22409
23105
|
.input(z.object({ id: z.number() }))
|
|
22410
23106
|
{{/if}}
|
|
22411
23107
|
.handler(async ({ input }) => {
|
|
23108
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
23109
|
+
const prisma = createPrismaClient();
|
|
23110
|
+
{{/if}}
|
|
22412
23111
|
return await prisma.todo.delete({
|
|
22413
23112
|
where: { id: input.id },
|
|
22414
23113
|
});
|
|
@@ -22419,11 +23118,18 @@ export const todoRouter = {
|
|
|
22419
23118
|
{{#if (eq api "trpc")}}
|
|
22420
23119
|
import { TRPCError } from "@trpc/server";
|
|
22421
23120
|
import z from "zod";
|
|
23121
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
23122
|
+
import { createPrismaClient } from "@{{projectName}}/db";
|
|
23123
|
+
{{else}}
|
|
22422
23124
|
import prisma from "@{{projectName}}/db";
|
|
23125
|
+
{{/if}}
|
|
22423
23126
|
import { publicProcedure, router } from "../index";
|
|
22424
23127
|
|
|
22425
23128
|
export const todoRouter = router({
|
|
22426
23129
|
getAll: publicProcedure.query(async () => {
|
|
23130
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
23131
|
+
const prisma = createPrismaClient();
|
|
23132
|
+
{{/if}}
|
|
22427
23133
|
return await prisma.todo.findMany({
|
|
22428
23134
|
orderBy: {
|
|
22429
23135
|
id: "asc"
|
|
@@ -22434,6 +23140,9 @@ export const todoRouter = router({
|
|
|
22434
23140
|
create: publicProcedure
|
|
22435
23141
|
.input(z.object({ text: z.string().min(1) }))
|
|
22436
23142
|
.mutation(async ({ input }) => {
|
|
23143
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
23144
|
+
const prisma = createPrismaClient();
|
|
23145
|
+
{{/if}}
|
|
22437
23146
|
return await prisma.todo.create({
|
|
22438
23147
|
data: {
|
|
22439
23148
|
text: input.text,
|
|
@@ -22448,6 +23157,9 @@ export const todoRouter = router({
|
|
|
22448
23157
|
.input(z.object({ id: z.number(), completed: z.boolean() }))
|
|
22449
23158
|
{{/if}}
|
|
22450
23159
|
.mutation(async ({ input }) => {
|
|
23160
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
23161
|
+
const prisma = createPrismaClient();
|
|
23162
|
+
{{/if}}
|
|
22451
23163
|
try {
|
|
22452
23164
|
return await prisma.todo.update({
|
|
22453
23165
|
where: { id: input.id },
|
|
@@ -22468,6 +23180,9 @@ export const todoRouter = router({
|
|
|
22468
23180
|
.input(z.object({ id: z.number() }))
|
|
22469
23181
|
{{/if}}
|
|
22470
23182
|
.mutation(async ({ input }) => {
|
|
23183
|
+
{{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}
|
|
23184
|
+
const prisma = createPrismaClient();
|
|
23185
|
+
{{/if}}
|
|
22471
23186
|
try {
|
|
22472
23187
|
return await prisma.todo.delete({
|
|
22473
23188
|
where: { id: input.id },
|
|
@@ -24802,6 +25517,9 @@ export const unstable_settings = {
|
|
|
24802
25517
|
|
|
24803
25518
|
{{#if (eq backend "convex")}}
|
|
24804
25519
|
const convex = new ConvexReactClient(env.EXPO_PUBLIC_CONVEX_URL, {
|
|
25520
|
+
{{#if (eq auth "better-auth")}}
|
|
25521
|
+
expectAuth: true,
|
|
25522
|
+
{{/if}}
|
|
24805
25523
|
unsavedChangesWarning: false,
|
|
24806
25524
|
});
|
|
24807
25525
|
{{/if}}
|
|
@@ -25850,6 +26568,9 @@ export const unstable_settings = {
|
|
|
25850
26568
|
|
|
25851
26569
|
{{#if (eq backend "convex")}}
|
|
25852
26570
|
const convex = new ConvexReactClient(env.EXPO_PUBLIC_CONVEX_URL, {
|
|
26571
|
+
{{#if (eq auth "better-auth")}}
|
|
26572
|
+
expectAuth: true,
|
|
26573
|
+
{{/if}}
|
|
25853
26574
|
unsavedChangesWarning: false,
|
|
25854
26575
|
});
|
|
25855
26576
|
{{/if}}
|
|
@@ -27150,6 +27871,9 @@ export const unstable_settings = {
|
|
|
27150
27871
|
|
|
27151
27872
|
{{#if (eq backend "convex")}}
|
|
27152
27873
|
const convex = new ConvexReactClient(env.EXPO_PUBLIC_CONVEX_URL, {
|
|
27874
|
+
{{#if (eq auth "better-auth")}}
|
|
27875
|
+
expectAuth: true,
|
|
27876
|
+
{{/if}}
|
|
27153
27877
|
unsavedChangesWarning: false,
|
|
27154
27878
|
});
|
|
27155
27879
|
{{/if}}
|
|
@@ -27946,7 +28670,7 @@ module.exports = uniwindConfig;
|
|
|
27946
28670
|
"expo-secure-store": "~55.0.8",
|
|
27947
28671
|
"expo-status-bar": "~55.0.4",
|
|
27948
28672
|
"expo-web-browser": "~55.0.9",
|
|
27949
|
-
"heroui-native": "^1.0.0
|
|
28673
|
+
"heroui-native": "^1.0.0",
|
|
27950
28674
|
"react": "19.2.0",
|
|
27951
28675
|
"react-dom": "19.2.0",
|
|
27952
28676
|
"react-native": "0.83.2",
|
|
@@ -27960,8 +28684,8 @@ module.exports = uniwindConfig;
|
|
|
27960
28684
|
"react-native-worklets": "0.7.2",
|
|
27961
28685
|
"tailwind-merge": "^3.4.0",
|
|
27962
28686
|
"tailwind-variants": "^3.2.2",
|
|
27963
|
-
"tailwindcss": "^4.
|
|
27964
|
-
"uniwind": "^1.
|
|
28687
|
+
"tailwindcss": "^4.2.2",
|
|
28688
|
+
"uniwind": "^1.6.0"
|
|
27965
28689
|
},
|
|
27966
28690
|
"devDependencies": {
|
|
27967
28691
|
"@types/node": "^24.10.0",
|
|
@@ -28830,6 +29554,9 @@ import { ConvexReactClient } from "convex/react";
|
|
|
28830
29554
|
import { env } from "@{{projectName}}/env/web";
|
|
28831
29555
|
{{#if (eq auth "clerk")}}
|
|
28832
29556
|
import { ConvexProviderWithClerk } from "convex/react-clerk";
|
|
29557
|
+
{{else if (eq auth "better-auth")}}
|
|
29558
|
+
import { ConvexBetterAuthProvider } from "@convex-dev/better-auth/react";
|
|
29559
|
+
import { authClient } from "@/lib/auth-client";
|
|
28833
29560
|
{{else}}
|
|
28834
29561
|
import { ConvexProvider } from "convex/react";
|
|
28835
29562
|
{{/if}}
|
|
@@ -28899,10 +29626,18 @@ export function Layout({ children }: { children: React.ReactNode }) {
|
|
|
28899
29626
|
{{#if (eq backend "convex")}}
|
|
28900
29627
|
{{#if (eq auth "clerk")}}
|
|
28901
29628
|
export default function App({ loaderData }: Route.ComponentProps) {
|
|
29629
|
+
{{else if (eq auth "better-auth")}}
|
|
29630
|
+
export default function App() {
|
|
28902
29631
|
{{else}}
|
|
28903
29632
|
export default function App() {
|
|
28904
29633
|
{{/if}}
|
|
29634
|
+
{{#if (eq auth "better-auth")}}
|
|
29635
|
+
const convex = new ConvexReactClient(env.VITE_CONVEX_URL, {
|
|
29636
|
+
expectAuth: true,
|
|
29637
|
+
});
|
|
29638
|
+
{{else}}
|
|
28905
29639
|
const convex = new ConvexReactClient(env.VITE_CONVEX_URL);
|
|
29640
|
+
{{/if}}
|
|
28906
29641
|
{{#if (eq auth "clerk")}}
|
|
28907
29642
|
return (
|
|
28908
29643
|
<ClerkProvider loaderData={loaderData}>
|
|
@@ -28922,6 +29657,23 @@ export default function App() {
|
|
|
28922
29657
|
</ConvexProviderWithClerk>
|
|
28923
29658
|
</ClerkProvider>
|
|
28924
29659
|
);
|
|
29660
|
+
{{else if (eq auth "better-auth")}}
|
|
29661
|
+
return (
|
|
29662
|
+
<ConvexBetterAuthProvider client={convex} authClient={authClient}>
|
|
29663
|
+
<ThemeProvider
|
|
29664
|
+
attribute="class"
|
|
29665
|
+
defaultTheme="dark"
|
|
29666
|
+
disableTransitionOnChange
|
|
29667
|
+
storageKey="vite-ui-theme"
|
|
29668
|
+
>
|
|
29669
|
+
<div className="grid grid-rows-[auto_1fr] h-svh">
|
|
29670
|
+
<Header />
|
|
29671
|
+
<Outlet />
|
|
29672
|
+
</div>
|
|
29673
|
+
<Toaster richColors />
|
|
29674
|
+
</ThemeProvider>
|
|
29675
|
+
</ConvexBetterAuthProvider>
|
|
29676
|
+
);
|
|
28925
29677
|
{{else}}
|
|
28926
29678
|
return (
|
|
28927
29679
|
<ConvexProvider client={convex}>
|
|
@@ -29340,7 +30092,13 @@ import { routeTree } from "./routeTree.gen";
|
|
|
29340
30092
|
{{else}}
|
|
29341
30093
|
import { ConvexProvider } from "convex/react";
|
|
29342
30094
|
{{/if}}
|
|
30095
|
+
{{#if (eq auth "better-auth")}}
|
|
30096
|
+
const convex = new ConvexReactClient(env.VITE_CONVEX_URL, {
|
|
30097
|
+
expectAuth: true,
|
|
30098
|
+
});
|
|
30099
|
+
{{else}}
|
|
29343
30100
|
const convex = new ConvexReactClient(env.VITE_CONVEX_URL);
|
|
30101
|
+
{{/if}}
|
|
29344
30102
|
{{/if}}
|
|
29345
30103
|
|
|
29346
30104
|
{{#if (and (eq auth "clerk") (ne backend "convex") (ne api "none"))}}
|
|
@@ -31150,7 +31908,69 @@ export const env = createEnv({
|
|
|
31150
31908
|
emptyStringAsUndefined: true,
|
|
31151
31909
|
});
|
|
31152
31910
|
`],
|
|
31153
|
-
["packages/env/src/server.ts.hbs", `{{#if (
|
|
31911
|
+
["packages/env/src/server.ts.hbs", `{{#if (eq serverDeploy "cloudflare")}}
|
|
31912
|
+
/// <reference path="../env.d.ts" />
|
|
31913
|
+
// For Cloudflare Workers, env is accessed via cloudflare:workers module
|
|
31914
|
+
// Types are defined in env.d.ts based on your alchemy.run.ts bindings
|
|
31915
|
+
export { env } from "cloudflare:workers";
|
|
31916
|
+
{{else if (and (eq backend "self") (eq webDeploy "cloudflare") (includes frontend "next"))}}
|
|
31917
|
+
/// <reference path="../env.d.ts" />
|
|
31918
|
+
import { getCloudflareContext } from "@opennextjs/cloudflare";
|
|
31919
|
+
|
|
31920
|
+
function getNodeEnvValue(key: string) {
|
|
31921
|
+
return process.env[key];
|
|
31922
|
+
}
|
|
31923
|
+
|
|
31924
|
+
function getCloudflareEnvSync() {
|
|
31925
|
+
try {
|
|
31926
|
+
return getCloudflareContext().env as Env;
|
|
31927
|
+
} catch {
|
|
31928
|
+
return undefined;
|
|
31929
|
+
}
|
|
31930
|
+
}
|
|
31931
|
+
|
|
31932
|
+
type EnvValue = Env[keyof Env];
|
|
31933
|
+
|
|
31934
|
+
function createEnvProxy(getValue: (key: keyof Env & string) => EnvValue | undefined) {
|
|
31935
|
+
return new Proxy({} as Env, {
|
|
31936
|
+
get(_target, prop) {
|
|
31937
|
+
if (typeof prop !== "string") {
|
|
31938
|
+
return undefined;
|
|
31939
|
+
}
|
|
31940
|
+
|
|
31941
|
+
return getValue(prop as keyof Env & string);
|
|
31942
|
+
},
|
|
31943
|
+
});
|
|
31944
|
+
}
|
|
31945
|
+
|
|
31946
|
+
function resolveEnvValue(key: keyof Env & string): EnvValue | undefined {
|
|
31947
|
+
const nodeValue = getNodeEnvValue(key);
|
|
31948
|
+
if (nodeValue !== undefined) {
|
|
31949
|
+
return nodeValue as EnvValue;
|
|
31950
|
+
}
|
|
31951
|
+
|
|
31952
|
+
return getCloudflareEnvSync()?.[key as keyof Env];
|
|
31953
|
+
}
|
|
31954
|
+
|
|
31955
|
+
// Next.js local dev runs in Node.js, where env vars are exposed on process.env.
|
|
31956
|
+
// In the Cloudflare runtime, fall back to OpenNext's Cloudflare context bindings.
|
|
31957
|
+
// For static routes (ISR/SSG), use getEnvAsync() so OpenNext can resolve bindings
|
|
31958
|
+
// with the async Cloudflare context API.
|
|
31959
|
+
export async function getEnvAsync() {
|
|
31960
|
+
const cloudflareEnv = (await getCloudflareContext({ async: true })).env as Env;
|
|
31961
|
+
|
|
31962
|
+
return createEnvProxy((key) => {
|
|
31963
|
+
const nodeValue = getNodeEnvValue(key);
|
|
31964
|
+
if (nodeValue !== undefined) {
|
|
31965
|
+
return nodeValue;
|
|
31966
|
+
}
|
|
31967
|
+
|
|
31968
|
+
return cloudflareEnv[key as keyof Env];
|
|
31969
|
+
});
|
|
31970
|
+
}
|
|
31971
|
+
|
|
31972
|
+
export const env = createEnvProxy(resolveEnvValue);
|
|
31973
|
+
{{else if (and (eq backend "self") (eq webDeploy "cloudflare"))}}
|
|
31154
31974
|
/// <reference path="../env.d.ts" />
|
|
31155
31975
|
// For Cloudflare Workers, env is accessed via cloudflare:workers module
|
|
31156
31976
|
// Types are defined in env.d.ts based on your alchemy.run.ts bindings
|
|
@@ -32631,7 +33451,7 @@ function SuccessPage() {
|
|
|
32631
33451
|
</div>
|
|
32632
33452
|
`]
|
|
32633
33453
|
]);
|
|
32634
|
-
const TEMPLATE_COUNT =
|
|
33454
|
+
const TEMPLATE_COUNT = 462;
|
|
32635
33455
|
|
|
32636
33456
|
//#endregion
|
|
32637
33457
|
export { EMBEDDED_TEMPLATES, GeneratorError, Handlebars, TEMPLATE_COUNT, VirtualFileSystem, dependencyVersionMap, generate, generateReproducibleCommand, isBinaryFile, processAddonTemplates, processAddonsDeps, processFileContent, processTemplateString, transformFilename, writeBtsConfigToVfs };
|