Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion packages/core/supabase-js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ export {
} from '@supabase/functions-js'
export * from '@supabase/realtime-js'
export { default as SupabaseClient } from './SupabaseClient'
export type { SupabaseClientOptions, QueryResult, QueryData, QueryError } from './lib/types'
export type {
SupabaseClientOptions,
QueryResult,
QueryData,
QueryError,
DatabaseWithoutInternals,
} from './lib/types'

/**
* Creates a new Supabase Client.
Expand Down
14 changes: 14 additions & 0 deletions packages/core/supabase-js/src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,17 @@ export type SupabaseClientOptions<SchemaName> = {
export type QueryResult<T> = T extends PromiseLike<infer U> ? U : never
export type QueryData<T> = T extends PromiseLike<{ data: infer U }> ? Exclude<U, null> : never
export type QueryError = PostgrestError

/** @internal Key used for Supabase internal metadata in Database types. */
type InternalSupabaseKey = '__InternalSupabase'

/**
* Strips internal Supabase metadata from Database types.
* Useful for libraries defining generic constraints on Database types.
*
* @example
* ```typescript
* type CleanDB = DatabaseWithoutInternals<Database>
* ```
*/
export type DatabaseWithoutInternals<DB> = Omit<DB, InternalSupabaseKey>
46 changes: 45 additions & 1 deletion packages/core/supabase-js/test/types/index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { expectError, expectType } from 'tsd'
import { PostgrestSingleResponse, SupabaseClient, createClient } from '../../src/index'
import {
PostgrestSingleResponse,
SupabaseClient,
createClient,
DatabaseWithoutInternals,
} from '../../src/index'
import { Database, Json } from '../types'

const URL = 'http://localhost:3000'
Expand Down Expand Up @@ -265,3 +270,42 @@ const supabase = createClient<Database>(URL, KEY)
// @ts-expect-error should raise error if providing table name not in the schema
pg13CustomSchemaClient.from('channels_details')
}

// DatabaseWithoutInternals utility type
{
type TestDatabaseWithInternals = {
__InternalSupabase: {
PostgrestVersion: '14'
}
public: {
Tables: {
users: {
Row: { id: number }
Insert: { id: number }
Update: { id?: number }
Relationships: []
}
}
Views: { [_ in never]: never }
Functions: { [_ in never]: never }
Enums: { [_ in never]: never }
CompositeTypes: { [_ in never]: never }
}
}

type CleanedDatabase = DatabaseWithoutInternals<TestDatabaseWithInternals>

// Should have 'public' schema
expectType<CleanedDatabase['public']>({} as TestDatabaseWithInternals['public'])

// Should not have '__InternalSupabase' key
type HasInternalKey = '__InternalSupabase' extends keyof CleanedDatabase ? true : false
expectType<HasInternalKey>(false)

// Should work with databases that don't have __InternalSupabase
type PlainDatabase = {
public: { Tables: {}; Views: {}; Functions: {}; Enums: {}; CompositeTypes: {} }
}
type CleanedPlainDatabase = DatabaseWithoutInternals<PlainDatabase>
expectType<CleanedPlainDatabase>({} as PlainDatabase)
}