diff --git a/cmd/kit/main.go b/cmd/kit/main.go index a92f3c9..b556911 100644 --- a/cmd/kit/main.go +++ b/cmd/kit/main.go @@ -1,14 +1,10 @@ package main import ( - "github.com/golang/protobuf/proto" - "google.golang.org/genproto/googleapis/api/annotations" + protogen2 "git.diulo.com/mogfee/protoc-gen-kit/pkg/protogen" "google.golang.org/protobuf/compiler/protogen" - "google.golang.org/protobuf/types/descriptorpb" ) -// go build && protoc --unknow_out=./proto --go_out=./proto/ --go-grpc_out=./proto proto/user.proto -I ./proto -// protoc --unknow_out=./proto proto/user.proto func main() { u := &Kit{ imports: map[string]string{}, @@ -49,7 +45,7 @@ func (u *Kit) Generate(plugin *protogen.Plugin) error { serverName := s.GoName t.P(`func Register`, serverName, `Handler(app *gin.Engine,srv `, serverName, `Server,m ...middleware.Middleware) {`) for _, m := range s.Methods { - method, path := u.getMethod(m) + method, path := protogen2.GetProtoMethod(m) if method == "" { continue } @@ -60,16 +56,16 @@ func (u *Kit) Generate(plugin *protogen.Plugin) error { for _, s := range f.Services { serverName := s.GoName for _, m := range s.Methods { - method, _ := u.getMethod(m) + method, _ := protogen2.GetProtoMethod(m) if method == "" { continue } switch method { - case method_get: + case protogen2.METHOD_GET: u.genGet(serverName, t, m) - case method_post: + case protogen2.METHOD_POST: u.genPost(serverName, t, m) - case method_delete: + case protogen2.METHOD_DELETE: u.genDelete(serverName, t, m) } @@ -154,40 +150,3 @@ func (u *Kit) genDelete(serverName string, t *protogen.GeneratedFile, m *protoge }`) t.P("}") } - -// func (Kit) getAuth(m *protogen.Method) *auth.AuthInfo { -// if op, ok := m.Desc.Options().(*descriptorpb.MethodOptions); ok { -// if opts, err := proto.GetExtension(op, auth.E_Auth); err != nil { -// log.Println(err) -// } else { -// if vv, ok := opts.(*auth.AuthInfo); ok { -// return vv -// } -// } -// } -// return &auth.AuthInfo{} -// } -func (Kit) getMethod(m *protogen.Method) (method string, path string) { - if op, ok := m.Desc.Options().(*descriptorpb.MethodOptions); ok { - if opts, err := proto.GetExtension(op, annotations.E_Http); err != nil { - //log.Println(err) - } else { - if vv, ok := opts.(*annotations.HttpRule); ok { - if vvv, ok := vv.Pattern.(*annotations.HttpRule_Get); ok { - return method_get, vvv.Get - } else if vvv, ok := vv.Pattern.(*annotations.HttpRule_Post); ok { - return method_post, vvv.Post - } else if vvv, ok := vv.Pattern.(*annotations.HttpRule_Delete); ok { - return method_delete, vvv.Delete - } - } - } - } - return "", "" -} - -const ( - method_get = "GET" - method_post = "POST" - method_delete = "DELETE" -) diff --git a/cmd/ts/main.go b/cmd/ts/main.go index 6f9cb28..4a5a655 100644 --- a/cmd/ts/main.go +++ b/cmd/ts/main.go @@ -2,34 +2,31 @@ package main import ( "fmt" + protogen2 "git.diulo.com/mogfee/protoc-gen-kit/pkg/protogen" "google.golang.org/protobuf/compiler/protogen" "strings" ) func main() { - u := &Kit{ - imports: map[string]string{}, - } + u := &Kit{} protogen.Options{}.Run(u.Generate) } type Kit struct { - imports map[string]string } -func (u *Kit) addImports(imp string) { - u.imports[imp] = imp -} 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(`import {Config,http} from "./http";`) for _, s := range f.Messages { t.P(`export interface `, s.Desc.Name(), ` {`) for _, vv := range s.Fields { @@ -43,52 +40,49 @@ func (u *Kit) Generate(plugin *protogen.Plugin) error { 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" { - //t.P(vv.Desc.Message().Fields()) - //t.P(vv.Desc.Message().Name()) - //if vv.Desc.Message().Fields().Get(0).Name() == "value" { - // isRequired = "?:" - // //typ = append(typ, getType(vv.Desc.Message().Fields().Get(0).Kind().String())) - //} else { 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())) } - - //vtype := fmt.Sprintf("%v", vv.Desc.Kind()) - //if vtype == "bytes" { - // typ = append(typ, "Uint8Array") - //} else if vtype == "message" { - // if vv.Desc.IsMap() { - // typ = append(typ, fmt.Sprintf(`{ [key: %s]: %s }`, fields.Get(0).Kind().String(), fields.Get(1).Kind().String())) - // } else { - // - // } - // - // //for _,v:=range vv.Desc.Message().Fields(){ - // // - // //} - // //t.P() - // //typ = append(typ, "Uint8Array") - //} else { - // typ = append(typ, vtype) - //} if vv.Desc.IsList() { typ = append(typ, "[]") } - //t.P(vv.Desc) 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 + } + common := strings.TrimSpace(m.Comments.Leading.String()) + if common != "" { + t.P(` `, common) + } + t.P(getInd(1), `static async `, m.Desc.Name(), `(data :`, m.Input.Desc.Name(), `, param?: Config):Promise<`, m.Output.Desc.Name(), `>{`) + t.P(getInd(2), `return http<`, m.Input.Desc.Name(), `, `, 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", diff --git a/pkg/protogen/protogen.go b/pkg/protogen/protogen.go new file mode 100644 index 0000000..b16bdd0 --- /dev/null +++ b/pkg/protogen/protogen.go @@ -0,0 +1,33 @@ +package protogen + +import ( + "github.com/golang/protobuf/proto" + "google.golang.org/genproto/googleapis/api/annotations" + "google.golang.org/protobuf/compiler/protogen" + "google.golang.org/protobuf/types/descriptorpb" +) + +const ( + METHOD_GET = "GET" + METHOD_POST = "POST" + METHOD_DELETE = "DELETE" +) + +func GetProtoMethod(m *protogen.Method) (method string, path string) { + if op, ok := m.Desc.Options().(*descriptorpb.MethodOptions); ok { + if opts, err := proto.GetExtension(op, annotations.E_Http); err != nil { + //log.Println(err) + } else { + if vv, ok := opts.(*annotations.HttpRule); ok { + if vvv, ok := vv.Pattern.(*annotations.HttpRule_Get); ok { + return METHOD_GET, vvv.Get + } else if vvv, ok := vv.Pattern.(*annotations.HttpRule_Post); ok { + return METHOD_POST, vvv.Post + } else if vvv, ok := vv.Pattern.(*annotations.HttpRule_Delete); ok { + return METHOD_DELETE, vvv.Delete + } + } + } + } + return "", "" +} diff --git a/proto/main b/proto/main new file mode 100755 index 0000000..38db6e6 Binary files /dev/null and b/proto/main differ diff --git a/proto/user.proto b/proto/user.proto index dda1c19..f5a5345 100644 --- a/proto/user.proto +++ b/proto/user.proto @@ -10,11 +10,13 @@ import "google/protobuf/wrappers.proto"; import "google/protobuf/descriptor.proto"; service user{ + //列表 rpc list(loginRequest)returns(loginResponse){ option(google.api.http) = { get:"/api/v1/user/list" }; } + //等了 rpc login(loginRequest)returns(loginResponse){ option (google.api.http) = { post: "/api/v1/user/login", diff --git a/proto/v1/http.ts b/proto/v1/http.ts new file mode 100644 index 0000000..b320347 --- /dev/null +++ b/proto/v1/http.ts @@ -0,0 +1,54 @@ +//复制时倒入qs +// @ts-ignore +import qs from "qs"; + +const API_SERVER = process.env.NEXT_PUBLIC_WEB_SITE + +export interface Config extends RequestInit { + token?: string + data?: T + method?: 'POST' | 'GET' +} + +interface IError { + status: number + details: [], + message: string + metadata: any + reason: string +} + +const http = async (endpoint: string, {data, token, headers, ...customConfig}: Config) => { + const config = { + method: "GET", + headers: { + Authorization: token ? `Bearer ${token}` : '', + 'Content-type': data ? 'application/json' : '', + }, + ...customConfig + } + if (config.method.toUpperCase() === "GET") { + endpoint += `?${qs.stringify(data)}` + } else { + config.body = JSON.stringify(data || {}) + } + console.log(API_SERVER + endpoint, token) + return fetch(API_SERVER + endpoint, config).then(async response => { + if (response.status == 401) { + if (typeof window != 'undefined') { + // window.location.reload(); + } + return Promise.reject({message: "请重新登录", status: 401}) + } + const data = await response.json(); + if (response.ok) { + return data as V; + } else { + return Promise.reject(data as IError); + } + }) +} + +export { + http +} diff --git a/proto/v1/user.ts b/proto/v1/user.ts index 3252e95..20c3ccb 100644 --- a/proto/v1/user.ts +++ b/proto/v1/user.ts @@ -1,3 +1,4 @@ +import {Config,http} from "./http"; export interface loginRequest { //用户名 username: string @@ -10,3 +11,21 @@ export interface loginResponse { token: string } +export class userService{ + //列表 + static async list(data :loginRequest, param?: Config):Promise{ + return http('/api/v1/user/list', { + ...param, + data: data, + method:'GET' + }) + } + //等了 + static async login(data :loginRequest, param?: Config):Promise{ + return http('/api/v1/user/login', { + ...param, + data: data, + method:'POST' + }) + } +} diff --git a/proto/v1/user_grpc.pb.go b/proto/v1/user_grpc.pb.go index 8cd5713..ecf8f91 100644 --- a/proto/v1/user_grpc.pb.go +++ b/proto/v1/user_grpc.pb.go @@ -22,7 +22,9 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type UserClient interface { + //列表 List(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error) + //等了 Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error) Delete(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error) } @@ -66,7 +68,9 @@ func (c *userClient) Delete(ctx context.Context, in *LoginRequest, opts ...grpc. // All implementations must embed UnimplementedUserServer // for forward compatibility type UserServer interface { + //列表 List(context.Context, *LoginRequest) (*LoginResponse, error) + //等了 Login(context.Context, *LoginRequest) (*LoginResponse, error) Delete(context.Context, *LoginRequest) (*LoginResponse, error) mustEmbedUnimplementedUserServer()