@supabase/postgrest-js 1.19.3 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/cjs/PostgrestBuilder.d.ts +6 -6
  2. package/dist/cjs/PostgrestBuilder.d.ts.map +1 -1
  3. package/dist/cjs/PostgrestBuilder.js.map +1 -1
  4. package/dist/cjs/PostgrestClient.d.ts +8 -6
  5. package/dist/cjs/PostgrestClient.d.ts.map +1 -1
  6. package/dist/cjs/PostgrestClient.js.map +1 -1
  7. package/dist/cjs/PostgrestFilterBuilder.d.ts +5 -2
  8. package/dist/cjs/PostgrestFilterBuilder.d.ts.map +1 -1
  9. package/dist/cjs/PostgrestFilterBuilder.js.map +1 -1
  10. package/dist/cjs/PostgrestQueryBuilder.d.ts +10 -10
  11. package/dist/cjs/PostgrestQueryBuilder.d.ts.map +1 -1
  12. package/dist/cjs/PostgrestQueryBuilder.js.map +1 -1
  13. package/dist/cjs/PostgrestTransformBuilder.d.ts +9 -9
  14. package/dist/cjs/PostgrestTransformBuilder.d.ts.map +1 -1
  15. package/dist/cjs/PostgrestTransformBuilder.js.map +1 -1
  16. package/dist/cjs/index.d.ts +1 -1
  17. package/dist/cjs/index.d.ts.map +1 -1
  18. package/dist/cjs/select-query-parser/result.d.ts +21 -11
  19. package/dist/cjs/select-query-parser/result.d.ts.map +1 -1
  20. package/dist/cjs/types.d.ts +12 -1
  21. package/dist/cjs/types.d.ts.map +1 -1
  22. package/dist/cjs/types.js +1 -0
  23. package/dist/cjs/types.js.map +1 -1
  24. package/package.json +5 -3
  25. package/src/PostgrestBuilder.ts +17 -6
  26. package/src/PostgrestClient.ts +17 -10
  27. package/src/PostgrestFilterBuilder.ts +12 -2
  28. package/src/PostgrestQueryBuilder.ts +87 -16
  29. package/src/PostgrestTransformBuilder.ts +41 -21
  30. package/src/index.ts +1 -0
  31. package/src/select-query-parser/result.ts +80 -14
  32. package/src/types.ts +27 -1
  33. package/src/version.ts +1 -1
@@ -1,9 +1,10 @@
1
1
  import PostgrestBuilder from './PostgrestBuilder'
2
2
  import PostgrestFilterBuilder from './PostgrestFilterBuilder'
3
3
  import { GetResult } from './select-query-parser/result'
4
- import { Fetch, GenericSchema, GenericTable, GenericView } from './types'
4
+ import { ClientServerOptions, Fetch, GenericSchema, GenericTable, GenericView } from './types'
5
5
 
6
6
  export default class PostgrestQueryBuilder<
7
+ ClientOptions extends ClientServerOptions,
7
8
  Schema extends GenericSchema,
8
9
  Relation extends GenericTable | GenericView,
9
10
  RelationName = unknown,
@@ -56,7 +57,14 @@ export default class PostgrestQueryBuilder<
56
57
  */
57
58
  select<
58
59
  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
+ >
60
68
  >(
61
69
  columns?: Query,
62
70
  {
@@ -66,7 +74,14 @@ export default class PostgrestQueryBuilder<
66
74
  head?: boolean
67
75
  count?: 'exact' | 'planned' | 'estimated'
68
76
  } = {}
69
- ): PostgrestFilterBuilder<Schema, Relation['Row'], ResultOne[], RelationName, Relationships> {
77
+ ): PostgrestFilterBuilder<
78
+ ClientOptions,
79
+ Schema,
80
+ Relation['Row'],
81
+ ResultOne[],
82
+ RelationName,
83
+ Relationships
84
+ > {
70
85
  const method = head ? 'HEAD' : 'GET'
71
86
  // Remove whitespaces except when quoted
72
87
  let quoted = false
@@ -94,7 +109,7 @@ export default class PostgrestQueryBuilder<
94
109
  schema: this.schema,
95
110
  fetch: this.fetch,
96
111
  allowEmpty: false,
97
- } as unknown as PostgrestBuilder<ResultOne[]>)
112
+ } as unknown as PostgrestBuilder<ClientOptions, ResultOne[]>)
98
113
  }
