Skip to content
This repository was archived by the owner on Oct 9, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 29 additions & 9 deletions src/lib/PostgrestQueryBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,28 @@ export default class PostgrestQueryBuilder<T> extends PostgrestBuilder<T> {
*
* @param values The values to insert.
* @param upsert If `true`, performs an UPSERT.
* @param onConflict By specifying the `on_conflict` query parameter, you can make UPSERT work on a column(s) that has a UNIQUE constraint.
* @param onConflict By specifying the `on_conflict` query parameter, you can make UPSERT work on a column(s) that has a UNIQUE constraint.
* @param returning By default the new record is returned. Set this to 'minimal' if you don't need this value.
*/
insert(
values: Partial<T> | Partial<T>[],
{ upsert = false, onConflict }: { upsert?: boolean; onConflict?: string } = {}
{
upsert = false,
onConflict,
returning = 'representation',
}: {
upsert?: boolean
onConflict?: string
returning?: 'minimal' | 'representation'
} = {}
): PostgrestFilterBuilder<T> {
this.method = 'POST'
this.headers['Prefer'] = upsert
? 'return=representation,resolution=merge-duplicates'
: 'return=representation'

let prefersHeaders = []
prefersHeaders.push(`return=${returning}`)
if (upsert) prefersHeaders.push('resolution=merge-duplicates')
this.headers['Prefer'] = prefersHeaders.join(',')

if (upsert && onConflict !== undefined) this.url.searchParams.set('on_conflict', onConflict)
this.body = values
return new PostgrestFilterBuilder(this)
Expand All @@ -65,20 +77,28 @@ export default class PostgrestQueryBuilder<T> extends PostgrestBuilder<T> {
* Performs an UPDATE on the table.
*
* @param values The values to update.
* @param returning By default the updated record is returned. Set this to 'minimal' if you don't need this value.
*/
update(values: Partial<T>): PostgrestFilterBuilder<T> {
update(
values: Partial<T>,
{ returning = 'representation' }: { returning?: 'minimal' | 'representation' } = {}
): PostgrestFilterBuilder<T> {
this.method = 'PATCH'
this.headers['Prefer'] = 'return=representation'
this.headers['Prefer'] = `return=${returning}`
this.body = values
return new PostgrestFilterBuilder(this)
}

/**
* Performs a DELETE on the table.
*
* @param returning If `true`, return the deleted row(s) in the response.
*/
delete(): PostgrestFilterBuilder<T> {
delete({
returning = 'representation',
}: { returning?: 'minimal' | 'representation' } = {}): PostgrestFilterBuilder<T> {
this.method = 'DELETE'
this.headers['Prefer'] = 'return=representation'
this.headers['Prefer'] = `return=${returning}`
return new PostgrestFilterBuilder(this)
}

Expand Down
7 changes: 5 additions & 2 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ interface PostgrestSingleResponseSuccess<T> extends PostgrestResponseBase {
// For backward compatibility: body === data
body: T
}
export type PostgrestSingleResponse<T> = PostgrestSingleResponseSuccess<T> | PostgrestResponseFailure
export type PostgrestSingleResponse<T> =
| PostgrestSingleResponseSuccess<T>
| PostgrestResponseFailure

export abstract class PostgrestBuilder<T> implements PromiseLike<PostgrestResponse<T>> {
protected method!: 'GET' | 'HEAD' | 'POST' | 'PATCH' | 'DELETE'
Expand Down Expand Up @@ -81,7 +83,8 @@ export abstract class PostgrestBuilder<T> implements PromiseLike<PostgrestRespon
let error, data
if (res.ok) {
error = null
data = await res.json()
const isReturnMinimal = this.headers['Prefer']?.split(',').includes('return=minimal')
data = isReturnMinimal ? null : await res.json()
} else {
error = await res.json()
data = null
Expand Down
Loading