Skip to content

Commit e953e71

Browse files
7ttpmandarini
andauthored
feat(supabase): export DatabaseWithoutInternals utility type (#1935)
Co-authored-by: Katerina Skroumpelou <[email protected]>
1 parent efca12c commit e953e71

File tree

3 files changed

+66
-2
lines changed

3 files changed

+66
-2
lines changed

packages/core/supabase-js/src/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,13 @@ export {
1919
} from '@supabase/functions-js'
2020
export * from '@supabase/realtime-js'
2121
export { default as SupabaseClient } from './SupabaseClient'
22-
export type { SupabaseClientOptions, QueryResult, QueryData, QueryError } from './lib/types'
22+
export type {
23+
SupabaseClientOptions,
24+
QueryResult,
25+
QueryData,
26+
QueryError,
27+
DatabaseWithoutInternals,
28+
} from './lib/types'
2329

2430
/**
2531
* Creates a new Supabase Client.

packages/core/supabase-js/src/lib/types.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,17 @@ export type SupabaseClientOptions<SchemaName> = {
135135
export type QueryResult<T> = T extends PromiseLike<infer U> ? U : never
136136
export type QueryData<T> = T extends PromiseLike<{ data: infer U }> ? Exclude<U, null> : never
137137
export type QueryError = PostgrestError
138+
139+
/** @internal Key used for Supabase internal metadata in Database types. */
140+
type InternalSupabaseKey = '__InternalSupabase'
141+
142+
/**
143+
* Strips internal Supabase metadata from Database types.
144+
* Useful for libraries defining generic constraints on Database types.
145+
*
146+
* @example
147+
* ```typescript
148+
* type CleanDB = DatabaseWithoutInternals<Database>
149+
* ```
150+
*/
151+
export type DatabaseWithoutInternals<DB> = Omit<DB, InternalSupabaseKey>

packages/core/supabase-js/test/types/index.test-d.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { expectError, expectType } from 'tsd'
2-
import { PostgrestSingleResponse, SupabaseClient, createClient } from '../../src/index'
2+
import {
3+
PostgrestSingleResponse,
4+
SupabaseClient,
5+
createClient,
6+
DatabaseWithoutInternals,
7+
} from '../../src/index'
38
import { Database, Json } from '../types'
49

510
const URL = 'http://localhost:3000'
@@ -265,3 +270,42 @@ const supabase = createClient<Database>(URL, KEY)
265270
// @ts-expect-error should raise error if providing table name not in the schema
266271
pg13CustomSchemaClient.from('channels_details')
267272
}
273+
274+
// DatabaseWithoutInternals utility type
275+
{
276+
type TestDatabaseWithInternals = {
277+
__InternalSupabase: {
278+
PostgrestVersion: '14'
279+
}
280+
public: {
281+
Tables: {
282+
users: {
283+
Row: { id: number }
284+
Insert: { id: number }
285+
Update: { id?: number }
286+
Relationships: []
287+
}
288+
}
289+
Views: { [_ in never]: never }
290+
Functions: { [_ in never]: never }
291+
Enums: { [_ in never]: never }
292+
CompositeTypes: { [_ in never]: never }
293+
}
294+
}
295+
296+
type CleanedDatabase = DatabaseWithoutInternals<TestDatabaseWithInternals>
297+
298+
// Should have 'public' schema
299+
expectType<CleanedDatabase['public']>({} as TestDatabaseWithInternals['public'])
300+
301+
// Should not have '__InternalSupabase' key
302+
type HasInternalKey = '__InternalSupabase' extends keyof CleanedDatabase ? true : false
303+
expectType<HasInternalKey>(false)
304+
305+
// Should work with databases that don't have __InternalSupabase
306+
type PlainDatabase = {
307+
public: { Tables: {}; Views: {}; Functions: {}; Enums: {}; CompositeTypes: {} }
308+
}
309+
type CleanedPlainDatabase = DatabaseWithoutInternals<PlainDatabase>
310+
expectType<CleanedPlainDatabase>({} as PlainDatabase)
311+
}

0 commit comments

Comments
 (0)