99
114
 
100
115
  // TODO(v3): Make `defaultToNull` consistent for both single & bulk inserts.
@@ -103,14 +118,28 @@ export default class PostgrestQueryBuilder<
103
118
  options?: {
104
119
  count?: 'exact' | 'planned' | 'estimated'
105
120
  }
106
- ): PostgrestFilterBuilder<Schema, Relation['Row'], null, RelationName, Relationships>
121
+ ): PostgrestFilterBuilder<
122
+ ClientOptions,
123
+ Schema,
124
+ Relation['Row'],
125
+ null,
126
+ RelationName,
127
+ Relationships
128
+ >
107
129
  insert<Row extends Relation extends { Insert: unknown } ? Relation['Insert'] : never>(
108
130
  values: Row[],
109
131
  options?: {
110
132
  count?: 'exact' | 'planned' | 'estimated'
111
133
  defaultToNull?: boolean
112
134
  }
113
- ): PostgrestFilterBuilder<Schema, Relation['Row'], null, RelationName, Relationships>
135
+ ): PostgrestFilterBuilder<
136
+ ClientOptions,
137
+ Schema,
138
+ Relation['Row'],
139
+ null,
140
+ RelationName,
141
+ Relationships
142
+ >
114
143
  /**
115
144
  * Perform an INSERT into the table or view.
116
145
  *
@@ -146,7 +175,14 @@ export default class PostgrestQueryBuilder<
146
175
  count?: 'exact' | 'planned' | 'estimated'
147
176
  defaultToNull?: boolean
148
177
  } = {}
149
- ): PostgrestFilterBuilder<Schema, Relation['Row'], null, RelationName, Relationships> {
178
+ ): PostgrestFilterBuilder<
179
+ ClientOptions,
180
+ Schema,
181
+ Relation['Row'],
182
+ null,
183
+ RelationName,
184
+ Relationships
185
+ > {
150
186
  const method = 'POST'
151
187
 
152
188
  const prefersHeaders = []
@@ -177,7 +213,7 @@ export default class PostgrestQueryBuilder<
177
213
  body: values,
178
214
  fetch: this.fetch,
179
215
  allowEmpty: false,
180
- } as unknown as PostgrestBuilder<null>)
216
+ } as unknown as PostgrestBuilder<ClientOptions, null>)
181
217
  }
182
218
 
183
219
  // TODO(v3): Make `defaultToNull` consistent for both single & bulk upserts.
@@ -188,7 +224,14 @@ export default class PostgrestQueryBuilder<
188
224
  ignoreDuplicates?: boolean
189
225
  count?: 'exact' | 'planned' | 'estimated'
190
226
  }
191
- ): PostgrestFilterBuilder<Schema, Relation['Row'], null, RelationName, Relationships>
227
+ ): PostgrestFilterBuilder<
228
+ ClientOptions,
229
+ Schema,
230
+ Relation['Row'],
231
+ null,
232
+ RelationName,
233
+ Relationships
234
+ >
192
235
  upsert<Row extends Relation extends { Insert: unknown } ? Relation['Insert'] : never>(
193
236
  values: Row[],
194
237
  options?: {
@@ -197,7 +240,14 @@ export default class PostgrestQueryBuilder<
197
240
  count?: 'exact' | 'planned' | 'estimated'
198
241
  defaultToNull?: boolean
199
242
  }
200
- ): PostgrestFilterBuilder<Schema, Relation['Row'], null, RelationName, Relationships>
243
+ ): PostgrestFilterBuilder<
244
+ ClientOptions,
245
+ Schema,
246
+ Relation['Row'],
247
+ null,
248
+ RelationName,
249
+ Relationships
250
+ >
201
251
  /**
202
252
  * Perform an UPSERT on the table or view. Depending on the column(s) passed
203
253
  * to `onConflict`, `.upsert()` allows you to perform the equivalent of
@@ -249,7 +299,14 @@ export default class PostgrestQueryBuilder<
249
299
  count?: 'exact' | 'planned' | 'estimated'
250
300
  defaultToNull?: boolean
251
301
  } = {}
252
- ): PostgrestFilterBuilder<Schema, Relation['Row'], null, RelationName, Relationships> {
302
+ ): PostgrestFilterBuilder<
303
+ ClientOptions,
304
+ Schema,
305
+ Relation['Row'],
306
+ null,
307
+ RelationName,
308
+ Relationships
309
+ > {
253
310
  const method = 'POST'
254
311
 
255
312
  const prefersHeaders = [`resolution=${ignoreDuplicates ? 'ignore' : 'merge'}-duplicates`]
@@ -282,7 +339,7 @@ export default class PostgrestQueryBuilder<
282
339
  body: values,
283
340
  fetch: this.fetch,
284
341
  allowEmpty: false,
285
- } as unknown as PostgrestBuilder<null>)
342
+ } as unknown as PostgrestBuilder<ClientOptions, null>)
286
343
  }
287
344
 
288
345
  /**
@@ -313,7 +370,14 @@ export default class PostgrestQueryBuilder<
313
370
  }: {
314
371
  count?: 'exact' | 'planned' | 'estimated'
315
372
  } = {}
316
- ): PostgrestFilterBuilder<Schema, Relation['Row'], null, RelationName, Relationships> {
373
+ ): PostgrestFilterBuilder<
374
+ ClientOptions,
375
+ Schema,
376
+ Relation['Row'],
377
+ null,
378
+ RelationName,
379
+ Relationships
380
+ > {
317
381
  const method = 'PATCH'
318
382
  const prefersHeaders = []
319
383
  if (this.headers['Prefer']) {
@@ -332,7 +396,7 @@ export default class PostgrestQueryBuilder<
332
396
  body: values,
333
397
  fetch: this.fetch,
334
398
  allowEmpty: false,
335
- } as unknown as PostgrestBuilder<null>)
399
+ } as unknown as PostgrestBuilder<ClientOptions, null>)
336
400
  }
337
401
 
338
402
  /**
@@ -358,7 +422,14 @@ export default class PostgrestQueryBuilder<
358
422
  count,
359
423
  }: {
360
424
  count?: 'exact' | 'planned' | 'estimated'
361
- } = {}): PostgrestFilterBuilder<Schema, Relation['Row'], null, RelationName, Relationships> {
425
+ } = {}): PostgrestFilterBuilder<
426
+ ClientOptions,
427
+ Schema,
428
+ Relation['Row'],
429
+ null,
430
+ RelationName,
431
+ Relationships
432
+ > {
362
433
  const method = 'DELETE'
363
434
  const prefersHeaders = []
364
435
  if (count) {
@@ -376,6 +447,6 @@ export default class PostgrestQueryBuilder<
376
447
  schema: this.schema,
377
448
  fetch: this.fetch,
378
449
  allowEmpty: false,
379
- } as unknown as PostgrestBuilder<null>)
450
+ } as unknown as PostgrestBuilder<ClientOptions, null>)
380
451
  }
381
452
  }
@@ -1,14 +1,16 @@
1
1
  import PostgrestBuilder from './PostgrestBuilder'
2
2
  import { GetResult } from './select-query-parser/result'
3
- import { GenericSchema, CheckMatchingArrayTypes } from './types'
3
+ import { GenericSchema, CheckMatchingArrayTypes, ClientServerOptions } from './types'
4
4
 
5
5
  export default class PostgrestTransformBuilder<
6
+ ClientOptions extends ClientServerOptions,
6
7
  Schema extends GenericSchema,
7
8
  Row extends Record<string, unknown>,
8
9
  Result,
9
10
  RelationName = unknown,
10
- Relationships = unknown
11
- > extends PostgrestBuilder<Result> {
11
+ Relationships = unknown,
12
+ Method = unknown
13
+ > extends PostgrestBuilder<ClientOptions, Result> {
12
14
  /**
13
15
  * Perform a SELECT on the query result.
14
16
  *
@@ -20,10 +22,18 @@ export default class PostgrestTransformBuilder<
20
22
  */
