mirror of
https://github.com/supabase/supabase.git
synced 2026-06-28 19:39:19 -04:00
e81c714aae
Extracted from the TanStack Start migration (#46424) to shrink that PR. The self-hosted storage/auth API routes each constructed a module-scope admin client (`createClient(process.env.SUPABASE_URL!, process.env.SUPABASE_SERVICE_KEY!)`). Those env vars only exist on self-hosted, so eager module-scope construction is wasteful on platform and fragile on any runtime that evaluates an API module before its route is hit (constructing with `undefined` credentials throws on import). **Changed:** - Add `lib/api/self-hosted-admin.ts` — `selfHostedSupabaseAdmin`, a `Proxy` that defers `createClient(...)` until first property access (inside a handler, i.e. on self-hosted where the vars are set). - Swap **all 17** storage/auth/vector-bucket handlers from module-scope `createClient(...)` to `import { selfHostedSupabaseAdmin as supabase }`. - **Enforce it:** add an eslint `no-restricted-syntax` rule banning module-scope `createClient` in `pages/api/**` + `routes/**` (now that every flagged handler is lazy). The same eslint config block also carries an analytics-SQL boundary rule — 0 violations on master. Behaviour is unchanged (the client is still built lazily inside the handler). This is also the change that makes those routes safe under TanStack's single-handler module evaluation. ## To test - Self-hosted Studio: storage buckets/objects, vector buckets, and auth users operations work as before. ## Verification studio lint (0 errors, both rules active) ✓ · studio typecheck ✓. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Standardized self-hosted Supabase admin client usage across platform authentication and storage endpoints, removing per-route client setup. * Improved reliability by lazily creating the admin client only when first used. * **Chores / Tooling** * Updated ESLint rules to prevent module-scope Supabase client creation in API routes and to enforce safe analytics SQL access patterns. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> Co-authored-by: Ali Waseem <waseema393@gmail.com>
23 lines
1.0 KiB
TypeScript
23 lines
1.0 KiB
TypeScript
import { createClient, SupabaseClient } from '@supabase/supabase-js'
|
|
|
|
// Lazy admin client for self-hosted API routes under
|
|
// `pages/api/platform/{auth,storage}/**`. SUPABASE_URL and
|
|
// SUPABASE_SERVICE_KEY are only set on self-hosted deployments — the
|
|
// platform build doesn't need these env vars. But on the TanStack Start
|
|
// server, every API route's module gets evaluated when the single function
|
|
// handler loads, regardless of whether its URL is hit. Without a lazy
|
|
// wrapper, constructing the client at module scope with undefined
|
|
// credentials would crash every request on platform.
|
|
//
|
|
// Proxy defers client construction until a property is actually accessed,
|
|
// which only happens inside the handler (i.e. on self-hosted where the env
|
|
// vars are set).
|
|
let _client: SupabaseClient | undefined
|
|
|
|
export const selfHostedSupabaseAdmin = new Proxy({} as SupabaseClient, {
|
|
get(_target, prop) {
|
|
_client ??= createClient(process.env.SUPABASE_URL!, process.env.SUPABASE_SERVICE_KEY!)
|
|
return Reflect.get(_client, prop)
|
|
},
|
|
})
|