Browse Source

feat(goctl): better generate the api code of typescript (#2483)

foliet 2 years ago
parent
commit
799c118d95

+ 15 - 0
tools/goctl/api/spec/example_test.go

@@ -0,0 +1,15 @@
+package spec_test
+
+import (
+	"fmt"
+	"github.com/zeromicro/go-zero/tools/goctl/api/spec"
+)
+
+func ExampleMember_GetEnumOptions() {
+	member := spec.Member{
+		Tag: `json:"foo,options=foo|bar|options|123"`,
+	}
+	fmt.Println(member.GetEnumOptions())
+	// Output:
+	// [foo bar options 123]
+}

+ 21 - 0
tools/goctl/api/spec/fn.go

@@ -154,6 +154,27 @@ func (m Member) IsTagMember(tagKey string) bool {
 	return false
 }
 
+// GetEnumOptions return a slice contains all enumeration options
+func (m Member) GetEnumOptions() []string {
+	if !m.IsBodyMember() {
+		return nil
+	}
+
+	tags := m.Tags()
+	for _, tag := range tags {
+		if tag.Key == bodyTagKey {
+			options := tag.Options
+			for _, option := range options {
+				if strings.Index(option, "options=") == 0 {
+					option = strings.TrimPrefix(option, "options=")
+					return strings.Split(option, "|")
+				}
+			}
+		}
+	}
+	return nil
+}
+
 // GetBodyMembers returns all json fields
 func (t DefineStruct) GetBodyMembers() []Member {
 	var result []Member

+ 14 - 1
tools/goctl/api/tsgen/util.go

@@ -19,7 +19,7 @@ const (
 
 func writeProperty(writer io.Writer, member spec.Member, indent int) error {
 	writeIndent(writer, indent)
-	ty, err := goTypeToTs(member.Type, false)
+	ty, err := genTsType(member)
 	if err != nil {
 		return err
 	}
@@ -52,6 +52,19 @@ func writeIndent(writer io.Writer, indent int) {
 	}
 }
 
+func genTsType(m spec.Member) (ty string, err error) {
+	ty, err = goTypeToTs(m.Type, false)
+	if enums := m.GetEnumOptions(); enums != nil {
+		if ty == "string" {
+			for i := range enums {
+				enums[i] = "'" + enums[i] + "'"
+			}
+		}
+		ty = strings.Join(enums, " | ")
+	}
+	return
+}
+
 func goTypeToTs(tp spec.Type, fromPacket bool) (string, error) {
 	switch v := tp.(type) {
 	case spec.DefineStruct:

+ 38 - 0
tools/goctl/api/tsgen/util_test.go

@@ -0,0 +1,38 @@
+package tsgen
+
+import (
+	"github.com/stretchr/testify/assert"
+	"github.com/zeromicro/go-zero/tools/goctl/api/spec"
+	"testing"
+)
+
+func TestGenTsType(t *testing.T) {
+	member := spec.Member{
+		Name:     "foo",
+		Type:     spec.PrimitiveType{RawName: "string"},
+		Tag:      `json:"foo,options=foo|bar|options|123"`,
+		Comment:  "",
+		Docs:     nil,
+		IsInline: false,
+	}
+	ty, err := genTsType(member)
+	if err != nil {
+		t.Fatal(err)
+	}
+	assert.Equal(t, `'foo' | 'bar' | 'options' | '123'`, ty)
+
+	member.IsInline = true
+	ty, err = genTsType(member)
+	if err != nil {
+		t.Fatal(err)
+	}
+	assert.Equal(t, `'foo' | 'bar' | 'options' | '123'`, ty)
+
+	member.Type = spec.PrimitiveType{RawName: "int"}
+	member.Tag = `json:"foo,options=1|3|4|123"`
+	ty, err = genTsType(member)
+	if err != nil {
+		t.Fatal(err)
+	}
+	assert.Equal(t, `1 | 3 | 4 | 123`, ty)
+}