mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-30 21:01:54 +08:00
## Summary - Adds the generated `@stackframe/tanstack-start` workspace package registration. - Adds TanStack Start platform macros/dependencies to the SDK template and generator. - Adds TanStack Start cookie/token-store support plus the handler SSR guard needed by Start. ## Scope This intentionally excludes Dashboard V2 routes, hooks, components, app shell logic, and dashboard API type additions. Those stay in the existing dashboard PR/branch. ## Validation - `pnpm install --lockfile-only --ignore-scripts` - `pnpm install --ignore-scripts` - `pnpm -C packages/template lint src/components-page/stack-handler-client.tsx src/lib/cookie.ts src/lib/stack-app/apps/implementations/client-app-impl.ts` Package typecheck was attempted with `pnpm -C packages/template typecheck`, but the clean worktree lacks generated package declaration outputs for workspace dependencies such as `@stackframe/stack-shared` and `@stackframe/stack-ui`. Per repo instructions, package builds/codegen are not run by agents. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * TanStack Start integration: published SDK package, example demo app, dashboard onboarding flow, framework-aware CTAs/docs, and a TanStack-specific provider for client-only auth routes. * Improved client/server auth: safer runtime guards and consistent cookie/token-store behavior across SSR and client. * **Documentation** * New Integrations guide and expanded getting-started/setup docs with TanStack Start examples and env/key guidance. * **Chores** * Template, build, tooling, and demo config updates to support the new platform. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
95 lines
2.9 KiB
TypeScript
95 lines
2.9 KiB
TypeScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
|
|
import viteReact from "@vitejs/plugin-react";
|
|
import { defineConfig, type Plugin } from "vite";
|
|
import { nitro } from "nitro/vite";
|
|
import tsConfigPaths from "vite-tsconfig-paths";
|
|
|
|
const stackAuthRootPath = fileURLToPath(new URL("../..", import.meta.url));
|
|
|
|
function watchNodeModules(modules: string[]): Plugin {
|
|
return {
|
|
name: "watch-node-modules",
|
|
config() {
|
|
return {
|
|
server: {
|
|
watch: {
|
|
ignored: modules.map((moduleName) => `!**/node_modules/${moduleName}/**`),
|
|
},
|
|
},
|
|
};
|
|
},
|
|
};
|
|
}
|
|
|
|
function waitForWorkspacePackages(packages: string[]): Plugin {
|
|
const packageDistEntries = packages.map((pkg) => ({
|
|
name: pkg,
|
|
entry: path.resolve(__dirname, "node_modules", pkg, "dist", "esm", "index.js"),
|
|
}));
|
|
|
|
async function waitForFile(filePath: string, timeoutMs = 60_000): Promise<void> {
|
|
if (fs.existsSync(filePath)) return;
|
|
const start = performance.now();
|
|
return await new Promise((resolve, reject) => {
|
|
const interval = setInterval(() => {
|
|
if (fs.existsSync(filePath)) {
|
|
clearInterval(interval);
|
|
resolve();
|
|
} else if (performance.now() - start > timeoutMs) {
|
|
clearInterval(interval);
|
|
reject(new Error(`Timed out waiting for ${filePath} to exist`));
|
|
}
|
|
}, 500);
|
|
});
|
|
}
|
|
|
|
return {
|
|
name: "wait-for-workspace-packages",
|
|
enforce: "pre",
|
|
async buildStart() {
|
|
const missing = packageDistEntries.filter((pkg) => !fs.existsSync(pkg.entry));
|
|
if (missing.length === 0) return;
|
|
console.log(`Waiting for workspace packages to build: ${missing.map((pkg) => pkg.name).join(", ")}`);
|
|
await Promise.all(missing.map((pkg) => waitForFile(pkg.entry)));
|
|
console.log("All workspace packages are ready.");
|
|
},
|
|
};
|
|
}
|
|
|
|
export default defineConfig(({ mode }) => {
|
|
const isVitest = mode === "test" || process.env.VITEST === "true";
|
|
|
|
return {
|
|
server: {
|
|
port: Number(`${process.env.NEXT_PUBLIC_STACK_PORT_PREFIX || "81"}43`),
|
|
fs: {
|
|
allow: [stackAuthRootPath],
|
|
},
|
|
},
|
|
resolve: {
|
|
dedupe: ["react", "react-dom"],
|
|
},
|
|
ssr: {
|
|
noExternal: [/^@stackframe\//, /^@radix-ui\//],
|
|
},
|
|
optimizeDeps: {
|
|
include: ["@stackframe/stack-shared", "@stackframe/stack-shared/config"],
|
|
},
|
|
plugins: [
|
|
...(isVitest ? [] : [
|
|
waitForWorkspacePackages(["@stackframe/tanstack-start", "@stackframe/stack-shared", "@stackframe/stack-ui"]),
|
|
watchNodeModules(["@stackframe/tanstack-start", "@stackframe/stack-shared", "@stackframe/stack-ui"]),
|
|
]),
|
|
tsConfigPaths(),
|
|
...(isVitest ? [] : [
|
|
tanstackStart(),
|
|
nitro(),
|
|
]),
|
|
viteReact(),
|
|
],
|
|
};
|
|
});
|