Skip to content

Commit

Permalink
refactor tsgen.
Browse files Browse the repository at this point in the history
  • Loading branch information
chaosannals committed Feb 14, 2025
1 parent 6b4975f commit e1a79eb
Show file tree
Hide file tree
Showing 18 changed files with 531 additions and 458 deletions.
21 changes: 9 additions & 12 deletions tools/goctl/api/tsgen/gen.go → tools/goctl/api/tsgen/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/spf13/cobra"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/tools/goctl/api/parser"
"github.com/zeromicro/go-zero/tools/goctl/api/tsgen/gen"
"github.com/zeromicro/go-zero/tools/goctl/util/pathx"
)

Expand All @@ -16,8 +17,6 @@ var (
VarStringDir string
// VarStringAPI describes an API file.
VarStringAPI string
// VarStringWebAPI describes a web API file.
VarStringWebAPI string
// VarStringCaller describes a caller.
VarStringCaller string
// VarBoolUnWrap describes whether wrap or not.
Expand All @@ -32,9 +31,6 @@ var (
func TsCommand(_ *cobra.Command, _ []string) error {
apiFile := VarStringAPI
dir := VarStringDir
webAPI := VarStringWebAPI
caller := VarStringCaller
unwrapAPI := VarBoolUnWrap
if len(apiFile) == 0 {
return errors.New("missing -api")
}
Expand All @@ -43,10 +39,6 @@ func TsCommand(_ *cobra.Command, _ []string) error {
return errors.New("missing -dir")
}

if len(webAPI) == 0 {
webAPI = "."
}

api, err := parser.Parse(apiFile)
if err != nil {
fmt.Println(color.Red.Render("Failed"))
Expand All @@ -57,11 +49,16 @@ func TsCommand(_ *cobra.Command, _ []string) error {
return err
}

caller := VarStringCaller
if len(caller) == 0 {
caller = "webapi"
}

api.Service = api.Service.JoinPrefix()
logx.Must(pathx.MkdirIfNotExist(dir))
logx.Must(genRequest(dir))
logx.Must(genHandler(dir, webAPI, caller, api, unwrapAPI))
logx.Must(genComponents(dir, api))
logx.Must(gen.GenRequests(dir, caller))
logx.Must(gen.GenHandler(dir, caller, api, VarBoolUnWrap, VarBoolCustomBody, VarStringUrlPrefix))
logx.Must(gen.GenComponents(dir, api))

fmt.Println(color.Green.Render("Done."))
return nil
Expand Down
4 changes: 0 additions & 4 deletions tools/goctl/api/tsgen/components.tpl

This file was deleted.

203 changes: 203 additions & 0 deletions tools/goctl/api/tsgen/gen/components.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
package gen

import (
_ "embed"
"errors"
"fmt"
"strings"

"github.com/zeromicro/go-zero/tools/goctl/api/spec"
"github.com/zeromicro/go-zero/tools/goctl/api/tsgen/template"
apiutil "github.com/zeromicro/go-zero/tools/goctl/api/util"
"github.com/zeromicro/go-zero/tools/goctl/internal/version"
"github.com/zeromicro/go-zero/tools/goctl/util"
)

func BuildTagMembers(tp spec.Type, tagKey string, indent int) ([]*template.ComponentMemberTemplateData, error) {
definedType, ok := tp.(spec.DefineStruct)
if !ok {
if pointType, ok := tp.(spec.PointerType); ok {
return BuildTagMembers(pointType.Type, tagKey, indent)
}

if nestedType, ok := tp.(spec.NestedStruct); ok {
return BuildTagMembers(spec.DefineStruct(nestedType), tagKey, indent)
}

return nil, fmt.Errorf("type %s not supported", tp.Name())
}

result := []*template.ComponentMemberTemplateData{}
members := definedType.GetTagMembers(tagKey)
for _, member := range members {
if member.IsInline {
if r, err := BuildTagMembers(member.Type, tagKey, indent); err != nil {
return nil, err
} else {
result = append(result, r...)
}
continue
}

if p, err := BuildProperty(member, indent); err != nil {
return nil, apiutil.WrapErr(err, " type "+tp.Name())
} else {
result = append(result, p)
}
}
return result, nil
}

func BuildMembers(tp spec.Type, isParam bool, indent int) ([]*template.ComponentMemberTemplateData, error) {
definedType, ok := tp.(spec.DefineStruct)
if !ok {
if pointType, ok := tp.(spec.PointerType); ok {
return BuildMembers(pointType.Type, isParam, indent)
}

if nestedType, ok := tp.(spec.NestedStruct); ok {
return BuildMembers(spec.DefineStruct(nestedType), isParam, indent)
}

return nil, fmt.Errorf("type %s not supported", tp.Name())
}

result := []*template.ComponentMemberTemplateData{}
members := definedType.GetBodyMembers()
if isParam {
members = definedType.GetNonBodyMembers()
}
for _, member := range members {
if member.IsInline {
if ms, err := BuildMembers(member.Type, isParam, indent); err != nil {
return nil, err
} else {
result = append(result, ms...)
}
continue
}

if p, err := BuildProperty(member, indent); err != nil {
return nil, apiutil.WrapErr(err, " type "+tp.Name())
} else {
result = append(result, p)
}
}
return result, nil
}

func BuildSubTypes(tp spec.Type, indent int) ([]*template.ComponentTypeTemplateData, error) {
definedType, ok := tp.(spec.DefineStruct)
if !ok {
return nil, errors.New("no members of type " + tp.Name())
}

result := []*template.ComponentTypeTemplateData{}
members := definedType.GetNonBodyMembers()
if len(members) == 0 {
return result, nil
}

if len(definedType.GetTagMembers(formTagKey)) > 0 {
ctt := &template.ComponentTypeTemplateData{
TypeName: fmt.Sprintf("%sParams", util.Title(tp.Name())),
}

if ms, err := BuildTagMembers(tp, formTagKey, indent); err != nil {
return nil, err
} else {
ctt.Members = ms
}
result = append(result, ctt)
}

if len(definedType.GetTagMembers(headerTagKey)) > 0 {
ctt := &template.ComponentTypeTemplateData{
TypeName: fmt.Sprintf("%sHeaders", util.Title(tp.Name())),
}
if ms, err := BuildTagMembers(tp, headerTagKey, indent); err != nil {
return nil, err
} else {
ctt.Members = ms
}

result = append(result, ctt)
}

return result, nil
}

func BuildProperty(member spec.Member, indent int) (*template.ComponentMemberTemplateData, error) {
ty, err := GenTsType(member, indent)
if err != nil {
return nil, err
}

result := &template.ComponentMemberTemplateData{}

if IsOptionalOrOmitEmpty(member) {
result.OptionalTag = "?"
}

name, err := member.GetPropertyName()
if err != nil {
return nil, err
}
if strings.Contains(name, "-") {
name = fmt.Sprintf("\"%s\"", name)
}
result.PropertyName = name

comment := member.GetComment()
if len(comment) > 0 {
comment = strings.TrimPrefix(comment, "//")
result.Comment = strings.TrimSpace(comment)
}
// result.Docs = member.Docs
result.PropertyType = ty

return result, nil
}

// BuildTypes generates the typescript code for the types.
func BuildTypes(types []spec.Type) ([]template.ComponentTypeTemplateData, error) {
result := []template.ComponentTypeTemplateData{}
for _, tp := range types {
members, err := BuildMembers(tp, false, 0)
if err != nil {
return nil, err
}

subTypes, err := BuildSubTypes(tp, 0)
if err != nil {
return nil, err
}
ctt := template.ComponentTypeTemplateData{
TypeName: util.Title(tp.Name()),
Members: members,
SubTypes: subTypes,
}
result = append(result, ctt)
}

return result, nil
}

func GenComponents(dir string, api *spec.ApiSpec) error {
types := api.Types
if len(types) == 0 {
return nil
}

val, err := BuildTypes(types)
if err != nil {
return err
}

componentName := apiutil.ComponentName(api)
data := template.ComponentTemplateData{
Version: version.BuildVersion,
Types: val,
}
return template.GenTsFile(dir, componentName, template.Components, data)
}
Loading

0 comments on commit e1a79eb

Please sign in to comment.