Skip to content

Commit 9ec17a4

Browse files
committed
feat: add max-affected method
1 parent 6705c5c commit 9ec17a4

File tree

6 files changed

+52
-26
lines changed

6 files changed

+52
-26
lines changed

src/PostgrestFilterBuilder.ts

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -89,19 +89,6 @@ export default class PostgrestFilterBuilder<
8989
Relationships,
9090
Method
9191
> {
92-
maxAffected(
93-
value: number
94-
): Method extends 'PATCH' | 'DELETE'
95-
? this
96-
: InvalidMethodError<'maxAffected method only available on update or delete'> {
97-
const preferHeaderManager = new HeaderManager('Prefer', this.headers['Prefer'])
98-
preferHeaderManager.add('handling=strict')
99-
preferHeaderManager.add(`max-affected=${value}`)
100-
this.headers['Prefer'] = preferHeaderManager.get()
101-
return this as unknown as Method extends 'PATCH' | 'DELETE'
102-
? this
103-
: InvalidMethodError<'maxAffected method only available on update or delete'>
104-
}
10592
/**
10693
* Match only rows where `column` is equal to `value`.
10794
*
@@ -615,4 +602,28 @@ export default class PostgrestFilterBuilder<
615602
this.url.searchParams.append(column, `${operator}.${value}`)
616603
return this
617604
}
605+
606+
/**
607+
* Set the maximum number of rows that can be affected by the query.
608+
* Only available in PostgREST v13+ and only works with PATCH and DELETE methods.
609+
*
610+
* @param value - The maximum number of rows that can be affected
611+
*/
612+
maxAffected(
613+
value: number
614+
): ClientOptions['postgrestVersion'] extends 13
615+
? Method extends 'PATCH' | 'DELETE'
616+
? this
617+
: InvalidMethodError<'maxAffected method only available on update or delete'>
618+
: InvalidMethodError<'maxAffected method only available on postgrest 13+'> {
619+
const preferHeaderManager = new HeaderManager('Prefer', this.headers['Prefer'])
620+
preferHeaderManager.add('handling=strict')
621+
preferHeaderManager.add(`max-affected=${value}`)
622+
this.headers['Prefer'] = preferHeaderManager.get()
623+
return this as unknown as ClientOptions['postgrestVersion'] extends 13
624+
? Method extends 'PATCH' | 'DELETE'
625+
? this
626+
: InvalidMethodError<'maxAffected method only available on update or delete'>
627+
: InvalidMethodError<'maxAffected method only available on postgrest 13+'>
628+
}
618629
}

test/index.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ import './resource-embedding'
55
import './transforms'
66
import './rpc'
77
import './utils'
8-
// import './max-affected'
8+
import './max-affected'

test/max-affected.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,20 @@ import { expectType } from 'tsd'
44
import { InvalidMethodError } from '../src/PostgrestFilterBuilder'
55

66
const REST_URL_13 = 'http://localhost:3001'
7-
const postgrest13 = new PostgrestClient<Database>(REST_URL_13)
7+
const postgrest13 = new PostgrestClient<Database, { postgrestVersion: 13 }>(REST_URL_13)
8+
const postgrest12 = new PostgrestClient<Database>(REST_URL_13)
89

910
describe('maxAffected', () => {
1011
// Type checking tests
11-
test('maxAffected should show warning on non update / delete', async () => {
12+
test('maxAffected should show type warning on postgrest 12 clients', async () => {
13+
const resUpdate = await postgrest12
14+
.from('messages')
15+
.update({ channel_id: 2 })
16+
.eq('message', 'foo')
17+
.maxAffected(1)
18+
expectType<InvalidMethodError<'maxAffected method only available on postgrest 13+'>>(resUpdate)
19+
})
20+
test('maxAffected should show type warning on non update / delete', async () => {
1221
const resSelect = await postgrest13.from('messages').select('*').maxAffected(10)
1322
const resInsert = await postgrest13
1423
.from('messages')

test/relationships.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,15 +1762,18 @@ test('select spread on many relation postgrest13', async () => {
17621762
expect(res).toMatchInlineSnapshot(`
17631763
Object {
17641764
"count": null,
1765-
"data": null,
1766-
"error": Object {
1767-
"code": "PGRST119",
1768-
"details": "'channels' and 'messages' do not form a many-to-one or one-to-one relationship",
1769-
"hint": null,
1770-
"message": "A spread operation on 'messages' is not possible",
1765+
"data": Object {
1766+
"channel_id": 1,
1767+
"id": Array [
1768+
1,
1769+
],
1770+
"message": Array [
1771+
"Hello World 👋",
1772+
],
17711773
},
1772-
"status": 400,
1773-
"statusText": "Bad Request",
1774+
"error": null,
1775+
"status": 200,
1776+
"statusText": "OK",
17741777
}
17751778
`)
17761779
})

test/returns.test-d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ const postgrest = new PostgrestClient<Database>(REST_URL)
5353
.returns<{ username: string }[]>()
5454
expectType<
5555
PostgrestBuilder<
56+
{ postgrestVersion: 12 },
5657
{
5758
Error: 'Type mismatch: Cannot cast single object to array type. Remove Array wrapper from return type or make sure you are not using .single() up in the calling chain'
5859
},

test/select-query-parser/result.test-d.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ type SelectQueryFromTableResult<
1515
Database['public']['Tables'][TableName]['Row'],
1616
TableName,
1717
Database['public']['Tables'][TableName]['Relationships'],
18-
Q
18+
Q,
19+
{ postgrestVersion: 12 }
1920
>
2021

2122
// This test file is here to help develop, debug and maintain the GetResult
@@ -130,7 +131,8 @@ type SelectQueryFromTableResult<
130131
Database['personal']['Tables'][TableName]['Row'],
131132
TableName,
132133
Database['personal']['Tables'][TableName]['Relationships'],
133-
Q
134+
Q,
135+
{ postgrestVersion: 12 }
134136
>
135137
// Should work with Json object accessor
136138
{

0 commit comments

Comments
 (0)