Skip to content

Allow to pass fetch options while building the query #527

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
8 changes: 4 additions & 4 deletions src/PostgrestBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @ts-ignore
import nodeFetch from '@supabase/node-fetch'

import type { Fetch, PostgrestSingleResponse, PostgrestResponseSuccess } from './types'
import type { Fetch, FetchOptions, PostgrestSingleResponse, PostgrestResponseSuccess } from './types'
import PostgrestError from './PostgrestError'

export default abstract class PostgrestBuilder<Result, ThrowOnError extends boolean = false>
Expand All @@ -16,7 +16,7 @@ export default abstract class PostgrestBuilder<Result, ThrowOnError extends bool
protected schema?: string
protected body?: unknown
protected shouldThrowOnError = false
protected signal?: AbortSignal
protected fetchOpts: Omit<FetchOptions, 'headers'> = {}
protected fetch: Fetch
protected isMaybeSingle: boolean

Expand All @@ -27,7 +27,7 @@ export default abstract class PostgrestBuilder<Result, ThrowOnError extends bool
this.schema = builder.schema
this.body = builder.body
this.shouldThrowOnError = builder.shouldThrowOnError
this.signal = builder.signal
this.fetchOpts = builder.fetchOpts
this.isMaybeSingle = builder.isMaybeSingle

if (builder.fetch) {
Expand Down Expand Up @@ -91,10 +91,10 @@ export default abstract class PostgrestBuilder<Result, ThrowOnError extends bool
// https://github.com/supabase/postgrest-js/pull/247
const _fetch = this.fetch
let res = _fetch(this.url.toString(), {
...this.fetchOpts,
method: this.method,
headers: this.headers,
body: JSON.stringify(this.body),
signal: this.signal,
}).then(async (res) => {
let error = null
let data = null
Expand Down
40 changes: 37 additions & 3 deletions src/PostgrestTransformBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import PostgrestBuilder from './PostgrestBuilder'
import { GetResult } from './select-query-parser/result'
import { GenericSchema } from './types'
import { GetResult } from './select-query-parser/reesult'
import type { FetchOptions, GenericSchema } from './types'

export default class PostgrestTransformBuilder<
Schema extends GenericSchema,
Expand Down Expand Up @@ -176,9 +176,43 @@ export default class PostgrestTransformBuilder<
* Set the AbortSignal for the fetch request.
*
* @param signal - The AbortSignal to use for the fetch request
* @deprecated Use fetchOptions instead. E.g. `fetchOptions({ signal: new AbortController().signal })`
*/
abortSignal(signal: AbortSignal): this {
this.signal = signal
this.fetchOptions({ signal })

return this
}

/**
* Set fetch options for the request.
*
* @param init - Fetch options.
*/
fetchOptions(init: FetchOptions): this {
const { headers, ...rest } = init

this.fetchOpts = {
...this.fetchOpts,
...rest,
}

if (headers) {
let entries: Iterable<string[]>

if (Array.isArray(headers)) {
entries = headers.values()
} else if (headers instanceof Headers) {
entries = headers.entries()
} else {
entries = Object.entries(headers)
}

for (const [name, val] of entries) {
this.headers[name] = val
}
}

return this
}

Expand Down
3 changes: 3 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export type GenericSchema = {

// https://twitter.com/mattpocockuk/status/1622730173446557697
export type Prettify<T> = { [K in keyof T]: T[K] } & {}

// https://github.com/sindresorhus/type-fest
export type SimplifyDeep<Type, ExcludeType = never> = ConditionalSimplifyDeep<
Type,
Expand All @@ -89,3 +90,5 @@ type ConditionalSimplifyDeep<
type NonRecursiveType = BuiltIns | Function | (new (...arguments_: any[]) => unknown)
type BuiltIns = Primitive | void | Date | RegExp
type Primitive = null | undefined | string | number | boolean | symbol | bigint

export type FetchOptions = Omit<RequestInit, 'method' | 'body'>
56 changes: 56 additions & 0 deletions test/transforms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { PostgrestClient } from '../src/index'
import { Database } from './types'

import { AbortController } from 'node-abort-controller'
// @ts-ignore
import nodeFetch from '@supabase/node-fetch'

const postgrest = new PostgrestClient<Database>('http://localhost:3000')

Expand Down Expand Up @@ -539,3 +541,57 @@ test('rollback delete', async () => {
}
`)
})

test('Next.js options', async () => {
let fetchImpl = fetch
if (typeof fetchImpl === 'undefined') {
fetchImpl = nodeFetch
}
const fetchSpy = jest.fn(fetchImpl)

const postgrest = new PostgrestClient<Database>('http://localhost:3000', {
fetch: fetchSpy,
})

const builder = postgrest
.from('users')
.select()
.eq('username', 'supabot')
.fetchOptions({
next: {
tags: ['users', 'supabot'],
},
} as any)
const res = await builder
expect(res).toMatchInlineSnapshot(`
Object {
"count": null,
"data": Array [
Object {
"age_range": "[1,2)",
"catchphrase": "'cat' 'fat'",
"data": null,
"status": "ONLINE",
"username": "supabot",
},
],
"error": null,
"status": 200,
"statusText": "OK",
}
`)
expect(fetchSpy).toHaveBeenCalledWith(
'http://localhost:3000/users?select=*&username=eq.supabot',
{
body: undefined,
headers: {
'X-Client-Info': 'postgrest-js/0.0.0-automated',
},
method: 'GET',
next: {
tags: ['users', 'supabot'],
},
signal: undefined,
}
)
})