21
23
  select<
22
24
  Query extends string = '*',
23
- NewResultOne = GetResult<Schema, Row, RelationName, Relationships, Query>
25
+ NewResultOne = GetResult<Schema, Row, RelationName, Relationships, Query, ClientOptions>
24
26
  >(
25
27
  columns?: Query
26
- ): PostgrestTransformBuilder<Schema, Row, NewResultOne[], RelationName, Relationships> {
28
+ ): PostgrestTransformBuilder<
29
+ ClientOptions,
30
+ Schema,
31
+ Row,
32
+ NewResultOne[],
33
+ RelationName,
34
+ Relationships,
35
+ Method
36
+ > {
27
37
  // Remove whitespaces except when quoted
28
38
  let quoted = false
29
39
  const cleanedColumns = (columns ?? '*')
@@ -44,11 +54,13 @@ export default class PostgrestTransformBuilder<
44
54
  }
45
55
  this.headers['Prefer'] += 'return=representation'
46
56
  return this as unknown as PostgrestTransformBuilder<
57
+ ClientOptions,
47
58
  Schema,
48
59
  Row,
49
60
  NewResultOne[],
50
61
  RelationName,
51
- Relationships
62
+ Relationships,
63
+ Method
52
64
  >
53
65
  }
54
66
 
