Skip to content
5 changes: 4 additions & 1 deletion 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 } from './types'
import type { Fetch, NextFetchRequestConfig, PostgrestSingleResponse } from './types'
import PostgrestError from './PostgrestError'

export default abstract class PostgrestBuilder<Result>
Expand All @@ -14,6 +14,7 @@ export default abstract class PostgrestBuilder<Result>
protected body?: unknown
protected shouldThrowOnError = false
protected signal?: AbortSignal
protected nextOptions?: NextFetchRequestConfig
protected fetch: Fetch
protected isMaybeSingle: boolean

Expand All @@ -25,6 +26,7 @@ export default abstract class PostgrestBuilder<Result>
this.body = builder.body
this.shouldThrowOnError = builder.shouldThrowOnError
this.signal = builder.signal
this.nextOptions = builder.nextOptions
this.isMaybeSingle = builder.isMaybeSingle

if (builder.fetch) {
Expand Down Expand Up @@ -74,6 +76,7 @@ export default abstract class PostgrestBuilder<Result>
headers: this.headers,
body: JSON.stringify(this.body),
signal: this.signal,
next: this.nextOptions,
}).then(async (res) => {
let error = null
let data = null
Expand Down
13 changes: 12 additions & 1 deletion 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'
import { GenericSchema } from './types'
import { GenericSchema, NextFetchRequestConfig } from './types'

export default class PostgrestTransformBuilder<
Schema extends GenericSchema,
Expand Down Expand Up @@ -182,6 +182,17 @@ export default class PostgrestTransformBuilder<
return this
}

/**
* Set Next.js's tags for the fetch request.
*
* @param tags - An array of tags. A tag represents the cache tag associated with the data.
* Must be less than or equal to 256 characters. This value is case-sensitive.
*/
next(nextOptions: NextFetchRequestConfig): this {
this.nextOptions = nextOptions
return this
}

/**
* Return `data` as a single object instead of an array of objects.
*
Expand Down
15 changes: 15 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,18 @@ export type GenericSchema = {

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

export type NextFetchRequestConfig = RequestInit extends { next: infer T }
? T
: {
revalidate?: number | false
tags?: string[]
}

declare global {
namespace globalThis {
interface RequestInit {
next?: unknown // Avoid: 'next' is referenced directly or indirectly in its own type annotation.ts(2502)
}
}
}
48 changes: 48 additions & 0 deletions test/transforms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -473,3 +473,51 @@ test('rollback delete', async () => {
}
`)
})

test('Next.js options', async () => {
const fetchSpy = jest.fn(fetch)

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

const builder = postgrest
.from('users')
.select()
.eq('username', 'supabot')
.next({
tags: ['users', 'supabot'],
})
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,
}
)
})