Skip to content

Commit 6705c5c

Browse files
committed
feat(types): add ClientOptions to handle multi postgrest versions
1 parent 74c8bb6 commit 6705c5c

File tree

12 files changed

+281
-74
lines changed

12 files changed

+281
-74
lines changed

src/PostgrestBuilder.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,16 @@ import type {
88
CheckMatchingArrayTypes,
99
MergePartialResult,
1010
IsValidResultOverride,
11+
ClientServerOptions,
1112
} from './types'
1213
import PostgrestError from './PostgrestError'
1314
import { ContainsNull } from './select-query-parser/types'
1415

15-
export default abstract class PostgrestBuilder<Result, ThrowOnError extends boolean = false>
16-
implements
16+
export default abstract class PostgrestBuilder<
17+
ClientOptions extends ClientServerOptions,
18+
Result,
19+
ThrowOnError extends boolean = false
20+
> implements
1721
PromiseLike<
1822
ThrowOnError extends true ? PostgrestResponseSuccess<Result> : PostgrestSingleResponse<Result>
1923
>
@@ -28,7 +32,7 @@ export default abstract class PostgrestBuilder<Result, ThrowOnError extends bool
2832
protected fetch: Fetch
2933
protected isMaybeSingle: boolean
3034

31-
constructor(builder: PostgrestBuilder<Result>) {
35+
constructor(builder: PostgrestBuilder<ClientOptions, Result>) {
3236
this.method = builder.method
3337
this.url = builder.url
3438
this.headers = builder.headers
@@ -53,9 +57,9 @@ export default abstract class PostgrestBuilder<Result, ThrowOnError extends bool
5357
*
5458
* {@link https://github.com/supabase/supabase-js/issues/92}
5559
*/
56-
throwOnError(): this & PostgrestBuilder<Result, true> {
60+
throwOnError(): this & PostgrestBuilder<ClientOptions, Result, true> {
5761
this.shouldThrowOnError = true
58-
return this as this & PostgrestBuilder<Result, true>
62+
return this as this & PostgrestBuilder<ClientOptions, Result, true>
5963
}
6064

6165
/**
@@ -224,9 +228,14 @@ export default abstract class PostgrestBuilder<Result, ThrowOnError extends bool
224228
* @typeParam NewResult - The new result type to override with
225229
* @deprecated Use overrideTypes<yourType, { merge: false }>() method at the end of your call chain instead
226230
*/
227-
returns<NewResult>(): PostgrestBuilder<CheckMatchingArrayTypes<Result, NewResult>, ThrowOnError> {
231+
returns<NewResult>(): PostgrestBuilder<
232+
ClientOptions,
233+
CheckMatchingArrayTypes<Result, NewResult>,
234+
ThrowOnError
235+
> {
228236
/* istanbul ignore next */
229237
return this as unknown as PostgrestBuilder<
238+
ClientOptions,
230239
CheckMatchingArrayTypes<Result, NewResult>,
231240
ThrowOnError
232241
>
@@ -258,6 +267,7 @@ export default abstract class PostgrestBuilder<Result, ThrowOnError extends bool
258267
NewResult,
259268
Options extends { merge?: boolean } = { merge: true }
260269
>(): PostgrestBuilder<
270+
ClientOptions,
261271
IsValidResultOverride<Result, NewResult, false, false> extends true
262272
? // Preserve the optionality of the result if the overriden type is an object (case of chaining with `maybeSingle`)
263273
ContainsNull<Result> extends true
@@ -267,6 +277,7 @@ export default abstract class PostgrestBuilder<Result, ThrowOnError extends bool
267277
ThrowOnError
268278
> {
269279
return this as unknown as PostgrestBuilder<
280+
ClientOptions,
270281
IsValidResultOverride<Result, NewResult, false, false> extends true
271282
? // Preserve the optionality of the result if the overriden type is an object (case of chaining with `maybeSingle`)
272283
ContainsNull<Result> extends true

src/PostgrestClient.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import PostgrestQueryBuilder from './PostgrestQueryBuilder'
22
import PostgrestFilterBuilder from './PostgrestFilterBuilder'
33
import PostgrestBuilder from './PostgrestBuilder'
44
import { DEFAULT_HEADERS } from './constants'
5-
import { Fetch, GenericSchema } from './types'
5+
import { Fetch, GenericSchema, ClientServerOptions } from './types'
66

77
/**
88
* PostgREST client.
@@ -16,6 +16,7 @@ import { Fetch, GenericSchema } from './types'
1616
*/
1717
export default class PostgrestClient<
1818
Database = any,
19+
ClientOptions extends ClientServerOptions = { postgrestVersion: 12 },
1920
SchemaName extends string & keyof Database = 'public' extends keyof Database
2021
? 'public'
2122
: string & keyof Database,
@@ -59,16 +60,16 @@ export default class PostgrestClient<
5960
from<
6061
TableName extends string & keyof Schema['Tables'],
6162
Table extends Schema['Tables'][TableName]
62-
>(relation: TableName): PostgrestQueryBuilder<Schema, Table, TableName>
63+
>(relation: TableName): PostgrestQueryBuilder<ClientOptions, Schema, Table, TableName>
6364
from<ViewName extends string & keyof Schema['Views'], View extends Schema['Views'][ViewName]>(
6465
relation: ViewName
65-
): PostgrestQueryBuilder<Schema, View, ViewName>
66+
): PostgrestQueryBuilder<ClientOptions, Schema, View, ViewName>
6667
/**
6768
* Perform a query on a table or a view.
6869
*
6970
* @param relation - The table or view name to query
7071
*/
71-
from(relation: string): PostgrestQueryBuilder<Schema, any, any> {
72+
from(relation: string): PostgrestQueryBuilder<ClientOptions, Schema, any, any> {
7273
const url = new URL(`${this.url}/${relation}`)
7374
return new PostgrestQueryBuilder(url, {
7475
headers: { ...this.headers },
@@ -88,6 +89,7 @@ export default class PostgrestClient<
8889
schema: DynamicSchema
8990
): PostgrestClient<
9091
Database,
92+
ClientOptions,
9193
DynamicSchema,
9294
Database[DynamicSchema] extends GenericSchema ? Database[DynamicSchema] : any
9395
> {
@@ -134,6 +136,7 @@ export default class PostgrestClient<
134136
count?: 'exact' | 'planned' | 'estimated'
135137
} = {}
136138
): PostgrestFilterBuilder<
139+
ClientOptions,
137140
Schema,
138141
Fn['Returns'] extends any[]
139142
? Fn['Returns'][number] extends Record<string, unknown>
@@ -176,6 +179,6 @@ export default class PostgrestClient<
176179
body,
177180
fetch: this.fetch,
178181
allowEmpty: false,
179-
} as unknown as PostgrestBuilder<Fn['Returns']>)
182+
} as unknown as PostgrestBuilder<ClientOptions, Fn['Returns']>)
180183
}
181184
}

src/PostgrestFilterBuilder.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import PostgrestTransformBuilder from './PostgrestTransformBuilder'
22
import { JsonPathToAccessor, JsonPathToType } from './select-query-parser/utils'
3-
import { GenericSchema } from './types'
3+
import { ClientServerOptions, GenericSchema } from './types'
44
import { HeaderManager } from './utils'
55

66
type FilterOperator =
@@ -73,13 +73,22 @@ type ResolveFilterRelationshipValue<
7373
export type InvalidMethodError<S extends string> = { Error: S }
7474

7575
export default class PostgrestFilterBuilder<
76+
ClientOptions extends ClientServerOptions,
7677
Schema extends GenericSchema,
7778
Row extends Record<string, unknown>,
7879
Result,
7980
RelationName = unknown,
8081
Relationships = unknown,
8182
Method = unknown
82-
> extends PostgrestTransformBuilder<Schema, Row, Result, RelationName, Relationships, Method> {
83+
> extends PostgrestTransformBuilder<
84+
ClientOptions,
85+
Schema,
86+
Row,
87+
Result,
88+
RelationName,
89+
Relationships,
90+
Method
91+
> {
8392
maxAffected(
8493
value: number
8594
): Method extends 'PATCH' | 'DELETE'

src/PostgrestQueryBuilder.ts

Lines changed: 80 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import PostgrestBuilder from './PostgrestBuilder'
22
import PostgrestFilterBuilder from './PostgrestFilterBuilder'
33
import { GetResult } from './select-query-parser/result'
4-
import { Fetch, GenericSchema, GenericTable, GenericView } from './types'
4+
import { ClientServerOptions, Fetch, GenericSchema, GenericTable, GenericView } from './types'
55

66
export default class PostgrestQueryBuilder<
7+
ClientOptions extends ClientServerOptions,
78
Schema extends GenericSchema,
89
Relation extends GenericTable | GenericView,
910
RelationName = unknown,
@@ -56,7 +57,14 @@ export default class PostgrestQueryBuilder<
5657
*/
5758
select<
5859
Query extends string = '*',
59-
ResultOne = GetResult<Schema, Relation['Row'], RelationName, Relationships, Query>
60+
ResultOne = GetResult<
61+
Schema,
62+
Relation['Row'],
63+
RelationName,
64+
Relationships,
65+
Query,
66+
ClientOptions
67+
>
6068
>(
6169
columns?: Query,
6270
{
@@ -67,6 +75,7 @@ export default class PostgrestQueryBuilder<
6775
count?: 'exact' | 'planned' | 'estimated'
6876
} = {}
6977
): PostgrestFilterBuilder<
78+
ClientOptions,
7079
Schema,
7180
Relation['Row'],
7281
ResultOne[],
@@ -101,7 +110,7 @@ export default class PostgrestQueryBuilder<
101110
schema: this.schema,
102111
fetch: this.fetch,
103112
allowEmpty: false,
104-
} as unknown as PostgrestBuilder<ResultOne[]>)
113+
} as unknown as PostgrestBuilder<ClientOptions, ResultOne[]>)
105114
}
106115

