mirror of
https://github.com/supabase/server.git
synced 2026-09-14 15:28:52 +08:00
fix(jsr): resolve slow-type errors in elysia and h3 adapters (#69)
* fix(jsr): resolve slow-type errors in elysia and h3 adapters * chore(lint): disable no-empty-object-type for elysia plugin return type
This commit is contained in:
@@ -10,6 +10,20 @@ pnpm add h3
|
||||
|
||||
The adapter exports its own `withSupabase` that returns H3 middleware instead of a fetch handler. Works with standalone H3 servers and Nuxt server routes (which run on H3 under the hood).
|
||||
|
||||
## Typing `event.context.supabaseContext`
|
||||
|
||||
The middleware stores the context on `event.context.supabaseContext`. Add this declaration once in your project (e.g. in `types/h3.d.ts`) for typed access:
|
||||
|
||||
```ts
|
||||
import type { SupabaseContext } from '@supabase/server'
|
||||
|
||||
declare module 'h3' {
|
||||
interface H3EventContext {
|
||||
supabaseContext: SupabaseContext
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Basic app with auth
|
||||
|
||||
```ts
|
||||
|
||||
@@ -4,4 +4,4 @@
|
||||
* @packageDocumentation
|
||||
*/
|
||||
|
||||
export { withSupabase } from './plugin.js'
|
||||
export { SupabaseError, withSupabase } from './plugin.js'
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Elysia } from 'elysia'
|
||||
import { Elysia, type ExtractErrorFromHandle } from 'elysia'
|
||||
|
||||
import { createSupabaseContext } from '../../create-supabase-context.js'
|
||||
import type { AuthError } from '../../errors.js'
|
||||
import type { SupabaseContext, WithSupabaseConfig } from '../../types.js'
|
||||
|
||||
class SupabaseError extends Error {
|
||||
export class SupabaseError extends Error {
|
||||
status: number
|
||||
declare cause: AuthError
|
||||
constructor(inner: AuthError) {
|
||||
@@ -56,7 +56,39 @@ class SupabaseError extends Error {
|
||||
* app.listen(3000)
|
||||
* ```
|
||||
*/
|
||||
export function withSupabase(config?: Omit<WithSupabaseConfig, 'cors'>) {
|
||||
// The explicit return type below mirrors Elysia's own generic defaults, which use
|
||||
// `{}` literals — switching to `object` or `Record<string, never>` would not satisfy
|
||||
// the corresponding generic constraints.
|
||||
/* eslint-disable @typescript-eslint/no-empty-object-type */
|
||||
export function withSupabase(config?: Omit<WithSupabaseConfig, 'cors'>): Elysia<
|
||||
'',
|
||||
{ decorator: {}; store: {}; derive: {}; resolve: {} },
|
||||
{ typebox: {}; error: { readonly SupabaseError: SupabaseError } },
|
||||
{
|
||||
schema: {}
|
||||
standaloneSchema: {}
|
||||
macro: {}
|
||||
macroFn: {}
|
||||
parser: {}
|
||||
response: {}
|
||||
},
|
||||
{},
|
||||
{
|
||||
derive: {}
|
||||
resolve: { supabaseContext: SupabaseContext }
|
||||
schema: {}
|
||||
standaloneSchema: {}
|
||||
response: ExtractErrorFromHandle<{ supabaseContext: SupabaseContext }>
|
||||
},
|
||||
{
|
||||
derive: {}
|
||||
resolve: {}
|
||||
schema: {}
|
||||
standaloneSchema: {}
|
||||
response: {}
|
||||
}
|
||||
> {
|
||||
/* eslint-enable @typescript-eslint/no-empty-object-type */
|
||||
return new Elysia()
|
||||
.error({ SupabaseError })
|
||||
.resolve(async (ctx): Promise<{ supabaseContext: SupabaseContext }> => {
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
import { H3, HTTPError, onError } from 'h3'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import type { SupabaseContext } from '../../types.js'
|
||||
|
||||
import { withSupabase } from './middleware.js'
|
||||
|
||||
declare module 'h3' {
|
||||
interface H3EventContext {
|
||||
supabaseContext: SupabaseContext
|
||||
}
|
||||
}
|
||||
|
||||
describe('h3 supabase middleware', () => {
|
||||
const env = {
|
||||
url: 'https://test.supabase.co',
|
||||
|
||||
@@ -47,18 +47,13 @@ export function withSupabase(
|
||||
config?: Omit<WithSupabaseConfig, 'cors'>,
|
||||
): Middleware {
|
||||
return defineMiddleware(async (event, next) => {
|
||||
if (event.context.supabaseContext) return next()
|
||||
const context = event.context as { supabaseContext?: SupabaseContext }
|
||||
if (context.supabaseContext) return next()
|
||||
const { data: ctx, error } = await createSupabaseContext(event.req, config)
|
||||
if (error) {
|
||||
throw new HTTPError(error.message, { status: error.status, cause: error })
|
||||
}
|
||||
event.context.supabaseContext = ctx
|
||||
context.supabaseContext = ctx
|
||||
return next()
|
||||
})
|
||||
}
|
||||
|
||||
declare module 'h3' {
|
||||
interface H3EventContext {
|
||||
supabaseContext: SupabaseContext
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user