package main import ( "flag" "fmt" protogen2 "git.diulo.com/mogfee/kit/protogen" "google.golang.org/protobuf/compiler/protogen" "strings" ) func main() { u := &Kit{} var flags flag.FlagSet flags.StringVar(&u.Prefix, "prefix", "", "API path prefix") protogen.Options{ ParamFunc: flags.Set, }.Run(u.Generate) } type Kit struct { Prefix string } func (u *Kit) Generate(plugin *protogen.Plugin) error { if len(plugin.Files) < 1 { return nil } for _, f := range plugin.Files { if len(f.Services) == 0 { continue } fname := f.GeneratedFilenamePrefix + ".ts" t := plugin.NewGeneratedFile(fname, f.GoImportPath) t.P(`// http.prefix:`, u.Prefix) t.P(`// @ts-ignore`) t.P(`import {Config,http} from "./http";`) for _, s := range f.Messages { t.P(`export interface `, s.Desc.Name(), ` {`) for _, vv := range s.Fields { common := strings.TrimSpace(vv.Comments.Leading.String()) if common != "" { t.P(` `, common) } typ := []string{} isRequired := ":" if vv.Desc.IsMap() { fields := vv.Desc.Message().Fields() typ = append(typ, fmt.Sprintf(`{ [key: %s]: %s }`, getType(fields.Get(0).Kind().String()), getType(fields.Get(1).Kind().String()))) } else if vv.Desc.Kind().String() == "message" { fullName := fmt.Sprintf("%v", vv.Desc.Message().FullName()) if strings.HasPrefix(fullName, "google.protobuf") && strings.HasSuffix(fullName, "Value") { isRequired = "?:" } typ = append(typ, getType(fmt.Sprintf("%v", vv.Desc.Message().Name()))) } else { typ = append(typ, getType(vv.Desc.Kind().String())) } if vv.Desc.IsList() { typ = append(typ, "[]") } //t.P(` `, vv.Desc.FullName().Name(), isRequired, ` `, strings.Join(typ, "")) t.P(` `, vv.Desc.JSONName(), isRequired, ` `, strings.Join(typ, "")) } t.P(`}`) t.P() } for _, s := range f.Services { t.P(`export class `, s.Desc.Name(), `Service{`) for _, m := range s.Methods { method, path := protogen2.GetProtoMethod(m) if method == "" { continue } if u.Prefix != "" { path = u.Prefix + path } common := strings.TrimSpace(m.Comments.Leading.String()) if common != "" { t.P(` `, common) } t.P(getInd(1), `static async `, m.Desc.Name(), `(data :Partial<`, m.Input.Desc.Name(), `>, param?: Partial):Promise<`, m.Output.Desc.Name(), `>{`) t.P(getInd(2), `return http<`, m.Output.Desc.Name(), `>('`, path, `', {`) t.P(getInd(3), `...param,`) t.P(getInd(3), `data: data,`) t.P(getInd(3), `method:'`, method, `'`) t.P(getInd(2), `})`) t.P(getInd(1), `}`) } t.P(`}`) } } return nil } func getInd(i int) string { return strings.Repeat(` `, i) } func getType(key string) string { mps := map[string]string{ "int32": "number", "int64": "string", "bytes": "Uint8Array", "Int32Value": "number", "StringValue": "string", "bool": "boolean", } if v, ok := mps[key]; ok { return v } return key }