107116
// TODO(v3): Make `defaultToNull` consistent for both single & bulk inserts.
@@ -110,14 +119,30 @@ export default class PostgrestQueryBuilder<
110119
options?: {
111120
count?: 'exact' | 'planned' | 'estimated'
112121
}
113-
): PostgrestFilterBuilder<Schema, Relation['Row'], null, RelationName, Relationships, 'POST'>
122+
): PostgrestFilterBuilder<
123+
ClientOptions,
124+
Schema,
125+
Relation['Row'],
126+
null,
127+
RelationName,
128+
Relationships,
129+
'POST'
130+
>
114131
insert<Row extends Relation extends { Insert: unknown } ? Relation['Insert'] : never>(
115132
values: Row[],
116133
options?: {
117134
count?: 'exact' | 'planned' | 'estimated'
118135
defaultToNull?: boolean
119136
}
120-
): PostgrestFilterBuilder<Schema, Relation['Row'], null, RelationName, Relationships, 'POST'>
137+
): PostgrestFilterBuilder<
138+
ClientOptions,
139+
Schema,
140+
Relation['Row'],
141+
null,
142+
RelationName,
143+
Relationships,
144+
'POST'
145+
>
121146
/**
122147
* Perform an INSERT into the table or view.
123148
*
@@ -153,7 +178,15 @@ export default class PostgrestQueryBuilder<
153178
count?: 'exact' | 'planned' | 'estimated'
154179
defaultToNull?: boolean
155180
} = {}
156-
): PostgrestFilterBuilder<Schema, Relation['Row'], null, RelationName, Relationships, 'POST'> {
181+
): PostgrestFilterBuilder<
182+
ClientOptions,
183+
Schema,
184+
Relation['Row'],
185+
null,
186+
RelationName,
187+
Relationships,
188+
'POST'
189+
> {
157190
const method = 'POST'
158191

159192
const prefersHeaders = []
@@ -184,7 +217,7 @@ export default class PostgrestQueryBuilder<
184217
body: values,
185218
fetch: this.fetch,
186219
allowEmpty: false,
187-
} as unknown as PostgrestBuilder<null>)
220+
} as unknown as PostgrestBuilder<ClientOptions, null>)
188221
}
189222

190223
// TODO(v3): Make `defaultToNull` consistent for both single & bulk upserts.
@@ -195,7 +228,15 @@ export default class PostgrestQueryBuilder<
195228
ignoreDuplicates?: boolean
196229
count?: 'exact' | 'planned' | 'estimated'
197230
}
198-
): PostgrestFilterBuilder<Schema, Relation['Row'], null, RelationName, Relationships, 'POST'>
231+
): PostgrestFilterBuilder<
232+
ClientOptions,
233+
Schema,
234+
Relation['Row'],
235+
null,
236+
RelationName,
237+
Relationships,
238+
'POST'
239+
>
199240
upsert<Row extends Relation extends { Insert: unknown } ? Relation['Insert'] : never>(
200241
values: Row[],
201242
options?: {
@@ -204,7 +245,15 @@ export default class PostgrestQueryBuilder<
204245
count?: 'exact' | 'planned' | 'estimated'
205246
defaultToNull?: boolean
206247
}
207-
): PostgrestFilterBuilder<Schema, Relation['Row'], null, RelationName, Relationships, 'POST'>
248+
): PostgrestFilterBuilder<
249+
ClientOptions,
250+
Schema,
251+
Relation['Row'],
252+
null,
253+
RelationName,
254+
Relationships,
255+
'POST'
256+
>
208257
/**
209258
* Perform an UPSERT on the table or view. Depending on the column(s) passed
210259
* to `onConflict`, `.upsert()` allows you to perform the equivalent of
@@ -256,7 +305,15 @@ export default class PostgrestQueryBuilder<
256305
count?: 'exact' | 'planned' | 'estimated'
257306
defaultToNull?: boolean
258307
} = {}
259-
): PostgrestFilterBuilder<Schema, Relation['Row'], null, RelationName, Relationships, 'POST'> {
308+
): PostgrestFilterBuilder<
309+
ClientOptions,
310+
Schema,
311+
Relation['Row'],
312+
null,
313+
RelationName,
314+
Relationships,
315+
'POST'
316+
> {
260317
const method = 'POST'
261318

262319
const prefersHeaders = [`resolution=${ignoreDuplicates ? 'ignore' : 'merge'}-duplicates`]
@@ -289,7 +346,7 @@ export default class PostgrestQueryBuilder<
289346
body: values,
290347
fetch: this.fetch,
291348
allowEmpty: false,
292-
} as unknown as PostgrestBuilder<null>)
349+
} as unknown as PostgrestBuilder<ClientOptions, null>)
293350
}
294351

295352
/**
@@ -320,7 +377,15 @@ export default class PostgrestQueryBuilder<
320377
}: {
321378
count?: 'exact' | 'planned' | 'estimated'
322379
} = {}
323-
): PostgrestFilterBuilder<Schema, Relation['Row'], null, RelationName, Relationships, 'PATCH'> {
380+
): PostgrestFilterBuilder<
381+
ClientOptions,
382+
Schema,
383+
Relation['Row'],
384+
null,
385+
RelationName,
386+
Relationships,
387+
'PATCH'
388+
> {
324389
const method = 'PATCH'
325390
const prefersHeaders = []
326391
if (this.headers['Prefer']) {
@@ -339,7 +404,7 @@ export default class PostgrestQueryBuilder<
339404
body: values,
340405
fetch: this.fetch,
341406
allowEmpty: false,
342-
} as unknown as PostgrestBuilder<null>)
407+
} as unknown as PostgrestBuilder<ClientOptions, null>)
343408
}
344409

345410
/**
@@ -366,6 +431,7 @@ export default class PostgrestQueryBuilder<
366431
}: {
367432
count?: 'exact' | 'planned' | 'estimated'
368433
} = {}): PostgrestFilterBuilder<
434+
ClientOptions,
369435
Schema,
370436
Relation['Row'],
371437
null,
@@ -390,6 +456,6 @@ export default class PostgrestQueryBuilder<
390456
schema: this.schema,
391457
fetch: this.fetch,
392458
allowEmpty: false,
393-
} as unknown as PostgrestBuilder<null>)
459+
} as unknown as PostgrestBuilder<ClientOptions, null>)
394460
}
395461
}

0 commit comments

Comments
 (0)