@@ -796,15 +796,19 @@ type Union struct {
796796 PrivateDescription string `json:"description"`
797797 ResolveType ResolveTypeFn
798798
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
802803
803804 err error
804805}
806+
807+ type UnionTypesThunk func () []* Object
808+
805809type UnionConfig struct {
806- Name string `json:"name"`
807- Types [] * Object `json:"types"`
810+ Name string `json:"name"`
811+ Types interface {} `json:"types"`
808812 ResolveType ResolveTypeFn
809813 Description string `json:"description"`
810814}
@@ -822,48 +826,80 @@ func NewUnion(config UnionConfig) *Union {
822826 objectType .PrivateDescription = config .Description
823827 objectType .ResolveType = config .ResolveType
824828
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
830865 }
831- for _ , ttype := range config .Types {
832- if objectType .err = invariantf (
866+
867+ for _ , ttype := range unionTypes {
868+ if err := invariantf (
833869 ttype != nil ,
834870 `%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
837873 }
838874 if objectType .ResolveType == nil {
839- if objectType . err = invariantf (
875+ if err : = invariantf (
840876 ttype .IsTypeOf != nil ,
841877 `Union Type %v does not provide a "resolveType" function ` +
842878 `and possible Type %v does not provide a "isTypeOf" ` +
843879 `function. There is no way to resolve this possible type ` +
844880 `during execution.` , objectType , ttype ,
845- ); objectType . err != nil {
846- return objectType
881+ ); err != nil {
882+ return definedUnionTypes , err
847883 }
848884 }
885+ definedUnionTypes = append (definedUnionTypes , ttype )
849886 }
850- objectType .types = config .Types
851- objectType .typeConfig = config
852887
853- return objectType
854- }
855- func (ut * Union ) Types () []* Object {
856- return ut .types
888+ return definedUnionTypes , nil
857889}
890+
858891func (ut * Union ) String () string {
859892 return ut .PrivateName
860893}
894+
861895func (ut * Union ) Name () string {
862896 return ut .PrivateName
863897}
898+
864899func (ut * Union ) Description () string {
865900 return ut .PrivateDescription
866901}
902+
867903func (ut * Union ) Error () error {
868904 return ut .err
869905}
0 commit comments