Spaces:
Running
Running
| import PostgrestQueryBuilder from './PostgrestQueryBuilder' | |
| import PostgrestFilterBuilder from './PostgrestFilterBuilder' | |
| import PostgrestBuilder from './PostgrestBuilder' | |
| import { DEFAULT_HEADERS } from './constants' | |
| import { Fetch, GenericSchema } from './types' | |
| /** | |
| * PostgREST client. | |
| * | |
| * @typeParam Database - Types for the schema from the [type | |
| * generator](https://supabase.com/docs/reference/javascript/next/typescript-support) | |
| * | |
| * @typeParam SchemaName - Postgres schema to switch to. Must be a string | |
| * literal, the same one passed to the constructor. If the schema is not | |
| * `"public"`, this must be supplied manually. | |
| */ | |
| export default class PostgrestClient< | |
| Database = any, | |
| SchemaName extends string & keyof Database = 'public' extends keyof Database | |
| ? 'public' | |
| : string & keyof Database, | |
| Schema extends GenericSchema = Database[SchemaName] extends GenericSchema | |
| ? Database[SchemaName] | |
| : any | |
| > { | |
| url: string | |
| headers: Record<string, string> | |
| schemaName?: SchemaName | |
| fetch?: Fetch | |
| // TODO: Add back shouldThrowOnError once we figure out the typings | |
| /** | |
| * Creates a PostgREST client. | |
| * | |
| * @param url - URL of the PostgREST endpoint | |
| * @param options - Named parameters | |
| * @param options.headers - Custom headers | |
| * @param options.schema - Postgres schema to switch to | |
| * @param options.fetch - Custom fetch | |
| */ | |
| constructor( | |
| url: string, | |
| { | |
| headers = {}, | |
| schema, | |
| fetch, | |
| }: { | |
| headers?: Record<string, string> | |
| schema?: SchemaName | |
| fetch?: Fetch | |
| } = {} | |
| ) { | |
| this.url = url | |
| this.headers = { ...DEFAULT_HEADERS, ...headers } | |
| this.schemaName = schema | |
| this.fetch = fetch | |
| } | |
| from< | |
| TableName extends string & keyof Schema['Tables'], | |
| Table extends Schema['Tables'][TableName] | |
| >(relation: TableName): PostgrestQueryBuilder<Schema, Table, TableName> | |
| from<ViewName extends string & keyof Schema['Views'], View extends Schema['Views'][ViewName]>( | |
| relation: ViewName | |
| ): PostgrestQueryBuilder<Schema, View, ViewName> | |
| from(relation: string): PostgrestQueryBuilder<Schema, any, any> | |
| /** | |
| * Perform a query on a table or a view. | |
| * | |
| * @param relation - The table or view name to query | |
| */ | |
| from(relation: string): PostgrestQueryBuilder<Schema, any, any> { | |
| const url = new URL(`${this.url}/${relation}`) | |
| return new PostgrestQueryBuilder(url, { | |
| headers: { ...this.headers }, | |
| schema: this.schemaName, | |
| fetch: this.fetch, | |
| }) | |
| } | |
| /** | |
| * Select a schema to query or perform an function (rpc) call. | |
| * | |
| * The schema needs to be on the list of exposed schemas inside Supabase. | |
| * | |
| * @param schema - The schema to query | |
| */ | |
| schema<DynamicSchema extends string & keyof Database>( | |
| schema: DynamicSchema | |
| ): PostgrestClient< | |
| Database, | |
| DynamicSchema, | |
| Database[DynamicSchema] extends GenericSchema ? Database[DynamicSchema] : any | |
| > { | |
| return new PostgrestClient(this.url, { | |
| headers: this.headers, | |
| schema, | |
| fetch: this.fetch, | |
| }) | |
| } | |
| /** | |
| * Perform a function call. | |
| * | |
| * @param fn - The function name to call | |
| * @param args - The arguments to pass to the function call | |
| * @param options - Named parameters | |
| * @param options.head - When set to `true`, `data` will not be returned. | |
| * Useful if you only need the count. | |
| * @param options.count - Count algorithm to use to count rows returned by the | |
| * function. Only applicable for [set-returning | |
| * functions](https://www.postgresql.org/docs/current/functions-srf.html). | |
| * | |
| * `"exact"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the | |
| * hood. | |
| * | |
| * `"planned"`: Approximated but fast count algorithm. Uses the Postgres | |
| * statistics under the hood. | |
| * | |
| * `"estimated"`: Uses exact count for low numbers and planned count for high | |
| * numbers. | |
| */ | |
| rpc< | |
| FunctionName extends string & keyof Schema['Functions'], | |
| Function_ extends Schema['Functions'][FunctionName] | |
| >( | |
| fn: FunctionName, | |
| args: Function_['Args'] = {}, | |
| { | |
| head = false, | |
| count, | |
| }: { | |
| head?: boolean | |
| count?: 'exact' | 'planned' | 'estimated' | |
| } = {} | |
| ): PostgrestFilterBuilder< | |
| Schema, | |
| Function_['Returns'] extends any[] | |
| ? Function_['Returns'][number] extends Record<string, unknown> | |
| ? Function_['Returns'][number] | |
| : never | |
| : never, | |
| Function_['Returns'] | |
| > { | |
| let method: 'HEAD' | 'POST' | |
| const url = new URL(`${this.url}/rpc/${fn}`) | |
| let body: unknown | undefined | |
| if (head) { | |
| method = 'HEAD' | |
| Object.entries(args).forEach(([name, value]) => { | |
| url.searchParams.append(name, `${value}`) | |
| }) | |
| } else { | |
| method = 'POST' | |
| body = args | |
| } | |
| const headers = { ...this.headers } | |
| if (count) { | |
| headers['Prefer'] = `count=${count}` | |
| } | |
| return new PostgrestFilterBuilder({ | |
| method, | |
| url, | |
| headers, | |
| schema: this.schemaName, | |
| body, | |
| fetch: this.fetch, | |
| allowEmpty: false, | |
| } as unknown as PostgrestBuilder<Function_['Returns']>) | |
| } | |
| } | |