Skip to content

Commit 5a0a15b

Browse files
fix(template-generator): isolate tanstack start auth state
1 parent e1bdb1f commit 5a0a15b

9 files changed

Lines changed: 459 additions & 161 deletions

File tree

apps/cli/test/api.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,49 @@ describe("API Configurations", () => {
576576
);
577577
});
578578

579+
it("should scaffold TanStack Start oRPC with a request-scoped query client", async () => {
580+
const result = await createVirtual({
581+
projectName: "tanstack-start-orpc-auth-workers",
582+
api: "orpc",
583+
frontend: ["tanstack-start"],
584+
backend: "hono",
585+
runtime: "workers",
586+
database: "sqlite",
587+
orm: "prisma",
588+
auth: "better-auth",
589+
payments: "none",
590+
addons: ["turborepo"],
591+
examples: ["todo"],
592+
dbSetup: "d1",
593+
webDeploy: "cloudflare",
594+
serverDeploy: "cloudflare",
595+
install: false,
596+
git: false,
597+
packageManager: "bun",
598+
});
599+
600+
if (result.isErr()) {
601+
throw result.error;
602+
}
603+
604+
const files = collectFiles(result.value.root, result.value.root.path);
605+
const orpcFile = files.get("apps/web/src/utils/orpc.ts");
606+
const routerFile = files.get("apps/web/src/router.tsx");
607+
const dashboardFile = files.get("apps/web/src/routes/dashboard.tsx");
608+
609+
expect(orpcFile).toContain("export function createQueryClient()");
610+
expect(orpcFile).toContain("defaultOptions: { queries: { staleTime: 60 * 1000 } },");
611+
expect(orpcFile).toContain("void query.invalidate();");
612+
expect(orpcFile).not.toContain("onClick: query.invalidate");
613+
expect(orpcFile).not.toContain("export const queryClient");
614+
expect(routerFile).toContain('import { createQueryClient, orpc } from "./utils/orpc";');
615+
expect(routerFile).toContain("const queryClient = createQueryClient();");
616+
expect(dashboardFile).toContain("ssr: false");
617+
expect(dashboardFile).toContain("const session = await authClient.getSession();");
618+
expect(dashboardFile).toContain("session.data?.user.name");
619+
expect(dashboardFile).not.toContain('import { getUser } from "@/functions/get-user";');
620+
});
621+
579622
it("should handle API with complex frontend combinations", async () => {
580623
const result = await runTRPCTest({
581624
projectName: "api-complex-frontend",

apps/cli/test/auth.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,40 @@ describe("Authentication Configurations", () => {
183183
expect(authFile).toContain("tanstackStartCookies()");
184184
});
185185

186+
it("should guard TanStack Start self dashboard before loading Polar payment state", async () => {
187+
const result = await runTRPCTest({
188+
projectName: "better-auth-tanstack-start-self-polar-guard",
189+
auth: "better-auth",
190+
backend: "self",
191+
runtime: "none",
192+
database: "postgres",
193+
orm: "drizzle",
194+
api: "orpc",
195+
frontend: ["tanstack-start"],
196+
payments: "polar",
197+
addons: ["none"],
198+
examples: ["none"],
199+
dbSetup: "none",
200+
webDeploy: "none",
201+
serverDeploy: "none",
202+
install: false,
203+
});
204+
205+
expectSuccess(result);
206+
if (!result.projectDir) {
207+
throw new Error("Expected projectDir to be defined");
208+
}
209+
210+
const dashboardFile = await fs.readFile(
211+
path.join(result.projectDir, "apps/web/src/routes/dashboard.tsx"),
212+
"utf8",
213+
);
214+
215+
expect(dashboardFile.indexOf("if (!session)")).toBeLessThan(
216+
dashboardFile.indexOf("const customerState = await getPayment();"),
217+
);
218+
});
219+
186220
it("should fail with better-auth + no database (non-convex)", async () => {
187221
const result = await runTRPCTest({
188222
projectName: "better-auth-no-db-fail",

apps/cli/test/deployment.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,42 @@ describe("Deployment Configurations", () => {
340340
expectSuccess(result);
341341
});
342342

343+
it("should wire Cloudflare web deploys to the generated server Worker URL", async () => {
344+
const result = await createVirtual({
345+
projectName: "tanstack-start-hono-cloudflare-auth",
346+
webDeploy: "cloudflare",
347+
serverDeploy: "cloudflare",
348+
backend: "hono",
349+
runtime: "workers",
350+
database: "sqlite",
351+
orm: "prisma",
352+
auth: "better-auth",
353+
payments: "none",
354+
api: "orpc",
355+
frontend: ["tanstack-start"],
356+
addons: ["turborepo"],
357+
examples: ["todo"],
358+
dbSetup: "d1",
359+
install: false,
360+
git: false,
361+
packageManager: "bun",
362+
});
363+
364+
if (result.isErr()) {
365+
throw result.error;
366+
}
367+
368+
const files = collectFiles(result.value.root, result.value.root.path);
369+
const infraFile = files.get("packages/infra/alchemy.run.ts");
370+
371+
expect(infraFile).toContain('export const server = await Worker("server"');
372+
expect(infraFile).toContain("url: true");
373+
expect(infraFile).toContain("VITE_SERVER_URL: server.url!");
374+
expect(infraFile!.indexOf('export const server = await Worker("server"')).toBeLessThan(
375+
infraFile!.indexOf('export const web = await TanStackStart("web"'),
376+
);
377+
});
378+
343379
it("should keep native Metro from watching Alchemy state", async () => {
344380
const result = await createVirtual({
345381
projectName: "native-astro-alchemy",

0 commit comments

Comments
 (0)