From e283eb2efdc81303afa70a4ca4ff529c0453e622 Mon Sep 17 00:00:00 2001 From: ph0t0shop Date: Tue, 30 Sep 2025 10:23:09 +0200 Subject: [PATCH 1/2] Expose query builder options in PostgrestClient#from --- src/PostgrestClient.ts | 24 +++++++++++++----------- src/PostgrestQueryBuilder.ts | 8 ++------ src/types.ts | 9 +++++++++ src/utils.ts | 18 ++++++++++++++++++ 4 files changed, 42 insertions(+), 17 deletions(-) create mode 100644 src/utils.ts diff --git a/src/PostgrestClient.ts b/src/PostgrestClient.ts index 13afc923..a82a5171 100644 --- a/src/PostgrestClient.ts +++ b/src/PostgrestClient.ts @@ -1,6 +1,7 @@ import PostgrestQueryBuilder from './PostgrestQueryBuilder' import PostgrestFilterBuilder from './PostgrestFilterBuilder' -import { Fetch, GenericSchema, ClientServerOptions } from './types' +import { Fetch, GenericSchema, ClientServerOptions, PostgrestQueryBuilderOptions, PostgrestQueryBuilderOptionsWithSchema } from './types' +import { mergeHeaders } from './utils' /** * PostgREST client. @@ -54,11 +55,7 @@ export default class PostgrestClient< headers = {}, schema, fetch, - }: { - headers?: HeadersInit - schema?: SchemaName - fetch?: Fetch - } = {} + }: PostgrestQueryBuilderOptionsWithSchema = {} ) { this.url = url this.headers = new Headers(headers) @@ -68,21 +65,26 @@ export default class PostgrestClient< from< TableName extends string & keyof Schema['Tables'], Table extends Schema['Tables'][TableName] - >(relation: TableName): PostgrestQueryBuilder + >( + relation: TableName, + options?: PostgrestQueryBuilderOptions + ): PostgrestQueryBuilder from( - relation: ViewName + relation: ViewName, + options?: PostgrestQueryBuilderOptions ): PostgrestQueryBuilder /** * Perform a query on a table or a view. * * @param relation - The table or view name to query */ - from(relation: string): PostgrestQueryBuilder { + from(relation: string, options?: PostgrestQueryBuilderOptions): PostgrestQueryBuilder { const url = new URL(`${this.url}/${relation}`) + return new PostgrestQueryBuilder(url, { - headers: new Headers(this.headers), + headers: mergeHeaders(this.headers, options?.headers), schema: this.schemaName, - fetch: this.fetch, + fetch: options?.fetch ?? this.fetch, }) } diff --git a/src/PostgrestQueryBuilder.ts b/src/PostgrestQueryBuilder.ts index 1a866b1a..f24b7baa 100644 --- a/src/PostgrestQueryBuilder.ts +++ b/src/PostgrestQueryBuilder.ts @@ -1,6 +1,6 @@ import PostgrestFilterBuilder from './PostgrestFilterBuilder' import { GetResult } from './select-query-parser/result' -import { ClientServerOptions, Fetch, GenericSchema, GenericTable, GenericView } from './types' +import { ClientServerOptions, Fetch, GenericSchema, GenericTable, GenericView, PostgrestQueryBuilderOptions, PostgrestQueryBuilderOptionsWithSchema } from './types' export default class PostgrestQueryBuilder< ClientOptions extends ClientServerOptions, @@ -21,11 +21,7 @@ export default class PostgrestQueryBuilder< headers = {}, schema, fetch, - }: { - headers?: HeadersInit - schema?: string - fetch?: Fetch - } + }: PostgrestQueryBuilderOptionsWithSchema ) { this.url = url this.headers = new Headers(headers) diff --git a/src/types.ts b/src/types.ts index d0b89036..9f46f9d0 100644 --- a/src/types.ts +++ b/src/types.ts @@ -31,6 +31,15 @@ export type PostgrestSingleResponse = PostgrestResponseSuccess | Postgrest export type PostgrestMaybeSingleResponse = PostgrestSingleResponse export type PostgrestResponse = PostgrestSingleResponse +export type PostgrestQueryBuilderOptions = { + headers?: HeadersInit + fetch?: Fetch +} + +export type PostgrestQueryBuilderOptionsWithSchema = PostgrestQueryBuilderOptions & { + schema?: TSchema +} + export type GenericRelationship = { foreignKeyName: string columns: string[] diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 00000000..234f935d --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,18 @@ +/** + * Non-destructively merges an optional {@link HeadersInit} into a {@link Headers} object, where {@link right} takes precedence over {@link left} if it exists. + * @param {Headers} left Base {@link Headers} object + * @param {HeadersInit?} right Optional {@link HeadersInit} to merge into {@link left} + * @returns The resulting merged {@link HeadersInit} object. + */ + +export function mergeHeaders(left: Headers, right?: HeadersInit): HeadersInit { + if (!right) return left; + + const merged = new Headers(left); + const rightEntries = (right instanceof Headers) ? right.entries() : Array.isArray(right) ? right : Object.entries(right); + for (const [key, value] of rightEntries) { + merged.set(key, value); + } + + return merged; +} \ No newline at end of file From ea5c0e593d0568a2665011e12fb6f4b964dce636 Mon Sep 17 00:00:00 2001 From: ph0t0shop Date: Tue, 30 Sep 2025 10:42:51 +0200 Subject: [PATCH 2/2] Run linter --- src/PostgrestClient.ts | 19 ++++++++++++------- src/PostgrestQueryBuilder.ts | 15 +++++++++------ src/index.ts | 2 ++ src/types.ts | 7 ++++--- src/utils.ts | 21 +++++++++++++-------- 5 files changed, 40 insertions(+), 24 deletions(-) diff --git a/src/PostgrestClient.ts b/src/PostgrestClient.ts index a82a5171..c63eb930 100644 --- a/src/PostgrestClient.ts +++ b/src/PostgrestClient.ts @@ -1,6 +1,12 @@ import PostgrestQueryBuilder from './PostgrestQueryBuilder' import PostgrestFilterBuilder from './PostgrestFilterBuilder' -import { Fetch, GenericSchema, ClientServerOptions, PostgrestQueryBuilderOptions, PostgrestQueryBuilderOptionsWithSchema } from './types' +import { + Fetch, + GenericSchema, + ClientServerOptions, + PostgrestQueryBuilderOptions, + PostgrestQueryBuilderOptionsWithSchema, +} from './types' import { mergeHeaders } from './utils' /** @@ -51,11 +57,7 @@ export default class PostgrestClient< */ constructor( url: string, - { - headers = {}, - schema, - fetch, - }: PostgrestQueryBuilderOptionsWithSchema = {} + { headers = {}, schema, fetch }: PostgrestQueryBuilderOptionsWithSchema = {} ) { this.url = url this.headers = new Headers(headers) @@ -78,7 +80,10 @@ export default class PostgrestClient< * * @param relation - The table or view name to query */ - from(relation: string, options?: PostgrestQueryBuilderOptions): PostgrestQueryBuilder { + from( + relation: string, + options?: PostgrestQueryBuilderOptions + ): PostgrestQueryBuilder { const url = new URL(`${this.url}/${relation}`) return new PostgrestQueryBuilder(url, { diff --git a/src/PostgrestQueryBuilder.ts b/src/PostgrestQueryBuilder.ts index f24b7baa..bb3e71ed 100644 --- a/src/PostgrestQueryBuilder.ts +++ b/src/PostgrestQueryBuilder.ts @@ -1,6 +1,13 @@ import PostgrestFilterBuilder from './PostgrestFilterBuilder' import { GetResult } from './select-query-parser/result' -import { ClientServerOptions, Fetch, GenericSchema, GenericTable, GenericView, PostgrestQueryBuilderOptions, PostgrestQueryBuilderOptionsWithSchema } from './types' +import { + ClientServerOptions, + Fetch, + GenericSchema, + GenericTable, + GenericView, + PostgrestQueryBuilderOptionsWithSchema, +} from './types' export default class PostgrestQueryBuilder< ClientOptions extends ClientServerOptions, @@ -17,11 +24,7 @@ export default class PostgrestQueryBuilder< constructor( url: URL, - { - headers = {}, - schema, - fetch, - }: PostgrestQueryBuilderOptionsWithSchema + { headers = {}, schema, fetch }: PostgrestQueryBuilderOptionsWithSchema ) { this.url = url this.headers = new Headers(headers) diff --git a/src/index.ts b/src/index.ts index 8c435dda..85aa686b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,6 +29,8 @@ export type { PostgrestSingleResponse, PostgrestMaybeSingleResponse, ClientServerOptions as PostgrestClientOptions, + PostgrestQueryBuilderOptions, + PostgrestQueryBuilderOptionsWithSchema, } from './types' // https://github.com/supabase/postgrest-js/issues/551 // To be replaced with a helper type that only uses public types diff --git a/src/types.ts b/src/types.ts index 9f46f9d0..89a888ab 100644 --- a/src/types.ts +++ b/src/types.ts @@ -36,9 +36,10 @@ export type PostgrestQueryBuilderOptions = { fetch?: Fetch } -export type PostgrestQueryBuilderOptionsWithSchema = PostgrestQueryBuilderOptions & { - schema?: TSchema -} +export type PostgrestQueryBuilderOptionsWithSchema = + PostgrestQueryBuilderOptions & { + schema?: TSchema + } export type GenericRelationship = { foreignKeyName: string diff --git a/src/utils.ts b/src/utils.ts index 234f935d..20696a20 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -6,13 +6,18 @@ */ export function mergeHeaders(left: Headers, right?: HeadersInit): HeadersInit { - if (!right) return left; + if (!right) return left - const merged = new Headers(left); - const rightEntries = (right instanceof Headers) ? right.entries() : Array.isArray(right) ? right : Object.entries(right); - for (const [key, value] of rightEntries) { - merged.set(key, value); - } + const merged = new Headers(left) + const rightEntries = + right instanceof Headers + ? right.entries() + : Array.isArray(right) + ? right + : Object.entries(right) + for (const [key, value] of rightEntries) { + merged.set(key, value) + } - return merged; -} \ No newline at end of file + return merged +}