@@ -24,6 +24,7 @@ import (
2424 "io/fs"
2525 "net/http"
2626 "os"
27+ "reflect"
2728 "runtime/debug"
2829 "sort"
2930 "strings"
@@ -109,6 +110,7 @@ func Generate(spec *openapi3.T, opts Configuration) (string, error) {
109110 globalState .importMapping = constructImportMapping (opts .ImportMapping )
110111
111112 filterOperationsByTag (spec , opts )
113+ fixExternalRefPropagation (spec )
112114 if ! opts .OutputOptions .SkipPrune {
113115 pruneUnusedComponents (spec )
114116 }
@@ -1160,3 +1162,58 @@ func GetParametersImports(params map[string]*openapi3.ParameterRef) (map[string]
11601162func SetGlobalStateSpec (spec * openapi3.T ) {
11611163 globalState .spec = spec
11621164}
1165+
1166+ func fixExternalRefPropagation (doc * openapi3.T ) {
1167+ visited := make (map [interface {}]struct {})
1168+ fixExternalRefPropagationCore (reflect .ValueOf (doc ), visited , "" )
1169+ }
1170+
1171+ func fixExternalRefPropagationCore (vObj reflect.Value , visited map [interface {}]struct {}, curUri string ) {
1172+ if ! vObj .IsValid () {
1173+ return
1174+ }
1175+
1176+ switch vObj .Kind () {
1177+ case reflect .Pointer :
1178+ if ! vObj .IsNil () && vObj .Elem ().Kind () == reflect .Struct && vObj .CanInterface () {
1179+ iObj := vObj .Interface ()
1180+ if _ , exist := visited [iObj ]; exist {
1181+ return
1182+ }
1183+ visited [iObj ] = struct {}{}
1184+ }
1185+ fallthrough
1186+ case reflect .Interface :
1187+ fixExternalRefPropagationCore (vObj .Elem (), visited , curUri )
1188+ case reflect .Map :
1189+ iter := vObj .MapRange ()
1190+ for iter .Next () {
1191+ fixExternalRefPropagationCore (iter .Value (), visited , curUri )
1192+ }
1193+ case reflect .Slice :
1194+ for i := 0 ; i < vObj .Len (); i ++ {
1195+ fixExternalRefPropagationCore (vObj .Index (i ), visited , curUri )
1196+ }
1197+ case reflect .Struct :
1198+ vRef := vObj .FieldByName ("Ref" )
1199+ vValue := vObj .FieldByName ("Value" )
1200+ if vRef .IsValid () && (vValue .IsValid () || vObj .Type () == reflect .TypeOf (openapi3.PathItem {})) {
1201+ ref := vRef .String ()
1202+ if ref != "" {
1203+ split := strings .SplitN (ref , "#" , 2 )
1204+ if len (split ) == 2 {
1205+ if split [0 ] != "" {
1206+ curUri = split [0 ]
1207+ } else {
1208+ vRef .SetString (curUri + "#" + split [1 ])
1209+ }
1210+ } else {
1211+ curUri = split [0 ]
1212+ }
1213+ }
1214+ }
1215+ for i := 0 ; i < vObj .NumField (); i ++ {
1216+ fixExternalRefPropagationCore (vObj .Field (i ), visited , curUri )
1217+ }
1218+ }
1219+ }
0 commit comments