diff --git a/.github/workflows/scf-actions.yml b/.github/workflows/scf-actions.yml new file mode 100644 index 0000000..7bf9701 --- /dev/null +++ b/.github/workflows/scf-actions.yml @@ -0,0 +1,79 @@ +name: Scf Actions +on: [push] +jobs: + deploy: + runs-on: ubuntu-latest + environment: development + timeout-minutes: 5 + strategy: + matrix: + node-version: ["16.x"] + pnpm-version: ["6.0.2"] + go-version: ["1.18.2"] + steps: + - uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - name: Use pnpm ${{ matrix.pnpm-version }} + uses: pnpm/action-setup@v2.1.0 + with: + version: ${{ matrix.pnpm-version }} + run_install: false + - name: Use Golang ${{ matrix.go-version }} + uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.go-version }} + + - name: Use Buf + uses: bufbuild/buf-setup-action@v1.4.0 + - name: Use Buf Lint + uses: bufbuild/buf-lint-action@v1 + + - name: Setup pnpm cache + uses: actions/cache@v3 + with: + path: | + ~/.pnpm-store + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/serverless.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Stepup go cache + uses: actions/cache@v3 + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Install dependencies + run: pnpm install --global serverless serverless-tencent + + - name: Check Go Version + run: go version + + - name: Make prepare + run: | + export PATH="$PATH:$(go env GOPATH)/bin" + make plugins + make buf + + # - name: Make build + # run: | + # export PATH="$PATH:$(go env GOPATH)/bin" + # make scf-build + + # - name: Make and deploy + # run: make + # env: + # TENCENT_APP_ID: ${{ secrets.TENCENT_APP_ID }} + # TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }} + # TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }} + # TENCENT_TOKEN: ${{ secrets.TENCENT_TOKEN }} + # STAGE: ${{ secrets.STAGE }} + # SCF_NAMESPACE: ${{ secrets.SCF_NAMESPACE }} + # SERVERLESS_PLATFORM_VENDOR: ${{ secrets.SERVERLESS_PLATFORM_VENDOR }} diff --git a/.gitignore b/.gitignore index 8f939bf..6c5ad56 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ __debug_bin xadmin-api main +.env # Test binary, built with `go test -c` *.test diff --git a/Makefile b/Makefile index 7d480b6..06a636f 100644 --- a/Makefile +++ b/Makefile @@ -3,22 +3,31 @@ GIT:='github.com/go-masonry/mortar/mortar.gitCommit=$(shell git rev-parse --shor BUILD_TAG:='github.com/go-masonry/mortar/mortar.buildTag=42' BUILD_TS:='github.com/go-masonry/mortar/mortar.buildTimestamp=$(shell date -u +"%Y-%m-%dT%H:%M:%SZ")' +LDFLAGS=-ldflags +LDFLAGS+="-X ${VER} -X ${GIT} -X ${BUILD_TAG} -X ${BUILD_TS}" + export JAEGER_AGENT_HOST = localhost export JAEGER_AGENT_PORT = 6831 export JAEGER_SAMPLER_TYPE = const export JAEGER_SAMPLER_PARAM = 1 run: buf - @go run -ldflags="-X ${VER} -X ${GIT} -X ${BUILD_TAG} -X ${BUILD_TS}" main.go \ + @go run $(LDFLAGS) -o output/main cmd/api-server/main.go \ config config/config.yml dev-local: buf - @CGO_ENABLED=1 go run -ldflags="-X ${VER} -X ${GIT} -X ${BUILD_TAG} -X ${BUILD_TS}" main.go \ + @go run $(LDFLAGS) -o output/main cmd/api-server/main.go \ config config/config.yml \ --additional-files config/config_local.yml build: buf - @CGO_ENABLED=1 go build -ldflags="-X ${VER} -X ${GIT} -X ${BUILD_TAG} -X ${BUILD_TS}" main.go + go build $(LDFLAGS) -o output/main cmd/api-server/main.go + +scf-build: + GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o main cmd/api-scf/main.go + +scf-deploy: + sls deploy format: go fmt ./... diff --git a/api/annotation/v1/extends.proto b/api/annotation/v1/extends.proto index 249bdef..6e259d0 100644 --- a/api/annotation/v1/extends.proto +++ b/api/annotation/v1/extends.proto @@ -41,6 +41,10 @@ extend google.protobuf.MethodOptions { optional bool method_option = 50007; } +message GencodeOption { + repeated string layers = 2; +} + // The message descriptor. message MessageDescriptor { // The the FieldMask paths mapping. @@ -48,6 +52,8 @@ message MessageDescriptor { // The default feild actions when message's field action is empty. repeated string default_field_actions = 2; + + GencodeOption gencode = 3; } // The resource field descriptor. @@ -61,6 +67,8 @@ message FieldDescriptor { // The the field tags. // Append extra tags on filed, default add yaml with camlecase. map tags = 2; + + GencodeOption gencode = 3; } message ResourceDescriptor { diff --git a/api/bchm/v1/bchm.proto b/api/bchm/v1/bchm.proto index eb39b66..ec96246 100644 --- a/api/bchm/v1/bchm.proto +++ b/api/bchm/v1/bchm.proto @@ -13,6 +13,10 @@ option java_outer_classname = "BchmProto"; option java_package = "com.github.airdb.xadmin-api.bchm.v1"; // 宝贝回家 业务 +// +// @Kit +// gencode: +// layers: ["*"] service BchmService { // ListLosts 走失信息 列表. // diff --git a/app/controllers/bchm.go b/app/controllers/bchm.go index fbffa79..dc7404f 100644 --- a/app/controllers/bchm.go +++ b/app/controllers/bchm.go @@ -20,9 +20,8 @@ type BchmServiceController interface { type bchmInfoControllerDeps struct { fx.In - DB data.LostRepo - LostRepo data.LostRepo Logger log.Logger + LostRepo data.LostRepo } type bchmInfoController struct { diff --git a/app/data/lost.go b/app/data/lost.go index 363ddf8..46362a1 100644 --- a/app/data/lost.go +++ b/app/data/lost.go @@ -16,6 +16,12 @@ type lostRepoDeps struct { fx.In } +type lostRepo struct { + *repokit.Repo[LostEntity, uint, bchmv1.ListLostsRequest] + + deps lostRepoDeps +} + func NewLostRepo(deps lostRepoDeps) LostRepo { repo := &lostRepo{ deps: deps, @@ -24,9 +30,3 @@ func NewLostRepo(deps lostRepoDeps) LostRepo { return repo } - -type lostRepo struct { - *repokit.Repo[LostEntity, uint, bchmv1.ListLostsRequest] - - deps lostRepoDeps -} diff --git a/app/mortar/auth.go b/app/mortar/auth.go index 1f64c29..3b69d73 100644 --- a/app/mortar/auth.go +++ b/app/mortar/auth.go @@ -86,11 +86,13 @@ func (interceptor *AuthInterceptor) Unary() grpc.UnaryServerInterceptor { claims, err := auth.ParseJwtToken(token) if err != nil { interceptor.log.WithError(err).Debug(ctx, "parse oauth token") + return handler(ctx, req) } user, err := auth.GetUser(claims.User.Name) if err != nil { interceptor.log.WithError(err).Debug(ctx, "get oauth user error") + return handler(ctx, req) } return handler(authkit.NewContextUser(ctx, user), req) diff --git a/app/mortar/serverless.go b/app/mortar/serverless.go new file mode 100644 index 0000000..645f73a --- /dev/null +++ b/app/mortar/serverless.go @@ -0,0 +1,154 @@ +package mortar + +import ( + "context" + "encoding/json" + "net" + "net/http" + + "github.com/go-chi/chi/v5" + "github.com/go-masonry/mortar/constructors/partial" + serverInt "github.com/go-masonry/mortar/interfaces/http/server" + "github.com/go-masonry/mortar/interfaces/log" + chiadapter "github.com/serverless-plus/tencent-serverless-go/chi" + "github.com/serverless-plus/tencent-serverless-go/events" + "github.com/serverless-plus/tencent-serverless-go/faas" + "go.uber.org/fx" +) + +func BuildServerlessFxOption() fx.Option { + return fx.Options( + fx.Provide(NewServerless), + // fx.Provide(fx.Annotated{ + // Group: partial.FxGroupBuilderCallbacks, + // Target: func(s *Serverless) partial.BuilderCallback { + // return s.BuilderCallback() + // }, + // }), + fx.Provide(fx.Annotated{ + Group: partial.FxGroupExternalBuilderCallbacks, + Target: func(s *Serverless) partial.RESTBuilderCallback { + return s.ExternalBuilderCallback() + }, + }), + // fx.Provide(fx.Annotated{ + // Group: partial.FxGroupInternalBuilderCallbacks, + // Target: func(s *Serverless) partial.RESTBuilderCallback { + // return s.InternalBuilderCallback() + // }, + // }), + ) +} + +type serverlessDeps struct { + fx.In + + LifeCycle fx.Lifecycle + Logger log.Logger + Serverless *Serverless +} + +// InvokeWebServerlessFxOption creates the entire dependency graph +// and registers all provided fx.LifeCycle hooks +func InvokeWebServerlessFxOption() fx.Option { + return fx.Invoke(func(deps serverlessDeps) error { + deps.Serverless.initAdapter() + + deps.LifeCycle.Append(fx.Hook{ + OnStart: func(ctx context.Context) error { + go faas.Start(deps.Serverless.scfHandler) + return nil + }, + OnStop: func(ctx context.Context) error { + return nil + }, + }) + + return nil + }) +} + +type Serverless struct { + externalMux *http.ServeMux + chiFaas *chiadapter.ChiFaas +} + +func NewServerless() *Serverless { + return &Serverless{ + externalMux: http.NewServeMux(), + } +} + +func (s *Serverless) initAdapter() { + r := chi.NewRouter() + r.Mount("/", s.externalMux) + r.Route("/debug", func(r chi.Router) { + r.Get("/", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + buf, _ := json.Marshal(map[string]interface{}{ + "message": "Hello Serverless Chi", + "query": r.URL.Query().Get("q"), + }) + w.Write(buf) + }) + }) + + s.chiFaas = chiadapter.New(r) +} + +// Handler serverless faas handler +func (s *Serverless) scfHandler(ctx context.Context, req events.APIGatewayRequest) (events.APIGatewayResponse, error) { + return s.chiFaas.ProxyWithContext(ctx, req) +} + +func (s *Serverless) BuilderCallback() partial.BuilderCallback { + return func(builder serverInt.GRPCWebServiceBuilder) serverInt.GRPCWebServiceBuilder { + ln, err := s.listen("./output/grpc.socket") + if err != nil { + panic(err) + } + return builder.SetCustomListener(ln) + } +} + +func (s *Serverless) ExternalBuilderCallback() partial.RESTBuilderCallback { + return func(builder serverInt.RESTBuilder) serverInt.RESTBuilder { + // ln, err := s.listen("./output/external.socket") + // if err != nil { + // panic(err) + // } + // return builder.SetCustomListener(ln) + return builder.SetCustomServer(&http.Server{ + Handler: s.externalMux, + }) + } +} + +func (s *Serverless) InternalBuilderCallback() partial.RESTBuilderCallback { + return func(builder serverInt.RESTBuilder) serverInt.RESTBuilder { + ln, err := s.listen("./output/internal.socket") + if err != nil { + panic(err) + } + return builder.SetCustomListener(ln) + } +} + +func (s *Serverless) listen(name string) (net.Listener, error) { + ln, err := net.Listen("unix", name) + if err != nil { + return nil, err + } + // if ln, ok := ln.(*net.UnixListener); ok { + // fp, err := ln.File() + // if err != nil { + // return nil, err + // } + // if err = fp.Sync(); err != nil { + // return nil, err + // } + // } + + return ln, nil +} diff --git a/buf.gen.kit.yaml b/buf.gen.kit.yaml index daea1ae..46bb318 100644 --- a/buf.gen.kit.yaml +++ b/buf.gen.kit.yaml @@ -18,3 +18,9 @@ plugins: - actions=extends - paths=source_relative - Meinride/iam/v1/annotations.proto=go.einride.tech/iam/proto/gen/einride/iam/v1 + # - name: kit + # out: output + # opt: + # - actions=code + # - paths=source_relative + # - Meinride/iam/v1/annotations.proto=go.einride.tech/iam/proto/gen/einride/iam/v1 diff --git a/buf.gen.yaml b/buf.gen.yaml index 84287e7..f2fd1ff 100644 --- a/buf.gen.yaml +++ b/buf.gen.yaml @@ -42,8 +42,10 @@ plugins: - generate_unbound_methods=true - Meinride/iam/v1/annotations.proto=go.einride.tech/iam/proto/gen/einride/iam/v1 - name: openapiv2 - out: genproto + out: ./output + strategy: all opt: - allow_repeated_fields_in_body=true - - use_go_templates=true + - output_format=yaml + - allow_merge=true,merge_file_name=apis - Meinride/iam/v1/annotations.proto=go.einride.tech/iam/proto/gen/einride/iam/v1 diff --git a/cmd/api-scf/main.go b/cmd/api-scf/main.go new file mode 100644 index 0000000..a5dd123 --- /dev/null +++ b/cmd/api-scf/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "github.com/airdb/xadmin-api/app/mortar" + "github.com/go-masonry/mortar/providers" + "go.uber.org/fx" +) + +func main() { + app := createApplication("./config/config.yml", []string{"./config/config_local.yml"}) + app.Run() +} + +func createApplication(configFilePath string, additionalFiles []string) *fx.App { + return fx.New( + // fx.NopLogger, // remove fx debug + mortar.ViperFxOption(configFilePath, additionalFiles...), // Configuration map + mortar.LoggerFxOption(), // Logger + mortar.TracerFxOption(), // Jaeger tracing + mortar.PrometheusFxOption(), // Prometheus + mortar.HttpClientFxOptions(), + mortar.HttpServerFxOptions(), + mortar.InternalHttpHandlersFxOptions(), + // Tutorial service dependencies + mortar.ServicesAPIsAndOtherDependenciesFxOption(), // register tutorial APIs + // This one invokes all the above + mortar.BuildAuthFxInvoke(), + mortar.BuildServerlessFxOption(), // serverless plugin + providers.BuildMortarWebServiceFxOption(), // http server invoker + mortar.InvokeWebServerlessFxOption(), // serverless invoker + ) +} diff --git a/main.go b/cmd/api-server/main.go similarity index 100% rename from main.go rename to cmd/api-server/main.go diff --git a/cmd/protoc-gen-kit/main.go b/cmd/protoc-gen-kit/main.go index e4edd64..eb769dd 100644 --- a/cmd/protoc-gen-kit/main.go +++ b/cmd/protoc-gen-kit/main.go @@ -8,6 +8,7 @@ import ( "path/filepath" "github.com/airdb/xadmin-api/pkg/protockit" + "github.com/airdb/xadmin-api/pkg/protockit/gencode" "github.com/airdb/xadmin-api/pkg/protockit/generror" "github.com/airdb/xadmin-api/pkg/protockit/genextends" "github.com/airdb/xadmin-api/pkg/protockit/util" @@ -26,6 +27,7 @@ func init() { registedProcessort = map[string]util.Processor{ "error": generror.Process, "extends": genextends.Process, + "code": gencode.Process, } } diff --git a/go.mod b/go.mod index eaa0871..75a26e4 100644 --- a/go.mod +++ b/go.mod @@ -2,9 +2,13 @@ module github.com/airdb/xadmin-api go 1.18 +replace github.com/go-masonry/mortar => ../../xqbumu/mortar + require ( github.com/alecthomas/kong v0.5.0 github.com/casdoor/casdoor-go-sdk v0.4.1 + github.com/glebarez/sqlite v1.4.5 + github.com/go-chi/chi/v5 v5.0.7 github.com/go-masonry/bjaeger v1.0.12 github.com/go-masonry/bprometheus v1.0.12 github.com/go-masonry/bviper v1.0.12 @@ -18,6 +22,7 @@ require ( github.com/pseudomuto/protokit v0.2.1 github.com/rs/cors v1.8.2 github.com/samber/lo v1.21.0 + github.com/serverless-plus/tencent-serverless-go v1.0.1 github.com/stretchr/testify v1.7.1 go.uber.org/fx v1.17.1 golang.org/x/text v0.3.7 @@ -26,7 +31,6 @@ require ( google.golang.org/protobuf v1.28.0 gopkg.in/yaml.v3 v3.0.0-20220512140231-539c8e751b99 gorm.io/driver/mysql v1.3.3 - gorm.io/driver/sqlite v1.3.2 gorm.io/gorm v1.23.5 ) @@ -35,13 +39,15 @@ require ( github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/glebarez/go-sqlite v1.17.2 // indirect github.com/go-sql-driver/mysql v1.6.0 // indirect github.com/golang-jwt/jwt/v4 v4.4.1 // indirect + github.com/google/uuid v1.3.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/magiconair/properties v1.8.6 // indirect - github.com/mattn/go-sqlite3 v1.14.13 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.0-beta.8 // indirect @@ -51,6 +57,7 @@ require ( github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.34.0 // indirect github.com/prometheus/procfs v0.7.3 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect github.com/rs/zerolog v1.26.1 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/cast v1.5.0 // indirect @@ -71,4 +78,8 @@ require ( google.golang.org/appengine v1.6.7 // indirect gopkg.in/ini.v1 v1.66.4 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect + modernc.org/libc v1.16.8 // indirect + modernc.org/mathutil v1.4.1 // indirect + modernc.org/memory v1.1.1 // indirect + modernc.org/sqlite v1.17.2 // indirect ) diff --git a/go.sum b/go.sum index a4a7845..0b123df 100644 --- a/go.sum +++ b/go.sum @@ -50,6 +50,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/HdrHistogram/hdrhistogram-go v1.0.1 h1:GX8GAYDuhlFQnI2fRDHQhTlkHMz8bEn0jTI6LJU0mpw= github.com/HdrHistogram/hdrhistogram-go v1.0.1/go.mod h1:BWJ+nMSHY3L41Zj7CA3uXnloDp7xxV0YvstAE7nKTaM= +github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/alecthomas/kong v0.5.0 h1:u8Kdw+eeml93qtMZ04iei0CFYve/WPcA5IFh+9wSskE= github.com/alecthomas/kong v0.5.0/go.mod h1:uzxf/HUh0tj43x1AyJROl3JT7SgsZ5m+icOv1csRhc0= @@ -60,11 +61,16 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= +github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/beego/beego/v2 v2.0.1/go.mod h1:8zyHi1FnWO1mZLwTn62aKRIZF/aIKvkCBB2JYs+eqQI= +github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ= +github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -73,6 +79,8 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= +github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE= github.com/casdoor/casdoor-go-sdk v0.4.1 h1:rCvfmMlxLqSx05kFkDGJ6xh5w4/+mSKny8HA/8JA8Js= github.com/casdoor/casdoor-go-sdk v0.4.1/go.mod h1:MBed3ISHQfXTtoOCAk5T8l5lt4wFvsyynrw0awggydY= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -84,6 +92,7 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -93,12 +102,23 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/coreos/etcd v3.3.25+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U= +github.com/couchbase/gomemcached v0.0.0-20200526233749-ec430f949808/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c= +github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI= +github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -112,10 +132,22 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.7.2/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= +github.com/glebarez/go-sqlite v1.17.2 h1:gyTyFr2RFFQd2gp6fOOdfnTvUn99zwvVOrQFHA4S+DY= +github.com/glebarez/go-sqlite v1.17.2/go.mod h1:lakPjzvnJ6uSIARV+5dPALDuSLL3879PlzHFMEpbceM= +github.com/glebarez/sqlite v1.4.5 h1:oaJupO4X9iTn4sXRvP5Vs15BNvKh9dx5AQfciKlDvV4= +github.com/glebarez/sqlite v1.4.5/go.mod h1:6D+bB+DdXlEC4mO+pUFJWixVcnrHTIAJ9U6Ynnn4Lxk= +github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw= +github.com/go-chi/chi/v5 v5.0.3/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8= +github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -135,9 +167,13 @@ github.com/go-masonry/bviper v1.0.12 h1:wCZk9Ksfy8AiF1QEc05mzm9E/s3pOYLyCzHRy799 github.com/go-masonry/bviper v1.0.12/go.mod h1:KtoKEZqcIAco1T/iaQ57B8i0lX9Vz9o3XRk3WPERe1k= github.com/go-masonry/bzerolog v1.0.12 h1:elbxHSw/lcd4h33W4sGnOSs2yCXw+iWmEmVOyzlKFlo= github.com/go-masonry/bzerolog v1.0.12/go.mod h1:iUJGzilXRqXOpXf4xVtQX0EIAlr6852X+8aBDzFkU2E= -github.com/go-masonry/mortar v1.0.25/go.mod h1:elqpHsoKQLC79/IpIuhKF8VRxZVi67+3NStCYSJ+Ohw= -github.com/go-masonry/mortar v1.0.28 h1:TgRL/MM5rbci0THICSPTg73sq98gaQJCNFvaiq9/lSo= -github.com/go-masonry/mortar v1.0.28/go.mod h1:CsKDQa6HCXf4qgr0zsnN4od8FYkOp1+GX3H69Awb8Mg= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-redis/redis/v7 v7.4.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -145,6 +181,7 @@ github.com/gobeam/stringy v0.0.5 h1:TvxQGSAqr/qF0SBVxa8Q67WWIo7bCWS0bM101WOd52g= github.com/gobeam/stringy v0.0.5/go.mod h1:W3620X9dJHf2FSZF5fRnWekHcHQjwmCz8ZQ2d1qloqE= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.4.1 h1:pC5DB52sCeK48Wlb9oPcdhnjkz1TKt1D/P7WKJ0kUcQ= @@ -183,7 +220,10 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -221,13 +261,16 @@ github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.1/go.mod h1:8ZeZajTed/blCOHBbj8Fss8bPHiFKcmJJzuIbUtFCAo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.0 h1:ESEyqQqXXFIcImj/BE8oKEX37Zsuceb2cZI+EL/zNCY= github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.0/go.mod h1:XnLCLFp3tjoZJszVKjfpyAK6J8sYIcQXWQxmqLWF21I= github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= @@ -246,12 +289,14 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -261,6 +306,7 @@ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= @@ -268,6 +314,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -281,6 +329,9 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6/go.mod h1:n931TsDuKuq+uX4v1fulaMbA/7ZLLhjc85h7chZGBCQ= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= @@ -292,9 +343,10 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.13 h1:1tj15ngiFfcZzii7yd82foL+ks+ouQcj8j/TPq3fk1I= -github.com/mattn/go-sqlite3 v1.14.13/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -304,6 +356,7 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -317,14 +370,30 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M= +github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA= +github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.0-beta.8 h1:dy81yyLYJDwMTifq24Oi/IslOslRrDSb3jwDggjz3Z0= github.com/pelletier/go-toml/v2 v2.0.0-beta.8/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -337,6 +406,7 @@ github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndr github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.7.0/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= @@ -361,6 +431,8 @@ github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/pseudomuto/protokit v0.2.1 h1:kCYpE3thoR6Esm0CUvd5xbrDTOZPvQPTDeyXpZfrJdk= github.com/pseudomuto/protokit v0.2.1/go.mod h1:gt7N5Rz2flBzYafvaxyIxMZC0TTF5jDZfRnw25hAAyo= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= @@ -375,6 +447,12 @@ github.com/sagikazarmark/crypt v0.1.0/go.mod h1:B/mN0msZuINBtQ1zZLEQcegFJJf9vnYI github.com/samber/lo v1.21.0 h1:FSby8pJQtX4KmyddTCCGhc3JvnnIVrDA+NW37rG+7G8= github.com/samber/lo v1.21.0/go.mod h1:2I7tgIv8Q1SG2xEIkRq0F2i2zgxVpnyPOP0d3Gj2r+A= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/serverless-plus/tencent-serverless-go v1.0.1 h1:E3rnNuExs6XWfaj/h5UiaAPXx4ehpR6hbA3FEQ2uEvA= +github.com/serverless-plus/tencent-serverless-go v1.0.1/go.mod h1:FW0SG4pqDY5pcO9b1J+mbFdsZDudLY19HNZrEVxjNSo= +github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg= +github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= +github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKzU3qCuvj/tPnimWSsZZzvk9qvkvrIL5naVBPh5s= +github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= @@ -394,6 +472,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.9.0/go.mod h1:+i6ajR7OX2XaiBkrcZJFK21htRk7eDeLg7+O6bhUPP4= github.com/spf13/viper v1.11.0 h1:7OX/1FS6n7jHD1zGrZTM7WtY13ZELRyosK4k93oPr44= github.com/spf13/viper v1.11.0/go.mod h1:djo0X/bA5+tYVoCn+C7cAYJGcVn/qYLFTG8gdUsX7Zk= +github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -407,18 +486,26 @@ github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMT github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= +github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU= +go.etcd.io/etcd v3.3.25+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= @@ -435,25 +522,22 @@ go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/dig v1.12.0/go.mod h1:X34SnWGr8Fyla9zQNO2GSO2D+TIuqB14OS8JhYocIyw= -go.uber.org/dig v1.13.0/go.mod h1:X34SnWGr8Fyla9zQNO2GSO2D+TIuqB14OS8JhYocIyw= go.uber.org/dig v1.14.0/go.mod h1:jHAn/z1Ld1luVVyGKOAIFYz/uBFqKjjEEdIqVAqfQ2o= go.uber.org/dig v1.14.1 h1:fyakRgZDdi2F8FgwJJoRGangMSPTIxPSLGzR3Oh0/54= go.uber.org/dig v1.14.1/go.mod h1:52EKx/Vjdpz9EzeNcweC4YMsTrDdFn9mS/+Uw5ZnVTI= go.uber.org/fx v1.16.0/go.mod h1:OMoT5BnXcOaiexlpjtpE4vcAmzyDKyRs9TRYXCzamx8= go.uber.org/fx v1.17.1 h1:S42dZ6Pok8hQ3jxKwo6ZMYcCgHQA/wAS/gnpRa1Pksg= go.uber.org/fx v1.17.1/go.mod h1:yO7KN5rhlARljyo4LR047AjaV6J+KFzd/Z7rnTbEn0A= -go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -508,6 +592,7 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -532,10 +617,12 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -548,7 +635,6 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220421235706-1d1ef9303861/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -569,7 +655,6 @@ golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= @@ -588,6 +673,7 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -600,11 +686,15 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -621,6 +711,7 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -652,9 +743,10 @@ golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a h1:N2T1jUrTQE9Re6TFF5PhvEHXHCguynGhKjWVsIUt5cY= @@ -675,6 +767,7 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -722,8 +815,10 @@ golang.org/x/tools v0.0.0-20200806022845-90696ccdc692/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -829,7 +924,6 @@ google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKr google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220317150908-0efb43f6373e/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20220422154200-b37d22cd5731/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3 h1:q1kiSVscqoDeqTF27eQ2NnLLDmqF0I373qQNXYMy0fo= @@ -859,7 +953,6 @@ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.46.2 h1:u+MLGgVf7vRdjEYZ8wDFhAVNmhkbJ5hmrA1LMWK1CAQ= @@ -888,10 +981,14 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4= gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -907,10 +1004,7 @@ gopkg.in/yaml.v3 v3.0.0-20220512140231-539c8e751b99 h1:dbuHpmKjkDzSOMKAWl10QNlga gopkg.in/yaml.v3 v3.0.0-20220512140231-539c8e751b99/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/mysql v1.3.3 h1:jXG9ANrwBc4+bMvBcSl8zCfPBaVoPyBEBshA8dA93X8= gorm.io/driver/mysql v1.3.3/go.mod h1:ChK6AHbHgDCFZyJp0F+BmVGb06PSIoh9uVYKAlRbb2U= -gorm.io/driver/sqlite v1.3.2 h1:nWTy4cE52K6nnMhv23wLmur9Y3qWbZvOBz+V4PrGAxg= -gorm.io/driver/sqlite v1.3.2/go.mod h1:B+8GyC9K7VgzJAcrcXMRPdnMcck+8FgJynEehEPM16U= gorm.io/gorm v1.23.1/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= -gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= gorm.io/gorm v1.23.5 h1:TnlF26wScKSvknUC/Rn8t0NLLM22fypYBlvj1+aH6dM= gorm.io/gorm v1.23.5/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -920,6 +1014,33 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.5/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= +modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= +modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= +modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= +modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= +modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU= +modernc.org/libc v1.16.7/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= +modernc.org/libc v1.16.8 h1:Ux98PaOMvolgoFX/YwusFOHBnanXdGRmWgI8ciI2z4o= +modernc.org/libc v1.16.8/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= +modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8= +modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/memory v1.1.1 h1:bDOL0DIDLQv7bWhP3gMvIrnoFw+Eo6F7a2QK9HPDiFU= +modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sqlite v1.17.2 h1:TjmF36Wi5QcPYqRoAacV1cAyJ7xB/CD0ExpVUEMebnw= +modernc.org/sqlite v1.17.2/go.mod h1:GOQmuiXd6pTTes1Fi2s9apiCcD/wbKQtBZ0Nw6/etjM= +modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= +modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= +modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/output/.gitignore b/output/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/output/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/pkg/protockit/fixtures/library.proto b/pkg/protockit/fixtures/library.proto index d9ef87e..746c835 100644 --- a/pkg/protockit/fixtures/library.proto +++ b/pkg/protockit/fixtures/library.proto @@ -24,6 +24,10 @@ option java_package = "com.github.airdb.xadmin-api.fixtures"; // // - Each Shelf has a collection of [Book][google.example.library.v1.Book] // resources, named `shelves/*/books/*` +// +// @Kit +// gencode: +// layers: ["*"] service LibraryService { option (google.api.default_host) = "library-example.googleapis.com"; @@ -153,7 +157,11 @@ message Book { // - update // tags: // yaml: name - string name = 1; + string name = 1 [ + (annotation.v1.field_option) = { + actions: ["create", "update"], + } + ]; // The name of the book author // diff --git a/pkg/protockit/gencode/gen_controller.go b/pkg/protockit/gencode/gen_controller.go new file mode 100644 index 0000000..492c811 --- /dev/null +++ b/pkg/protockit/gencode/gen_controller.go @@ -0,0 +1,370 @@ +package gencode + +import ( + "fmt" + "path" + "strings" + + "github.com/airdb/xadmin-api/pkg/protockit/util" + "github.com/gobeam/stringy" + "github.com/samber/lo" + "google.golang.org/protobuf/compiler/protogen" + "google.golang.org/protobuf/reflect/protoreflect" +) + +type controllerGenerator struct { + gen *protogen.Plugin + file *protogen.File + service *protogen.Service + name string +} + +func NewControllerGenerator( + gen *protogen.Plugin, + file *protogen.File, + service *protogen.Service, +) *controllerGenerator { + return &controllerGenerator{ + gen: gen, + file: file, + service: service, + } +} + +func (r *controllerGenerator) Run() error { + if r.service.GoName[len(r.service.GoName)-7:] != "Service" { + return fmt.Errorf("%s should end with Service", r.service.GoName) + } + + r.name = strings.ToLower(r.service.GoName[0 : len(r.service.GoName)-7]) + + if len(r.service.Methods) == 0 { + return nil + } + + filename := path.Join("app", "controllers", + stringy.New(r.name).SnakeCase().LcFirst()+`.go`) + + g := r.gen.NewGeneratedFile(filename, controllersPackage) + + g.P("package controllers") + + if err := r.genInterface(g); err != nil { + return err + } + + if err := r.genDeps(g); err != nil { + return err + } + + if err := r.genImpl(g); err != nil { + return err + } + + if err := r.genNew(g); err != nil { + return err + } + + if err := r.genMethods(g); err != nil { + return err + } + + return nil +} + +func (r controllerGenerator) genInterface(g *protogen.GeneratedFile) error { + g.P() + g.P("type ", r.service.GoName, "Controller interface {") + g.P(g.QualifiedGoIdent(r.file.GoImportPath.Ident(r.service.GoName + "Server"))) + g.P("}") + + return nil +} + +func (r controllerGenerator) genDeps(g *protogen.GeneratedFile) error { + entityMethods := map[string][]string{} + for _, method := range r.service.Methods { + ret := reMethod.FindStringSubmatch(method.GoName) + if ret == nil || len(ret) < 1 { + continue + } + name := util.Pluralize.Singular(ret[2]) + if _, ok := entityMethods[name]; ok { + entityMethods[name] = []string{} + } + entityMethods[name] = append(entityMethods[name], name) + } + g.P() + g.P("type ", util.LcFirst(r.service.GoName), "ControllerDeps struct {") + g.P(fxPackage.Ident("In")) + g.P() + g.P("Config ", cfgPackage.Ident("Config")) + g.P("Logger ", logPackage.Ident("Logger")) + g.P("Metrics ", monitorPackage.Ident("Metrics")) + g.P() + for entityMethod := range entityMethods { + g.P(entityMethod+"Repo ", dataPackage.Ident(entityMethod+"Repo")) + } + g.P("}") + + return nil +} + +func (r controllerGenerator) genImpl(g *protogen.GeneratedFile) error { + g.P() + g.P("type ", util.LcFirst(r.service.GoName), "Controller struct {") + g.P(g.QualifiedGoIdent( + r.file.GoImportPath.Ident("Unimplemented" + r.service.GoName + "Server"))) + g.P() + g.P("deps ", util.LcFirst(r.service.GoName)+"ControllerDeps") + g.P("log ", logPackage.Ident("Fields")) + g.P("convert *", r.name+"Convert") + g.P("}") + + return nil +} + +func (r controllerGenerator) genNew(g *protogen.GeneratedFile) error { + g.P() + g.P("func New", r.service.GoName, "Controller(deps ", + util.LcFirst(r.service.GoName), "ControllerDeps) ", + r.service.GoName+"Controller", + " {") + g.P("return &", util.LcFirst(r.service.GoName), "Controller{") + g.P("deps: deps,") + g.P(`log: deps.Logger.WithField("service", "`, r.name, `"),`) + g.P(`convert: new`, util.UcFirst(r.name), "Convert(),") + g.P("}") + g.P("}") + + return nil +} + +func (r controllerGenerator) genMethods(g *protogen.GeneratedFile) error { + g.P() + var methodIndex, streamIndex int + + for _, method := range r.service.Methods { + if !method.Desc.IsStreamingServer() && !method.Desc.IsStreamingClient() { + // Unary RPC method + r.genServiceMethod(g, method, methodIndex) + methodIndex++ + } else { + // Streaming RPC method + r.genServiceMethod(g, method, streamIndex) + streamIndex++ + } + } + + return nil +} + +func (r controllerGenerator) genServiceMethod(g *protogen.GeneratedFile, method *protogen.Method, index int) { + ret := reMethod.FindStringSubmatch(method.GoName) + if ret == nil || len(ret) < 1 { + r.genServiceMethodDefault(g, method, index) + return + } + + switch ret[1] { + case "List": + r.genServiceMethodList(g, method, index) + case "Get": + r.genServiceMethodGet(g, method, index) + case "Create": + r.genServiceMethodCreate(g, method, index) + case "Update": + r.genServiceMethodUpdate(g, method, index) + case "Delete": + r.genServiceMethodDelete(g, method, index) + default: + r.genServiceMethodDefault(g, method, index) + } + + return +} +func (r controllerGenerator) genServiceMethodDefault(g *protogen.GeneratedFile, method *protogen.Method, index int) { + g.P("func (c *", util.LcFirst(r.service.GoName), "Controller) ", + methodSignature(g, method), "{") + g.P("out := new(", method.Output.GoIdent, ")") + g.P("return out, nil") + g.P("}") + g.P() +} + +func (r controllerGenerator) genServiceMethodList(g *protogen.GeneratedFile, method *protogen.Method, index int) { + ret := reMethod.FindStringSubmatch(method.GoName) + entityStr := util.Pluralize.Singular(ret[2]) + repoStr := entityStr + "Repo" + + g.P("func (c *", util.LcFirst(r.service.GoName), "Controller) ", + methodSignature(g, method), "{") + g.P(`c.log.Debug(ctx, "`, method.GoName, ` accepted")`) + g.P() + g.P("total, filtered, err := c.deps.", repoStr+".Count(ctx, in)") + g.P("if err != nil {") + errorListStr := `"` + method.GoName + ` count error"` + g.P("c.log.WithError(err).Debug(ctx, ", errorListStr, ")") + g.P("return nil, ", errorsPackage.Ident("New"), "(", errorListStr, ")") + g.P("}") + g.P("if total == 0 {") + errorEmptyStr := `"` + r.name + "s is empty" + `"` + g.P("return nil, ", errorsPackage.Ident("New"), "(", errorEmptyStr, ")") + g.P("}") + g.P("") + g.P("items, err := c.deps.", repoStr, ".List(ctx, in)") + g.P("if err != nil {") + errorListQuery := `"` + method.GoName + ` error"` + g.P("c.log.WithError(err).Debug(ctx, ", errorListQuery, ")") + g.P("return nil, ", errorsPackage.Ident("New"), "(", errorListQuery, ")") + g.P("}") + g.P("") + r.genOut(g, method.Output, index) + g.P("}") + g.P() + return +} + +func (r controllerGenerator) genServiceMethodGet(g *protogen.GeneratedFile, method *protogen.Method, index int) { + ret := reMethod.FindStringSubmatch(method.GoName) + entityStr := util.Pluralize.Singular(ret[2]) + repoStr := entityStr + "Repo" + + g.P("func (c *", util.LcFirst(r.service.GoName), "Controller) ", + methodSignature(g, method), "{") + g.P(`c.log.Debug(ctx, "`, method.GoName, ` accepted")`) + g.P() + g.P("item, err := c.deps.", repoStr, ".Get(ctx, uint(in.GetId()))") + g.P("if err != nil {") + errorListStr := `"` + method.GoName + ` error"` + g.P("c.log.WithError(err).Debug(ctx, ", errorListStr, ")") + g.P("return nil, ", errorsPackage.Ident("New"), "(", errorListStr, ")") + g.P("}") + g.P("") + r.genOut(g, method.Output, index) + g.P("}") + g.P() + return +} + +func (r controllerGenerator) genServiceMethodCreate(g *protogen.GeneratedFile, method *protogen.Method, index int) { + ret := reMethod.FindStringSubmatch(method.GoName) + entityStr := util.Pluralize.Singular(ret[2]) + repoStr := entityStr + "Repo" + + g.P("func (c *", util.LcFirst(r.service.GoName), "Controller) ", + methodSignature(g, method), "{") + g.P(`c.log.Debug(ctx, "`, method.GoName, ` accepted")`) + g.P() + entityName := util.Pluralize.Singular(entityStr) + convertFuncName := fmt.Sprintf("FromProtoCreate%sToModel%s", entityName, entityName) + g.P("item := c.convert.", convertFuncName, "(in)") + g.P("err := c.deps.", repoStr, ".Create(ctx, item)") + g.P("if err != nil {") + errorListStr := `"` + method.GoName + ` error"` + g.P("c.log.WithError(err).Debug(ctx, ", errorListStr, ")") + g.P("return nil, ", errorsPackage.Ident("New"), "(", errorListStr, ")") + g.P("}") + g.P("") + r.genOut(g, method.Output, index) + g.P("}") + g.P() + return +} + +func (r controllerGenerator) genServiceMethodUpdate(g *protogen.GeneratedFile, method *protogen.Method, index int) { + ret := reMethod.FindStringSubmatch(method.GoName) + entityStr := util.Pluralize.Singular(ret[2]) + repoStr := entityStr + "Repo" + + g.P("func (c *", util.LcFirst(r.service.GoName), "Controller) ", + methodSignature(g, method), "{") + g.P(`c.log.Debug(ctx, "`, method.GoName, ` accepted")`) + g.P() + entityName := util.Pluralize.Singular(entityStr) + convertFuncName := fmt.Sprintf("FromProto%sToModel%s", entityName, entityName) + g.P("data := c.convert.", convertFuncName, "(in.GetItem())") + g.P() + g.P("fm := ", queryKitPackage.Ident("NewField"), + `(in.GetUpdateMask(), in.GetItem()).WithAction("update")`) + g.P() + g.P("err := c.deps.", repoStr, ".Update(ctx, data.ID, data, fm)") + g.P("if err != nil {") + errorStr := `"` + method.GoName + ` failed"` + g.P("c.log.WithError(err).Debug(ctx, ", errorStr, ")") + g.P("return nil, ", errorsPackage.Ident("New"), "(", errorStr, ")") + g.P("}") + g.P("") + g.P("item, err := c.deps.", repoStr, ".Get(ctx, uint(data.ID))") + g.P("if err != nil {") + errorStr = `"` + method.GoName + ` item not exist"` + g.P("c.log.WithError(err).Debug(ctx, ", errorStr, ")") + g.P("return nil, ", errorsPackage.Ident("New"), "(", errorStr, ")") + g.P("}") + g.P("") + r.genOut(g, method.Output, index) + g.P("}") + g.P() + return +} + +func (r controllerGenerator) genServiceMethodDelete(g *protogen.GeneratedFile, method *protogen.Method, index int) { + ret := reMethod.FindStringSubmatch(method.GoName) + entityStr := util.Pluralize.Singular(ret[2]) + repoStr := entityStr + "Repo" + + g.P("func (c *", util.LcFirst(r.service.GoName), "Controller) ", + methodSignature(g, method), "{") + g.P(`c.log.Debug(ctx, "`, method.GoName, ` accepted")`) + g.P() + g.P("err := c.deps.", repoStr, ".Delete(ctx, uint(in.GetId()))") + g.P("if err != nil {") + errorListStr := `"` + method.GoName + ` failed"` + g.P("c.log.WithError(err).Debug(ctx, ", errorListStr, ")") + g.P("return nil, ", errorsPackage.Ident("New"), "(", errorListStr, ")") + g.P("}") + g.P("") + r.genOut(g, method.Output, index) + g.P("}") + g.P() + return +} + +func (r controllerGenerator) genOut(g *protogen.GeneratedFile, msg *protogen.Message, index int) { + ret := reInOut.FindStringSubmatch(msg.GoIdent.GoName) + if ret == nil { + if strings.Contains(msg.GoIdent.GoImportPath.String(), "genproto") { + entityName := util.Pluralize.Singular(msg.GoIdent.GoName) + convertFuncName := fmt.Sprintf("FromModel%sToProto%s", entityName, entityName) + g.P("return ", "c.convert.", convertFuncName, "(item), nil") + return + } + g.P("return &", g.QualifiedGoIdent(msg.GoIdent), "{}, nil") + return + } + + g.P("return &", g.QualifiedGoIdent(msg.GoIdent), "{") + intKinds := []protoreflect.Kind{protoreflect.Int32Kind, protoreflect.Int64Kind} + for _, field := range msg.Fields { + if field.Desc.IsList() { + entityName := util.Pluralize.Plural(field.Message.GoIdent.GoName) + convertFuncName := fmt.Sprintf("FromModel%sToProto%s", entityName, entityName) + g.P(field.GoName, ": c.convert.", convertFuncName, "(items),") + } else if lo.Contains(intKinds, field.Desc.Kind()) { + switch field.GoName { + case "TotalSize": + g.P(field.GoName, ": total,") + continue + case "FilteredSize": + g.P(field.GoName, ": filtered,") + continue + } + } else if field.Desc.Kind() == protoreflect.MessageKind { + entityName := util.Pluralize.Singular(field.Message.GoIdent.GoName) + convertFuncName := fmt.Sprintf("FromModel%sToProto%s", entityName, entityName) + g.P(field.GoName, ": c.convert.", convertFuncName, "(item),") + continue + } + } + g.P("}, nil") +} diff --git a/pkg/protockit/gencode/gen_converter.go b/pkg/protockit/gencode/gen_converter.go new file mode 100644 index 0000000..e9f0f43 --- /dev/null +++ b/pkg/protockit/gencode/gen_converter.go @@ -0,0 +1,200 @@ +package gencode + +import ( + "fmt" + "path" + "regexp" + "strings" + + "github.com/airdb/xadmin-api/pkg/protockit/util" + "github.com/gobeam/stringy" + "google.golang.org/protobuf/compiler/protogen" +) + +type converterGenerator struct { + gen *protogen.Plugin + file *protogen.File + service *protogen.Service + name string + reMethod *regexp.Regexp + reInOut *regexp.Regexp +} + +func NewConverterGenerator( + gen *protogen.Plugin, + file *protogen.File, + service *protogen.Service, +) *converterGenerator { + return &converterGenerator{ + gen: gen, + file: file, + service: service, + reMethod: regexp.MustCompile( + fmt.Sprintf(`^(%s)([A-Z].*)$`, strings.Join(actionsWords, "|")), + ), + reInOut: regexp.MustCompile(`^([A-Z].*)(Request|Response)$`), + } +} + +func (r *converterGenerator) Run() error { + r.name = strings.ToLower(r.service.GoName[0 : len(r.service.GoName)-7]) + + if len(r.service.Methods) == 0 { + return nil + } + + filename := path.Join("app", "controllers", + stringy.New(r.name).SnakeCase().LcFirst()+`_converter.go`) + + g := r.gen.NewGeneratedFile(filename, controllersPackage) + + g.P("package controllers") + + if err := r.genImpl(g); err != nil { + return err + } + + if err := r.genNew(g); err != nil { + return err + } + + if err := r.genMethods(g); err != nil { + return err + } + + return nil +} + +func (r converterGenerator) genImpl(g *protogen.GeneratedFile) error { + g.P() + g.P("type ", util.LcFirst(r.name), "Convert struct {") + g.P("}") + + return nil +} + +func (r converterGenerator) genNew(g *protogen.GeneratedFile) error { + g.P() + g.P("func new", util.UcFirst(r.name), "Convert() *", + r.name+"Convert", + " {") + g.P("return &", util.LcFirst(r.name), "Convert{") + g.P("}") + g.P("}") + + return nil +} + +func (r converterGenerator) genMethods(g *protogen.GeneratedFile) error { + g.P() + createMsg := findCreateRequest(r.service) + for _, entity := range guessEntity(r.service) { + r.genConvertProtoToModel(g, entity) + if createMsg != nil { + r.genConvertProtoCreateToModel(g, entity, createMsg) + } + } + + return nil +} + +func (r converterGenerator) genConvertProtoToModel( + g *protogen.GeneratedFile, entity *protogen.Message, +) { + protoIdent := g.QualifiedGoIdent(entity.GoIdent) + modelIdent := g.QualifiedGoIdent(dataPackage.Ident( + entity.GoIdent.GoName + "Entity")) + + pmFunc := fmt.Sprintf("FromProto%sToModel%s", + entity.GoIdent.GoName, entity.GoIdent.GoName) + pmSign := pmFunc + pmSign += "(in *" + protoIdent + pmSign += ") *" + modelIdent + + g.P("func (c ", util.LcFirst(r.name), "Convert) ", pmSign, "{") + g.P("if in == nil {") + g.P("return nil") + g.P("}") + g.P("") + g.P("return &", modelIdent, "{}") + g.P("}") + g.P() + + pmsSign := fmt.Sprintf("FromProto%sToModel%s", + util.Pluralize.Plural(entity.GoIdent.GoName), + util.Pluralize.Plural(entity.GoIdent.GoName)) + pmsSign += "(in []*" + protoIdent + pmsSign += ") []*" + modelIdent + + g.P("func (c ", util.LcFirst(r.name), "Convert) ", pmsSign, "{") + g.P("if in == nil || len(in) == 0 {") + g.P("return nil") + g.P("}") + g.P("") + g.P("res := make([]*", modelIdent, ", len(in))") + g.P("for i := 0; i < len(in); i++ {") + g.P("res[i] = c.", pmFunc, "(in[i])") + g.P("}") + g.P("") + g.P("return res") + g.P("}") + g.P() + + mpFunc := fmt.Sprintf("FromModel%sToProto%s", + entity.GoIdent.GoName, entity.GoIdent.GoName) + mpSign := mpFunc + mpSign += "(in *" + modelIdent + mpSign += ") *" + protoIdent + + g.P("func (c ", util.LcFirst(r.name), "Convert) ", mpSign, "{") + g.P("if in == nil {") + g.P("return nil") + g.P("}") + g.P("") + g.P("return &", protoIdent, "{}") + g.P("}") + g.P() + + mpsSign := fmt.Sprintf("FromModel%sToProto%s", + util.Pluralize.Plural(entity.GoIdent.GoName), + util.Pluralize.Plural(entity.GoIdent.GoName)) + mpsSign += "(in []*" + modelIdent + mpsSign += ") []*" + protoIdent + + g.P("func (c ", util.LcFirst(r.name), "Convert) ", mpsSign, "{") + g.P("if in == nil || len(in) == 0 {") + g.P("return nil") + g.P("}") + g.P("") + g.P("res := make([]*", protoIdent, ", len(in))") + g.P("for i := 0; i < len(in); i++ {") + g.P("res[i] = c.", mpFunc, "(in[i])") + g.P("}") + g.P("return res") + g.P("") + g.P("}") + g.P() +} + +func (r converterGenerator) genConvertProtoCreateToModel( + g *protogen.GeneratedFile, entity *protogen.Message, create *protogen.Message, +) { + modelIdent := g.QualifiedGoIdent(dataPackage.Ident( + entity.GoIdent.GoName + "Entity")) + createIdent := g.QualifiedGoIdent(create.GoIdent) + + pmCreateFunc := fmt.Sprintf("FromProtoCreate%sToModel%s", + entity.GoIdent.GoName, entity.GoIdent.GoName) + pmCreateSign := pmCreateFunc + pmCreateSign += "(in *" + createIdent + pmCreateSign += ") *" + modelIdent + + g.P("func (c ", util.LcFirst(r.name), "Convert) ", pmCreateSign, "{") + g.P("if in == nil {") + g.P("return nil") + g.P("}") + g.P("") + g.P("return &", modelIdent, "{}") + g.P("}") + g.P() +} diff --git a/pkg/protockit/gencode/gen_repo.go b/pkg/protockit/gencode/gen_repo.go new file mode 100644 index 0000000..812c9f0 --- /dev/null +++ b/pkg/protockit/gencode/gen_repo.go @@ -0,0 +1,117 @@ +package gencode + +import ( + "path" + "strings" + + "github.com/airdb/xadmin-api/pkg/protockit/util" + "github.com/gobeam/stringy" + "google.golang.org/protobuf/compiler/protogen" +) + +type repoGenerator struct { + gen *protogen.Plugin + file *protogen.File + message *protogen.Message + name string +} + +func NewRepoGenerator( + gen *protogen.Plugin, + file *protogen.File, + message *protogen.Message, +) *repoGenerator { + return &repoGenerator{ + gen: gen, + file: file, + message: message, + } +} + +func (r *repoGenerator) Run() error { + r.name = strings.ToLower(r.message.GoIdent.GoName) + + filename := path.Join("app", "data", + stringy.New(r.message.GoIdent.GoName).SnakeCase().LcFirst()+`.go`) + g := r.gen.NewGeneratedFile(filename, dataPackage) + + g.P("package data") + + if err := r.genInterface(g); err != nil { + return err + } + + if err := r.genDeps(g); err != nil { + return err + } + + if err := r.genImpl(g); err != nil { + return err + } + + if err := r.genNew(g); err != nil { + return err + } + + return nil +} + +func (r repoGenerator) genInterface(g *protogen.GeneratedFile) error { + g.P() + g.P("type ", r.message.GoIdent.GoName, "Repo interface {") + g.P(g.QualifiedGoIdent(repoPackage.Ident("Repo")), + r.genericSignature(g)) + g.P("}") + + return nil +} + +func (r repoGenerator) genDeps(g *protogen.GeneratedFile) error { + g.P() + g.P("type ", util.LcFirst(r.message.GoIdent.GoName), "RepoDeps struct {") + g.P(fxPackage.Ident("In")) + g.P("}") + + return nil +} + +func (r repoGenerator) genImpl(g *protogen.GeneratedFile) error { + g.P() + g.P("type ", util.LcFirst(r.message.GoIdent.GoName), "Repo struct {") + g.P("*", g.QualifiedGoIdent(repoKitPackage.Ident("Repo")), + r.genericSignature(g)) + g.P() + g.P("deps ", util.LcFirst(r.message.GoIdent.GoName), "RepoDeps") + g.P("}") + + return nil +} + +func (r repoGenerator) genNew(g *protogen.GeneratedFile) error { + g.P() + g.P("func New", r.message.GoIdent.GoName, + "Repo(deps ", util.LcFirst(r.message.GoIdent.GoName), "RepoDeps) ", + r.message.GoIdent.GoName+"Repo {") + g.P("repo := ", util.LcFirst(r.message.GoIdent.GoName), "Repo {") + g.P("deps: deps,") + g.P("}") + g.P("repo.Repo = ", + repoKitPackage.Ident("NewRepo"), r.genericSignature(g)) + g.P() + g.P("return repo") + g.P("}") + + return nil +} + +func (r repoGenerator) genericSignature(g *protogen.GeneratedFile) string { + s := "[" + s += g.QualifiedGoIdent( + dataPackage.Ident(r.message.GoIdent.GoName + "Entity")) + s += ", uint, " + s += g.QualifiedGoIdent(r.file.GoImportPath.Ident( + "List" + util.Pluralize.Plural(r.message.GoIdent.GoName) + "Request")) + s += "]" + + return s +} diff --git a/pkg/protockit/gencode/gen_service.go b/pkg/protockit/gencode/gen_service.go new file mode 100644 index 0000000..b28904e --- /dev/null +++ b/pkg/protockit/gencode/gen_service.go @@ -0,0 +1,129 @@ +package gencode + +import ( + "path" + "strings" + + "github.com/airdb/xadmin-api/pkg/protockit/util" + "github.com/gobeam/stringy" + "google.golang.org/protobuf/compiler/protogen" +) + +type serviceGenerator struct { + gen *protogen.Plugin + file *protogen.File + service *protogen.Service + name string +} + +func NewServiceGenerator( + gen *protogen.Plugin, + file *protogen.File, + service *protogen.Service, +) *serviceGenerator { + return &serviceGenerator{ + gen: gen, + file: file, + service: service, + } +} + +func (r *serviceGenerator) Run() error { + r.name = strings.ToLower(r.service.GoName[0 : len(r.service.GoName)-7]) + + if len(r.service.Methods) == 0 { + return nil + } + + filename := path.Join("app", "services", + stringy.New(r.name).SnakeCase().LcFirst()+`.go`) + g := r.gen.NewGeneratedFile(filename, servicesPackage) + + g.P("package services") + + if err := r.genDeps(g); err != nil { + return err + } + + if err := r.genImpl(g); err != nil { + return err + } + + if err := r.genNew(g); err != nil { + return err + } + + if err := r.genMethods(g); err != nil { + return err + } + + return nil +} + +func (r serviceGenerator) genDeps(g *protogen.GeneratedFile) error { + g.P() + g.P("type ", util.LcFirst(r.service.GoName), "Deps struct {") + g.P(fxPackage.Ident("In")) + g.P() + g.P("Config ", cfgPackage.Ident("Config")) + g.P("Logger ", logPackage.Ident("Logger")) + g.P("Metrics ", monitorPackage.Ident("Metrics")) + g.P("}") + + return nil +} + +func (r serviceGenerator) genImpl(g *protogen.GeneratedFile) error { + g.P() + g.P("type ", r.name, "Impl struct {") + g.P("*", g.QualifiedGoIdent( + r.file.GoImportPath.Ident("Unimplemented"+r.service.GoName+"Server"))) + g.P() + g.P("deps ", util.LcFirst(r.service.GoName)+"Deps") + g.P("log ", logPackage.Ident("Fields")) + g.P("}") + + return nil +} + +func (r serviceGenerator) genNew(g *protogen.GeneratedFile) error { + g.P() + g.P("func Create", r.service.GoName, "Server(deps ", util.LcFirst(r.service.GoName), "Deps) ", + g.QualifiedGoIdent(r.file.GoImportPath.Ident(r.service.GoName+"Server")), + " {") + g.P("return &", r.name, "Impl{") + g.P("deps: deps,") + g.P(`log: deps.Logger.WithField("service", "`, r.name, `"),`) + g.P("}") + g.P("}") + + return nil +} + +func (r serviceGenerator) genMethods(g *protogen.GeneratedFile) error { + g.P() + var methodIndex, streamIndex int + + for _, method := range r.service.Methods { + if !method.Desc.IsStreamingServer() && !method.Desc.IsStreamingClient() { + // Unary RPC method + r.genServiceMethod(g, method, methodIndex) + methodIndex++ + } else { + // Streaming RPC method + r.genServiceMethod(g, method, streamIndex) + streamIndex++ + } + } + + return nil +} + +func (r serviceGenerator) genServiceMethod(g *protogen.GeneratedFile, method *protogen.Method, index int) { + g.P("func (c *", r.name, "Impl) ", methodSignature(g, method), "{") + g.P("out := new(", method.Output.GoIdent, ")") + g.P("return out, nil") + g.P("}") + g.P() + return +} diff --git a/pkg/protockit/gencode/gen_validation.go b/pkg/protockit/gencode/gen_validation.go new file mode 100644 index 0000000..f6aad87 --- /dev/null +++ b/pkg/protockit/gencode/gen_validation.go @@ -0,0 +1,119 @@ +package gencode + +import ( + "path" + "strings" + + "github.com/airdb/xadmin-api/pkg/protockit/util" + "github.com/gobeam/stringy" + "google.golang.org/protobuf/compiler/protogen" +) + +type validationGenerator struct { + gen *protogen.Plugin + file *protogen.File + service *protogen.Service + name string +} + +func NewValidationGenerator( + gen *protogen.Plugin, + file *protogen.File, + service *protogen.Service, +) *validationGenerator { + return &validationGenerator{ + gen: gen, + file: file, + service: service, + } +} + +func (r *validationGenerator) Run() error { + r.name = strings.ToLower(r.service.GoName[0 : len(r.service.GoName)-7]) + + if len(r.service.Methods) == 0 { + return nil + } + + filename := path.Join("app", "validations", + stringy.New(r.name).SnakeCase().LcFirst()+`.go`) + g := r.gen.NewGeneratedFile(filename, validationsPackage) + + g.P("package validations") + + if err := r.genInterface(g); err != nil { + return err + } + + if err := r.genImpl(g); err != nil { + return err + } + + if err := r.genNew(g); err != nil { + return err + } + + if err := r.genMethods(g); err != nil { + return err + } + + return nil +} + +func (r validationGenerator) genInterface(g *protogen.GeneratedFile) error { + g.P() + g.P("type ", util.UcFirst(r.service.GoName), "Validations interface {") + for _, method := range r.service.Methods { + g.P(validationMethodSignature(g, method)) + } + g.P("}") + + return nil +} + +func (r validationGenerator) genImpl(g *protogen.GeneratedFile) error { + g.P() + g.P("type ", util.LcFirst(r.service.GoName), "Validations struct {") + g.P("}") + + return nil +} + +func (r validationGenerator) genNew(g *protogen.GeneratedFile) error { + g.P() + g.P("func New", r.service.GoName, "Validations() ", + r.service.GoName+"Validations", + " {") + g.P("return new(", util.LcFirst(r.service.GoName), "Validations)") + g.P("}") + + return nil +} + +func (r validationGenerator) genMethods(g *protogen.GeneratedFile) error { + g.P() + var methodIndex, streamIndex int + + for _, method := range r.service.Methods { + if !method.Desc.IsStreamingServer() && !method.Desc.IsStreamingClient() { + // Unary RPC method + r.genServiceMethod(g, method, methodIndex) + methodIndex++ + } else { + // Streaming RPC method + r.genServiceMethod(g, method, streamIndex) + streamIndex++ + } + } + + return nil +} + +func (r validationGenerator) genServiceMethod(g *protogen.GeneratedFile, method *protogen.Method, index int) { + g.P("func (c *", util.LcFirst(r.service.GoName), "Validations) ", + validationMethodSignature(g, method), "{") + g.P("return nil") + g.P("}") + g.P() + return +} diff --git a/pkg/protockit/gencode/generator.go b/pkg/protockit/gencode/generator.go new file mode 100644 index 0000000..324e7e5 --- /dev/null +++ b/pkg/protockit/gencode/generator.go @@ -0,0 +1,124 @@ +package gencode + +import ( + "fmt" + "log" + "regexp" + "strings" + + annov1 "github.com/airdb/xadmin-api/genproto/annotation/v1" + "github.com/airdb/xadmin-api/pkg/protockit/util" + "github.com/samber/lo" + "google.golang.org/protobuf/compiler/protogen" + "google.golang.org/protobuf/reflect/protoreflect" +) + +const ( + contextPackage = protogen.GoImportPath("context") + errorsPackage = protogen.GoImportPath("errors") + fxPackage = protogen.GoImportPath("go.uber.org/fx") + cfgPackage = protogen.GoImportPath("github.com/go-masonry/mortar/interfaces/cfg") + logPackage = protogen.GoImportPath("github.com/go-masonry/mortar/interfaces/log") + monitorPackage = protogen.GoImportPath("github.com/go-masonry/mortar/interfaces/monitor") +) + +var ( + repoPackage protogen.GoImportPath + repoKitPackage protogen.GoImportPath + queryKitPackage protogen.GoImportPath + dataPackage protogen.GoImportPath + validationsPackage protogen.GoImportPath + controllersPackage protogen.GoImportPath + servicesPackage protogen.GoImportPath +) + +var ( + actionsWords = []string{"List", "Get", "Create", "Update", "Delete"} + reMethod = regexp.MustCompile( + fmt.Sprintf(`^(%s)([A-Z].*)$`, strings.Join(actionsWords, "|")), + ) + reInOut = regexp.MustCompile(`^([A-Z].*)(Request|Response)$`) +) + +func guessGoimportPath(s string, dirs ...string) protogen.GoImportPath { + segs := []string{} + for _, seg := range strings.Split(strings.Trim(s, "\""), "/") { + if seg == "genproto" { + break + } + segs = append(segs, seg) + } + + segs = append(segs, dirs...) + + return protogen.GoImportPath(strings.Join(segs, "/")) +} + +func methodSignature(g *protogen.GeneratedFile, method *protogen.Method) string { + s := method.GoName + "(ctx " + g.QualifiedGoIdent(contextPackage.Ident("Context")) + s += ", in *" + g.QualifiedGoIdent(method.Input.GoIdent) + s += ") (" + s += "*" + g.QualifiedGoIdent(method.Output.GoIdent) + s += ", error)" + return s +} + +func validationMethodSignature(g *protogen.GeneratedFile, method *protogen.Method) string { + s := method.GoName + "(ctx " + g.QualifiedGoIdent(contextPackage.Ident("Context")) + s += ", in *" + g.QualifiedGoIdent(method.Input.GoIdent) + s += ") error" + return s +} + +func guessEntity(service *protogen.Service) []*protogen.Message { + entities := []*protogen.Message{} + for _, method := range service.Methods { + retMethod := reMethod.FindStringSubmatch(method.GoName) + if retMethod == nil || len(retMethod) < 1 { + continue + } + if !lo.Contains([]string{"Get"}, retMethod[1]) { + continue + } + + retOutput := reInOut.FindStringSubmatch(method.Output.GoIdent.GoName) + if retOutput == nil { + entities = append(entities, method.Output) + continue + } + if len(retOutput) != 3 { + continue + } + for _, field := range method.Output.Fields { + option, err := util.KitParser[annov1.FieldDescriptor]( + service.Comments.Leading.String()) + if err != nil { + log.Printf("can not parse %s kit option: (%s)", service.GoName, err) + } + if util.KitGencodeLayerEmpty(&option) { + continue + } + if field.Desc.Kind() == protoreflect.MessageKind { + entities = append(entities, field.Message) + } + } + } + + return entities +} + +func findCreateRequest(service *protogen.Service) *protogen.Message { + for _, method := range service.Methods { + retMethod := reMethod.FindStringSubmatch(method.GoName) + if retMethod == nil || len(retMethod) < 1 { + continue + } + if !lo.Contains([]string{"Create"}, retMethod[1]) { + continue + } + + return method.Input + } + + return nil +} diff --git a/pkg/protockit/gencode/plugin.go b/pkg/protockit/gencode/plugin.go new file mode 100644 index 0000000..0ce235e --- /dev/null +++ b/pkg/protockit/gencode/plugin.go @@ -0,0 +1,95 @@ +package gencode + +import ( + "context" + "fmt" + "log" + + annov1 "github.com/airdb/xadmin-api/genproto/annotation/v1" + "github.com/airdb/xadmin-api/pkg/protockit/util" + "google.golang.org/protobuf/compiler/protogen" +) + +func Process(ctx context.Context, file *protogen.File) (context.Context, error) { + gen := util.FromContextGen(ctx) + if gen == nil { + panic("plugin not in context") + } + + repoPackage = protogen.GoImportPath( + guessGoimportPath(file.GoImportPath.String(), "pkg", "interfaces", "repo")) + repoKitPackage = protogen.GoImportPath( + guessGoimportPath(file.GoImportPath.String(), "pkg", "repoKit")) + queryKitPackage = protogen.GoImportPath( + guessGoimportPath(file.GoImportPath.String(), "pkg", "querykit")) + dataPackage = protogen.GoImportPath( + guessGoimportPath(file.GoImportPath.String(), "app", "data")) + validationsPackage = protogen.GoImportPath( + guessGoimportPath(file.GoImportPath.String(), "app", "validations")) + controllersPackage = protogen.GoImportPath( + guessGoimportPath(file.GoImportPath.String(), "app", "controllers")) + servicesPackage = protogen.GoImportPath( + guessGoimportPath(file.GoImportPath.String(), "app", "services")) + + services := map[*protogen.Service]*annov1.MessageDescriptor{} + entiryNames := []string{} + entiryMessages := []*protogen.Message{} + + for _, service := range file.Services { + option, err := util.KitParser[annov1.MessageDescriptor]( + service.Comments.Leading.String()) + if err != nil { + log.Printf("can not parse %s kit option: (%s)", service.GoName, err) + } + if !util.KitGencodeValid(&option) { + continue + } + if service.GoName[len(service.GoName)-7:] != "Service" { + return ctx, fmt.Errorf("%s should end with Service", service.GoName) + } + + services[service] = &option + + if util.KitGencodeLayerValid(&option, "*", "repo") { + entities := guessEntity(service) + entiryMessages = append(entiryMessages, entities...) + for _, entity := range entities { + option, err := util.KitParser[annov1.MessageDescriptor]( + entity.Comments.Leading.String()) + if err != nil { + log.Printf("can not parse %s kit option: (%s)", entity.GoIdent.GoName, err) + } + if util.KitGencodeLayerEmpty(&option) { + continue + } + entiryNames = append(entiryNames, entity.GoIdent.GoName) + } + } + } + + var rangeErr error + for _, entity := range entiryMessages { + if err := NewRepoGenerator(gen, file, entity).Run(); err != nil { + rangeErr = err + } + } + + for service := range services { + if err := NewValidationGenerator(gen, file, service).Run(); err != nil { + rangeErr = err + } + if err := NewControllerGenerator(gen, file, service).Run(); err != nil { + rangeErr = err + } + if err := NewConverterGenerator(gen, file, service).Run(); err != nil { + rangeErr = err + } + if err := NewServiceGenerator(gen, file, service).Run(); err != nil { + rangeErr = err + } + } + if rangeErr != nil { + return ctx, rangeErr + } + return ctx, nil +} diff --git a/pkg/protockit/generror/plugin.go b/pkg/protockit/generror/plugin.go index 5013cb0..aff7c09 100644 --- a/pkg/protockit/generror/plugin.go +++ b/pkg/protockit/generror/plugin.go @@ -42,12 +42,12 @@ func RangeEnumCodeDescriptorsInFile( option *annov1.ErrorEnumCodeDescriptor, opts map[string]*annov1.ErrorEnumValueDescriptor) bool, ) { - option, err := util.ParseComment[*annov1.ErrorEnumCodeDescriptor]( + option, err := util.KitParser[*annov1.ErrorEnumCodeDescriptor]( enum.Comments.Leading.String()) if err != nil { option = &annov1.ErrorEnumCodeDescriptor{} } - if option.Category != "error" { + if err != nil || option == nil || option.Category != "error" { return } if option.DefaultHttpCode == 0 { @@ -59,7 +59,7 @@ func RangeEnumCodeDescriptorsInFile( opts := map[string]*annov1.ErrorEnumValueDescriptor{} for _, value := range enum.Values { - opt, err := util.ParseComment[*annov1.ErrorEnumValueDescriptor]( + opt, err := util.KitParser[*annov1.ErrorEnumValueDescriptor]( value.Comments.Leading.String()) if err != nil { panic(err) diff --git a/pkg/protockit/genextends/plugin_message.go b/pkg/protockit/genextends/plugin_message.go index c6913de..00a4bb7 100644 --- a/pkg/protockit/genextends/plugin_message.go +++ b/pkg/protockit/genextends/plugin_message.go @@ -40,7 +40,7 @@ func RangeFieldDescriptorsInMessage( return } - option, err := util.ParseComment[*annov1.MessageDescriptor]( + option, err := util.KitParser[*annov1.MessageDescriptor]( message.Comments.Leading.String()) if err != nil || option == nil { option = &annov1.MessageDescriptor{} @@ -51,7 +51,7 @@ func RangeFieldDescriptorsInMessage( opts := map[string]*annov1.FieldDescriptor{} for _, field := range message.Fields { - opt, err := util.ParseComment[*annov1.FieldDescriptor]( + opt, err := util.KitParser[*annov1.FieldDescriptor]( field.Comments.Leading.String()) if err != nil || opt == nil { opt = &annov1.FieldDescriptor{} diff --git a/pkg/protockit/gentags/plugin.go b/pkg/protockit/gentags/plugin.go index c8d344f..80feee9 100644 --- a/pkg/protockit/gentags/plugin.go +++ b/pkg/protockit/gentags/plugin.go @@ -180,7 +180,7 @@ func (v visitor) Visit(node ast.Node) ast.Visitor { }) // parse comment - opt, err := util.ParseComment[*annov1.FieldDescriptor](docs.String()) + opt, err := util.KitParser[*annov1.FieldDescriptor](docs.String()) if err != nil { break } diff --git a/pkg/protockit/run_test.go b/pkg/protockit/run_test.go index 265425b..bfeaada 100644 --- a/pkg/protockit/run_test.go +++ b/pkg/protockit/run_test.go @@ -2,38 +2,74 @@ package protockit_test import ( "context" + "log" "testing" . "github.com/airdb/xadmin-api/pkg/protockit" + "github.com/airdb/xadmin-api/pkg/protockit/gencode" "github.com/airdb/xadmin-api/pkg/protockit/generror" "github.com/airdb/xadmin-api/pkg/protockit/genextends" "github.com/airdb/xadmin-api/pkg/protockit/tests" "github.com/airdb/xadmin-api/pkg/protockit/util" - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/compiler/protogen" + "github.com/stretchr/testify/assert" ) -func TestRunCode(t *testing.T) { +func TestRunTags(t *testing.T) { plugin, err := tests.NewPlugin("code.proto") - require.NoError(t, err) - - err = New(context.Background(), map[string]util.Processor{ - "test": func(ctx context.Context, file *protogen.File) (context.Context, error) { - return ctx, nil - }, - }).Run(plugin) - require.NoError(t, err) + assert.Nil(t, err) + + registedProcessort := map[string]util.Processor{ + "tags": generror.Process, + } + + err = New(context.Background(), registedProcessort).Run(plugin) + assert.Nil(t, err) +} + +func TestRunError(t *testing.T) { + plugin, err := tests.NewPlugin("library.proto") + assert.Nil(t, err) + + registedProcessort := map[string]util.Processor{ + "error": generror.Process, + } + + err = New(context.Background(), registedProcessort).Run(plugin) + assert.Nil(t, err) } -func TestRunLibrary(t *testing.T) { +func TestRunExtends(t *testing.T) { plugin, err := tests.NewPlugin("library.proto") - require.NoError(t, err) + assert.Nil(t, err) registedProcessort := map[string]util.Processor{ - "error": generror.Process, "extends": genextends.Process, } err = New(context.Background(), registedProcessort).Run(plugin) - require.NoError(t, err) + assert.Nil(t, err) +} + +func TestRunCode(t *testing.T) { + plugin, err := tests.NewPlugin("library.proto") + assert.Nil(t, err) + + registedProcessort := map[string]util.Processor{ + "code": gencode.Process, + } + + err = New(context.Background(), registedProcessort).Run(plugin) + assert.Nil(t, err) + + response := plugin.Response() + assert.Nil(t, response.Error) + if response.Error != nil { + log.Println(*response.Error) + } + + assert.Greater(t, len(response.File), 0) + + if len(response.File) > 0 { + log.Println(*response.File[0].Content) + } } diff --git a/pkg/protockit/util/parser.go b/pkg/protockit/util/kit_helper.go similarity index 56% rename from pkg/protockit/util/parser.go rename to pkg/protockit/util/kit_helper.go index ec7bea4..eed48f1 100644 --- a/pkg/protockit/util/parser.go +++ b/pkg/protockit/util/kit_helper.go @@ -6,12 +6,18 @@ import ( "net/url" "strings" + annov1 "github.com/airdb/xadmin-api/genproto/annotation/v1" + "github.com/samber/lo" "gopkg.in/yaml.v3" ) const beginSymbol = `@Kit` -func ParseComment[T any](docs string) (T, error) { +type GetGencodeInterface interface { + GetGencode() *annov1.GencodeOption +} + +func KitParser[T any](docs string) (T, error) { var stared bool buf := bytes.NewBufferString(docs) data := bytes.NewBuffer(nil) @@ -39,6 +45,19 @@ func ParseComment[T any](docs string) (T, error) { return dest, err } +func KitGencodeValid(message GetGencodeInterface) bool { + return message.GetGencode() != nil && message.GetGencode().Layers != nil +} + +func KitGencodeLayerEmpty(message GetGencodeInterface) bool { + return KitGencodeValid(message) && len(message.GetGencode().Layers) == 0 +} + +func KitGencodeLayerValid(message GetGencodeInterface, layers ...string) bool { + return KitGencodeValid(message) && + len(lo.Intersect(message.GetGencode().Layers, layers)) > 0 +} + func ParseParameter(s string) url.Values { res := url.Values{} for _, item := range strings.Split(s, ",") { diff --git a/pkg/protockit/util/pluralize.go b/pkg/protockit/util/pluralize.go new file mode 100644 index 0000000..1d851e2 --- /dev/null +++ b/pkg/protockit/util/pluralize.go @@ -0,0 +1,503 @@ +// Refer: https://github.com/gertd/go-pluralize +package util + +import ( + "fmt" + "regexp" + "strconv" + "strings" +) + +var Pluralize = NewPluralize() + +// PluralizeRule -- pluralize rule expression and replacement value. +type PluralizeRule struct { + expression *regexp.Regexp + replacement string +} + +// pluralize -- pluralize client. +type pluralize struct { + pluralRules []PluralizeRule + singularRules []PluralizeRule + uncountables map[string]bool + irregularSingles map[string]string + irregularPlurals map[string]string + interpolateExpr *regexp.Regexp +} + +// NewPluralize - pluralization client factory method. +func NewPluralize() *pluralize { + client := pluralize{} + client.init() + + return &client +} + +func (c *pluralize) init() { + c.pluralRules = make([]PluralizeRule, 0) + c.singularRules = make([]PluralizeRule, 0) + c.uncountables = make(map[string]bool) + c.irregularSingles = make(map[string]string) + c.irregularPlurals = make(map[string]string) + + c.loadIrregularRules() + c.loadPluralizationRules() + c.loadSingularizationRules() + c.loadUncountableRules() + c.interpolateExpr = regexp.MustCompile(`\$(\d{1,2})`) +} + +// Pluralize -- Pluralize or singularize a word based on the passed in count. +// word: the word to pluralize +// count: how many of the word exist +// inclusive: whether to prefix with the number (e.g. 3 ducks) +func (c *pluralize) Pluralize(word string, count int, inclusive bool) string { + pluralized := func() func(string) string { + if count == 1 { + return c.Singular + } + + return c.Plural + } + + if inclusive { + return fmt.Sprintf("%d %s", count, pluralized()(word)) + } + + return pluralized()(word) +} + +// Plural -- Pluralize a word. +func (c *pluralize) Plural(word string) string { + return c.replaceWord(c.irregularSingles, c.irregularPlurals, c.pluralRules)(word) +} + +// IsPlural -- Check if a word is plural. +func (c *pluralize) IsPlural(word string) bool { + return c.checkWord(c.irregularSingles, c.irregularPlurals, c.pluralRules)(word) +} + +// Singular -- Singularize a word. +func (c *pluralize) Singular(word string) string { + return c.replaceWord(c.irregularPlurals, c.irregularSingles, c.singularRules)(word) +} + +// IsSingular -- Check if a word is singular. +func (c *pluralize) IsSingular(word string) bool { + return c.checkWord(c.irregularPlurals, c.irregularSingles, c.singularRules)(word) +} + +// AddPluralRule -- Add a pluralization rule to the collection. +func (c *pluralize) AddPluralRule(rule string, replacement string) { + c.pluralRules = append(c.pluralRules, PluralizeRule{pluralizeSanitizeRule(rule), replacement}) +} + +// AddSingularRule -- Add a singularization rule to the collection. +func (c *pluralize) AddSingularRule(rule string, replacement string) { + c.singularRules = append(c.singularRules, PluralizeRule{pluralizeSanitizeRule(rule), replacement}) +} + +// AddUncountableRule -- Add an uncountable word rule. +func (c *pluralize) AddUncountableRule(word string) { + if !pluralizeIsExpr(word) { + c.uncountables[strings.ToLower(word)] = true + return + } + + c.AddPluralRule(word, `$0`) + c.AddSingularRule(word, `$0`) +} + +// AddIrregularRule -- Add an irregular word definition. +func (c *pluralize) AddIrregularRule(single string, plural string) { + p := strings.ToLower(plural) + s := strings.ToLower(single) + + c.irregularSingles[s] = p + c.irregularPlurals[p] = s +} + +func (c *pluralize) replaceWord(replaceMap map[string]string, keepMap map[string]string, rules []PluralizeRule) func(w string) string { //nolint:lll + f := func(word string) string { + // Get the correct token and case restoration functions. + var token = strings.ToLower(word) + + // Check against the keep object map. + if _, ok := keepMap[token]; ok { + return pluralizeRestoreCase(word, token) + } + + // Check against the replacement map for a direct word replacement. + if replaceToken, ok := replaceMap[token]; ok { + return pluralizeRestoreCase(word, replaceToken) + } + + // Run all the rules against the word. + return c.sanitizeWord(token, word, rules) + } + + return f +} + +func (c *pluralize) checkWord(replaceMap map[string]string, keepMap map[string]string, rules []PluralizeRule) func(w string) bool { + f := func(word string) bool { + var token = strings.ToLower(word) + + if _, ok := keepMap[token]; ok { + return true + } + + if _, ok := replaceMap[token]; ok { + return false + } + + return c.sanitizeWord(token, token, rules) == token + } + + return f +} + +func (c *pluralize) interpolate(str string, args []string) string { + lookup := map[string]string{} + + for _, submatch := range c.interpolateExpr.FindAllStringSubmatch(str, -1) { + element, _ := strconv.Atoi(submatch[1]) + lookup[submatch[0]] = args[element] + } + + result := c.interpolateExpr.ReplaceAllStringFunc(str, func(repl string) string { + return lookup[repl] + }) + + return result +} + +func (c *pluralize) replace(word string, rule PluralizeRule) string { + return rule.expression.ReplaceAllStringFunc(word, func(w string) string { + match := rule.expression.FindString(word) + index := rule.expression.FindStringIndex(word)[0] + args := rule.expression.FindAllStringSubmatch(word, -1)[0] + + result := c.interpolate(rule.replacement, args) + + if match == `` { + return pluralizeRestoreCase(word[index-1:index], result) + } + return pluralizeRestoreCase(match, result) + }) +} + +func (c *pluralize) sanitizeWord(token string, word string, rules []PluralizeRule) string { + // If empty string + if len(token) == 0 { + return word + } + // If does not need fixup + if _, ok := c.uncountables[token]; ok { + return word + } + + // Iterate over the sanitization rules and use the first one to match. + // NOTE: iterate rules array in reverse order specific => general rules + for i := len(rules) - 1; i >= 0; i-- { + if rules[i].expression.MatchString(word) { + return c.replace(word, rules[i]) + } + } + + return word +} + +func pluralizeSanitizeRule(rule string) *regexp.Regexp { + if pluralizeIsExpr(rule) { + return regexp.MustCompile(rule) + } + + return regexp.MustCompile(`(?i)^` + rule + `$`) +} + +func pluralizeRestoreCase(word string, token string) string { + // Tokens are an exact match. + if word == token { + return token + } + + // Lower cased words. E.g. "hello". + if word == strings.ToLower(word) { + return strings.ToLower(token) + } + + // Upper cased words. E.g. "WHISKY". + if word == strings.ToUpper(word) { + return strings.ToUpper(token) + } + + // Title cased words. E.g. "Title". + if word[:1] == strings.ToUpper(word[:1]) { + return strings.ToUpper(token[:1]) + strings.ToLower(token[1:]) + } + + // Lower cased words. E.g. "test". + return strings.ToLower(token) +} + +// pluralizeIsExpr -- helper to detect if string represents an expression by checking first character to be `(`. +func pluralizeIsExpr(s string) bool { + return s[:1] == `(` +} + +func (c *pluralize) loadIrregularRules() { //nolint:funlen + var irregularRules = []struct { + single string + plural string + }{ + // Pronouns. + {`I`, `we`}, + {`me`, `us`}, + {`he`, `they`}, + {`she`, `they`}, + {`them`, `them`}, + {`myself`, `ourselves`}, + {`yourself`, `yourselves`}, + {`itself`, `themselves`}, + {`herself`, `themselves`}, + {`himself`, `themselves`}, + {`themself`, `themselves`}, + {`is`, `are`}, + {`was`, `were`}, + {`has`, `have`}, + {`this`, `these`}, + {`that`, `those`}, + {`my`, `our`}, + {`its`, `their`}, + {`his`, `their`}, + {`her`, `their`}, + // Words ending in with a consonant and `o`. + {`echo`, `echoes`}, + {`dingo`, `dingoes`}, + {`volcano`, `volcanoes`}, + {`tornado`, `tornadoes`}, + {`torpedo`, `torpedoes`}, + // Ends with `us`. + {`genus`, `genera`}, + {`viscus`, `viscera`}, + // Ends with `ma`. + {`stigma`, `stigmata`}, + {`stoma`, `stomata`}, + {`dogma`, `dogmata`}, + {`lemma`, `lemmata`}, + {`schema`, `schemata`}, + {`anathema`, `anathemata`}, + // Other irregular rules. + {`ox`, `oxen`}, + {`axe`, `axes`}, + {`die`, `dice`}, + {`yes`, `yeses`}, + {`foot`, `feet`}, + {`eave`, `eaves`}, + {`goose`, `geese`}, + {`tooth`, `teeth`}, + {`quiz`, `quizzes`}, + {`human`, `humans`}, + {`proof`, `proofs`}, + {`carve`, `carves`}, + {`valve`, `valves`}, + {`looey`, `looies`}, + {`thief`, `thieves`}, + {`groove`, `grooves`}, + {`pickaxe`, `pickaxes`}, + {`passerby`, `passersby`}, + {`canvas`, `canvases`}, + {`sms`, `sms`}, + } + + for _, r := range irregularRules { + c.AddIrregularRule(r.single, r.plural) + } +} + +func (c *pluralize) loadPluralizationRules() { + var pluralizationRules = []struct { + rule string + replacement string + }{ + {`(?i)s?$`, `s`}, + {`(?i)[^[:ascii:]]$`, `$0`}, + {`(?i)([^aeiou]ese)$`, `$1`}, + {`(?i)(ax|test)is$`, `$1es`}, + {`(?i)(alias|[^aou]us|t[lm]as|gas|ris)$`, `$1es`}, + {`(?i)(e[mn]u)s?$`, `$1s`}, + {`(?i)([^l]ias|[aeiou]las|[ejzr]as|[iu]am)$`, `$1`}, + {`(?i)(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$`, `$1i`}, //nolint:lll,misspell + {`(?i)(alumn|alg|vertebr)(?:a|ae)$`, `$1ae`}, + {`(?i)(seraph|cherub)(?:im)?$`, `$1im`}, + {`(?i)(her|at|gr)o$`, `$1oes`}, + {`(?i)(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$`, `$1a`}, //nolint:lll,misspell + {`(?i)(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$`, `$1a`}, + {`(?i)sis$`, `ses`}, + {`(?i)(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$`, `$1$2ves`}, + {`(?i)([^aeiouy]|qu)y$`, `$1ies`}, + {`(?i)([^ch][ieo][ln])ey$`, `$1ies`}, + {`(?i)(x|ch|ss|sh|zz)$`, `$1es`}, + {`(?i)(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$`, `$1ices`}, + {`(?i)\b((?:tit)?m|l)(?:ice|ouse)$`, `$1ice`}, + {`(?i)(pe)(?:rson|ople)$`, `$1ople`}, + {`(?i)(child)(?:ren)?$`, `$1ren`}, + {`(?i)eaux$`, `$0`}, + {`(?i)m[ae]n$`, `men`}, + {`thou`, `you`}, + } + + for _, r := range pluralizationRules { + c.AddPluralRule(r.rule, r.replacement) + } +} + +func (c *pluralize) loadSingularizationRules() { + var singularizationRules = []struct { + rule string + replacement string + }{ + {`(?i)s$`, ``}, + {`(?i)(ss)$`, `$1`}, + {`(?i)(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$`, `$1fe`}, + {`(?i)(ar|(?:wo|[ae])l|[eo][ao])ves$`, `$1f`}, + {`(?i)ies$`, `y`}, + {`(?i)(dg|ss|ois|lk|ok|wn|mb|th|ch|ec|oal|is|ck|ix|sser|ts|wb)ies$`, `$1ie`}, + {`(?i)\b(l|(?:neck|cross|hog|aun)?t|coll|faer|food|gen|goon|group|hipp|junk|vegg|(?:pork)?p|charl|calor|cut)ies$`, `$1ie`}, //nolint:lll + {`(?i)\b(mon|smil)ies$`, `$1ey`}, + {`(?i)\b((?:tit)?m|l)ice$`, `$1ouse`}, + {`(?i)(seraph|cherub)im$`, `$1`}, + {`(?i)(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$`, `$1`}, + {`(?i)(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$`, `$1sis`}, + {`(?i)(movie|twelve|abuse|e[mn]u)s$`, `$1`}, + {`(?i)(test)(?:is|es)$`, `$1is`}, + {`(?i)(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$`, `$1us`}, //nolint:lll,misspell + {`(?i)(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$`, `$1um`}, //nolint:lll,misspell + {`(?i)(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$`, `$1on`}, + {`(?i)(alumn|alg|vertebr)ae$`, `$1a`}, + {`(?i)(cod|mur|sil|vert|ind)ices$`, `$1ex`}, + {`(?i)(matr|append)ices$`, `$1ix`}, + {`(?i)(pe)(rson|ople)$`, `$1rson`}, + {`(?i)(child)ren$`, `$1`}, + {`(?i)(eau)x?$`, `$1`}, + {`(?i)men$`, `man`}, + } + + for _, r := range singularizationRules { + c.AddSingularRule(r.rule, r.replacement) + } +} + +func (c *pluralize) loadUncountableRules() { //nolint:funlen + var uncountableRules = []string{ + // Singular words with no plurals. + `adulthood`, + `advice`, + `agenda`, + `aid`, + `aircraft`, + `alcohol`, + `ammo`, + `analytics`, + `anime`, + `athletics`, + `audio`, + `bison`, + `blood`, + `bream`, + `buffalo`, + `butter`, + `carp`, + `cash`, + `chassis`, + `chess`, + `clothing`, + `cod`, + `commerce`, + `cooperation`, + `corps`, + `debris`, + `diabetes`, + `digestion`, + `elk`, + `energy`, + `equipment`, + `excretion`, + `expertise`, + `firmware`, + `flounder`, + `fun`, + `gallows`, + `garbage`, + `graffiti`, + `hardware`, + `headquarters`, + `health`, + `herpes`, + `highjinks`, + `homework`, + `housework`, + `information`, + `jeans`, + `justice`, + `kudos`, + `labour`, + `literature`, + `machinery`, + `mackerel`, + `mail`, + `media`, + `mews`, + `moose`, + `music`, + `mud`, + `manga`, + `news`, + `only`, + `personnel`, + `pike`, + `plankton`, + `pliers`, + `police`, + `pollution`, + `premises`, + `rain`, + `research`, + `rice`, + `salmon`, + `scissors`, + `series`, + `sewage`, + `shambles`, + `shrimp`, + `software`, + `staff`, + `swine`, + `tennis`, + `traffic`, + `transportation`, + `trout`, + `tuna`, + `wealth`, + `welfare`, + `whiting`, + `wildebeest`, + `wildlife`, + `you`, + // Regexes. + `(?i)pok[eé]mon$`, // + `(?i)[^aeiou]ese$`, // "chinese", "japanese" + `(?i)deer$`, // "deer", "reindeer" + `(?i)(fish)$`, // "fish", "blowfish", "angelfish" + `(?i)measles$`, // + `(?i)o[iu]s$`, // "carnivorous" + `(?i)pox$`, // "chickpox", "smallpox" + `(?i)sheep$`, // + } + + for _, w := range uncountableRules { + c.AddUncountableRule(w) + } +} diff --git a/pkg/protockit/util/tpl.go b/pkg/protockit/util/tpl.go new file mode 100644 index 0000000..4e877b7 --- /dev/null +++ b/pkg/protockit/util/tpl.go @@ -0,0 +1,38 @@ +package util + +import ( + "bytes" + "text/template" + + "github.com/gobeam/stringy" + "google.golang.org/protobuf/compiler/protogen" +) + +func NewTpl(name string) *template.Template { + tpl := template.New(name).Funcs(template.FuncMap{ + "sliceJoin": func(items []string) string { + buf := new(bytes.Buffer) + for k, v := range items { + buf.WriteString(`"` + v + `"`) + if k < len(items) { + buf.WriteString(`,`) + } + } + return buf.String() + }, + "lcFirst": LcFirst, + "outputParams": func(output *protogen.Message) string { + return "" + }, + }) + + return tpl +} + +func LcFirst(s string) string { + return stringy.New(s).LcFirst() +} + +func UcFirst(s string) string { + return stringy.New(s).UcFirst() +} diff --git a/pkg/storagekit/manager.go b/pkg/storagekit/manager.go index 090f080..b770903 100644 --- a/pkg/storagekit/manager.go +++ b/pkg/storagekit/manager.go @@ -4,8 +4,8 @@ import ( "fmt" "time" + "github.com/glebarez/sqlite" "gorm.io/driver/mysql" - "gorm.io/driver/sqlite" "gorm.io/gorm" "gorm.io/gorm/schema" ) diff --git a/serverless.yaml b/serverless.yaml new file mode 100644 index 0000000..ad2b98d --- /dev/null +++ b/serverless.yaml @@ -0,0 +1,53 @@ +# Ref: +# https://github.com/serverless-components/tencent-scf/blob/master/docs/configure.md. +# https://github.com/serverless/serverless-tencent/discussions/22 +# https://github.com/serverless/serverless-tencent/blob/master/docs/basic/variables.md +# +#应用组织信息 +app: 'xadmin' # 应用名称。留空则默认取当前组件的实例名称为app名称。 +#stage: 'test' # 环境名称。默认值是 dev。建议使用${env:STAGE}变量定义环境名称 +stage: ${env:STAGE} # 环境名称。默认值是 dev。建议使用${env:STAGE}变量定义环境名称 + +component: scf +name: api + +inputs: + src: + src: ./ + hook: "ls" + exclude: + - .env + - .env.test + - .env.release + - .vscode + namespace: ${env:SCF_NAMESPACE} + region: ap-shanghai + runtime: Go1 + handler: main + memorySize: 64 # 内存大小,单位MB + timeout: 5 # 函数执行超时时间,单位秒 + initTimeout: 3 # 初始化超时时间,单位秒 + + environment: # 环境变量 + variables: # 环境变量对象 + ENV: ${stage} + + publicAccess: true # 是否开启公网访问 + + events: + - apigw: + parameters: + serviceName: serverless + serviceId: ${env:SCF_SERVICE_ID} + protocols: + - http + - https + environment: ${stage} + endpoints: + - path: / + apiName: ${name} + method: ANY + enableCORS: true + function: + isIntegratedResponse: true + functionQualifier: $DEFAULT