diff --git a/package-lock.json b/package-lock.json index 07b523c2..97b3f44b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,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" @@ -1069,9 +1069,9 @@ } }, "node_modules/@supabase/postgrest-js": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.7.0.tgz", - "integrity": "sha512-wLADHZ5jm7LljF4GigK0H2vc1wGupBY2hGYfb4fVo0UuyMftmA6tOYy+ZpMH/vPq01CUFwXGwvIke6kyqh/QDg==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.8.0.tgz", + "integrity": "sha512-R6leDIC92NgjyG2/tCRJ42rWN7+fZY6ulTEE+c00tcnghn6cX4IYUlnTNMtrdfYC2JYNOTyM+rWj63Wdhr7Zig==", "dependencies": { "cross-fetch": "^3.1.5" } diff --git a/package.json b/package.json index 8e7ad53f..92845251 100644 --- a/package.json +++ b/package.json @@ -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" diff --git a/src/SupabaseClient.ts b/src/SupabaseClient.ts index fbb3bb8c..071c7f9f 100644 --- a/src/SupabaseClient.ts +++ b/src/SupabaseClient.ts @@ -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( + schema: DynamicSchema + ): PostgrestClient< + Database, + DynamicSchema, + Database[DynamicSchema] extends GenericSchema ? Database[DynamicSchema] : any + > { + return this.rest.schema(schema) + } + /** * Perform a function call. * diff --git a/src/lib/types.ts b/src/lib/types.ts index d6c4047f..b3e3469d 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -42,7 +42,7 @@ export type SupabaseClientOptions = { flowType?: SupabaseAuthClientOptions['flowType'] /** * If debug messages for authentication client are emitted. Can be used to inspect the behavior of the library. - */ + */ debug?: boolean } /** diff --git a/test/client.test.ts b/test/client.test.ts index d8f15581..38f97e8e 100644 --- a/test/client.test.ts +++ b/test/client.test.ts @@ -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' @@ -57,6 +59,14 @@ describe('Realtime url', () => { }) }) +describe('Dynamic schema', () => { + test('should swap schemas', async () => { + const client = createClient('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 diff --git a/test/types.ts b/test/types.ts new file mode 100644 index 00000000..74fd1e07 --- /dev/null +++ b/test/types.ts @@ -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 + Returns: undefined + } + } + Enums: { + user_status: 'ONLINE' | 'OFFLINE' + } + CompositeTypes: { + [_ in never]: never + } + } +}