Skip to content

Commit

Permalink
feat: enable dynamic schema selection on a per-query basis
Browse files Browse the repository at this point in the history
  • Loading branch information
sjones6 authored and soedirgo committed Aug 7, 2023
1 parent c07ce23 commit 90bd357
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 6 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"dependencies": {
"@supabase/functions-js": "^2.1.0",
"@supabase/gotrue-js": "^2.46.1",
"@supabase/postgrest-js": "^1.7.0",
"@supabase/postgrest-js": "^1.8.0",
"@supabase/realtime-js": "^2.7.3",
"@supabase/storage-js": "^2.5.1",
"cross-fetch": "^3.1.5"
Expand Down
18 changes: 18 additions & 0 deletions src/SupabaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,24 @@ export default class SupabaseClient<
return this.rest.from(relation)
}

/**
* Perform a query on a schema distinct from the default schema supplied via
* the `options.db.schema` constructor parameter.
*
* The schema needs to be on the list of exposed schemas inside Supabase.
*
* @param schema - The name of the schema to query
*/
schema<DynamicSchema extends string & keyof Database>(
schema: DynamicSchema
): PostgrestClient<
Database,
DynamicSchema,
Database[DynamicSchema] extends GenericSchema ? Database[DynamicSchema] : any
> {
return this.rest.schema<DynamicSchema>(schema)
}

/**
* Perform a function call.
*
Expand Down
2 changes: 1 addition & 1 deletion src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export type SupabaseClientOptions<SchemaName> = {
flowType?: SupabaseAuthClientOptions['flowType']
/**
* If debug messages for authentication client are emitted. Can be used to inspect the behavior of the library.
*/
*/
debug?: boolean
}
/**
Expand Down
10 changes: 10 additions & 0 deletions test/client.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { PostgrestClient } from '@supabase/postgrest-js'
import { createClient, SupabaseClient } from '../src/index'
import { Database } from './types'

const URL = 'http://localhost:3000'
const KEY = 'some.fake.key'
Expand Down Expand Up @@ -57,6 +59,14 @@ describe('Realtime url', () => {
})
})

describe('Dynamic schema', () => {
test('should swap schemas', async () => {
const client = createClient<Database>('HTTP://localhost:3000', KEY)
expect(client.schema('personal')).toBeInstanceOf(PostgrestClient)
expect(client.schema('personal').from('users').schema).toBe('personal')
})
})

// Socket should close when there are no open connections
// https://github.com/supabase/supabase-js/issues/44

Expand Down
201 changes: 201 additions & 0 deletions test/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
export type Json = string | number | boolean | null | { [key: string]: Json } | Json[]

export interface Database {
personal: {
Tables: {
users: {
Row: {
age_range: unknown | null
data: Json | null
status: Database['public']['Enums']['user_status'] | null
username: string
}
Insert: {
age_range?: unknown | null
data?: Json | null
status?: Database['public']['Enums']['user_status'] | null
username: string
}
Update: {
age_range?: unknown | null
data?: Json | null
status?: Database['public']['Enums']['user_status'] | null
username?: string
}
Relationships: []
}
}
Views: {
[_ in never]: never
}
Functions: {
get_status: {
Args: {
name_param: string
}
Returns: Database['public']['Enums']['user_status']
}
}
Enums: {
user_status: 'ONLINE' | 'OFFLINE'
}
CompositeTypes: {
[_ in never]: never
}
}
public: {
Tables: {
channels: {
Row: {
data: Json | null
id: number
slug: string | null
}
Insert: {
data?: Json | null
id?: number
slug?: string | null
}
Update: {
data?: Json | null
id?: number
slug?: string | null
}
Relationships: []
}
messages: {
Row: {
channel_id: number
data: Json | null
id: number
message: string | null
username: string
}
Insert: {
channel_id: number
data?: Json | null
id?: number
message?: string | null
username: string
}
Update: {
channel_id?: number
data?: Json | null
id?: number
message?: string | null
username?: string
}
Relationships: [
{
foreignKeyName: 'messages_username_fkey'
columns: ['username']
referencedRelation: 'users'
referencedColumns: ['username']
},
{
foreignKeyName: 'messages_channel_id_fkey'
columns: ['channel_id']
referencedRelation: 'channels'
referencedColumns: ['id']
}
]
}
shops: {
Row: {
address: string | null
id: number
shop_geom: unknown | null
}
Insert: {
address?: string | null
id: number
shop_geom?: unknown | null
}
Update: {
address?: string | null
id?: number
shop_geom?: unknown | null
}
Relationships: []
}
users: {
Row: {
age_range: unknown | null
catchphrase: unknown | null
data: Json | null
status: Database['public']['Enums']['user_status'] | null
username: string
}
Insert: {
age_range?: unknown | null
catchphrase?: unknown | null
data?: Json | null
status?: Database['public']['Enums']['user_status'] | null
username: string
}
Update: {
age_range?: unknown | null
catchphrase?: unknown | null
data?: Json | null
status?: Database['public']['Enums']['user_status'] | null
username?: string
}
Relationships: []
}
}
Views: {
non_updatable_view: {
Row: {
username: string | null
}
}
updatable_view: {
Row: {
non_updatable_column: number | null
username: string | null
}
Insert: {
non_updatable_column?: never
username?: string | null
}
Update: {
non_updatable_column?: never
username?: string | null
}
}
}
Functions: {
get_status: {
Args: {
name_param: string
}
Returns: Database['public']['Enums']['user_status']
}
get_username_and_status: {
Args: {
name_param: string
}
Returns: {
username: string
status: Database['public']['Enums']['user_status']
}[]
}
offline_user: {
Args: {
name_param: string
}
Returns: Database['public']['Enums']['user_status']
}
void_func: {
Args: Record<PropertyKey, never>
Returns: undefined
}
}
Enums: {
user_status: 'ONLINE' | 'OFFLINE'
}
CompositeTypes: {
[_ in never]: never
}
}
}

0 comments on commit 90bd357

Please sign in to comment.