1- import { ClientServerOptions , GenericTable } from '../types'
2- import { ContainsNull , GenericRelationship , PostgreSQLTypes } from './types'
31import { Ast , ParseQuery } from './parser'
42import {
53 AggregateFunctions ,
@@ -9,6 +7,11 @@ import {
97 Prettify ,
108 TablesAndViews ,
119 TypeScriptTypes ,
10+ ContainsNull ,
11+ GenericRelationship ,
12+ PostgreSQLTypes ,
13+ GenericTable ,
14+ ClientServerOptions ,
1215} from './types'
1316import {
1417 CheckDuplicateEmbededReference ,
@@ -366,7 +369,7 @@ export type ProcessEmbeddedResource<
366369 ResolveRelationship < Schema , Relationships , Field , CurrentTableOrView > extends infer Resolved
367370 ? Resolved extends {
368371 referencedTable : Pick < GenericTable , 'Row' | 'Relationships' >
369- relation : GenericRelationship & { match : 'refrel' | 'col' | 'fkname' }
372+ relation : GenericRelationship & { match : 'refrel' | 'col' | 'fkname' | 'func' }
370373 direction : string
371374 }
372375 ? ProcessEmbeddedResourceResult < ClientOptions , Schema , Resolved , Field , CurrentTableOrView >
@@ -385,7 +388,12 @@ type ProcessEmbeddedResourceResult<
385388 Schema extends GenericSchema ,
386389 Resolved extends {
387390 referencedTable : Pick < GenericTable , 'Row' | 'Relationships' >
388- relation : GenericRelationship & { match : 'refrel' | 'col' | 'fkname' }
391+ relation : GenericRelationship & {
392+ match : 'refrel' | 'col' | 'fkname' | 'func'
393+ isNotNullable ?: boolean
394+ referencedRelation : string
395+ isSetofReturn ?: boolean
396+ }
389397 direction : string
390398 } ,
391399 Field extends Ast . FieldNode ,
@@ -395,7 +403,11 @@ type ProcessEmbeddedResourceResult<
395403 ClientOptions ,
396404 Schema ,
397405 Resolved [ 'referencedTable' ] [ 'Row' ] ,
398- Field [ 'name' ] ,
406+ // For embeded function selection, the source of truth is the 'referencedRelation'
407+ // coming from the SetofOptions.to parameter
408+ Resolved [ 'relation' ] [ 'match' ] extends 'func'
409+ ? Resolved [ 'relation' ] [ 'referencedRelation' ]
410+ : Field [ 'name' ] ,
399411 Resolved [ 'referencedTable' ] [ 'Relationships' ] ,
400412 Field [ 'children' ] extends undefined
401413 ? [ ]
@@ -410,7 +422,18 @@ type ProcessEmbeddedResourceResult<
410422 ? ProcessedChildren
411423 : ProcessedChildren [ ]
412424 : Resolved [ 'relation' ] [ 'isOneToOne' ] extends true
413- ? ProcessedChildren | null
425+ ? Resolved [ 'relation' ] [ 'match' ] extends 'func'
426+ ? Resolved [ 'relation' ] [ 'isNotNullable' ] extends true
427+ ? Resolved [ 'relation' ] [ 'isSetofReturn' ] extends true
428+ ? ProcessedChildren
429+ : // TODO: This shouldn't be necessary but is due in an inconsitency in PostgREST v12/13 where if a function
430+ // is declared with RETURNS <table-name> instead of RETURNS SETOF <table-name> ROWS 1
431+ // In case where there is no object matching the relations, the object will be returned with all the properties within it
432+ // set to null, we mimic this buggy behavior for type safety an issue is opened on postgREST here:
433+ // https://github.com/PostgREST/postgrest/issues/4234
434+ { [ P in keyof ProcessedChildren ] : ProcessedChildren [ P ] | null }
435+ : ProcessedChildren | null
436+ : ProcessedChildren | null
414437 : ProcessedChildren [ ]
415438 : // If the relation is a self-reference it'll always be considered as reverse relationship
416439 Resolved [ 'relation' ] [ 'referencedRelation' ] extends CurrentTableOrView
0 commit comments