@@ -53,14 +53,12 @@ func MergeOpenAPISpecs(specs ...*openapi3.T) (*openapi3.T, error) {
5353 if spec .Paths != nil {
5454 for path , pathItem := range spec .Paths .Map () {
5555 if existingPathItem , exists := merged .Paths .Map ()[path ]; exists {
56- mergedPathItem , err := mergePathItems (existingPathItem , pathItem )
56+ err := mergePathItems (existingPathItem , pathItem )
5757 if err != nil {
5858 return nil , fmt .Errorf ("error merging path %s from spec %d: %v" , path , i , err )
5959 }
6060
61- merged .Paths .Set (path , mergedPathItem )
6261 } else {
63-
6462 merged .Paths .Set (path , pathItem )
6563 }
6664 }
@@ -89,89 +87,49 @@ func MergeOpenAPISpecs(specs ...*openapi3.T) (*openapi3.T, error) {
8987 return merged , nil
9088}
9189
92- // mergePathItems merges two path items, combining their operations
93- func mergePathItems (existing , new * openapi3.PathItem ) (* openapi3.PathItem , error ) {
94- merged := & openapi3.PathItem {
95- Ref : existing .Ref ,
96- Summary : existing .Summary ,
97- Description : existing .Description ,
98- Servers : existing .Servers ,
99- Parameters : existing .Parameters ,
100- }
101-
102- // Copy existing operations
103- if existing .Get != nil {
104- merged .Get = existing .Get
105- }
106- if existing .Put != nil {
107- merged .Put = existing .Put
108- }
109- if existing .Post != nil {
110- merged .Post = existing .Post
111- }
112- if existing .Delete != nil {
113- merged .Delete = existing .Delete
114- }
115- if existing .Options != nil {
116- merged .Options = existing .Options
117- }
118- if existing .Head != nil {
119- merged .Head = existing .Head
120- }
121- if existing .Patch != nil {
122- merged .Patch = existing .Patch
123- }
124- if existing .Trace != nil {
125- merged .Trace = existing .Trace
126- }
127-
128- // Add new operations (overwrite existing operations with new ones)
90+ func mergePathItems (existing , new * openapi3.PathItem ) error {
91+ // TODO: error and log warn when new one overrides existing one
12992 if new .Get != nil {
130- merged .Get = new .Get
93+ existing .Get = new .Get
13194 }
13295 if new .Put != nil {
133- merged .Put = new .Put
96+ existing .Put = new .Put
13497 }
13598 if new .Post != nil {
136- merged .Post = new .Post
99+ existing .Post = new .Post
137100 }
138101 if new .Delete != nil {
139- merged .Delete = new .Delete
102+ existing .Delete = new .Delete
140103 }
141104 if new .Options != nil {
142- merged .Options = new .Options
105+ existing .Options = new .Options
143106 }
144107 if new .Head != nil {
145- merged .Head = new .Head
108+ existing .Head = new .Head
146109 }
147110 if new .Patch != nil {
148- merged .Patch = new .Patch
111+ existing .Patch = new .Patch
149112 }
150113 if new .Trace != nil {
151- merged .Trace = new .Trace
114+ existing .Trace = new .Trace
152115 }
153116
154- // Merge parameters
155117 if new .Parameters != nil {
156- merged .Parameters = append ( merged .Parameters , new .Parameters ... )
118+ existing .Parameters = mergeParameters ( existing .Parameters , new .Parameters )
157119 }
158120
159- // Merge servers
160121 if new .Servers != nil {
161- merged .Servers = append (merged .Servers , new .Servers ... )
122+ existing .Servers = append (existing .Servers , new .Servers ... )
162123 }
163124
164- return merged , nil
125+ return nil
165126}
166127
167- // mergeComponents merges components from source into target
168128func mergeComponents (target , source * openapi3.Components , specIndex int ) error {
169- // Merge schemas
170129 if source .Schemas != nil {
171130 maps .Copy (target .Schemas , source .Schemas )
172131 }
173132
174- // Merge parameters
175133 if source .Parameters != nil {
176134 for name , param := range source .Parameters {
177135 if _ , exists := target .Parameters [name ]; exists {
@@ -181,7 +139,6 @@ func mergeComponents(target, source *openapi3.Components, specIndex int) error {
181139 }
182140 }
183141
184- // Merge headers
185142 if source .Headers != nil {
186143 for name , header := range source .Headers {
187144 if _ , exists := target .Headers [name ]; exists {
@@ -191,7 +148,6 @@ func mergeComponents(target, source *openapi3.Components, specIndex int) error {
191148 }
192149 }
193150
194- // Merge request bodies
195151 if source .RequestBodies != nil {
196152 for name , requestBody := range source .RequestBodies {
197153 if _ , exists := target .RequestBodies [name ]; exists {
@@ -201,7 +157,6 @@ func mergeComponents(target, source *openapi3.Components, specIndex int) error {
201157 }
202158 }
203159
204- // Merge responses
205160 if source .Responses != nil {
206161 for name , response := range source .Responses {
207162 if _ , exists := target .Responses [name ]; exists {
@@ -211,7 +166,6 @@ func mergeComponents(target, source *openapi3.Components, specIndex int) error {
211166 }
212167 }
213168
214- // Merge security schemes
215169 if source .SecuritySchemes != nil {
216170 for name , securityScheme := range source .SecuritySchemes {
217171 if _ , exists := target .SecuritySchemes [name ]; exists {
@@ -221,7 +175,6 @@ func mergeComponents(target, source *openapi3.Components, specIndex int) error {
221175 }
222176 }
223177
224- // Merge examples
225178 if source .Examples != nil {
226179 for name , example := range source .Examples {
227180 if _ , exists := target .Examples [name ]; exists {
@@ -231,7 +184,6 @@ func mergeComponents(target, source *openapi3.Components, specIndex int) error {
231184 }
232185 }
233186
234- // Merge links
235187 if source .Links != nil {
236188 for name , link := range source .Links {
237189 if _ , exists := target .Links [name ]; exists {
@@ -241,7 +193,6 @@ func mergeComponents(target, source *openapi3.Components, specIndex int) error {
241193 }
242194 }
243195
244- // Merge callbacks
245196 if source .Callbacks != nil {
246197 for name , callback := range source .Callbacks {
247198 if _ , exists := target .Callbacks [name ]; exists {
@@ -253,3 +204,48 @@ func mergeComponents(target, source *openapi3.Components, specIndex int) error {
253204
254205 return nil
255206}
207+
208+ func mergeParameters (existing , new openapi3.Parameters ) openapi3.Parameters {
209+ if len (existing ) == 0 {
210+ return new
211+ }
212+ if len (new ) == 0 {
213+ return existing
214+ }
215+
216+ paramMap := make (map [string ]* openapi3.ParameterRef )
217+ var result openapi3.Parameters
218+
219+ for _ , param := range existing {
220+ if param != nil && param .Value != nil {
221+ key := getParameterKey (param .Value )
222+ paramMap [key ] = param
223+ result = append (result , param )
224+ }
225+ }
226+
227+ for _ , param := range new {
228+ if param != nil && param .Value != nil {
229+ key := getParameterKey (param .Value )
230+ if existingParam , exists := paramMap [key ]; exists {
231+ for i , resultParam := range result {
232+ if resultParam == existingParam {
233+ result [i ] = param
234+ break
235+ }
236+ }
237+ paramMap [key ] = param
238+ } else {
239+ // Add new parameter
240+ paramMap [key ] = param
241+ result = append (result , param )
242+ }
243+ }
244+ }
245+
246+ return result
247+ }
248+
249+ func getParameterKey (param * openapi3.Parameter ) string {
250+ return param .Name + ":" + param .In
251+ }
0 commit comments