Skip to content

Commit 87dd967

Browse files
Copilotkevwan
andcommitted
Fix TypeScript generator to handle inline/embedded structs correctly
- Add hasActualTagMembers helper to recursively check for actual tag members - Add hasActualBodyMembers helper to recursively check for actual body members - Add hasActualNonBodyMembers helper to recursively check for actual non-body members - Update genParamsTypesIfNeed to use hasActualNonBodyMembers and hasActualTagMembers - Update hasRequestBody, hasRequestHeader, hasRequestPath, and pathHasParams to use new helpers - Add comprehensive test coverage for new helper functions Co-authored-by: kevwan <[email protected]>
1 parent 4e52d77 commit 87dd967

File tree

3 files changed

+357
-8
lines changed

3 files changed

+357
-8
lines changed

tools/goctl/api/tsgen/genpacket.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ func pathHasParams(route spec.Route) bool {
212212
return false
213213
}
214214

215-
return len(ds.Members) != len(ds.GetBodyMembers())
215+
return hasActualNonBodyMembers(ds)
216216
}
217217

218218
func hasRequestBody(route spec.Route) bool {
@@ -221,7 +221,7 @@ func hasRequestBody(route spec.Route) bool {
221221
return false
222222
}
223223

224-
return len(route.RequestTypeName()) > 0 && len(ds.GetBodyMembers()) > 0
224+
return len(route.RequestTypeName()) > 0 && hasActualBodyMembers(ds)
225225
}
226226

227227
func hasRequestPath(route spec.Route) bool {
@@ -230,7 +230,7 @@ func hasRequestPath(route spec.Route) bool {
230230
return false
231231
}
232232

233-
return len(route.RequestTypeName()) > 0 && len(ds.GetTagMembers(pathTagKey)) > 0
233+
return len(route.RequestTypeName()) > 0 && hasActualTagMembers(ds, pathTagKey)
234234
}
235235

236236
func hasRequestHeader(route spec.Route) bool {
@@ -239,5 +239,5 @@ func hasRequestHeader(route spec.Route) bool {
239239
return false
240240
}
241241

242-
return len(route.RequestTypeName()) > 0 && len(ds.GetTagMembers(headerTagKey)) > 0
242+
return len(route.RequestTypeName()) > 0 && hasActualTagMembers(ds, headerTagKey)
243243
}

tools/goctl/api/tsgen/util.go

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,13 @@ func writeType(writer io.Writer, tp spec.Type) error {
164164
}
165165

166166
func genParamsTypesIfNeed(writer io.Writer, tp spec.Type) error {
167-
definedType, ok := tp.(spec.DefineStruct)
167+
_, ok := tp.(spec.DefineStruct)
168168
if !ok {
169169
return errors.New("no members of type " + tp.Name())
170170
}
171171

172-
members := definedType.GetNonBodyMembers()
173-
if len(members) == 0 {
172+
// Check if there are actual non-body members (recursively through inline structs)
173+
if !hasActualNonBodyMembers(tp) {
174174
return nil
175175
}
176176

@@ -180,7 +180,7 @@ func genParamsTypesIfNeed(writer io.Writer, tp spec.Type) error {
180180
}
181181
fmt.Fprintf(writer, "}\n")
182182

183-
if len(definedType.GetTagMembers(headerTagKey)) > 0 {
183+
if hasActualTagMembers(tp, headerTagKey) {
184184
fmt.Fprintf(writer, "export interface %sHeaders {\n", util.Title(tp.Name()))
185185
if err := writeTagMembers(writer, tp, headerTagKey); err != nil {
186186
return err
@@ -247,3 +247,87 @@ func writeTagMembers(writer io.Writer, tp spec.Type, tagKey string) error {
247247
}
248248
return nil
249249
}
250+
251+
// hasActualTagMembers checks if a type has actual members with the given tag,
252+
// recursively checking inline/embedded structs
253+
func hasActualTagMembers(tp spec.Type, tagKey string) bool {
254+
definedType, ok := tp.(spec.DefineStruct)
255+
if !ok {
256+
pointType, ok := tp.(spec.PointerType)
257+
if ok {
258+
return hasActualTagMembers(pointType.Type, tagKey)
259+
}
260+
return false
261+
}
262+
263+
for _, m := range definedType.Members {
264+
if m.IsInline {
265+
// Recursively check inline members
266+
if hasActualTagMembers(m.Type, tagKey) {
267+
return true
268+
}
269+
} else {
270+
// Check non-inline members for the tag
271+
if m.IsTagMember(tagKey) {
272+
return true
273+
}
274+
}
275+
}
276+
return false
277+
}
278+
279+
// hasActualBodyMembers checks if a type has actual body members (json tags),
280+
// recursively checking inline/embedded structs
281+
func hasActualBodyMembers(tp spec.Type) bool {
282+
definedType, ok := tp.(spec.DefineStruct)
283+
if !ok {
284+
pointType, ok := tp.(spec.PointerType)
285+
if ok {
286+
return hasActualBodyMembers(pointType.Type)
287+
}
288+
return false
289+
}
290+
291+
for _, m := range definedType.Members {
292+
if m.IsInline {
293+
// Recursively check inline members
294+
if hasActualBodyMembers(m.Type) {
295+
return true
296+
}
297+
} else {
298+
// Check non-inline members for json tag
299+
if m.IsBodyMember() {
300+
return true
301+
}
302+
}
303+
}
304+
return false
305+
}
306+
307+
// hasActualNonBodyMembers checks if a type has actual non-body members (form, path, header tags),
308+
// recursively checking inline/embedded structs
309+
func hasActualNonBodyMembers(tp spec.Type) bool {
310+
definedType, ok := tp.(spec.DefineStruct)
311+
if !ok {
312+
pointType, ok := tp.(spec.PointerType)
313+
if ok {
314+
return hasActualNonBodyMembers(pointType.Type)
315+
}
316+
return false
317+
}
318+
319+
for _, m := range definedType.Members {
320+
if m.IsInline {
321+
// Recursively check inline members
322+
if hasActualNonBodyMembers(m.Type) {
323+
return true
324+
}
325+
} else {
326+
// Check non-inline members for non-body tags
327+
if !m.IsBodyMember() {
328+
return true
329+
}
330+
}
331+
}
332+
return false
333+
}

0 commit comments

Comments
 (0)