create-better-t-stack 3.11.0 → 3.12.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.
Files changed (71) hide show
  1. package/dist/chunk-Dt3mZKp0.mjs +24 -0
  2. package/dist/cli.mjs +1 -1
  3. package/dist/index.d.mts +40 -60
  4. package/dist/index.mjs +2 -2
  5. package/dist/{src-XVvJUQ_h.mjs → src-DBVnwTkj.mjs} +668 -631
  6. package/package.json +2 -2
  7. package/templates/addons/turborepo/turbo.json.hbs +13 -0
  8. package/templates/api/orpc/native/utils/orpc.ts.hbs +21 -20
  9. package/templates/api/orpc/web/nuxt/app/plugins/orpc.ts.hbs +3 -5
  10. package/templates/api/orpc/web/react/base/src/utils/orpc.ts.hbs +73 -67
  11. package/templates/api/orpc/web/solid/src/utils/orpc.ts.hbs +15 -14
  12. package/templates/api/trpc/native/utils/trpc.ts.hbs +8 -7
  13. package/templates/api/trpc/web/react/base/src/utils/trpc.ts.hbs +59 -57
  14. package/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs +3 -5
  15. package/templates/auth/better-auth/convex/backend/convex/privateData.ts.hbs +13 -12
  16. package/templates/auth/better-auth/convex/native/base/lib/auth-client.ts.hbs +10 -9
  17. package/templates/auth/better-auth/convex/web/react/next/src/lib/auth-client.ts.hbs +2 -2
  18. package/templates/auth/better-auth/convex/web/react/next/src/lib/auth-server.ts.hbs +11 -9
  19. package/templates/auth/better-auth/convex/web/react/tanstack-router/src/lib/auth-client.ts.hbs +5 -4
  20. package/templates/auth/better-auth/convex/web/react/tanstack-start/src/lib/auth-server.ts.hbs +8 -7
  21. package/templates/auth/better-auth/native/base/lib/auth-client.ts.hbs +9 -8
  22. package/templates/auth/better-auth/server/base/src/index.ts.hbs +239 -235
  23. package/templates/auth/better-auth/web/nuxt/app/plugins/auth-client.ts.hbs +2 -3
  24. package/templates/auth/better-auth/web/react/base/src/lib/auth-client.ts.hbs +9 -11
  25. package/templates/auth/better-auth/web/solid/src/lib/auth-client.ts.hbs +3 -2
  26. package/templates/backend/server/elysia/src/index.ts.hbs +71 -71
  27. package/templates/backend/server/express/src/index.ts.hbs +57 -57
  28. package/templates/backend/server/fastify/src/index.ts.hbs +107 -107
  29. package/templates/backend/server/hono/src/index.ts.hbs +75 -85
  30. package/templates/base/tsconfig.json.hbs +3 -0
  31. package/templates/db/drizzle/mysql/src/index.ts.hbs +23 -30
  32. package/templates/db/drizzle/postgres/src/index.ts.hbs +6 -13
  33. package/templates/db/drizzle/sqlite/src/index.ts.hbs +11 -18
  34. package/templates/db/mongoose/mongodb/src/index.ts.hbs +3 -2
  35. package/templates/db/prisma/mongodb/prisma/schema/schema.prisma.hbs +1 -1
  36. package/templates/db/prisma/mysql/prisma/schema/schema.prisma.hbs +1 -1
  37. package/templates/db/prisma/mysql/prisma.config.ts.hbs +16 -16
  38. package/templates/db/prisma/mysql/src/index.ts.hbs +16 -15
  39. package/templates/db/prisma/postgres/prisma/schema/schema.prisma.hbs +1 -1
  40. package/templates/db/prisma/postgres/src/index.ts.hbs +10 -9
  41. package/templates/db/prisma/sqlite/prisma/schema/schema.prisma.hbs +1 -1
  42. package/templates/db/prisma/sqlite/src/index.ts.hbs +4 -7
  43. package/templates/examples/ai/native/bare/app/(drawer)/ai.tsx.hbs +2 -1
  44. package/templates/examples/ai/native/unistyles/app/(drawer)/ai.tsx.hbs +2 -1
  45. package/templates/examples/ai/native/uniwind/app/(drawer)/ai.tsx.hbs +2 -1
  46. package/templates/examples/ai/web/nuxt/app/pages/ai.vue.hbs +1 -3
  47. package/templates/examples/ai/web/react/next/src/app/ai/page.tsx.hbs +4 -3
  48. package/templates/examples/ai/web/react/react-router/src/routes/ai.tsx.hbs +2 -1
  49. package/templates/examples/ai/web/react/tanstack-router/src/routes/ai.tsx.hbs +4 -1
  50. package/templates/examples/ai/web/react/tanstack-start/src/routes/ai.tsx.hbs +4 -1
  51. package/templates/frontend/native/bare/app/_layout.tsx.hbs +4 -2
  52. package/templates/frontend/native/unistyles/app/_layout.tsx.hbs +4 -2
  53. package/templates/frontend/native/uniwind/app/_layout.tsx.hbs +4 -3
  54. package/templates/frontend/nuxt/nuxt.config.ts.hbs +6 -3
  55. package/templates/frontend/react/next/next.config.ts.hbs +9 -8
  56. package/templates/frontend/react/next/src/components/providers.tsx.hbs +4 -1
  57. package/templates/frontend/react/next/tsconfig.json.hbs +2 -2
  58. package/templates/frontend/react/react-router/src/root.tsx.hbs +3 -4
  59. package/templates/frontend/react/tanstack-router/src/main.tsx.hbs +3 -2
  60. package/templates/frontend/react/tanstack-start/src/router.tsx.hbs +100 -108
  61. package/templates/frontend/react/tanstack-start/src/routes/__root.tsx.hbs +25 -7
  62. package/templates/packages/config/tsconfig.base.json.hbs +1 -1
  63. package/templates/{deploy/alchemy → packages/env}/env.d.ts.hbs +6 -4
  64. package/templates/packages/env/package.json.hbs +7 -0
  65. package/templates/packages/env/src/native.ts.hbs +21 -0
  66. package/templates/packages/env/src/server.ts.hbs +38 -0
  67. package/templates/packages/env/src/web.ts.hbs +89 -0
  68. package/templates/packages/env/tsconfig.json.hbs +3 -0
  69. package/templates/{deploy/alchemy → packages/infra}/alchemy.run.ts.hbs +86 -82
  70. package/templates/packages/infra/package.json.hbs +10 -0
  71. package/templates/payments/polar/server/base/src/lib/payments.ts.hbs +3 -2
