Skip to content

Commit fa63bdf

Browse files
committed
feat: handle options declaration within Database
1 parent ceae114 commit fa63bdf

File tree

8 files changed

+887
-23
lines changed

8 files changed

+887
-23
lines changed

src/PostgrestClient.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import PostgrestQueryBuilder from './PostgrestQueryBuilder'
22
import PostgrestFilterBuilder from './PostgrestFilterBuilder'
33
import PostgrestBuilder from './PostgrestBuilder'
44
import { DEFAULT_HEADERS } from './constants'
5-
import { Fetch, GenericSchema, ClientServerOptions } from './types'
5+
import { Fetch, GenericSchema, ClientServerOptions, GetGenericDatabaseWithOptions } from './types'
66

77
/**
88
* PostgREST client.
@@ -16,12 +16,13 @@ import { Fetch, GenericSchema, ClientServerOptions } from './types'
1616
*/
1717
export default class PostgrestClient<
1818
Database = any,
19-
ClientOptions extends ClientServerOptions = { postgrestVersion: 12 },
20-
SchemaName extends string & keyof Database = 'public' extends keyof Database
19+
ClientOptions extends ClientServerOptions = GetGenericDatabaseWithOptions<Database>['options'],
20+
SchemaName extends string &
21+
keyof GetGenericDatabaseWithOptions<Database>['db'] = 'public' extends keyof GetGenericDatabaseWithOptions<Database>['db']
2122
? 'public'
22-
: string & keyof Database,
23-
Schema extends GenericSchema = Database[SchemaName] extends GenericSchema
24-
? Database[SchemaName]
23+
: string & keyof GetGenericDatabaseWithOptions<Database>['db'],
24+
Schema extends GenericSchema = GetGenericDatabaseWithOptions<Database>['db'][SchemaName] extends GenericSchema
25+
? GetGenericDatabaseWithOptions<Database>['db'][SchemaName]
2526
: any
2627
> {
2728
url: string
@@ -85,7 +86,7 @@ export default class PostgrestClient<
8586
*
8687
* @param schema - The schema to query
8788
*/
88-
schema<DynamicSchema extends string & keyof Database>(
89+
schema<DynamicSchema extends string & keyof GetGenericDatabaseWithOptions<Database>['db']>(
8990
schema: DynamicSchema
9091
): PostgrestClient<
9192
Database,

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export type {
2929
PostgrestSingleResponse,
3030
PostgrestMaybeSingleResponse,
3131
ClientServerOptions,
32+
PostgRESTVersion,
3233
} from './types'
3334
// https://github.com/supabase/postgrest-js/issues/551
3435
// To be replaced with a helper type that only uses public types

src/types.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import PostgrestError from './PostgrestError'
22
import { ContainsNull } from './select-query-parser/types'
3-
import { SelectQueryError } from './select-query-parser/utils'
3+
import { IsAny, SelectQueryError } from './select-query-parser/utils'
44

55
export type Fetch = typeof fetch
66

@@ -76,8 +76,28 @@ export type ClientServerOptions = {
7676
postgrestVersion?: PostgRESTVersion
7777
}
7878

79+
export type DatabaseWithOptions<Database, Options extends ClientServerOptions> = {
80+
db: Database
81+
options: Options
82+
}
83+
84+
const INTERNAL_SUPABASE_OPTIONS = '__internal_supabase'
85+
86+
export type GetGenericDatabaseWithOptions<
87+
Database,
88+
Opts extends ClientServerOptions = { postgrestVersion: 12 }
89+
> = IsAny<Database> extends true
90+
? DatabaseWithOptions<Database, Opts>
91+
: typeof INTERNAL_SUPABASE_OPTIONS extends keyof Database
92+
? DatabaseWithOptions<
93+
Omit<Database, typeof INTERNAL_SUPABASE_OPTIONS>,
94+
Database[typeof INTERNAL_SUPABASE_OPTIONS]
95+
>
96+
: DatabaseWithOptions<Database, Opts>
97+
7998
// https://twitter.com/mattpocockuk/status/1622730173446557697
8099
export type Prettify<T> = { [K in keyof T]: T[K] } & {}
100+
81101
// https://github.com/sindresorhus/type-fest
82102
export type SimplifyDeep<Type, ExcludeType = never> = ConditionalSimplifyDeep<
83103
Type,

test/index.test-d.ts

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import { PostgrestClient, PostgrestError } from '../src/index'
44
import { Prettify } from '../src/types'
55
import { Json } from '../src/select-query-parser/types'
66
import { Database } from './types.override'
7+
import { Database as DatabaseWithOptions } from './types.override-with-options-postgrest13'
78

89
const REST_URL = 'http://localhost:3000'
910
const postgrest = new PostgrestClient<Database>(REST_URL)
11+
const postgrestWithOptions = new PostgrestClient<DatabaseWithOptions>(REST_URL)
1012

1113
// table invalid type
1214
{
@@ -295,20 +297,9 @@ const postgrest = new PostgrestClient<Database>(REST_URL)
295297
}[]
296298
>(result.data)
297299
}
298-
// Json string Accessor with custom types overrides
300+
// Check that client options __internal_supabase isn't considered like the other schemas
299301
{
300-
const result = await postgrest
301-
.schema('personal')
302-
.from('users')
303-
.select('data->bar->>baz, data->>en, data->>bar')
304-
if (result.error) {
305-
throw new Error(result.error.message)
306-
}
307-
expectType<
308-
{
309-
baz: string
310-
en: 'ONE' | 'TWO' | 'THREE'
311-
bar: string
312-
}[]
313-
>(result.data)
302+
await postgrestWithOptions
303+
// @ts-expect-error supabase internal shouldn't be available as one of the selectable schema
304+
.schema('__internal_supabase')
314305
}

test/relationships.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { PostgrestClient } from '../src/index'
22
import { Database } from './types.override'
3+
import { Database as DatabaseWithOptions13 } from './types.override-with-options-postgrest13'
34

45
const REST_URL = 'http://localhost:3000'
56
export const postgrest = new PostgrestClient<Database>(REST_URL)
67
const REST_URL_13 = 'http://localhost:3001'
78
const postgrest13 = new PostgrestClient<Database, { postgrestVersion: 13 }>(REST_URL_13)
9+
const postgrest13FromDatabaseTypes = new PostgrestClient<DatabaseWithOptions13>(REST_URL_13)
810

911
const userColumn: 'catchphrase' | 'username' = 'username'
1012

@@ -350,6 +352,9 @@ export const selectQueries = {
350352
selectSpreadOnManyRelation13: postgrest13
351353
.from(selectParams.selectSpreadOnManyRelation.from)
352354
.select(selectParams.selectSpreadOnManyRelation.select),
355+
selectSpreadOnManyRelation13FromDatabaseType: postgrest13FromDatabaseTypes
356+
.from(selectParams.selectSpreadOnManyRelation.from)
357+
.select(selectParams.selectSpreadOnManyRelation.select),
353358
selectWithDuplicatesFields: postgrest
354359
.from(selectParams.selectWithDuplicatesFields.from)
355360
.select(selectParams.selectWithDuplicatesFields.select),
@@ -1778,6 +1783,27 @@ test('select spread on many relation postgrest13', async () => {
17781783
`)
17791784
})
17801785

1786+
test('select spread on many relation postgrest13FromDatabaseTypes', async () => {
1787+
const res = await selectQueries.selectSpreadOnManyRelation13FromDatabaseType.limit(1).single()
1788+
expect(res).toMatchInlineSnapshot(`
1789+
Object {
1790+
"count": null,
1791+
"data": Object {
1792+
"channel_id": 1,
1793+
"id": Array [
1794+
1,
1795+
],
1796+
"message": Array [
1797+
"Hello World 👋",
1798+
],
1799+
},
1800+
"error": null,
1801+
"status": 200,
1802+
"statusText": "OK",
1803+
}
1804+
`)
1805+
})
1806+
17811807
test('multiple times the same column in selection', async () => {
17821808
const res = await selectQueries.selectWithDuplicatesFields.limit(1).single()
17831809
expect(res).toMatchInlineSnapshot(`

test/select-query-parser/select.test-d.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,20 @@ type Schema = Database['public']
672672
expectType<TypeEqual<typeof result, typeof expected>>(true)
673673
}
674674

675+
// spread over a many relation with postgrest13 passed within the Database type
676+
{
677+
const { data } = await selectQueries.selectSpreadOnManyRelation13FromDatabaseType
678+
.limit(1)
679+
.single()
680+
let result: Exclude<typeof data, null>
681+
let expected: {
682+
channel_id: number
683+
id: Array<number>
684+
message: Array<string | null>
685+
}
686+
expectType<TypeEqual<typeof result, typeof expected>>(true)
687+
}
688+
675689
// multiple times the same column in selection
676690
{
677691
const { data } = await selectQueries.selectWithDuplicatesFields.limit(1).single()

0 commit comments

Comments
 (0)