@@ -188,11 +200,12 @@ export default class PostgrestTransformBuilder<
188
200
  * Query result must be one row (e.g. using `.limit(1)`), otherwise this
189
201
  * returns an error.
190
202
  */
191
- single<
192
- ResultOne = Result extends (infer ResultOne)[] ? ResultOne : never
193
- >(): PostgrestBuilder<ResultOne> {
203
+ single<ResultOne = Result extends (infer ResultOne)[] ? ResultOne : never>(): PostgrestBuilder<
204
+ ClientOptions,
205
+ ResultOne
206
+ > {
194
207
  this.headers['Accept'] = 'application/vnd.pgrst.object+json'
195
- return this as unknown as PostgrestBuilder<ResultOne>
208
+ return this as unknown as PostgrestBuilder<ClientOptions, ResultOne>
196
209
  }
197
210
 
198
211
  /**
@@ -203,7 +216,7 @@ export default class PostgrestTransformBuilder<
203
216
  */
204
217
  maybeSingle<
205
218
  ResultOne = Result extends (infer ResultOne)[] ? ResultOne : never
206
- >(): PostgrestBuilder<ResultOne | null> {
219
+ >(): PostgrestBuilder<ClientOptions, ResultOne | null> {
207
220
  // Temporary partial fix for https://github.com/supabase/postgrest-js/issues/361
208
221
  // Issue persists e.g. for `.insert([...]).select().maybeSingle()`
209
222
  if (this.method === 'GET') {
@@ -212,23 +225,23 @@ export default class PostgrestTransformBuilder<
212
225
  this.headers['Accept'] = 'application/vnd.pgrst.object+json'
213
226
  }
214
227
  this.isMaybeSingle = true
215
- return this as unknown as PostgrestBuilder<ResultOne | null>
228
+ return this as unknown as PostgrestBuilder<ClientOptions, ResultOne | null>
216
229
  }
217
230
 
218
231
  /**
219
232
  * Return `data` as a string in CSV format.
220
233
  */
221
- csv(): PostgrestBuilder<string> {
234
+ csv(): PostgrestBuilder<ClientOptions, string> {
222
235
  this.headers['Accept'] = 'text/csv'
223
- return this as unknown as PostgrestBuilder<string>
236
+ return this as unknown as PostgrestBuilder<ClientOptions, string>
224
237
  }
225
238
 
226
239
  /**
227
240
  * Return `data` as an object in [GeoJSON](https://geojson.org) format.
228
241
  */
229
- geojson(): PostgrestBuilder<Record<string, unknown>> {
242
+ geojson(): PostgrestBuilder<ClientOptions, Record<string, unknown>> {
230
243
  this.headers['Accept'] = 'application/geo+json'
231
- return this as unknown as PostgrestBuilder<Record<string, unknown>>
244
+ return this as unknown as PostgrestBuilder<ClientOptions, Record<string, unknown>>
232
245
  }
233
246
 
234
247
  /**
@@ -270,7 +283,9 @@ export default class PostgrestTransformBuilder<
270
283
  buffers?: boolean
271
284
  wal?: boolean
272
285
  format?: 'json' | 'text'
273
- } = {}): PostgrestBuilder<Record<string, unknown>[]> | PostgrestBuilder<string> {
286
+ } = {}):
287
+ | PostgrestBuilder<ClientOptions, Record<string, unknown>[]>
288
+ | PostgrestBuilder<ClientOptions, string> {
274
289
  const options = [
275
290
  analyze ? 'analyze' : null,
276
291
  verbose ? 'verbose' : null,
@@ -285,8 +300,9 @@ export default class PostgrestTransformBuilder<
285
300
  this.headers[
286
301
  'Accept'
287
302
  ] = `application/vnd.pgrst.plan+${format}; for="${forMediatype}"; options=${options};`
288
- if (format === 'json') return this as unknown as PostgrestBuilder<Record<string, unknown>[]>
289
- else return this as unknown as PostgrestBuilder<string>
303
+ if (format === 'json')
304
+ return this as unknown as PostgrestBuilder<ClientOptions, Record<string, unknown>[]>
305
+ else return this as unknown as PostgrestBuilder<ClientOptions, string>
290
306
  }
291
307
 
292
308
  /**
@@ -310,18 +326,22 @@ export default class PostgrestTransformBuilder<
310
326
  * @deprecated Use overrideTypes<yourType, { merge: false }>() method at the end of your call chain instead
311
327
  */
312
328
  returns<NewResult>(): PostgrestTransformBuilder<
329
+ ClientOptions,
313
330
  Schema,
314
331
  Row,
315
332
  CheckMatchingArrayTypes<Result, NewResult>,
316
333
  RelationName,
317
- Relationships
334
+ Relationships,
335
+ Method
318
336
  > {
319
337
  return this as unknown as PostgrestTransformBuilder<
338
+ ClientOptions,
320
339
  Schema,
321
340
  Row,
322
341
  CheckMatchingArrayTypes<Result, NewResult>,
323
342
  RelationName,
324
- Relationships
343
+ Relationships,
344
+ Method
325
345
  >
326
346
  }
327
347
  }
package/src/index.ts CHANGED
@@ -28,6 +28,7 @@ export type {
28
28
  PostgrestResponseSuccess,
29
29
  PostgrestSingleResponse,
30
30
  PostgrestMaybeSingleResponse,
31
+ ClientServerOptions,
31
32
  } from './types'
32
33
  // https://github.com/supabase/postgrest-js/issues/551
33
34
  // To be replaced with a helper type that only uses public types
@@ -1,4 +1,4 @@
1
- import { GenericTable } from '../types'
1
+ import { ClientServerOptions, GenericTable } from '../types'
2
2
  import { ContainsNull, GenericRelationship, PostgreSQLTypes } from './types'
3
3
  import { Ast, ParseQuery } from './parser'
4
4
  import {
@@ -21,6 +21,9 @@ import {
21
21
  SelectQueryError,
22
22
  } from './utils'
23
23
 
24
+ export type SpreadOnManyEnabled<PostgrestVersion extends string | undefined> =
25
+ PostgrestVersion extends `13${string}` ? true : false
26
+
24
27
  /**
25
28
  * Main entry point for constructing the result type of a PostgREST query.
26
29
  *
@@ -35,7 +38,8 @@ export type GetResult<
35
38
  Row extends Record<string, unknown>,
36
39
  RelationName,
37
40
  Relationships,
38
- Query extends string
41
+ Query extends string,
42
+ ClientOptions extends ClientServerOptions
39
43
  > = IsAny<Schema> extends true
40
44
  ? ParseQuery<Query> extends infer ParsedQuery
41
45
  ? ParsedQuery extends Ast.Node[]
@@ -54,7 +58,7 @@ export type GetResult<
54
58
  ? ParsedQuery extends Ast.Node[]
55
59
  ? RelationName extends string
56
60
  ? Relationships extends GenericRelationship[]
57
- ? ProcessNodes<Schema, Row, RelationName, Relationships, ParsedQuery>
61
+ ? ProcessNodes<ClientOptions, Schema, Row, RelationName, Relationships, ParsedQuery>
58
62
  : SelectQueryError<'Invalid Relationships cannot infer result type'>
59
63
  : SelectQueryError<'Invalid RelationName cannot infer result type'>
60
64
  : ParsedQuery
@@ -173,6 +177,7 @@ export type RPCCallNodes<
173
177
  * @param Acc - Accumulator for the constructed type.
174
178
  */
175
179
  export type ProcessNodes<
180
+ ClientOptions extends ClientServerOptions,
176
181
  Schema extends GenericSchema,
177
182
  Row extends Record<string, unknown>,
178
183
  RelationName extends string,
@@ -183,9 +188,24 @@ export type ProcessNodes<
183
188
  ? Nodes extends [infer FirstNode, ...infer RestNodes]
184
189
  ? FirstNode extends Ast.Node
185
190
  ? RestNodes extends Ast.Node[]
186
- ? ProcessNode<Schema, Row, RelationName, Relationships, FirstNode> extends infer FieldResult
191
+ ? ProcessNode<
192
+ ClientOptions,
193
+ Schema,
194
+ Row,
195
+ RelationName,
196
+ Relationships,
197
+ FirstNode
198
+ > extends infer FieldResult
187
199
  ? FieldResult extends Record<string, unknown>
188
- ? ProcessNodes<Schema, Row, RelationName, Relationships, RestNodes, Acc & FieldResult>
200
+ ? ProcessNodes<
201
+ ClientOptions,
202
+ Schema,
203
+ Row,
204
+ RelationName,
205
+ Relationships,
206
+ RestNodes,
207
+ Acc & FieldResult
208
+ >
189
209
  : FieldResult extends SelectQueryError<infer E>
190
210
  ? SelectQueryError<E>
191
211
  : SelectQueryError<'Could not retrieve a valid record or error value'>
@@ -205,6 +225,7 @@ export type ProcessNodes<
205
225
  * @param NodeType - The Node to process.
206
226
  */
207
227
  export type ProcessNode<
228
+ ClientOptions extends ClientServerOptions,
208
229
  Schema extends GenericSchema,
209
230
  Row extends Record<string, unknown>,
210
231
  RelationName extends string,
@@ -215,9 +236,23 @@ export type ProcessNode<
215
236
  NodeType['type'] extends Ast.StarNode['type'] // If the selection is *
216
237
  ? Row
217
238
  : NodeType['type'] extends Ast.SpreadNode['type'] // If the selection is a ...spread
218
- ? ProcessSpreadNode<Schema, Row, RelationName, Relationships, Extract<NodeType, Ast.SpreadNode>>
239
+ ? ProcessSpreadNode<
240
+ ClientOptions,
241
+ Schema,
242
+ Row,
243
+ RelationName,
244
+ Relationships,
245
+ Extract<NodeType, Ast.SpreadNode>
246
+ >
219
247
  : NodeType['type'] extends Ast.FieldNode['type']
220
- ? ProcessFieldNode<Schema, Row, RelationName, Relationships, Extract<NodeType, Ast.FieldNode>>
248
+ ? ProcessFieldNode<
249
+ ClientOptions,
250
+ Schema,
251
+ Row,
252
+ RelationName,
253
+ Relationships,
254
+ Extract<NodeType, Ast.FieldNode>
255
+ >
221
256
  : SelectQueryError<'Unsupported node type.'>
222
257
 
223
258
  /**
@@ -230,6 +265,7 @@ export type ProcessNode<
230
265
  * @param Field - The FieldNode to process.
231
266
  */
232
267
  type ProcessFieldNode<
268
+ ClientOptions extends ClientServerOptions,
233
269
  Schema extends GenericSchema,
234
270
  Row extends Record<string, unknown>,
235
271
  RelationName extends string,
@@ -238,7 +274,7 @@ type ProcessFieldNode<
238
274
  > = Field['children'] extends []
239
275
  ? {}
240
276
  : IsNonEmptyArray<Field['children']> extends true // Has embedded resource?
241
- ? ProcessEmbeddedResource<Schema, Relationships, Field, RelationName>
277
+ ? ProcessEmbeddedResource<ClientOptions, Schema, Relationships, Field, RelationName>
242
278
  : ProcessSimpleField<Row, RelationName, Field>
243
279
 
244
280
  type ResolveJsonPathType<
@@ -303,6 +339,7 @@ type ProcessSimpleField<
303
339
  * @param Field - The FieldNode to process.
304
340
  */
305
341
  export type ProcessEmbeddedResource<
342
+ ClientOptions extends ClientServerOptions,
306
343
  Schema extends GenericSchema,
307
344
  Relationships extends GenericRelationship[],
308
345
  Field extends Ast.FieldNode,
@@ -313,7 +350,7 @@ export type ProcessEmbeddedResource<
313
350
  relation: GenericRelationship & { match: 'refrel' | 'col' | 'fkname' }
314
351
  direction: string
315
352
  }
316
- ? ProcessEmbeddedResourceResult<Schema, Resolved, Field, CurrentTableOrView>
353
+ ? ProcessEmbeddedResourceResult<ClientOptions, Schema, Resolved, Field, CurrentTableOrView>
317
354
  : // Otherwise the Resolved is a SelectQueryError return it
318
355
  { [K in GetFieldNodeResultName<Field>]: Resolved }
319
356
  : {
@@ -325,6 +362,7 @@ export type ProcessEmbeddedResource<
325
362
  * Helper type to process the result of an embedded resource.
326
363
  */
327
364
  type ProcessEmbeddedResourceResult<
365
+ ClientOptions extends ClientServerOptions,
328
366
  Schema extends GenericSchema,
329
367
  Resolved extends {
330
368
  referencedTable: Pick<GenericTable, 'Row' | 'Relationships'>
@@ -334,6 +372,7 @@ type ProcessEmbeddedResourceResult<
334
372
  Field extends Ast.FieldNode,
335
373
  CurrentTableOrView extends keyof TablesAndViews<Schema>
336
374
  > = ProcessNodes<
375
+ ClientOptions,
337
376
  Schema,
338
377
  Resolved['referencedTable']['Row'],
339
378
  Field['name'],
@@ -372,7 +411,9 @@ type ProcessEmbeddedResourceResult<
372
411
  TablesAndViews<Schema>[CurrentTableOrView],
373
412
  Resolved['relation']
374
413
  > extends true
375
- ? ProcessedChildren | null
414
+ ? Field extends { innerJoin: true }
415
+ ? ProcessedChildren
416
+ : ProcessedChildren | null
376
417
  : ProcessedChildren
377
418
  }
378
419
  : {
@@ -390,21 +431,46 @@ type ProcessEmbeddedResourceResult<
390
431
  * @param Spread - The SpreadNode to process.
391
432
  */
392
433
  type ProcessSpreadNode<
434
+ ClientOptions extends ClientServerOptions,
393
435
  Schema extends GenericSchema,
394
436
  Row extends Record<string, unknown>,
395
437
  RelationName extends string,
396
438
  Relationships extends GenericRelationship[],
397
439
  Spread extends Ast.SpreadNode
398
- > = ProcessNode<Schema, Row, RelationName, Relationships, Spread['target']> extends infer Result
440
+ > = ProcessNode<
441
+ ClientOptions,
442
+ Schema,
443
+ Row,
444
+ RelationName,
445
+ Relationships,
446
+ Spread['target']
447
+ > extends infer Result
399
448
  ? Result extends SelectQueryError<infer E>
400
449
  ? SelectQueryError<E>
401
450
  : ExtractFirstProperty<Result> extends unknown[]
402
- ? {
403
- [K in Spread['target']['name']]: SelectQueryError<`"${RelationName}" and "${Spread['target']['name']}" do not form a many-to-one or one-to-one relationship spread not possible`>
404
- }
451
+ ? SpreadOnManyEnabled<ClientOptions['PostgrestVersion']> extends true // Spread over an many-to-many relationship, turn all the result fields into correlated arrays
452
+ ? ProcessManyToManySpreadNodeResult<Result>
453
+ : {
454
+ [K in Spread['target']['name']]: SelectQueryError<`"${RelationName}" and "${Spread['target']['name']}" do not form a many-to-one or one-to-one relationship spread not possible`>
455
+ }
405
456
  : ProcessSpreadNodeResult<Result>
406
457
  : never
407
458
 
459
+ /**
460
+ * Helper type to process the result of a many-to-many spread node.
461
+ * Converts all fields in the spread object into arrays.
462
+ */
463
+ type ProcessManyToManySpreadNodeResult<Result> = Result extends Record<
464
+ string,
465
+ SelectQueryError<string> | null
466
+ >
467
+ ? Result
468
+ : ExtractFirstProperty<Result> extends infer SpreadedObject
469
+ ? SpreadedObject extends Array<Record<string, unknown>>
470
+ ? { [K in keyof SpreadedObject[number]]: Array<SpreadedObject[number][K]> }
471
+ : SelectQueryError<'An error occurred spreading the many-to-many object'>
472
+ : SelectQueryError<'An error occurred spreading the many-to-many object'>
473
+
408
474
  /**
409
475
  * Helper type to process the result of a spread node.
410
476
  */
package/src/types.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import PostgrestError from './PostgrestError'
2
2
  import { ContainsNull } from './select-query-parser/types'
3
- import { SelectQueryError } from './select-query-parser/utils'
3
+ import { IsAny, SelectQueryError } from './select-query-parser/utils'
4
4
 
5
5
  export type Fetch = typeof fetch
6
6
 
@@ -71,8 +71,34 @@ export type GenericSchema = {
71
71
  Functions: Record<string, GenericFunction>
72
72
  }
73
73
 
74
+ export type ClientServerOptions = {
75
+ PostgrestVersion?: string
76
+ }
77
+
78
+ export type DatabaseWithOptions<Database, Options extends ClientServerOptions> = {
79
+ db: Database
80
+ options: Options
81
+ }
82
+
83
+ const INTERNAL_SUPABASE_OPTIONS = '__InternalSupabase'
84
+
85
+ export type GetGenericDatabaseWithOptions<
86
+ Database,
87
+ Opts extends ClientServerOptions = { PostgrestVersion: '12' }
88
+ > = IsAny<Database> extends true
89
+ ? DatabaseWithOptions<Database, Opts>
90
+ : typeof INTERNAL_SUPABASE_OPTIONS extends keyof Database
91
+ ? Database[typeof INTERNAL_SUPABASE_OPTIONS] extends ClientServerOptions
92
+ ? DatabaseWithOptions<
93
+ Omit<Database, typeof INTERNAL_SUPABASE_OPTIONS>,
94
+ Database[typeof INTERNAL_SUPABASE_OPTIONS]
95
+ >
96
+ : DatabaseWithOptions<Omit<Database, typeof INTERNAL_SUPABASE_OPTIONS>, Opts>
97
+ : DatabaseWithOptions<Database, Opts>
98
+
74
99
  // https://twitter.com/mattpocockuk/status/1622730173446557697
75
100
  export type Prettify<T> = { [K in keyof T]: T[K] } & {}
101
+
76
102
  // https://github.com/sindresorhus/type-fest
77
103
  export type SimplifyDeep<Type, ExcludeType = never> = ConditionalSimplifyDeep<
78
104
  Type,
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '1.19.3'
1
+ export const version = '1.20.0'