Commit Graph
9 Commits
Author SHA1 Message Date
Alaister Young 63b98c055d chore(studio): port remaining auth pages to TanStack routes
Re-exports sign-up, sign-in-sso, sign-in-partner, sign-in-mfa,
forgot-password(-mfa), reset-password, cli/login, and the Stripe
partners login page under `routes/_auth/`. Each wrapper replicates the
page's `getLayout` treatment; pages that inline their own layout are
rendered directly. `withAuth`-wrapped default exports stay intact.

Also hardens `compat/next/link.tsx` to accept Next's `UrlObject`
(`{pathname, query, hash}`) href form — sign-in.tsx uses this to forward
`router.query` into SSO/sign-up links, and the old shim was coercing it
to "[object Object]". Anchor attrs and `replace` now spread through;
remaining Next-only props are dropped silently.
2026-04-21 19:32:02 +08:00
Alaister Young 2428cfd3b5 chore(studio): shim next/server in Vite compat layer
Two App Router routes (incident-banner, incident-status) and a few
type-only uses elsewhere import from 'next/server'. The Vite
nextCompat guard was 500ing on the build. Shim exposes
NextResponse.json (the only value surface used) and a type alias
NextRequest = Request.
2026-04-21 19:14:15 +08:00
Alaister Young 387e9b1385 chore(studio): migrate Next API routes to TanStack server routes
Adds `compat/next/api.ts` exposing `toWebHandler(nextHandler)`: an
adapter that builds a NextApiRequest-shaped object from a Web
`Request` (lowercased headers, parsed cookies, merged query + route
params, JSON/urlencoded body parsing) and a NextApiResponse proxy
capturing `status` / `setHeader` / `json` / `send` / `write` / `end`
/ `redirect`. Handler output is buffered then returned as a Web
`Response`. Handlers that already return a `Response` (edge-runtime
style) pass through unchanged.

Each ported route in `routes/api/**` is a 9-line re-export: import
the default export from `pages/api/...`, wrap with `toWebHandler`,
register under `server.handlers.{GET,POST,...}`. `apiWrapper` and
`apiAuthenticate` stay untouched — they run inside the shim seeing
the shaped `req`/`res`.

Coverage: 88 of the 90 `pages/api/**` handlers. The two exceptions
need bespoke rewrites and are tracked in TANSTACK_MIGRATION.md:
- `v1/projects/[ref]/functions/[slug]/body.ts` — pipes
  `fs.createReadStream` into `res`; needs a Web-stream rewrite.
- `mcp/index.ts` — the MCP SDK transport expects Node req/res; need
  to check for a Web-fetch transport option.

Also adds `query` (params + search) to the existing `next/router`
shim to unblock components like FeedbackDropdown that read
`router.query.ref`.
2026-04-21 19:04:59 +08:00
Alaister Young 7058506661 chore(studio): migrate account/me and sign-in to TanStack routes
First two pages ported under the minimum-diff Path A strategy: the
TanStack route wraps the page default-exported from pages/ rather
than rewriting the body. Layout chains provided by pathless _app /
_auth pathless routes + sibling-file layouts, reading per-leaf props
(AccountLayout title, DefaultLayout headerTitle) from route
staticData via useMatches.

Supporting fixes:
- compat/next/router: add `query` (params + search) so components
  like FeedbackDropdown that read `router.query.ref` keep working
  under the shim.
- ConnectSheet content loader: switch to `import.meta.glob` for
  Vite (the template path spans multiple directories so
  dynamic-import-vars can't analyse it), guarded with
  `import.meta.env.SSR` to keep the 37 content modules out of the
  SSR graph — they reshuffle chunks enough to surface circular-dep
  bugs in unrelated modules. Next/webpack falls through a try/catch
  to the existing `import(\`./content/\${filePath}/content\`)`.

TANSTACK_MIGRATION.md tracks per-page status during the migration.
2026-04-21 18:41:40 +08:00
Alaister Young 7b6c11ec72 chore(studio): port RouteValidationWrapper
Extends next/router shims to expose router.pathname as the route
pattern (Next pages-router semantics) rather than the resolved URL,
by converting TanStack's matched route id ($param → [param]). Also
adds push/replace/asPath to the next/router shim so consumers like
RouteValidationWrapper can keep working unchanged.
2026-04-21 17:35:51 +08:00
Alaister Young 055c1e2df8 chore(studio): port MonacoThemeProvider + monaco loader config
Also adds next/legacy/image and useSearchParams shims that the build
uncovered, and bumps @radix-ui/react-visually-hidden to ^1.2.3 so
react-select's import of VISUALLY_HIDDEN_STYLES resolves at runtime.
2026-04-21 17:12:09 +08:00
Alaister Young 6dbcc27767 chore(studio): port StudioCommandProvider + expose router.events in next shims
- Wrap Outlet with StudioCommandProvider (imported as CommandProvider,
  matching pages/_app.tsx) inside AiAssistantStateContextProvider so
  the command menu context works in the Vite build.
- Add an events adapter to both next/router and next/compat/router
  shims so workspace code that does router.events.on('routeChangeX')
  (CommandProvider, telemetry, usePreventNavigationOnUnsavedChanges,
  QueryInsightsTable, ...) doesn't crash on `.on` of undefined.
  Subscriptions proxy to TanStack Router's router.subscribe
  (routeChangeStart -> onBeforeLoad, routeChangeComplete -> onResolved)
  and .off unsubscribes by handler identity. The proxy is cached per
  router instance via a WeakMap so effect deps stay stable.
2026-04-21 16:52:56 +08:00
Alaister Young 853364a1de chore(studio): port DevToolbarProvider to TanStack root route
- Wrap Outlet with DevToolbarProvider from 'dev-tools' inside the
  ThemeProvider, and render <DevToolbar extraTabs={...} /> +
  <DevToolbarTrigger /> as siblings, mirroring pages/_app.tsx.
- Guard everything behind IS_DEV_TOOLBAR_ENABLED (NEXT_PUBLIC_ENVIRONMENT
  in {local, staging}) so prod bundles tree-shake the dev-only code.
- Use React.lazy + Suspense directly for ResourceWarningsTab since
  __root.tsx is new code we control — the compat shim is only for
  existing workspace code that still imports next/dynamic.
- Add the next/dynamic -> compat/next/dynamic.tsx entry to nextShims
  so any workspace file pulled transitively (e.g. common, ui-patterns)
  keeps working via the compat layer. Shim proxies to React.lazy +
  Suspense and honours the ssr: false option.
2026-04-21 16:42:56 +08:00
Alaister Young 339316c721 chore(studio): port global error boundary to TanStack root + next compat shims
- Wire ErrorBoundary + Sentry-aware handler into routes/__root.tsx to
  mirror pages/_app.tsx; switch the handler's Sentry import to
  framework-agnostic @sentry/react.
- Add apps/studio/compat/next/ shims (link, router, head, navigation,
  image, script, compat/router) that proxy to TanStack Router
  equivalents. Shims implement only the surface used today; expand as
  new usage appears.
- Combine shim aliasing and a build-time guard into a single Vite
  plugin (nextCompat): resolves shimmed next/* ids to local files, and
  fails the build on any unshimmed next/* import from workspace source
  so we catch regressions during the migration.
- ssr.noExternal lodash to fix CJS named-export interop during
  prerender.
2026-04-21 15:43:14 +08:00