@@ -65,6 +65,26 @@ type EatWhitespace<Input extends string> = string extends Input
65
65
? EatWhitespace < Remainder >
66
66
: Input
67
67
68
+ type HasFKey < FKeyName , Relationships > = Relationships extends [ infer R ]
69
+ ? R extends { foreignKeyName : FKeyName }
70
+ ? true
71
+ : false
72
+ : Relationships extends [ infer R , ...infer Rest ]
73
+ ? HasFKey < FKeyName , [ R ] > extends true
74
+ ? true
75
+ : HasFKey < FKeyName , Rest >
76
+ : false
77
+
78
+ type HasFKeyToFRel < FRelName , Relationships > = Relationships extends [ infer R ]
79
+ ? R extends { referencedRelation : FRelName }
80
+ ? true
81
+ : false
82
+ : Relationships extends [ infer R , ...infer Rest ]
83
+ ? HasFKeyToFRel < FRelName , [ R ] > extends true
84
+ ? true
85
+ : HasFKeyToFRel < FRelName , Rest >
86
+ : false
87
+
68
88
/**
69
89
* Constructs a type definition for a single field of an object.
70
90
*
@@ -75,20 +95,44 @@ type EatWhitespace<Input extends string> = string extends Input
75
95
type ConstructFieldDefinition <
76
96
Schema extends GenericSchema ,
77
97
Row extends Record < string , unknown > ,
98
+ Relationships ,
78
99
Field
79
- > = Field extends {
80
- star : true
81
- }
100
+ > = Field extends { star : true }
82
101
? Row
102
+ : Field extends { name : string ; original : string ; hint : string ; children : unknown [ ] }
103
+ ? {
104
+ [ _ in Field [ 'name' ] ] : GetResultHelper <
105
+ Schema ,
106
+ ( Schema [ 'Tables' ] & Schema [ 'Views' ] ) [ Field [ 'original' ] ] [ 'Row' ] ,
107
+ ( Schema [ 'Tables' ] & Schema [ 'Views' ] ) [ Field [ 'original' ] ] extends { Relationships : infer R }
108
+ ? R
109
+ : unknown ,
110
+ Field [ 'children' ] ,
111
+ unknown
112
+ > extends infer Child
113
+ ? Relationships extends unknown [ ]
114
+ ? HasFKey < Field [ 'hint' ] , Relationships > extends true
115
+ ? Child | null
116
+ : Child [ ]
117
+ : Child [ ]
118
+ : never
119
+ }
83
120
: Field extends { name : string ; original : string ; children : unknown [ ] }
84
121
? {
85
122
[ _ in Field [ 'name' ] ] : GetResultHelper <
86
123
Schema ,
87
124
( Schema [ 'Tables' ] & Schema [ 'Views' ] ) [ Field [ 'original' ] ] [ 'Row' ] ,
125
+ ( Schema [ 'Tables' ] & Schema [ 'Views' ] ) [ Field [ 'original' ] ] extends { Relationships : infer R }
126
+ ? R
127
+ : unknown ,
88
128
Field [ 'children' ] ,
89
129
unknown
90
130
> extends infer Child
91
- ? Child | Child [ ] | null
131
+ ? Relationships extends unknown [ ]
132
+ ? HasFKeyToFRel < Field [ 'original' ] , Relationships > extends true
133
+ ? Child | null
134
+ : Child [ ]
135
+ : Child [ ]
92
136
: never
93
137
}
94
138
: Field extends { name : string ; original : string }
@@ -191,14 +235,14 @@ type ParseNode<Input extends string> = Input extends ''
191
235
? ParseEmbeddedResource < EatWhitespace < Remainder > >
192
236
: ParserError < 'Expected embedded resource after `!inner`' >
193
237
: EatWhitespace < Remainder > extends `!${infer Remainder } `
194
- ? ParseIdentifier < EatWhitespace < Remainder > > extends [ infer _Hint , `${infer Remainder } `]
238
+ ? ParseIdentifier < EatWhitespace < Remainder > > extends [ infer Hint , `${infer Remainder } `]
195
239
? EatWhitespace < Remainder > extends `!inner${infer Remainder } `
196
240
? ParseEmbeddedResource < EatWhitespace < Remainder > > extends [
197
241
infer Fields ,
198
242
`${infer Remainder } `
199
243
]
200
244
? // `field!hint!inner(nodes)`
201
- [ { name : Name ; original : Name ; children : Fields } , EatWhitespace < Remainder > ]
245
+ [ { name : Name ; original : Name ; hint : Hint ; children : Fields } , EatWhitespace < Remainder > ]
202
246
: ParseEmbeddedResource < EatWhitespace < Remainder > > extends ParserError < string >
203
247
? ParseEmbeddedResource < EatWhitespace < Remainder > >
204
248
: ParserError < 'Expected embedded resource after `!inner`' >
@@ -207,7 +251,7 @@ type ParseNode<Input extends string> = Input extends ''
207
251
`${infer Remainder } `
208
252
]
209
253
? // `field!hint(nodes)`
210
- [ { name : Name ; original : Name ; children : Fields } , EatWhitespace < Remainder > ]
254
+ [ { name : Name ; original : Name ; hint : Hint ; children : Fields } , EatWhitespace < Remainder > ]
211
255
: ParseEmbeddedResource < EatWhitespace < Remainder > > extends ParserError < string >
212
256
? ParseEmbeddedResource < EatWhitespace < Remainder > >
213
257
: ParserError < 'Expected embedded resource after `!hint`' >
@@ -225,14 +269,17 @@ type ParseNode<Input extends string> = Input extends ''
225
269
? ParseEmbeddedResource < EatWhitespace < Remainder > >
226
270
: ParserError < 'Expected embedded resource after `!inner`' >
227
271
: EatWhitespace < Remainder > extends `!${infer Remainder } `
228
- ? ParseIdentifier < EatWhitespace < Remainder > > extends [ infer _Hint , `${infer Remainder } `]
272
+ ? ParseIdentifier < EatWhitespace < Remainder > > extends [ infer Hint , `${infer Remainder } `]
229
273
? EatWhitespace < Remainder > extends `!inner${infer Remainder } `
230
274
? ParseEmbeddedResource < EatWhitespace < Remainder > > extends [
231
275
infer Fields ,
232
276
`${infer Remainder } `
233
277
]
234
278
? // `renamed_field:field!hint!inner(nodes)`
235
- [ { name : Name ; original : OriginalName ; children : Fields } , EatWhitespace < Remainder > ]
279
+ [
280
+ { name : Name ; original : OriginalName ; hint : Hint ; children : Fields } ,
281
+ EatWhitespace < Remainder >
282
+ ]
236
283
: ParseEmbeddedResource < EatWhitespace < Remainder > > extends ParserError < string >
237
284
? ParseEmbeddedResource < EatWhitespace < Remainder > >
238
285
: ParserError < 'Expected embedded resource after `!inner`' >
@@ -245,6 +292,7 @@ type ParseNode<Input extends string> = Input extends ''
245
292
{
246
293
name : Name
247
294
original : OriginalName
295
+ hint : Hint
248
296
children : Fields
249
297
} ,
250
298
EatWhitespace < Remainder >
@@ -363,12 +411,25 @@ type ParseQuery<Query extends string> = string extends Query
363
411
type GetResultHelper <
364
412
Schema extends GenericSchema ,
365
413
Row extends Record < string , unknown > ,
414
+ Relationships ,
366
415
Fields extends unknown [ ] ,
367
416
Acc
368
417
> = Fields extends [ infer R ]
369
- ? GetResultHelper < Schema , Row , [ ] , ConstructFieldDefinition < Schema , Row , R > & Acc >
418
+ ? GetResultHelper <
419
+ Schema ,
420
+ Row ,
421
+ Relationships ,
422
+ [ ] ,
423
+ ConstructFieldDefinition < Schema , Row , Relationships , R > & Acc
424
+ >
370
425
: Fields extends [ infer R , ...infer Rest ]
371
- ? GetResultHelper < Schema , Row , Rest , ConstructFieldDefinition < Schema , Row , R > & Acc >
426
+ ? GetResultHelper <
427
+ Schema ,
428
+ Row ,
429
+ Relationships ,
430
+ Rest ,
431
+ ConstructFieldDefinition < Schema , Row , Relationships , R > & Acc
432
+ >
372
433
: Prettify < Acc >
373
434
374
435
/**
@@ -380,7 +441,8 @@ type GetResultHelper<
380
441
export type GetResult <
381
442
Schema extends GenericSchema ,
382
443
Row extends Record < string , unknown > ,
444
+ Relationships ,
383
445
Query extends string
384
446
> = ParseQuery < Query > extends unknown [ ]
385
- ? GetResultHelper < Schema , Row , ParseQuery < Query > , unknown >
447
+ ? GetResultHelper < Schema , Row , Relationships , ParseQuery < Query > , unknown >
386
448
: ParseQuery < Query >
0 commit comments