@query-graph/core 1.1.0 → 1.1.2

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.
package/dsl.d.ts CHANGED
@@ -224,11 +224,15 @@ declare const projectionPathType: unique symbol
224
224
  declare const projectionScalarType: unique symbol
225
225
  declare const projectionNullabilityType: unique symbol
226
226
  declare const projectionDefaultType: unique symbol
227
+ declare const projectionObjectPathType: unique symbol
228
+ declare const projectionObjectNullabilityType: unique symbol
227
229
  declare const summaryFieldType: unique symbol
228
230
  declare const typedProjectionPathType: unique symbol
229
231
  declare const typedProjectionScalarType: unique symbol
230
232
  declare const typedProjectionNullabilityType: unique symbol
231
233
  declare const typedProjectionDefaultType: unique symbol
234
+ declare const typedProjectionObjectPathType: unique symbol
235
+ declare const typedProjectionObjectNullabilityType: unique symbol
232
236
 
233
237
  export interface ProjectionTypeMetadata<
234
238
  Path extends string = string,
@@ -242,6 +246,19 @@ export interface ProjectionTypeMetadata<
242
246
  readonly [typedProjectionDefaultType]: SelectedByDefault
243
247
  }
244
248
 
249
+ export interface ProjectionObjectTypeMetadata<
250
+ Path extends string = string,
251
+ Nullability extends NullabilityExpression = NullabilityExpression,
252
+ > {
253
+ readonly [typedProjectionObjectPathType]: Path
254
+ readonly [typedProjectionObjectNullabilityType]: Nullability
255
+ }
256
+
257
+ export type TypedProjectionObject<
258
+ Path extends string = string,
259
+ Nullability extends NullabilityExpression = NullabilityExpression,
260
+ > = ProjectionObjectDefinition<Path, Nullability> & ProjectionObjectTypeMetadata<Path, Nullability>
261
+
245
262
  export type TypedProjectionField<
246
263
  Path extends string = string,
247
264
  Type extends ScalarType = ScalarType,
@@ -282,6 +299,16 @@ export interface ProjectionFieldDefinition<
282
299
  selectedByDefault?: boolean
283
300
  }
284
301
 
302
+ export interface ProjectionObjectDefinition<
303
+ Path extends string = string,
304
+ Nullability extends NullabilityExpression = NullabilityExpression,
305
+ > {
306
+ path: string[]
307
+ readonly [projectionObjectPathType]?: Path
308
+ readonly [projectionObjectNullabilityType]?: Nullability
309
+ presence: Expression
310
+ }
311
+
285
312
  export interface DimensionDefinition<
286
313
  Path extends string = string,
287
314
  Type extends ScalarType = ScalarType,
@@ -314,15 +341,19 @@ export type SummaryFieldDefinition<
314
341
  export interface ProjectionDefinition<
315
342
  Path extends string = string,
316
343
  Field extends ProjectionFieldDefinition = ProjectionFieldDefinition<Path>,
344
+ Object extends ProjectionObjectDefinition = ProjectionObjectDefinition,
317
345
  > {
318
346
  fields: Field[]
347
+ objects: Object[]
319
348
  }
320
349
 
321
350
  export interface ProjectionDefinitionInput<
322
351
  Path extends string = string,
323
352
  Field extends ProjectionFieldDefinition = ProjectionFieldDefinition<Path>,
353
+ Object extends ProjectionObjectDefinition = ProjectionObjectDefinition,
324
354
  > {
325
355
  fields?: Field[]
356
+ objects?: Object[]
326
357
  }
327
358
 
