Skip to content
This repository was archived by the owner on Oct 9, 2025. It is now read-only.

Commit 902e55a

Browse files
soedirgokiwicopplesteve-chavez
authored
feat: Allow Prefer: return=minimal for C(R)UD (#133)
* style: run prettier * feat: allow Prefer return=minimal in C(R)UD `Prefer return` is set to `representation` by default, but this gives an error when inserting/updating/deleting on, say, a write-only table. Allow the users to set it to `minimal` by setting `returning`. * test: reorganize tests to have deterministic order Co-authored-by: Paul Copplestone <[email protected]> Co-authored-by: Steve Chavez <[email protected]>
1 parent 4dbcbb9 commit 902e55a

12 files changed

+2237
-2202
lines changed

src/lib/PostgrestQueryBuilder.ts

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,28 @@ export default class PostgrestQueryBuilder<T> extends PostgrestBuilder<T> {
4646
*
4747
* @param values The values to insert.
4848
* @param upsert If `true`, performs an UPSERT.
49-
* @param onConflict By specifying the `on_conflict` query parameter, you can make UPSERT work on a column(s) that has a UNIQUE constraint.
49+
* @param onConflict By specifying the `on_conflict` query parameter, you can make UPSERT work on a column(s) that has a UNIQUE constraint.
50+
* @param returning By default the new record is returned. Set this to 'minimal' if you don't need this value.
5051
*/
5152
insert(
5253
values: Partial<T> | Partial<T>[],
53-
{ upsert = false, onConflict }: { upsert?: boolean; onConflict?: string } = {}
54+
{
55+
upsert = false,
56+
onConflict,
57+
returning = 'representation',
58+
}: {
59+
upsert?: boolean
60+
onConflict?: string
61+
returning?: 'minimal' | 'representation'
62+
} = {}
5463
): PostgrestFilterBuilder<T> {
5564
this.method = 'POST'
56-
this.headers['Prefer'] = upsert
57-
? 'return=representation,resolution=merge-duplicates'
58-
: 'return=representation'
65+
66+
let prefersHeaders = []
67+
prefersHeaders.push(`return=${returning}`)
68+
if (upsert) prefersHeaders.push('resolution=merge-duplicates')
69+
this.headers['Prefer'] = prefersHeaders.join(',')
70+
5971
if (upsert && onConflict !== undefined) this.url.searchParams.set('on_conflict', onConflict)
6072
this.body = values
6173
return new PostgrestFilterBuilder(this)
@@ -65,20 +77,28 @@ export default class PostgrestQueryBuilder<T> extends PostgrestBuilder<T> {
6577
* Performs an UPDATE on the table.
6678
*
6779
* @param values The values to update.
80+
* @param returning By default the updated record is returned. Set this to 'minimal' if you don't need this value.
6881
*/
69-
update(values: Partial<T>): PostgrestFilterBuilder<T> {
82+
update(
83+
values: Partial<T>,
84+
{ returning = 'representation' }: { returning?: 'minimal' | 'representation' } = {}
85+
): PostgrestFilterBuilder<T> {
7086
this.method = 'PATCH'
71-
this.headers['Prefer'] = 'return=representation'
87+
this.headers['Prefer'] = `return=${returning}`
7288
this.body = values
7389
return new PostgrestFilterBuilder(this)
7490
}
7591

7692
/**
7793
* Performs a DELETE on the table.
94+
*
95+
* @param returning If `true`, return the deleted row(s) in the response.
7896
*/
79-
delete(): PostgrestFilterBuilder<T> {
97+
delete({
98+
returning = 'representation',
99+
}: { returning?: 'minimal' | 'representation' } = {}): PostgrestFilterBuilder<T> {
80100
this.method = 'DELETE'
81-
this.headers['Prefer'] = 'return=representation'
101+
this.headers['Prefer'] = `return=${returning}`
82102
return new PostgrestFilterBuilder(this)
83103
}
84104

src/lib/types.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ interface PostgrestSingleResponseSuccess<T> extends PostgrestResponseBase {
4040
// For backward compatibility: body === data
4141
body: T
4242
}
43-
export type PostgrestSingleResponse<T> = PostgrestSingleResponseSuccess<T> | PostgrestResponseFailure
43+
export type PostgrestSingleResponse<T> =
44+
| PostgrestSingleResponseSuccess<T>
45+
| PostgrestResponseFailure
4446

4547
export abstract class PostgrestBuilder<T> implements PromiseLike<PostgrestResponse<T>> {
4648
protected method!: 'GET' | 'HEAD' | 'POST' | 'PATCH' | 'DELETE'
@@ -81,7 +83,8 @@ export abstract class PostgrestBuilder<T> implements PromiseLike<PostgrestRespon
8183
let error, data
8284
if (res.ok) {
8385
error = null
84-
data = await res.json()
86+
const isReturnMinimal = this.headers['Prefer']?.split(',').includes('return=minimal')
87+
data = isReturnMinimal ? null : await res.json()
8588
} else {
8689
error = await res.json()
8790
data = null

0 commit comments

Comments
 (0)