[
  {
    "path": ".circleci/config.yml",
    "content": "version: 2.1\njobs:\n  test:\n    docker:\n      - image: cimg/go:1.17\n    working_directory: ~/golang-example-app\n    steps:\n      - checkout\n      - run:\n          name: \"Setup APP_WD\"\n          command: echo 'export APP_WD=\"$(cd ${CIRCLE_WORKING_DIRECTORY}; pwd)/resources\"' >> $BASH_ENV\n      - run:\n          name: Fetch dependencies\n          command: go mod download\n      - run:\n          name: Test\n          command: go test ./...\n  build:\n    docker:\n      - image: cimg/go:1.17\n    working_directory: ~/golang-example-app\n    steps:\n      - checkout\n      - run:\n          name: Fetch dependencies\n          command: go mod download\n      - run:\n          name: Building\n          command: |\n            VERSION=${CIRCLE_TAG}\n            GOOS=linux GOARCH=amd64 go build -ldflags \"-X main.Version=${VERSION}\" -o bin/app-${VERSION}-linux-amd64 main.go\n            GOOS=darwin GOARCH=amd64 go build -ldflags \"-X main.Version=${VERSION}\" -o bin/app-${VERSION}-darwin-amd64 main.go\n      - persist_to_workspace:\n          root: .\n          paths:\n            - bin\n  publish-github-release:\n    docker:\n      - image: cibuilds/github:0.13\n    steps:\n      - attach_workspace:\n          at: ~/golang-example-app\n      - run:\n          name: \"Publish Release on GitHub\"\n          command: |\n            VERSION=${CIRCLE_TAG}\n            ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete ${VERSION} ~/golang-example-app/bin\nworkflows:\n  version: 2\n  main:\n    jobs:\n      - test\n  release:\n    jobs:\n      - build:\n          filters:\n            branches:\n              ignore: /.*/\n            tags:\n              only: /^v\\d+\\.\\d+\\.\\d+.*/\n      - publish-github-release:\n          requires:\n            - build\n          filters:\n            branches:\n              ignore: /.*/\n            tags:\n              only: /^v\\d+\\.\\d+\\.\\d+.*/\n"
  },
  {
    "path": ".gitignore",
    "content": "# Binaries for programs and plugins\n*.exe\n*.dll\n*.so\n*.dylib\n\n# Test binary, build with `go test -c`\n*.test\n\n# Output of the go coverage tool, specifically when used with LiteIDE\n*.out\n\n# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736\n.glide/\n\nvendor/\n\n.idea/\nartifacts/\n\ncoverage.out\n\n.DS_Store\n"
  },
  {
    "path": "Makefile",
    "content": "GO_DIR ?= $(shell pwd)\nGO_PKG ?= $(shell go list -e -f \"{{ .ImportPath }}\")\n\nGOOS ?= $(shell go env GOOS || echo linux)\nGOARCH ?= $(shell go env GOARCH || echo amd64)\nCGO_ENABLED ?= 0\n\nDOCKER_IMAGE ?= unknown\nTAG ?= unknown\nCACHE_TAG ?= unknown_cache\n\nDATABASE_URL ?= golang_example_development\n\nREMOVE_CONTAINERS ?= OFF\n\ndefine build_resources\n \tfind \"$(GO_DIR)/resources\" -maxdepth 1 -mindepth 1 -exec cp -R -f {} $(GO_DIR)/artifacts/${1} \\;\nendef\n\ninstall: init ## install cli tools\n\tgo get -v github.com/rubenv/sql-migrate/... ;\\\n    go get -u github.com/google/wire/cmd/wire ;\\\n    go get -u github.com/vektah/dataloaden ;\n\ninit: ## init packages\n\tmkdir -p artifacts ;\\\n    rm -rf artifacts/*\n\nstart: ## start daemon on development mode\n\t./artifacts/bin daemon -c ./artifacts/configs/development.yaml -d\n\ndependencies: ## generate dependencies\n\tgo mod download\n\ngqlgen-generate: ## generate graphql resolver\n\tgo run github.com/99designs/gqlgen\n\nprototool-generate: ## generate proto file\n\tprotoc --go_out=generated --go_opt=paths=source_relative --go-grpc_out=generated --go-grpc_opt=paths=source_relative resources/proto/products/products.proto\n\tprotoc --go_out=generated --go_opt=paths=source_relative --go-grpc_out=generated --go-grpc_opt=paths=source_relative resources/proto/health_checks/health_checks.proto\n\nbuild: init ## build binary file\n\t$(call build_resources) ;\\\n\tGOOS=${GOOS} CGO_ENABLED=${CGO_ENABLED} GOARCH=${GOARCH} \\\n\tgo build -ldflags \"-X $(GO_PKG)/cmd/version.appVersion=$(TAG)-$$(date -u +%Y%m%d%H%M)\" -o \"$(GO_DIR)/artifacts/bin\" main.go\n\ndocker-image: ## build docker image\n\tREMOVE_CONTAINERS=${REMOVE_CONTAINERS} DOCKER_IMAGE=${DOCKER_IMAGE} ./scripts/remove_docker_containers.sh\n\tdocker rmi ${DOCKER_IMAGE}:${TAG} -f || true ;\\\n\tdocker build --cache-from ${DOCKER_IMAGE}:${CACHE_TAG} -f \"${GO_DIR}/docker/app/Dockerfile\" -t ${DOCKER_IMAGE}:${TAG} ${GO_DIR}\n\ntest: ## test application with race\n\tgo test -v ./...\n\ncoverage: ## test coverage\n\tgo test -coverprofile=coverage.out ./...\n\tgo tool cover -html coverage.out\n\ncreatedb: ## create database\n\tcreatedb $(DATABASE_URL)\n\ndropdb: ## drop database\n\tdropdb $(DATABASE_URL)\n\n.PHONY: install init dependencies gqlgen-generate prototool-generate\n\nhelp:\n\t@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = \":.*?## \"}; {printf \"\\033[36m%-30s\\033[0m %s\\n\", $$1, $$2}'\n\n.DEFAULT_GOAL := help\n"
  },
  {
    "path": "README.md",
    "content": "![golang logo](golang_logo.png)\n\n# Golang Example Application\n\n# Table of Contents\n\n- [Overview](#overview)\n- [Package list](#package-list)\n- [Installing](#installing)\n  * [Local environment](#local-environment)\n  * [Docker environment](#docker-enviroment)\n- [Run services](#run-services)\n  * [Start in local](#start-in-local-machine)\n  * [Start in docker](#start-in-docker)\n- [Getting started](#getting-started)  \n  * [Jaeger](#jaeger)\n  * [Http with gRPC](#http-example-with-grpc)\n  * [Graphql with gRPC](#graphql-example-with-grpc)\n- [Deprecate version](#deprecated-version)  \n- [Testing](#testing)\n\n# Overview\n\nThis is an example golang application.\nCommands list:\n1. Daemon - main service\n2. Product service - service that returns Product, an example of gRPC client/server interaction\n3. Health check service - this service is needed to show how convenient to understand on which of the services an error occurred in jaeger\n4. Migrate - commands for migration\n5. JWT - commands for generate JWT token\n\n# Package list\n\nPackages which use in this example project\n\n1. [sql-migrate](https://github.com/rubenv/sql-migrate) - SQL migrations\n2. [wire](https://github.com/google/wire) - dependency Injection\n3. [viper](https://github.com/spf13/viper) - environment configuration\n4. [cobra](https://github.com/spf13/cobra) - create commands\n5. [cast](https://github.com/spf13/cast) - easy casting from one type to another\n6. [gorm](https://github.com/jinzhu/gorm) - database ORM\n7. [zap](https://github.com/uber-go/zap) - logger\n8. [mux](https://github.com/gorilla/mux) - http router\n9. [nats-streaming](https://github.com/nats-io/stan.go) - NATS Streaming System\n10. [gqlgen](https://github.com/99designs/gqlgen) - graphql server library\n11. [protobuf](https://pkg.go.dev/google.golang.org/protobuf) - Google's data interchange format\n12. [grpc](google.golang.org/grpc) - RPC framework\n13. [opentelemetry](https://github.com/open-telemetry/opentelemetry-go) - OpenTelemetry\n14. [jaeger](https://github.com/uber/jaeger-client-go) - Jaeger Bindings for Go OpenTelemetry API\n15. [casbin](https://github.com/casbin/casbin) - Supports access control\n16. [dataloaden](https://github.com/vektah/dataloaden) - DataLoader for graphql\n17. [nats](https://github.com/nats-io/nats.go) - Golang client for NATS, the cloud native messaging system\n\n# Installing\n\nInstall the Golang and GO environment\n\n```$xslt\nhttps://golang.org/doc/install\n```\n\nInstall [Postgresql](https://www.postgresql.org/download) (if you want to run locally)\n\nClone repository\n\n```$xslt\ngit clone git@github.com:Aristat/golang-example-app.git (go get)\n```\n\n## Local environment\n\nInstall Golang packages without modules\n\n```$xslt\nmake install\n```\n\nInstall database\n\n```$xslt\nmake createdb\n```\n\nSql migrations\n\n```$xslt\nsql-migrate up\n```\n\nInstall Golang dependencies\n\n```$xslt\nmake dependencies\n```\n\nGenerate artifacts(binary files and configs)\n\n```$xslt\nmake build\n```\n\nPackages for proto generator\n\n```$xslt\nhttps://grpc.io/docs/languages/go/quickstart/#prerequisites\n```\n\nSet APP_WD if you start to use html templates or path to ssh keys or run `make test`\n\n```$xslt\nexport APP_WD=go_path to project_path/resources or project_path/artifacts\n```\n\n## Docker environment\n\nGenerate docker image\n\n```$xslt\nDOCKER_IMAGE=golang-example-app TAG=development make docker-image\n```\n\n# Run services\n\n## Start in local machine\n\nUp jaeger in docker-compose or disable Jaeger(and rebuild binary file) in `resources/configs/*.yaml`\n\n```$xslt\ndocker-compose up jaeger\n```\n\nStart daemon (main service)\n\n```$xslt\nmake start\n```\n\nor\n\n```$xslt\n./artifacts/bin daemon -c ./artifacts/configs/development.yaml -d\n```\n\nStart product service \n\n```$xslt\n./artifacts/bin product-service -c ./artifacts/configs/development.yaml -d\n```\n\nStart health-check service\n\n```$xslt\n./artifacts/bin health-check -c ./artifacts/configs/development.yaml -d\n```\n\n## Start in docker\n\n#### Run this commands\n```$xslt\ndocker-compose rm # Remove previous containers\nREMOVE_CONTAINERS=on DOCKER_IMAGE=golang-example-app TAG=development make docker-image # Generate new docker image\ndocker-compose up\n```\n\n#### or run script\n\n```$xslt\n./scripts/docker-compose-start.sh\n```\n\n# Getting Started\n\n## Jaeger\n\n```$xslt\nhttp://localhost:16686\n```\n\n## Http example with gRPC\n\n```$xslt\nhttp://localhost:9096/products_grpc\n```\n\n## Http example with Nats Streaming\n\n```$xslt\nhttp://localhost:9096/products_nats\n```\n\n## Http example with graceful shutdown(long request, you can check the server shutdown)\n\n```$xslt\nhttp://localhost:9096/products_slowly\n```\n\n## Graphql example with gRPC\n\nGraphql [client](https://github.com/prisma-labs/graphql-playground) for testing. End-point `http://localhost:9096/query`.\n\nGenerate JWT for Graphql authorization\n\n```$xslt\n./artifacts/bin jwt token --key='./artifacts/keys/local/private_key.pem' --fields='{\"sub\": \"owner\", \"iss\": \"test-service\"}'\n```\n\nSet JWT token in headers\n\n```$xslt\n{\n  \"Authorization\": \"bearer token\"\n}\n```\n\nExample query\n\n```\nquery oneUser {\n  users {\n    one(email: \"test@gmail.com\") {\n      email\n      id\n    }\n  }\n}\n```\n\nExample query with data loader\n\n```\nquery allProducts {\n  products {\n    list {\n      products {\n        id\n        productItems {\n          id\n          name\n        }\n      }\n    }\n  }\n}\n```\n\nExample mutation\n\n```\nmutation createUser {\n  users {\n    createUser(email: \"test1@gmail.com\", password: \"123456789\") {\n      id\n      email\n    }\n  }\n}\n```\n\n# Testing\n```\n➜  make test\n```\n"
  },
  {
    "path": "app/auth/middleware.go",
    "content": "package auth\n\nimport (\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/aristat/golang-example-app/app/common\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\n\t\"github.com/golang-jwt/jwt\"\n\n\tappContext \"github.com/aristat/golang-example-app/app/context\"\n\t\"github.com/pkg/errors\"\n)\n\nconst prefix = \"app.auth\"\nconst defaultSubject = \"anonymous\"\nconst defaultServiceName = \"unknown\"\nconst defaultServiceId = 0\n\nvar errPublicNotFound = errors.New(\"public key not found for issuer\")\nvar errAuthJWT = errors.New(\"Authentication failed, JWT invalid\")\n\n// CustomClaims\ntype CustomClaims struct {\n\tjwt.StandardClaims\n}\n\n// Config\ntype Config struct {\n\tServices     map[string]uint64\n\tRelativePath string\n}\n\n// Middleware\ntype Middleware struct {\n\tkeys keys\n\tcfg  Config\n\tlog  logger.Logger\n}\n\n// keys\ntype keys struct {\n\tpublicPemKey  []byte\n\tprivatePemKey []byte\n}\n\n// Handler for check Bearer token\nfunc (m Middleware) JWTHandler(next http.Handler) http.Handler {\n\tfn := func(w http.ResponseWriter, r *http.Request) {\n\t\tvar (\n\t\t\ttoken       string\n\t\t\tbearerToken = strings.Split(r.Header.Get(\"Authorization\"), \" \")\n\t\t\tsubject     = defaultSubject\n\t\t\tclaims      *CustomClaims\n\t\t\tok          bool\n\t\t)\n\n\t\tif len(bearerToken) > 1 {\n\t\t\ttoken = bearerToken[1]\n\t\t} else {\n\t\t\tcommon.SendGraphqlErrorf(w, http.StatusUnauthorized, \"Not found authorization token\")\n\t\t\treturn\n\t\t}\n\n\t\tt, err := jwt.ParseWithClaims(token, &CustomClaims{}, func(t *jwt.Token) (interface{}, error) {\n\t\t\tif _, ok := t.Claims.(*CustomClaims); ok {\n\t\t\t\treturn jwt.ParseRSAPublicKeyFromPEM(m.keys.publicPemKey)\n\t\t\t}\n\n\t\t\tm.log.Error(\"Public key not found: %s\", logger.Args(errPublicNotFound.Error()))\n\t\t\treturn nil, errPublicNotFound\n\t\t})\n\n\t\tif err != nil {\n\t\t\tm.log.Error(\"Parse error: %s\", logger.Args(err.Error()))\n\t\t\tcommon.SendGraphqlErrorf(w, http.StatusUnauthorized, err.Error())\n\t\t\treturn\n\t\t}\n\n\t\tif t.Valid {\n\t\t\tif claims, ok = t.Claims.(*CustomClaims); ok {\n\t\t\t\tsubject = claims.Subject\n\t\t\t}\n\t\t} else {\n\t\t\tm.log.Error(\"Validation Error: %s\", logger.Args(errAuthJWT.Error()))\n\t\t\tcommon.SendGraphqlErrorf(w, http.StatusUnauthorized, errAuthJWT.Error())\n\t\t\treturn\n\t\t}\n\n\t\tserviceName, serviceID := m.Service(claims)\n\t\tr = r.WithContext(appContext.NewContext(r.Context(), appContext.Mapping{\n\t\t\tSubject:     subject,\n\t\t\tServiceId:   serviceID,\n\t\t\tServiceName: serviceName,\n\t\t}))\n\n\t\tnext.ServeHTTP(w, r)\n\t}\n\treturn http.HandlerFunc(fn)\n}\n\n// Service returns service data as pair of name and id\nfunc (m Middleware) Service(claims *CustomClaims) (string, uint64) {\n\tif claims == nil {\n\t\treturn defaultServiceName, defaultServiceId\n\t}\n\n\tissuer := claims.Issuer\n\n\tif id, ok := m.cfg.Services[issuer]; ok {\n\t\treturn claims.Issuer, id\n\t}\n\treturn defaultServiceName, defaultServiceId\n}\n\nfunc NewMiddleware(cfg Config, log logger.Logger) (*Middleware, func(), error) {\n\trPath := strings.Trim(cfg.RelativePath, \"/\")\n\tlog = log.WithFields(logger.Fields{\"service\": prefix})\n\tm := &Middleware{cfg: cfg, log: log}\n\n\tpublicKey, err := ioutil.ReadFile(entrypoint.WorkDir() + \"/\" + rPath + \"/public_key.pem\")\n\tif err != nil {\n\t\treturn nil, func() {}, err\n\t}\n\n\tm.keys.publicPemKey = publicKey\n\tm.keys.privatePemKey, err = ioutil.ReadFile(entrypoint.WorkDir() + \"/\" + rPath + \"/private_key.pem\")\n\tif err != nil {\n\t\treturn nil, func() {}, err\n\t}\n\n\treturn m, func() {}, nil\n}\n\nfunc NewTestMiddleware(log logger.Logger) (*Middleware, func(), error) {\n\tlog = log.WithFields(logger.Fields{\"service\": prefix})\n\tprivate := ``\n\tpublic := ``\n\n\tmiddleware := &Middleware{\n\t\tcfg: Config{},\n\t\tkeys: keys{\n\t\t\tpublicPemKey:  []byte(public),\n\t\t\tprivatePemKey: []byte(private),\n\t\t},\n\t\tlog: log,\n\t}\n\n\treturn middleware, func() {}, nil\n}\n"
  },
  {
    "path": "app/auth/provider.go",
    "content": "package auth\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/google/wire\"\n\t\"github.com/spf13/viper\"\n)\n\n// ProviderCfg\nfunc ProviderCfg(cfg *viper.Viper) (Config, func(), error) {\n\tc := Config{}\n\te := cfg.UnmarshalKey(\"auth\", &c)\n\treturn c, func() {}, e\n}\n\n// Provider\nfunc Provider(cfg Config, logger logger.Logger) (*Middleware, func(), error) {\n\treturn NewMiddleware(cfg, logger)\n}\n\n// ProviderTest\nfunc ProviderTest(logger logger.Logger) (*Middleware, func(), error) {\n\treturn NewTestMiddleware(logger)\n}\n\nvar (\n\tProviderProductionSet = wire.NewSet(Provider, ProviderCfg)\n\tProviderTestSet       = wire.NewSet(ProviderTest)\n)\n"
  },
  {
    "path": "app/casbin/provider.go",
    "content": "package casbin\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\t\"github.com/casbin/casbin\"\n\tfileadapter \"github.com/casbin/casbin/persist/file-adapter\"\n\t\"github.com/google/wire\"\n)\n\nfunc Provider() (*casbin.Enforcer, func(), error) {\n\twd := entrypoint.WorkDir()\n\tenf := casbin.NewEnforcer(wd+\"/casbin/model.conf\", wd+\"/casbin/policy.csv\")\n\treturn enf, func() {}, nil\n}\n\nfunc ProviderTest() (*casbin.Enforcer, func(), error) {\n\n\tmodel := `\n[request_definition]\nr = sub, obj, act\n\n[policy_definition]\np = sub, obj, act\n\n[role_definition]\ng = _, _\n\n[policy_effect]\ne = some(where (p.eft == allow))\n\n[matchers]\nm = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act\n`\n\tpolicy := `\np, reader, users, read\np, owner, users, write\n\ng, reader, anonymous\ng, owner, reader\n`\n\tenf := casbin.NewEnforcer(casbin.NewModel(model), fileadapter.NewAdapter(policy))\n\treturn enf, func() {}, nil\n}\n\nvar (\n\tProviderProductionSet = wire.NewSet(Provider)\n\tProviderTestSet       = wire.NewSet(ProviderTest)\n)\n"
  },
  {
    "path": "app/common/bcrypt.go",
    "content": "package common\n\nimport \"golang.org/x/crypto/bcrypt\"\n\nfunc HashPassword(password string, cost int) (string, error) {\n\tbytes, err := bcrypt.GenerateFromPassword([]byte(password), cost)\n\treturn string(bytes), err\n}\n\nfunc CheckPasswordHash(password, hash string) bool {\n\terr := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))\n\treturn err == nil\n}\n"
  },
  {
    "path": "app/common/constants.go",
    "content": "package common\n\nconst (\n\tSrvProducts = \"products\"\n)\n"
  },
  {
    "path": "app/common/graphql.go",
    "content": "package common\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/vektah/gqlparser/v2/gqlerror\"\n\n\t\"github.com/99designs/gqlgen/graphql\"\n)\n\nfunc SendGraphqlError(w http.ResponseWriter, code int, errors gqlerror.List) {\n\tw.Header().Set(\"Content-Type\", \"application/json\")\n\tw.WriteHeader(code)\n\tb, err := json.Marshal(&graphql.Response{Errors: errors})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tw.Write(b)\n}\n\nfunc SendGraphqlErrorf(w http.ResponseWriter, code int, format string, args ...interface{}) {\n\tSendGraphqlError(w, code, gqlerror.List{{Message: fmt.Sprintf(format, args...)}})\n}\n"
  },
  {
    "path": "app/common/jaeger.go",
    "content": "package common\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/tracing\"\n\t\"go.opentelemetry.io/otel/exporters/jaeger\"\n\t\"go.opentelemetry.io/otel/sdk/resource\"\n\ttracesdk \"go.opentelemetry.io/otel/sdk/trace\"\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.4.0\"\n\n\t\"github.com/spf13/viper\"\n)\n\nfunc GenerateTracerForTestClient(serviceName string, cfg *viper.Viper) (*tracesdk.TracerProvider, error) {\n\tconfiguration := tracing.Configuration{}\n\terr := cfg.UnmarshalKey(\"tracing.jaeger\", &configuration)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\texp, err := jaeger.New(\n\t\tjaeger.WithAgentEndpoint(\n\t\t\tjaeger.WithAgentHost(configuration.AgentHost),\n\t\t\tjaeger.WithAgentPort(configuration.AgentPort),\n\t\t),\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttp := tracesdk.NewTracerProvider(\n\t\ttracesdk.WithBatcher(exp),\n\t\ttracesdk.WithResource(resource.NewWithAttributes(\n\t\t\tsemconv.SchemaURL,\n\t\t\tsemconv.ServiceNameKey.String(serviceName),\n\t\t)),\n\t)\n\treturn tp, nil\n}\n"
  },
  {
    "path": "app/config/injector.go",
    "content": "// +build wireinject\n\npackage config\n\nimport (\n\t\"github.com/google/wire\"\n\t\"github.com/spf13/viper\"\n)\n\n// Build returns spf13/viper instance with resolved dependencies\nfunc Build() (*viper.Viper, func(), error) {\n\tpanic(wire.Build(Provider))\n}\n"
  },
  {
    "path": "app/config/provider.go",
    "content": "package config\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\t\"github.com/google/wire\"\n\t\"github.com/spf13/viper\"\n)\n\n// Provider returns spf13/viper instance with resolved dependencies\nfunc Provider() (*viper.Viper, func(), error) {\n\tv := entrypoint.Viper()\n\tfor _, key := range v.AllKeys() {\n\t\tval := v.Get(key)\n\t\tv.Set(key, val)\n\t}\n\treturn v, func() {}, nil\n}\n\nvar ProviderSet = wire.NewSet(Provider)\n"
  },
  {
    "path": "app/config/wire_gen.go",
    "content": "// Code generated by Wire. DO NOT EDIT.\n\n//go:generate go run github.com/google/wire/cmd/wire\n//go:build !wireinject\n// +build !wireinject\n\npackage config\n\nimport (\n\t\"github.com/spf13/viper\"\n)\n\n// Injectors from injector.go:\n\n// Build returns spf13/viper instance with resolved dependencies\nfunc Build() (*viper.Viper, func(), error) {\n\tviperViper, cleanup, err := Provider()\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\treturn viperViper, func() {\n\t\tcleanup()\n\t}, nil\n}\n"
  },
  {
    "path": "app/context/context.go",
    "content": "package context\n\nimport (\n\t\"context\"\n\n\t\"github.com/mitchellh/mapstructure\"\n)\n\nconst prefix = \"app.context\"\n\n// Manager\ntype Manager struct {\n\tmapping *Mapping\n\tctx     context.Context\n}\n\nfunc (m *Manager) ToMapping() *Mapping {\n\treturn &Mapping{\n\t\tSubject:     m.mapping.Subject,\n\t\tServiceId:   m.mapping.ServiceId,\n\t\tServiceName: m.mapping.ServiceName,\n\t}\n}\n\n// NewManager\nfunc NewManager(ctx context.Context) (*Manager, error) {\n\tm := &Manager{ctx: ctx}\n\tmapping := &Mapping{}\n\n\tconfig := &mapstructure.DecoderConfig{TagName: \"json\", Result: &mapping}\n\tdecoder, _ := mapstructure.NewDecoder(config)\n\terr := decoder.Decode(ctx.Value(prefix))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tm.mapping = mapping\n\treturn m, nil\n}\n\n// Mapping\ntype Mapping struct {\n\tSubject     string\n\tServiceId   uint64 `json:\"service_id\"`\n\tServiceName string `json:\"service_name\"`\n}\n\n// NewContext\nfunc NewContext(ctx context.Context, m Mapping) context.Context {\n\treturn context.WithValue(ctx, prefix, map[string]interface{}{\n\t\t\"subject\":      m.Subject,\n\t\t\"service_id\":   m.ServiceId,\n\t\t\"service_name\": m.ServiceName,\n\t})\n}\n"
  },
  {
    "path": "app/dataloader/dataloader.go",
    "content": "//go:generate go run github.com/vektah/dataloaden ProductItemLoader int []*github.com/aristat/golang-example-app/generated/domain.ProductItem\n\npackage dataloader\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/aristat/golang-example-app/app/db/domain\"\n)\n\ntype ctxKeyType struct{ name string }\n\nvar ctxKey = ctxKeyType{\"userDataLoader\"}\n\ntype loaders struct {\n\tProductItemsByProduct *ProductItemLoader\n}\n\nfunc LoaderMiddleware(next http.Handler) http.Handler {\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tldrs := loaders{}\n\n\t\t// set this to zero what happens without data loading\n\t\twait := 250 * time.Microsecond\n\n\t\tldrs.ProductItemsByProduct = &ProductItemLoader{\n\t\t\twait:     wait,\n\t\t\tmaxBatch: 100,\n\t\t\tfetch: func(keys []int) ([][]*domain.ProductItem, []error) {\n\t\t\t\tfmt.Println(\"ProductItems Start Fetch\")\n\t\t\t\tvar keySQL []string\n\t\t\t\tfor _, key := range keys {\n\t\t\t\t\tkeySQL = append(keySQL, strconv.Itoa(key))\n\t\t\t\t}\n\n\t\t\t\tfmt.Printf(\"SELECT * FROM product_items WHERE product_id IN (%s)\\n\", strings.Join(keySQL, \",\"))\n\t\t\t\ttime.Sleep(5 * time.Millisecond)\n\n\t\t\t\tproductItems := make([][]*domain.ProductItem, len(keys))\n\t\t\t\terrors := make([]error, len(keys))\n\t\t\t\tfor i := range keys {\n\t\t\t\t\tproductItems[i] = []*domain.ProductItem{\n\t\t\t\t\t\t{ID: 1, Name: \"item \" + strconv.Itoa(rand.Int()%20+20)},\n\t\t\t\t\t\t{ID: 2, Name: \"item \" + strconv.Itoa(rand.Int()%20+20)},\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn productItems, errors\n\t\t\t},\n\t\t}\n\n\t\tdlCtx := context.WithValue(r.Context(), ctxKey, ldrs)\n\t\tnext.ServeHTTP(w, r.WithContext(dlCtx))\n\t})\n}\n\nfunc CtxLoaders(ctx context.Context) loaders {\n\treturn ctx.Value(ctxKey).(loaders)\n}\n"
  },
  {
    "path": "app/dataloader/productitemloader_gen.go",
    "content": "// Code generated by github.com/vektah/dataloaden, DO NOT EDIT.\n\npackage dataloader\n\nimport (\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/aristat/golang-example-app/app/db/domain\"\n)\n\n// ProductItemLoaderConfig captures the config to create a new ProductItemLoader\ntype ProductItemLoaderConfig struct {\n\t// Fetch is a method that provides the data for the loader\n\tFetch func(keys []int) ([][]*domain.ProductItem, []error)\n\n\t// Wait is how long wait before sending a batch\n\tWait time.Duration\n\n\t// MaxBatch will limit the maximum number of keys to send in one batch, 0 = not limit\n\tMaxBatch int\n}\n\n// NewProductItemLoader creates a new ProductItemLoader given a fetch, wait, and maxBatch\nfunc NewProductItemLoader(config ProductItemLoaderConfig) *ProductItemLoader {\n\treturn &ProductItemLoader{\n\t\tfetch:    config.Fetch,\n\t\twait:     config.Wait,\n\t\tmaxBatch: config.MaxBatch,\n\t}\n}\n\n// ProductItemLoader batches and caches requests\ntype ProductItemLoader struct {\n\t// this method provides the data for the loader\n\tfetch func(keys []int) ([][]*domain.ProductItem, []error)\n\n\t// how long to done before sending a batch\n\twait time.Duration\n\n\t// this will limit the maximum number of keys to send in one batch, 0 = no limit\n\tmaxBatch int\n\n\t// INTERNAL\n\n\t// lazily created cache\n\tcache map[int][]*domain.ProductItem\n\n\t// the current batch. keys will continue to be collected until timeout is hit,\n\t// then everything will be sent to the fetch method and out to the listeners\n\tbatch *productItemLoaderBatch\n\n\t// mutex to prevent races\n\tmu sync.Mutex\n}\n\ntype productItemLoaderBatch struct {\n\tkeys    []int\n\tdata    [][]*domain.ProductItem\n\terror   []error\n\tclosing bool\n\tdone    chan struct{}\n}\n\n// Load a ProductItem by key, batching and caching will be applied automatically\nfunc (l *ProductItemLoader) Load(key int) ([]*domain.ProductItem, error) {\n\treturn l.LoadThunk(key)()\n}\n\n// LoadThunk returns a function that when called will block waiting for a ProductItem.\n// This method should be used if you want one goroutine to make requests to many\n// different data loaders without blocking until the thunk is called.\nfunc (l *ProductItemLoader) LoadThunk(key int) func() ([]*domain.ProductItem, error) {\n\tl.mu.Lock()\n\tif it, ok := l.cache[key]; ok {\n\t\tl.mu.Unlock()\n\t\treturn func() ([]*domain.ProductItem, error) {\n\t\t\treturn it, nil\n\t\t}\n\t}\n\tif l.batch == nil {\n\t\tl.batch = &productItemLoaderBatch{done: make(chan struct{})}\n\t}\n\tbatch := l.batch\n\tpos := batch.keyIndex(l, key)\n\tl.mu.Unlock()\n\n\treturn func() ([]*domain.ProductItem, error) {\n\t\t<-batch.done\n\n\t\tvar data []*domain.ProductItem\n\t\tif pos < len(batch.data) {\n\t\t\tdata = batch.data[pos]\n\t\t}\n\n\t\tvar err error\n\t\t// its convenient to be able to return a single error for everything\n\t\tif len(batch.error) == 1 {\n\t\t\terr = batch.error[0]\n\t\t} else if batch.error != nil {\n\t\t\terr = batch.error[pos]\n\t\t}\n\n\t\tif err == nil {\n\t\t\tl.mu.Lock()\n\t\t\tl.unsafeSet(key, data)\n\t\t\tl.mu.Unlock()\n\t\t}\n\n\t\treturn data, err\n\t}\n}\n\n// LoadAll fetches many keys at once. It will be broken into appropriate sized\n// sub batches depending on how the loader is configured\nfunc (l *ProductItemLoader) LoadAll(keys []int) ([][]*domain.ProductItem, []error) {\n\tresults := make([]func() ([]*domain.ProductItem, error), len(keys))\n\n\tfor i, key := range keys {\n\t\tresults[i] = l.LoadThunk(key)\n\t}\n\n\tproductItems := make([][]*domain.ProductItem, len(keys))\n\terrors := make([]error, len(keys))\n\tfor i, thunk := range results {\n\t\tproductItems[i], errors[i] = thunk()\n\t}\n\treturn productItems, errors\n}\n\n// LoadAllThunk returns a function that when called will block waiting for a ProductItems.\n// This method should be used if you want one goroutine to make requests to many\n// different data loaders without blocking until the thunk is called.\nfunc (l *ProductItemLoader) LoadAllThunk(keys []int) func() ([][]*domain.ProductItem, []error) {\n\tresults := make([]func() ([]*domain.ProductItem, error), len(keys))\n\tfor i, key := range keys {\n\t\tresults[i] = l.LoadThunk(key)\n\t}\n\treturn func() ([][]*domain.ProductItem, []error) {\n\t\tproductItems := make([][]*domain.ProductItem, len(keys))\n\t\terrors := make([]error, len(keys))\n\t\tfor i, thunk := range results {\n\t\t\tproductItems[i], errors[i] = thunk()\n\t\t}\n\t\treturn productItems, errors\n\t}\n}\n\n// Prime the cache with the provided key and value. If the key already exists, no change is made\n// and false is returned.\n// (To forcefully prime the cache, clear the key first with loader.clear(key).prime(key, value).)\nfunc (l *ProductItemLoader) Prime(key int, value []*domain.ProductItem) bool {\n\tl.mu.Lock()\n\tvar found bool\n\tif _, found = l.cache[key]; !found {\n\t\t// make a copy when writing to the cache, its easy to pass a pointer in from a loop var\n\t\t// and end up with the whole cache pointing to the same value.\n\t\tcpy := make([]*domain.ProductItem, len(value))\n\t\tcopy(cpy, value)\n\t\tl.unsafeSet(key, cpy)\n\t}\n\tl.mu.Unlock()\n\treturn !found\n}\n\n// Clear the value at key from the cache, if it exists\nfunc (l *ProductItemLoader) Clear(key int) {\n\tl.mu.Lock()\n\tdelete(l.cache, key)\n\tl.mu.Unlock()\n}\n\nfunc (l *ProductItemLoader) unsafeSet(key int, value []*domain.ProductItem) {\n\tif l.cache == nil {\n\t\tl.cache = map[int][]*domain.ProductItem{}\n\t}\n\tl.cache[key] = value\n}\n\n// keyIndex will return the location of the key in the batch, if its not found\n// it will add the key to the batch\nfunc (b *productItemLoaderBatch) keyIndex(l *ProductItemLoader, key int) int {\n\tfor i, existingKey := range b.keys {\n\t\tif key == existingKey {\n\t\t\treturn i\n\t\t}\n\t}\n\n\tpos := len(b.keys)\n\tb.keys = append(b.keys, key)\n\tif pos == 0 {\n\t\tgo b.startTimer(l)\n\t}\n\n\tif l.maxBatch != 0 && pos >= l.maxBatch-1 {\n\t\tif !b.closing {\n\t\t\tb.closing = true\n\t\t\tl.batch = nil\n\t\t\tgo b.end(l)\n\t\t}\n\t}\n\n\treturn pos\n}\n\nfunc (b *productItemLoaderBatch) startTimer(l *ProductItemLoader) {\n\ttime.Sleep(l.wait)\n\tl.mu.Lock()\n\n\t// we must have hit a batch limit and are already finalizing this batch\n\tif b.closing {\n\t\tl.mu.Unlock()\n\t\treturn\n\t}\n\n\tl.batch = nil\n\tl.mu.Unlock()\n\n\tb.end(l)\n}\n\nfunc (b *productItemLoaderBatch) end(l *ProductItemLoader) {\n\tb.data, b.error = l.fetch(b.keys)\n\tclose(b.done)\n}\n"
  },
  {
    "path": "app/db/db.go",
    "content": "package db\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/jinzhu/gorm\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t_ \"github.com/lib/pq\"\n)\n\nconst prefix = \"app.db\"\n\n// Config\ntype Config struct {\n\tURL             string\n\tMaxOpenConns    int\n\tMaxIdleConns    int\n\tConnMaxLifetime time.Duration\n\tLogLevel        logger.Level\n}\n\n// Http\ntype Manager struct {\n\tctx context.Context\n\tcfg Config\n\tlog logger.Logger\n\tDB  *gorm.DB\n}\n\n// New\nfunc New(ctx context.Context, log logger.Logger, cfg Config, db *gorm.DB) *Manager {\n\treturn &Manager{\n\t\tctx: ctx,\n\t\tcfg: cfg,\n\t\tlog: log.WithFields(logger.Fields{\"service\": prefix}),\n\t\tDB:  db,\n\t}\n}\n"
  },
  {
    "path": "app/db/domain/product.go",
    "content": "package domain\n\ntype Product struct {\n\tID           int\n\tName         string\n\tproductItems []ProductItem\n}\n"
  },
  {
    "path": "app/db/domain/product_item.go",
    "content": "package domain\n\ntype ProductItem struct {\n\tID   int\n\tName string\n}\n"
  },
  {
    "path": "app/db/domain/user.go",
    "content": "package domain\n\ntype User struct {\n\tID                int    `gorm:\"column:id\"`\n\tEmail             string `gorm:\"column:email\"`\n\tEncryptedPassword string `gorm:\"column:encrypted_password\"`\n}\n\n// UsersRepo interface\ntype UsersRepo interface {\n\tCreateUser(email string, encryptPassword string) (*User, error)\n\tFindByEmail(email string) (*User, error)\n}\n"
  },
  {
    "path": "app/db/injector.go",
    "content": "// +build wireinject\n\npackage db\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/provider\"\n\t\"github.com/google/wire\"\n)\n\nfunc Build() (*Manager, func(), error) {\n\tpanic(wire.Build(ProviderProductionSet, provider.AwareProductionSet))\n}\n\nfunc BuildTest() (*Manager, func(), error) {\n\tpanic(wire.Build(ProviderTestSet, provider.AwareTestSet))\n}\n"
  },
  {
    "path": "app/db/provider.go",
    "content": "package db\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\n\t\"github.com/jinzhu/gorm\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\n\t\"github.com/google/wire\"\n\tmocket \"github.com/selvatico/go-mocket\"\n\t\"github.com/spf13/viper\"\n)\n\n// Cfg\nfunc Cfg(cfg *viper.Viper) (Config, func(), error) {\n\tc := Config{LogLevel: logger.LevelDebug}\n\te := cfg.UnmarshalKey(\"db\", &c)\n\tif e != nil {\n\t\treturn c, func() {}, e\n\t}\n\treturn c, func() {}, nil\n}\n\n// CfgTest\nfunc CfgTest() (Config, func(), error) {\n\treturn Config{}, func() {}, nil\n}\n\n// ProviderGORM\nfunc ProviderGORM(ctx context.Context, log logger.Logger, cfg Config) (*gorm.DB, func(), error) {\n\tlog = log.WithFields(logger.Fields{\"service\": prefix})\n\n\tdb, err := gorm.Open(\"postgres\", cfg.URL)\n\tdb.DB().SetMaxOpenConns(cfg.MaxOpenConns)\n\tdb.DB().SetMaxIdleConns(cfg.MaxIdleConns)\n\tdb.DB().SetConnMaxLifetime(cfg.ConnMaxLifetime)\n\n\tif cfg.LogLevel == logger.LevelDebug {\n\t\tdb.LogMode(true)\n\t}\n\n\tcleanup := func() {\n\t\tif db != nil {\n\t\t\t_ = db.Close()\n\t\t}\n\t\tlog.Info(\"Closed db connections\")\n\t}\n\n\treturn db, cleanup, err\n}\n\n// ProviderGORMTest for test, using go-mocket\nfunc ProviderGORMTest() (*gorm.DB, func(), error) {\n\tvar db *gorm.DB\n\n\tcleanup := func() {\n\t\tif db != nil {\n\t\t\t_ = db.Close()\n\t\t}\n\t}\n\n\tmocket.Catcher.Register()\n\tmocket.Catcher.Logging = true\n\n\tsqlDB, err := sql.Open(mocket.DriverName, \"gorm\")\n\tif err != nil {\n\t\treturn db, cleanup, err\n\t}\n\n\tdb, err = gorm.Open(\"postgres\", sqlDB)\n\n\treturn db, cleanup, err\n}\n\n// Provider\nfunc Provider(ctx context.Context, log logger.Logger, cfg Config, db *gorm.DB) (*Manager, func(), error) {\n\tg := New(ctx, log, cfg, db)\n\treturn g, func() {}, nil\n}\n\nvar (\n\tProviderProductionSet = wire.NewSet(Provider, ProviderGORM, Cfg)\n\tProviderTestSet       = wire.NewSet(Provider, ProviderGORMTest, CfgTest)\n)\n"
  },
  {
    "path": "app/db/repo/provider.go",
    "content": "package repo\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/db/domain\"\n\t\"github.com/google/wire\"\n)\n\n// Repo for all records\ntype Repo struct {\n\tUsers domain.UsersRepo\n}\n\n// Provider\nfunc Provider(userDomain domain.UsersRepo) (*Repo, func(), error) {\n\trepo := &Repo{\n\t\tUsers: userDomain,\n\t}\n\n\treturn repo, func() {}, nil\n}\n\nvar (\n\tProviderProductionSet = wire.NewSet(Provider, NewUsersRepo)\n\tProviderTestSet       = wire.NewSet(Provider, NewUsersRepo)\n)\n"
  },
  {
    "path": "app/db/repo/users.go",
    "content": "package repo\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/db/domain\"\n\t\"github.com/jinzhu/gorm\"\n)\n\ntype UsersRepo struct {\n\tdb *gorm.DB\n}\n\nfunc (u *UsersRepo) CreateUser(email string, encryptPassword string) (*domain.User, error) {\n\tuser := &domain.User{Email: email, EncryptedPassword: encryptPassword}\n\n\tif err := u.db.Create(user).Error; err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn user, nil\n}\n\nfunc (u *UsersRepo) FindByEmail(email string) (*domain.User, error) {\n\tuser := &domain.User{}\n\n\terr := u.db.\n\t\tTable(\"users\").\n\t\tSelect(\"id, email, encrypted_password\").\n\t\tWhere(\"users.email = ?\", email).\n\t\tLimit(1).\n\t\tScan(&user).Error\n\n\treturn user, err\n}\n\nfunc NewUsersRepo(db *gorm.DB) (domain.UsersRepo, func(), error) {\n\ta := &UsersRepo{db: db}\n\treturn a, func() {}, nil\n}\n"
  },
  {
    "path": "app/db/repo/users_test.go",
    "content": "package repo_test\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\n\t\"golang.org/x/crypto/bcrypt\"\n\n\t\"github.com/aristat/golang-example-app/app/db\"\n\t\"github.com/aristat/golang-example-app/app/db/domain\"\n\n\tmocket \"github.com/selvatico/go-mocket\"\n\n\t\"github.com/aristat/golang-example-app/app/db/repo\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nvar customInsertError = errors.New(\"sql: custom insert error\")\n\nfunc TestCreateUser(t *testing.T) {\n\tmocket.Catcher.Logging = true\n\n\tdbManager, _, e := db.BuildTest()\n\tassert.Nil(t, e, \"DB manager error should be nil\")\n\n\tuserRepo, _, e := repo.NewUsersRepo(dbManager.DB)\n\tassert.Nil(t, e, \"Repo error should be nil\")\n\n\tdefaultEmail := \"test@gmail.com\"\n\tdefaultPassword := \"123456789\"\n\tprimaryKey := 333\n\n\tmockCreateWithError := func() {\n\t\tmocket.Catcher.\n\t\t\tReset().\n\t\t\tNewMock().\n\t\t\tWithQuery(\"INSERT  INTO \\\"users\\\" (\\\"email\\\",\\\"encrypted_password\\\") VALUES ($1,$2)\").\n\t\t\tWithArgs(defaultEmail, defaultPassword).\n\t\t\tWithError(customInsertError)\n\t}\n\tmockCreate := func() {\n\t\treply := []map[string]interface{}{{\"id\": primaryKey}}\n\t\tmocket.Catcher.\n\t\t\tReset().\n\t\t\tNewMock().\n\t\t\tWithQuery(\"INSERT  INTO \\\"users\\\" (\\\"email\\\",\\\"encrypted_password\\\") VALUES ($1,$2)\").\n\t\t\tWithArgs(defaultEmail, defaultPassword).\n\t\t\tWithReply(reply)\n\t}\n\n\ttests := []struct {\n\t\tname    string\n\t\tmock    func()\n\t\tasserts func(user *domain.User, err error)\n\t}{\n\t\t{\n\t\t\tname: \"USER NOT CREATED\",\n\t\t\tmock: mockCreateWithError,\n\t\t\tasserts: func(user *domain.User, err error) {\n\t\t\t\tassert.Nil(t, user, \"user should be nil\")\n\t\t\t\tassert.NotNil(t, err, \"err should not be nil\")\n\t\t\t\tassert.Equal(t, customInsertError.Error(), err.Error())\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"USER CREATED\",\n\t\t\tmock: mockCreate,\n\t\t\tasserts: func(user *domain.User, err error) {\n\t\t\t\tassert.Equal(t, primaryKey, user.ID)\n\t\t\t\tassert.Nil(t, err, \"err should be nil\")\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\ttest.mock()\n\n\t\t\tuser, err := userRepo.CreateUser(defaultEmail, defaultPassword)\n\t\t\ttest.asserts(user, err)\n\t\t})\n\t}\n}\n\nfunc TestFindByEmail(t *testing.T) {\n\tmocket.Catcher.Logging = true\n\n\tdbManager, _, e := db.BuildTest()\n\tassert.Nil(t, e, \"DB manager error should be nil\")\n\n\tuserRepo, _, e := repo.NewUsersRepo(dbManager.DB)\n\tassert.Nil(t, e, \"Repo error should be nil\")\n\n\tePassword, e := bcrypt.GenerateFromPassword([]byte(\"12345\"), 8)\n\tassert.Nil(t, e, \"Password is correct\")\n\n\tdefaultEmail := \"test@gmail.com\"\n\tmockSelect := func() {\n\t\treply := []map[string]interface{}{{\"id\": 1, \"email\": defaultEmail, \"encrypted_password\": ePassword}}\n\t\tmocket.Catcher.Reset().NewMock().WithQuery(`WHERE (users.email = $1) LIMIT 1`).WithArgs(defaultEmail).WithReply(reply)\n\t}\n\n\ttests := []struct {\n\t\tname    string\n\t\tmock    func()\n\t\tasserts func(user *domain.User, err error)\n\t}{\n\t\t{\n\t\t\tname: \"USER IS EMPTY\",\n\t\t\tmock: func() {},\n\t\t\tasserts: func(user *domain.User, err error) {\n\t\t\t\tassert.Equal(t, \"\", user.Email, \"email should be equals\")\n\t\t\t\tassert.NotNil(t, err, \"err should not be nil\")\n\t\t\t\tassert.Equal(t, err.Error(), \"record not found\", \"error should be corrects\")\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"USER EXIST\",\n\t\t\tmock: mockSelect,\n\t\t\tasserts: func(user *domain.User, err error) {\n\t\t\t\tassert.Equal(t, defaultEmail, user.Email, \"email should be equals\")\n\t\t\t\tassert.Nil(t, e, \"err should be nil\")\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tmocket.Catcher.Reset()\n\t\t\ttest.mock()\n\n\t\t\tuser, err := userRepo.FindByEmail(defaultEmail)\n\t\t\ttest.asserts(user, err)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "app/db/wire_gen.go",
    "content": "// Code generated by Wire. DO NOT EDIT.\n\n//go:generate go run github.com/google/wire/cmd/wire\n//go:build !wireinject\n// +build !wireinject\n\npackage db\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/config\"\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\t\"github.com/aristat/golang-example-app/app/logger\"\n)\n\nimport (\n\t_ \"github.com/lib/pq\"\n)\n\n// Injectors from injector.go:\n\nfunc Build() (*Manager, func(), error) {\n\tcontext, cleanup, err := entrypoint.ContextProvider()\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tviper, cleanup2, err := config.Provider()\n\tif err != nil {\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tloggerConfig, cleanup3, err := logger.ProviderCfg(viper)\n\tif err != nil {\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tzap, cleanup4, err := logger.Provider(context, loggerConfig)\n\tif err != nil {\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tdbConfig, cleanup5, err := Cfg(viper)\n\tif err != nil {\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tdb, cleanup6, err := ProviderGORM(context, zap, dbConfig)\n\tif err != nil {\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tmanager, cleanup7, err := Provider(context, zap, dbConfig, db)\n\tif err != nil {\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\treturn manager, func() {\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t}, nil\n}\n\nfunc BuildTest() (*Manager, func(), error) {\n\tcontext, cleanup, err := entrypoint.ContextProviderTest()\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tloggerConfig, cleanup2, err := logger.ProviderCfgTest()\n\tif err != nil {\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tmock, cleanup3, err := logger.ProviderTest(context, loggerConfig)\n\tif err != nil {\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tdbConfig, cleanup4, err := CfgTest()\n\tif err != nil {\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tdb, cleanup5, err := ProviderGORMTest()\n\tif err != nil {\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tmanager, cleanup6, err := Provider(context, mock, dbConfig, db)\n\tif err != nil {\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\treturn manager, func() {\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t}, nil\n}\n"
  },
  {
    "path": "app/entrypoint/entrypoint.go",
    "content": "package entrypoint\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"sync\"\n\n\t\"github.com/spf13/viper\"\n)\n\nvar (\n\tvi          *viper.Viper\n\tmu          sync.Mutex\n\treloadCh    = make(chan struct{})\n\tshutdownCtx context.Context\n\tcancelFn    context.CancelFunc\n\tep          *EntryPoint\n\twd          string\n)\n\nconst prefix = \"app.entrypoint\"\n\nfunc init() {\n\tshutdownCtx, cancelFn = context.WithCancel(context.Background())\n}\n\n// Viper returns instance of Viper\nfunc Viper() *viper.Viper {\n\tmu.Lock()\n\tdefer mu.Unlock()\n\tif vi != nil {\n\t\treturn vi\n\t}\n\tvi = viper.GetViper()\n\treturn vi\n}\n\n// Initialize returns instance of entry point singleton manager, workDir uses to attach templates\nfunc Initialize(workDir string, v *viper.Viper) (*EntryPoint, error) {\n\tmu.Lock()\n\tdefer mu.Unlock()\n\tif ep != nil {\n\t\treturn ep, nil\n\t}\n\tif len(workDir) > 0 {\n\t\twd = workDir\n\t} else {\n\t\twd, _ = os.Getwd()\n\t}\n\tvi, ep = v, &EntryPoint{}\n\treturn ep, nil\n}\n\n// OnShutdown subscribe on shutdown event for gracefully exit via context.\nfunc OnShutdown() context.Context {\n\treturn shutdownCtx\n}\n\n// OnReload subscribe on reload event.\nfunc OnReload() <-chan struct{} {\n\treturn reloadCh\n}\n\n// EntryPoint manager of single point of application\ntype EntryPoint struct {\n}\n\n// Shutdown raise shutdown event.\nfunc Shutdown(ctx context.Context, code int) {\n\tmu.Lock()\n\tdefer mu.Unlock()\n\tcancelFn()\n\tif _, ok := ctx.Deadline(); ok {\n\t\t<-ctx.Done()\n\t}\n}\n\n// Reload raise reload event.\nfunc (e *EntryPoint) Reload() {\n\tmu.Lock()\n\tdefer mu.Unlock()\n\tch := reloadCh\n\treloadCh = make(chan struct{})\n\tclose(ch)\n}\n\n// WorkDir returns current work directory\nfunc WorkDir() string {\n\treturn wd\n}\n"
  },
  {
    "path": "app/entrypoint/entrypoint_test.go",
    "content": "package entrypoint_test\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestInitialize(t *testing.T) {\n\twd, _ := filepath.Abs(os.Getenv(\"APP_WD\"))\n\tentryPoint, err := entrypoint.Initialize(wd, nil)\n\n\tassert.Nil(t, err, \"err should be nil\")\n\tassert.NotNil(t, entryPoint, \"entryPoint should not be nil\")\n}\n"
  },
  {
    "path": "app/entrypoint/provider.go",
    "content": "package entrypoint\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/google/wire\"\n)\n\n// ContextProvider\nfunc ContextProvider() (context.Context, func(), error) {\n\tc := OnShutdown()\n\treturn c, func() {}, nil\n}\n\n// ContextProviderTest\nfunc ContextProviderTest() (context.Context, func(), error) {\n\t// initializing\n\twd, _ := filepath.Abs(os.Getenv(\"APP_WD\"))\n\t_, err := Initialize(wd, nil)\n\n\tc := context.Background()\n\treturn c, func() {}, err\n}\n\nvar (\n\tProviderProductionSet = wire.NewSet(ContextProvider)\n\tProviderTestSet       = wire.NewSet(ContextProviderTest)\n)\n"
  },
  {
    "path": "app/graphql/graphql.go",
    "content": "package graphql\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/99designs/gqlgen/graphql/handler\"\n\n\t\"github.com/99designs/gqlgen/graphql/handler/extension\"\n\t\"github.com/99designs/gqlgen/graphql/handler/lru\"\n\t\"github.com/99designs/gqlgen/graphql/handler/transport\"\n\n\tgqlgen \"github.com/99designs/gqlgen/graphql\"\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/aristat/golang-example-app/generated/graphql\"\n\t\"github.com/go-chi/chi/v5\"\n\t\"github.com/vektah/gqlparser/v2/gqlerror\"\n)\n\nconst (\n\tprefix = \"app.graphql\"\n)\n\nvar errInternalServer = errors.New(\"internal server error\")\n\n// GraphQL\ntype GraphQL struct {\n\tctx      context.Context\n\tresolver *graphql.Config\n\tlog      logger.Logger\n\tcfg      Config\n}\n\n// Use\nfunc (g *GraphQL) Use(router *chi.Mux) {\n\trouter.Use(g.cfg.Middleware...)\n}\n\n// Routers\nfunc (g *GraphQL) Routers(router chi.Router) {\n\tsrv := handler.New(graphql.NewExecutableSchema(*g.resolver))\n\n\tsrv.AddTransport(transport.Websocket{\n\t\tKeepAlivePingInterval: 10 * time.Second,\n\t})\n\tsrv.AddTransport(transport.Options{})\n\tsrv.AddTransport(transport.GET{})\n\tsrv.AddTransport(transport.POST{})\n\tsrv.AddTransport(transport.MultipartForm{})\n\n\tsrv.SetQueryCache(lru.New(1000))\n\n\tif g.cfg.Introspection {\n\t\tsrv.Use(extension.Introspection{})\n\t}\n\tsrv.Use(extension.AutomaticPersistedQuery{\n\t\tCache: lru.New(100),\n\t})\n\n\tsrv.SetRecoverFunc(func(ctx context.Context, err interface{}) error {\n\t\tg.log.Alert(\"unhandled panic, err: %v\", logger.Args(err))\n\t\treturn nil\n\t})\n\tsrv.SetErrorPresenter(func(ctx context.Context, e error) *gqlerror.Error {\n\t\tif e != nil {\n\t\t\tg.log.Alert(\"recover on middleware, err: %v\", logger.Args(e))\n\t\t\tgoto done\n\t\t}\n\t\te = errInternalServer\n\tdone:\n\t\treturn gqlgen.DefaultErrorPresenter(ctx, e)\n\t})\n\n\tif g.cfg.Debug {\n\t\tsrv.AroundResponses(func(ctx context.Context, next gqlgen.ResponseHandler) *gqlgen.Response {\n\t\t\tstartTime := time.Now()\n\t\t\trc := gqlgen.GetOperationContext(ctx)\n\t\t\tresp := next(ctx)\n\t\t\tg.log.Debug(\"\\nVARS:\\n%+v\\nQUERY:\\n%v\\nRESPONSE:\\n%v\\nERROR:\\n%v\\n\",\n\t\t\t\tlogger.Args(rc.Variables, strings.TrimRight(rc.RawQuery, \"\\n\"), string(resp.Data), resp.Errors),\n\t\t\t\tlogger.WithFields(logger.Fields{\n\t\t\t\t\t\"time\": time.Since(startTime).String(),\n\t\t\t\t}),\n\t\t\t)\n\t\t\treturn resp\n\t\t})\n\t}\n\n\trouter.Handle(\"/query\", srv)\n}\n\n// Config\ntype Config struct {\n\tDebug         bool\n\tIntrospection bool\n\tName          string\n\tMiddleware    []func(http.Handler) http.Handler\n}\n\n// New\nfunc New(ctx context.Context, resolver graphql.Config, log logger.Logger, cfg Config) *GraphQL {\n\tlog = log.WithFields(logger.Fields{\"service\": prefix})\n\treturn &GraphQL{\n\t\tctx:      ctx,\n\t\tresolver: &resolver,\n\t\tcfg:      cfg,\n\t\tlog:      log,\n\t}\n}\n"
  },
  {
    "path": "app/graphql/provider.go",
    "content": "package graphql\n\nimport (\n\t\"context\"\n\n\t\"github.com/aristat/golang-example-app/app/graphql_resolver\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/aristat/golang-example-app/generated/graphql\"\n\t\"github.com/google/wire\"\n\t\"github.com/spf13/viper\"\n)\n\n// Cfg\nfunc Cfg(cfg *viper.Viper) (Config, func(), error) {\n\tc := Config{}\n\te := cfg.UnmarshalKey(\"graphql\", &c)\n\tif e != nil {\n\t\treturn c, func() {}, e\n\t}\n\tif cfg.IsSet(\"debug\") && !c.Debug {\n\t\tc.Debug = cfg.GetBool(\"debug\")\n\t}\n\treturn c, func() {}, nil\n}\n\n// CfgTest\nfunc CfgTest() (Config, func(), error) {\n\treturn Config{}, func() {}, nil\n}\n\n// Provider\nfunc Provider(ctx context.Context, resolver graphql.Config, log logger.Logger, cfg Config) (*GraphQL, func(), error) {\n\tg := New(ctx, resolver, log, cfg)\n\treturn g, func() {}, nil\n}\n\nvar (\n\tProviderProductionSet = wire.NewSet(Provider, Cfg, graphql_resolver.ProviderProductionSet)\n\tProviderTestSet       = wire.NewSet(Provider, CfgTest, graphql_resolver.ProviderTestSet)\n)\n"
  },
  {
    "path": "app/graphql_resolver/injector.go",
    "content": "// +build wireinject\n\npackage graphql_resolver\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/db\"\n\t\"github.com/aristat/golang-example-app/app/db/repo\"\n\t\"github.com/aristat/golang-example-app/app/provider\"\n\t\"github.com/aristat/golang-example-app/generated/graphql\"\n\t\"github.com/google/wire\"\n)\n\n// Build\nfunc Build() (graphql.Config, func(), error) {\n\tpanic(wire.Build(ProviderProductionSet, repo.ProviderProductionSet, db.ProviderProductionSet, provider.AwareProductionSet))\n}\n\nfunc BuildTest() (graphql.Config, func(), error) {\n\tpanic(wire.Build(ProviderTestSet, repo.ProviderTestSet, db.ProviderTestSet, provider.AwareTestSet))\n}\n"
  },
  {
    "path": "app/graphql_resolver/mock.go",
    "content": "package graphql_resolver\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/aristat/golang-example-app/generated/resources/proto/products\"\n)\n\ntype ProductServerMock struct {\n\tproducts.UnimplementedProductsServer\n}\n\nfunc (s *ProductServerMock) ListProduct(ctx context.Context, in *products.ListProductIn) (*products.ListProductOut, error) {\n\tproductIds := []int64{1, 2, 3, 4, 5}\n\tout := &products.ListProductOut{Status: products.ListProductOut_OK, Products: []*products.Product{}}\n\n\tfor _, id := range productIds {\n\t\tout.Products = append(out.Products, &products.Product{Id: id, Name: fmt.Sprintf(\"product_%d\", id)})\n\t}\n\n\treturn out, nil\n}\n"
  },
  {
    "path": "app/graphql_resolver/product.go",
    "content": "package graphql_resolver\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/aristat/golang-example-app/app/dataloader\"\n\n\t\"github.com/aristat/golang-example-app/app/db/domain\"\n\n\t\"github.com/aristat/golang-example-app/app/common\"\n\t\"github.com/aristat/golang-example-app/app/grpc\"\n\t\"github.com/aristat/golang-example-app/generated/graphql\"\n\t\"github.com/aristat/golang-example-app/generated/resources/proto/products\"\n\t\"github.com/spf13/cast\"\n)\n\ntype productsQueryResolver struct{ *Resolver }\ntype productResolver struct{ *Resolver }\n\nfunc (r *Resolver) ProductsQuery() graphql.ProductsQueryResolver {\n\treturn &productsQueryResolver{r}\n}\n\n// QUERY\n\nfunc (r *queryResolver) Products(ctx context.Context) (*graphql.ProductsQuery, error) {\n\treturn &graphql.ProductsQuery{}, nil\n}\n\nfunc (r *productsQueryResolver) List(ctx context.Context, obj *graphql.ProductsQuery) (*graphql.ProductsListOut, error) {\n\tconn, d, err := grpc.GetConnGRPC(r.pollManager, common.SrvProducts)\n\tdefer d()\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tc := products.NewProductsClient(conn)\n\n\tctx, cancel := context.WithTimeout(ctx, time.Second*time.Duration(r.cfg.ProductTimeout))\n\tdefer cancel()\n\n\tproductOut, err := c.ListProduct(ctx, &products.ListProductIn{Id: 1})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlist := make([]*domain.Product, len(productOut.Products))\n\tfor i, product := range productOut.Products {\n\t\tlist[i] = &domain.Product{\n\t\t\tID:   cast.ToInt(&product.Id),\n\t\t\tName: product.Name,\n\t\t}\n\t}\n\n\treturn &graphql.ProductsListOut{Products: list}, nil\n}\n\nfunc (r *queryResolver) ProductsRoot(ctx context.Context) ([]*domain.Product, error) {\n\treturn []*domain.Product{{ID: 1, Name: \"test1\"}, {ID: 2, Name: \"test2\"}}, nil\n}\n\nfunc (r *Resolver) Product() graphql.ProductResolver {\n\treturn &productResolver{r}\n}\n\nfunc (r *productResolver) ProductItems(ctx context.Context, obj *domain.Product) ([]*domain.ProductItem, error) {\n\tr.log.Info(\"ProductItems Start Request\")\n\treturn dataloader.CtxLoaders(ctx).ProductItemsByProduct.Load(obj.ID)\n}\n"
  },
  {
    "path": "app/graphql_resolver/product_test.go",
    "content": "package graphql_resolver_test\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"log\"\n\t\"net\"\n\t\"os\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/aristat/golang-example-app/app/common\"\n\n\t\"github.com/aristat/golang-example-app/generated/resources/proto/products\"\n\n\t\"google.golang.org/grpc\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/aristat/golang-example-app/app/graphql_resolver\"\n\tgrpc1 \"github.com/aristat/golang-example-app/app/grpc\"\n\tgraphql1 \"github.com/aristat/golang-example-app/generated/graphql\"\n)\n\nvar (\n\tproductServerHost = \"localhost\"\n\tgrpcPort          string\n)\n\nfunc TestMain(m *testing.M) {\n\tlis, err := net.Listen(\"tcp\", \":0\")\n\tif err != nil {\n\t\tlog.Fatalf(err.Error())\n\t}\n\tdefer lis.Close()\n\n\tgrpcPort = \":\" + strconv.Itoa(lis.Addr().(*net.TCPAddr).Port)\n\ts := grpc.NewServer()\n\tproducts.RegisterProductsServer(s, &graphql_resolver.ProductServerMock{})\n\n\tgo func() {\n\t\tif err := s.Serve(lis); err != nil {\n\t\t\tlog.Fatalf(\"Server exited with error: %v\", err)\n\t\t}\n\t}()\n\n\tcode := m.Run()\n\n\tos.Exit(code)\n}\n\nfunc TestList(t *testing.T) {\n\tvar opts []grpc.DialOption\n\tctx := context.Background()\n\topts = append(opts, grpc.WithInsecure())\n\n\tpool, _ := grpc1.NewPool(ctx, common.SrvProducts, productServerHost+grpcPort, grpc1.ConnOptions(opts...))\n\tgrpc1.SetPool(pool, common.SrvProducts)\n\n\tcfg, _, err := graphql_resolver.BuildTest()\n\tif err != nil {\n\t\tassert.Failf(t, \"graphql_resolver instance failed, err: %v\", err.Error())\n\t\treturn\n\t}\n\n\tobj := graphql1.ProductsQuery{}\n\n\tout, err := cfg.Resolvers.ProductsQuery().List(ctx, &obj)\n\tif err != nil {\n\t\tassert.Failf(t, \"request failed, err: %v\", err.Error())\n\t\treturn\n\t}\n\n\tjsonProducts, _ := json.Marshal(out.Products)\n\tt.Log(string(jsonProducts))\n\tassert.Equal(t, len(out.Products), 5)\n}\n"
  },
  {
    "path": "app/graphql_resolver/provider.go",
    "content": "package graphql_resolver\n\nimport (\n\t\"context\"\n\n\t\"github.com/casbin/casbin\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/aristat/golang-example-app/generated/graphql\"\n\t\"github.com/google/wire\"\n\t\"github.com/spf13/viper\"\n)\n\n// Cfg\nfunc Cfg(cfg *viper.Viper) (Config, func(), error) {\n\tc := Config{}\n\te := cfg.UnmarshalKey(\"graphql_resolver\", &c)\n\treturn c, func() {}, e\n}\n\n// CfgTest\nfunc CfgTest() (Config, func(), error) {\n\treturn Config{ProductTimeout: 5}, func() {}, nil\n}\n\nvar ProviderManagers = wire.NewSet(\n\twire.Struct(new(Managers), \"*\"),\n)\n\n// Provider\nfunc Provider(ctx context.Context, log logger.Logger, cfg Config, enforcer *casbin.Enforcer, managers Managers) (graphql.Config, func(), error) {\n\tc := New(ctx, log, cfg, enforcer, managers)\n\treturn c, func() {}, nil\n}\n\nvar (\n\tProviderProductionSet = wire.NewSet(Provider, Cfg, ProviderManagers)\n\tProviderTestSet       = wire.NewSet(Provider, CfgTest, ProviderManagers)\n)\n"
  },
  {
    "path": "app/graphql_resolver/resolver.go",
    "content": "package graphql_resolver\n\nimport (\n\t\"context\"\n\t\"strings\"\n\n\t\"github.com/pkg/errors\"\n\n\t\"github.com/99designs/gqlgen/graphql\"\n\t\"github.com/casbin/casbin\"\n\n\t\"github.com/aristat/golang-example-app/app/grpc\"\n\n\t\"github.com/aristat/golang-example-app/app/db/repo\"\n\n\tappContext \"github.com/aristat/golang-example-app/app/context\"\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\tgraphql1 \"github.com/aristat/golang-example-app/generated/graphql\"\n)\n\nvar prefix = \"app.graphql_resolver\"\nvar errPermission = errors.WithMessage(errors.New(\"No have permission\"), prefix)\n\n// Config\ntype Config struct {\n\tProductTimeout int\n}\n\n// Managers\ntype Managers struct {\n\tRepo        *repo.Repo\n\tPollManager *grpc.PoolManager\n}\n\ntype queryResolver struct{ *Resolver }\ntype mutationResolver struct{ *Resolver }\n\n// Resolver config graphql resolvers\ntype Resolver struct {\n\tctx         context.Context\n\tlog         logger.Logger\n\tcfg         Config\n\trepo        *repo.Repo\n\tpollManager *grpc.PoolManager\n}\n\n// Mutation returns root graphql mutation graphql_resolver\nfunc (r *Resolver) Mutation() graphql1.MutationResolver {\n\treturn &mutationResolver{r}\n}\n\n// Query returns root graphql query graphql_resolver\nfunc (r *Resolver) Query() graphql1.QueryResolver {\n\treturn &queryResolver{r}\n}\n\n// New\nfunc New(ctx context.Context, log logger.Logger, cfg Config, enforcer *casbin.Enforcer, managers Managers) graphql1.Config {\n\tlog = log.WithFields(logger.Fields{\"service\": prefix})\n\tc := graphql1.Config{\n\t\tResolvers: &Resolver{\n\t\t\tctx:         ctx,\n\t\t\tlog:         log,\n\t\t\tcfg:         cfg,\n\t\t\trepo:        managers.Repo,\n\t\t\tpollManager: managers.PollManager,\n\t\t},\n\t}\n\n\tc.Directives.HasUsersPermission = func(ctx context.Context, obj interface{}, next graphql.Resolver, role graphql1.UsersPermissionEnum) (res interface{}, err error) {\n\t\tm, err := appContext.NewManager(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tmapping := m.ToMapping()\n\t\tif !enforcer.Enforce(mapping.Subject, \"users\", strings.ToLower(string(role))) {\n\t\t\treturn nil, errPermission\n\t\t}\n\n\t\treturn next(ctx)\n\t}\n\n\treturn c\n}\n"
  },
  {
    "path": "app/graphql_resolver/resolver_gen.go",
    "content": "package graphql_resolver\n"
  },
  {
    "path": "app/graphql_resolver/user.go",
    "content": "package graphql_resolver\n\nimport (\n\t\"context\"\n\n\t\"github.com/aristat/golang-example-app/app/common\"\n\n\tgraphql1 \"github.com/aristat/golang-example-app/generated/graphql\"\n\t\"github.com/spf13/cast\"\n)\n\ntype usersQueryResolver struct{ *Resolver }\ntype usersMutationResolver struct{ *Resolver }\n\nfunc (r *Resolver) UsersMutation() graphql1.UsersMutationResolver {\n\treturn &usersMutationResolver{r}\n}\nfunc (r *Resolver) UsersQuery() graphql1.UsersQueryResolver {\n\treturn &usersQueryResolver{r}\n}\n\n// QUERY\n\nfunc (r *queryResolver) Users(ctx context.Context) (*graphql1.UsersQuery, error) {\n\treturn &graphql1.UsersQuery{}, nil\n}\n\nfunc (r *usersQueryResolver) One(ctx context.Context, obj *graphql1.UsersQuery, email string) (*graphql1.UsersOneOut, error) {\n\tuser, err := r.repo.Users.FindByEmail(email)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tuserData := &graphql1.UsersOneOut{\n\t\tID:    cast.ToString(&user.ID),\n\t\tEmail: user.Email,\n\t}\n\n\treturn userData, nil\n}\n\n// MUTATIONS\n\nfunc (r *mutationResolver) Users(ctx context.Context) (*graphql1.UsersMutation, error) {\n\treturn &graphql1.UsersMutation{}, nil\n}\n\nfunc (r *usersMutationResolver) CreateUser(ctx context.Context, obj *graphql1.UsersMutation, email string, password string) (*graphql1.UsersCreateOut, error) {\n\tencryptPassword, err := common.HashPassword(password, 8)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tuser, err := r.repo.Users.CreateUser(email, encryptPassword)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tuserData := &graphql1.UsersCreateOut{\n\t\tID:     cast.ToString(user.ID),\n\t\tEmail:  user.Email,\n\t\tStatus: graphql1.UsersCreateOutStatusOk,\n\t}\n\n\treturn userData, nil\n}\n"
  },
  {
    "path": "app/graphql_resolver/user_test.go",
    "content": "package graphql_resolver_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/spf13/cast\"\n\n\t\"golang.org/x/crypto/bcrypt\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/aristat/golang-example-app/app/graphql_resolver\"\n\tgraphql1 \"github.com/aristat/golang-example-app/generated/graphql\"\n\tmocket \"github.com/selvatico/go-mocket\"\n)\n\ntype UserParams struct {\n\ttestName string\n\tid       int\n\temail    string\n}\n\nfunc TestOne(t *testing.T) {\n\tctx := context.Background()\n\n\tcfg, _, err := graphql_resolver.BuildTest()\n\tif err != nil {\n\t\tassert.Failf(t, \"graphql_resolver instance failed, err: %v\", err.Error())\n\t\treturn\n\t}\n\n\tePassword, e := bcrypt.GenerateFromPassword([]byte(\"12345\"), 8)\n\tassert.Nil(t, e, \"Password is correct\")\n\n\tobj := graphql1.UsersQuery{}\n\tdefaultEmail := \"test@gmail.com\"\n\tid := 1\n\tmockDefaultResult := func() {\n\t\treply := []map[string]interface{}{{\"id\": id, \"email\": defaultEmail, \"encrypted_password\": ePassword}}\n\t\tmocket.Catcher.Reset().NewMock().WithQuery(`WHERE (users.email = $1) LIMIT 1`).WithArgs(defaultEmail).WithReply(reply)\n\t}\n\n\ttests := []struct {\n\t\tuserParams UserParams\n\t\tmock       func()\n\t\tasserts    func(userParams UserParams, out *graphql1.UsersOneOut, err error)\n\t}{\n\t\t{\n\t\t\tuserParams: UserParams{id: 2, email: \"test1@gmail.com\", testName: \"USER NOT EXIST\"},\n\t\t\tmock:       mockDefaultResult,\n\t\t\tasserts: func(userParams UserParams, out *graphql1.UsersOneOut, err error) {\n\t\t\t\tassert.NotNil(t, err, \"err should not be nil\")\n\t\t\t\tassert.Nil(t, out, \"out should be nil\")\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tuserParams: UserParams{id: id, email: defaultEmail, testName: \"USER EXIST\"},\n\t\t\tmock:       mockDefaultResult,\n\t\t\tasserts: func(userParams UserParams, out *graphql1.UsersOneOut, err error) {\n\t\t\t\tassert.Nil(t, err, \"err should be nil\")\n\t\t\t\tassert.Equal(t, cast.ToString(userParams.id), out.ID, \"id should be equals\")\n\t\t\t\tassert.Equal(t, userParams.email, out.Email, \"email should be equals\")\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(test.userParams.testName, func(t *testing.T) {\n\t\t\tmocket.Catcher.Reset()\n\t\t\ttest.mock()\n\n\t\t\tout, err := cfg.Resolvers.UsersQuery().One(ctx, &obj, test.userParams.email)\n\t\t\ttest.asserts(test.userParams, out, err)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "app/graphql_resolver/wire_gen.go",
    "content": "// Code generated by Wire. DO NOT EDIT.\n\n//go:generate go run github.com/google/wire/cmd/wire\n//go:build !wireinject\n// +build !wireinject\n\npackage graphql_resolver\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/casbin\"\n\t\"github.com/aristat/golang-example-app/app/config\"\n\t\"github.com/aristat/golang-example-app/app/db\"\n\t\"github.com/aristat/golang-example-app/app/db/repo\"\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\t\"github.com/aristat/golang-example-app/app/grpc\"\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/aristat/golang-example-app/app/tracing\"\n\t\"github.com/aristat/golang-example-app/generated/graphql\"\n)\n\n// Injectors from injector.go:\n\n// Build\nfunc Build() (graphql.Config, func(), error) {\n\tcontext, cleanup, err := entrypoint.ContextProvider()\n\tif err != nil {\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tviper, cleanup2, err := config.Provider()\n\tif err != nil {\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tloggerConfig, cleanup3, err := logger.ProviderCfg(viper)\n\tif err != nil {\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tzap, cleanup4, err := logger.Provider(context, loggerConfig)\n\tif err != nil {\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tgraphql_resolverConfig, cleanup5, err := Cfg(viper)\n\tif err != nil {\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tenforcer, cleanup6, err := casbin.Provider()\n\tif err != nil {\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tdbConfig, cleanup7, err := db.Cfg(viper)\n\tif err != nil {\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tgormDB, cleanup8, err := db.ProviderGORM(context, zap, dbConfig)\n\tif err != nil {\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tusersRepo, cleanup9, err := repo.NewUsersRepo(gormDB)\n\tif err != nil {\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\trepoRepo, cleanup10, err := repo.Provider(usersRepo)\n\tif err != nil {\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tconfiguration, cleanup11, err := tracing.Cfg(viper)\n\tif err != nil {\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\ttracerProvider, cleanup12, err := tracing.Provider(context, configuration, zap)\n\tif err != nil {\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tgrpcConfig, cleanup13, err := grpc.Cfg(viper)\n\tif err != nil {\n\t\tcleanup12()\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tpoolManager, cleanup14, err := grpc.Provider(context, tracerProvider, zap, grpcConfig)\n\tif err != nil {\n\t\tcleanup13()\n\t\tcleanup12()\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tmanagers := Managers{\n\t\tRepo:        repoRepo,\n\t\tPollManager: poolManager,\n\t}\n\tgraphqlConfig, cleanup15, err := Provider(context, zap, graphql_resolverConfig, enforcer, managers)\n\tif err != nil {\n\t\tcleanup14()\n\t\tcleanup13()\n\t\tcleanup12()\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\treturn graphqlConfig, func() {\n\t\tcleanup15()\n\t\tcleanup14()\n\t\tcleanup13()\n\t\tcleanup12()\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t}, nil\n}\n\nfunc BuildTest() (graphql.Config, func(), error) {\n\tcontext, cleanup, err := entrypoint.ContextProviderTest()\n\tif err != nil {\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tloggerConfig, cleanup2, err := logger.ProviderCfgTest()\n\tif err != nil {\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tmock, cleanup3, err := logger.ProviderTest(context, loggerConfig)\n\tif err != nil {\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tgraphql_resolverConfig, cleanup4, err := CfgTest()\n\tif err != nil {\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tenforcer, cleanup5, err := casbin.ProviderTest()\n\tif err != nil {\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tgormDB, cleanup6, err := db.ProviderGORMTest()\n\tif err != nil {\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tusersRepo, cleanup7, err := repo.NewUsersRepo(gormDB)\n\tif err != nil {\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\trepoRepo, cleanup8, err := repo.Provider(usersRepo)\n\tif err != nil {\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\ttracerProvider, cleanup9, err := tracing.ProviderTest()\n\tif err != nil {\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tgrpcConfig, cleanup10, err := grpc.CfgTest()\n\tif err != nil {\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tpoolManager, cleanup11, err := grpc.Provider(context, tracerProvider, mock, grpcConfig)\n\tif err != nil {\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\tmanagers := Managers{\n\t\tRepo:        repoRepo,\n\t\tPollManager: poolManager,\n\t}\n\tgraphqlConfig, cleanup12, err := Provider(context, mock, graphql_resolverConfig, enforcer, managers)\n\tif err != nil {\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn graphql.Config{}, nil, err\n\t}\n\treturn graphqlConfig, func() {\n\t\tcleanup12()\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t}, nil\n}\n"
  },
  {
    "path": "app/grpc/connection.go",
    "content": "package grpc\n\nimport (\n\t\"sync\"\n\n\t\"google.golang.org/grpc\"\n)\n\nvar (\n\tsrvMu   sync.Mutex\n\tpoolSrv = map[string]*Pool{}\n)\n\n// Set pool connections\nfunc SetPool(p *Pool, srv string) {\n\tif _, ok := poolSrv[srv]; !ok {\n\t\tsrvMu.Lock()\n\t\tdefer srvMu.Unlock()\n\t\tpoolSrv[srv] = p\n\t}\n}\n\n// Get client connection\nfunc GetConnGRPC(poolManager *PoolManager, srv string) (*grpc.ClientConn, Done, error) {\n\tif _, ok := poolSrv[srv]; !ok {\n\t\tsrvMu.Lock()\n\t\tdefer srvMu.Unlock()\n\t\tif _, ok := poolSrv[srv]; !ok {\n\t\t\tp, _, e := poolManager.NewPool(srv)\n\t\t\tif e != nil {\n\t\t\t\treturn nil, func() {}, e\n\t\t\t}\n\t\t\tpoolSrv[srv] = p\n\t\t}\n\t}\n\treturn poolSrv[srv].Get()\n}\n"
  },
  {
    "path": "app/grpc/manager.go",
    "content": "package grpc\n\nimport (\n\t\"context\"\n\t\"errors\"\n\n\t\"go.opentelemetry.io/otel/propagation\"\n\n\t\"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc\"\n\ttracesdk \"go.opentelemetry.io/otel/sdk/trace\"\n\n\t\"google.golang.org/grpc/credentials/insecure\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/keepalive\"\n)\n\nconst prefix = \"app.grpc\"\n\nvar errCfgInvalid = errors.New(\"cfg is not present or invalid\")\n\n// PoolManager\ntype PoolManager struct {\n\tctx     context.Context\n\ttracing *tracesdk.TracerProvider\n\tcfg     *Config\n\tlogger  logger.Logger\n}\n\n// New\nfunc (p *PoolManager) NewPool(service string) (_ *Pool, loaded bool, _ error) {\n\ts, ok := p.cfg.Services[service]\n\n\tif !ok {\n\t\treturn nil, false, errCfgInvalid\n\t}\n\n\tvar opts []grpc.DialOption\n\topts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))\n\n\tcl := s.ClientParameters\n\tif cl == nil {\n\t\tif p.cfg.ClientParameters != nil {\n\t\t\tcl = p.cfg.ClientParameters\n\t\t} else {\n\t\t\tcl = &keepalive.ClientParameters{}\n\t\t}\n\t}\n\n\topts = append(opts, grpc.WithKeepaliveParams(*cl))\n\topts = append(opts,\n\t\tgrpc.WithChainUnaryInterceptor(\n\t\t\tlogger.UnaryClientInterceptor(p.logger, true),\n\t\t\totelgrpc.UnaryClientInterceptor(otelgrpc.WithTracerProvider(p.tracing), otelgrpc.WithPropagators(propagation.TraceContext{})),\n\t\t),\n\t)\n\topts = append(opts,\n\t\tgrpc.WithChainStreamInterceptor(\n\t\t\tlogger.StreamClientInterceptor(p.logger, true),\n\t\t\totelgrpc.StreamClientInterceptor(otelgrpc.WithTracerProvider(p.tracing), otelgrpc.WithPropagators(propagation.TraceContext{})),\n\t\t),\n\t)\n\n\tpool, l := NewPool(p.ctx, service, s.Target,\n\t\tMaxConn(s.MaxConn),\n\t\tInitConn(s.InitConn),\n\t\tMaxLifeDuration(s.MaxLifeDuration),\n\t\tIdleTimeout(s.IdleTimeout),\n\t\tConnOptions(opts...),\n\t)\n\n\treturn pool, l, nil\n}\n\n// NewPoolManager\nfunc NewPoolManager(ctx context.Context, tracing *tracesdk.TracerProvider, logger logger.Logger, cfg *Config) *PoolManager {\n\treturn &PoolManager{ctx: ctx, tracing: tracing, cfg: cfg, logger: logger}\n}\n"
  },
  {
    "path": "app/grpc/pool.go",
    "content": "package grpc\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/pkg/errors\"\n\tgrpcpool \"github.com/processout/grpc-go-pool\"\n\t\"google.golang.org/grpc\"\n)\n\nvar (\n\tpoolList map[string]*Pool\n\tmu       sync.Mutex\n)\n\n// Done\ntype Done func()\n\ntype conn struct {\n\tconn *grpc.ClientConn\n\tpool *Pool\n\terr  error\n}\n\nfunc (c *conn) init() {\n\tc.conn, c.err = grpc.Dial(c.pool.target, c.pool.opts.dialOptions...)\n}\n\n// Pool\ntype Pool struct {\n\tid      string\n\tctx     context.Context\n\tservice string\n\tpool    *grpcpool.Pool\n\ttarget  string\n\topts    *opts\n}\n\n// Get\nfunc (p *Pool) Get() (*grpc.ClientConn, Done, error) {\n\tc, e := p.pool.Get(p.ctx)\n\treturn c.ClientConn, func() {\n\t\t_ = c.Close()\n\t}, errors.WithMessage(e, prefix)\n}\n\ntype opts struct {\n\tdialOptions     []grpc.DialOption\n\tinitConn        int\n\tmaxConn         int\n\tidleTimeout     time.Duration\n\tmaxLifeDuration time.Duration\n}\n\n// Option\ntype Option func(*opts) error\n\n// ConnOptions\nfunc ConnOptions(o ...grpc.DialOption) Option {\n\treturn func(f *opts) error {\n\t\tf.dialOptions = o\n\t\treturn nil\n\t}\n}\n\n// MaxConn\nfunc MaxConn(value int) Option {\n\treturn func(f *opts) error {\n\t\tf.maxConn = value\n\t\treturn nil\n\t}\n}\n\n// InitConn\nfunc InitConn(value int) Option {\n\treturn func(f *opts) error {\n\t\tf.initConn = value\n\t\treturn nil\n\t}\n}\n\n// MaxLifeDuration\nfunc MaxLifeDuration(value time.Duration) Option {\n\treturn func(f *opts) error {\n\t\tf.maxLifeDuration = value\n\t\treturn nil\n\t}\n}\n\n// IdleTimeout\nfunc IdleTimeout(value time.Duration) Option {\n\treturn func(f *opts) error {\n\t\tf.idleTimeout = value\n\t\treturn nil\n\t}\n}\n\n// NewPool\nfunc NewPool(ctx context.Context, service, target string, o ...Option) (_ *Pool, loaded bool) {\n\tmu.Lock()\n\tdefer mu.Unlock()\n\tif p := poolList[service]; p != nil {\n\t\treturn p, true\n\t}\n\tp := &Pool{\n\t\tid:      time.Now().String(),\n\t\tctx:     ctx,\n\t\tservice: service,\n\t\topts:    &opts{},\n\t\ttarget:  target,\n\t}\n\tfor _, option := range o {\n\t\t_ = option(p.opts)\n\t}\n\tfactory := func() (*grpc.ClientConn, error) {\n\t\tc := &conn{pool: p}\n\t\tc.init()\n\t\treturn c.conn, c.err\n\t}\n\tp.pool, _ = grpcpool.New(factory, p.opts.initConn, p.opts.maxConn, p.opts.idleTimeout, p.opts.maxLifeDuration)\n\treturn p, false\n}\n"
  },
  {
    "path": "app/grpc/provider.go",
    "content": "package grpc\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\ttracesdk \"go.opentelemetry.io/otel/sdk/trace\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\n\t\"github.com/google/wire\"\n\t\"github.com/spf13/viper\"\n\t\"google.golang.org/grpc/keepalive\"\n)\n\nvar (\n\tpm      *PoolManager\n\tmutexPM sync.Mutex\n)\n\n// Cfg\nfunc Cfg(cfg *viper.Viper) (*Config, func(), error) {\n\tc := &Config{}\n\te := cfg.UnmarshalKey(\"grpc\", c)\n\tif e != nil {\n\t\treturn c, func() {}, e\n\t}\n\treturn c, func() {}, e\n}\n\n// CfgTest\nfunc CfgTest() (*Config, func(), error) {\n\treturn &Config{}, func() {}, nil\n}\n\n// Service\ntype Service struct {\n\tTarget           string\n\tMaxConn          int\n\tInitConn         int\n\tMaxLifeDuration  time.Duration\n\tIdleTimeout      time.Duration\n\tClientParameters *keepalive.ClientParameters\n}\n\n// Config\ntype Config struct {\n\tServices         map[string]*Service\n\tClientParameters *keepalive.ClientParameters\n}\n\n// Provider\nfunc Provider(ctx context.Context, tracing *tracesdk.TracerProvider, logger logger.Logger, cfg *Config) (*PoolManager, func(), error) {\n\tmutexPM.Lock()\n\tdefer mutexPM.Unlock()\n\tif pm != nil {\n\t\treturn pm, func() {}, nil\n\t}\n\tpm = NewPoolManager(ctx, tracing, logger, cfg)\n\treturn pm, func() {}, nil\n}\n\nvar (\n\tProviderProductionSet = wire.NewSet(Provider, Cfg)\n\tProviderTestSet       = wire.NewSet(Provider, CfgTest)\n)\n"
  },
  {
    "path": "app/http/http.go",
    "content": "package http\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"sync\"\n\n\t\"github.com/go-chi/chi/v5\"\n\n\t\"github.com/go-session/session\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n)\n\nconst prefix = \"app.http\"\n\n// Config\ntype Config struct {\n\tDebug bool\n\tBind  string\n}\n\n// Http\ntype Http struct {\n\tctx     context.Context\n\tcfg     Config\n\tsession *session.Manager\n\tlog     logger.Logger\n\tmux     *chi.Mux\n}\n\n// ListenAndServe\nfunc (m *Http) ListenAndServe(wg *sync.WaitGroup, bind ...string) (server *http.Server) {\n\tbindAddress := m.cfg.Bind\n\n\tif len(bind) > 0 && len(bind[0]) > 0 {\n\t\tbindAddress = bind[0]\n\t}\n\n\tserver = &http.Server{\n\t\tAddr:    bindAddress,\n\t\tHandler: m.mux,\n\t}\n\n\tgo func() {\n\t\tdefer wg.Done()\n\n\t\tif err := server.ListenAndServe(); err != nil {\n\t\t\tif err != http.ErrServerClosed {\n\t\t\t\tm.log.Emergency(\"Server is shutdown with error, %v\", logger.Args(err))\n\t\t\t} else {\n\t\t\t\terr = nil\n\t\t\t}\n\t\t}\n\n\t\tm.log.Info(\"HTTP Server stopped successfully\")\n\t}()\n\n\treturn server\n}\n\n// New\nfunc New(ctx context.Context, mux *chi.Mux, log logger.Logger, cfg Config) *Http {\n\treturn &Http{\n\t\tctx: ctx,\n\t\tcfg: cfg,\n\t\tmux: mux,\n\t\tlog: log.WithFields(logger.Fields{\"service\": prefix}),\n\t}\n}\n"
  },
  {
    "path": "app/http/injector.go",
    "content": "// +build wireinject\n\npackage http\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/auth\"\n\t\"github.com/aristat/golang-example-app/app/db\"\n\t\"github.com/aristat/golang-example-app/app/db/repo\"\n\t\"github.com/aristat/golang-example-app/app/graphql\"\n\tproducts_router \"github.com/aristat/golang-example-app/app/http_routers/products-router\"\n\t\"github.com/aristat/golang-example-app/app/provider\"\n\t\"github.com/google/wire\"\n)\n\n// Build\nfunc Build() (*Http, func(), error) {\n\tpanic(wire.Build(\n\t\tProviderProductionSet,\n\t\tauth.ProviderProductionSet,\n\t\tgraphql.ProviderProductionSet,\n\t\tproducts_router.ProviderProductionSet,\n\t\trepo.ProviderProductionSet,\n\t\tdb.ProviderProductionSet,\n\t\tprovider.AwareProductionSet,\n\t))\n}\n"
  },
  {
    "path": "app/http/logger.go",
    "content": "package http\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/go-chi/chi/v5/middleware\"\n)\n\nfunc Logger(l logger.Logger) func(next http.Handler) http.Handler {\n\treturn func(next http.Handler) http.Handler {\n\t\tfn := func(w http.ResponseWriter, r *http.Request) {\n\t\t\tww := middleware.NewWrapResponseWriter(w, r.ProtoMajor)\n\n\t\t\tt1 := time.Now()\n\t\t\tdefer func() {\n\t\t\t\tl.Info(\"proto %s, path %s, lat %d, status %d, size %d, reqId %s\", logger.Args(\n\t\t\t\t\tr.Proto,\n\t\t\t\t\tr.URL.Path,\n\t\t\t\t\ttime.Since(t1),\n\t\t\t\t\tww.Status(),\n\t\t\t\t\tww.BytesWritten(),\n\t\t\t\t\tmiddleware.GetReqID(r.Context()),\n\t\t\t\t))\n\t\t\t}()\n\n\t\t\tnext.ServeHTTP(ww, r)\n\t\t}\n\t\treturn http.HandlerFunc(fn)\n\t}\n}\n"
  },
  {
    "path": "app/http/provider.go",
    "content": "package http\n\nimport (\n\t\"context\"\n\n\t\"github.com/riandyrn/otelchi\"\n\n\t\"github.com/aristat/golang-example-app/app/dataloader\"\n\n\tproducts_router \"github.com/aristat/golang-example-app/app/http_routers/products-router\"\n\n\t\"github.com/aristat/golang-example-app/app/auth\"\n\n\t\"github.com/aristat/golang-example-app/app/graphql\"\n\t\"github.com/go-chi/chi/v5\"\n\t\"github.com/go-chi/chi/v5/middleware\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\n\t\"github.com/google/wire\"\n\t\"github.com/spf13/viper\"\n)\n\nvar muxRouter *chi.Mux\n\n// Cfg\nfunc Cfg(cfg *viper.Viper) (Config, func(), error) {\n\tc := Config{}\n\te := cfg.UnmarshalKey(\"http\", &c)\n\tif e != nil {\n\t\treturn c, func() {}, e\n\t}\n\tc.Debug = cfg.GetBool(\"debug\")\n\treturn c, func() {}, nil\n}\n\n// CfgTest\nfunc CfgTest() (Config, func(), error) {\n\treturn Config{}, func() {}, nil\n}\n\n// Mux\nfunc Mux(managers Managers, log logger.Logger) (*chi.Mux, func(), error) {\n\tif muxRouter != nil {\n\t\treturn muxRouter, func() {}, nil\n\t}\n\n\tmuxRouter = chi.NewRouter()\n\tmuxRouter.Use(middleware.RequestID)\n\tmuxRouter.Use(Logger(log))\n\tmuxRouter.Use(otelchi.Middleware(\"http-server\", otelchi.WithChiRoutes(muxRouter)))\n\tmuxRouter.Use(dataloader.LoaderMiddleware)\n\n\tmanagers.products.Router.Run(muxRouter)\n\tmanagers.graphql.Routers(muxRouter.With(managers.authMiddleware.JWTHandler))\n\n\treturn muxRouter, func() {}, nil\n}\n\n// ServiceManagers\ntype Managers struct {\n\tproducts       *products_router.Manager\n\tauthMiddleware *auth.Middleware\n\tgraphql        *graphql.GraphQL\n}\n\nvar ProviderManagers = wire.NewSet(\n\twire.Struct(new(Managers), \"*\"),\n)\n\n// Provider\nfunc Provider(ctx context.Context, mux *chi.Mux, log logger.Logger, cfg Config) (*Http, func(), error) {\n\tg := New(ctx, mux, log, cfg)\n\treturn g, func() {}, nil\n}\n\nvar (\n\tProviderProductionSet = wire.NewSet(Provider, Cfg, Mux, ProviderManagers)\n\tProviderTestSet       = wire.NewSet(Provider, CfgTest)\n)\n"
  },
  {
    "path": "app/http/wire_gen.go",
    "content": "// Code generated by Wire. DO NOT EDIT.\n\n//go:generate go run github.com/google/wire/cmd/wire\n//go:build !wireinject\n// +build !wireinject\n\npackage http\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/auth\"\n\t\"github.com/aristat/golang-example-app/app/casbin\"\n\t\"github.com/aristat/golang-example-app/app/config\"\n\t\"github.com/aristat/golang-example-app/app/db\"\n\t\"github.com/aristat/golang-example-app/app/db/repo\"\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\t\"github.com/aristat/golang-example-app/app/graphql\"\n\t\"github.com/aristat/golang-example-app/app/graphql_resolver\"\n\t\"github.com/aristat/golang-example-app/app/grpc\"\n\t\"github.com/aristat/golang-example-app/app/http_routers/products-router\"\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/aristat/golang-example-app/app/tracing\"\n)\n\n// Injectors from injector.go:\n\n// Build\nfunc Build() (*Http, func(), error) {\n\tcontext, cleanup, err := entrypoint.ContextProvider()\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tviper, cleanup2, err := config.Provider()\n\tif err != nil {\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tloggerConfig, cleanup3, err := logger.ProviderCfg(viper)\n\tif err != nil {\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tzap, cleanup4, err := logger.Provider(context, loggerConfig)\n\tif err != nil {\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tconfiguration, cleanup5, err := tracing.Cfg(viper)\n\tif err != nil {\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\ttracerProvider, cleanup6, err := tracing.Provider(context, configuration, zap)\n\tif err != nil {\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tgrpcConfig, cleanup7, err := grpc.Cfg(viper)\n\tif err != nil {\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tpoolManager, cleanup8, err := grpc.Provider(context, tracerProvider, zap, grpcConfig)\n\tif err != nil {\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tserviceManagers := products_router.ServiceManagers{\n\t\tPoolManager: poolManager,\n\t}\n\tproducts_routerConfig, cleanup9, err := products_router.Cfg(viper)\n\tif err != nil {\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tmanager, cleanup10, err := products_router.Provider(context, zap, serviceManagers, products_routerConfig)\n\tif err != nil {\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tauthConfig, cleanup11, err := auth.ProviderCfg(viper)\n\tif err != nil {\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tmiddleware, cleanup12, err := auth.Provider(authConfig, zap)\n\tif err != nil {\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tgraphql_resolverConfig, cleanup13, err := graphql_resolver.Cfg(viper)\n\tif err != nil {\n\t\tcleanup12()\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tenforcer, cleanup14, err := casbin.Provider()\n\tif err != nil {\n\t\tcleanup13()\n\t\tcleanup12()\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tdbConfig, cleanup15, err := db.Cfg(viper)\n\tif err != nil {\n\t\tcleanup14()\n\t\tcleanup13()\n\t\tcleanup12()\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tgormDB, cleanup16, err := db.ProviderGORM(context, zap, dbConfig)\n\tif err != nil {\n\t\tcleanup15()\n\t\tcleanup14()\n\t\tcleanup13()\n\t\tcleanup12()\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tusersRepo, cleanup17, err := repo.NewUsersRepo(gormDB)\n\tif err != nil {\n\t\tcleanup16()\n\t\tcleanup15()\n\t\tcleanup14()\n\t\tcleanup13()\n\t\tcleanup12()\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\trepoRepo, cleanup18, err := repo.Provider(usersRepo)\n\tif err != nil {\n\t\tcleanup17()\n\t\tcleanup16()\n\t\tcleanup15()\n\t\tcleanup14()\n\t\tcleanup13()\n\t\tcleanup12()\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tmanagers := graphql_resolver.Managers{\n\t\tRepo:        repoRepo,\n\t\tPollManager: poolManager,\n\t}\n\tgraphqlConfig, cleanup19, err := graphql_resolver.Provider(context, zap, graphql_resolverConfig, enforcer, managers)\n\tif err != nil {\n\t\tcleanup18()\n\t\tcleanup17()\n\t\tcleanup16()\n\t\tcleanup15()\n\t\tcleanup14()\n\t\tcleanup13()\n\t\tcleanup12()\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tconfig2, cleanup20, err := graphql.Cfg(viper)\n\tif err != nil {\n\t\tcleanup19()\n\t\tcleanup18()\n\t\tcleanup17()\n\t\tcleanup16()\n\t\tcleanup15()\n\t\tcleanup14()\n\t\tcleanup13()\n\t\tcleanup12()\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tgraphQL, cleanup21, err := graphql.Provider(context, graphqlConfig, zap, config2)\n\tif err != nil {\n\t\tcleanup20()\n\t\tcleanup19()\n\t\tcleanup18()\n\t\tcleanup17()\n\t\tcleanup16()\n\t\tcleanup15()\n\t\tcleanup14()\n\t\tcleanup13()\n\t\tcleanup12()\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\thttpManagers := Managers{\n\t\tproducts:       manager,\n\t\tauthMiddleware: middleware,\n\t\tgraphql:        graphQL,\n\t}\n\tmux, cleanup22, err := Mux(httpManagers, zap)\n\tif err != nil {\n\t\tcleanup21()\n\t\tcleanup20()\n\t\tcleanup19()\n\t\tcleanup18()\n\t\tcleanup17()\n\t\tcleanup16()\n\t\tcleanup15()\n\t\tcleanup14()\n\t\tcleanup13()\n\t\tcleanup12()\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\thttpConfig, cleanup23, err := Cfg(viper)\n\tif err != nil {\n\t\tcleanup22()\n\t\tcleanup21()\n\t\tcleanup20()\n\t\tcleanup19()\n\t\tcleanup18()\n\t\tcleanup17()\n\t\tcleanup16()\n\t\tcleanup15()\n\t\tcleanup14()\n\t\tcleanup13()\n\t\tcleanup12()\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\thttp, cleanup24, err := Provider(context, mux, zap, httpConfig)\n\tif err != nil {\n\t\tcleanup23()\n\t\tcleanup22()\n\t\tcleanup21()\n\t\tcleanup20()\n\t\tcleanup19()\n\t\tcleanup18()\n\t\tcleanup17()\n\t\tcleanup16()\n\t\tcleanup15()\n\t\tcleanup14()\n\t\tcleanup13()\n\t\tcleanup12()\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\treturn http, func() {\n\t\tcleanup24()\n\t\tcleanup23()\n\t\tcleanup22()\n\t\tcleanup21()\n\t\tcleanup20()\n\t\tcleanup19()\n\t\tcleanup18()\n\t\tcleanup17()\n\t\tcleanup16()\n\t\tcleanup15()\n\t\tcleanup14()\n\t\tcleanup13()\n\t\tcleanup12()\n\t\tcleanup11()\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t}, nil\n}\n"
  },
  {
    "path": "app/http_routers/products-router/injector.go",
    "content": "// +build wireinject\n\npackage products_router\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/provider\"\n\t\"github.com/google/wire\"\n)\n\n// Build\nfunc Build() (*Manager, func(), error) {\n\tpanic(wire.Build(ProviderProductionSet, provider.AwareProductionSet))\n}\n\nfunc BuildTest() (*Manager, func(), error) {\n\tpanic(wire.Build(ProviderTestSet, provider.AwareTestSet))\n}\n"
  },
  {
    "path": "app/http_routers/products-router/manager.go",
    "content": "package products_router\n\nimport (\n\t\"context\"\n\n\t\"github.com/aristat/golang-example-app/app/grpc\"\n\t\"github.com/aristat/golang-example-app/app/logger\"\n)\n\nconst prefix = \"app.products-router\"\n\n// Product Manager\ntype Manager struct {\n\tctx    context.Context\n\tlogger logger.Logger\n\tRouter *Router\n}\n\n// ServiceManagers\ntype ServiceManagers struct {\n\tPoolManager *grpc.PoolManager\n}\n\nfunc New(ctx context.Context, log logger.Logger, managers ServiceManagers, cfg *Config) *Manager {\n\tlog = log.WithFields(logger.Fields{\"service\": prefix})\n\n\trouter := &Router{\n\t\tctx:         ctx,\n\t\tcfg:         cfg,\n\t\tlogger:      log,\n\t\tpoolManager: managers.PoolManager,\n\t}\n\n\treturn &Manager{\n\t\tctx:    ctx,\n\t\tlogger: log,\n\t\tRouter: router,\n\t}\n}\n"
  },
  {
    "path": "app/http_routers/products-router/provider.go",
    "content": "package products_router\n\nimport (\n\t\"context\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/google/wire\"\n\t\"github.com/spf13/viper\"\n)\n\n// Cfg\nfunc Cfg(cfg *viper.Viper) (*Config, func(), error) {\n\tc := &Config{}\n\te := cfg.UnmarshalKey(\"products\", c)\n\tif e != nil {\n\t\treturn c, func() {}, e\n\t}\n\treturn c, func() {}, e\n}\n\n// CfgTest\nfunc CfgTest() (*Config, func(), error) {\n\treturn &Config{}, func() {}, nil\n}\n\n// Config\ntype Config struct {\n\tNatsURL string\n\tSubject string\n}\n\nvar ProviderManagers = wire.NewSet(\n\twire.Struct(new(ServiceManagers), \"*\"),\n)\n\n// Provider\nfunc Provider(ctx context.Context, log logger.Logger, managers ServiceManagers, cfg *Config) (*Manager, func(), error) {\n\tg := New(ctx, log, managers, cfg)\n\treturn g, func() {}, nil\n}\n\nvar (\n\tProviderProductionSet = wire.NewSet(Provider, ProviderManagers, Cfg)\n\tProviderTestSet       = wire.NewSet(Provider, ProviderManagers, CfgTest)\n)\n"
  },
  {
    "path": "app/http_routers/products-router/router.go",
    "content": "package products_router\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/nats-io/stan.go\"\n\n\t\"github.com/aristat/golang-example-app/app/common\"\n\t\"github.com/go-chi/chi/v5\"\n\t\"github.com/nats-io/nats.go\"\n\n\t\"github.com/aristat/golang-example-app/app/grpc\"\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/aristat/golang-example-app/generated/resources/proto/products\"\n)\n\ntype Router struct {\n\tctx         context.Context\n\tcfg         *Config\n\tlogger      logger.Logger\n\tpoolManager *grpc.PoolManager\n}\n\nfunc (router *Router) Run(chiRouter chi.Router) {\n\tchiRouter.Get(\"/products_grpc\", router.GetProductsGrpc)\n\tchiRouter.Get(\"/products_nats\", router.GetProductsNats)\n\tchiRouter.Get(\"/products_slowly\", router.GetProductsSlowly)\n}\n\nfunc (router *Router) GetProductsGrpc(w http.ResponseWriter, r *http.Request) {\n\tconn, d, err := grpc.GetConnGRPC(router.poolManager, common.SrvProducts)\n\tdefer d()\n\tdefer r.Body.Close()\n\n\tif err != nil {\n\t\trouter.logger.Printf(\"[ERROR] %s\", err.Error())\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tc := products.NewProductsClient(conn)\n\n\tctx, cancel := context.WithTimeout(r.Context(), time.Second)\n\tdefer cancel()\n\n\te := json.NewEncoder(w)\n\n\tproductOut, err := c.ListProduct(ctx, &products.ListProductIn{Id: 1})\n\tif err != nil {\n\t\tw.WriteHeader(http.StatusBadGateway)\n\t\te.Encode(\"{}\")\n\t\treturn\n\t}\n\n\te.Encode(productOut)\n}\n\nfunc (router *Router) GetProductsNats(w http.ResponseWriter, r *http.Request) {\n\t// Connect to NATS\n\tnc, err := nats.Connect(router.cfg.NatsURL)\n\tif err != nil {\n\t\trouter.logger.Error(err.Error())\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\tdefer nc.Close()\n\n\tsc, err := stan.Connect(\"test-cluster\", \"stan-pub\", stan.NatsConn(nc))\n\tif err != nil {\n\t\trouter.logger.Error(err.Error())\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\t// Close connection\n\tdefer sc.Close()\n\n\tmessage := \"Hello\"\n\trouter.logger.Printf(\"[NATS] send %s\", message)\n\terr = sc.Publish(router.cfg.Subject, []byte(message))\n\n\tif err != nil {\n\t\trouter.logger.Printf(\"[ERROR] %s\", err.Error())\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\te := json.NewEncoder(w)\n\te.Encode(\"done\")\n}\n\nfunc (router *Router) GetProductsSlowly(w http.ResponseWriter, r *http.Request) {\n\trouter.logger.Info(\"Start sleep\")\n\ttime.Sleep(time.Second * 10)\n\trouter.logger.Info(\"Stop sleep\")\n\te := json.NewEncoder(w)\n\te.Encode(\"\")\n}\n"
  },
  {
    "path": "app/http_routers/products-router/router_test.go",
    "content": "package products_router_test\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"testing\"\n\n\tproducts_router \"github.com/aristat/golang-example-app/app/http_routers/products-router\"\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/aristat/golang-example-app/app/common\"\n\tgrpc1 \"github.com/aristat/golang-example-app/app/grpc\"\n\n\t\"github.com/aristat/golang-example-app/app/graphql_resolver\"\n\n\t\"github.com/aristat/golang-example-app/generated/resources/proto/products\"\n\n\t\"google.golang.org/grpc\"\n)\n\nvar (\n\tproductServerHost = \"localhost\"\n\tgrpcPort          string\n)\n\nfunc TestMain(m *testing.M) {\n\tlis, err := net.Listen(\"tcp\", \":0\")\n\tif err != nil {\n\t\tlog.Fatalf(err.Error())\n\t}\n\tdefer lis.Close()\n\n\tgrpcPort = \":\" + strconv.Itoa(lis.Addr().(*net.TCPAddr).Port)\n\ts := grpc.NewServer()\n\tproducts.RegisterProductsServer(s, &graphql_resolver.ProductServerMock{})\n\n\tgo func() {\n\t\tif err := s.Serve(lis); err != nil {\n\t\t\tlog.Fatalf(\"Server exited with error: %v\", err)\n\t\t}\n\t}()\n\n\tcode := m.Run()\n\n\tos.Exit(code)\n}\n\nfunc TestGetProductsGrpc(t *testing.T) {\n\tvar opts []grpc.DialOption\n\tctx := context.Background()\n\topts = append(opts, grpc.WithInsecure())\n\n\tpool, _ := grpc1.NewPool(ctx, common.SrvProducts, productServerHost+grpcPort, grpc1.ConnOptions(opts...))\n\tgrpc1.SetPool(pool, common.SrvProducts)\n\n\ttests := []struct {\n\t\tname         string\n\t\texpectedCode int\n\t}{\n\t\t{\n\t\t\tname:         \"successful\",\n\t\t\texpectedCode: http.StatusOK,\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tprovider, _, e := products_router.BuildTest()\n\t\t\tassert.Nil(t, e, \"err should be nil\")\n\n\t\t\trec := httptest.NewRecorder()\n\t\t\treq, _ := http.NewRequest(http.MethodGet, \"/products_grpc\", strings.NewReader(\"\"))\n\t\t\tprovider.Router.GetProductsGrpc(rec, req)\n\n\t\t\tassert.Equal(t, test.expectedCode, rec.Code)\n\t\t\tassert.NotNil(t, rec.Body)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "app/http_routers/products-router/wire_gen.go",
    "content": "// Code generated by Wire. DO NOT EDIT.\n\n//go:generate go run github.com/google/wire/cmd/wire\n//go:build !wireinject\n// +build !wireinject\n\npackage products_router\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/config\"\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\t\"github.com/aristat/golang-example-app/app/grpc\"\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/aristat/golang-example-app/app/tracing\"\n)\n\n// Injectors from injector.go:\n\n// Build\nfunc Build() (*Manager, func(), error) {\n\tcontext, cleanup, err := entrypoint.ContextProvider()\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tviper, cleanup2, err := config.Provider()\n\tif err != nil {\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tloggerConfig, cleanup3, err := logger.ProviderCfg(viper)\n\tif err != nil {\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tzap, cleanup4, err := logger.Provider(context, loggerConfig)\n\tif err != nil {\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tconfiguration, cleanup5, err := tracing.Cfg(viper)\n\tif err != nil {\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\ttracerProvider, cleanup6, err := tracing.Provider(context, configuration, zap)\n\tif err != nil {\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tgrpcConfig, cleanup7, err := grpc.Cfg(viper)\n\tif err != nil {\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tpoolManager, cleanup8, err := grpc.Provider(context, tracerProvider, zap, grpcConfig)\n\tif err != nil {\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tserviceManagers := ServiceManagers{\n\t\tPoolManager: poolManager,\n\t}\n\tproducts_routerConfig, cleanup9, err := Cfg(viper)\n\tif err != nil {\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tmanager, cleanup10, err := Provider(context, zap, serviceManagers, products_routerConfig)\n\tif err != nil {\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\treturn manager, func() {\n\t\tcleanup10()\n\t\tcleanup9()\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t}, nil\n}\n\nfunc BuildTest() (*Manager, func(), error) {\n\tcontext, cleanup, err := entrypoint.ContextProviderTest()\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tloggerConfig, cleanup2, err := logger.ProviderCfgTest()\n\tif err != nil {\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tmock, cleanup3, err := logger.ProviderTest(context, loggerConfig)\n\tif err != nil {\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\ttracerProvider, cleanup4, err := tracing.ProviderTest()\n\tif err != nil {\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tgrpcConfig, cleanup5, err := grpc.CfgTest()\n\tif err != nil {\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tpoolManager, cleanup6, err := grpc.Provider(context, tracerProvider, mock, grpcConfig)\n\tif err != nil {\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tserviceManagers := ServiceManagers{\n\t\tPoolManager: poolManager,\n\t}\n\tproducts_routerConfig, cleanup7, err := CfgTest()\n\tif err != nil {\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tmanager, cleanup8, err := Provider(context, mock, serviceManagers, products_routerConfig)\n\tif err != nil {\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\treturn manager, func() {\n\t\tcleanup8()\n\t\tcleanup7()\n\t\tcleanup6()\n\t\tcleanup5()\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t}, nil\n}\n"
  },
  {
    "path": "app/logger/injector.go",
    "content": "// +build wireinject\n\npackage logger\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/config\"\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\t\"github.com/google/wire\"\n)\n\n// Build returns logger instance implemented of Logger interface with resolved dependencies\nfunc Build() (Logger, func(), error) {\n\tpanic(wire.Build(ProviderProductionSet, entrypoint.ProviderProductionSet, config.ProviderSet))\n}\n\nfunc BuildTest() (Logger, func(), error) {\n\tpanic(wire.Build(ProviderTestSet, entrypoint.ProviderTestSet))\n}\n"
  },
  {
    "path": "app/logger/logger.go",
    "content": "package logger\n\ntype (\n\tFields map[string]interface{}\n)\n\n// Level represent RFC5424 logger severity\ntype Level int8\n\n// String implements interface Stringer\nfunc (l Level) String() string {\n\tswitch l {\n\tcase LevelDebug:\n\t\treturn \"debug\"\n\tcase LevelInfo:\n\t\treturn \"info\"\n\tcase LevelNotice:\n\t\treturn \"notice\"\n\tcase LevelWarning:\n\t\treturn \"warning\"\n\tcase LevelError:\n\t\treturn \"error\"\n\tcase LevelCritical:\n\t\treturn \"critical\"\n\tcase LevelAlert:\n\t\treturn \"alert\"\n\tcase LevelEmergency:\n\t\treturn \"emergency\"\n\t}\n\treturn \"unknown\"\n}\n\n// FromString set logger level from string representation\nfunc (l *Level) FromString(level string) Level {\n\tswitch level {\n\tcase \"debug\":\n\t\t*l = LevelDebug\n\tcase \"info\":\n\t\t*l = LevelInfo\n\tcase \"notice\":\n\t\t*l = LevelNotice\n\tcase \"warning\":\n\t\t*l = LevelWarning\n\tcase \"error\":\n\t\t*l = LevelError\n\tcase \"critical\":\n\t\t*l = LevelCritical\n\tcase \"alert\":\n\t\t*l = LevelAlert\n\tcase \"emergency\":\n\t\t*l = LevelEmergency\n\t}\n\treturn *l\n}\n\nconst (\n\t// Debug: debug-level messages\n\tLevelDebug Level = 7\n\t// Informational: informational messages\n\tLevelInfo Level = 6\n\t// Notice: normal but significant condition\n\tLevelNotice Level = 5\n\t// Warning: warning conditions\n\tLevelWarning Level = 4\n\t// Error: error conditions\n\tLevelError Level = 3\n\t// Critical: critical conditions\n\tLevelCritical Level = 2\n\t// Alert: action must be taken immediately\n\tLevelAlert Level = 1\n\t// Emergency: system is unusable\n\tLevelEmergency Level = 0\n)\n\ntype opts struct {\n\targs   []interface{}\n\tfields Fields\n}\n\n// Option is func hook for underling logic call\ntype Option func(*opts) error\n\n// Args returns func hook a logger for replace fmt placeholders on represent values\nfunc Args(a ...interface{}) Option {\n\treturn func(f *opts) error {\n\t\tf.args = a\n\t\treturn nil\n\t}\n}\n\n// WithFields returns func hook a logger for adding fields for call\nfunc WithFields(fields Fields) Option {\n\treturn func(f *opts) error {\n\t\tf.fields = fields\n\t\treturn nil\n\t}\n}\n\n// Config is a general logger config settings\ntype Config struct {\n\tDebug bool\n}\n\n// Logger is the interface for logger client\ntype Logger interface {\n\t// Printf is like fmt.Printf, push to log entry with debug level\n\tPrintf(format string, a ...interface{})\n\t// Emergency push to log entry with emergency level & throw panic\n\tEmergency(format string, opts ...Option)\n\t// Alert push to log entry with alert level\n\tAlert(format string, opts ...Option)\n\t// Critical push to log entry with critical level\n\tCritical(format string, opts ...Option)\n\t// Error push to log entry with error level\n\tError(format string, opts ...Option)\n\t// Warning push to log entry with warning level\n\tWarning(format string, opts ...Option)\n\t// Notice push to log entry with notice level\n\tNotice(format string, opts ...Option)\n\t// Info push to log entry with info level\n\tInfo(format string, opts ...Option)\n\t// Debug push to log entry with debug level\n\tDebug(format string, opts ...Option)\n\t// Write push to log entry with debug level\n\tWrite(p []byte) (n int, err error)\n\t// Log push to log with specified level\n\tLog(level Level, format string, opts ...Option)\n\t// WithFields create new instance with fields\n\tWithFields(fields Fields) Logger\n}\n"
  },
  {
    "path": "app/logger/middleware.go",
    "content": "package logger\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"time\"\n\n\t\"google.golang.org/grpc\"\n)\n\n// UnaryClientInterceptor wrapper to logging query\nfunc UnaryClientInterceptor(log Logger, enable bool) grpc.UnaryClientInterceptor {\n\treturn func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {\n\t\tif !enable {\n\t\t\treturn invoker(ctx, method, req, reply, cc, opts...)\n\t\t}\n\n\t\tstartTime := time.Now()\n\t\terr := invoker(ctx, method, req, reply, cc, opts...)\n\n\t\tvar e string\n\t\tif err != nil {\n\t\t\te = strings.ReplaceAll(err.Error(), \"\\n\", \"\")\n\t\t}\n\n\t\tlog.Debug(\"\\nQUERY UnaryClient:\\n\\nData: %v\\n\\nERROR:\\n%v\\n\\n\", Args(req, e), WithFields(Fields{\n\t\t\t\"time\": time.Since(startTime).String(),\n\t\t}))\n\n\t\treturn err\n\t}\n}\n\n// StreamClientInterceptor returns a new streaming client interceptor\nfunc StreamClientInterceptor(log Logger, enable bool) grpc.StreamClientInterceptor {\n\treturn func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {\n\t\tif !enable {\n\t\t\treturn streamer(ctx, desc, cc, method, opts...)\n\t\t}\n\n\t\tstartTime := time.Now()\n\t\tclientStream, err := streamer(ctx, desc, cc, method, opts...)\n\t\tvar e string\n\t\tif err != nil {\n\t\t\te = strings.ReplaceAll(err.Error(), \"\\n\", \"\")\n\t\t}\n\n\t\tlog.Debug(\"\\nQUERY StreamClient:\\n\\nMethod: %v\\n\\nERROR:\\n%v\\n\\n\", Args(method, e), WithFields(Fields{\n\t\t\t\"time\": time.Since(startTime).String(),\n\t\t}))\n\n\t\treturn clientStream, err\n\t}\n}\n\n// UnaryServerInterceptor wrapper to logging query\nfunc UnaryServerInterceptor(log Logger, enable bool) grpc.UnaryServerInterceptor {\n\treturn func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {\n\t\tif !enable {\n\t\t\treturn handler(ctx, req)\n\t\t}\n\n\t\tstartTime := time.Now()\n\t\tres, err := handler(ctx, req)\n\n\t\tvar e string\n\t\tif err != nil {\n\t\t\te = strings.ReplaceAll(err.Error(), \"\\n\", \"\")\n\t\t}\n\n\t\tlog.Debug(\"\\nQUERY UnaryServer:\\n\\nFullMethod: %v\\nData: %v\\nRESPONSE:\\n\\nData: %v\\nERROR:\\n%v\\n\", Args(info.FullMethod, req, res, e), WithFields(Fields{\n\t\t\t\"time\": time.Since(startTime).String(),\n\t\t}))\n\n\t\treturn res, err\n\t}\n}\n\n// StreamServerInterceptor returns a new streaming server interceptor\nfunc StreamServerInterceptor(log Logger, enable bool) grpc.StreamServerInterceptor {\n\treturn func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {\n\t\tif !enable {\n\t\t\treturn handler(srv, stream)\n\t\t}\n\n\t\tstartTime := time.Now()\n\t\terr := handler(srv, stream)\n\n\t\tvar e string\n\t\tif err != nil {\n\t\t\te = strings.ReplaceAll(err.Error(), \"\\n\", \"\")\n\t\t}\n\n\t\tlog.Debug(\"\\nQUERY StreamServer:\\n\\nFullMethod: %v\\n\\nERROR:\\n%v\\n\", Args(info.FullMethod, e), WithFields(Fields{\n\t\t\t\"time\": time.Since(startTime).String(),\n\t\t}))\n\n\t\treturn err\n\t}\n}\n"
  },
  {
    "path": "app/logger/mock.go",
    "content": "package logger\n\nimport (\n\t\"context\"\n)\n\n// Entity represent log struct with all assets\ntype Entity struct {\n\tLevel  Level\n\tFields Fields\n\tArgs   []interface{}\n\tFormat string\n}\n\n// Mock is the logger with stubbed methods\ntype Mock struct {\n\tctx     context.Context\n\tch      chan Entity\n\tdiscard bool\n\tcfg     Config\n\tfields  map[string]interface{}\n}\n\n// Printf is like fmt.Printf, push to log entry with debug level\nfunc (m *Mock) Printf(format string, a ...interface{}) {\n\tm.Debug(format, Args(a...))\n}\n\n// Emergency push to log entry with emergency level & throw panic\nfunc (m *Mock) Emergency(format string, opts ...Option) {\n\tm.Log(LevelEmergency, format, opts...)\n}\n\n// Alert push to log entry with alert level\nfunc (m *Mock) Alert(format string, opts ...Option) {\n\tm.Log(LevelAlert, format, opts...)\n}\n\n// Critical push to log entry with critical level\nfunc (m *Mock) Critical(format string, opts ...Option) {\n\tm.Log(LevelCritical, format, opts...)\n}\n\n// Error push to log entry with error level\nfunc (m *Mock) Error(format string, opts ...Option) {\n\tm.Log(LevelError, format, opts...)\n}\n\n// Warning push to log entry with warning level\nfunc (m *Mock) Warning(format string, opts ...Option) {\n\tm.Log(LevelWarning, format, opts...)\n}\n\n// Notice push to log entry with notice level\nfunc (m *Mock) Notice(format string, opts ...Option) {\n\tm.Log(LevelNotice, format, opts...)\n}\n\n// Info push to log entry with info level\nfunc (m *Mock) Info(format string, opts ...Option) {\n\tm.Log(LevelInfo, format, opts...)\n}\n\n// Debug push to log entry with debug level\nfunc (m *Mock) Debug(format string, opts ...Option) {\n\tm.Log(LevelDebug, format, opts...)\n}\n\n// Write push to log entry with debug level\nfunc (m *Mock) Write(p []byte) (n int, err error) {\n\tm.Debug(string(p))\n\treturn len(p), nil\n}\n\n// Log push to log with specified level\nfunc (m *Mock) Log(level Level, format string, o ...Option) {\n\tif !m.discard {\n\t\treturn\n\t}\n\topts := &opts{}\n\tfor _, option := range o {\n\t\t_ = option(opts)\n\t}\n\tvar (\n\t\tfields = map[string]interface{}{}\n\t)\n\t// fields\n\tfor k, v := range m.fields {\n\t\tfields[k] = v\n\t}\n\tfor k, v := range opts.fields {\n\t\tfields[k] = v\n\t}\n\n\tgo func() {\n\t\tm.ch <- Entity{\n\t\t\tLevel:  level,\n\t\t\tFormat: format,\n\t\t\tArgs:   opts.args,\n\t\t\tFields: fields,\n\t\t}\n\t}()\n}\n\n// WithFields create new instance with fields\nfunc (m *Mock) WithFields(fields Fields) Logger {\n\tnm := &Mock{}\n\tcopyMock(nm, m, fields)\n\treturn nm\n}\n\nfunc copyMock(dst, src *Mock, fields map[string]interface{}) {\n\tvar cFields = map[string]interface{}{}\n\t// fields\n\tfor k, v := range src.fields {\n\t\tcFields[k] = v\n\t}\n\tdst.fields = cFields\n\tif fields != nil {\n\t\tfor k, v := range fields {\n\t\t\tdst.fields[k] = v\n\t\t}\n\t}\n\tdst.discard = src.discard\n\tdst.ch = src.ch\n}\n\n// Catch returns channel of entity structure for testing event content\nfunc (m *Mock) Catch() <-chan Entity {\n\treturn m.ch\n}\n\n// NewMock returns mock instance implemented of Logger interface\nfunc newMock(ctx context.Context, cfg Config, discard bool) *Mock {\n\treturn &Mock{\n\t\tctx:     ctx,\n\t\tcfg:     cfg,\n\t\tch:      make(chan Entity),\n\t\tdiscard: discard,\n\t}\n}\n"
  },
  {
    "path": "app/logger/provider.go",
    "content": "package logger\n\nimport (\n\t\"context\"\n\n\t\"github.com/google/wire\"\n\t\"github.com/spf13/viper\"\n)\n\n// ProviderCfg returns configuration for production logger\nfunc ProviderCfg(cfg *viper.Viper) (Config, func(), error) {\n\tc := Config{}\n\te := cfg.UnmarshalKey(\"logger\", &c)\n\tif e != nil {\n\t\treturn c, func() {}, e\n\t}\n\tif cfg.IsSet(\"debug\") && !c.Debug {\n\t\tc.Debug = cfg.GetBool(\"debug\")\n\t}\n\treturn c, func() {}, nil\n}\n\n// ProviderCfgTest returns configuration for stub/mock logger\nfunc ProviderCfgTest() (Config, func(), error) {\n\treturn Config{}, func() {}, nil\n}\n\n// Provider returns logger instance implemented of Logger interface with resolved dependencies\nfunc Provider(ctx context.Context, cfg Config) (*Zap, func(), error) {\n\treturn newZap(ctx, cfg), func() {}, nil\n}\n\n// ProviderTest returns stub/mock logger instance implemented of Logger interface with resolved dependencies\nfunc ProviderTest(ctx context.Context, cfg Config) (*Mock, func(), error) {\n\tmock := newMock(ctx, cfg, true)\n\n\tcleanup := func() {\n\t\tif mock.ch != nil {\n\t\t\tclose(mock.ch)\n\t\t}\n\t}\n\treturn mock, cleanup, nil\n}\n\nvar (\n\tProviderProductionSet = wire.NewSet(Provider, ProviderCfg, wire.Bind(new(Logger), new(*Zap)))\n\tProviderTestSet       = wire.NewSet(ProviderTest, ProviderCfgTest, wire.Bind(new(Logger), new(*Mock)))\n)\n"
  },
  {
    "path": "app/logger/wire_gen.go",
    "content": "// Code generated by Wire. DO NOT EDIT.\n\n//go:generate go run github.com/google/wire/cmd/wire\n//go:build !wireinject\n// +build !wireinject\n\npackage logger\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/config\"\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n)\n\n// Injectors from injector.go:\n\n// Build returns logger instance implemented of Logger interface with resolved dependencies\nfunc Build() (Logger, func(), error) {\n\tcontext, cleanup, err := entrypoint.ContextProvider()\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tviper, cleanup2, err := config.Provider()\n\tif err != nil {\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tloggerConfig, cleanup3, err := ProviderCfg(viper)\n\tif err != nil {\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tzap, cleanup4, err := Provider(context, loggerConfig)\n\tif err != nil {\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\treturn zap, func() {\n\t\tcleanup4()\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t}, nil\n}\n\nfunc BuildTest() (Logger, func(), error) {\n\tcontext, cleanup, err := entrypoint.ContextProviderTest()\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tloggerConfig, cleanup2, err := ProviderCfgTest()\n\tif err != nil {\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\tmock, cleanup3, err := ProviderTest(context, loggerConfig)\n\tif err != nil {\n\t\tcleanup2()\n\t\tcleanup()\n\t\treturn nil, nil, err\n\t}\n\treturn mock, func() {\n\t\tcleanup3()\n\t\tcleanup2()\n\t\tcleanup()\n\t}, nil\n}\n"
  },
  {
    "path": "app/logger/zap.go",
    "content": "package logger\n\nimport (\n\t\"context\"\n\n\t\"go.uber.org/zap/zapcore\"\n\n\t\"go.uber.org/zap\"\n)\n\n// Zap is uber/zap logger implemented of Logger interface\ntype Zap struct {\n\tctx    context.Context\n\tcfg    Config\n\tlogger *zap.SugaredLogger\n\tfields map[string]interface{}\n}\n\n// Printf is like fmt.Printf, push to log entry with debug level\nfunc (z *Zap) Printf(format string, a ...interface{}) {\n\tz.Debug(format, Args(a...))\n}\n\n// Emergency push to log entry with emergency level & throw panic\nfunc (z *Zap) Emergency(format string, opts ...Option) {\n\tz.Log(LevelEmergency, format, opts...)\n}\n\n// Alert push to log entry with alert level\nfunc (z *Zap) Alert(format string, opts ...Option) {\n\tz.Log(LevelAlert, format, opts...)\n}\n\n// Critical push to log entry with critical level\nfunc (z *Zap) Critical(format string, opts ...Option) {\n\tz.Log(LevelCritical, format, opts...)\n}\n\n// Error push to log entry with error level\nfunc (z *Zap) Error(format string, opts ...Option) {\n\tz.Log(LevelError, format, opts...)\n}\n\n// Warning push to log entry with warning level\nfunc (z *Zap) Warning(format string, opts ...Option) {\n\tz.Log(LevelWarning, format, opts...)\n}\n\n// Notice push to log entry with notice level\nfunc (z *Zap) Notice(format string, opts ...Option) {\n\tz.Log(LevelNotice, format, opts...)\n}\n\n// Info push to log entry with info level\nfunc (z *Zap) Info(format string, opts ...Option) {\n\tz.Log(LevelInfo, format, opts...)\n}\n\n// Debug push to log entry with debug level\nfunc (z *Zap) Debug(format string, opts ...Option) {\n\tz.Log(LevelDebug, format, opts...)\n}\n\n// Write push to log entry with debug level\nfunc (z *Zap) Write(p []byte) (n int, err error) {\n\tz.Debug(string(p))\n\treturn len(p), nil\n}\n\n// Log push to log with specified level\nfunc (z *Zap) Log(level Level, format string, o ...Option) {\n\topts := &opts{}\n\tfor _, option := range o {\n\t\t_ = option(opts)\n\t}\n\tvar (\n\t\twargs = []interface{}{\"level\", level.String()}\n\t)\n\n\t// fields\n\tfor k, v := range z.fields {\n\t\twargs = append(wargs, k, v)\n\t}\n\tfor k, v := range opts.fields {\n\t\twargs = append(wargs, k, v)\n\t}\n\n\tvar logger = z.logger\n\tif len(wargs) > 0 {\n\t\tlogger = logger.With(wargs...)\n\t}\n\n\tif len(opts.args) == 0 {\n\t\tvar fn func(args ...interface{})\n\t\tswitch level {\n\t\tdefault:\n\t\t\tfn = logger.Debug\n\t\tcase LevelInfo, LevelNotice:\n\t\t\tfn = logger.Info\n\t\tcase LevelWarning:\n\t\t\tfn = logger.Warn\n\t\tcase LevelError, LevelCritical, LevelAlert:\n\t\t\tfn = logger.Error\n\t\tcase LevelEmergency:\n\t\t\tfn = logger.Panic\n\t\t}\n\t\tfn(format)\n\t} else {\n\t\tvar fn func(format string, args ...interface{})\n\t\tswitch level {\n\t\tdefault:\n\t\t\tfn = logger.Debugf\n\t\tcase LevelInfo, LevelNotice:\n\t\t\tfn = logger.Infof\n\t\tcase LevelWarning:\n\t\t\tfn = logger.Warnf\n\t\tcase LevelError, LevelCritical, LevelAlert:\n\t\t\tfn = logger.Errorf\n\t\tcase LevelEmergency:\n\t\t\tfn = logger.Panicf\n\t\t}\n\t\tfn(format, opts.args...)\n\t}\n}\n\n// WithFields create new instance with fields\nfunc (z *Zap) WithFields(fields Fields) Logger {\n\tnz := &Zap{}\n\tcopyZap(nz, z, fields)\n\treturn nz\n}\n\nfunc copyZap(dst, src *Zap, fields map[string]interface{}) {\n\tvar cFields = map[string]interface{}{}\n\t// fields\n\tfor k, v := range src.fields {\n\t\tcFields[k] = v\n\t}\n\tdst.fields = cFields\n\tif fields != nil {\n\t\tfor k, v := range fields {\n\t\t\tdst.fields[k] = v\n\t\t}\n\t}\n\tdst.logger = src.logger\n}\n\n// NewZap returns zap logger\nfunc newZap(ctx context.Context, cfg Config) *Zap {\n\tvar logger *zap.Logger\n\n\tif !cfg.Debug {\n\t\tcfg := zap.NewProductionConfig()\n\t\tlogger, _ = cfg.Build(zap.AddCallerSkip(3), zap.AddStacktrace(zap.WarnLevel))\n\t} else {\n\t\tcfg := zap.NewDevelopmentConfig()\n\t\tcfg.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder\n\t\tlogger, _ = cfg.Build(zap.AddCallerSkip(3), zap.AddStacktrace(zap.WarnLevel))\n\t}\n\n\tgo func(logger *zap.Logger) {\n\t\t<-ctx.Done()\n\t\t_ = logger.Sync()\n\t}(logger)\n\n\treturn &Zap{ctx: ctx, cfg: cfg, logger: logger.Sugar()}\n}\n"
  },
  {
    "path": "app/provider/provider.go",
    "content": "package provider\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/casbin\"\n\t\"github.com/aristat/golang-example-app/app/config\"\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\t\"github.com/aristat/golang-example-app/app/grpc\"\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/aristat/golang-example-app/app/tracing\"\n\t\"github.com/google/wire\"\n)\n\nvar AwareProductionSet = wire.NewSet(\n\tentrypoint.ProviderProductionSet,\n\tlogger.ProviderProductionSet,\n\tconfig.ProviderSet,\n\ttracing.ProviderProductionSet,\n\tgrpc.ProviderProductionSet,\n\tcasbin.ProviderProductionSet,\n)\n\nvar AwareTestSet = wire.NewSet(\n\tentrypoint.ProviderTestSet,\n\tlogger.ProviderTestSet,\n\ttracing.ProviderTestSet,\n\tgrpc.ProviderTestSet,\n\tcasbin.ProviderTestSet,\n)\n"
  },
  {
    "path": "app/tracing/jaeger.go",
    "content": "package tracing\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/exporters/jaeger\"\n\t\"go.opentelemetry.io/otel/sdk/resource\"\n\ttracesdk \"go.opentelemetry.io/otel/sdk/trace\"\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.4.0\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/pkg/errors\"\n)\n\ntype Configuration struct {\n\tAgentHost   string\n\tAgentPort   string\n\tServiceName string\n}\n\nconst prefix = \"app.tracer\"\n\nfunc newJaegerTracer(ctx context.Context, configuration *Configuration, log logger.Logger) (*tracesdk.TracerProvider, error) {\n\tlog = log.WithFields(logger.Fields{\"service\": prefix})\n\n\texp, err := jaeger.New(\n\t\tjaeger.WithAgentEndpoint(\n\t\t\tjaeger.WithAgentHost(configuration.AgentHost),\n\t\t\tjaeger.WithAgentPort(configuration.AgentPort),\n\t\t),\n\t)\n\tif err != nil {\n\t\treturn nil, errors.WithMessage(err, prefix)\n\t}\n\n\ttracer := tracesdk.NewTracerProvider(\n\t\ttracesdk.WithBatcher(exp),\n\t\ttracesdk.WithResource(resource.NewWithAttributes(\n\t\t\tsemconv.SchemaURL,\n\t\t\tsemconv.ServiceNameKey.String(configuration.ServiceName),\n\t\t)),\n\t)\n\n\tgo func() {\n\t\t<-ctx.Done()\n\t\tif err := tracer.Shutdown(ctx); err != nil {\n\t\t\tlog.Printf(\"Error shutting down tracer provider: %v\", err)\n\t\t}\n\t}()\n\n\treturn tracer, errors.WithMessage(err, prefix)\n}\n"
  },
  {
    "path": "app/tracing/provider.go",
    "content": "package tracing\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/propagation\"\n\n\t\"github.com/google/wire\"\n\t\"github.com/spf13/viper\"\n\n\ttracesdk \"go.opentelemetry.io/otel/sdk/trace\"\n\n\t\"go.opentelemetry.io/otel\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n)\n\n// Cfg\nfunc Cfg(cfg *viper.Viper) (*Configuration, func(), error) {\n\tc := Configuration{}\n\te := cfg.UnmarshalKey(\"tracing.jaeger\", &c)\n\tif e != nil {\n\t\treturn nil, func() {}, e\n\t}\n\treturn &c, func() {}, nil\n}\n\n// Provider\nfunc Provider(ctx context.Context, configuration *Configuration, log logger.Logger) (*tracesdk.TracerProvider, func(), error) {\n\tt, e := newJaegerTracer(ctx, configuration, log)\n\totel.SetTracerProvider(t)\n\totel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))\n\treturn t, func() {}, e\n}\n\n// ProviderTest\nfunc ProviderTest() (*tracesdk.TracerProvider, func(), error) {\n\tm := tracesdk.NewTracerProvider()\n\treturn m, func() {}, nil\n}\n\nvar (\n\tProviderProductionSet = wire.NewSet(Provider, Cfg)\n\tProviderTestSet       = wire.NewSet(ProviderTest)\n)\n"
  },
  {
    "path": "cmd/daemon/daemon.go",
    "content": "package daemon\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"os/signal\"\n\t\"sync\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\t\"github.com/aristat/golang-example-app/app/http\"\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\n\t\"github.com/spf13/cobra\"\n)\n\nvar (\n\tbind          string\n\tgracefulDelay time.Duration\n\tCmd           = &cobra.Command{\n\t\tUse:           \"daemon\",\n\t\tShort:         \"Gateway API daemon\",\n\t\tSilenceUsage:  true,\n\t\tSilenceErrors: true,\n\t\tRun: func(_ *cobra.Command, _ []string) {\n\t\t\tvar (\n\t\t\t\te error\n\t\t\t\ts *http.Http\n\t\t\t\tc func()\n\t\t\t)\n\n\t\t\tlog, c, e := logger.Build()\n\t\t\tif e != nil {\n\t\t\t\tpanic(e)\n\t\t\t}\n\t\t\tdefer c()\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\tif re, _ := r.(error); re != nil {\n\t\t\t\t\t\tlog.Error(re.Error())\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlog.Alert(\"unhandled panic, err: %v\", logger.Args(r))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\ts, c, e = http.Build()\n\t\t\tif e != nil {\n\t\t\t\tlog.Error(e.Error())\n\t\t\t\treturn\n\t\t\t}\n\t\t\tdefer c()\n\n\t\t\twg := &sync.WaitGroup{}\n\t\t\twg.Add(1)\n\n\t\t\tserver := s.ListenAndServe(wg, bind)\n\n\t\t\tshutdownSignal := make(chan os.Signal)\n\t\t\tsignal.Notify(shutdownSignal, syscall.SIGTERM, syscall.SIGINT)\n\t\t\tsig := <-shutdownSignal\n\t\t\tlog.Printf(\"OS signaled `%v`\\n\", sig.String())\n\n\t\t\tlog.Info(\"Server shutdown is raised\")\n\t\t\tif e := server.Shutdown(context.Background()); e != nil {\n\t\t\t\tlog.Emergency(\"Graceful shutdown error, %v\", logger.Args(e))\n\t\t\t}\n\n\t\t\twg.Wait()\n\n\t\t\tlog.Printf(\"Graceful shutdown in %s\\n\", gracefulDelay)\n\t\t\tctx, _ := context.WithTimeout(context.Background(), gracefulDelay)\n\t\t\tentrypoint.Shutdown(ctx, 0)\n\t\t},\n\t}\n)\n\nfunc init() {\n\tCmd.PersistentFlags().StringVarP(&bind, \"bind\", \"b\", \":9096\", \"bind address\")\n\tCmd.PersistentFlags().DurationVar(&gracefulDelay, \"graceful.delay\", 50*time.Millisecond, \"graceful delay\")\n}\n"
  },
  {
    "path": "cmd/health-check-service/health_check_service.go",
    "content": "package health_check_service\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"math/rand\"\n\t\"net\"\n\t\"time\"\n\n\t\"go.opentelemetry.io/otel/propagation\"\n\n\t\"go.opentelemetry.io/otel\"\n\n\t\"github.com/aristat/golang-example-app/app/config\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\n\t\"github.com/aristat/golang-example-app/app/common\"\n\n\t\"github.com/aristat/golang-example-app/generated/resources/proto/health_checks\"\n\t\"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc\"\n\temptypb \"google.golang.org/protobuf/types/known/emptypb\"\n\n\t\"github.com/spf13/cobra\"\n\t\"google.golang.org/grpc\"\n)\n\n// Config\ntype Config struct {\n\tPort          string\n\tRandomDisable bool\n}\n\ntype server struct {\n\tcfg Config\n\thealth_checks.UnimplementedHealthChecksServer\n}\n\nfunc (s *server) IsAlive(ctx context.Context, empty *emptypb.Empty) (*health_checks.IsAliveOut, error) {\n\tif s.cfg.RandomDisable {\n\t\treturn &health_checks.IsAliveOut{Status: health_checks.IsAliveOut_OK}, nil\n\t}\n\n\tvar status health_checks.IsAliveOut_Status\n\n\trand.Seed(time.Now().UTC().UnixNano())\n\tnumber := rand.Intn(2-0) + 0\n\n\tif number == 1 {\n\t\tstatus = health_checks.IsAliveOut_OK\n\t} else {\n\t\tstatus = health_checks.IsAliveOut_NOT_OK\n\t}\n\n\treturn &health_checks.IsAliveOut{Status: status}, nil\n}\n\n// Example service, which need for testing jaeger and grpc pool\nvar (\n\t//bind string\n\tCmd = &cobra.Command{\n\t\tUse:           \"health-check\",\n\t\tShort:         \"Health check\",\n\t\tSilenceUsage:  true,\n\t\tSilenceErrors: true,\n\t\tRun: func(_ *cobra.Command, _ []string) {\n\t\t\tconf, c, e := config.Build()\n\t\t\tif e != nil {\n\t\t\t\tpanic(e)\n\t\t\t}\n\t\t\tdefer c()\n\n\t\t\tclientConfig := Config{}\n\t\t\te = conf.UnmarshalKey(\"services.healthCheckService\", &clientConfig)\n\t\t\tif e != nil {\n\t\t\t\tlog.Fatal(\"Config initialize error\")\n\t\t\t}\n\n\t\t\tlog, c, e := logger.Build()\n\t\t\tif e != nil {\n\t\t\t\tpanic(e)\n\t\t\t}\n\t\t\tdefer c()\n\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\tif re, _ := r.(error); re != nil {\n\t\t\t\t\t\tlog.Error(re.Error())\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlog.Alert(\"unhandled panic, err: %v\", logger.Args(r))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\ttracer, e := common.GenerateTracerForTestClient(\"golang-example-app-health-check-service\", conf)\n\t\t\totel.SetTracerProvider(tracer)\n\n\t\t\tif e != nil {\n\t\t\t\tpanic(e)\n\t\t\t}\n\n\t\t\tdefer func() {\n\t\t\t\tif err := tracer.Shutdown(context.Background()); err != nil {\n\t\t\t\t\tlog.Printf(\"Error shutting down tracer provider: %v\", err)\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\tlis, err := net.Listen(\"tcp\", \":\"+clientConfig.Port)\n\t\t\tif err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\n\t\t\ts := grpc.NewServer(\n\t\t\t\tgrpc.ChainUnaryInterceptor(\n\t\t\t\t\tlogger.UnaryServerInterceptor(log, true),\n\t\t\t\t\totelgrpc.UnaryServerInterceptor(otelgrpc.WithTracerProvider(tracer), otelgrpc.WithPropagators(propagation.TraceContext{})),\n\t\t\t\t),\n\t\t\t\tgrpc.ChainStreamInterceptor(\n\t\t\t\t\tlogger.StreamServerInterceptor(log, true),\n\t\t\t\t\totelgrpc.StreamServerInterceptor(otelgrpc.WithTracerProvider(tracer), otelgrpc.WithPropagators(propagation.TraceContext{})),\n\t\t\t\t),\n\t\t\t)\n\t\t\thealth_checks.RegisterHealthChecksServer(s, &server{cfg: clientConfig})\n\t\t\tif err := s.Serve(lis); err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\t\t},\n\t}\n)\n\nfunc init() {\n}\n"
  },
  {
    "path": "cmd/jwt/jwt.go",
    "content": "package jwt\n\nimport \"github.com/spf13/cobra\"\n\nvar Cmd = &cobra.Command{\n\tUse:           \"jwt\",\n\tShort:         \"Tools for generate JWT\",\n\tSilenceUsage:  true,\n\tSilenceErrors: true,\n}\n\nfunc init() {\n\tCmd.AddCommand(tokenCmd)\n}\n"
  },
  {
    "path": "cmd/jwt/token.go",
    "content": "package jwt\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/spf13/cast\"\n\n\t\"github.com/golang-jwt/jwt\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar (\n\tjwtFlagPrivateKey string\n\tjwtFlagFields     string\n)\n\nfunc init() {\n\ttokenCmd.PersistentFlags().StringVar(&jwtFlagPrivateKey, \"key\", \"\", \"private key\")\n\ttokenCmd.PersistentFlags().StringVar(&jwtFlagFields, \"fields\", \"\", \"JWT fields in JSON format\")\n}\n\nvar tokenCmd = &cobra.Command{\n\tUse:           \"token\",\n\tShort:         \"Generate JWT token with sign\",\n\tExample:       `jwt --key='{path to private key}' --fields='{in json format {\"key\":\"value\"} }'`,\n\tSilenceUsage:  true,\n\tSilenceErrors: true,\n\tRun: func(cmd *cobra.Command, args []string) {\n\n\t\tif jwtFlagPrivateKey == \"\" {\n\t\t\tfmt.Printf(\"Flag `key` is required\\n\")\n\t\t\tos.Exit(1)\n\t\t}\n\n\t\tprivatePemKey, err := ioutil.ReadFile(jwtFlagPrivateKey)\n\n\t\tif err != nil {\n\n\t\t\tfmt.Printf(\"Error occurred: %v\\n\", err.Error())\n\t\t\tos.Exit(1)\n\t\t}\n\n\t\tfields := make(map[string]interface{})\n\n\t\tif jwtFlagFields != \"\" {\n\n\t\t\tif err = json.Unmarshal([]byte(jwtFlagFields), &fields); err != nil {\n\n\t\t\t\tfmt.Printf(\"Parse fields error %v\\n\", err.Error())\n\t\t\t\tos.Exit(1)\n\t\t\t}\n\t\t}\n\n\t\tjwtEncoded, err := GenerateJWT(privatePemKey, fields)\n\n\t\tif err != nil {\n\n\t\t\tfmt.Printf(\"Error occurred: %v\\n\", err.Error())\n\t\t\tos.Exit(1)\n\t\t}\n\n\t\tfmt.Println(jwtEncoded)\n\t},\n}\n\n// GenerateJWT returns token signed by private key with filled fields\nfunc GenerateJWT(privateKey []byte, fields map[string]interface{}) (string, error) {\n\n\ttype CustomClaims struct {\n\t\tUserId int64 `json:\"user_id,omitempty\"`\n\t\tjwt.StandardClaims\n\t}\n\n\tclaims := &CustomClaims{}\n\n\tfor k, v := range fields {\n\t\tswitch k {\n\t\tcase \"aud\":\n\t\t\tclaims.Audience = cast.ToString(v)\n\t\tcase \"sub\":\n\t\t\tclaims.Subject = cast.ToString(v)\n\t\tcase \"iss\":\n\t\t\tclaims.Issuer = cast.ToString(v)\n\t\tcase \"id\":\n\t\t\tclaims.Id = cast.ToString(v)\n\t\tcase \"exp\":\n\t\t\tclaims.ExpiresAt = cast.ToInt64(v)\n\t\tcase \"user_id\":\n\t\t\tclaims.UserId = cast.ToInt64(v)\n\t\tcase \"nbf\":\n\t\t\tclaims.NotBefore = cast.ToInt64(v)\n\t\tcase \"iat\":\n\t\t\tclaims.IssuedAt = time.Now().Unix()\n\t\t}\n\t}\n\n\tvar (\n\t\tsPrivateKey interface{}\n\t\terr         error\n\t)\n\n\tsPrivateKey, err = jwt.ParseRSAPrivateKeyFromPEM(privateKey)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\ttoken := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)\n\tss, err := token.SignedString(sPrivateKey)\n\n\tif err != nil {\n\n\t\treturn \"\", err\n\t}\n\treturn ss, nil\n}\n"
  },
  {
    "path": "cmd/migrate/migrate.go",
    "content": "package migrate\n\nimport (\n\t\"database/sql\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\t_ \"github.com/lib/pq\"\n\tmigrate \"github.com/rubenv/sql-migrate\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar (\n\targDsn, argTable string\n\targLimit         int\n\tdb               *sql.DB\n\tms               *migrate.FileMigrationSource\n\tinitCmdFn        = func(cmd *cobra.Command, _ []string) (re error) {\n\t\tvar e error\n\t\tdefer func() {\n\t\t\trecover()\n\t\t\tre = e\n\t\t}()\n\t\tms = &migrate.FileMigrationSource{\n\t\t\tDir: entrypoint.WorkDir() + \"/migrations\",\n\t\t}\n\t\tmigrate.SetTable(argTable)\n\t\tdb, e = sql.Open(\"postgres\", argDsn)\n\t\tif e != nil {\n\t\t\treturn e\n\t\t}\n\t\treturn nil\n\t}\n\tcmdUp = &cobra.Command{\n\t\tUse:           \"up\",\n\t\tShort:         \"Migrates the database to the most recent version available\",\n\t\tSilenceUsage:  true,\n\t\tSilenceErrors: true,\n\t\tRun: func(_ *cobra.Command, _ []string) {\n\t\t\tif e := initCmdFn(nil, nil); e != nil {\n\t\t\t\tfmt.Printf(\"Failed: %v\\n\", e.Error())\n\t\t\t\tos.Exit(1)\n\t\t\t}\n\t\t\tn, err := migrate.ExecMax(db, \"postgres\", ms, migrate.Up, argLimit)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Printf(\"Failed: %v\\n\", err.Error())\n\t\t\t\tos.Exit(1)\n\t\t\t}\n\t\t\tfmt.Printf(\"Applied %d migrations!\\n\", n)\n\t\t},\n\t}\n\tcmdDown = &cobra.Command{\n\t\tUse:           \"down\",\n\t\tShort:         \"Rollback a database migration\",\n\t\tSilenceUsage:  true,\n\t\tSilenceErrors: true,\n\t\tRun: func(_ *cobra.Command, _ []string) {\n\t\t\tif e := initCmdFn(nil, nil); e != nil {\n\t\t\t\tfmt.Printf(\"Failed: %v\\n\", e.Error())\n\t\t\t\tos.Exit(1)\n\t\t\t}\n\t\t\tn, err := migrate.ExecMax(db, \"postgres\", ms, migrate.Down, argLimit)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Printf(\"Failed: %v\\n\", err.Error())\n\t\t\t\tos.Exit(1)\n\t\t\t}\n\t\t\tfmt.Printf(\"Applied %d migrations!\\n\", n)\n\t\t},\n\t}\n\tCmd = &cobra.Command{\n\t\tUse:           \"migrate\",\n\t\tShort:         \"SQL migration tool\",\n\t\tSilenceUsage:  true,\n\t\tSilenceErrors: true,\n\t}\n)\n\nfunc init() {\n\tCmd.PersistentFlags().StringVar(&argTable, \"table\", \"migrations\", \"Table for migration history\")\n\tCmd.PersistentFlags().IntVar(&argLimit, \"limit\", 1, \"Limit the number of migrations (0 = unlimited)\")\n\tCmd.PersistentFlags().StringVar(&argDsn, \"dsn\", \"postgres://localhost:5432/golang_example_development?sslmode=disable\", \"DSN connection string\")\n\tCmd.AddCommand(cmdUp, cmdDown)\n}\n"
  },
  {
    "path": "cmd/product-service/nats_service.go",
    "content": "package product_service\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/nats-io/stan.go\"\n)\n\ntype natsService struct {\n\tlogger logger.Logger\n}\n\nfunc (s *natsService) workerHanlder(m *stan.Msg) {\n\ts.logger.Info(\"[NATS] Received a message: %s\\n\", logger.Args(string(m.Data)))\n\tm.Ack()\n}\n"
  },
  {
    "path": "cmd/product-service/product_service.go",
    "content": "package product_service\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"log\"\n\t\"net\"\n\t\"time\"\n\n\t\"go.opentelemetry.io/otel/propagation\"\n\n\t\"google.golang.org/grpc/credentials/insecure\"\n\n\t\"go.opentelemetry.io/otel\"\n\n\t\"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc\"\n\n\t\"github.com/nats-io/nats.go\"\n\t\"github.com/nats-io/stan.go\"\n\n\t\"github.com/aristat/golang-example-app/app/config\"\n\n\t\"github.com/aristat/golang-example-app/app/common\"\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\n\t\"github.com/aristat/golang-example-app/generated/resources/proto/health_checks\"\n\t\"github.com/aristat/golang-example-app/generated/resources/proto/products\"\n\temptypb \"google.golang.org/protobuf/types/known/emptypb\"\n\n\t\"github.com/spf13/cobra\"\n\t\"google.golang.org/grpc\"\n)\n\n// Config\ntype Config struct {\n\tPort           string\n\tHealthCheckUrl string\n\tNatsURL        string\n\tSubject        string\n}\n\ntype server struct {\n\tlogger logger.Logger\n\tcfg    Config\n\tproducts.UnimplementedProductsServer\n}\n\nfunc (s *server) ListProduct(ctx context.Context, in *products.ListProductIn) (*products.ListProductOut, error) {\n\ttracer := otel.GetTracerProvider()\n\n\tconn, err := grpc.Dial(s.cfg.HealthCheckUrl,\n\t\tgrpc.WithTransportCredentials(insecure.NewCredentials()),\n\t\tgrpc.WithChainUnaryInterceptor(\n\t\t\tlogger.UnaryClientInterceptor(s.logger, true),\n\t\t\totelgrpc.UnaryClientInterceptor(otelgrpc.WithTracerProvider(tracer), otelgrpc.WithPropagators(propagation.TraceContext{})),\n\t\t),\n\t\tgrpc.WithChainStreamInterceptor(\n\t\t\tlogger.StreamClientInterceptor(s.logger, true),\n\t\t\totelgrpc.StreamClientInterceptor(otelgrpc.WithTracerProvider(tracer), otelgrpc.WithPropagators(propagation.TraceContext{})),\n\t\t),\n\t)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer conn.Close()\n\tc := health_checks.NewHealthChecksClient(conn)\n\n\tctx, cancel := context.WithTimeout(ctx, time.Second)\n\tdefer cancel()\n\tisAliveOut, err := c.IsAlive(ctx, &emptypb.Empty{})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif isAliveOut.Status != health_checks.IsAliveOut_OK {\n\t\treturn nil, errors.New(\"Heal checks not working\")\n\t}\n\n\t// test result\n\tout := &products.ListProductOut{Status: products.ListProductOut_OK, Products: []*products.Product{}}\n\tout.Products = append(out.Products, &products.Product{Id: 1, Name: \"first_product\"})\n\tout.Products = append(out.Products, &products.Product{Id: 2, Name: \"second_product\"})\n\n\treturn out, nil\n}\n\n// Example service, which gives some data\nvar (\n\t//bind string\n\tCmd = &cobra.Command{\n\t\tUse:           \"product-service\",\n\t\tShort:         \"Product service\",\n\t\tSilenceUsage:  true,\n\t\tSilenceErrors: true,\n\t\tRun: func(_ *cobra.Command, _ []string) {\n\t\t\tconf, c, e := config.Build()\n\t\t\tif e != nil {\n\t\t\t\tpanic(e)\n\t\t\t}\n\t\t\tdefer c()\n\n\t\t\tclientConfig := Config{}\n\t\t\te = conf.UnmarshalKey(\"services.productService\", &clientConfig)\n\t\t\tif e != nil {\n\t\t\t\tlog.Fatal(\"Config initialize error\")\n\t\t\t}\n\n\t\t\tlog, c, e := logger.Build()\n\t\t\tif e != nil {\n\t\t\t\tpanic(e)\n\t\t\t}\n\t\t\tdefer c()\n\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\tif re, _ := r.(error); re != nil {\n\t\t\t\t\t\tlog.Error(re.Error())\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlog.Alert(\"unhandled panic, err: %v\", logger.Args(r))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\ttracer, e := common.GenerateTracerForTestClient(\"golang-example-app-product-service\", conf)\n\t\t\totel.SetTracerProvider(tracer)\n\n\t\t\tif e != nil {\n\t\t\t\tpanic(e)\n\t\t\t}\n\n\t\t\tdefer func() {\n\t\t\t\tif err := tracer.Shutdown(context.Background()); err != nil {\n\t\t\t\t\tlog.Printf(\"Error shutting down tracer provider: %v\", err)\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\tlog.Info(\"Start product service %s\", logger.Args(clientConfig.Port))\n\t\t\tlis, err := net.Listen(\"tcp\", \":\"+clientConfig.Port)\n\t\t\tif err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\n\t\t\tnc, err := nats.Connect(clientConfig.NatsURL)\n\t\t\tif err != nil {\n\t\t\t\tlog.Error(err.Error())\n\t\t\t\tpanic(err)\n\t\t\t}\n\t\t\tdefer nc.Close()\n\n\t\t\tsc, _ := stan.Connect(\"test-cluster\", \"example-subscriber\", stan.NatsConn(nc))\n\t\t\tnatsService := natsService{logger: log}\n\t\t\t_, err = sc.QueueSubscribe(clientConfig.Subject, \"worker\", natsService.workerHanlder, stan.DurableName(\"i-will-remember\"), stan.MaxInflight(1), stan.SetManualAckMode())\n\n\t\t\tif err != nil {\n\t\t\t\tsc.Close()\n\t\t\t\tlog.Error(err.Error())\n\t\t\t\tpanic(err)\n\t\t\t}\n\n\t\t\ts := grpc.NewServer(\n\t\t\t\tgrpc.ChainUnaryInterceptor(\n\t\t\t\t\tlogger.UnaryServerInterceptor(log, true),\n\t\t\t\t\totelgrpc.UnaryServerInterceptor(otelgrpc.WithTracerProvider(tracer), otelgrpc.WithPropagators(propagation.TraceContext{})),\n\t\t\t\t),\n\t\t\t\tgrpc.ChainStreamInterceptor(\n\t\t\t\t\tlogger.StreamServerInterceptor(log, true),\n\t\t\t\t\totelgrpc.StreamServerInterceptor(otelgrpc.WithTracerProvider(tracer), otelgrpc.WithPropagators(propagation.TraceContext{})),\n\t\t\t\t),\n\t\t\t)\n\t\t\tproducts.RegisterProductsServer(s, &server{logger: log, cfg: clientConfig})\n\n\t\t\tif err := s.Serve(lis); err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\t\t},\n\t}\n)\n\nfunc init() {\n}\n"
  },
  {
    "path": "cmd/root.go",
    "content": "package cmd\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/signal\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"syscall\"\n\n\t\"github.com/aristat/golang-example-app/cmd/jwt\"\n\n\t\"github.com/aristat/golang-example-app/cmd/migrate\"\n\n\thealth_check_service \"github.com/aristat/golang-example-app/cmd/health-check-service\"\n\tproduct_service \"github.com/aristat/golang-example-app/cmd/product-service\"\n\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\n\t\"go.uber.org/automaxprocs/maxprocs\"\n\n\t\"github.com/aristat/golang-example-app/cmd/daemon\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/viper\"\n)\n\nvar (\n\tconfigPath string\n\tdebug      bool\n\tv          *viper.Viper\n\tlog        logger.Logger\n)\n\nconst prefix = \"cmd.root\"\n\n// Root command\nvar rootCmd = &cobra.Command{\n\tUse:           \"bin [command]\",\n\tLong:          \"\",\n\tSilenceUsage:  true,\n\tSilenceErrors: true,\n\tPersistentPreRun: func(cmd *cobra.Command, _ []string) {\n\t\tl, c, e := logger.Build()\n\t\tdefer c()\n\t\tif e != nil {\n\t\t\tpanic(e)\n\t\t}\n\n\t\tlog = l.WithFields(logger.Fields{\"service\": prefix})\n\n\t\tv.SetConfigFile(configPath)\n\n\t\tif configPath != \"\" {\n\t\t\te := v.ReadInConfig()\n\t\t\tif e != nil {\n\t\t\t\tlog.Error(\"can't read config, %v\", logger.Args(errors.WithMessage(e, prefix)))\n\t\t\t\tos.Exit(1)\n\t\t\t}\n\t\t}\n\n\t\tif debug {\n\t\t\tb, _ := json.Marshal(v.AllSettings())\n\t\t\tvar out bytes.Buffer\n\t\t\te := json.Indent(&out, b, \"\", \"  \")\n\t\t\tif e != nil {\n\t\t\t\tlog.Error(\"can't prettify config\")\n\t\t\t\tos.Exit(1)\n\t\t\t}\n\t\t\tfmt.Println(string(out.Bytes()))\n\t\t}\n\n\t\t_, _ = maxprocs.Set(maxprocs.Logger(log.Printf))\n\t},\n}\n\nfunc init() {\n\tv = viper.New()\n\tv.SetConfigType(\"yaml\")\n\tv.SetEnvPrefix(\"APP\")\n\tv.SetEnvKeyReplacer(strings.NewReplacer(\"-\", \"_\", \".\", \"_\"))\n\tv.AutomaticEnv()\n\n\t// pflags\n\trootCmd.PersistentFlags().StringVarP(&configPath, \"config\", \"c\", \"\", \"config file\")\n\trootCmd.PersistentFlags().BoolVarP(&debug, \"debug\", \"d\", false, \"debug mode\")\n\n\t// initializing\n\twd := os.Getenv(\"APP_WD\")\n\tif len(wd) == 0 {\n\t\twd, _ = filepath.Abs(filepath.Dir(os.Args[0]))\n\t}\n\twd, _ = filepath.Abs(wd)\n\tep, _ := entrypoint.Initialize(wd, v)\n\n\t// bin pflags to viper\n\t_ = v.BindPFlags(rootCmd.PersistentFlags())\n\n\tgo func() {\n\t\treloadSignal := make(chan os.Signal)\n\t\tsignal.Notify(reloadSignal, syscall.SIGHUP)\n\t\tfor {\n\t\t\tsig := <-reloadSignal\n\t\t\tep.Reload()\n\t\t\tfmt.Printf(\"OS signaled `%v`, reload\", sig.String())\n\t\t}\n\t}()\n}\n\nfunc Execute() {\n\trootCmd.AddCommand(daemon.Cmd, product_service.Cmd, health_check_service.Cmd, migrate.Cmd, jwt.Cmd)\n\tif e := rootCmd.Execute(); e != nil {\n\t\t_, _ = fmt.Fprintf(os.Stderr, \"%v\\n\", e.Error())\n\t\tos.Exit(1)\n\t}\n}\n"
  },
  {
    "path": "dbconfig.yml",
    "content": "development:\n    dialect: postgres\n    datasource: dbname=golang_example_development sslmode=disable\n    dir: resources/migrations\n    table: migrations\n"
  },
  {
    "path": "docker/app/Dockerfile",
    "content": "FROM golang:1.17.9-alpine3.15 as builder\n\nRUN apk add --update make \\\n    && rm -rf /tmp/* \\\n    && rm -rf /var/cache/apk/*\n\nRUN mkdir /build\nWORKDIR /build\n\nCOPY . .\n\nRUN GOOS=linux GOARCH=amd64 make build\n\nFROM alpine:3.9\n\nCOPY --from=builder /build/docker/app/files /\nCOPY --from=builder /build/artifacts /app/\n\nWORKDIR /app\n\nRUN apk --no-cache add tzdata bash \\\n    && chmod +x /docker/bin/* \\\n    && chmod +x bin \\\n    && rm -rf /tmp/* \\\n    && rm -rf /var/cache/apk/*\n\nENTRYPOINT [\"/docker/bin/entrypoint.sh\"]\n"
  },
  {
    "path": "docker/app/files/docker/bin/entrypoint.sh",
    "content": "#!/usr/bin/env sh\n\nexec ./bin \"$@\"\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "version: '3.7'\nservices:\n  jaeger:\n    image: jaegertracing/all-in-one:latest\n    networks:\n      - intranet\n    ports:\n      - \"5775:5775/udp\"\n      - \"6831:6831/udp\"\n      - \"6832:6832/udp\"\n      - \"5778:5778\"\n      - \"16686:16686\"\n      - \"14268:14268\"\n      - \"9411:9411\"\n\n  #=============================#\n\n  # check migration before start\n  daemon-migrate:\n    image: golang-example-app:development\n    depends_on:\n      - postgres\n    networks:\n      - intranet\n    command:\n      migrate up --dsn=postgres://postgres@postgres:5432/golang_example_development?sslmode=disable --limit=0\n\n  daemon:\n    image: golang-example-app:development\n    command: daemon -c ./configs/docker_development.yaml -d\n    depends_on:\n      - product_service\n      - health_check_service\n      - daemon-migrate\n      - postgres\n      - redis\n      - nats-streaming\n    networks:\n      - intranet\n    ports:\n      - \"9096:9096\"\n\n  #=============================#\n\n  product_service:\n    image: golang-example-app:development\n    command: product-service -c ./configs/docker_development.yaml -d\n    depends_on:\n      - postgres\n    networks:\n      - intranet\n    ports:\n      - \"50051:50051\"\n\n  #=============================#\n\n  health_check_service:\n    image: golang-example-app:development\n    command: health-check -c ./configs/docker_development.yaml -d\n    networks:\n      - intranet\n    ports:\n      - \"50052:50052\"\n\n  #=============================#\n\n  postgres:\n    image: postgres:9.6\n    environment:\n      - POSTGRES_USER=postgres\n      - POSTGRES_DB=golang_example_development\n      - POSTGRES_HOST_AUTH_METHOD=trust\n    volumes:\n      - postgres_data:/var/lib/postgresql/data\n    ports:\n      - \"5532:5432\"\n    networks:\n      - intranet\n\n  redis:\n    image: redis:latest\n    volumes:\n      - redis_data:/data\n    networks:\n      - intranet\n\n  nats-streaming:\n    image: nats-streaming\n    ports:\n      - \"8222:8222\"\n      - \"4222:4222\"\n    networks:\n      - intranet\n\nnetworks:\n  intranet:\n    driver: bridge\n\nvolumes:\n  postgres_data:\n  redis_data:\n"
  },
  {
    "path": "generated/graphql/generated.go",
    "content": "// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\npackage graphql\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\t\"github.com/99designs/gqlgen/graphql\"\n\t\"github.com/99designs/gqlgen/graphql/introspection\"\n\t\"github.com/aristat/golang-example-app/app/db/domain\"\n\tgqlparser \"github.com/vektah/gqlparser/v2\"\n\t\"github.com/vektah/gqlparser/v2/ast\"\n)\n\n// region    ************************** generated!.gotpl **************************\n\n// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface.\nfunc NewExecutableSchema(cfg Config) graphql.ExecutableSchema {\n\treturn &executableSchema{\n\t\tresolvers:  cfg.Resolvers,\n\t\tdirectives: cfg.Directives,\n\t\tcomplexity: cfg.Complexity,\n\t}\n}\n\ntype Config struct {\n\tResolvers  ResolverRoot\n\tDirectives DirectiveRoot\n\tComplexity ComplexityRoot\n}\n\ntype ResolverRoot interface {\n\tMutation() MutationResolver\n\tProduct() ProductResolver\n\tProductsQuery() ProductsQueryResolver\n\tQuery() QueryResolver\n\tUsersMutation() UsersMutationResolver\n\tUsersQuery() UsersQueryResolver\n}\n\ntype DirectiveRoot struct {\n\tHasUsersPermission func(ctx context.Context, obj interface{}, next graphql.Resolver, permission UsersPermissionEnum) (res interface{}, err error)\n}\n\ntype ComplexityRoot struct {\n\tMutation struct {\n\t\tUsers func(childComplexity int) int\n\t}\n\n\tProduct struct {\n\t\tID           func(childComplexity int) int\n\t\tName         func(childComplexity int) int\n\t\tProductItems func(childComplexity int) int\n\t}\n\n\tProductItem struct {\n\t\tID   func(childComplexity int) int\n\t\tName func(childComplexity int) int\n\t}\n\n\tProductsListOut struct {\n\t\tProducts func(childComplexity int) int\n\t}\n\n\tProductsQuery struct {\n\t\tList func(childComplexity int) int\n\t}\n\n\tQuery struct {\n\t\tProducts func(childComplexity int) int\n\t\tUsers    func(childComplexity int) int\n\t}\n\n\tUsersCreateOut struct {\n\t\tEmail  func(childComplexity int) int\n\t\tID     func(childComplexity int) int\n\t\tStatus func(childComplexity int) int\n\t}\n\n\tUsersMutation struct {\n\t\tCreateUser func(childComplexity int, email string, password string) int\n\t}\n\n\tUsersOneOut struct {\n\t\tEmail func(childComplexity int) int\n\t\tID    func(childComplexity int) int\n\t}\n\n\tUsersQuery struct {\n\t\tOne func(childComplexity int, email string) int\n\t}\n}\n\ntype MutationResolver interface {\n\tUsers(ctx context.Context) (*UsersMutation, error)\n}\ntype ProductResolver interface {\n\tProductItems(ctx context.Context, obj *domain.Product) ([]*domain.ProductItem, error)\n}\ntype ProductsQueryResolver interface {\n\tList(ctx context.Context, obj *ProductsQuery) (*ProductsListOut, error)\n}\ntype QueryResolver interface {\n\tUsers(ctx context.Context) (*UsersQuery, error)\n\tProducts(ctx context.Context) (*ProductsQuery, error)\n}\ntype UsersMutationResolver interface {\n\tCreateUser(ctx context.Context, obj *UsersMutation, email string, password string) (*UsersCreateOut, error)\n}\ntype UsersQueryResolver interface {\n\tOne(ctx context.Context, obj *UsersQuery, email string) (*UsersOneOut, error)\n}\n\ntype executableSchema struct {\n\tresolvers  ResolverRoot\n\tdirectives DirectiveRoot\n\tcomplexity ComplexityRoot\n}\n\nfunc (e *executableSchema) Schema() *ast.Schema {\n\treturn parsedSchema\n}\n\nfunc (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) {\n\tec := executionContext{nil, e}\n\t_ = ec\n\tswitch typeName + \".\" + field {\n\n\tcase \"Mutation.users\":\n\t\tif e.complexity.Mutation.Users == nil {\n\t\t\tbreak\n\t\t}\n\n\t\treturn e.complexity.Mutation.Users(childComplexity), true\n\n\tcase \"Product.id\":\n\t\tif e.complexity.Product.ID == nil {\n\t\t\tbreak\n\t\t}\n\n\t\treturn e.complexity.Product.ID(childComplexity), true\n\n\tcase \"Product.name\":\n\t\tif e.complexity.Product.Name == nil {\n\t\t\tbreak\n\t\t}\n\n\t\treturn e.complexity.Product.Name(childComplexity), true\n\n\tcase \"Product.productItems\":\n\t\tif e.complexity.Product.ProductItems == nil {\n\t\t\tbreak\n\t\t}\n\n\t\treturn e.complexity.Product.ProductItems(childComplexity), true\n\n\tcase \"ProductItem.id\":\n\t\tif e.complexity.ProductItem.ID == nil {\n\t\t\tbreak\n\t\t}\n\n\t\treturn e.complexity.ProductItem.ID(childComplexity), true\n\n\tcase \"ProductItem.name\":\n\t\tif e.complexity.ProductItem.Name == nil {\n\t\t\tbreak\n\t\t}\n\n\t\treturn e.complexity.ProductItem.Name(childComplexity), true\n\n\tcase \"ProductsListOut.products\":\n\t\tif e.complexity.ProductsListOut.Products == nil {\n\t\t\tbreak\n\t\t}\n\n\t\treturn e.complexity.ProductsListOut.Products(childComplexity), true\n\n\tcase \"ProductsQuery.list\":\n\t\tif e.complexity.ProductsQuery.List == nil {\n\t\t\tbreak\n\t\t}\n\n\t\treturn e.complexity.ProductsQuery.List(childComplexity), true\n\n\tcase \"Query.products\":\n\t\tif e.complexity.Query.Products == nil {\n\t\t\tbreak\n\t\t}\n\n\t\treturn e.complexity.Query.Products(childComplexity), true\n\n\tcase \"Query.users\":\n\t\tif e.complexity.Query.Users == nil {\n\t\t\tbreak\n\t\t}\n\n\t\treturn e.complexity.Query.Users(childComplexity), true\n\n\tcase \"UsersCreateOut.email\":\n\t\tif e.complexity.UsersCreateOut.Email == nil {\n\t\t\tbreak\n\t\t}\n\n\t\treturn e.complexity.UsersCreateOut.Email(childComplexity), true\n\n\tcase \"UsersCreateOut.id\":\n\t\tif e.complexity.UsersCreateOut.ID == nil {\n\t\t\tbreak\n\t\t}\n\n\t\treturn e.complexity.UsersCreateOut.ID(childComplexity), true\n\n\tcase \"UsersCreateOut.status\":\n\t\tif e.complexity.UsersCreateOut.Status == nil {\n\t\t\tbreak\n\t\t}\n\n\t\treturn e.complexity.UsersCreateOut.Status(childComplexity), true\n\n\tcase \"UsersMutation.createUser\":\n\t\tif e.complexity.UsersMutation.CreateUser == nil {\n\t\t\tbreak\n\t\t}\n\n\t\targs, err := ec.field_UsersMutation_createUser_args(context.TODO(), rawArgs)\n\t\tif err != nil {\n\t\t\treturn 0, false\n\t\t}\n\n\t\treturn e.complexity.UsersMutation.CreateUser(childComplexity, args[\"email\"].(string), args[\"password\"].(string)), true\n\n\tcase \"UsersOneOut.email\":\n\t\tif e.complexity.UsersOneOut.Email == nil {\n\t\t\tbreak\n\t\t}\n\n\t\treturn e.complexity.UsersOneOut.Email(childComplexity), true\n\n\tcase \"UsersOneOut.id\":\n\t\tif e.complexity.UsersOneOut.ID == nil {\n\t\t\tbreak\n\t\t}\n\n\t\treturn e.complexity.UsersOneOut.ID(childComplexity), true\n\n\tcase \"UsersQuery.one\":\n\t\tif e.complexity.UsersQuery.One == nil {\n\t\t\tbreak\n\t\t}\n\n\t\targs, err := ec.field_UsersQuery_one_args(context.TODO(), rawArgs)\n\t\tif err != nil {\n\t\t\treturn 0, false\n\t\t}\n\n\t\treturn e.complexity.UsersQuery.One(childComplexity, args[\"email\"].(string)), true\n\n\t}\n\treturn 0, false\n}\n\nfunc (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {\n\trc := graphql.GetOperationContext(ctx)\n\tec := executionContext{rc, e}\n\tfirst := true\n\n\tswitch rc.Operation.Operation {\n\tcase ast.Query:\n\t\treturn func(ctx context.Context) *graphql.Response {\n\t\t\tif !first {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tfirst = false\n\t\t\tdata := ec._Query(ctx, rc.Operation.SelectionSet)\n\t\t\tvar buf bytes.Buffer\n\t\t\tdata.MarshalGQL(&buf)\n\n\t\t\treturn &graphql.Response{\n\t\t\t\tData: buf.Bytes(),\n\t\t\t}\n\t\t}\n\tcase ast.Mutation:\n\t\treturn func(ctx context.Context) *graphql.Response {\n\t\t\tif !first {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tfirst = false\n\t\t\tdata := ec._Mutation(ctx, rc.Operation.SelectionSet)\n\t\t\tvar buf bytes.Buffer\n\t\t\tdata.MarshalGQL(&buf)\n\n\t\t\treturn &graphql.Response{\n\t\t\t\tData: buf.Bytes(),\n\t\t\t}\n\t\t}\n\n\tdefault:\n\t\treturn graphql.OneShot(graphql.ErrorResponse(ctx, \"unsupported GraphQL operation\"))\n\t}\n}\n\ntype executionContext struct {\n\t*graphql.OperationContext\n\t*executableSchema\n}\n\nfunc (ec *executionContext) introspectSchema() (*introspection.Schema, error) {\n\tif ec.DisableIntrospection {\n\t\treturn nil, errors.New(\"introspection disabled\")\n\t}\n\treturn introspection.WrapSchema(parsedSchema), nil\n}\n\nfunc (ec *executionContext) introspectType(name string) (*introspection.Type, error) {\n\tif ec.DisableIntrospection {\n\t\treturn nil, errors.New(\"introspection disabled\")\n\t}\n\treturn introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil\n}\n\nvar sources = []*ast.Source{\n\t{Name: \"resources/graphql/products.graphql\", Input: `type ProductsQuery {\n    list: ProductsListOut!\n}\n\ntype Product {\n    id: ID!\n    name: String!\n    productItems: [ProductItem!]!\n}\n\ntype ProductItem {\n    id: ID!\n    name: String!\n}\n\ntype ProductsListOut {\n    products: [Product!]!\n}\n`, BuiltIn: false},\n\t{Name: \"resources/graphql/root.graphql\", Input: `type Query {\n    users: UsersQuery\n    products: ProductsQuery\n}\n\ntype Mutation {\n    users: UsersMutation\n}\n`, BuiltIn: false},\n\t{Name: \"resources/graphql/user.graphql\", Input: `type UsersOneOut {\n    id: ID!\n    email: String!\n}\n\ntype UsersQuery {\n    one(email: String!): UsersOneOut! @hasUsersPermission(permission: READ)\n}\n\ntype UsersMutation {\n    createUser(email: String!, password: String!): UsersCreateOut! @hasUsersPermission(permission: WRITE)\n}\n\ntype UsersCreateOut {\n    status: UsersCreateOutStatus!\n    id: ID!\n    email: String!\n}\n\nenum UsersCreateOutStatus {\n    OK\n    BAD_REQUEST\n    SERVER_INTERNAL_ERROR\n}\n\ndirective @hasUsersPermission(permission: UsersPermissionEnum!) on FIELD_DEFINITION\n\nenum UsersPermissionEnum {\n    READ\n    WRITE\n}\n`, BuiltIn: false},\n}\nvar parsedSchema = gqlparser.MustLoadSchema(sources...)\n\n// endregion ************************** generated!.gotpl **************************\n\n// region    ***************************** args.gotpl *****************************\n\nfunc (ec *executionContext) dir_hasUsersPermission_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {\n\tvar err error\n\targs := map[string]interface{}{}\n\tvar arg0 UsersPermissionEnum\n\tif tmp, ok := rawArgs[\"permission\"]; ok {\n\t\tctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField(\"permission\"))\n\t\targ0, err = ec.unmarshalNUsersPermissionEnum2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersPermissionEnum(ctx, tmp)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\targs[\"permission\"] = arg0\n\treturn args, nil\n}\n\nfunc (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {\n\tvar err error\n\targs := map[string]interface{}{}\n\tvar arg0 string\n\tif tmp, ok := rawArgs[\"name\"]; ok {\n\t\tctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField(\"name\"))\n\t\targ0, err = ec.unmarshalNString2string(ctx, tmp)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\targs[\"name\"] = arg0\n\treturn args, nil\n}\n\nfunc (ec *executionContext) field_UsersMutation_createUser_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {\n\tvar err error\n\targs := map[string]interface{}{}\n\tvar arg0 string\n\tif tmp, ok := rawArgs[\"email\"]; ok {\n\t\tctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField(\"email\"))\n\t\targ0, err = ec.unmarshalNString2string(ctx, tmp)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\targs[\"email\"] = arg0\n\tvar arg1 string\n\tif tmp, ok := rawArgs[\"password\"]; ok {\n\t\tctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField(\"password\"))\n\t\targ1, err = ec.unmarshalNString2string(ctx, tmp)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\targs[\"password\"] = arg1\n\treturn args, nil\n}\n\nfunc (ec *executionContext) field_UsersQuery_one_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {\n\tvar err error\n\targs := map[string]interface{}{}\n\tvar arg0 string\n\tif tmp, ok := rawArgs[\"email\"]; ok {\n\t\tctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField(\"email\"))\n\t\targ0, err = ec.unmarshalNString2string(ctx, tmp)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\targs[\"email\"] = arg0\n\treturn args, nil\n}\n\nfunc (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {\n\tvar err error\n\targs := map[string]interface{}{}\n\tvar arg0 bool\n\tif tmp, ok := rawArgs[\"includeDeprecated\"]; ok {\n\t\tctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField(\"includeDeprecated\"))\n\t\targ0, err = ec.unmarshalOBoolean2bool(ctx, tmp)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\targs[\"includeDeprecated\"] = arg0\n\treturn args, nil\n}\n\nfunc (ec *executionContext) field___Type_fields_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {\n\tvar err error\n\targs := map[string]interface{}{}\n\tvar arg0 bool\n\tif tmp, ok := rawArgs[\"includeDeprecated\"]; ok {\n\t\tctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField(\"includeDeprecated\"))\n\t\targ0, err = ec.unmarshalOBoolean2bool(ctx, tmp)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\targs[\"includeDeprecated\"] = arg0\n\treturn args, nil\n}\n\n// endregion ***************************** args.gotpl *****************************\n\n// region    ************************** directives.gotpl **************************\n\n// endregion ************************** directives.gotpl **************************\n\n// region    **************************** field.gotpl *****************************\n\nfunc (ec *executionContext) _Mutation_users(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"Mutation\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn ec.resolvers.Mutation().Users(rctx)\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(*UsersMutation)\n\tfc.Result = res\n\treturn ec.marshalOUsersMutation2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersMutation(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) _Product_id(ctx context.Context, field graphql.CollectedField, obj *domain.Product) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"Product\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.ID, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(int)\n\tfc.Result = res\n\treturn ec.marshalNID2int(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) _Product_name(ctx context.Context, field graphql.CollectedField, obj *domain.Product) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"Product\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Name, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(string)\n\tfc.Result = res\n\treturn ec.marshalNString2string(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) _Product_productItems(ctx context.Context, field graphql.CollectedField, obj *domain.Product) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"Product\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn ec.resolvers.Product().ProductItems(rctx, obj)\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.([]*domain.ProductItem)\n\tfc.Result = res\n\treturn ec.marshalNProductItem2ᚕᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProductItemᚄ(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) _ProductItem_id(ctx context.Context, field graphql.CollectedField, obj *domain.ProductItem) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"ProductItem\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.ID, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(int)\n\tfc.Result = res\n\treturn ec.marshalNID2int(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) _ProductItem_name(ctx context.Context, field graphql.CollectedField, obj *domain.ProductItem) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"ProductItem\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Name, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(string)\n\tfc.Result = res\n\treturn ec.marshalNString2string(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) _ProductsListOut_products(ctx context.Context, field graphql.CollectedField, obj *ProductsListOut) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"ProductsListOut\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Products, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.([]*domain.Product)\n\tfc.Result = res\n\treturn ec.marshalNProduct2ᚕᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProductᚄ(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) _ProductsQuery_list(ctx context.Context, field graphql.CollectedField, obj *ProductsQuery) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"ProductsQuery\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn ec.resolvers.ProductsQuery().List(rctx, obj)\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(*ProductsListOut)\n\tfc.Result = res\n\treturn ec.marshalNProductsListOut2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐProductsListOut(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) _Query_users(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"Query\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn ec.resolvers.Query().Users(rctx)\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(*UsersQuery)\n\tfc.Result = res\n\treturn ec.marshalOUsersQuery2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersQuery(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) _Query_products(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"Query\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn ec.resolvers.Query().Products(rctx)\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(*ProductsQuery)\n\tfc.Result = res\n\treturn ec.marshalOProductsQuery2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐProductsQuery(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"Query\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\trawArgs := field.ArgumentMap(ec.Variables)\n\targs, err := ec.field_Query___type_args(ctx, rawArgs)\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tfc.Args = args\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn ec.introspectType(args[\"name\"].(string))\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(*introspection.Type)\n\tfc.Result = res\n\treturn ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"Query\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn ec.introspectSchema()\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(*introspection.Schema)\n\tfc.Result = res\n\treturn ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) _UsersCreateOut_status(ctx context.Context, field graphql.CollectedField, obj *UsersCreateOut) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"UsersCreateOut\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Status, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(UsersCreateOutStatus)\n\tfc.Result = res\n\treturn ec.marshalNUsersCreateOutStatus2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersCreateOutStatus(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) _UsersCreateOut_id(ctx context.Context, field graphql.CollectedField, obj *UsersCreateOut) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"UsersCreateOut\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.ID, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(string)\n\tfc.Result = res\n\treturn ec.marshalNID2string(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) _UsersCreateOut_email(ctx context.Context, field graphql.CollectedField, obj *UsersCreateOut) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"UsersCreateOut\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Email, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(string)\n\tfc.Result = res\n\treturn ec.marshalNString2string(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) _UsersMutation_createUser(ctx context.Context, field graphql.CollectedField, obj *UsersMutation) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"UsersMutation\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\trawArgs := field.ArgumentMap(ec.Variables)\n\targs, err := ec.field_UsersMutation_createUser_args(ctx, rawArgs)\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tfc.Args = args\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tdirective0 := func(rctx context.Context) (interface{}, error) {\n\t\t\tctx = rctx // use context from middleware stack in children\n\t\t\treturn ec.resolvers.UsersMutation().CreateUser(rctx, obj, args[\"email\"].(string), args[\"password\"].(string))\n\t\t}\n\t\tdirective1 := func(ctx context.Context) (interface{}, error) {\n\t\t\tpermission, err := ec.unmarshalNUsersPermissionEnum2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersPermissionEnum(ctx, \"WRITE\")\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif ec.directives.HasUsersPermission == nil {\n\t\t\t\treturn nil, errors.New(\"directive hasUsersPermission is not implemented\")\n\t\t\t}\n\t\t\treturn ec.directives.HasUsersPermission(ctx, obj, directive0, permission)\n\t\t}\n\n\t\ttmp, err := directive1(rctx)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif tmp == nil {\n\t\t\treturn nil, nil\n\t\t}\n\t\tif data, ok := tmp.(*UsersCreateOut); ok {\n\t\t\treturn data, nil\n\t\t}\n\t\treturn nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/aristat/golang-example-app/generated/graphql.UsersCreateOut`, tmp)\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(*UsersCreateOut)\n\tfc.Result = res\n\treturn ec.marshalNUsersCreateOut2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersCreateOut(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) _UsersOneOut_id(ctx context.Context, field graphql.CollectedField, obj *UsersOneOut) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"UsersOneOut\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.ID, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(string)\n\tfc.Result = res\n\treturn ec.marshalNID2string(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) _UsersOneOut_email(ctx context.Context, field graphql.CollectedField, obj *UsersOneOut) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"UsersOneOut\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Email, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(string)\n\tfc.Result = res\n\treturn ec.marshalNString2string(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) _UsersQuery_one(ctx context.Context, field graphql.CollectedField, obj *UsersQuery) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"UsersQuery\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\trawArgs := field.ArgumentMap(ec.Variables)\n\targs, err := ec.field_UsersQuery_one_args(ctx, rawArgs)\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tfc.Args = args\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tdirective0 := func(rctx context.Context) (interface{}, error) {\n\t\t\tctx = rctx // use context from middleware stack in children\n\t\t\treturn ec.resolvers.UsersQuery().One(rctx, obj, args[\"email\"].(string))\n\t\t}\n\t\tdirective1 := func(ctx context.Context) (interface{}, error) {\n\t\t\tpermission, err := ec.unmarshalNUsersPermissionEnum2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersPermissionEnum(ctx, \"READ\")\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif ec.directives.HasUsersPermission == nil {\n\t\t\t\treturn nil, errors.New(\"directive hasUsersPermission is not implemented\")\n\t\t\t}\n\t\t\treturn ec.directives.HasUsersPermission(ctx, obj, directive0, permission)\n\t\t}\n\n\t\ttmp, err := directive1(rctx)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif tmp == nil {\n\t\t\treturn nil, nil\n\t\t}\n\t\tif data, ok := tmp.(*UsersOneOut); ok {\n\t\t\treturn data, nil\n\t\t}\n\t\treturn nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/aristat/golang-example-app/generated/graphql.UsersOneOut`, tmp)\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(*UsersOneOut)\n\tfc.Result = res\n\treturn ec.marshalNUsersOneOut2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersOneOut(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Directive\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Name, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(string)\n\tfc.Result = res\n\treturn ec.marshalNString2string(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Directive\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Description, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(string)\n\tfc.Result = res\n\treturn ec.marshalOString2string(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Directive\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Locations, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.([]string)\n\tfc.Result = res\n\treturn ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Directive\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Args, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.([]introspection.InputValue)\n\tfc.Result = res\n\treturn ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__EnumValue\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Name, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(string)\n\tfc.Result = res\n\treturn ec.marshalNString2string(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__EnumValue\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Description, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(string)\n\tfc.Result = res\n\treturn ec.marshalOString2string(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__EnumValue\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.IsDeprecated(), nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(bool)\n\tfc.Result = res\n\treturn ec.marshalNBoolean2bool(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__EnumValue\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.DeprecationReason(), nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(*string)\n\tfc.Result = res\n\treturn ec.marshalOString2ᚖstring(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Field\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Name, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(string)\n\tfc.Result = res\n\treturn ec.marshalNString2string(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Field\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Description, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(string)\n\tfc.Result = res\n\treturn ec.marshalOString2string(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Field\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Args, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.([]introspection.InputValue)\n\tfc.Result = res\n\treturn ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Field\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Type, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(*introspection.Type)\n\tfc.Result = res\n\treturn ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Field\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.IsDeprecated(), nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(bool)\n\tfc.Result = res\n\treturn ec.marshalNBoolean2bool(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Field\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.DeprecationReason(), nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(*string)\n\tfc.Result = res\n\treturn ec.marshalOString2ᚖstring(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__InputValue\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Name, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(string)\n\tfc.Result = res\n\treturn ec.marshalNString2string(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__InputValue\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Description, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(string)\n\tfc.Result = res\n\treturn ec.marshalOString2string(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__InputValue\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Type, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(*introspection.Type)\n\tfc.Result = res\n\treturn ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__InputValue\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: false,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.DefaultValue, nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(*string)\n\tfc.Result = res\n\treturn ec.marshalOString2ᚖstring(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Schema\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Types(), nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.([]introspection.Type)\n\tfc.Result = res\n\treturn ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Schema\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.QueryType(), nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(*introspection.Type)\n\tfc.Result = res\n\treturn ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Schema\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.MutationType(), nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(*introspection.Type)\n\tfc.Result = res\n\treturn ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Schema\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.SubscriptionType(), nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(*introspection.Type)\n\tfc.Result = res\n\treturn ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Schema\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Directives(), nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.([]introspection.Directive)\n\tfc.Result = res\n\treturn ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Type\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Kind(), nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\tif !graphql.HasFieldError(ctx, fc) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(string)\n\tfc.Result = res\n\treturn ec.marshalN__TypeKind2string(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Type\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Name(), nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(*string)\n\tfc.Result = res\n\treturn ec.marshalOString2ᚖstring(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Type\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Description(), nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(string)\n\tfc.Result = res\n\treturn ec.marshalOString2string(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Type\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\trawArgs := field.ArgumentMap(ec.Variables)\n\targs, err := ec.field___Type_fields_args(ctx, rawArgs)\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tfc.Args = args\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Fields(args[\"includeDeprecated\"].(bool)), nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.([]introspection.Field)\n\tfc.Result = res\n\treturn ec.marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Type\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.Interfaces(), nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.([]introspection.Type)\n\tfc.Result = res\n\treturn ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Type\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.PossibleTypes(), nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.([]introspection.Type)\n\tfc.Result = res\n\treturn ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Type\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\trawArgs := field.ArgumentMap(ec.Variables)\n\targs, err := ec.field___Type_enumValues_args(ctx, rawArgs)\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tfc.Args = args\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.EnumValues(args[\"includeDeprecated\"].(bool)), nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.([]introspection.EnumValue)\n\tfc.Result = res\n\treturn ec.marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Type\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.InputFields(), nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.([]introspection.InputValue)\n\tfc.Result = res\n\treturn ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res)\n}\n\nfunc (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = graphql.Null\n\t\t}\n\t}()\n\tfc := &graphql.FieldContext{\n\t\tObject:   \"__Type\",\n\t\tField:    field,\n\t\tArgs:     nil,\n\t\tIsMethod: true,\n\t}\n\n\tctx = graphql.WithFieldContext(ctx, fc)\n\tresTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {\n\t\tctx = rctx // use context from middleware stack in children\n\t\treturn obj.OfType(), nil\n\t})\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn graphql.Null\n\t}\n\tif resTmp == nil {\n\t\treturn graphql.Null\n\t}\n\tres := resTmp.(*introspection.Type)\n\tfc.Result = res\n\treturn ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)\n}\n\n// endregion **************************** field.gotpl *****************************\n\n// region    **************************** input.gotpl *****************************\n\n// endregion **************************** input.gotpl *****************************\n\n// region    ************************** interface.gotpl ***************************\n\n// endregion ************************** interface.gotpl ***************************\n\n// region    **************************** object.gotpl ****************************\n\nvar mutationImplementors = []string{\"Mutation\"}\n\nfunc (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler {\n\tfields := graphql.CollectFields(ec.OperationContext, sel, mutationImplementors)\n\n\tctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{\n\t\tObject: \"Mutation\",\n\t})\n\n\tout := graphql.NewFieldSet(fields)\n\tvar invalids uint32\n\tfor i, field := range fields {\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString(\"Mutation\")\n\t\tcase \"users\":\n\t\t\tout.Values[i] = ec._Mutation_users(ctx, field)\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\tout.Dispatch()\n\tif invalids > 0 {\n\t\treturn graphql.Null\n\t}\n\treturn out\n}\n\nvar productImplementors = []string{\"Product\"}\n\nfunc (ec *executionContext) _Product(ctx context.Context, sel ast.SelectionSet, obj *domain.Product) graphql.Marshaler {\n\tfields := graphql.CollectFields(ec.OperationContext, sel, productImplementors)\n\n\tout := graphql.NewFieldSet(fields)\n\tvar invalids uint32\n\tfor i, field := range fields {\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString(\"Product\")\n\t\tcase \"id\":\n\t\t\tout.Values[i] = ec._Product_id(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tatomic.AddUint32(&invalids, 1)\n\t\t\t}\n\t\tcase \"name\":\n\t\t\tout.Values[i] = ec._Product_name(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tatomic.AddUint32(&invalids, 1)\n\t\t\t}\n\t\tcase \"productItems\":\n\t\t\tfield := field\n\t\t\tout.Concurrently(i, func() (res graphql.Marshaler) {\n\t\t\t\tdefer func() {\n\t\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t\tres = ec._Product_productItems(ctx, field, obj)\n\t\t\t\tif res == graphql.Null {\n\t\t\t\t\tatomic.AddUint32(&invalids, 1)\n\t\t\t\t}\n\t\t\t\treturn res\n\t\t\t})\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\tout.Dispatch()\n\tif invalids > 0 {\n\t\treturn graphql.Null\n\t}\n\treturn out\n}\n\nvar productItemImplementors = []string{\"ProductItem\"}\n\nfunc (ec *executionContext) _ProductItem(ctx context.Context, sel ast.SelectionSet, obj *domain.ProductItem) graphql.Marshaler {\n\tfields := graphql.CollectFields(ec.OperationContext, sel, productItemImplementors)\n\n\tout := graphql.NewFieldSet(fields)\n\tvar invalids uint32\n\tfor i, field := range fields {\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString(\"ProductItem\")\n\t\tcase \"id\":\n\t\t\tout.Values[i] = ec._ProductItem_id(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tcase \"name\":\n\t\t\tout.Values[i] = ec._ProductItem_name(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\tout.Dispatch()\n\tif invalids > 0 {\n\t\treturn graphql.Null\n\t}\n\treturn out\n}\n\nvar productsListOutImplementors = []string{\"ProductsListOut\"}\n\nfunc (ec *executionContext) _ProductsListOut(ctx context.Context, sel ast.SelectionSet, obj *ProductsListOut) graphql.Marshaler {\n\tfields := graphql.CollectFields(ec.OperationContext, sel, productsListOutImplementors)\n\n\tout := graphql.NewFieldSet(fields)\n\tvar invalids uint32\n\tfor i, field := range fields {\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString(\"ProductsListOut\")\n\t\tcase \"products\":\n\t\t\tout.Values[i] = ec._ProductsListOut_products(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\tout.Dispatch()\n\tif invalids > 0 {\n\t\treturn graphql.Null\n\t}\n\treturn out\n}\n\nvar productsQueryImplementors = []string{\"ProductsQuery\"}\n\nfunc (ec *executionContext) _ProductsQuery(ctx context.Context, sel ast.SelectionSet, obj *ProductsQuery) graphql.Marshaler {\n\tfields := graphql.CollectFields(ec.OperationContext, sel, productsQueryImplementors)\n\n\tout := graphql.NewFieldSet(fields)\n\tvar invalids uint32\n\tfor i, field := range fields {\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString(\"ProductsQuery\")\n\t\tcase \"list\":\n\t\t\tfield := field\n\t\t\tout.Concurrently(i, func() (res graphql.Marshaler) {\n\t\t\t\tdefer func() {\n\t\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t\tres = ec._ProductsQuery_list(ctx, field, obj)\n\t\t\t\tif res == graphql.Null {\n\t\t\t\t\tatomic.AddUint32(&invalids, 1)\n\t\t\t\t}\n\t\t\t\treturn res\n\t\t\t})\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\tout.Dispatch()\n\tif invalids > 0 {\n\t\treturn graphql.Null\n\t}\n\treturn out\n}\n\nvar queryImplementors = []string{\"Query\"}\n\nfunc (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler {\n\tfields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors)\n\n\tctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{\n\t\tObject: \"Query\",\n\t})\n\n\tout := graphql.NewFieldSet(fields)\n\tvar invalids uint32\n\tfor i, field := range fields {\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString(\"Query\")\n\t\tcase \"users\":\n\t\t\tfield := field\n\t\t\tout.Concurrently(i, func() (res graphql.Marshaler) {\n\t\t\t\tdefer func() {\n\t\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t\tres = ec._Query_users(ctx, field)\n\t\t\t\treturn res\n\t\t\t})\n\t\tcase \"products\":\n\t\t\tfield := field\n\t\t\tout.Concurrently(i, func() (res graphql.Marshaler) {\n\t\t\t\tdefer func() {\n\t\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t\tres = ec._Query_products(ctx, field)\n\t\t\t\treturn res\n\t\t\t})\n\t\tcase \"__type\":\n\t\t\tout.Values[i] = ec._Query___type(ctx, field)\n\t\tcase \"__schema\":\n\t\t\tout.Values[i] = ec._Query___schema(ctx, field)\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\tout.Dispatch()\n\tif invalids > 0 {\n\t\treturn graphql.Null\n\t}\n\treturn out\n}\n\nvar usersCreateOutImplementors = []string{\"UsersCreateOut\"}\n\nfunc (ec *executionContext) _UsersCreateOut(ctx context.Context, sel ast.SelectionSet, obj *UsersCreateOut) graphql.Marshaler {\n\tfields := graphql.CollectFields(ec.OperationContext, sel, usersCreateOutImplementors)\n\n\tout := graphql.NewFieldSet(fields)\n\tvar invalids uint32\n\tfor i, field := range fields {\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString(\"UsersCreateOut\")\n\t\tcase \"status\":\n\t\t\tout.Values[i] = ec._UsersCreateOut_status(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tcase \"id\":\n\t\t\tout.Values[i] = ec._UsersCreateOut_id(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tcase \"email\":\n\t\t\tout.Values[i] = ec._UsersCreateOut_email(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\tout.Dispatch()\n\tif invalids > 0 {\n\t\treturn graphql.Null\n\t}\n\treturn out\n}\n\nvar usersMutationImplementors = []string{\"UsersMutation\"}\n\nfunc (ec *executionContext) _UsersMutation(ctx context.Context, sel ast.SelectionSet, obj *UsersMutation) graphql.Marshaler {\n\tfields := graphql.CollectFields(ec.OperationContext, sel, usersMutationImplementors)\n\n\tout := graphql.NewFieldSet(fields)\n\tvar invalids uint32\n\tfor i, field := range fields {\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString(\"UsersMutation\")\n\t\tcase \"createUser\":\n\t\t\tfield := field\n\t\t\tout.Concurrently(i, func() (res graphql.Marshaler) {\n\t\t\t\tdefer func() {\n\t\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t\tres = ec._UsersMutation_createUser(ctx, field, obj)\n\t\t\t\tif res == graphql.Null {\n\t\t\t\t\tatomic.AddUint32(&invalids, 1)\n\t\t\t\t}\n\t\t\t\treturn res\n\t\t\t})\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\tout.Dispatch()\n\tif invalids > 0 {\n\t\treturn graphql.Null\n\t}\n\treturn out\n}\n\nvar usersOneOutImplementors = []string{\"UsersOneOut\"}\n\nfunc (ec *executionContext) _UsersOneOut(ctx context.Context, sel ast.SelectionSet, obj *UsersOneOut) graphql.Marshaler {\n\tfields := graphql.CollectFields(ec.OperationContext, sel, usersOneOutImplementors)\n\n\tout := graphql.NewFieldSet(fields)\n\tvar invalids uint32\n\tfor i, field := range fields {\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString(\"UsersOneOut\")\n\t\tcase \"id\":\n\t\t\tout.Values[i] = ec._UsersOneOut_id(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tcase \"email\":\n\t\t\tout.Values[i] = ec._UsersOneOut_email(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\tout.Dispatch()\n\tif invalids > 0 {\n\t\treturn graphql.Null\n\t}\n\treturn out\n}\n\nvar usersQueryImplementors = []string{\"UsersQuery\"}\n\nfunc (ec *executionContext) _UsersQuery(ctx context.Context, sel ast.SelectionSet, obj *UsersQuery) graphql.Marshaler {\n\tfields := graphql.CollectFields(ec.OperationContext, sel, usersQueryImplementors)\n\n\tout := graphql.NewFieldSet(fields)\n\tvar invalids uint32\n\tfor i, field := range fields {\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString(\"UsersQuery\")\n\t\tcase \"one\":\n\t\t\tfield := field\n\t\t\tout.Concurrently(i, func() (res graphql.Marshaler) {\n\t\t\t\tdefer func() {\n\t\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t\tres = ec._UsersQuery_one(ctx, field, obj)\n\t\t\t\tif res == graphql.Null {\n\t\t\t\t\tatomic.AddUint32(&invalids, 1)\n\t\t\t\t}\n\t\t\t\treturn res\n\t\t\t})\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\tout.Dispatch()\n\tif invalids > 0 {\n\t\treturn graphql.Null\n\t}\n\treturn out\n}\n\nvar __DirectiveImplementors = []string{\"__Directive\"}\n\nfunc (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler {\n\tfields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors)\n\n\tout := graphql.NewFieldSet(fields)\n\tvar invalids uint32\n\tfor i, field := range fields {\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString(\"__Directive\")\n\t\tcase \"name\":\n\t\t\tout.Values[i] = ec.___Directive_name(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tcase \"description\":\n\t\t\tout.Values[i] = ec.___Directive_description(ctx, field, obj)\n\t\tcase \"locations\":\n\t\t\tout.Values[i] = ec.___Directive_locations(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tcase \"args\":\n\t\t\tout.Values[i] = ec.___Directive_args(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\tout.Dispatch()\n\tif invalids > 0 {\n\t\treturn graphql.Null\n\t}\n\treturn out\n}\n\nvar __EnumValueImplementors = []string{\"__EnumValue\"}\n\nfunc (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler {\n\tfields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors)\n\n\tout := graphql.NewFieldSet(fields)\n\tvar invalids uint32\n\tfor i, field := range fields {\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString(\"__EnumValue\")\n\t\tcase \"name\":\n\t\t\tout.Values[i] = ec.___EnumValue_name(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tcase \"description\":\n\t\t\tout.Values[i] = ec.___EnumValue_description(ctx, field, obj)\n\t\tcase \"isDeprecated\":\n\t\t\tout.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tcase \"deprecationReason\":\n\t\t\tout.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj)\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\tout.Dispatch()\n\tif invalids > 0 {\n\t\treturn graphql.Null\n\t}\n\treturn out\n}\n\nvar __FieldImplementors = []string{\"__Field\"}\n\nfunc (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler {\n\tfields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors)\n\n\tout := graphql.NewFieldSet(fields)\n\tvar invalids uint32\n\tfor i, field := range fields {\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString(\"__Field\")\n\t\tcase \"name\":\n\t\t\tout.Values[i] = ec.___Field_name(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tcase \"description\":\n\t\t\tout.Values[i] = ec.___Field_description(ctx, field, obj)\n\t\tcase \"args\":\n\t\t\tout.Values[i] = ec.___Field_args(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tcase \"type\":\n\t\t\tout.Values[i] = ec.___Field_type(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tcase \"isDeprecated\":\n\t\t\tout.Values[i] = ec.___Field_isDeprecated(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tcase \"deprecationReason\":\n\t\t\tout.Values[i] = ec.___Field_deprecationReason(ctx, field, obj)\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\tout.Dispatch()\n\tif invalids > 0 {\n\t\treturn graphql.Null\n\t}\n\treturn out\n}\n\nvar __InputValueImplementors = []string{\"__InputValue\"}\n\nfunc (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler {\n\tfields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors)\n\n\tout := graphql.NewFieldSet(fields)\n\tvar invalids uint32\n\tfor i, field := range fields {\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString(\"__InputValue\")\n\t\tcase \"name\":\n\t\t\tout.Values[i] = ec.___InputValue_name(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tcase \"description\":\n\t\t\tout.Values[i] = ec.___InputValue_description(ctx, field, obj)\n\t\tcase \"type\":\n\t\t\tout.Values[i] = ec.___InputValue_type(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tcase \"defaultValue\":\n\t\t\tout.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj)\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\tout.Dispatch()\n\tif invalids > 0 {\n\t\treturn graphql.Null\n\t}\n\treturn out\n}\n\nvar __SchemaImplementors = []string{\"__Schema\"}\n\nfunc (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler {\n\tfields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors)\n\n\tout := graphql.NewFieldSet(fields)\n\tvar invalids uint32\n\tfor i, field := range fields {\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString(\"__Schema\")\n\t\tcase \"types\":\n\t\t\tout.Values[i] = ec.___Schema_types(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tcase \"queryType\":\n\t\t\tout.Values[i] = ec.___Schema_queryType(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tcase \"mutationType\":\n\t\t\tout.Values[i] = ec.___Schema_mutationType(ctx, field, obj)\n\t\tcase \"subscriptionType\":\n\t\t\tout.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj)\n\t\tcase \"directives\":\n\t\t\tout.Values[i] = ec.___Schema_directives(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\tout.Dispatch()\n\tif invalids > 0 {\n\t\treturn graphql.Null\n\t}\n\treturn out\n}\n\nvar __TypeImplementors = []string{\"__Type\"}\n\nfunc (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler {\n\tfields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors)\n\n\tout := graphql.NewFieldSet(fields)\n\tvar invalids uint32\n\tfor i, field := range fields {\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString(\"__Type\")\n\t\tcase \"kind\":\n\t\t\tout.Values[i] = ec.___Type_kind(ctx, field, obj)\n\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\tinvalids++\n\t\t\t}\n\t\tcase \"name\":\n\t\t\tout.Values[i] = ec.___Type_name(ctx, field, obj)\n\t\tcase \"description\":\n\t\t\tout.Values[i] = ec.___Type_description(ctx, field, obj)\n\t\tcase \"fields\":\n\t\t\tout.Values[i] = ec.___Type_fields(ctx, field, obj)\n\t\tcase \"interfaces\":\n\t\t\tout.Values[i] = ec.___Type_interfaces(ctx, field, obj)\n\t\tcase \"possibleTypes\":\n\t\t\tout.Values[i] = ec.___Type_possibleTypes(ctx, field, obj)\n\t\tcase \"enumValues\":\n\t\t\tout.Values[i] = ec.___Type_enumValues(ctx, field, obj)\n\t\tcase \"inputFields\":\n\t\t\tout.Values[i] = ec.___Type_inputFields(ctx, field, obj)\n\t\tcase \"ofType\":\n\t\t\tout.Values[i] = ec.___Type_ofType(ctx, field, obj)\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\tout.Dispatch()\n\tif invalids > 0 {\n\t\treturn graphql.Null\n\t}\n\treturn out\n}\n\n// endregion **************************** object.gotpl ****************************\n\n// region    ***************************** type.gotpl *****************************\n\nfunc (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v interface{}) (bool, error) {\n\tres, err := graphql.UnmarshalBoolean(v)\n\treturn res, graphql.WrapErrorWithInputPath(ctx, err)\n}\n\nfunc (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler {\n\tres := graphql.MarshalBoolean(v)\n\tif res == graphql.Null {\n\t\tif !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t}\n\treturn res\n}\n\nfunc (ec *executionContext) unmarshalNID2int(ctx context.Context, v interface{}) (int, error) {\n\tres, err := graphql.UnmarshalIntID(v)\n\treturn res, graphql.WrapErrorWithInputPath(ctx, err)\n}\n\nfunc (ec *executionContext) marshalNID2int(ctx context.Context, sel ast.SelectionSet, v int) graphql.Marshaler {\n\tres := graphql.MarshalIntID(v)\n\tif res == graphql.Null {\n\t\tif !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t}\n\treturn res\n}\n\nfunc (ec *executionContext) unmarshalNID2string(ctx context.Context, v interface{}) (string, error) {\n\tres, err := graphql.UnmarshalID(v)\n\treturn res, graphql.WrapErrorWithInputPath(ctx, err)\n}\n\nfunc (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler {\n\tres := graphql.MarshalID(v)\n\tif res == graphql.Null {\n\t\tif !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t}\n\treturn res\n}\n\nfunc (ec *executionContext) marshalNProduct2ᚕᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProductᚄ(ctx context.Context, sel ast.SelectionSet, v []*domain.Product) graphql.Marshaler {\n\tret := make(graphql.Array, len(v))\n\tvar wg sync.WaitGroup\n\tisLen1 := len(v) == 1\n\tif !isLen1 {\n\t\twg.Add(len(v))\n\t}\n\tfor i := range v {\n\t\ti := i\n\t\tfc := &graphql.FieldContext{\n\t\t\tIndex:  &i,\n\t\t\tResult: &v[i],\n\t\t}\n\t\tctx := graphql.WithFieldContext(ctx, fc)\n\t\tf := func(i int) {\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\t\t\tret = nil\n\t\t\t\t}\n\t\t\t}()\n\t\t\tif !isLen1 {\n\t\t\t\tdefer wg.Done()\n\t\t\t}\n\t\t\tret[i] = ec.marshalNProduct2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProduct(ctx, sel, v[i])\n\t\t}\n\t\tif isLen1 {\n\t\t\tf(i)\n\t\t} else {\n\t\t\tgo f(i)\n\t\t}\n\n\t}\n\twg.Wait()\n\treturn ret\n}\n\nfunc (ec *executionContext) marshalNProduct2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProduct(ctx context.Context, sel ast.SelectionSet, v *domain.Product) graphql.Marshaler {\n\tif v == nil {\n\t\tif !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\treturn ec._Product(ctx, sel, v)\n}\n\nfunc (ec *executionContext) marshalNProductItem2ᚕᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProductItemᚄ(ctx context.Context, sel ast.SelectionSet, v []*domain.ProductItem) graphql.Marshaler {\n\tret := make(graphql.Array, len(v))\n\tvar wg sync.WaitGroup\n\tisLen1 := len(v) == 1\n\tif !isLen1 {\n\t\twg.Add(len(v))\n\t}\n\tfor i := range v {\n\t\ti := i\n\t\tfc := &graphql.FieldContext{\n\t\t\tIndex:  &i,\n\t\t\tResult: &v[i],\n\t\t}\n\t\tctx := graphql.WithFieldContext(ctx, fc)\n\t\tf := func(i int) {\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\t\t\tret = nil\n\t\t\t\t}\n\t\t\t}()\n\t\t\tif !isLen1 {\n\t\t\t\tdefer wg.Done()\n\t\t\t}\n\t\t\tret[i] = ec.marshalNProductItem2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProductItem(ctx, sel, v[i])\n\t\t}\n\t\tif isLen1 {\n\t\t\tf(i)\n\t\t} else {\n\t\t\tgo f(i)\n\t\t}\n\n\t}\n\twg.Wait()\n\treturn ret\n}\n\nfunc (ec *executionContext) marshalNProductItem2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProductItem(ctx context.Context, sel ast.SelectionSet, v *domain.ProductItem) graphql.Marshaler {\n\tif v == nil {\n\t\tif !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\treturn ec._ProductItem(ctx, sel, v)\n}\n\nfunc (ec *executionContext) marshalNProductsListOut2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐProductsListOut(ctx context.Context, sel ast.SelectionSet, v ProductsListOut) graphql.Marshaler {\n\treturn ec._ProductsListOut(ctx, sel, &v)\n}\n\nfunc (ec *executionContext) marshalNProductsListOut2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐProductsListOut(ctx context.Context, sel ast.SelectionSet, v *ProductsListOut) graphql.Marshaler {\n\tif v == nil {\n\t\tif !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\treturn ec._ProductsListOut(ctx, sel, v)\n}\n\nfunc (ec *executionContext) unmarshalNString2string(ctx context.Context, v interface{}) (string, error) {\n\tres, err := graphql.UnmarshalString(v)\n\treturn res, graphql.WrapErrorWithInputPath(ctx, err)\n}\n\nfunc (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler {\n\tres := graphql.MarshalString(v)\n\tif res == graphql.Null {\n\t\tif !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t}\n\treturn res\n}\n\nfunc (ec *executionContext) marshalNUsersCreateOut2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersCreateOut(ctx context.Context, sel ast.SelectionSet, v UsersCreateOut) graphql.Marshaler {\n\treturn ec._UsersCreateOut(ctx, sel, &v)\n}\n\nfunc (ec *executionContext) marshalNUsersCreateOut2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersCreateOut(ctx context.Context, sel ast.SelectionSet, v *UsersCreateOut) graphql.Marshaler {\n\tif v == nil {\n\t\tif !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\treturn ec._UsersCreateOut(ctx, sel, v)\n}\n\nfunc (ec *executionContext) unmarshalNUsersCreateOutStatus2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersCreateOutStatus(ctx context.Context, v interface{}) (UsersCreateOutStatus, error) {\n\tvar res UsersCreateOutStatus\n\terr := res.UnmarshalGQL(v)\n\treturn res, graphql.WrapErrorWithInputPath(ctx, err)\n}\n\nfunc (ec *executionContext) marshalNUsersCreateOutStatus2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersCreateOutStatus(ctx context.Context, sel ast.SelectionSet, v UsersCreateOutStatus) graphql.Marshaler {\n\treturn v\n}\n\nfunc (ec *executionContext) marshalNUsersOneOut2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersOneOut(ctx context.Context, sel ast.SelectionSet, v UsersOneOut) graphql.Marshaler {\n\treturn ec._UsersOneOut(ctx, sel, &v)\n}\n\nfunc (ec *executionContext) marshalNUsersOneOut2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersOneOut(ctx context.Context, sel ast.SelectionSet, v *UsersOneOut) graphql.Marshaler {\n\tif v == nil {\n\t\tif !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\treturn ec._UsersOneOut(ctx, sel, v)\n}\n\nfunc (ec *executionContext) unmarshalNUsersPermissionEnum2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersPermissionEnum(ctx context.Context, v interface{}) (UsersPermissionEnum, error) {\n\tvar res UsersPermissionEnum\n\terr := res.UnmarshalGQL(v)\n\treturn res, graphql.WrapErrorWithInputPath(ctx, err)\n}\n\nfunc (ec *executionContext) marshalNUsersPermissionEnum2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersPermissionEnum(ctx context.Context, sel ast.SelectionSet, v UsersPermissionEnum) graphql.Marshaler {\n\treturn v\n}\n\nfunc (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler {\n\treturn ec.___Directive(ctx, sel, &v)\n}\n\nfunc (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Directive) graphql.Marshaler {\n\tret := make(graphql.Array, len(v))\n\tvar wg sync.WaitGroup\n\tisLen1 := len(v) == 1\n\tif !isLen1 {\n\t\twg.Add(len(v))\n\t}\n\tfor i := range v {\n\t\ti := i\n\t\tfc := &graphql.FieldContext{\n\t\t\tIndex:  &i,\n\t\t\tResult: &v[i],\n\t\t}\n\t\tctx := graphql.WithFieldContext(ctx, fc)\n\t\tf := func(i int) {\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\t\t\tret = nil\n\t\t\t\t}\n\t\t\t}()\n\t\t\tif !isLen1 {\n\t\t\t\tdefer wg.Done()\n\t\t\t}\n\t\t\tret[i] = ec.marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx, sel, v[i])\n\t\t}\n\t\tif isLen1 {\n\t\t\tf(i)\n\t\t} else {\n\t\t\tgo f(i)\n\t\t}\n\n\t}\n\twg.Wait()\n\treturn ret\n}\n\nfunc (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx context.Context, v interface{}) (string, error) {\n\tres, err := graphql.UnmarshalString(v)\n\treturn res, graphql.WrapErrorWithInputPath(ctx, err)\n}\n\nfunc (ec *executionContext) marshalN__DirectiveLocation2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler {\n\tres := graphql.MarshalString(v)\n\tif res == graphql.Null {\n\t\tif !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t}\n\treturn res\n}\n\nfunc (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) {\n\tvar vSlice []interface{}\n\tif v != nil {\n\t\tif tmp1, ok := v.([]interface{}); ok {\n\t\t\tvSlice = tmp1\n\t\t} else {\n\t\t\tvSlice = []interface{}{v}\n\t\t}\n\t}\n\tvar err error\n\tres := make([]string, len(vSlice))\n\tfor i := range vSlice {\n\t\tctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithIndex(i))\n\t\tres[i], err = ec.unmarshalN__DirectiveLocation2string(ctx, vSlice[i])\n\t\tif err != nil {\n\t\t\treturn nil, graphql.WrapErrorWithInputPath(ctx, err)\n\t\t}\n\t}\n\treturn res, nil\n}\n\nfunc (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler {\n\tret := make(graphql.Array, len(v))\n\tvar wg sync.WaitGroup\n\tisLen1 := len(v) == 1\n\tif !isLen1 {\n\t\twg.Add(len(v))\n\t}\n\tfor i := range v {\n\t\ti := i\n\t\tfc := &graphql.FieldContext{\n\t\t\tIndex:  &i,\n\t\t\tResult: &v[i],\n\t\t}\n\t\tctx := graphql.WithFieldContext(ctx, fc)\n\t\tf := func(i int) {\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\t\t\tret = nil\n\t\t\t\t}\n\t\t\t}()\n\t\t\tif !isLen1 {\n\t\t\t\tdefer wg.Done()\n\t\t\t}\n\t\t\tret[i] = ec.marshalN__DirectiveLocation2string(ctx, sel, v[i])\n\t\t}\n\t\tif isLen1 {\n\t\t\tf(i)\n\t\t} else {\n\t\t\tgo f(i)\n\t\t}\n\n\t}\n\twg.Wait()\n\treturn ret\n}\n\nfunc (ec *executionContext) marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx context.Context, sel ast.SelectionSet, v introspection.EnumValue) graphql.Marshaler {\n\treturn ec.___EnumValue(ctx, sel, &v)\n}\n\nfunc (ec *executionContext) marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx context.Context, sel ast.SelectionSet, v introspection.Field) graphql.Marshaler {\n\treturn ec.___Field(ctx, sel, &v)\n}\n\nfunc (ec *executionContext) marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx context.Context, sel ast.SelectionSet, v introspection.InputValue) graphql.Marshaler {\n\treturn ec.___InputValue(ctx, sel, &v)\n}\n\nfunc (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler {\n\tret := make(graphql.Array, len(v))\n\tvar wg sync.WaitGroup\n\tisLen1 := len(v) == 1\n\tif !isLen1 {\n\t\twg.Add(len(v))\n\t}\n\tfor i := range v {\n\t\ti := i\n\t\tfc := &graphql.FieldContext{\n\t\t\tIndex:  &i,\n\t\t\tResult: &v[i],\n\t\t}\n\t\tctx := graphql.WithFieldContext(ctx, fc)\n\t\tf := func(i int) {\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\t\t\tret = nil\n\t\t\t\t}\n\t\t\t}()\n\t\t\tif !isLen1 {\n\t\t\t\tdefer wg.Done()\n\t\t\t}\n\t\t\tret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i])\n\t\t}\n\t\tif isLen1 {\n\t\t\tf(i)\n\t\t} else {\n\t\t\tgo f(i)\n\t\t}\n\n\t}\n\twg.Wait()\n\treturn ret\n}\n\nfunc (ec *executionContext) marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v introspection.Type) graphql.Marshaler {\n\treturn ec.___Type(ctx, sel, &v)\n}\n\nfunc (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler {\n\tret := make(graphql.Array, len(v))\n\tvar wg sync.WaitGroup\n\tisLen1 := len(v) == 1\n\tif !isLen1 {\n\t\twg.Add(len(v))\n\t}\n\tfor i := range v {\n\t\ti := i\n\t\tfc := &graphql.FieldContext{\n\t\t\tIndex:  &i,\n\t\t\tResult: &v[i],\n\t\t}\n\t\tctx := graphql.WithFieldContext(ctx, fc)\n\t\tf := func(i int) {\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\t\t\tret = nil\n\t\t\t\t}\n\t\t\t}()\n\t\t\tif !isLen1 {\n\t\t\t\tdefer wg.Done()\n\t\t\t}\n\t\t\tret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i])\n\t\t}\n\t\tif isLen1 {\n\t\t\tf(i)\n\t\t} else {\n\t\t\tgo f(i)\n\t\t}\n\n\t}\n\twg.Wait()\n\treturn ret\n}\n\nfunc (ec *executionContext) marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler {\n\tif v == nil {\n\t\tif !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t\treturn graphql.Null\n\t}\n\treturn ec.___Type(ctx, sel, v)\n}\n\nfunc (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Context, v interface{}) (string, error) {\n\tres, err := graphql.UnmarshalString(v)\n\treturn res, graphql.WrapErrorWithInputPath(ctx, err)\n}\n\nfunc (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler {\n\tres := graphql.MarshalString(v)\n\tif res == graphql.Null {\n\t\tif !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {\n\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t}\n\t}\n\treturn res\n}\n\nfunc (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interface{}) (bool, error) {\n\tres, err := graphql.UnmarshalBoolean(v)\n\treturn res, graphql.WrapErrorWithInputPath(ctx, err)\n}\n\nfunc (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler {\n\treturn graphql.MarshalBoolean(v)\n}\n\nfunc (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) {\n\tif v == nil {\n\t\treturn nil, nil\n\t}\n\tres, err := graphql.UnmarshalBoolean(v)\n\treturn &res, graphql.WrapErrorWithInputPath(ctx, err)\n}\n\nfunc (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast.SelectionSet, v *bool) graphql.Marshaler {\n\tif v == nil {\n\t\treturn graphql.Null\n\t}\n\treturn graphql.MarshalBoolean(*v)\n}\n\nfunc (ec *executionContext) marshalOProductsQuery2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐProductsQuery(ctx context.Context, sel ast.SelectionSet, v *ProductsQuery) graphql.Marshaler {\n\tif v == nil {\n\t\treturn graphql.Null\n\t}\n\treturn ec._ProductsQuery(ctx, sel, v)\n}\n\nfunc (ec *executionContext) unmarshalOString2string(ctx context.Context, v interface{}) (string, error) {\n\tres, err := graphql.UnmarshalString(v)\n\treturn res, graphql.WrapErrorWithInputPath(ctx, err)\n}\n\nfunc (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler {\n\treturn graphql.MarshalString(v)\n}\n\nfunc (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v interface{}) (*string, error) {\n\tif v == nil {\n\t\treturn nil, nil\n\t}\n\tres, err := graphql.UnmarshalString(v)\n\treturn &res, graphql.WrapErrorWithInputPath(ctx, err)\n}\n\nfunc (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler {\n\tif v == nil {\n\t\treturn graphql.Null\n\t}\n\treturn graphql.MarshalString(*v)\n}\n\nfunc (ec *executionContext) marshalOUsersMutation2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersMutation(ctx context.Context, sel ast.SelectionSet, v *UsersMutation) graphql.Marshaler {\n\tif v == nil {\n\t\treturn graphql.Null\n\t}\n\treturn ec._UsersMutation(ctx, sel, v)\n}\n\nfunc (ec *executionContext) marshalOUsersQuery2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersQuery(ctx context.Context, sel ast.SelectionSet, v *UsersQuery) graphql.Marshaler {\n\tif v == nil {\n\t\treturn graphql.Null\n\t}\n\treturn ec._UsersQuery(ctx, sel, v)\n}\n\nfunc (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler {\n\tif v == nil {\n\t\treturn graphql.Null\n\t}\n\tret := make(graphql.Array, len(v))\n\tvar wg sync.WaitGroup\n\tisLen1 := len(v) == 1\n\tif !isLen1 {\n\t\twg.Add(len(v))\n\t}\n\tfor i := range v {\n\t\ti := i\n\t\tfc := &graphql.FieldContext{\n\t\t\tIndex:  &i,\n\t\t\tResult: &v[i],\n\t\t}\n\t\tctx := graphql.WithFieldContext(ctx, fc)\n\t\tf := func(i int) {\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\t\t\tret = nil\n\t\t\t\t}\n\t\t\t}()\n\t\t\tif !isLen1 {\n\t\t\t\tdefer wg.Done()\n\t\t\t}\n\t\t\tret[i] = ec.marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx, sel, v[i])\n\t\t}\n\t\tif isLen1 {\n\t\t\tf(i)\n\t\t} else {\n\t\t\tgo f(i)\n\t\t}\n\n\t}\n\twg.Wait()\n\treturn ret\n}\n\nfunc (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Field) graphql.Marshaler {\n\tif v == nil {\n\t\treturn graphql.Null\n\t}\n\tret := make(graphql.Array, len(v))\n\tvar wg sync.WaitGroup\n\tisLen1 := len(v) == 1\n\tif !isLen1 {\n\t\twg.Add(len(v))\n\t}\n\tfor i := range v {\n\t\ti := i\n\t\tfc := &graphql.FieldContext{\n\t\t\tIndex:  &i,\n\t\t\tResult: &v[i],\n\t\t}\n\t\tctx := graphql.WithFieldContext(ctx, fc)\n\t\tf := func(i int) {\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\t\t\tret = nil\n\t\t\t\t}\n\t\t\t}()\n\t\t\tif !isLen1 {\n\t\t\t\tdefer wg.Done()\n\t\t\t}\n\t\t\tret[i] = ec.marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx, sel, v[i])\n\t\t}\n\t\tif isLen1 {\n\t\t\tf(i)\n\t\t} else {\n\t\t\tgo f(i)\n\t\t}\n\n\t}\n\twg.Wait()\n\treturn ret\n}\n\nfunc (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler {\n\tif v == nil {\n\t\treturn graphql.Null\n\t}\n\tret := make(graphql.Array, len(v))\n\tvar wg sync.WaitGroup\n\tisLen1 := len(v) == 1\n\tif !isLen1 {\n\t\twg.Add(len(v))\n\t}\n\tfor i := range v {\n\t\ti := i\n\t\tfc := &graphql.FieldContext{\n\t\t\tIndex:  &i,\n\t\t\tResult: &v[i],\n\t\t}\n\t\tctx := graphql.WithFieldContext(ctx, fc)\n\t\tf := func(i int) {\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\t\t\tret = nil\n\t\t\t\t}\n\t\t\t}()\n\t\t\tif !isLen1 {\n\t\t\t\tdefer wg.Done()\n\t\t\t}\n\t\t\tret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i])\n\t\t}\n\t\tif isLen1 {\n\t\t\tf(i)\n\t\t} else {\n\t\t\tgo f(i)\n\t\t}\n\n\t}\n\twg.Wait()\n\treturn ret\n}\n\nfunc (ec *executionContext) marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx context.Context, sel ast.SelectionSet, v *introspection.Schema) graphql.Marshaler {\n\tif v == nil {\n\t\treturn graphql.Null\n\t}\n\treturn ec.___Schema(ctx, sel, v)\n}\n\nfunc (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler {\n\tif v == nil {\n\t\treturn graphql.Null\n\t}\n\tret := make(graphql.Array, len(v))\n\tvar wg sync.WaitGroup\n\tisLen1 := len(v) == 1\n\tif !isLen1 {\n\t\twg.Add(len(v))\n\t}\n\tfor i := range v {\n\t\ti := i\n\t\tfc := &graphql.FieldContext{\n\t\t\tIndex:  &i,\n\t\t\tResult: &v[i],\n\t\t}\n\t\tctx := graphql.WithFieldContext(ctx, fc)\n\t\tf := func(i int) {\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\t\t\tret = nil\n\t\t\t\t}\n\t\t\t}()\n\t\t\tif !isLen1 {\n\t\t\t\tdefer wg.Done()\n\t\t\t}\n\t\t\tret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i])\n\t\t}\n\t\tif isLen1 {\n\t\t\tf(i)\n\t\t} else {\n\t\t\tgo f(i)\n\t\t}\n\n\t}\n\twg.Wait()\n\treturn ret\n}\n\nfunc (ec *executionContext) marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler {\n\tif v == nil {\n\t\treturn graphql.Null\n\t}\n\treturn ec.___Type(ctx, sel, v)\n}\n\n// endregion ***************************** type.gotpl *****************************\n"
  },
  {
    "path": "generated/graphql/models_gen.go",
    "content": "// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\npackage graphql\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\n\t\"github.com/aristat/golang-example-app/app/db/domain\"\n)\n\ntype ProductsListOut struct {\n\tProducts []*domain.Product `json:\"products\"`\n}\n\ntype ProductsQuery struct {\n\tList *ProductsListOut `json:\"list\"`\n}\n\ntype UsersCreateOut struct {\n\tStatus UsersCreateOutStatus `json:\"status\"`\n\tID     string               `json:\"id\"`\n\tEmail  string               `json:\"email\"`\n}\n\ntype UsersMutation struct {\n\tCreateUser *UsersCreateOut `json:\"createUser\"`\n}\n\ntype UsersOneOut struct {\n\tID    string `json:\"id\"`\n\tEmail string `json:\"email\"`\n}\n\ntype UsersQuery struct {\n\tOne *UsersOneOut `json:\"one\"`\n}\n\ntype UsersCreateOutStatus string\n\nconst (\n\tUsersCreateOutStatusOk                  UsersCreateOutStatus = \"OK\"\n\tUsersCreateOutStatusBadRequest          UsersCreateOutStatus = \"BAD_REQUEST\"\n\tUsersCreateOutStatusServerInternalError UsersCreateOutStatus = \"SERVER_INTERNAL_ERROR\"\n)\n\nvar AllUsersCreateOutStatus = []UsersCreateOutStatus{\n\tUsersCreateOutStatusOk,\n\tUsersCreateOutStatusBadRequest,\n\tUsersCreateOutStatusServerInternalError,\n}\n\nfunc (e UsersCreateOutStatus) IsValid() bool {\n\tswitch e {\n\tcase UsersCreateOutStatusOk, UsersCreateOutStatusBadRequest, UsersCreateOutStatusServerInternalError:\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (e UsersCreateOutStatus) String() string {\n\treturn string(e)\n}\n\nfunc (e *UsersCreateOutStatus) UnmarshalGQL(v interface{}) error {\n\tstr, ok := v.(string)\n\tif !ok {\n\t\treturn fmt.Errorf(\"enums must be strings\")\n\t}\n\n\t*e = UsersCreateOutStatus(str)\n\tif !e.IsValid() {\n\t\treturn fmt.Errorf(\"%s is not a valid UsersCreateOutStatus\", str)\n\t}\n\treturn nil\n}\n\nfunc (e UsersCreateOutStatus) MarshalGQL(w io.Writer) {\n\tfmt.Fprint(w, strconv.Quote(e.String()))\n}\n\ntype UsersPermissionEnum string\n\nconst (\n\tUsersPermissionEnumRead  UsersPermissionEnum = \"READ\"\n\tUsersPermissionEnumWrite UsersPermissionEnum = \"WRITE\"\n)\n\nvar AllUsersPermissionEnum = []UsersPermissionEnum{\n\tUsersPermissionEnumRead,\n\tUsersPermissionEnumWrite,\n}\n\nfunc (e UsersPermissionEnum) IsValid() bool {\n\tswitch e {\n\tcase UsersPermissionEnumRead, UsersPermissionEnumWrite:\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (e UsersPermissionEnum) String() string {\n\treturn string(e)\n}\n\nfunc (e *UsersPermissionEnum) UnmarshalGQL(v interface{}) error {\n\tstr, ok := v.(string)\n\tif !ok {\n\t\treturn fmt.Errorf(\"enums must be strings\")\n\t}\n\n\t*e = UsersPermissionEnum(str)\n\tif !e.IsValid() {\n\t\treturn fmt.Errorf(\"%s is not a valid UsersPermissionEnum\", str)\n\t}\n\treturn nil\n}\n\nfunc (e UsersPermissionEnum) MarshalGQL(w io.Writer) {\n\tfmt.Fprint(w, strconv.Quote(e.String()))\n}\n"
  },
  {
    "path": "generated/resources/proto/health_checks/health_checks.pb.go",
    "content": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.27.1\n// \tprotoc        v3.17.3\n// source: resources/proto/health_checks/health_checks.proto\n\npackage health_checks\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\temptypb \"google.golang.org/protobuf/types/known/emptypb\"\n\treflect \"reflect\"\n\tsync \"sync\"\n)\n\nconst (\n\t// Verify that this generated code is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\n\t// Verify that runtime/protoimpl is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\n)\n\ntype IsAliveOut_Status int32\n\nconst (\n\tIsAliveOut_OK     IsAliveOut_Status = 0\n\tIsAliveOut_NOT_OK IsAliveOut_Status = 2\n)\n\n// Enum value maps for IsAliveOut_Status.\nvar (\n\tIsAliveOut_Status_name = map[int32]string{\n\t\t0: \"OK\",\n\t\t2: \"NOT_OK\",\n\t}\n\tIsAliveOut_Status_value = map[string]int32{\n\t\t\"OK\":     0,\n\t\t\"NOT_OK\": 2,\n\t}\n)\n\nfunc (x IsAliveOut_Status) Enum() *IsAliveOut_Status {\n\tp := new(IsAliveOut_Status)\n\t*p = x\n\treturn p\n}\n\nfunc (x IsAliveOut_Status) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (IsAliveOut_Status) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_resources_proto_health_checks_health_checks_proto_enumTypes[0].Descriptor()\n}\n\nfunc (IsAliveOut_Status) Type() protoreflect.EnumType {\n\treturn &file_resources_proto_health_checks_health_checks_proto_enumTypes[0]\n}\n\nfunc (x IsAliveOut_Status) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use IsAliveOut_Status.Descriptor instead.\nfunc (IsAliveOut_Status) EnumDescriptor() ([]byte, []int) {\n\treturn file_resources_proto_health_checks_health_checks_proto_rawDescGZIP(), []int{0, 0}\n}\n\ntype IsAliveOut struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tStatus IsAliveOut_Status `protobuf:\"varint,1,opt,name=status,proto3,enum=health_checks.IsAliveOut_Status\" json:\"status,omitempty\"`\n}\n\nfunc (x *IsAliveOut) Reset() {\n\t*x = IsAliveOut{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_resources_proto_health_checks_health_checks_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *IsAliveOut) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*IsAliveOut) ProtoMessage() {}\n\nfunc (x *IsAliveOut) ProtoReflect() protoreflect.Message {\n\tmi := &file_resources_proto_health_checks_health_checks_proto_msgTypes[0]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use IsAliveOut.ProtoReflect.Descriptor instead.\nfunc (*IsAliveOut) Descriptor() ([]byte, []int) {\n\treturn file_resources_proto_health_checks_health_checks_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *IsAliveOut) GetStatus() IsAliveOut_Status {\n\tif x != nil {\n\t\treturn x.Status\n\t}\n\treturn IsAliveOut_OK\n}\n\nvar File_resources_proto_health_checks_health_checks_proto protoreflect.FileDescriptor\n\nvar file_resources_proto_health_checks_health_checks_proto_rawDesc = []byte{\n\t0x0a, 0x31, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74,\n\t0x6f, 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x2f,\n\t0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x2e, 0x70, 0x72,\n\t0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x65, 0x63,\n\t0x6b, 0x73, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,\n\t0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,\n\t0x64, 0x0a, 0x0a, 0x49, 0x73, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x4f, 0x75, 0x74, 0x12, 0x38, 0x0a,\n\t0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e,\n\t0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x2e, 0x49, 0x73,\n\t0x41, 0x6c, 0x69, 0x76, 0x65, 0x4f, 0x75, 0x74, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,\n\t0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x1c, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75,\n\t0x73, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x54,\n\t0x5f, 0x4f, 0x4b, 0x10, 0x02, 0x32, 0x4e, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43,\n\t0x68, 0x65, 0x63, 0x6b, 0x73, 0x12, 0x3e, 0x0a, 0x07, 0x49, 0x73, 0x41, 0x6c, 0x69, 0x76, 0x65,\n\t0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,\n\t0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x68, 0x65, 0x61, 0x6c, 0x74,\n\t0x68, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x2e, 0x49, 0x73, 0x41, 0x6c, 0x69, 0x76, 0x65,\n\t0x4f, 0x75, 0x74, 0x22, 0x00, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,\n\t0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x69, 0x73, 0x74, 0x61, 0x74, 0x2f, 0x67, 0x6f, 0x6c, 0x61,\n\t0x6e, 0x67, 0x2d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2d, 0x61, 0x70, 0x70, 0x2f, 0x68,\n\t0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x62, 0x06, 0x70, 0x72,\n\t0x6f, 0x74, 0x6f, 0x33,\n}\n\nvar (\n\tfile_resources_proto_health_checks_health_checks_proto_rawDescOnce sync.Once\n\tfile_resources_proto_health_checks_health_checks_proto_rawDescData = file_resources_proto_health_checks_health_checks_proto_rawDesc\n)\n\nfunc file_resources_proto_health_checks_health_checks_proto_rawDescGZIP() []byte {\n\tfile_resources_proto_health_checks_health_checks_proto_rawDescOnce.Do(func() {\n\t\tfile_resources_proto_health_checks_health_checks_proto_rawDescData = protoimpl.X.CompressGZIP(file_resources_proto_health_checks_health_checks_proto_rawDescData)\n\t})\n\treturn file_resources_proto_health_checks_health_checks_proto_rawDescData\n}\n\nvar file_resources_proto_health_checks_health_checks_proto_enumTypes = make([]protoimpl.EnumInfo, 1)\nvar file_resources_proto_health_checks_health_checks_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_resources_proto_health_checks_health_checks_proto_goTypes = []interface{}{\n\t(IsAliveOut_Status)(0), // 0: health_checks.IsAliveOut.Status\n\t(*IsAliveOut)(nil),     // 1: health_checks.IsAliveOut\n\t(*emptypb.Empty)(nil),  // 2: google.protobuf.Empty\n}\nvar file_resources_proto_health_checks_health_checks_proto_depIdxs = []int32{\n\t0, // 0: health_checks.IsAliveOut.status:type_name -> health_checks.IsAliveOut.Status\n\t2, // 1: health_checks.HealthChecks.IsAlive:input_type -> google.protobuf.Empty\n\t1, // 2: health_checks.HealthChecks.IsAlive:output_type -> health_checks.IsAliveOut\n\t2, // [2:3] is the sub-list for method output_type\n\t1, // [1:2] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_resources_proto_health_checks_health_checks_proto_init() }\nfunc file_resources_proto_health_checks_health_checks_proto_init() {\n\tif File_resources_proto_health_checks_health_checks_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_resources_proto_health_checks_health_checks_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*IsAliveOut); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\ttype x struct{}\n\tout := protoimpl.TypeBuilder{\n\t\tFile: protoimpl.DescBuilder{\n\t\t\tGoPackagePath: reflect.TypeOf(x{}).PkgPath(),\n\t\t\tRawDescriptor: file_resources_proto_health_checks_health_checks_proto_rawDesc,\n\t\t\tNumEnums:      1,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   1,\n\t\t},\n\t\tGoTypes:           file_resources_proto_health_checks_health_checks_proto_goTypes,\n\t\tDependencyIndexes: file_resources_proto_health_checks_health_checks_proto_depIdxs,\n\t\tEnumInfos:         file_resources_proto_health_checks_health_checks_proto_enumTypes,\n\t\tMessageInfos:      file_resources_proto_health_checks_health_checks_proto_msgTypes,\n\t}.Build()\n\tFile_resources_proto_health_checks_health_checks_proto = out.File\n\tfile_resources_proto_health_checks_health_checks_proto_rawDesc = nil\n\tfile_resources_proto_health_checks_health_checks_proto_goTypes = nil\n\tfile_resources_proto_health_checks_health_checks_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "generated/resources/proto/health_checks/health_checks_grpc.pb.go",
    "content": "// Code generated by protoc-gen-go-grpc. DO NOT EDIT.\n\npackage health_checks\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google.golang.org/grpc\"\n\tcodes \"google.golang.org/grpc/codes\"\n\tstatus \"google.golang.org/grpc/status\"\n\temptypb \"google.golang.org/protobuf/types/known/emptypb\"\n)\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the grpc package it is being compiled against.\n// Requires gRPC-Go v1.32.0 or later.\nconst _ = grpc.SupportPackageIsVersion7\n\n// HealthChecksClient is the client API for HealthChecks service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.\ntype HealthChecksClient interface {\n\tIsAlive(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*IsAliveOut, error)\n}\n\ntype healthChecksClient struct {\n\tcc grpc.ClientConnInterface\n}\n\nfunc NewHealthChecksClient(cc grpc.ClientConnInterface) HealthChecksClient {\n\treturn &healthChecksClient{cc}\n}\n\nfunc (c *healthChecksClient) IsAlive(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*IsAliveOut, error) {\n\tout := new(IsAliveOut)\n\terr := c.cc.Invoke(ctx, \"/health_checks.HealthChecks/IsAlive\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// HealthChecksServer is the server API for HealthChecks service.\n// All implementations must embed UnimplementedHealthChecksServer\n// for forward compatibility\ntype HealthChecksServer interface {\n\tIsAlive(context.Context, *emptypb.Empty) (*IsAliveOut, error)\n\tmustEmbedUnimplementedHealthChecksServer()\n}\n\n// UnimplementedHealthChecksServer must be embedded to have forward compatible implementations.\ntype UnimplementedHealthChecksServer struct {\n}\n\nfunc (UnimplementedHealthChecksServer) IsAlive(context.Context, *emptypb.Empty) (*IsAliveOut, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method IsAlive not implemented\")\n}\nfunc (UnimplementedHealthChecksServer) mustEmbedUnimplementedHealthChecksServer() {}\n\n// UnsafeHealthChecksServer may be embedded to opt out of forward compatibility for this service.\n// Use of this interface is not recommended, as added methods to HealthChecksServer will\n// result in compilation errors.\ntype UnsafeHealthChecksServer interface {\n\tmustEmbedUnimplementedHealthChecksServer()\n}\n\nfunc RegisterHealthChecksServer(s grpc.ServiceRegistrar, srv HealthChecksServer) {\n\ts.RegisterService(&HealthChecks_ServiceDesc, srv)\n}\n\nfunc _HealthChecks_IsAlive_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(emptypb.Empty)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(HealthChecksServer).IsAlive(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/health_checks.HealthChecks/IsAlive\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(HealthChecksServer).IsAlive(ctx, req.(*emptypb.Empty))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\n// HealthChecks_ServiceDesc is the grpc.ServiceDesc for HealthChecks service.\n// It's only intended for direct use with grpc.RegisterService,\n// and not to be introspected or modified (even as a copy)\nvar HealthChecks_ServiceDesc = grpc.ServiceDesc{\n\tServiceName: \"health_checks.HealthChecks\",\n\tHandlerType: (*HealthChecksServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"IsAlive\",\n\t\t\tHandler:    _HealthChecks_IsAlive_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"resources/proto/health_checks/health_checks.proto\",\n}\n"
  },
  {
    "path": "generated/resources/proto/products/products.pb.go",
    "content": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.27.1\n// \tprotoc        v3.17.3\n// source: resources/proto/products/products.proto\n\npackage products\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n)\n\nconst (\n\t// Verify that this generated code is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\n\t// Verify that runtime/protoimpl is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\n)\n\ntype ListProductOut_Status int32\n\nconst (\n\tListProductOut_OK        ListProductOut_Status = 0\n\tListProductOut_NOT_FOUND ListProductOut_Status = 2\n)\n\n// Enum value maps for ListProductOut_Status.\nvar (\n\tListProductOut_Status_name = map[int32]string{\n\t\t0: \"OK\",\n\t\t2: \"NOT_FOUND\",\n\t}\n\tListProductOut_Status_value = map[string]int32{\n\t\t\"OK\":        0,\n\t\t\"NOT_FOUND\": 2,\n\t}\n)\n\nfunc (x ListProductOut_Status) Enum() *ListProductOut_Status {\n\tp := new(ListProductOut_Status)\n\t*p = x\n\treturn p\n}\n\nfunc (x ListProductOut_Status) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (ListProductOut_Status) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_resources_proto_products_products_proto_enumTypes[0].Descriptor()\n}\n\nfunc (ListProductOut_Status) Type() protoreflect.EnumType {\n\treturn &file_resources_proto_products_products_proto_enumTypes[0]\n}\n\nfunc (x ListProductOut_Status) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use ListProductOut_Status.Descriptor instead.\nfunc (ListProductOut_Status) EnumDescriptor() ([]byte, []int) {\n\treturn file_resources_proto_products_products_proto_rawDescGZIP(), []int{2, 0}\n}\n\ntype Product struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tId   int64  `protobuf:\"varint,1,opt,name=id,proto3\" json:\"id,omitempty\"`\n\tName string `protobuf:\"bytes,2,opt,name=name,proto3\" json:\"name,omitempty\"`\n}\n\nfunc (x *Product) Reset() {\n\t*x = Product{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_resources_proto_products_products_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Product) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Product) ProtoMessage() {}\n\nfunc (x *Product) ProtoReflect() protoreflect.Message {\n\tmi := &file_resources_proto_products_products_proto_msgTypes[0]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Product.ProtoReflect.Descriptor instead.\nfunc (*Product) Descriptor() ([]byte, []int) {\n\treturn file_resources_proto_products_products_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Product) GetId() int64 {\n\tif x != nil {\n\t\treturn x.Id\n\t}\n\treturn 0\n}\n\nfunc (x *Product) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\ntype ListProductIn struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tId int64 `protobuf:\"varint,1,opt,name=id,proto3\" json:\"id,omitempty\"`\n}\n\nfunc (x *ListProductIn) Reset() {\n\t*x = ListProductIn{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_resources_proto_products_products_proto_msgTypes[1]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ListProductIn) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ListProductIn) ProtoMessage() {}\n\nfunc (x *ListProductIn) ProtoReflect() protoreflect.Message {\n\tmi := &file_resources_proto_products_products_proto_msgTypes[1]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use ListProductIn.ProtoReflect.Descriptor instead.\nfunc (*ListProductIn) Descriptor() ([]byte, []int) {\n\treturn file_resources_proto_products_products_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *ListProductIn) GetId() int64 {\n\tif x != nil {\n\t\treturn x.Id\n\t}\n\treturn 0\n}\n\ntype ListProductOut struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tStatus   ListProductOut_Status `protobuf:\"varint,1,opt,name=status,proto3,enum=products.ListProductOut_Status\" json:\"status,omitempty\"`\n\tProducts []*Product            `protobuf:\"bytes,2,rep,name=products,proto3\" json:\"products,omitempty\"`\n}\n\nfunc (x *ListProductOut) Reset() {\n\t*x = ListProductOut{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_resources_proto_products_products_proto_msgTypes[2]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ListProductOut) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ListProductOut) ProtoMessage() {}\n\nfunc (x *ListProductOut) ProtoReflect() protoreflect.Message {\n\tmi := &file_resources_proto_products_products_proto_msgTypes[2]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use ListProductOut.ProtoReflect.Descriptor instead.\nfunc (*ListProductOut) Descriptor() ([]byte, []int) {\n\treturn file_resources_proto_products_products_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *ListProductOut) GetStatus() ListProductOut_Status {\n\tif x != nil {\n\t\treturn x.Status\n\t}\n\treturn ListProductOut_OK\n}\n\nfunc (x *ListProductOut) GetProducts() []*Product {\n\tif x != nil {\n\t\treturn x.Products\n\t}\n\treturn nil\n}\n\nvar File_resources_proto_products_products_proto protoreflect.FileDescriptor\n\nvar file_resources_proto_products_products_proto_rawDesc = []byte{\n\t0x0a, 0x27, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74,\n\t0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75,\n\t0x63, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75,\n\t0x63, 0x74, 0x73, 0x22, 0x2d, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x0e,\n\t0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12,\n\t0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,\n\t0x6d, 0x65, 0x22, 0x1f, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63,\n\t0x74, 0x49, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52,\n\t0x02, 0x69, 0x64, 0x22, 0x99, 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x64,\n\t0x75, 0x63, 0x74, 0x4f, 0x75, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,\n\t0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74,\n\t0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4f, 0x75, 0x74,\n\t0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,\n\t0x2d, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,\n\t0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x2e, 0x50, 0x72, 0x6f,\n\t0x64, 0x75, 0x63, 0x74, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x22, 0x1f,\n\t0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x00,\n\t0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x02, 0x32,\n\t0x4e, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x12, 0x42, 0x0a, 0x0b, 0x4c,\n\t0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x17, 0x2e, 0x70, 0x72, 0x6f,\n\t0x64, 0x75, 0x63, 0x74, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63,\n\t0x74, 0x49, 0x6e, 0x1a, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x2e, 0x4c,\n\t0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4f, 0x75, 0x74, 0x22, 0x00, 0x42,\n\t0x30, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72,\n\t0x69, 0x73, 0x74, 0x61, 0x74, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2d, 0x65, 0x78, 0x61,\n\t0x6d, 0x70, 0x6c, 0x65, 0x2d, 0x61, 0x70, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74,\n\t0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,\n}\n\nvar (\n\tfile_resources_proto_products_products_proto_rawDescOnce sync.Once\n\tfile_resources_proto_products_products_proto_rawDescData = file_resources_proto_products_products_proto_rawDesc\n)\n\nfunc file_resources_proto_products_products_proto_rawDescGZIP() []byte {\n\tfile_resources_proto_products_products_proto_rawDescOnce.Do(func() {\n\t\tfile_resources_proto_products_products_proto_rawDescData = protoimpl.X.CompressGZIP(file_resources_proto_products_products_proto_rawDescData)\n\t})\n\treturn file_resources_proto_products_products_proto_rawDescData\n}\n\nvar file_resources_proto_products_products_proto_enumTypes = make([]protoimpl.EnumInfo, 1)\nvar file_resources_proto_products_products_proto_msgTypes = make([]protoimpl.MessageInfo, 3)\nvar file_resources_proto_products_products_proto_goTypes = []interface{}{\n\t(ListProductOut_Status)(0), // 0: products.ListProductOut.Status\n\t(*Product)(nil),            // 1: products.Product\n\t(*ListProductIn)(nil),      // 2: products.ListProductIn\n\t(*ListProductOut)(nil),     // 3: products.ListProductOut\n}\nvar file_resources_proto_products_products_proto_depIdxs = []int32{\n\t0, // 0: products.ListProductOut.status:type_name -> products.ListProductOut.Status\n\t1, // 1: products.ListProductOut.products:type_name -> products.Product\n\t2, // 2: products.Products.ListProduct:input_type -> products.ListProductIn\n\t3, // 3: products.Products.ListProduct:output_type -> products.ListProductOut\n\t3, // [3:4] is the sub-list for method output_type\n\t2, // [2:3] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_resources_proto_products_products_proto_init() }\nfunc file_resources_proto_products_products_proto_init() {\n\tif File_resources_proto_products_products_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_resources_proto_products_products_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Product); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_resources_proto_products_products_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ListProductIn); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_resources_proto_products_products_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ListProductOut); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\ttype x struct{}\n\tout := protoimpl.TypeBuilder{\n\t\tFile: protoimpl.DescBuilder{\n\t\t\tGoPackagePath: reflect.TypeOf(x{}).PkgPath(),\n\t\t\tRawDescriptor: file_resources_proto_products_products_proto_rawDesc,\n\t\t\tNumEnums:      1,\n\t\t\tNumMessages:   3,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   1,\n\t\t},\n\t\tGoTypes:           file_resources_proto_products_products_proto_goTypes,\n\t\tDependencyIndexes: file_resources_proto_products_products_proto_depIdxs,\n\t\tEnumInfos:         file_resources_proto_products_products_proto_enumTypes,\n\t\tMessageInfos:      file_resources_proto_products_products_proto_msgTypes,\n\t}.Build()\n\tFile_resources_proto_products_products_proto = out.File\n\tfile_resources_proto_products_products_proto_rawDesc = nil\n\tfile_resources_proto_products_products_proto_goTypes = nil\n\tfile_resources_proto_products_products_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "generated/resources/proto/products/products_grpc.pb.go",
    "content": "// Code generated by protoc-gen-go-grpc. DO NOT EDIT.\n\npackage products\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google.golang.org/grpc\"\n\tcodes \"google.golang.org/grpc/codes\"\n\tstatus \"google.golang.org/grpc/status\"\n)\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the grpc package it is being compiled against.\n// Requires gRPC-Go v1.32.0 or later.\nconst _ = grpc.SupportPackageIsVersion7\n\n// ProductsClient is the client API for Products service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.\ntype ProductsClient interface {\n\tListProduct(ctx context.Context, in *ListProductIn, opts ...grpc.CallOption) (*ListProductOut, error)\n}\n\ntype productsClient struct {\n\tcc grpc.ClientConnInterface\n}\n\nfunc NewProductsClient(cc grpc.ClientConnInterface) ProductsClient {\n\treturn &productsClient{cc}\n}\n\nfunc (c *productsClient) ListProduct(ctx context.Context, in *ListProductIn, opts ...grpc.CallOption) (*ListProductOut, error) {\n\tout := new(ListProductOut)\n\terr := c.cc.Invoke(ctx, \"/products.Products/ListProduct\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// ProductsServer is the server API for Products service.\n// All implementations must embed UnimplementedProductsServer\n// for forward compatibility\ntype ProductsServer interface {\n\tListProduct(context.Context, *ListProductIn) (*ListProductOut, error)\n\tmustEmbedUnimplementedProductsServer()\n}\n\n// UnimplementedProductsServer must be embedded to have forward compatible implementations.\ntype UnimplementedProductsServer struct {\n}\n\nfunc (UnimplementedProductsServer) ListProduct(context.Context, *ListProductIn) (*ListProductOut, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method ListProduct not implemented\")\n}\nfunc (UnimplementedProductsServer) mustEmbedUnimplementedProductsServer() {}\n\n// UnsafeProductsServer may be embedded to opt out of forward compatibility for this service.\n// Use of this interface is not recommended, as added methods to ProductsServer will\n// result in compilation errors.\ntype UnsafeProductsServer interface {\n\tmustEmbedUnimplementedProductsServer()\n}\n\nfunc RegisterProductsServer(s grpc.ServiceRegistrar, srv ProductsServer) {\n\ts.RegisterService(&Products_ServiceDesc, srv)\n}\n\nfunc _Products_ListProduct_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(ListProductIn)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ProductsServer).ListProduct(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/products.Products/ListProduct\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ProductsServer).ListProduct(ctx, req.(*ListProductIn))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\n// Products_ServiceDesc is the grpc.ServiceDesc for Products service.\n// It's only intended for direct use with grpc.RegisterService,\n// and not to be introspected or modified (even as a copy)\nvar Products_ServiceDesc = grpc.ServiceDesc{\n\tServiceName: \"products.Products\",\n\tHandlerType: (*ProductsServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"ListProduct\",\n\t\t\tHandler:    _Products_ListProduct_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"resources/proto/products/products.proto\",\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/aristat/golang-example-app\n\nrequire (\n\tgithub.com/99designs/gqlgen v0.12.2\n\tgithub.com/agnivade/levenshtein v1.1.0 // indirect\n\tgithub.com/casbin/casbin v1.9.1\n\tgithub.com/go-chi/chi/v5 v5.0.7\n\tgithub.com/go-session/session v3.1.2+incompatible\n\tgithub.com/golang-jwt/jwt v3.2.2+incompatible\n\tgithub.com/google/wire v0.5.0\n\tgithub.com/hashicorp/golang-lru v0.5.4 // indirect\n\tgithub.com/jinzhu/gorm v1.9.10\n\tgithub.com/kr/text v0.2.0 // indirect\n\tgithub.com/lib/pq v1.10.4\n\tgithub.com/mitchellh/mapstructure v1.4.1\n\tgithub.com/nats-io/nats-streaming-server v0.24.5 // indirect\n\tgithub.com/nats-io/nats.go v1.14.0\n\tgithub.com/nats-io/stan.go v0.10.2\n\tgithub.com/pkg/errors v0.9.1\n\tgithub.com/processout/grpc-go-pool v1.2.1\n\tgithub.com/riandyrn/otelchi v0.4.0\n\tgithub.com/rubenv/sql-migrate v1.1.1\n\tgithub.com/selvatico/go-mocket v1.0.7\n\tgithub.com/spf13/cast v1.3.1\n\tgithub.com/spf13/cobra v1.2.1\n\tgithub.com/spf13/viper v1.8.1\n\tgithub.com/stretchr/testify v1.7.1\n\tgithub.com/vektah/gqlparser/v2 v2.0.1\n\tgo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.32.0\n\tgo.opentelemetry.io/otel v1.7.0\n\tgo.opentelemetry.io/otel/exporters/jaeger v1.7.0\n\tgo.opentelemetry.io/otel/sdk v1.7.0\n\tgo.uber.org/atomic v1.9.0 // indirect\n\tgo.uber.org/automaxprocs v1.2.0\n\tgo.uber.org/zap v1.17.0\n\tgolang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd\n\tgolang.org/x/sys v0.0.0-20220429233432-b5fbb4746d32 // indirect\n\tgolang.org/x/text v0.3.7 // indirect\n\tgolang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect\n\tgoogle.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8 // indirect\n\tgoogle.golang.org/grpc v1.46.0\n\tgoogle.golang.org/protobuf v1.27.1\n)\n\ngo 1.13\n"
  },
  {
    "path": "go.sum",
    "content": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=\ncloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=\ncloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=\ncloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=\ncloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=\ncloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=\ncloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=\ncloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=\ncloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=\ncloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=\ncloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=\ncloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=\ncloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=\ncloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=\ncloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=\ncloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=\ncloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=\ncloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=\ncloud.google.com/go v0.81.0 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8=\ncloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=\ncloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=\ncloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=\ncloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=\ncloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=\ncloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=\ncloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=\ncloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=\ncloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=\ncloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=\ncloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=\ncloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=\ncloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=\ncloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=\ncloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=\ncloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=\ncloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=\ncloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=\ncloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=\ndmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=\ngithub.com/99designs/gqlgen v0.12.2 h1:aOdpsiCycFtCnAv8CAI1exnKrIDHMqtMzQoXeTziY4o=\ngithub.com/99designs/gqlgen v0.12.2/go.mod h1:7zdGo6ry9u1YBp/qlb2uxSU5Mt2jQKLcBETQiKk+Bxo=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=\ngithub.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=\ngithub.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=\ngithub.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=\ngithub.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=\ngithub.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=\ngithub.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=\ngithub.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=\ngithub.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=\ngithub.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=\ngithub.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=\ngithub.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6ie5efyrwRJXs=\ngithub.com/agnivade/levenshtein v1.1.0 h1:n6qGwyHG61v3ABce1rPVZklEYRT8NFpCMrpZdBUbYGM=\ngithub.com/agnivade/levenshtein v1.1.0/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=\ngithub.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=\ngithub.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=\ngithub.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=\ngithub.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=\ngithub.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=\ngithub.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=\ngithub.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=\ngithub.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=\ngithub.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM=\ngithub.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg=\ngithub.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\ngithub.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=\ngithub.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=\ngithub.com/casbin/casbin v1.9.1 h1:ucjbS5zTrmSLtH4XogqOG920Poe6QatdXtz1FEbApeM=\ngithub.com/casbin/casbin v1.9.1/go.mod h1:z8uPsfBJGUsnkagrt3G8QvjgTKFMBJ32UP8HpZllfog=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=\ngithub.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=\ngithub.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=\ngithub.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=\ngithub.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=\ngithub.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=\ngithub.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=\ngithub.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=\ngithub.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=\ngithub.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=\ngithub.com/denisenkom/go-mssqldb v0.9.0 h1:RSohk2RsiZqLZ0zCjtfn3S4Gp4exhpBWHyQ7D0yGjAk=\ngithub.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=\ngithub.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=\ngithub.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g=\ngithub.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=\ngithub.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=\ngithub.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=\ngithub.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=\ngithub.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=\ngithub.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=\ngithub.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=\ngithub.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=\ngithub.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=\ngithub.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=\ngithub.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o=\ngithub.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=\ngithub.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=\ngithub.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=\ngithub.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=\ngithub.com/go-chi/chi v3.3.2+incompatible h1:uQNcQN3NsV1j4ANsPh42P4ew4t6rnRbJb8frvpp31qQ=\ngithub.com/go-chi/chi v3.3.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=\ngithub.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8=\ngithub.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=\ngithub.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-gorp/gorp/v3 v3.0.2 h1:ULqJXIekoqMx29FI5ekXXFoH1dT2Vc8UhnRzBg+Emz4=\ngithub.com/go-gorp/gorp/v3 v3.0.2/go.mod h1:BJ3q1ejpV8cVALtcXvXaXyTOlMmJhWDxTmncaR6rwBY=\ngithub.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=\ngithub.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=\ngithub.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=\ngithub.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/go-session/session v3.1.2+incompatible h1:yStchEObKg4nk2F7JGE7KoFIrA/1Y078peagMWcrncg=\ngithub.com/go-session/session v3.1.2+incompatible/go.mod h1:8B3iivBQjrz/JtC68Np2T1yBBLxTan3mn/3OM0CyRt0=\ngithub.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=\ngithub.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=\ngithub.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=\ngithub.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\ngithub.com/gobuffalo/logger v1.0.6 h1:nnZNpxYo0zx+Aj9RfMPBm+x9zAU2OayFh/xrAWi34HU=\ngithub.com/gobuffalo/logger v1.0.6/go.mod h1:J31TBEHR1QLV2683OXTAItYIg8pv2JMHnF/quuAbMjs=\ngithub.com/gobuffalo/packd v1.0.1 h1:U2wXfRr4E9DH8IdsDLlRFwTZTK7hLfq9qT/QHXGVe/0=\ngithub.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY=\ngithub.com/gobuffalo/packr/v2 v2.8.3 h1:xE1yzvnO56cUC0sTpKR3DIbxZgB54AftTFMhB2XEWlY=\ngithub.com/gobuffalo/packr/v2 v2.8.3/go.mod h1:0SahksCVcx4IMnigTjiFuyldmTrdTctXsOdiU5KwbKc=\ngithub.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=\ngithub.com/godror/godror v0.24.2/go.mod h1:wZv/9vPiUib6tkoDl+AZ/QLf5YZgMravZ7jxH2eQWAE=\ngithub.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=\ngithub.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=\ngithub.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=\ngithub.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=\ngithub.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=\ngithub.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=\ngithub.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=\ngithub.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=\ngithub.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=\ngithub.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=\ngithub.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=\ngithub.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=\ngithub.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=\ngithub.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8=\ngithub.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU=\ngithub.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=\ngithub.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=\ngithub.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=\ngithub.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=\ngithub.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=\ngithub.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=\ngithub.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=\ngithub.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=\ngithub.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=\ngithub.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=\ngithub.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=\ngithub.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=\ngithub.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=\ngithub.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=\ngithub.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=\ngithub.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=\ngithub.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=\ngithub.com/hashicorp/go-hclog v1.1.0 h1:QsGcniKx5/LuX2eYoeL+Np3UKYPNaN7YKpTh29h8rbw=\ngithub.com/hashicorp/go-hclog v1.1.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=\ngithub.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=\ngithub.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=\ngithub.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=\ngithub.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=\ngithub.com/hashicorp/go-msgpack v1.1.5 h1:9byZdVjKTe5mce63pRVNP1L7UAmdHOTEMGehn6KvJWs=\ngithub.com/hashicorp/go-msgpack v1.1.5/go.mod h1:gWVc3sv/wbDmR3rQsj1CAktEZzoz1YNK9NfGLXJ69/4=\ngithub.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=\ngithub.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=\ngithub.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=\ngithub.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=\ngithub.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=\ngithub.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE=\ngithub.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=\ngithub.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=\ngithub.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=\ngithub.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=\ngithub.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=\ngithub.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=\ngithub.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=\ngithub.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=\ngithub.com/hashicorp/raft v1.3.7 h1:mnuQAuSMNRjAvFc9IYxnGxZJ9LBBZyheMR8Kv8Ve71M=\ngithub.com/hashicorp/raft v1.3.7/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM=\ngithub.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=\ngithub.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=\ngithub.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=\ngithub.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=\ngithub.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=\ngithub.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=\ngithub.com/jinzhu/gorm v1.9.10 h1:HvrsqdhCW78xpJF67g1hMxS6eCToo9PZH4LDB8WKPac=\ngithub.com/jinzhu/gorm v1.9.10/go.mod h1:Kh6hTsSGffh4ui079FHrR5Gg+5D0hgihqDcsDN2BBJY=\ngithub.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=\ngithub.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=\ngithub.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=\ngithub.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=\ngithub.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=\ngithub.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=\ngithub.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=\ngithub.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=\ngithub.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=\ngithub.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw=\ngithub.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=\ngithub.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/klauspost/compress v1.14.4 h1:eijASRJcobkVtSt81Olfh7JX43osYLwy5krOJo6YEu4=\ngithub.com/klauspost/compress v1.14.4/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/kortschak/utter v1.0.1/go.mod h1:vSmSjbyrlKjjsL71193LmzBOKgwePk9DH6uFaWHIInc=\ngithub.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=\ngithub.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=\ngithub.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=\ngithub.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=\ngithub.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=\ngithub.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=\ngithub.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=\ngithub.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=\ngithub.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=\ngithub.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI=\ngithub.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc=\ngithub.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY=\ngithub.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI=\ngithub.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI=\ngithub.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=\ngithub.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=\ngithub.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=\ngithub.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=\ngithub.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=\ngithub.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=\ngithub.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=\ngithub.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=\ngithub.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=\ngithub.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=\ngithub.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI=\ngithub.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=\ngithub.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=\ngithub.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=\ngithub.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=\ngithub.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=\ngithub.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=\ngithub.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=\ngithub.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=\ngithub.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4=\ngithub.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=\ngithub.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=\ngithub.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=\ngithub.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=\ngithub.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=\ngithub.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=\ngithub.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=\ngithub.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/nats-io/jwt/v2 v2.2.1-0.20220330180145-442af02fd36a h1:lem6QCvxR0Y28gth9P+wV2K/zYUUAkJ+55U8cpS0p5I=\ngithub.com/nats-io/jwt/v2 v2.2.1-0.20220330180145-442af02fd36a/go.mod h1:0tqz9Hlu6bCBFLWAASKhE5vUA4c24L9KPUUgvwumE/k=\ngithub.com/nats-io/nats-server/v2 v2.8.1 h1:WZ9m/d8rklkWo6opo3X927vXnuaE00VEEl5zXcpL6qw=\ngithub.com/nats-io/nats-server/v2 v2.8.1/go.mod h1:vIdpKz3OG+DCg4q/xVPdXHoztEyKDWRtykQ4N7hd7C4=\ngithub.com/nats-io/nats-streaming-server v0.24.5 h1:jB+GvMRqH6tTJIjmWEgcy7kaHtk081bc26u78U+JAqI=\ngithub.com/nats-io/nats-streaming-server v0.24.5/go.mod h1:wY5y2xJQxrYdSmKJplQk1zPjBiu7p2f/+p58/VokW1o=\ngithub.com/nats-io/nats.go v1.13.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w=\ngithub.com/nats-io/nats.go v1.14.0 h1:/QLCss4vQ6wvDpbqXucsVRDi13tFIR6kTdau+nXzKJw=\ngithub.com/nats-io/nats.go v1.14.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w=\ngithub.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8=\ngithub.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4=\ngithub.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=\ngithub.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=\ngithub.com/nats-io/stan.go v0.10.2 h1:gQLd05LhzmhFkHm3/qP/klYHfM/hys45GyHa1Uly/kI=\ngithub.com/nats-io/stan.go v0.10.2/go.mod h1:vo2ax8K2IxaR3JtEMLZRFKIdoK/3o1/PKueapB7ezX0=\ngithub.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=\ngithub.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=\ngithub.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=\ngithub.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=\ngithub.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=\ngithub.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=\ngithub.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=\ngithub.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=\ngithub.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ=\ngithub.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=\ngithub.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=\ngithub.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=\ngithub.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=\ngithub.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1 h1:oL4IBbcqwhhNWh31bjOX8C/OCy0zs9906d/VUru+bqg=\ngithub.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU=\ngithub.com/processout/grpc-go-pool v1.2.1 h1:hbp1BOA02CIxEAoRLHGpUhhPFv77nwfBLBeO3Ya9P7I=\ngithub.com/processout/grpc-go-pool v1.2.1/go.mod h1:F4hiNj96O6VQ87jv4rdz8R9tkHdelQQJ/J2B1a5VSt4=\ngithub.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=\ngithub.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=\ngithub.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=\ngithub.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=\ngithub.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=\ngithub.com/riandyrn/otelchi v0.4.0 h1:btWguNWE2NluzNqRNaqAdJ809GKP1CjZEi8UP4AdYGw=\ngithub.com/riandyrn/otelchi v0.4.0/go.mod h1:gYlFYJYyLUmgxgJFKE/NFno7ljcu2lCd8+aOlD8oLTw=\ngithub.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=\ngithub.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=\ngithub.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=\ngithub.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=\ngithub.com/rubenv/sql-migrate v1.1.1 h1:haR5Hn8hbW9/SpAICrXoZqXnywS7Q5WijwkQENPeNWY=\ngithub.com/rubenv/sql-migrate v1.1.1/go.mod h1:/7TZymwxN8VWumcIxw1jjHEcR1djpdkMHQPT4FWdnbQ=\ngithub.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=\ngithub.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=\ngithub.com/selvatico/go-mocket v1.0.7 h1:jbVa7RkoOCzBanQYiYF+VWgySHZogg25fOIKkM38q5k=\ngithub.com/selvatico/go-mocket v1.0.7/go.mod h1:7bSWzuNieCdUlanCVu3w0ppS0LvDtPAZmKBIlhoTcp8=\ngithub.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=\ngithub.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=\ngithub.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=\ngithub.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=\ngithub.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=\ngithub.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=\ngithub.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=\ngithub.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=\ngithub.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=\ngithub.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=\ngithub.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=\ngithub.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=\ngithub.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=\ngithub.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=\ngithub.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=\ngithub.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=\ngithub.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=\ngithub.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=\ngithub.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw=\ngithub.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=\ngithub.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=\ngithub.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=\ngithub.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=\ngithub.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44=\ngithub.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=\ngithub.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=\ngithub.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=\ngithub.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=\ngithub.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=\ngithub.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U=\ngithub.com/vektah/gqlparser v1.3.1 h1:8b0IcD3qZKWJQHSzynbDlrtP3IxVydZ2DZepCGofqfU=\ngithub.com/vektah/gqlparser v1.3.1/go.mod h1:bkVf0FX+Stjg/MHnm8mEyubuaArhNEqfQhF+OTiAL74=\ngithub.com/vektah/gqlparser/v2 v2.0.1 h1:xgl5abVnsd4hkN9rk65OJID9bfcLSMuTaTcZj777q1o=\ngithub.com/vektah/gqlparser/v2 v2.0.1/go.mod h1:SyUiHgLATUR8BiYURfTirrTcGpcE+4XkV2se04Px1Ms=\ngithub.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngithub.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngithub.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=\ngithub.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=\ngo.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=\ngo.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=\ngo.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=\ngo.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=\ngo.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=\ngo.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=\ngo.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=\ngo.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=\ngo.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=\ngo.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=\ngo.opentelemetry.io/contrib v1.0.0 h1:khwDCxdSspjOLmFnvMuSHd/5rPzbTx0+l6aURwtQdfE=\ngo.opentelemetry.io/contrib v1.0.0/go.mod h1:EH4yDYeNoaTqn/8yCWQmfNB78VHfGX2Jt2bvnvzBlGM=\ngo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.32.0 h1:WenoaOMNP71oq3KkMZ/jnxI9xU/JSCLw8yZILSI2lfU=\ngo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.32.0/go.mod h1:J0dBVrt7dPS/lKJyQoW0xzQiUr4r2Ik1VwPjAUWnofI=\ngo.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs=\ngo.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM=\ngo.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk=\ngo.opentelemetry.io/otel/exporters/jaeger v1.7.0 h1:wXgjiRldljksZkZrldGVe6XrG9u3kYDyQmkZwmm5dI0=\ngo.opentelemetry.io/otel/exporters/jaeger v1.7.0/go.mod h1:PwQAOqBgqbLQRKlj466DuD2qyMjbtcPpfPfj+AqbSBs=\ngo.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.3.0/go.mod h1:PQLM+xJ3EMSZU9rMevmw+4nH1efyp23CW/nD9BlB3sg=\ngo.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs=\ngo.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0=\ngo.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU=\ngo.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk=\ngo.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o=\ngo.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU=\ngo.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=\ngo.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=\ngo.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=\ngo.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=\ngo.uber.org/automaxprocs v1.2.0 h1:+RUihKM+nmYUoB9w0D0Ov5TJ2PpFO2FgenTxMJiZBZA=\ngo.uber.org/automaxprocs v1.2.0/go.mod h1:YfO3fm683kQpzETxlTGZhGIVmXAhaw3gxeBADbpZtnU=\ngo.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=\ngo.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=\ngo.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U=\ngo.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=\ngolang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=\ngolang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38=\ngolang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=\ngolang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=\ngolang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=\ngolang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=\ngolang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=\ngolang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=\ngolang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=\ngolang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=\ngolang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=\ngolang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=\ngolang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=\ngolang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=\ngolang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=\ngolang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 h1:0Ja1LBD+yisY6RWM/BH7TJVXWsSjs2VwBSmvSX4HdBc=\ngolang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220429233432-b5fbb4746d32 h1:Js08h5hqB5xyWR789+QqueR6sDE8mk+YvpETZ+F6X9Y=\ngolang.org/x/sys v0.0.0-20220429233432-b5fbb4746d32/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 h1:GZokNIeuVkl3aZHJchRrr13WCsols02MLUcz1U9is6M=\ngolang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=\ngolang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=\ngolang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=\ngolang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U=\ngolang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=\ngoogle.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=\ngoogle.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=\ngoogle.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=\ngoogle.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=\ngoogle.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=\ngoogle.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=\ngoogle.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=\ngoogle.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=\ngoogle.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=\ngoogle.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=\ngoogle.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=\ngoogle.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=\ngoogle.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=\ngoogle.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=\ngoogle.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=\ngoogle.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8 h1:XosVttQUxX8erNhEruTu053/VchgYuksoS9Bj/OITjU=\ngoogle.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=\ngoogle.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=\ngoogle.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=\ngoogle.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=\ngoogle.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=\ngoogle.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=\ngoogle.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=\ngoogle.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8=\ngoogle.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=\ngoogle.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=\ngoogle.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=\ngopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=\ngopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=\ngopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=\ngopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=\ngopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\nhonnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=\nhonnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nhonnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nrsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=\nrsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=\nrsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=\nsourcegraph.com/sourcegraph/appdash v0.0.0-20180110180208-2cc67fd64755/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=\nsourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67/go.mod h1:L5q+DGLGOQFpo1snNEkLOJT2d1YTW66rWNzatr3He1k=\n"
  },
  {
    "path": "gqlgen.yml",
    "content": "schema:\n  - \"resources/graphql/*.graphql\"\n\nexec:\n  filename: generated/graphql/generated.go\n\nmodel:\n  filename: generated/graphql/models_gen.go\n\nresolver:\n  filename: app/graphql_resolver/resolver_gen.go\n  type: Resolver\n\nmodels:\n  Product:\n    model: github.com/aristat/golang-example-app/app/db/domain.Product\n  ProductItem:\n    model: github.com/aristat/golang-example-app/app/db/domain.ProductItem\n  UsersQuery:\n    fields:\n      one:\n        resolver: true\n  ProductsQuery:\n    fields:\n      list:\n        resolver: true\n  UsersMutation:\n    fields:\n      createUser:\n        resolver: true\n"
  },
  {
    "path": "main.go",
    "content": "package main\n\nimport \"github.com/aristat/golang-example-app/cmd\"\n\nfunc main() {\n\tcmd.Execute()\n}\n"
  },
  {
    "path": "prototool.yaml",
    "content": "protoc:\n  version: 3.8.0\n\ngenerate:\n  go_options:\n    import_path: github.com/aristat/golang-example-app\n\n  plugins:\n    - name: go-grpc\n      type: go\n      flags: paths=source_relative\n      output: generated\n"
  },
  {
    "path": "resources/casbin/model.conf",
    "content": "[request_definition]\nr = sub, obj, act\n\n[policy_definition]\np = sub, obj, act\n\n[role_definition]\ng = _, _\n\n[policy_effect]\ne = some(where (p.eft == allow))\n\n[matchers]\nm = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act\n"
  },
  {
    "path": "resources/casbin/policy.csv",
    "content": "p, reader, users, read\np, owner, users, write\n\ng, reader, anonymous\ng, owner, reader\n"
  },
  {
    "path": "resources/configs/development.yaml",
    "content": "session:\n  redisUrl: localhost:6379\n  redisDB: 10\ndb:\n  url: postgresql://localhost:5432/golang_example_development?sslmode=disable\n  maxOpenConns: 5\n  maxIdleConns: 3\n  connMaxLifetime: 15m\n  logLevel: 7\ngrpc:\n  services:\n    products:\n      target: localhost:50051\n      maxConn: 10\n      initConn: 1\n      maxLifeDuration: 5m\n      idleTimeout: 1s\n  clientParameters:\n    time: 5m\n    timeout: 10s\n    permitWithoutStream: false\nauth:\n  services:\n    test-service: 1\n  relativePath: keys/local\nlogger:\n  debug: true\ngraphql:\n  introspection: true\ngraphql_resolver:\n  productTimeout: 5\ntracing:\n  jaeger:\n    agentHost: localhost\n    agentPort: 6831\n    serviceName: golang-example-app-server\nproducts:\n  natsUrl: http://localhost:4222\n  subject: products\nservices:\n  productService:\n    port: 50051\n    healthCheckUrl: localhost:50052\n    natsUrl: http://localhost:4222\n    subject: products\n  healthCheckService:\n    port: 50052\n    randomDisable: true\n"
  },
  {
    "path": "resources/configs/docker_development.yaml",
    "content": "session:\n  redisUrl: redis:6379\n  redisDB: 10\ndb:\n  url: postgres://postgres@postgres:5432/golang_example_development?sslmode=disable\n  maxOpenConns: 5\n  maxIdleConns: 3\n  connMaxLifetime: 15m\n  logLevel: 7\ngrpc:\n  services:\n    products:\n      target: product_service:50051\n      maxConn: 10\n      initConn: 1\n      maxLifeDuration: 5m\n      idleTimeout: 1s\n  clientParameters:\n    time: 5m\n    timeout: 10s\n    permitWithoutStream: false\nauth:\n  services:\n    test-service: 1\n  relativePath: keys/local\nlogger:\n  debug: true\ngraphql:\n  introspection: true\ngraphql_resolver:\n  productTimeout: 5\ntracing:\n  jaeger:\n    agentHost: jaeger\n    agentPort: 6831\n    serviceName: golang-example-app-server\nproducts:\n  natsUrl: nats-streaming:4222\n  subject: products\nservices:\n  productService:\n    port: 50051\n    healthCheckUrl: health_check_service:50052\n    natsUrl: nats-streaming:4222\n    subject: products\n  healthCheckService:\n    port: 50052\n    randomDisable: true\n"
  },
  {
    "path": "resources/graphql/products.graphql",
    "content": "type ProductsQuery {\n    list: ProductsListOut!\n}\n\ntype Product {\n    id: ID!\n    name: String!\n    productItems: [ProductItem!]!\n}\n\ntype ProductItem {\n    id: ID!\n    name: String!\n}\n\ntype ProductsListOut {\n    products: [Product!]!\n}\n"
  },
  {
    "path": "resources/graphql/root.graphql",
    "content": "type Query {\n    users: UsersQuery\n    products: ProductsQuery\n}\n\ntype Mutation {\n    users: UsersMutation\n}\n"
  },
  {
    "path": "resources/graphql/user.graphql",
    "content": "type UsersOneOut {\n    id: ID!\n    email: String!\n}\n\ntype UsersQuery {\n    one(email: String!): UsersOneOut! @hasUsersPermission(permission: READ)\n}\n\ntype UsersMutation {\n    createUser(email: String!, password: String!): UsersCreateOut! @hasUsersPermission(permission: WRITE)\n}\n\ntype UsersCreateOut {\n    status: UsersCreateOutStatus!\n    id: ID!\n    email: String!\n}\n\nenum UsersCreateOutStatus {\n    OK\n    BAD_REQUEST\n    SERVER_INTERNAL_ERROR\n}\n\ndirective @hasUsersPermission(permission: UsersPermissionEnum!) on FIELD_DEFINITION\n\nenum UsersPermissionEnum {\n    READ\n    WRITE\n}\n"
  },
  {
    "path": "resources/keys/local/private_key.pem",
    "content": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEA0yucnZD57YJ5bPjdZfltW1sObqjT89R6fiHJRkwtA29COZro\nH+I2ZNtXJ6Y5zOuE4DVgeCRIt5/Dk3XO24VClIewK30+hhKxEAHrVYivKiB7AXLg\nvL/CbQp0SSIu/qtJE0NkhEQEVPXRFsQzi1nv/uYOjWOcS66YzYyCV+V/Q885f9vY\nbnJ+pRoulvjTZIneeiGG58l68cRE3Cky3WnXP5q/BsMucPz52uSnaaMHybTKGVG1\nzbDIvRogOg/FHatA04K1fLlq3YKo2gDTRpMNuVWk4D3PGXqf3TTM6XmJdlulgbzn\nMe2p/EUuOaM1B3g6XyeTT8/3eBzgUjK9x0HALwIDAQABAoIBABGeZebPncqvRCpP\naUmE0hb5Ne8NrwF9DOtRLlXrLSZINiJQRmXCnf80PcVVHSV30RJT4cSkYlzPu6Wm\nAqhWKgPyfkRiosDU9mj7gAMW8GZ3Z0vrpcyZw0MNyD4B2CHvcJ1m1hAjDKl6CQP5\nQsOxsVB3KWeqk/PMkXs06fsjbsbdcHIflDxstAdHxh1Jjt+R/eOPGKRjkjr+XyIR\n5LLp6eg4D0i2fuh1uo08q3Ok654kAJmKQaDyD9FYqFcYw2jYkJPtwSehoTtfDv2L\n14MwDAJ3vfNHy7zV6PM80sw3lKH7752wK83FmPW2Irkt/UuDxOjs4g/g4uQnRP3w\n8o61J8ECgYEA984X1FLMQ7/iljd3eas1wOxky86Q/7NOBJy61NhYVWhrwswIoHVQ\nxyRVZBMAez0HQL4/YFkRpe/BQD9ABXIRUkauzOdNMs1F8GPE1Y50g8EkjtUwJ5Ke\nrn9T6UBxitjfe8mgCSVWRl4tlmNLaYetY3PPJsLkxinBg/F7NHnePgcCgYEA2ide\n91+Vup2AYOQb14R6QCBTGbHWOoPpUsRYg5+h2uHEE5onYIZpM4K4zheBz6L7IDlq\nk9qy83M/U7mW410iwrSbfTZYg9yJZClSCh/jZhU6/e5Rrg0+LT1lwbcnCrbtYyKu\nHsEOLbc6l66bqJimTT4JEYA7xuMi8EP5PsjQYpkCgYEA7ILBb57O4mLECodJ+tAT\n79wvn+25qrMh5XkJQJh0Rp/xKey+1xbhUBA3h9oy/WyT/ZEWwAiCtZONKJq1qfzi\n11oq/9pLbg9Jj1RJy2G5hv7Su5hx63MfDIDuP5OISvMO6gDYQ6JlI6hDbmO62C/s\npx0jO2WMIC4+SoYyBzXBjgUCgYEAvZp6b4YkHI3Hhm67xBTgK9vsXeiyySjdIZKF\nW+DiS9rtEBxrHPm1dY+oD3de25hLqzY760WpQu5nm90xx2qrS46tlaYmSHTk9Kj1\nJNeSTKcnHoyDcUMRR0CVsEf/JtDWgdMigphIOnOF+U9I+r+xynCgcRWC3tmLBEgP\n2QGwHAECgYEA9nTzfqm9Vjdyn6zjbkp9zr/j+r9KLPeEiXQKlAuPyg+zXrYzneIE\nFyqi2WMep+Q8oY1kCwPmHz72WrP/NCXPwjBVYZsGA4vCDLVm/g6A8yoTQV/Cb89s\npKNKfj4Tj1K1QIxO6yLbBb1SynOCxkLFyg9Xdt/jgW0cxpREQM6XMTE=\n-----END RSA PRIVATE KEY-----\n"
  },
  {
    "path": "resources/keys/local/public_key.pem",
    "content": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0yucnZD57YJ5bPjdZflt\nW1sObqjT89R6fiHJRkwtA29COZroH+I2ZNtXJ6Y5zOuE4DVgeCRIt5/Dk3XO24VC\nlIewK30+hhKxEAHrVYivKiB7AXLgvL/CbQp0SSIu/qtJE0NkhEQEVPXRFsQzi1nv\n/uYOjWOcS66YzYyCV+V/Q885f9vYbnJ+pRoulvjTZIneeiGG58l68cRE3Cky3WnX\nP5q/BsMucPz52uSnaaMHybTKGVG1zbDIvRogOg/FHatA04K1fLlq3YKo2gDTRpMN\nuVWk4D3PGXqf3TTM6XmJdlulgbznMe2p/EUuOaM1B3g6XyeTT8/3eBzgUjK9x0HA\nLwIDAQAB\n-----END PUBLIC KEY-----\n"
  },
  {
    "path": "resources/migrations/20181215164636-create_users.sql",
    "content": "\n-- +migrate Up\n\nCREATE TABLE users(\n    id SERIAL PRIMARY KEY,\n    email VARCHAR(255) NOT NULL DEFAULT '',\n    encrypted_password VARCHAR(255) NOT NULL DEFAULT ''\n);\n\nCREATE UNIQUE INDEX users_email ON users USING btree (email);\n\n-- +migrate Down\n"
  },
  {
    "path": "resources/migrations/20181216210607-records.sql",
    "content": "\n-- +migrate Up\n\n-- password: 123456789\nINSERT INTO users (email, encrypted_password) VALUES ('test@gmail.com', '$2a$10$bRGA2ckqEhydPBjA8jpDzehoAAhlmc95nGEB5WaZmxOz/EyUnE9l6');\n\n-- +migrate Down\nDELETE FROM users WHERE email = 'test@gmail.com';\n"
  },
  {
    "path": "resources/proto/health_checks/health_checks.proto",
    "content": "syntax = \"proto3\";\n\npackage health_checks;\n\nimport \"google/protobuf/empty.proto\";\n\noption go_package=\"github.com/aristat/golang-example-app/health_checks\";\n\nservice HealthChecks {\n    rpc IsAlive (google.protobuf.Empty) returns (IsAliveOut) {\n    }\n}\n\nmessage IsAliveOut {\n    enum Status {\n        OK = 0;\n        NOT_OK = 2;\n    }\n    Status status = 1;\n}\n"
  },
  {
    "path": "resources/proto/products/products.proto",
    "content": "syntax = \"proto3\";\n\npackage products;\n\noption go_package=\"github.com/aristat/golang-example-app/products\";\n\nmessage Product {\n    int64 id = 1;\n    string name = 2;\n}\n\nservice Products {\n    rpc ListProduct (ListProductIn) returns (ListProductOut) {\n    }\n}\n\nmessage ListProductIn {\n    int64 id = 1;\n}\n\nmessage ListProductOut {\n    enum Status {\n        OK = 0;\n        NOT_FOUND = 2;\n    }\n    Status status = 1;\n    repeated Product products = 2;\n}\n"
  },
  {
    "path": "resources/templates/helpers/errors.html",
    "content": "{{ define \"errors\" }}\n    {{if .errors }}\n        {{range .errors}}\n            <h1>\n                {{ . }}\n            </h1>\n        {{end}}\n    {{ end}}\n{{ end}}\n"
  },
  {
    "path": "scripts/docker-compose-start.sh",
    "content": "#!/bin/bash\n\ndocker-compose rm\nREMOVE_CONTAINERS=on DOCKER_IMAGE=golang-example-app TAG=development make docker-image\ndocker-compose up\n"
  },
  {
    "path": "scripts/remove_docker_containers.sh",
    "content": "#!/bin/bash\n\necho \"Start removing containers\"\n\nif [ \"$REMOVE_CONTAINERS\" == ON ]; then\n  docker_containers=$(docker ps -a -q --filter \"name=$DOCKER_IMAGE\")\n\n  if [ -z \"$docker_containers\" ]; then\n    echo \"No containers for remove\"\n  else\n    docker rm $docker_containers\n  fi\nelse\n    echo \"Containers removal disabled\"\nfi\n"
  }
]