@@ -796,15 +796,19 @@ type Union struct {
796
796
PrivateDescription string `json:"description"`
797
797
ResolveType ResolveTypeFn
798
798
799
- typeConfig UnionConfig
800
- types []* Object
801
- possibleTypes map [string ]bool
799
+ typeConfig UnionConfig
800
+ initalizedTypes bool
801
+ types []* Object
802
+ possibleTypes map [string ]bool
802
803
803
804
err error
804
805
}
806
+
807
+ type UnionTypesThunk func () []* Object
808
+
805
809
type UnionConfig struct {
806
- Name string `json:"name"`
807
- Types [] * Object `json:"types"`
810
+ Name string `json:"name"`
811
+ Types interface {} `json:"types"`
808
812
ResolveType ResolveTypeFn
809
813
Description string `json:"description"`
810
814
}
@@ -822,48 +826,80 @@ func NewUnion(config UnionConfig) *Union {
822
826
objectType .PrivateDescription = config .Description
823
827
objectType .ResolveType = config .ResolveType
824
828
825
- if objectType .err = invariantf (
826
- len (config .Types ) > 0 ,
827
- `Must provide Array of types for Union %v.` , config .Name ,
828
- ); objectType .err != nil {
829
- return objectType
829
+ objectType .typeConfig = config
830
+
831
+ return objectType
832
+ }
833
+
834
+ func (ut * Union ) Types () []* Object {
835
+ if ut .initalizedTypes {
836
+ return ut .types
837
+ }
838
+
839
+ var unionTypes []* Object
840
+ switch utype := ut .typeConfig .Types .(type ) {
841
+ case UnionTypesThunk :
842
+ unionTypes = utype ()
843
+ case []* Object :
844
+ unionTypes = utype
845
+ case nil :
846
+ default :
847
+ ut .err = fmt .Errorf ("Unknown Union.Types type: %T" , ut .typeConfig .Types )
848
+ ut .initalizedTypes = true
849
+ return nil
850
+ }
851
+
852
+ ut .types , ut .err = defineUnionTypes (ut , unionTypes )
853
+ ut .initalizedTypes = true
854
+ return ut .types
855
+ }
856
+
857
+ func defineUnionTypes (objectType * Union , unionTypes []* Object ) ([]* Object , error ) {
858
+ definedUnionTypes := []* Object {}
859
+
860
+ if err := invariantf (
861
+ len (unionTypes ) > 0 ,
862
+ `Must provide Array of types for Union %v.` , objectType .Name (),
863
+ ); err != nil {
864
+ return definedUnionTypes , err
830
865
}
831
- for _ , ttype := range config .Types {
832
- if objectType .err = invariantf (
866
+
867
+ for _ , ttype := range unionTypes {
868
+ if err := invariantf (
833
869
ttype != nil ,
834
870
`%v may only contain Object types, it cannot contain: %v.` , objectType , ttype ,
835
- ); objectType . err != nil {
836
- return objectType
871
+ ); err != nil {
872
+ return definedUnionTypes , err
837
873
}
838
874
if objectType .ResolveType == nil {
839
- if objectType . err = invariantf (
875
+ if err : = invariantf (
840
876
ttype .IsTypeOf != nil ,
841
877
`Union Type %v does not provide a "resolveType" function ` +
842
878
`and possible Type %v does not provide a "isTypeOf" ` +
843
879
`function. There is no way to resolve this possible type ` +
844
880
`during execution.` , objectType , ttype ,
845
- ); objectType . err != nil {
846
- return objectType
881
+ ); err != nil {
882
+ return definedUnionTypes , err
847
883
}
848
884
}
885
+ definedUnionTypes = append (definedUnionTypes , ttype )
849
886
}
850
- objectType .types = config .Types
851
- objectType .typeConfig = config
852
887
853
- return objectType
854
- }
855
- func (ut * Union ) Types () []* Object {
856
- return ut .types
888
+ return definedUnionTypes , nil
857
889
}
890
+
858
891
func (ut * Union ) String () string {
859
892
return ut .PrivateName
860
893
}
894
+
861
895
func (ut * Union ) Name () string {
862
896
return ut .PrivateName
863
897
}
898
+
864
899
func (ut * Union ) Description () string {
865
900
return ut .PrivateDescription
866
901
}
902
+
867
903
func (ut * Union ) Error () error {
868
904
return ut .err
869
905
}
0 commit comments