@@ -17,7 +17,6 @@ import appCss from "../index.css?url";
17
17
  {{#if (eq backend "convex")}}
18
18
  import type { QueryClient } from "@tanstack/react-query";
19
19
  import type { ConvexQueryClient } from "@convex-dev/react-query";
20
- import type { ConvexReactClient } from "convex/react";
21
20
  {{else}}
22
21
  {{#if (or (eq api "trpc") (eq api "orpc"))}}
23
22
  import type { QueryClient } from "@tanstack/react-query";
@@ -44,12 +43,13 @@ import { getToken } from "@/lib/auth-server";
44
43
  const getAuth = createServerFn({ method: "GET" }).handler(async () => {
45
44
  return await getToken();
46
45
  });
46
+ {{else if (eq backend "convex")}}
47
+ import { ConvexProvider } from "convex/react";
47
48
  {{/if}}
48
49
 
49
50
  {{#if (eq backend "convex")}}
50
51
  export interface RouterAppContext {
51
52
  queryClient: QueryClient;
52
- convexClient: ConvexReactClient;
53
53
  convexQueryClient: ConvexQueryClient;
54
54
  }
55
55
  {{else}}
@@ -122,7 +122,7 @@ function RootDocument() {
122
122
  const context = useRouteContext({ from: Route.id });
123
123
  return (
124
124
  <ClerkProvider>
125
- <ConvexProviderWithClerk client={context.convexClient} useAuth={useAuth}>
125
+ <ConvexProviderWithClerk client={context.convexQueryClient.convexClient} useAuth={useAuth}>
126
126
  <html lang="en" className="dark">
127
127
  <head>
128
128
  <HeadContent />
@@ -144,7 +144,7 @@ function RootDocument() {
144
144
  const context = useRouteContext({ from: Route.id });
145
145
  return (
146
146
  <ConvexBetterAuthProvider
147
- client={context.convexClient}
147
+ client={context.convexQueryClient.convexClient}
148
148
  authClient={authClient}
149
149
  initialToken={context.token}
150
150
  >
@@ -164,6 +164,26 @@ function RootDocument() {
164
164
  </html>
165
165
  </ConvexBetterAuthProvider>
166
166
  );
167
+ {{else if (eq backend "convex")}}
168
+ const { convexQueryClient } = Route.useRouteContext();
169
+ return (
170
+ <ConvexProvider client={convexQueryClient.convexClient}>
171
+ <html lang="en" className="dark">
172
+ <head>
173
+ <HeadContent />
174
+ </head>
175
+ <body>
176
+ <div className="grid h-svh grid-rows-[auto_1fr]">
177
+ <Header />
178
+ <Outlet />
179
+ </div>
180
+ <Toaster richColors />
181
+ <TanStackRouterDevtools position="bottom-left" />
182
+ <Scripts />
183
+ </body>
184
+ </html>
185
+ </ConvexProvider>
186
+ );
167
187
  {{else}}
168
188
  return (
169
189
  <html lang="en" className="dark">
@@ -177,10 +197,8 @@ function RootDocument() {
177
197
  </div>
178
198
  <Toaster richColors />
179
199
  <TanStackRouterDevtools position="bottom-left" />
180
- {{#unless (eq backend "convex")}}
181
- {{#unless (eq api "none")}}
200
+ {{#unless (eq api "none")}}
182
201
  <ReactQueryDevtools position="bottom" buttonPosition="bottom-right" />
183
- {{/unless}}
184
202
  {{/unless}}
185
203
  <Scripts />
186
204
  </body>
@@ -26,7 +26,7 @@
26
26
  "node"
27
27
  {{else}}
28
28
  "node"
29
- {{/if}}{{#if (or (eq serverDeploy "alchemy") (eq webDeploy "alchemy"))}},
29
+ {{/if}}{{#if (or (eq serverDeploy "cloudflare") (eq webDeploy "cloudflare"))}},
30
30
  "@cloudflare/workers-types"{{/if}}
31
31
  ]
32
32
  }
@@ -1,14 +1,16 @@
1
+ import { type server } from "@{{projectName}}/infra/alchemy.run";
2
+
1
3
  // This file infers types for the cloudflare:workers environment from your Alchemy Worker.
2
4
  // @see https://alchemy.run/concepts/bindings/#type-safe-bindings
3
5
 
4
6
  export type CloudflareEnv = typeof server.Env;
5
7
 
6
8
  declare global {
7
- type Env = CloudflareEnv;
9
+ type Env = CloudflareEnv;
8
10
  }
9
11
 
10
12
  declare module "cloudflare:workers" {
11
- namespace Cloudflare {
12
- export interface Env extends CloudflareEnv {}
13
- }
13
+ namespace Cloudflare {
14
+ export interface Env extends CloudflareEnv {}
15
+ }
14
16
  }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "@{{projectName}}/env",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "exports": {}
7
+ }
@@ -0,0 +1,21 @@
1
+ import { createEnv } from "@t3-oss/env-core";
2
+ import { z } from "zod";
3
+
4
+ export const env = createEnv({
5
+ clientPrefix: "EXPO_PUBLIC_",
6
+ client: {
7
+ {{#if (eq backend "convex")}}
8
+ EXPO_PUBLIC_CONVEX_URL: z.url(),
9
+ {{#if (eq auth "better-auth")}}
10
+ EXPO_PUBLIC_CONVEX_SITE_URL: z.url(),
11
+ {{/if}}
12
+ {{#if (eq auth "clerk")}}
13
+ EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string().min(1),
14
+ {{/if}}
15
+ {{else}}
16
+ EXPO_PUBLIC_SERVER_URL: z.url(),
17
+ {{/if}}
18
+ },
19
+ runtimeEnv: process.env,
20
+ emptyStringAsUndefined: true,
21
+ });
@@ -0,0 +1,38 @@
1
+ {{#if (eq serverDeploy "cloudflare")}}
2
+ /// <reference path="../env.d.ts" />
3
+ // For Cloudflare Workers, env is accessed via cloudflare:workers module
4
+ // Types are defined in env.d.ts based on your alchemy.run.ts bindings
5
+ export { env } from "cloudflare:workers";
6
+ {{else}}
7
+ import { createEnv } from "@t3-oss/env-core";
8
+ import { z } from "zod";
9
+
10
+ export const env = createEnv({
11
+ server: {
12
+ {{#if (ne database "none")}}
13
+ {{#if (eq dbSetup "planetscale")}}
14
+ DATABASE_HOST: z.string().min(1),
15
+ DATABASE_USERNAME: z.string().min(1),
16
+ DATABASE_PASSWORD: z.string().min(1),
17
+ {{else}}
18
+ DATABASE_URL: z.string().min(1),
19
+ {{#if (eq dbSetup "turso")}}
20
+ DATABASE_AUTH_TOKEN: z.string().min(1),
21
+ {{/if}}
22
+ {{/if}}
23
+ {{/if}}
24
+ {{#if (eq auth "better-auth")}}
25
+ BETTER_AUTH_SECRET: z.string().min(32),
26
+ BETTER_AUTH_URL: z.url(),
27
+ {{/if}}
28
+ {{#if (eq payments "polar")}}
29
+ POLAR_ACCESS_TOKEN: z.string().min(1),
30
+ POLAR_SUCCESS_URL: z.url(),
31
+ {{/if}}
32
+ CORS_ORIGIN: z.url(),
33
+ NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
34
+ },
35
+ runtimeEnv: process.env,
36
+ emptyStringAsUndefined: true,
37
+ });
38
+ {{/if}}
@@ -0,0 +1,89 @@
1
+ {{#if (includes frontend "next")}}
2
+ import { createEnv } from "@t3-oss/env-nextjs";
3
+ {{else if (includes frontend "nuxt")}}
4
+ import { createEnv } from "@t3-oss/env-nuxt";
5
+ {{else}}
6
+ import { createEnv } from "@t3-oss/env-core";
7
+ {{/if}}
8
+ import { z } from "zod";
9
+
10
+ {{#if (includes frontend "nuxt")}}
11
+ /**
12
+ * Nuxt env validation - validates at build time when imported in nuxt.config.ts
13
+ * For runtime access in components/plugins, use useRuntimeConfig() instead:
14
+ * const config = useRuntimeConfig()
15
+ * config.public.serverUrl (NUXT_PUBLIC_SERVER_URL maps to serverUrl)
16
+ */
17
+ {{/if}}
18
+ export const env = createEnv({
19
+ {{#if (eq backend "convex")}}
20
+ {{#if (includes frontend "next")}}
21
+ client: {
22
+ NEXT_PUBLIC_CONVEX_URL: z.url(),
23
+ {{#if (eq auth "better-auth")}}
24
+ NEXT_PUBLIC_CONVEX_SITE_URL: z.url(),
25
+ {{/if}}
26
+ {{#if (eq auth "clerk")}}
27
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string().min(1),
28
+ {{/if}}
29
+ },
30
+ runtimeEnv: {
31
+ NEXT_PUBLIC_CONVEX_URL: process.env.NEXT_PUBLIC_CONVEX_URL,
32
+ {{#if (eq auth "better-auth")}}
33
+ NEXT_PUBLIC_CONVEX_SITE_URL: process.env.NEXT_PUBLIC_CONVEX_SITE_URL,
34
+ {{/if}}
35
+ {{#if (eq auth "clerk")}}
36
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,
37
+ {{/if}}
38
+ },
39
+ {{else if (includes frontend "nuxt")}}
40
+ client: {
41
+ NUXT_PUBLIC_CONVEX_URL: z.url(),
42
+ },
43
+ {{else if (includes frontend "svelte")}}
44
+ clientPrefix: "PUBLIC_",
45
+ client: {
46
+ PUBLIC_CONVEX_URL: z.url(),
47
+ },
48
+ runtimeEnv: (import.meta as any).env,
49
+ {{else}}
50
+ clientPrefix: "VITE_",
51
+ client: {
52
+ VITE_CONVEX_URL: z.url(),
53
+ {{#if (eq auth "better-auth")}}
54
+ VITE_CONVEX_SITE_URL: z.url(),
55
+ {{/if}}
56
+ {{#if (eq auth "clerk")}}
57
+ VITE_CLERK_PUBLISHABLE_KEY: z.string().min(1),
58
+ {{/if}}
59
+ },
60
+ runtimeEnv: (import.meta as any).env,
61
+ {{/if}}
62
+ {{else if (ne backend "self")}}
63
+ {{#if (includes frontend "next")}}
64
+ client: {
65
+ NEXT_PUBLIC_SERVER_URL: z.url(),
66
+ },
67
+ runtimeEnv: {
68
+ NEXT_PUBLIC_SERVER_URL: process.env.NEXT_PUBLIC_SERVER_URL,
69
+ },
70
+ {{else if (includes frontend "nuxt")}}
71
+ client: {
72
+ NUXT_PUBLIC_SERVER_URL: z.url(),
73
+ },
74
+ {{else if (includes frontend "svelte")}}
75
+ clientPrefix: "PUBLIC_",
76
+ client: {
77
+ PUBLIC_SERVER_URL: z.url(),
78
+ },
79
+ runtimeEnv: (import.meta as any).env,
80
+ {{else}}
81
+ clientPrefix: "VITE_",
82
+ client: {
83
+ VITE_SERVER_URL: z.url(),
84
+ },
85
+ runtimeEnv: (import.meta as any).env,
86
+ {{/if}}
87
+ {{/if}}
88
+ emptyStringAsUndefined: true,
89
+ });
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "@{{projectName}}/config/tsconfig.base.json",
3
+ }
@@ -1,5 +1,5 @@
1
1
  import alchemy from "alchemy";
2
- {{#if (eq webDeploy "alchemy")}}
2
+ {{#if (eq webDeploy "cloudflare")}}
3
3
  {{#if (includes frontend "next")}}
4
4
  import { Nextjs } from "alchemy/cloudflare";
5
5
  {{else if (includes frontend "nuxt")}}
@@ -16,236 +16,240 @@ import { ReactRouter } from "alchemy/cloudflare";
16
16
  import { Vite } from "alchemy/cloudflare";
17
17
  {{/if}}
18
18
  {{/if}}
19
- {{#if (eq serverDeploy "alchemy")}}
19
+ {{#if (eq serverDeploy "cloudflare")}}
20
20
  import { Worker } from "alchemy/cloudflare";
21
21
  {{/if}}
22
- {{#if (and (or (eq serverDeploy "alchemy") (and (eq webDeploy "alchemy") (eq backend "self"))) (eq dbSetup "d1"))}}
22
+ {{#if (and (or (eq serverDeploy "cloudflare") (and (eq webDeploy "cloudflare") (eq backend "self"))) (eq dbSetup "d1"))}}
23
23
  import { D1Database } from "alchemy/cloudflare";
24
24
  {{/if}}
25
25
  import { config } from "dotenv";
26
26
 
27
- {{#if (and (eq webDeploy "alchemy") (eq serverDeploy "alchemy"))}}
27
+ {{#if (and (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare"))}}
28
28
  config({ path: "./.env" });
29
- config({ path: "./apps/web/.env" });
30
- config({ path: "./apps/server/.env" });
31
- {{else if (or (eq webDeploy "alchemy") (eq serverDeploy "alchemy"))}}
29
+ config({ path: "../../apps/web/.env" });
30
+ config({ path: "../../apps/server/.env" });
31
+ {{else if (eq webDeploy "cloudflare")}}
32
32
  config({ path: "./.env" });
33
+ config({ path: "../../apps/web/.env" });
34
+ {{else if (eq serverDeploy "cloudflare")}}
35
+ config({ path: "./.env" });
36
+ config({ path: "../../apps/server/.env" });
33
37
  {{/if}}
34
38
 
35
39
  const app = await alchemy("{{projectName}}");
36
40
 
37
- {{#if (and (or (eq serverDeploy "alchemy") (and (eq webDeploy "alchemy") (eq backend "self"))) (eq dbSetup "d1"))}}
41
+ {{#if (and (or (eq serverDeploy "cloudflare") (and (eq webDeploy "cloudflare") (eq backend "self"))) (eq dbSetup "d1"))}}
38
42
  const db = await D1Database("database", {
39
43
  {{#if (eq orm "prisma")}}
40
- migrationsDir: "packages/db/prisma/migrations",
44
+ migrationsDir: "../../packages/db/prisma/migrations",
41
45
  {{else if (eq orm "drizzle")}}
42
- migrationsDir: "packages/db/src/migrations",
46
+ migrationsDir: "../../packages/db/src/migrations",
43
47
  {{/if}}
44
48
  });
45
49
  {{/if}}
46
50
 
47
- {{#if (eq webDeploy "alchemy")}}
51
+ {{#if (eq webDeploy "cloudflare")}}
48
52
  {{#if (includes frontend "next")}}
49
53
  export const web = await Nextjs("web", {
50
- {{#if (eq serverDeploy "alchemy")}}cwd: "apps/web",{{/if}}
54
+ cwd: "../../apps/web",
51
55
  bindings: {
52
56
  {{#if (eq backend "convex")}}
53
- NEXT_PUBLIC_CONVEX_URL: alchemy.env.NEXT_PUBLIC_CONVEX_URL,
57
+ NEXT_PUBLIC_CONVEX_URL: alchemy.env.NEXT_PUBLIC_CONVEX_URL!,
54
58
  {{#if (eq auth "better-auth")}}
55
- NEXT_PUBLIC_CONVEX_SITE_URL: alchemy.env.NEXT_PUBLIC_CONVEX_SITE_URL,
59
+ NEXT_PUBLIC_CONVEX_SITE_URL: alchemy.env.NEXT_PUBLIC_CONVEX_SITE_URL!,
56
60
  {{/if}}
57
61
  {{else if (ne backend "self")}}
58
- NEXT_PUBLIC_SERVER_URL: alchemy.env.NEXT_PUBLIC_SERVER_URL,
62
+ NEXT_PUBLIC_SERVER_URL: alchemy.env.NEXT_PUBLIC_SERVER_URL!,
59
63
  {{/if}}
60
64
  {{#if (eq dbSetup "d1")}}
61
65
  DB: db,
62
66
  {{else if (ne database "none")}}
63
- DATABASE_URL: alchemy.secret.env.DATABASE_URL,
67
+ DATABASE_URL: alchemy.secret.env.DATABASE_URL!,
64
68
  {{/if}}
65
69
  {{#if (ne backend "convex")}}
66
- CORS_ORIGIN: alchemy.env.CORS_ORIGIN,
70
+ CORS_ORIGIN: alchemy.env.CORS_ORIGIN!,
67
71
  {{#if (eq auth "better-auth")}}
68
- BETTER_AUTH_SECRET: alchemy.secret.env.BETTER_AUTH_SECRET,
69
- BETTER_AUTH_URL: alchemy.env.BETTER_AUTH_URL,
72
+ BETTER_AUTH_SECRET: alchemy.secret.env.BETTER_AUTH_SECRET!,
73
+ BETTER_AUTH_URL: alchemy.env.BETTER_AUTH_URL!,
70
74
  {{/if}}
71
75
  {{/if}}
72
76
  {{#if (eq auth "clerk")}}
73
- CLERK_SECRET_KEY: alchemy.secret.env.CLERK_SECRET_KEY,
77
+ CLERK_SECRET_KEY: alchemy.secret.env.CLERK_SECRET_KEY!,
74
78
  {{/if}}
75
- {{#if (includes examples "ai")}}
76
- GOOGLE_GENERATIVE_AI_API_KEY: alchemy.secret.env.GOOGLE_GENERATIVE_AI_API_KEY,
79
+ {{#if (and (includes examples "ai") (ne backend "convex"))}}
80
+ GOOGLE_GENERATIVE_AI_API_KEY: alchemy.secret.env.GOOGLE_GENERATIVE_AI_API_KEY!,
77
81
  {{/if}}
78
82
  {{#if (eq payments "polar")}}
79
- POLAR_ACCESS_TOKEN: alchemy.secret.env.POLAR_ACCESS_TOKEN,
80
- POLAR_SUCCESS_URL: alchemy.env.POLAR_SUCCESS_URL,
83
+ POLAR_ACCESS_TOKEN: alchemy.secret.env.POLAR_ACCESS_TOKEN!,
84
+ POLAR_SUCCESS_URL: alchemy.env.POLAR_SUCCESS_URL!,
81
85
  {{/if}}
82
86
  {{#if (eq dbSetup "turso")}}
83
- DATABASE_AUTH_TOKEN: alchemy.secret.env.DATABASE_AUTH_TOKEN,
87
+ DATABASE_AUTH_TOKEN: alchemy.secret.env.DATABASE_AUTH_TOKEN!,
84
88
  {{/if}}
85
89
  {{#if (eq database "mysql")}}
86
90
  {{#if (eq orm "drizzle")}}
87
- DATABASE_HOST: alchemy.env.DATABASE_HOST,
88
- DATABASE_USERNAME: alchemy.env.DATABASE_USERNAME,
89
- DATABASE_PASSWORD: alchemy.secret.env.DATABASE_PASSWORD,
91
+ DATABASE_HOST: alchemy.env.DATABASE_HOST!,
92
+ DATABASE_USERNAME: alchemy.env.DATABASE_USERNAME!,
93
+ DATABASE_PASSWORD: alchemy.secret.env.DATABASE_PASSWORD!,
90
94
  {{/if}}
91
95
  {{/if}}
92
96
  }
93
97
  });
94
98
  {{else if (includes frontend "nuxt")}}
95
99
  export const web = await Nuxt("web", {
96
- {{#if (eq serverDeploy "alchemy")}}cwd: "apps/web",{{/if}}
100
+ cwd: "../../apps/web",
97
101
  bindings: {
98
102
  {{#if (eq backend "convex")}}
99
- NUXT_PUBLIC_CONVEX_URL: alchemy.env.NUXT_PUBLIC_CONVEX_URL,
103
+ NUXT_PUBLIC_CONVEX_URL: alchemy.env.NUXT_PUBLIC_CONVEX_URL!,
100
104
  {{#if (eq auth "better-auth")}}
101
- NUXT_PUBLIC_CONVEX_SITE_URL: alchemy.env.NUXT_PUBLIC_CONVEX_SITE_URL,
105
+ NUXT_PUBLIC_CONVEX_SITE_URL: alchemy.env.NUXT_PUBLIC_CONVEX_SITE_URL!,
102
106
  {{/if}}
103
107
  {{else if (ne backend "self")}}
104
- NUXT_PUBLIC_SERVER_URL: alchemy.env.NUXT_PUBLIC_SERVER_URL,
108
+ NUXT_PUBLIC_SERVER_URL: alchemy.env.NUXT_PUBLIC_SERVER_URL!,
105
109
  {{/if}}
106
110
  }
107
111
  });
108
112
  {{else if (includes frontend "svelte")}}
109
113
  export const web = await SvelteKit("web", {
110
- {{#if (eq serverDeploy "alchemy")}}cwd: "apps/web",{{/if}}
114
+ cwd: "../../apps/web",
111
115
  bindings: {
112
116
  {{#if (eq backend "convex")}}
113
- PUBLIC_CONVEX_URL: alchemy.env.PUBLIC_CONVEX_URL,
117
+ PUBLIC_CONVEX_URL: alchemy.env.PUBLIC_CONVEX_URL!,
114
118
  {{#if (eq auth "better-auth")}}
115
- PUBLIC_CONVEX_SITE_URL: alchemy.env.PUBLIC_CONVEX_SITE_URL,
119
+ PUBLIC_CONVEX_SITE_URL: alchemy.env.PUBLIC_CONVEX_SITE_URL!,
116
120
  {{/if}}
117
121
  {{else if (ne backend "self")}}
118
- PUBLIC_SERVER_URL: alchemy.env.PUBLIC_SERVER_URL,
122
+ PUBLIC_SERVER_URL: alchemy.env.PUBLIC_SERVER_URL!,
119
123
  {{/if}}
120
124
  }
121
125
  });
122
126
  {{else if (includes frontend "tanstack-start")}}
123
127
  export const web = await TanStackStart("web", {
124
- {{#if (eq serverDeploy "alchemy")}}cwd: "apps/web",{{/if}}
128
+ cwd: "../../apps/web",
125
129
  bindings: {
126
130
  {{#if (eq backend "convex")}}
127
- VITE_CONVEX_URL: alchemy.env.VITE_CONVEX_URL,
131
+ VITE_CONVEX_URL: alchemy.env.VITE_CONVEX_URL!,
128
132
  {{#if (eq auth "better-auth")}}
129
- VITE_CONVEX_SITE_URL: alchemy.env.VITE_CONVEX_SITE_URL,
133
+ VITE_CONVEX_SITE_URL: alchemy.env.VITE_CONVEX_SITE_URL!,
130
134
  {{/if}}
131
135
  {{else if (ne backend "self")}}
132
- VITE_SERVER_URL: alchemy.env.VITE_SERVER_URL,
136
+ VITE_SERVER_URL: alchemy.env.VITE_SERVER_URL!,
133
137
  {{/if}}
134
138
  {{#if (eq dbSetup "d1")}}
135
139
  DB: db,
136
140
  {{else if (ne database "none")}}
137
- DATABASE_URL: alchemy.secret.env.DATABASE_URL,
141
+ DATABASE_URL: alchemy.secret.env.DATABASE_URL!,
138
142
  {{/if}}
139
143
  {{#if (ne backend "convex")}}
140
- CORS_ORIGIN: alchemy.env.CORS_ORIGIN,
144
+ CORS_ORIGIN: alchemy.env.CORS_ORIGIN!,
141
145
  {{#if (eq auth "better-auth")}}
142
- BETTER_AUTH_SECRET: alchemy.secret.env.BETTER_AUTH_SECRET,
143
- BETTER_AUTH_URL: alchemy.env.BETTER_AUTH_URL,
146
+ BETTER_AUTH_SECRET: alchemy.secret.env.BETTER_AUTH_SECRET!,
147
+ BETTER_AUTH_URL: alchemy.env.BETTER_AUTH_URL!,
144
148
  {{/if}}
145
149
  {{/if}}
146
150
  {{#if (eq auth "clerk")}}
147
- CLERK_SECRET_KEY: alchemy.secret.env.CLERK_SECRET_KEY,
151
+ CLERK_SECRET_KEY: alchemy.secret.env.CLERK_SECRET_KEY!,
148
152
  {{/if}}
149
- {{#if (includes examples "ai")}}
150
- GOOGLE_GENERATIVE_AI_API_KEY: alchemy.secret.env.GOOGLE_GENERATIVE_AI_API_KEY,
153
+ {{#if (and (includes examples "ai") (ne backend "convex"))}}
154
+ GOOGLE_GENERATIVE_AI_API_KEY: alchemy.secret.env.GOOGLE_GENERATIVE_AI_API_KEY!,
151
155
  {{/if}}
152
156
  {{#if (eq payments "polar")}}
153
- POLAR_ACCESS_TOKEN: alchemy.secret.env.POLAR_ACCESS_TOKEN,
154
- POLAR_SUCCESS_URL: alchemy.env.POLAR_SUCCESS_URL,
157
+ POLAR_ACCESS_TOKEN: alchemy.secret.env.POLAR_ACCESS_TOKEN!,
158
+ POLAR_SUCCESS_URL: alchemy.env.POLAR_SUCCESS_URL!,
155
159
  {{/if}}
156
160
  {{#if (eq dbSetup "turso")}}
157
- DATABASE_AUTH_TOKEN: alchemy.secret.env.DATABASE_AUTH_TOKEN,
161
+ DATABASE_AUTH_TOKEN: alchemy.secret.env.DATABASE_AUTH_TOKEN!,
158
162
  {{/if}}
159
163
  {{#if (eq database "mysql")}}
160
164
  {{#if (eq orm "drizzle")}}
161
- DATABASE_HOST: alchemy.env.DATABASE_HOST,
162
- DATABASE_USERNAME: alchemy.env.DATABASE_USERNAME,
163
- DATABASE_PASSWORD: alchemy.secret.env.DATABASE_PASSWORD,
165
+ DATABASE_HOST: alchemy.env.DATABASE_HOST!,
166
+ DATABASE_USERNAME: alchemy.env.DATABASE_USERNAME!,
167
+ DATABASE_PASSWORD: alchemy.secret.env.DATABASE_PASSWORD!,
164
168
  {{/if}}
165
169
  {{/if}}
166
170
  }
167
171
  });
168
172
  {{else if (includes frontend "tanstack-router")}}
169
173
  export const web = await Vite("web", {
170
- {{#if (eq serverDeploy "alchemy")}}cwd: "apps/web",{{/if}}
174
+ cwd: "../../apps/web",
171
175
  assets: "dist",
172
176
  bindings: {
173
177
  {{#if (eq backend "convex")}}
174
- VITE_CONVEX_URL: alchemy.env.VITE_CONVEX_URL,
178
+ VITE_CONVEX_URL: alchemy.env.VITE_CONVEX_URL!,
175
179
  {{#if (eq auth "better-auth")}}
176
- VITE_CONVEX_SITE_URL: alchemy.env.VITE_CONVEX_SITE_URL,
180
+ VITE_CONVEX_SITE_URL: alchemy.env.VITE_CONVEX_SITE_URL!,
177
181
  {{/if}}
178
182
  {{else if (ne backend "self")}}
179
- VITE_SERVER_URL: alchemy.env.VITE_SERVER_URL,
183
+ VITE_SERVER_URL: alchemy.env.VITE_SERVER_URL!,
180
184
  {{/if}}
181
185
  }
182
186
  });
183
187
  {{else if (includes frontend "react-router")}}
184
188
  export const web = await ReactRouter("web", {
185
- {{#if (eq serverDeploy "alchemy")}}cwd: "apps/web",{{/if}}
189
+ cwd: "../../apps/web",
186
190
  bindings: {
187
191
  {{#if (eq backend "convex")}}
188
- VITE_CONVEX_URL: alchemy.env.VITE_CONVEX_URL,
192
+ VITE_CONVEX_URL: alchemy.env.VITE_CONVEX_URL!,
189
193
  {{#if (eq auth "better-auth")}}
190
- VITE_CONVEX_SITE_URL: alchemy.env.VITE_CONVEX_SITE_URL,
194
+ VITE_CONVEX_SITE_URL: alchemy.env.VITE_CONVEX_SITE_URL!,
191
195
  {{/if}}
192
196
  {{else if (ne backend "self")}}
193
- VITE_SERVER_URL: alchemy.env.VITE_SERVER_URL,
197
+ VITE_SERVER_URL: alchemy.env.VITE_SERVER_URL!,
194
198
  {{/if}}
195
199
  }
196
200
  });
197
201
  {{else if (includes frontend "solid")}}
198
202
  export const web = await Vite("web", {
199
- {{#if (eq serverDeploy "alchemy")}}cwd: "apps/web",{{/if}}
203
+ cwd: "../../apps/web",
200
204
  assets: "dist",
201
205
  bindings: {
202
206
  {{#if (eq backend "convex")}}
203
- VITE_CONVEX_URL: alchemy.env.VITE_CONVEX_URL,
207
+ VITE_CONVEX_URL: alchemy.env.VITE_CONVEX_URL!,
204
208
  {{#if (eq auth "better-auth")}}
205
- VITE_CONVEX_SITE_URL: alchemy.env.VITE_CONVEX_SITE_URL,
209
+ VITE_CONVEX_SITE_URL: alchemy.env.VITE_CONVEX_SITE_URL!,
206
210
  {{/if}}
207
211
  {{else if (ne backend "self")}}
208
- VITE_SERVER_URL: alchemy.env.VITE_SERVER_URL,
212
+ VITE_SERVER_URL: alchemy.env.VITE_SERVER_URL!,
209
213
  {{/if}}
210
214
  }
211
215
  });
212
216
  {{/if}}
213
217
  {{/if}}
214
218
 
215
- {{#if (eq serverDeploy "alchemy")}}
219
+ {{#if (eq serverDeploy "cloudflare")}}
216
220
  export const server = await Worker("server", {
217
- {{#if (eq webDeploy "alchemy")}}cwd: "apps/server",{{/if}}
221
+ cwd: "../../apps/server",
218
222
  entrypoint: "src/index.ts",
219
223
  compatibility: "node",
220
224
  bindings: {
221
225
  {{#if (eq dbSetup "d1")}}
222
226
  DB: db,
223
227
  {{else if (ne database "none")}}
224
- DATABASE_URL: alchemy.secret.env.DATABASE_URL,
228
+ DATABASE_URL: alchemy.secret.env.DATABASE_URL!,
225
229
  {{/if}}
226
- CORS_ORIGIN: alchemy.env.CORS_ORIGIN,
230
+ CORS_ORIGIN: alchemy.env.CORS_ORIGIN!,
227
231
  {{#if (eq auth "better-auth")}}
228
- BETTER_AUTH_SECRET: alchemy.secret.env.BETTER_AUTH_SECRET,
229
- BETTER_AUTH_URL: alchemy.env.BETTER_AUTH_URL,
232
+ BETTER_AUTH_SECRET: alchemy.secret.env.BETTER_AUTH_SECRET!,
233
+ BETTER_AUTH_URL: alchemy.env.BETTER_AUTH_URL!,
230
234
  {{/if}}
231
235
  {{#if (eq auth "clerk")}}
232
- CLERK_SECRET_KEY: alchemy.secret.env.CLERK_SECRET_KEY,
236
+ CLERK_SECRET_KEY: alchemy.secret.env.CLERK_SECRET_KEY!,
233
237
  {{/if}}
234
238
  {{#if (includes examples "ai")}}
235
- GOOGLE_GENERATIVE_AI_API_KEY: alchemy.secret.env.GOOGLE_GENERATIVE_AI_API_KEY,
239
+ GOOGLE_GENERATIVE_AI_API_KEY: alchemy.secret.env.GOOGLE_GENERATIVE_AI_API_KEY!,
236
240
  {{/if}}
237
241
  {{#if (eq payments "polar")}}
238
- POLAR_ACCESS_TOKEN: alchemy.secret.env.POLAR_ACCESS_TOKEN,
239
- POLAR_SUCCESS_URL: alchemy.env.POLAR_SUCCESS_URL,
242
+ POLAR_ACCESS_TOKEN: alchemy.secret.env.POLAR_ACCESS_TOKEN!,
243
+ POLAR_SUCCESS_URL: alchemy.env.POLAR_SUCCESS_URL!,
240
244
  {{/if}}
241
245
  {{#if (eq dbSetup "turso")}}
242
- DATABASE_AUTH_TOKEN: alchemy.secret.env.DATABASE_AUTH_TOKEN,
246
+ DATABASE_AUTH_TOKEN: alchemy.secret.env.DATABASE_AUTH_TOKEN!,
243
247
  {{/if}}
244
248
  {{#if (eq database "mysql")}}
245
249
  {{#if (eq orm "drizzle")}}
246
- DATABASE_HOST: alchemy.env.DATABASE_HOST,
247
- DATABASE_USERNAME: alchemy.env.DATABASE_USERNAME,
248
- DATABASE_PASSWORD: alchemy.secret.env.DATABASE_PASSWORD,
250
+ DATABASE_HOST: alchemy.env.DATABASE_HOST!,
251
+ DATABASE_USERNAME: alchemy.env.DATABASE_USERNAME!,
252
+ DATABASE_PASSWORD: alchemy.secret.env.DATABASE_PASSWORD!,
249
253
  {{/if}}
250
254
  {{/if}}
251
255
  },
@@ -255,12 +259,12 @@ export const server = await Worker("server", {
255
259
  });
256
260
  {{/if}}
257
261
 
258
- {{#if (and (eq webDeploy "alchemy") (eq serverDeploy "alchemy"))}}
262
+ {{#if (and (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare"))}}
259
263
  console.log(`Web -> ${web.url}`);
260
264
  console.log(`Server -> ${server.url}`);
261
- {{else if (eq webDeploy "alchemy")}}
265
+ {{else if (eq webDeploy "cloudflare")}}
262
266
  console.log(`Web -> ${web.url}`);
263
- {{else if (eq serverDeploy "alchemy")}}
267
+ {{else if (eq serverDeploy "cloudflare")}}
264
268
  console.log(`Server -> ${server.url}`);
265
269
  {{/if}}
266
270
 
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "@{{projectName}}/infra",
3
+ "private": true,
4
+ "type": "module",
5
+ "scripts": {
6
+ "dev": "alchemy dev",
7
+ "deploy": "alchemy deploy",
8
+ "destroy": "alchemy destroy"
9
+ }
10
+ }
@@ -1,6 +1,7 @@
1
1
  import { Polar } from "@polar-sh/sdk";
2
+ import { env } from "@{{projectName}}/env/server";
2
3
 
3
4
  export const polarClient = new Polar({
4
- accessToken: process.env.POLAR_ACCESS_TOKEN,
5
- server: "sandbox",
5
+ accessToken: env.POLAR_ACCESS_TOKEN,
6
+ server: "sandbox",
6
7
  });