328
359
  export interface OrderByDefinition {
@@ -345,7 +376,7 @@ export interface FirstBySelection {
345
376
  export type RelationSelection = FirstBySelection
346
377
 
347
378
  export interface GraphDefinitionInput {
348
- schemaVersion: 9
379
+ schemaVersion: 10
349
380
  name: string
350
381
  root: string
351
382
  sources: SourceDefinition[]
@@ -363,12 +394,13 @@ export interface GraphDefinition<
363
394
  ProjectionField extends ProjectionFieldDefinition = ProjectionFieldDefinition<ProjectionPath>,
364
395
  Relation extends RelationDefinition = RelationDefinition,
365
396
  Root extends string = string,
397
+ ProjectionObject extends ProjectionObjectDefinition = ProjectionObjectDefinition,
366
398
  > extends GraphDefinitionInput {
367
399
  root: Root
368
400
  parameters: Parameter[]
369
401
  relations: Relation[]
370
402
  constraints: ConstraintDefinition[]
371
- projection: ProjectionDefinition<ProjectionPath, ProjectionField>
403
+ projection: ProjectionDefinition<ProjectionPath, ProjectionField, ProjectionObject>
372
404
  orderings: OrderingDefinition<OrderingName>[]
373
405
  }
374
406
 
@@ -442,6 +474,9 @@ export type DefinitionOrderingName<Definition extends GraphDefinitionInput> =
442
474
  export type DefinitionProjectionField<Definition extends GraphDefinitionInput> = NonNullable<
443
475
  NonNullable<Definition['projection']>['fields']
444
476
  >[number]
477
+ export type DefinitionProjectionObject<Definition extends GraphDefinitionInput> = NonNullable<
478
+ NonNullable<Definition['projection']>['objects']
479
+ >[number]
445
480
 
446
481
  export type DefinitionRelation<Definition extends GraphDefinitionInput> = NonNullable<Definition['relations']>[number]
447
482
 
@@ -512,6 +547,278 @@ export interface RelationalQueryGraph<Definition extends GraphDefinitionInput =
512
547
  ): import('./index.js').CompiledSqlStatement
513
548
  }
514
549
 
550
+ export type BatchCardinality = RelationCardinality
551
+
552
+ export interface BatchRelationWire {
553
+ name: string
554
+ from: string
555
+ to: string
556
+ parameter: string
557
+ cardinality: BatchCardinality
558
+ parameters?: Record<string, unknown>
559
+ ordering?: string
560
+ }
561
+
562
+ type ListDefinitionParameter<Definition extends GraphDefinitionInput> =
563
+ DefinitionParameter<Definition> extends infer Parameter extends ParameterDefinition
564
+ ? Parameter extends { shape: 'list' }
565
+ ? Parameter
566
+ : never
567
+ : never
568
+
569
+ type ListParameterReference<Definition extends GraphDefinitionInput> =
570
+ | ListDefinitionParameter<Definition>
571
+ | ListDefinitionParameter<Definition>['name']
572
+
573
+ type ParameterReferenceName<Reference> = Reference extends { name: infer Name extends string }
574
+ ? Name
575
+ : Reference extends string
576
+ ? Reference
577
+ : never
578
+
579
+ type ResolveListParameter<Definition extends GraphDefinitionInput, Reference> = Extract<
580
+ ListDefinitionParameter<Definition>,
581
+ { name: ParameterReferenceName<Reference> }
582
+ >
583
+
584
+ type BatchStaticParameterCandidate<
585
+ Parameter extends ParameterDefinition,
586
+ KeyName extends string,
587
+ > = Parameter extends ParameterDefinition ? (Parameter['name'] extends KeyName ? never : Parameter) : never
588
+
589
+ type BatchStaticParameter<
590
+ Definition extends GraphDefinitionInput,
591
+ KeyName extends string,
592
+ > = BatchStaticParameterCandidate<DefinitionParameter<Definition>, KeyName>
593
+
594
+ type BatchStaticParameters<Definition extends GraphDefinitionInput, KeyName extends string> = {
595
+ [Parameter in RequiredParameter<
596
+ BatchStaticParameter<Definition, KeyName>
597
+ > as Parameter['name']]-?: ParameterValue<Parameter>
598
+ } & {
599
+ [Parameter in OptionalParameter<
600
+ BatchStaticParameter<Definition, KeyName>
601
+ > as Parameter['name']]?: ParameterValue<Parameter>
602
+ }
603
+
604
+ type BatchStaticParameterInput<Definition extends GraphDefinitionInput, KeyName extends string> = [
605
+ BatchStaticParameter<Definition, KeyName>,
606
+ ] extends [never]
607
+ ? { parameters?: never }
608
+ : [RequiredParameter<BatchStaticParameter<Definition, KeyName>>] extends [never]
609
+ ? { parameters?: BatchStaticParameters<Definition, KeyName> }
610
+ : { parameters: BatchStaticParameters<Definition, KeyName> }
611
+
612
+ declare const batchQueryType: unique symbol
613
+
614
+ export interface BatchQuery<
615
+ Child extends RelationalQueryGraph = RelationalQueryGraph,
616
+ KeyPath extends string = string,
617
+ KeyParameter extends ParameterDefinition & { shape: 'list' } = ListParameterRef,
618
+ > {
619
+ readonly graph: Child
620
+ readonly key: {
621
+ readonly path: KeyPath
622
+ readonly parameter: KeyParameter['name']
623
+ }
624
+ readonly [batchQueryType]?: KeyParameter
625
+ }
626
+
627
+ export type BatchQueryConfiguration<
628
+ Child extends RelationalQueryGraph,
629
+ KeyPath extends DefinitionProjectionPath<DefinitionOf<Child>>,
630
+ ParameterReference extends ListParameterReference<DefinitionOf<Child>>,
631
+ > = {
632
+ graph: Child
633
+ key: {
634
+ path: KeyPath
635
+ parameter: ParameterReference
636
+ }
637
+ }
638
+
639
+ type CompatibleBatchQueryConfiguration<
640
+ Child extends RelationalQueryGraph,
641
+ KeyPath extends DefinitionProjectionPath<DefinitionOf<Child>>,
642
+ KeyParameter extends ParameterDefinition & { shape: 'list' },
643
+ > =
644
+ EqualScalarType<ProjectionScalarTypeAtPath<DefinitionOf<Child>, KeyPath>, KeyParameter['scalarType']> extends true
645
+ ? unknown
646
+ : never
647
+
648
+ export function batchQuery<
649
+ const Child extends RelationalQueryGraph,
650
+ const KeyPath extends DefinitionProjectionPath<DefinitionOf<Child>>,
651
+ const ParameterReference extends ListParameterReference<DefinitionOf<Child>>,
652
+ >(
653
+ configuration: BatchQueryConfiguration<Child, KeyPath, ParameterReference> &
654
+ CompatibleBatchQueryConfiguration<
655
+ Child,
656
+ KeyPath,
657
+ ResolveListParameter<DefinitionOf<Child>, NoInfer<ParameterReference>>
658
+ >,
659
+ ): BatchQuery<Child, KeyPath, ResolveListParameter<DefinitionOf<Child>, ParameterReference>>
660
+
661
+ type BatchQueryGraph<Query extends BatchQuery> =
662
+ Query extends BatchQuery<infer Child, infer _KeyPath, infer _KeyParameter> ? Child : never
663
+
664
+ type BatchQueryKeyPath<Query extends BatchQuery> =
665
+ Query extends BatchQuery<infer _Child, infer KeyPath, infer _KeyParameter> ? KeyPath : never
666
+
667
+ type BatchQueryKeyParameter<Query extends BatchQuery> =
668
+ Query extends BatchQuery<infer _Child, infer _KeyPath, infer KeyParameter> ? KeyParameter : never
669
+
670
+ declare const batchRelationType: unique symbol
671
+
672
+ export interface BatchRelation<
673
+ Name extends string = string,
674
+ Query extends BatchQuery = BatchQuery,
675
+ From extends string = string,
676
+ Cardinality extends BatchCardinality = BatchCardinality,
677
+ > {
678
+ readonly name: Name
679
+ readonly from: From
680
+ readonly query: Query
681
+ readonly cardinality: Cardinality
682
+ readonly parameters: BatchStaticParameters<
683
+ DefinitionOf<BatchQueryGraph<Query>>,
684
+ BatchQueryKeyParameter<Query>['name']
685
+ >
686
+ readonly ordering?: DefinitionOrderingName<DefinitionOf<BatchQueryGraph<Query>>>
687
+ readonly [batchRelationType]?: Query
688
+ }
689
+
690
+ export type BatchRelationConfiguration<
691
+ Name extends string,
692
+ Query extends BatchQuery,
693
+ From extends string,
694
+ Cardinality extends BatchCardinality,
695
+ > = {
696
+ name: Name
697
+ from: From
698
+ query: Query
699
+ cardinality: Cardinality
700
+ ordering?: DefinitionOrderingName<DefinitionOf<BatchQueryGraph<Query>>>
701
+ } & BatchStaticParameterInput<DefinitionOf<BatchQueryGraph<Query>>, BatchQueryKeyParameter<Query>['name']>
702
+
703
+ export function batchRelation<
704
+ const Name extends string,
705
+ const Query extends BatchQuery,
706
+ const From extends string,
707
+ const Cardinality extends BatchCardinality,
708
+ >(
709
+ configuration: BatchRelationConfiguration<Name, Query, From, Cardinality>,
710
+ ): BatchRelation<Name, Query, From, Cardinality>
711
+
712
+ type ProjectionScalarTypeAtPath<Definition extends GraphDefinitionInput, Path extends string> =
713
+ ProjectionFieldByPath<DefinitionProjectionField<Definition>, Path> extends infer Field
714
+ ? Field extends ProjectionTypeMetadata<infer _Path, infer Type, infer _Nullability, infer _SelectedByDefault>
715
+ ? Type
716
+ : Field extends ProjectionFieldDefinition<infer _Path, infer Type>
717
+ ? Type
718
+ : never
719
+ : never
720
+
721
+ type EqualScalarType<Left, Right> = [Left] extends [Right] ? ([Right] extends [Left] ? true : false) : false
722
+
723
+ type CompatibleBatchRelation<Root extends RelationalQueryGraph, Relation extends BatchRelation> =
724
+ Relation extends BatchRelation<infer Name, infer Query, infer From, infer _Cardinality>
725
+ ? From extends DefinitionProjectionPath<DefinitionOf<Root>>
726
+ ? Extract<DefinitionProjectionPath<DefinitionOf<Root>>, Name | `${Name}.${string}`> extends never
727
+ ? EqualScalarType<
728
+ ProjectionScalarTypeAtPath<DefinitionOf<Root>, From>,
729
+ ProjectionScalarTypeAtPath<DefinitionOf<BatchQueryGraph<Query>>, BatchQueryKeyPath<Query>>
730
+ > extends true
731
+ ? EqualScalarType<
732
+ ProjectionScalarTypeAtPath<DefinitionOf<BatchQueryGraph<Query>>, BatchQueryKeyPath<Query>>,
733
+ BatchQueryKeyParameter<Query>['scalarType']
734
+ > extends true
735
+ ? Relation
736
+ : never
737
+ : never
738
+ : never
739
+ : never
740
+ : never
741
+
742
+ type CompatibleBatchRelations<Root extends RelationalQueryGraph, Relations extends readonly BatchRelation[]> = {
743
+ readonly [Index in keyof Relations]: Relations[Index] extends BatchRelation
744
+ ? CompatibleBatchRelation<Root, Relations[Index]>
745
+ : never
746
+ }
747
+
748
+ type RelationName<Relations extends readonly BatchRelation[]> = Relations[number]['name']
749
+ type ChildPathsForRelation<Relation extends BatchRelation> = Relation extends BatchRelation
750
+ ? `${Relation['name']}.${DefinitionProjectionPath<DefinitionOf<BatchQueryGraph<Relation['query']>>>}`
751
+ : never
752
+ type ChildPaths<Relations extends readonly BatchRelation[]> = ChildPathsForRelation<Relations[number]>
753
+
754
+ export type ComposedSelection<Root extends RelationalQueryGraph, Relations extends readonly BatchRelation[]> =
755
+ | DefinitionProjectionPath<DefinitionOf<Root>>
756
+ | ChildPaths<Relations>
757
+
758
+ export interface BatchPlanMetadata<Relation extends BatchRelation = BatchRelation> {
759
+ name: Relation['name']
760
+ parentKey: Relation['from']
761
+ childKey: BatchQueryKeyPath<Relation['query']>
762
+ keyParameter: BatchQueryKeyParameter<Relation['query']>['name']
763
+ parameters: Readonly<Relation['parameters']>
764
+ cardinality: Relation['cardinality']
765
+ parentKeyInjected: boolean
766
+ childKeyInjected: boolean
767
+ }
768
+
769
+ type BatchRelationNamed<Relation extends BatchRelation, Name extends string> = Relation extends BatchRelation
770
+ ? Relation['name'] extends Name
771
+ ? Relation
772
+ : never
773
+ : never
774
+
775
+ type BatchRelationByName<Relations extends readonly BatchRelation[], Name extends string> = BatchRelationNamed<
776
+ Relations[number],
777
+ Name
778
+ >
779
+
780
+ type BatchKeyValue<Relation extends BatchRelation> = ScalarParameterValue<
781
+ BatchQueryKeyParameter<Relation['query']>['scalarType']
782
+ >
783
+
784
+ export interface CompiledQueryPlan<Relations extends readonly BatchRelation[] = readonly BatchRelation[]> {
785
+ readonly root: import('./index.js').CompiledSqlStatement
786
+ readonly batches: readonly BatchPlanMetadata<Relations[number]>[]
787
+ compileBatch<const Name extends RelationName<Relations>>(
788
+ name: Name,
789
+ keys: readonly BatchKeyValue<BatchRelationByName<Relations, Name>>[],
790
+ ): import('./index.js').CompiledSqlStatement
791
+ }
792
+
793
+ export type ComposedQueryOperation<
794
+ Root extends RelationalQueryGraph,
795
+ Relations extends readonly BatchRelation[],
796
+ > = QueryOperationBase<ComposedSelection<Root, Relations>, DefinitionOrderingName<DefinitionOf<Root>>> &
797
+ OperationParameterInput<DefinitionOf<Root>>
798
+
799
+ export interface ComposedQueryGraph<
800
+ Root extends RelationalQueryGraph = RelationalQueryGraph,
801
+ Relations extends readonly BatchRelation[] = readonly BatchRelation[],
802
+ > {
803
+ readonly name: string
804
+ compileOraclePlan(
805
+ operation: ComposedQueryOperation<Root, Relations>,
806
+ options?: OracleCompileOptions,
807
+ ): CompiledQueryPlan<Relations>
808
+ compileSqlServerPlan(
809
+ operation: ComposedQueryOperation<Root, Relations>,
810
+ options?: SqlServerCompileOptions,
811
+ ): CompiledQueryPlan<Relations>
812
+ }
813
+
814
+ export function composeGraph<
815
+ const Root extends RelationalQueryGraph,
816
+ const Relations extends readonly BatchRelation[],
817
+ >(configuration: {
818
+ root: Root
819
+ relations: Relations & CompatibleBatchRelations<Root, Relations>
820
+ }): ComposedQueryGraph<Root, Relations>
821
+
515
822
  export interface ScalarOutputTypeMap {
516
823
  boolean: unknown
517
824
  int32: unknown
@@ -659,6 +966,23 @@ type ProjectionFieldPath<Field> =
659
966
  ? Path
660
967
  : never
661
968
 
969
+ type ProjectionObjectPath<Object> =
970
+ Object extends ProjectionObjectTypeMetadata<infer Path, infer _Nullability>
971
+ ? Path
972
+ : Object extends ProjectionObjectDefinition<infer Path>
973
+ ? Path
974
+ : never
975
+
976
+ type ProjectionObjectNullability<Object> =
977
+ Object extends ProjectionObjectTypeMetadata<infer _Path, infer Nullability>
978
+ ? Nullability
979
+ : Object extends ProjectionObjectDefinition<infer _Path, infer Nullability>
980
+ ? Nullability
981
+ : boolean
982
+
983
+ type ProjectionObjectIsNullable<Definition extends GraphDefinitionInput, Object> =
984
+ true extends EvaluateNullability<Definition, ProjectionObjectNullability<Object>> ? true : false
985
+
662
986
  type ProjectionFieldValue<Definition extends GraphDefinitionInput, Field, TypeMap extends ScalarOutputTypeMap> =
663
987
  Field extends ProjectionTypeMetadata<infer _Path, infer Type, infer Nullability, infer _SelectedByDefault>
664
988
  ? true extends EvaluateNullability<Definition, Nullability>
@@ -705,6 +1029,19 @@ type SelectedProjectionField<Definition extends GraphDefinitionInput, Operation>
705
1029
  ? ProjectionFieldByPath<DefinitionProjectionField<Definition>, Path>
706
1030
  : DefaultProjectionField<DefinitionProjectionField<Definition>>
707
1031
 
1032
+ type ProjectionObjectForField<Object, Field> = Object extends ProjectionObjectDefinition
1033
+ ? Field extends ProjectionFieldDefinition
1034
+ ? ProjectionFieldPath<Field> extends `${ProjectionObjectPath<Object>}.${string}`
1035
+ ? Object
1036
+ : never
1037
+ : never
1038
+ : never
1039
+
1040
+ type SelectedProjectionObject<Definition extends GraphDefinitionInput, Field> = ProjectionObjectForField<
1041
+ DefinitionProjectionObject<Definition>,
1042
+ Field
1043
+ >
1044
+
708
1045
  type ProjectionEntry<
709
1046
  Definition extends GraphDefinitionInput,
710
1047
  Field,
@@ -716,6 +1053,13 @@ type ProjectionEntry<
716
1053
  }
717
1054
  : never
718
1055
 
1056
+ type ProjectionObjectEntry<Definition extends GraphDefinitionInput, Object> = Object extends ProjectionObjectDefinition
1057
+ ? {
1058
+ path: ProjectionObjectPath<Object>
1059
+ nullable: ProjectionObjectIsNullable<Definition, Object>
1060
+ }
1061
+ : never
1062
+
719
1063
  type ProjectionEntryHead<Entry> = Entry extends { path: infer Path extends string }
720
1064
  ? Path extends `${infer Head}.${string}`
721
1065
  ? Head
@@ -740,27 +1084,109 @@ type NestedProjectionEntry<Entry, Key extends string> = Entry extends {
740
1084
  : never
741
1085
  : never
742
1086
 
743
- type ProjectionValueAtKey<Entry, Key extends string> = [NestedProjectionEntry<Entry, Key>] extends [never]
1087
+ type DirectProjectionObjectNullable<ObjectEntry, Key extends string> = ObjectEntry extends {
1088
+ path: infer Path extends string
1089
+ nullable: infer Nullable extends boolean
1090
+ }
1091
+ ? Path extends Key
1092
+ ? Nullable
1093
+ : never
1094
+ : never
1095
+
1096
+ type NestedProjectionObjectEntry<ObjectEntry, Key extends string> = ObjectEntry extends {
1097
+ path: infer Path extends string
1098
+ nullable: infer Nullable extends boolean
1099
+ }
1100
+ ? Path extends `${Key}.${infer Rest}`
1101
+ ? { path: Rest; nullable: Nullable }
1102
+ : never
1103
+ : never
1104
+
1105
+ type ApplyProjectionObjectNullability<Value, ObjectEntry, Key extends string> =
1106
+ true extends DirectProjectionObjectNullable<ObjectEntry, Key> ? Value | null : Value
1107
+
1108
+ type ProjectionValueAtKeyWithoutObject<Entry, ObjectEntry, Key extends string> = [
1109
+ NestedProjectionEntry<Entry, Key>,
1110
+ ] extends [never]
744
1111
  ? DirectProjectionEntryValue<Entry, Key>
745
1112
  : [DirectProjectionEntryValue<Entry, Key>] extends [never]
746
- ? BuildProjectionResult<NestedProjectionEntry<Entry, Key>>
747
- : DirectProjectionEntryValue<Entry, Key> | BuildProjectionResult<NestedProjectionEntry<Entry, Key>>
1113
+ ? BuildProjectionResult<NestedProjectionEntry<Entry, Key>, NestedProjectionObjectEntry<ObjectEntry, Key>>
1114
+ :
1115
+ | DirectProjectionEntryValue<Entry, Key>
1116
+ | BuildProjectionResult<NestedProjectionEntry<Entry, Key>, NestedProjectionObjectEntry<ObjectEntry, Key>>
1117
+
1118
+ type ProjectionValueAtKey<Entry, ObjectEntry, Key extends string> = ApplyProjectionObjectNullability<
1119
+ ProjectionValueAtKeyWithoutObject<Entry, ObjectEntry, Key>,
1120
+ ObjectEntry,
1121
+ Key
1122
+ >
748
1123
 
749
- type BuildProjectionResult<Entry> = [Entry] extends [never]
1124
+ type BuildProjectionResult<Entry, ObjectEntry = never> = [Entry] extends [never]
750
1125
  ? Record<never, never>
751
1126
  : {
752
- [Key in ProjectionEntryHead<Entry>]: ProjectionValueAtKey<Entry, Key>
1127
+ [Key in ProjectionEntryHead<Entry>]: ProjectionValueAtKey<Entry, ObjectEntry, Key>
753
1128
  }
754
1129
 
755
1130
  export type ResultOf<
756
- Subject extends GraphDefinitionInput | QueryGraph | RelationalQueryGraph,
1131
+ Subject extends GraphDefinitionInput | QueryGraph | RelationalQueryGraph | ComposedQueryGraph,
757
1132
  Operation = undefined,
758
1133
  TypeMap extends ScalarOutputTypeMap = DefaultScalarOutputTypeMap,
759
1134
  > =
760
- DefinitionOf<Subject> extends infer Definition extends GraphDefinitionInput
761
- ? BuildProjectionResult<ProjectionEntry<Definition, SelectedProjectionField<Definition, Operation>, TypeMap>>
1135
+ Subject extends ComposedQueryGraph<infer Root, infer Relations>
1136
+ ? ComposedResult<Root, Relations, Operation, TypeMap>
1137
+ : DefinitionOf<
1138
+ Extract<Subject, GraphDefinitionInput | QueryGraph | RelationalQueryGraph>
1139
+ > extends infer Definition extends GraphDefinitionInput
1140
+ ? SelectedProjectionField<Definition, Operation> extends infer Field
1141
+ ? BuildProjectionResult<
1142
+ ProjectionEntry<Definition, Field, TypeMap>,
1143
+ ProjectionObjectEntry<Definition, SelectedProjectionObject<Definition, Field>>
1144
+ >
1145
+ : never
1146
+ : never
1147
+
1148
+ type SelectedPaths<Operation> = Operation extends { select: readonly (infer Path extends string)[] } ? Path : never
1149
+
1150
+ type RootOperation<Operation, Relations extends readonly BatchRelation[]> = Operation extends {
1151
+ select: readonly string[]
1152
+ }
1153
+ ? { select: readonly Exclude<SelectedPaths<Operation>, ChildPaths<Relations>>[] }
1154
+ : undefined
1155
+
1156
+ type SelectedChildPath<Operation, Name extends string> =
1157
+ Extract<SelectedPaths<Operation>, `${Name}.${string}`> extends `${Name}.${infer Path}` ? Path : never
1158
+
1159
+ type ChildOperation<Operation, Name extends string> = {
1160
+ select: readonly SelectedChildPath<Operation, Name>[]
1161
+ }
1162
+
1163
+ type SelectedRelationCandidate<Relation extends BatchRelation, Operation> = Relation extends BatchRelation
1164
+ ? Extract<SelectedPaths<Operation>, `${Relation['name']}.${string}`> extends never
1165
+ ? never
1166
+ : Relation
1167
+ : never
1168
+
1169
+ type SelectedRelation<Relations extends readonly BatchRelation[], Operation> = SelectedRelationCandidate<
1170
+ Relations[number],
1171
+ Operation
1172
+ >
1173
+
1174
+ type BatchResult<Relation extends BatchRelation, Operation, TypeMap extends ScalarOutputTypeMap> =
1175
+ ResultOf<BatchQueryGraph<Relation['query']>, ChildOperation<Operation, Relation['name']>, TypeMap> extends infer Child
1176
+ ? Relation['cardinality'] extends 'many'
1177
+ ? Child[]
1178
+ : Child | null
762
1179
  : never
763
1180
 
1181
+ type ComposedResult<
1182
+ Root extends RelationalQueryGraph,
1183
+ Relations extends readonly BatchRelation[],
1184
+ Operation,
1185
+ TypeMap extends ScalarOutputTypeMap,
1186
+ > = ResultOf<Root, RootOperation<Operation, Relations>, TypeMap> & {
1187
+ [Relation in SelectedRelation<Relations, Operation> as Relation['name']]: BatchResult<Relation, Operation, TypeMap>
1188
+ }
1189
+
764
1190
  export type SqlServerVersion = '2008' | '2012' | '2016' | '2019' | '2022'
765
1191
  export type OracleVersion = '11g' | '12c' | '19c' | '21c' | '23ai'
766
1192
 
@@ -772,7 +1198,7 @@ export interface OracleCompileOptions {
772
1198
  version?: OracleVersion
773
1199
  }
774
1200
 
775
- export type QueryGraphErrorPhase = 'definition' | 'mapping' | 'operation' | 'sql'
1201
+ export type QueryGraphErrorPhase = 'definition' | 'mapping' | 'composition' | 'operation' | 'sql'
776
1202
 
777
1203
  export interface QueryGraphDiagnostic {
778
1204
  code: string
@@ -1134,6 +1560,14 @@ export interface ProjectionConfiguration<
1134
1560
  default?: SelectedByDefault
1135
1561
  }
1136
1562
 
1563
+ export interface ProjectionObjectConfiguration<
1564
+ Path extends string | readonly string[] = string | readonly string[],
1565
+ Value extends ExpressionInput = ExpressionInput,
1566
+ > {
1567
+ path: Path
1568
+ presence: Value
1569
+ }
1570
+
1137
1571
  type ConfigurationPath<Path extends string | readonly string[]> = Path extends string
1138
1572
  ? Path
1139
1573
  : Path extends readonly string[]
@@ -1153,6 +1587,10 @@ export function project<
1153
1587
  SelectedByDefault
1154
1588
  >
1155
1589
 
1590
+ export function projectObject<const Path extends string | readonly string[], const Value extends ExpressionInput>(
1591
+ configuration: ProjectionObjectConfiguration<Path, Value>,
1592
+ ): TypedProjectionObject<ConfigurationPath<Path>, InputNullability<Value>>
1593
+
1156
1594
  export function dimension<
1157
1595
  const Path extends string | readonly string[],
1158
1596
  const Value extends ExpressionInput,
@@ -1206,6 +1644,7 @@ export interface GraphModuleConfiguration {
1206
1644
  relations?: readonly RelationDefinition[]
1207
1645
  constraints?: readonly ConstraintDefinition[]
1208
1646
  projection?: readonly ProjectionFieldDefinition[]
1647
+ objects?: readonly ProjectionObjectDefinition[]
1209
1648
  orderings?: readonly OrderingDefinition[]
1210
1649
  }
1211
1650
 
@@ -1270,6 +1709,18 @@ type ModuleRelation<Module> =
1270
1709
  ? Relation
1271
1710
  : never
1272
1711
 
1712
+ type ModuleProjectionObject<Module> =
1713
+ Module extends GraphModule<
1714
+ infer _Parameter,
1715
+ infer _ProjectionPath,
1716
+ infer _OrderingName,
1717
+ infer _ProjectionField,
1718
+ infer _Relation,
1719
+ infer ProjectionObject
1720
+ >
1721
+ ? ProjectionObject
1722
+ : never
1723
+
1273
1724
  type ProjectionPathOf<Field> = Field extends ProjectionFieldDefinition<infer Path> ? Path : never
1274
1725
 
1275
1726
  type OrderingNameOf<Ordering> = Ordering extends OrderingDefinition<infer Name> ? Name : never
@@ -1290,6 +1741,10 @@ type ConfigurationProjectionField<Configuration> =
1290
1741
  | Extract<ConfigurationElement<Configuration, 'measures'>, ProjectionFieldDefinition>
1291
1742
  | ModuleProjectionField<ConfigurationElement<Configuration, 'modules'>>
1292
1743
 
1744
+ type ConfigurationProjectionObject<Configuration> =
1745
+ | Extract<ConfigurationElement<Configuration, 'objects'>, ProjectionObjectDefinition>
1746
+ | ModuleProjectionObject<ConfigurationElement<Configuration, 'modules'>>
1747
+
1293
1748
  type ConfigurationOrderingName<Configuration> =
1294
1749
  | OrderingNameOf<ConfigurationElement<Configuration, 'orderings'>>
1295
1750
  | ModuleOrderingName<ConfigurationElement<Configuration, 'modules'>>
@@ -1310,6 +1765,7 @@ export interface GraphModule<
1310
1765
  OrderingName extends string = string,
1311
1766
  ProjectionField extends ProjectionFieldDefinition = ProjectionFieldDefinition<ProjectionPath>,
1312
1767
  Relation extends RelationDefinition = RelationDefinition,
1768
+ ProjectionObject extends ProjectionObjectDefinition = ProjectionObjectDefinition,
1313
1769
  > {
1314
1770
  readonly name: string
1315
1771
  readonly sources: readonly SourceRef[]
@@ -1317,6 +1773,7 @@ export interface GraphModule<
1317
1773
  readonly relations: readonly Relation[]
1318
1774
  readonly constraints: readonly ConstraintDefinition[]
1319
1775
  readonly projection: readonly ProjectionField[]
1776
+ readonly objects: readonly ProjectionObject[]
1320
1777
  readonly orderings: readonly OrderingDefinition<OrderingName>[]
1321
1778
  }
1322
1779
 
@@ -1327,7 +1784,8 @@ export function defineGraphModule<const Configuration extends GraphModuleConfigu
1327
1784
  ConfigurationProjectionPath<Configuration>,
1328
1785
  ConfigurationOrderingName<Configuration>,
1329
1786
  ConfigurationProjectionField<Configuration>,
1330
- ConfigurationRelation<Configuration>
1787
+ ConfigurationRelation<Configuration>,
1788
+ ConfigurationProjectionObject<Configuration>
1331
1789
  >
1332
1790
 
1333
1791
  export interface GraphConfiguration {
@@ -1339,6 +1797,7 @@ export interface GraphConfiguration {
1339
1797
  relations?: readonly RelationDefinition[]
1340
1798
  constraints?: readonly ConstraintDefinition[]
1341
1799
  projection?: readonly ProjectionFieldDefinition[]
1800
+ objects?: readonly ProjectionObjectDefinition[]
1342
1801
  orderings?: readonly OrderingDefinition[]
1343
1802
  }
1344
1803
 
@@ -1350,7 +1809,8 @@ export function defineGraph<const Configuration extends GraphConfiguration>(
1350
1809
  ConfigurationOrderingName<Configuration>,
1351
1810
  ConfigurationProjectionField<Configuration>,
1352
1811
  ConfigurationRelation<Configuration>,
1353
- ConfigurationRoot<Configuration>
1812
+ ConfigurationRoot<Configuration>,
1813
+ ConfigurationProjectionObject<Configuration>
1354
1814
  >
1355
1815
 
1356
1816
  export interface SummaryGraphConfiguration {
@@ -1374,5 +1834,6 @@ export function defineSummaryGraph<const Configuration extends SummaryGraphConfi
1374
1834
  ConfigurationOrderingName<Configuration>,
1375
1835
  ConfigurationProjectionField<Configuration>,
1376
1836
  ConfigurationRelation<Configuration>,
1377
- ConfigurationRoot<Configuration>
1837
+ ConfigurationRoot<Configuration>,
1838
+ never
1378
1839
  >