feat: add create salty user

This commit is contained in:
Jon Lundy 2022-08-14 10:04:15 -06:00
parent 5ab185df21
commit ad57c89945
Signed by untrusted user who does not match committer: xuu
GPG Key ID: C63E6D61F3035024
18 changed files with 969 additions and 54 deletions

View File

@ -54,3 +54,13 @@ func (p *PageInput) GetCount(v int64) int64 {
} }
return *p.Count return *p.Count
} }
type SaltyUser struct {
Nick string `json:"nick"`
Pubkey string `json:"pubkey"`
Inbox string `json:"inbox"`
}
func (s SaltyUser) Endpoint(ctx context.Context) string {
return "https://ev.sour.is/inbox/" + s.Inbox
}

View File

@ -2,10 +2,14 @@ package gql_ev
import ( import (
"context" "context"
"crypto/sha256"
"fmt" "fmt"
"strings"
"time" "time"
"github.com/keys-pub/keys"
"github.com/sour-is/ev/internal/logz" "github.com/sour-is/ev/internal/logz"
"github.com/sour-is/ev/pkg/domain"
"github.com/sour-is/ev/pkg/es" "github.com/sour-is/ev/pkg/es"
"github.com/sour-is/ev/pkg/msgbus" "github.com/sour-is/ev/pkg/msgbus"
"go.opentelemetry.io/otel/metric/instrument/syncint64" "go.opentelemetry.io/otel/metric/instrument/syncint64"
@ -145,3 +149,40 @@ func (r *Resolver) PostAdded(ctx context.Context, streamID string, after int64)
return ch, nil return ch, nil
} }
func (r *Resolver) CreateSaltyUser(ctx context.Context, nick string, pub string) (*SaltyUser, error) {
streamID := fmt.Sprintf("saltyuser-%x", sha256.Sum256([]byte(strings.ToLower(nick))))
key, err := keys.NewEdX25519PublicKeyFromID(keys.ID(pub))
if err != nil {
return nil, err
}
a, err := es.Create(ctx, r.es, streamID, func(ctx context.Context, agg *domain.SaltyUser) error {
return agg.OnUserRegister(nick, key)
})
if err != nil {
return nil, err
}
return &SaltyUser{
Nick: nick,
Pubkey: pub,
Inbox: a.Inbox.String(),
}, err
}
func (r *Resolver) SaltyUser(ctx context.Context, nick string) (*SaltyUser, error) {
streamID := fmt.Sprintf("saltyuser-%x", sha256.Sum256([]byte(strings.ToLower(nick))))
a, err := es.Update(ctx, r.es, streamID, func(ctx context.Context, agg *domain.SaltyUser) error { return nil })
if err != nil {
return nil, err
}
return &SaltyUser{
Nick: nick,
Pubkey: a.Pubkey.String(),
Inbox: a.Inbox.String(),
}, err
}

14
api/gql_ev/salty.graphqls Normal file
View File

@ -0,0 +1,14 @@
extend type Query {
saltyUser(nick: String!): SaltyUser
}
extend type Mutation {
createSaltyUser(nick: String! pubkey: String!): SaltyUser
}
type SaltyUser {
nick: String!
pubkey: String!
inbox: String!
endpoint: String!
}

13
go.mod
View File

@ -23,22 +23,29 @@ require (
) )
require ( require (
github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5 // indirect
github.com/agnivade/levenshtein v1.1.1 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect
github.com/beeker1121/goque v2.1.0+incompatible // indirect github.com/beeker1121/goque v2.1.0+incompatible // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a // indirect
github.com/dchest/blake2b v1.0.0 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/logr v1.2.3 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-ole/go-ole v1.2.6 // indirect
github.com/golang/protobuf v1.5.2 // indirect github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-cmp v0.5.8 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/keybase/saltpack v0.0.0-20200430135328-e19b1910c0c5 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/onsi/ginkgo v1.14.0 // indirect github.com/onsi/ginkgo v1.14.0 // indirect
github.com/onsi/gomega v1.10.3 // indirect github.com/onsi/gomega v1.10.3 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/prometheus/client_golang v1.12.2 // indirect github.com/prometheus/client_golang v1.12.2 // indirect
github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect
@ -46,21 +53,27 @@ require (
github.com/prometheus/procfs v0.7.3 // indirect github.com/prometheus/procfs v0.7.3 // indirect
github.com/shirou/gopsutil/v3 v3.22.3 // indirect github.com/shirou/gopsutil/v3 v3.22.3 // indirect
github.com/syndtr/goleveldb v1.0.0 // indirect github.com/syndtr/goleveldb v1.0.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect
github.com/vmihailenco/tagparser v0.1.2 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect
go.opentelemetry.io/contrib v1.9.0 // indirect go.opentelemetry.io/contrib v1.9.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.9.0 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.9.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.9.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.9.0 // indirect
go.opentelemetry.io/proto/otlp v0.18.0 // indirect go.opentelemetry.io/proto/otlp v0.18.0 // indirect
go.uber.org/atomic v1.9.0 // indirect go.uber.org/atomic v1.9.0 // indirect
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f // indirect golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f // indirect
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect
golang.org/x/text v0.3.7 // indirect golang.org/x/text v0.3.7 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect
google.golang.org/grpc v1.46.2 // indirect google.golang.org/grpc v1.46.2 // indirect
google.golang.org/protobuf v1.28.0 // indirect google.golang.org/protobuf v1.28.0 // indirect
) )
require ( require (
github.com/keys-pub/keys v0.1.22
github.com/matryer/is v1.4.0 github.com/matryer/is v1.4.0
github.com/oklog/ulid/v2 v2.1.0 github.com/oklog/ulid/v2 v2.1.0
github.com/tidwall/gjson v1.10.2 // indirect github.com/tidwall/gjson v1.10.2 // indirect

46
go.sum
View File

@ -37,6 +37,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5 h1:VauE2GcJNZFun2Och6tIT2zJZK1v6jxALQDA9BIji/E=
github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5/go.mod h1:gxOHeajFfvGQh/fxlC8oOKBe23xnnJTif00IFFbiT+o=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
@ -77,9 +79,15 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a h1:saTgr5tMLFnmy/yg3qDTft4rE5DY2uJ/cCxCe3q0XTU=
github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a/go.mod h1:Bw9BbhOJVNR+t0jCqx2GC6zv0TGBsShs56Y3gfSCvl0=
github.com/dchest/blake2b v1.0.0 h1:KK9LimVmE0MjRl9095XJmKqZ+iLxWATvlcpVFRtaw6s=
github.com/dchest/blake2b v1.0.0/go.mod h1:U034kXgbJpCle2wSk5ybGIVhOSHCVLMDqOzcPEA0F7s=
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g=
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@ -92,6 +100,7 @@ github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
@ -113,6 +122,7 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
@ -142,6 +152,7 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
@ -161,6 +172,7 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@ -196,13 +208,25 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM= github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM=
github.com/keybase/go-codec v0.0.0-20180928230036-164397562123/go.mod h1:r/eVVWCngg6TsFV/3HuS9sWhDkAzGG8mXhiuYA+Z/20=
github.com/keybase/go-keychain v0.0.0-20201121013009-976c83ec27a6/go.mod h1:N83iQ9rnnzi2KZuTu+0xBcD1JNWn1jSN140ggAF7HeE=
github.com/keybase/go.dbus v0.0.0-20200324223359-a94be52c0b03/go.mod h1:a8clEhrrGV/d76/f9r2I41BwANMihfZYV9C223vaxqE=
github.com/keybase/saltpack v0.0.0-20200430135328-e19b1910c0c5 h1:X6nYzCVURqxDv0GuyptaCcRFTXPM0rSGNUrTeQ2NKUQ=
github.com/keybase/saltpack v0.0.0-20200430135328-e19b1910c0c5/go.mod h1:FNSq71OhXv/Z1W9M37nnHxJVhXitc03z6qshCbAten8=
github.com/keys-pub/keys v0.1.22 h1:bO0nx7c3HuC8dqjmjZ8njC8DzpuKWnOZQ5njaO5+A+o=
github.com/keys-pub/keys v0.1.22/go.mod h1:+41yREqLkYyGfGf4OkhUn/ljwe/+kwhrlTq1/46Jj8c=
github.com/keys-pub/secretservice v0.0.0-20200519003656-26e44b8df47f/go.mod h1:YRHMiVbZqh7u8xRm77CvwJNAZdDlNXwWvQ4DK0N9mYg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc= github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc=
github.com/logzio/logzio-go v1.0.6 h1:BIVu5TWDZc0vlEkwSDjoxPlV/aMJV2LdM3k+CjdzFDg= github.com/logzio/logzio-go v1.0.6 h1:BIVu5TWDZc0vlEkwSDjoxPlV/aMJV2LdM3k+CjdzFDg=
github.com/logzio/logzio-go v1.0.6/go.mod h1:ljlI3Zfi3hntJiHqCqWSUPT9cZP6yvDHUzDl5ZLGYRE= github.com/logzio/logzio-go v1.0.6/go.mod h1:ljlI3Zfi3hntJiHqCqWSUPT9cZP6yvDHUzDl5ZLGYRE=
@ -242,6 +266,7 @@ github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDs
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@ -286,6 +311,7 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@ -307,10 +333,17 @@ github.com/tidwall/wal v1.1.7 h1:emc1TRjIVsdKKSnpwGBAcsAGg0767SvUk8+ygx7Bb+4=
github.com/tidwall/wal v1.1.7/go.mod h1:r6lR1j27W9EPalgHiB7zLJDYu3mzW5BQP5KrzBpYY/E= github.com/tidwall/wal v1.1.7/go.mod h1:r6lR1j27W9EPalgHiB7zLJDYu3mzW5BQP5KrzBpYY/E=
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY= github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY=
github.com/vektah/gqlparser/v2 v2.4.6/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0= github.com/vektah/gqlparser/v2 v2.4.6/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0=
github.com/vektah/gqlparser/v2 v2.4.7 h1:yub2WLoSIr+chP1zMv6bjrsgTasfubxGZJeC8ISEpgE= github.com/vektah/gqlparser/v2 v2.4.7 h1:yub2WLoSIr+chP1zMv6bjrsgTasfubxGZJeC8ISEpgE=
github.com/vektah/gqlparser/v2 v2.4.7/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0= github.com/vektah/gqlparser/v2 v2.4.7/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0=
github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U=
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc=
github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@ -360,7 +393,11 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -427,6 +464,7 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f h1:OfiFi4JbukWwe3lzw+xunroH1mnC1e2Gy5cxNJApiSY= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f h1:OfiFi4JbukWwe3lzw+xunroH1mnC1e2Gy5cxNJApiSY=
@ -475,6 +513,7 @@ golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -492,6 +531,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -505,6 +545,8 @@ golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210317153231-de623e64d2a6 h1:EC6+IGYTjPpRfv9a2b/6Puw0W+hLtAhkV1tPsXhutqs=
golang.org/x/term v0.0.0-20210317153231-de623e64d2a6/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -586,6 +628,8 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@ -655,6 +699,8 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=

View File

@ -40,6 +40,7 @@ type Config struct {
} }
type ResolverRoot interface { type ResolverRoot interface {
Mutation() MutationResolver
Query() QueryResolver Query() QueryResolver
Subscription() SubscriptionResolver Subscription() SubscriptionResolver
} }
@ -60,6 +61,10 @@ type ComplexityRoot struct {
StreamID func(childComplexity int) int StreamID func(childComplexity int) int
} }
Mutation struct {
CreateSaltyUser func(childComplexity int, nick string, pubkey string) int
}
PageInfo struct { PageInfo struct {
Begin func(childComplexity int) int Begin func(childComplexity int) int
End func(childComplexity int) int End func(childComplexity int) int
@ -77,9 +82,17 @@ type ComplexityRoot struct {
Query struct { Query struct {
Posts func(childComplexity int, streamID string, paging *gql_ev.PageInput) int Posts func(childComplexity int, streamID string, paging *gql_ev.PageInput) int
SaltyUser func(childComplexity int, nick string) int
__resolve__service func(childComplexity int) int __resolve__service func(childComplexity int) int
} }
SaltyUser struct {
Endpoint func(childComplexity int) int
Inbox func(childComplexity int) int
Nick func(childComplexity int) int
Pubkey func(childComplexity int) int
}
Subscription struct { Subscription struct {
PostAdded func(childComplexity int, streamID string, after int64) int PostAdded func(childComplexity int, streamID string, after int64) int
} }
@ -89,8 +102,12 @@ type ComplexityRoot struct {
} }
} }
type MutationResolver interface {
CreateSaltyUser(ctx context.Context, nick string, pubkey string) (*gql_ev.SaltyUser, error)
}
type QueryResolver interface { type QueryResolver interface {
Posts(ctx context.Context, streamID string, paging *gql_ev.PageInput) (*gql_ev.Connection, error) Posts(ctx context.Context, streamID string, paging *gql_ev.PageInput) (*gql_ev.Connection, error)
SaltyUser(ctx context.Context, nick string) (*gql_ev.SaltyUser, error)
} }
type SubscriptionResolver interface { type SubscriptionResolver interface {
PostAdded(ctx context.Context, streamID string, after int64) (<-chan *gql_ev.PostEvent, error) PostAdded(ctx context.Context, streamID string, after int64) (<-chan *gql_ev.PostEvent, error)
@ -153,6 +170,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Meta.StreamID(childComplexity), true return e.complexity.Meta.StreamID(childComplexity), true
case "Mutation.createSaltyUser":
if e.complexity.Mutation.CreateSaltyUser == nil {
break
}
args, err := ec.field_Mutation_createSaltyUser_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Mutation.CreateSaltyUser(childComplexity, args["nick"].(string), args["pubkey"].(string)), true
case "PageInfo.begin": case "PageInfo.begin":
if e.complexity.PageInfo.Begin == nil { if e.complexity.PageInfo.Begin == nil {
break break
@ -228,6 +257,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Query.Posts(childComplexity, args["streamID"].(string), args["paging"].(*gql_ev.PageInput)), true return e.complexity.Query.Posts(childComplexity, args["streamID"].(string), args["paging"].(*gql_ev.PageInput)), true
case "Query.saltyUser":
if e.complexity.Query.SaltyUser == nil {
break
}
args, err := ec.field_Query_saltyUser_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Query.SaltyUser(childComplexity, args["nick"].(string)), true
case "Query._service": case "Query._service":
if e.complexity.Query.__resolve__service == nil { if e.complexity.Query.__resolve__service == nil {
break break
@ -235,6 +276,34 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Query.__resolve__service(childComplexity), true return e.complexity.Query.__resolve__service(childComplexity), true
case "SaltyUser.endpoint":
if e.complexity.SaltyUser.Endpoint == nil {
break
}
return e.complexity.SaltyUser.Endpoint(childComplexity), true
case "SaltyUser.inbox":
if e.complexity.SaltyUser.Inbox == nil {
break
}
return e.complexity.SaltyUser.Inbox(childComplexity), true
case "SaltyUser.nick":
if e.complexity.SaltyUser.Nick == nil {
break
}
return e.complexity.SaltyUser.Nick(childComplexity), true
case "SaltyUser.pubkey":
if e.complexity.SaltyUser.Pubkey == nil {
break
}
return e.complexity.SaltyUser.Pubkey(childComplexity), true
case "Subscription.postAdded": case "Subscription.postAdded":
if e.complexity.Subscription.PostAdded == nil { if e.complexity.Subscription.PostAdded == nil {
break break
@ -278,6 +347,21 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
var buf bytes.Buffer var buf bytes.Buffer
data.MarshalGQL(&buf) data.MarshalGQL(&buf)
return &graphql.Response{
Data: buf.Bytes(),
}
}
case ast.Mutation:
return func(ctx context.Context) *graphql.Response {
if !first {
return nil
}
first = false
ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap)
data := ec._Mutation(ctx, rc.Operation.SelectionSet)
var buf bytes.Buffer
data.MarshalGQL(&buf)
return &graphql.Response{ return &graphql.Response{
Data: buf.Bytes(), Data: buf.Bytes(),
} }
@ -383,6 +467,20 @@ type PostEvent implements Edge {
tags: [String!]! tags: [String!]!
meta: Meta! meta: Meta!
}`, BuiltIn: false},
{Name: "../../../api/gql_ev/salty.graphqls", Input: `extend type Query {
saltyUser(nick: String!): SaltyUser
}
extend type Mutation {
createSaltyUser(nick: String! pubkey: String!): SaltyUser
}
type SaltyUser {
nick: String!
pubkey: String!
inbox: String!
endpoint: String!
}`, BuiltIn: false}, }`, BuiltIn: false},
{Name: "../../../federation/directives.graphql", Input: ` {Name: "../../../federation/directives.graphql", Input: `
scalar _Any scalar _Any
@ -411,6 +509,30 @@ var parsedSchema = gqlparser.MustLoadSchema(sources...)
// region ***************************** args.gotpl ***************************** // region ***************************** args.gotpl *****************************
func (ec *executionContext) field_Mutation_createSaltyUser_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 string
if tmp, ok := rawArgs["nick"]; ok {
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("nick"))
arg0, err = ec.unmarshalNString2string(ctx, tmp)
if err != nil {
return nil, err
}
}
args["nick"] = arg0
var arg1 string
if tmp, ok := rawArgs["pubkey"]; ok {
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("pubkey"))
arg1, err = ec.unmarshalNString2string(ctx, tmp)
if err != nil {
return nil, err
}
}
args["pubkey"] = arg1
return args, nil
}
func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error var err error
args := map[string]interface{}{} args := map[string]interface{}{}
@ -450,6 +572,21 @@ func (ec *executionContext) field_Query_posts_args(ctx context.Context, rawArgs
return args, nil return args, nil
} }
func (ec *executionContext) field_Query_saltyUser_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 string
if tmp, ok := rawArgs["nick"]; ok {
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("nick"))
arg0, err = ec.unmarshalNString2string(ctx, tmp)
if err != nil {
return nil, err
}
}
args["nick"] = arg0
return args, nil
}
func (ec *executionContext) field_Subscription_postAdded_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { func (ec *executionContext) field_Subscription_postAdded_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error var err error
args := map[string]interface{}{} args := map[string]interface{}{}
@ -786,6 +923,68 @@ func (ec *executionContext) fieldContext_Meta_position(ctx context.Context, fiel
return fc, nil return fc, nil
} }
func (ec *executionContext) _Mutation_createSaltyUser(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Mutation_createSaltyUser(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().CreateSaltyUser(rctx, fc.Args["nick"].(string), fc.Args["pubkey"].(string))
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*gql_ev.SaltyUser)
fc.Result = res
return ec.marshalOSaltyUser2ᚖgithubᚗcomᚋsourᚑisᚋevᚋapiᚋgql_evᚐSaltyUser(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_createSaltyUser(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Mutation",
Field: field,
IsMethod: true,
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
case "nick":
return ec.fieldContext_SaltyUser_nick(ctx, field)
case "pubkey":
return ec.fieldContext_SaltyUser_pubkey(ctx, field)
case "inbox":
return ec.fieldContext_SaltyUser_inbox(ctx, field)
case "endpoint":
return ec.fieldContext_SaltyUser_endpoint(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type SaltyUser", field.Name)
},
}
defer func() {
if r := recover(); r != nil {
err = ec.Recover(ctx, r)
ec.Error(ctx, err)
}
}()
ctx = graphql.WithFieldContext(ctx, fc)
if fc.Args, err = ec.field_Mutation_createSaltyUser_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
ec.Error(ctx, err)
return
}
return fc, nil
}
func (ec *executionContext) _PageInfo_next(ctx context.Context, field graphql.CollectedField, obj *gql_ev.PageInfo) (ret graphql.Marshaler) { func (ec *executionContext) _PageInfo_next(ctx context.Context, field graphql.CollectedField, obj *gql_ev.PageInfo) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_PageInfo_next(ctx, field) fc, err := ec.fieldContext_PageInfo_next(ctx, field)
if err != nil { if err != nil {
@ -1253,6 +1452,68 @@ func (ec *executionContext) fieldContext_Query_posts(ctx context.Context, field
return fc, nil return fc, nil
} }
func (ec *executionContext) _Query_saltyUser(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Query_saltyUser(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().SaltyUser(rctx, fc.Args["nick"].(string))
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*gql_ev.SaltyUser)
fc.Result = res
return ec.marshalOSaltyUser2ᚖgithubᚗcomᚋsourᚑisᚋevᚋapiᚋgql_evᚐSaltyUser(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Query_saltyUser(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Query",
Field: field,
IsMethod: true,
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
case "nick":
return ec.fieldContext_SaltyUser_nick(ctx, field)
case "pubkey":
return ec.fieldContext_SaltyUser_pubkey(ctx, field)
case "inbox":
return ec.fieldContext_SaltyUser_inbox(ctx, field)
case "endpoint":
return ec.fieldContext_SaltyUser_endpoint(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type SaltyUser", field.Name)
},
}
defer func() {
if r := recover(); r != nil {
err = ec.Recover(ctx, r)
ec.Error(ctx, err)
}
}()
ctx = graphql.WithFieldContext(ctx, fc)
if fc.Args, err = ec.field_Query_saltyUser_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
ec.Error(ctx, err)
return
}
return fc, nil
}
func (ec *executionContext) _Query__service(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { func (ec *executionContext) _Query__service(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Query__service(ctx, field) fc, err := ec.fieldContext_Query__service(ctx, field)
if err != nil { if err != nil {
@ -1430,6 +1691,182 @@ func (ec *executionContext) fieldContext_Query___schema(ctx context.Context, fie
return fc, nil return fc, nil
} }
func (ec *executionContext) _SaltyUser_nick(ctx context.Context, field graphql.CollectedField, obj *gql_ev.SaltyUser) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_SaltyUser_nick(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Nick, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_SaltyUser_nick(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "SaltyUser",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _SaltyUser_pubkey(ctx context.Context, field graphql.CollectedField, obj *gql_ev.SaltyUser) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_SaltyUser_pubkey(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Pubkey, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_SaltyUser_pubkey(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "SaltyUser",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _SaltyUser_inbox(ctx context.Context, field graphql.CollectedField, obj *gql_ev.SaltyUser) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_SaltyUser_inbox(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Inbox, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_SaltyUser_inbox(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "SaltyUser",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _SaltyUser_endpoint(ctx context.Context, field graphql.CollectedField, obj *gql_ev.SaltyUser) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_SaltyUser_endpoint(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Endpoint(ctx), nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_SaltyUser_endpoint(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "SaltyUser",
Field: field,
IsMethod: true,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _Subscription_postAdded(ctx context.Context, field graphql.CollectedField) (ret func(ctx context.Context) graphql.Marshaler) { func (ec *executionContext) _Subscription_postAdded(ctx context.Context, field graphql.CollectedField) (ret func(ctx context.Context) graphql.Marshaler) {
fc, err := ec.fieldContext_Subscription_postAdded(ctx, field) fc, err := ec.fieldContext_Subscription_postAdded(ctx, field)
if err != nil { if err != nil {
@ -3473,6 +3910,42 @@ func (ec *executionContext) _Meta(ctx context.Context, sel ast.SelectionSet, obj
return out return out
} }
var mutationImplementors = []string{"Mutation"}
func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler {
fields := graphql.CollectFields(ec.OperationContext, sel, mutationImplementors)
ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{
Object: "Mutation",
})
out := graphql.NewFieldSet(fields)
var invalids uint32
for i, field := range fields {
innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{
Object: field.Name,
Field: field,
})
switch field.Name {
case "__typename":
out.Values[i] = graphql.MarshalString("Mutation")
case "createSaltyUser":
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
return ec._Mutation_createSaltyUser(ctx, field)
})
default:
panic("unknown field " + strconv.Quote(field.Name))
}
}
out.Dispatch()
if invalids > 0 {
return graphql.Null
}
return out
}
var pageInfoImplementors = []string{"PageInfo"} var pageInfoImplementors = []string{"PageInfo"}
func (ec *executionContext) _PageInfo(ctx context.Context, sel ast.SelectionSet, obj *gql_ev.PageInfo) graphql.Marshaler { func (ec *executionContext) _PageInfo(ctx context.Context, sel ast.SelectionSet, obj *gql_ev.PageInfo) graphql.Marshaler {
@ -3630,6 +4103,26 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc)
} }
out.Concurrently(i, func() graphql.Marshaler {
return rrm(innerCtx)
})
case "saltyUser":
field := field
innerFunc := func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Query_saltyUser(ctx, field)
return res
}
rrm := func(ctx context.Context) graphql.Marshaler {
return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc)
}
out.Concurrently(i, func() graphql.Marshaler { out.Concurrently(i, func() graphql.Marshaler {
return rrm(innerCtx) return rrm(innerCtx)
}) })
@ -3679,6 +4172,68 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
return out return out
} }
var saltyUserImplementors = []string{"SaltyUser"}
func (ec *executionContext) _SaltyUser(ctx context.Context, sel ast.SelectionSet, obj *gql_ev.SaltyUser) graphql.Marshaler {
fields := graphql.CollectFields(ec.OperationContext, sel, saltyUserImplementors)
out := graphql.NewFieldSet(fields)
var invalids uint32
for i, field := range fields {
switch field.Name {
case "__typename":
out.Values[i] = graphql.MarshalString("SaltyUser")
case "nick":
out.Values[i] = ec._SaltyUser_nick(ctx, field, obj)
if out.Values[i] == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
case "pubkey":
out.Values[i] = ec._SaltyUser_pubkey(ctx, field, obj)
if out.Values[i] == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
case "inbox":
out.Values[i] = ec._SaltyUser_inbox(ctx, field, obj)
if out.Values[i] == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
case "endpoint":
field := field
innerFunc := func(ctx context.Context) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._SaltyUser_endpoint(ctx, field, obj)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
}
out.Concurrently(i, func() graphql.Marshaler {
return innerFunc(ctx)
})
default:
panic("unknown field " + strconv.Quote(field.Name))
}
}
out.Dispatch()
if invalids > 0 {
return graphql.Null
}
return out
}
var subscriptionImplementors = []string{"Subscription"} var subscriptionImplementors = []string{"Subscription"}
func (ec *executionContext) _Subscription(ctx context.Context, sel ast.SelectionSet) func(ctx context.Context) graphql.Marshaler { func (ec *executionContext) _Subscription(ctx context.Context, sel ast.SelectionSet) func(ctx context.Context) graphql.Marshaler {
@ -4602,6 +5157,13 @@ func (ec *executionContext) marshalOPostEvent2ᚖgithubᚗcomᚋsourᚑisᚋev
return ec._PostEvent(ctx, sel, v) return ec._PostEvent(ctx, sel, v)
} }
func (ec *executionContext) marshalOSaltyUser2ᚖgithubᚗcomᚋsourᚑisᚋevᚋapiᚋgql_evᚐSaltyUser(ctx context.Context, sel ast.SelectionSet, v *gql_ev.SaltyUser) graphql.Marshaler {
if v == nil {
return graphql.Null
}
return ec._SaltyUser(ctx, sel, v)
}
func (ec *executionContext) unmarshalOString2string(ctx context.Context, v interface{}) (string, error) { func (ec *executionContext) unmarshalOString2string(ctx context.Context, v interface{}) (string, error) {
res, err := graphql.UnmarshalString(v) res, err := graphql.UnmarshalString(v)
return res, graphql.ErrorOnPath(ctx, err) return res, graphql.ErrorOnPath(ctx, err)

View File

@ -23,11 +23,16 @@ func New(r *gql_ev.Resolver) *Resolver {
// Query returns generated.QueryResolver implementation. // Query returns generated.QueryResolver implementation.
func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} } func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
// Query returns generated.QueryResolver implementation.
func (r *Resolver) Mutation() generated.MutationResolver { return &mutationResolver{r} }
// Subscription returns generated.SubscriptionResolver implementation. // Subscription returns generated.SubscriptionResolver implementation.
func (r *Resolver) Subscription() generated.SubscriptionResolver { return &subscriptionResolver{r} } func (r *Resolver) Subscription() generated.SubscriptionResolver { return &subscriptionResolver{r} }
type queryResolver struct{ *Resolver } type queryResolver struct{ *Resolver }
type mutationResolver struct{ *Resolver }
type subscriptionResolver struct{ *Resolver } type subscriptionResolver struct{ *Resolver }
func (r *Resolver) ChainMiddlewares(h http.Handler) http.Handler { func (r *Resolver) ChainMiddlewares(h http.Handler) http.Handler {

View File

@ -18,6 +18,7 @@ import (
"github.com/sour-is/ev/internal/graph" "github.com/sour-is/ev/internal/graph"
"github.com/sour-is/ev/internal/graph/generated" "github.com/sour-is/ev/internal/graph/generated"
"github.com/sour-is/ev/internal/logz" "github.com/sour-is/ev/internal/logz"
"github.com/sour-is/ev/pkg/domain"
"github.com/sour-is/ev/pkg/es" "github.com/sour-is/ev/pkg/es"
diskstore "github.com/sour-is/ev/pkg/es/driver/disk-store" diskstore "github.com/sour-is/ev/pkg/es/driver/disk-store"
memstore "github.com/sour-is/ev/pkg/es/driver/mem-store" memstore "github.com/sour-is/ev/pkg/es/driver/mem-store"
@ -44,13 +45,16 @@ func main() {
} }
Mup.Add(ctx, 1) Mup.Add(ctx, 1)
if err := run(ctx); err != nil { if err := run(ctx); err != nil && err != http.ErrServerClosed {
log.Println(err) log.Fatal(err)
} }
} }
func run(ctx context.Context) error { func run(ctx context.Context) error {
diskstore.Init(ctx) diskstore.Init(ctx)
memstore.Init(ctx) memstore.Init(ctx)
if err := domain.Init(ctx); err != nil {
return err
}
es, err := es.Open(ctx, env("EV_DATA", "file:data"), streamer.New(ctx)) es, err := es.Open(ctx, env("EV_DATA", "file:data"), streamer.New(ctx))
if err != nil { if err != nil {

74
pkg/domain/salty-user.go Normal file
View File

@ -0,0 +1,74 @@
package domain
import (
"context"
"crypto/sha256"
"fmt"
"log"
"strings"
"github.com/keys-pub/keys"
"github.com/oklog/ulid/v2"
"github.com/sour-is/ev/pkg/es/event"
)
func Init(ctx context.Context) error {
return event.Register(ctx, &UserRegistered{})
}
type SaltyUser struct {
Name string
Pubkey *keys.EdX25519PublicKey
Inbox ulid.ULID
event.AggregateRoot
}
var _ event.Aggregate = (*SaltyUser)(nil)
// ApplyEvent applies the event to the aggrigate state
func (a *SaltyUser) ApplyEvent(lis ...event.Event) {
for _, e := range lis {
switch e := e.(type) {
case *UserRegistered:
a.Name = e.Name
a.Pubkey = e.Pubkey
a.Inbox = e.EventMeta().EventID
a.SetStreamID(a.streamID())
default:
log.Printf("unknown event %T", e)
}
}
}
func (a *SaltyUser) streamID() string {
return fmt.Sprintf("saltyuser-%x", sha256.Sum256([]byte(strings.ToLower(a.Name))))
}
func (a *SaltyUser) OnUserRegister(name string, pubkey *keys.EdX25519PublicKey) error {
event.Raise(a, &UserRegistered{Name: name, Pubkey: pubkey})
return nil
}
type UserRegistered struct {
Name string
Pubkey *keys.EdX25519PublicKey
Endpoint ulid.ULID
eventMeta event.Meta
}
var _ event.Event = (*UserRegistered)(nil)
func (e *UserRegistered) EventMeta() event.Meta {
if e == nil {
return event.Meta{}
}
return e.eventMeta
}
func (e *UserRegistered) SetEventMeta(m event.Meta) {
if e != nil {
e.eventMeta = m
}
}

View File

@ -3,7 +3,6 @@ package diskstore
import ( import (
"context" "context"
"fmt" "fmt"
"log"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@ -94,12 +93,14 @@ func (d *diskStore) Open(ctx context.Context, dsn string) (driver.Driver, error)
err := w.Close() err := w.Close()
if err != nil { if err != nil {
log.Print(err) span.RecordError(err)
return err
} }
return nil return nil
}) })
}) })
if err != nil { if err != nil {
span.RecordError(err)
return nil, err return nil, err
} }
logs := &openlogs{logs: c} logs := &openlogs{logs: c}
@ -127,6 +128,7 @@ func (ds *diskStore) EventLog(ctx context.Context, streamID string) (driver.Even
l, err := wal.Open(filepath.Join(ds.path, streamID), wal.DefaultOptions) l, err := wal.Open(filepath.Join(ds.path, streamID), wal.DefaultOptions)
if err != nil { if err != nil {
span.RecordError(err)
return err return err
} }
el.events = locker.New(l) el.events = locker.New(l)
@ -155,6 +157,7 @@ func (es *eventLog) Append(ctx context.Context, events event.Events, version uin
last, err := l.LastIndex() last, err := l.LastIndex()
if err != nil { if err != nil {
span.RecordError(err)
return err return err
} }
@ -170,6 +173,8 @@ func (es *eventLog) Append(ctx context.Context, events event.Events, version uin
b, err = event.MarshalText(e) b, err = event.MarshalText(e)
if err != nil { if err != nil {
span.RecordError(err)
return err return err
} }
pos := last + uint64(i) + 1 pos := last + uint64(i) + 1
@ -196,10 +201,12 @@ func (es *eventLog) Read(ctx context.Context, pos, count int64) (event.Events, e
first, err := stream.FirstIndex() first, err := stream.FirstIndex()
if err != nil { if err != nil {
span.RecordError(err)
return err return err
} }
last, err := stream.LastIndex() last, err := stream.LastIndex()
if err != nil { if err != nil {
span.RecordError(err)
return err return err
} }
// --- // ---
@ -208,7 +215,7 @@ func (es *eventLog) Read(ctx context.Context, pos, count int64) (event.Events, e
} }
start, count := math.PagerBox(first, last, pos, count) start, count := math.PagerBox(first, last, pos, count)
log.Println("reading", first, last, pos, count, start) span.AddEvent(fmt.Sprint("reading", first, last, pos, count, start))
if count == 0 { if count == 0 {
return nil return nil
} }
@ -221,10 +228,12 @@ func (es *eventLog) Read(ctx context.Context, pos, count int64) (event.Events, e
var b []byte var b []byte
b, err = stream.Read(start) b, err = stream.Read(start)
if err != nil { if err != nil {
span.RecordError(err)
return err return err
} }
events[i], err = event.UnmarshalText(ctx, b, start) events[i], err = event.UnmarshalText(ctx, b, start)
if err != nil { if err != nil {
span.RecordError(err)
return err return err
} }
// --- // ---
@ -242,12 +251,13 @@ func (es *eventLog) Read(ctx context.Context, pos, count int64) (event.Events, e
return nil return nil
}) })
if err != nil { if err != nil {
span.RecordError(err)
return nil, err return nil, err
} }
event.SetStreamID(es.streamID, events...) event.SetStreamID(es.streamID, events...)
return events, err return events, nil
} }
func (es *eventLog) FirstIndex(ctx context.Context) (uint64, error) { func (es *eventLog) FirstIndex(ctx context.Context) (uint64, error) {
_, span := logz.Span(ctx) _, span := logz.Span(ctx)
@ -277,3 +287,6 @@ func (es *eventLog) LastIndex(ctx context.Context) (uint64, error) {
return idx, err return idx, err
} }
func (es *eventLog) LoadForUpdate(ctx context.Context, a event.Aggregate, fn func(context.Context, event.Aggregate) error) (uint64, error) {
panic("not implemented")
}

View File

@ -14,8 +14,10 @@ type Driver interface {
type EventLog interface { type EventLog interface {
Read(ctx context.Context, pos, count int64) (event.Events, error) Read(ctx context.Context, pos, count int64) (event.Events, error)
Append(ctx context.Context, events event.Events, version uint64) (uint64, error) Append(ctx context.Context, events event.Events, version uint64) (uint64, error)
FirstIndex(ctx context.Context) (uint64, error) FirstIndex(context.Context) (uint64, error)
LastIndex(ctx context.Context) (uint64, error) LastIndex(context.Context) (uint64, error)
LoadForUpdate(context.Context, event.Aggregate, func(context.Context, event.Aggregate) error) (uint64, error)
} }
type Subscription interface { type Subscription interface {

View File

@ -79,6 +79,8 @@ func (m *eventLog) Append(ctx context.Context, events event.Events, version uint
_, span := logz.Span(ctx) _, span := logz.Span(ctx)
defer span.End() defer span.End()
span.AddEvent(fmt.Sprintf(" %s %#v %d", m.streamID, stream, len(*stream)))
last := uint64(len(*stream)) last := uint64(len(*stream))
if version != AppendOnly && version != last { if version != AppendOnly && version != last {
return fmt.Errorf("current version wrong %d != %d", version, last) return fmt.Errorf("current version wrong %d != %d", version, last)
@ -97,16 +99,18 @@ func (m *eventLog) Append(ctx context.Context, events event.Events, version uint
} }
// Read implements driver.EventStore // Read implements driver.EventStore
func (es *eventLog) Read(ctx context.Context, pos int64, count int64) (event.Events, error) { func (m *eventLog) Read(ctx context.Context, pos int64, count int64) (event.Events, error) {
ctx, span := logz.Span(ctx) ctx, span := logz.Span(ctx)
defer span.End() defer span.End()
var events event.Events var events event.Events
err := es.events.Modify(ctx, func(stream *event.Events) error { err := m.events.Modify(ctx, func(stream *event.Events) error {
_, span := logz.Span(ctx) _, span := logz.Span(ctx)
defer span.End() defer span.End()
span.AddEvent(fmt.Sprintf(" %s %#v %d", m.streamID, stream, len(*stream)))
first := stream.First().EventMeta().Position first := stream.First().EventMeta().Position
last := stream.Last().EventMeta().Position last := stream.Last().EventMeta().Position
// --- // ---
@ -118,7 +122,7 @@ func (es *eventLog) Read(ctx context.Context, pos int64, count int64) (event.Eve
if count == 0 { if count == 0 {
return nil return nil
} }
span.AddEvent(fmt.Sprint("box", first, last, pos, count))
events = make([]event.Event, math.Abs(count)) events = make([]event.Event, math.Abs(count))
for i := range events { for i := range events {
span.AddEvent(fmt.Sprintf("read event %d of %d", i, math.Abs(count))) span.AddEvent(fmt.Sprintf("read event %d of %d", i, math.Abs(count)))
@ -143,7 +147,7 @@ func (es *eventLog) Read(ctx context.Context, pos int64, count int64) (event.Eve
return nil, err return nil, err
} }
event.SetStreamID(es.streamID, events...) event.SetStreamID(m.streamID, events...)
return events, nil return events, nil
} }
@ -165,3 +169,7 @@ func (m *eventLog) LastIndex(ctx context.Context) (uint64, error) {
events, err := m.events.Copy(ctx) events, err := m.events.Copy(ctx)
return events.Last().EventMeta().Position, err return events.Last().EventMeta().Position, err
} }
func (m *eventLog) LoadForUpdate(ctx context.Context, a event.Aggregate, fn func(context.Context, event.Aggregate) error) (uint64, error) {
panic("not implemented")
}

View File

@ -169,6 +169,10 @@ func (w *wrapper) LastIndex(ctx context.Context) (uint64, error) {
return w.up.LastIndex(ctx) return w.up.LastIndex(ctx)
} }
func (w *wrapper) LoadForUpdate(ctx context.Context, a event.Aggregate, fn func(context.Context, event.Aggregate) error) (uint64, error) {
return w.up.LoadForUpdate(ctx, a, fn)
}
type position struct { type position struct {
size int64 size int64
idx int64 idx int64

View File

@ -110,13 +110,17 @@ func (es *EventStore) Save(ctx context.Context, agg event.Aggregate) (uint64, er
ctx, span := logz.Span(ctx) ctx, span := logz.Span(ctx)
defer span.End() defer span.End()
events := agg.Events(true)
if len(events) == 0 {
return 0, nil
}
Mes_save.Add(ctx, 1) Mes_save.Add(ctx, 1)
l, err := es.EventLog(ctx, agg.StreamID()) l, err := es.EventLog(ctx, agg.StreamID())
if err != nil { if err != nil {
return 0, err return 0, err
} }
events := agg.Events(true)
count, err := l.Append(ctx, events, agg.StreamVersion()) count, err := l.Append(ctx, events, agg.StreamVersion())
if err != nil { if err != nil {
@ -141,6 +145,7 @@ func (es *EventStore) Load(ctx context.Context, agg event.Aggregate) error {
if err != nil { if err != nil {
return err return err
} }
event.Append(agg, events...) event.Append(agg, events...)
return nil return nil
@ -189,7 +194,6 @@ func (es *EventStore) LastIndex(ctx context.Context, streamID string) (uint64, e
} }
return l.LastIndex(ctx) return l.LastIndex(ctx)
} }
func (es *EventStore) EventStream() driver.EventStream { func (es *EventStore) EventStream() driver.EventStream {
d := es.Driver d := es.Driver
for d != nil { for d != nil {
@ -212,3 +216,65 @@ func Unwrap[T any](t T) T {
} }
var ErrNoDriver = errors.New("no driver") var ErrNoDriver = errors.New("no driver")
type PA[T any] interface {
event.Aggregate
*T
}
// Create uses fn to create a new aggregate and store in db.
func Create[A any, T PA[A]](ctx context.Context, es *EventStore, streamID string, fn func(context.Context, T) error) (agg T, err error) {
ctx, span := logz.Span(ctx)
defer span.End()
agg = new(A)
agg.SetStreamID(streamID)
if err = es.Load(ctx, agg); err != nil {
return
}
if err = event.NotExists(agg); err != nil {
return
}
if err = fn(ctx, agg); err != nil {
return
}
var i uint64
if i, err = es.Save(ctx, agg); err != nil {
return
}
span.AddEvent(fmt.Sprint("wrote events = ", i))
return
}
// Update uses fn to update an exsisting aggregate and store in db.
func Update[A any, T PA[A]](ctx context.Context, es *EventStore, streamID string, fn func(context.Context, T) error) (agg T, err error) {
ctx, span := logz.Span(ctx)
defer span.End()
agg = new(A)
agg.SetStreamID(streamID)
if err = es.Load(ctx, agg); err != nil {
return
}
if err = event.ShouldExist(agg); err != nil {
return
}
if err = fn(ctx, agg); err != nil {
return
}
if _, err = es.Save(ctx, agg); err != nil {
return
}
return
}

View File

@ -9,7 +9,6 @@ import (
type Aggregate interface { type Aggregate interface {
// ApplyEvent applies the event to the aggrigate state // ApplyEvent applies the event to the aggrigate state
ApplyEvent(...Event) ApplyEvent(...Event)
StreamID() string
AggregateRootInterface AggregateRootInterface
} }
@ -28,14 +27,6 @@ func Append(a Aggregate, lis ...Event) {
a.ApplyEvent(lis...) a.ApplyEvent(lis...)
} }
// CheckVersion returns an error if the version does not match.
func CheckVersion(a Aggregate, version uint64) error {
if version != uint64(a.StreamVersion()) {
return fmt.Errorf("version wrong, got (proposed) %d != (expected) %d", version, a.StreamVersion())
}
return nil
}
// NotExists returns error if there are no events present. // NotExists returns error if there are no events present.
func NotExists(a Aggregate) error { func NotExists(a Aggregate) error {
if a.StreamVersion() != 0 { if a.StreamVersion() != 0 {
@ -44,10 +35,22 @@ func NotExists(a Aggregate) error {
return nil return nil
} }
// ShouldExists returns error if there are no events present.
func ShouldExist(a Aggregate) error {
if a.StreamVersion() == 0 {
return fmt.Errorf("%w, got version == %d", ErrShouldExist, a.StreamVersion())
}
return nil
}
type AggregateRootInterface interface { type AggregateRootInterface interface {
// Events returns the aggrigate events // Events returns the aggregate events
// pass true for only uncommitted events // pass true for only uncommitted events
Events(bool) Events Events(bool) Events
// StreamID returns aggregate stream ID
StreamID() string
// SetStreamID sets aggregate stream ID
SetStreamID(streamID string)
// StreamVersion returns last commit events // StreamVersion returns last commit events
StreamVersion() uint64 StreamVersion() uint64
// Version returns the current aggrigate version. (committed + uncommitted) // Version returns the current aggrigate version. (committed + uncommitted)
@ -62,18 +65,17 @@ var _ AggregateRootInterface = &AggregateRoot{}
type AggregateRoot struct { type AggregateRoot struct {
events Events events Events
streamID string
streamVersion uint64 streamVersion uint64
mu sync.RWMutex mu sync.RWMutex
} }
func (a *AggregateRoot) Commit() { func (a *AggregateRoot) Commit() { a.streamVersion = uint64(len(a.events)) }
a.streamVersion = uint64(len(a.events)) func (a *AggregateRoot) StreamID() string { return a.streamID }
} func (a *AggregateRoot) SetStreamID(streamID string) { a.streamID = streamID }
func (a *AggregateRoot) StreamVersion() uint64 { return a.streamVersion }
func (a *AggregateRoot) StreamVersion() uint64 { func (a *AggregateRoot) Version() uint64 { return uint64(len(a.events)) }
return a.streamVersion
}
func (a *AggregateRoot) Events(new bool) Events { func (a *AggregateRoot) Events(new bool) Events {
a.mu.RLock() a.mu.RLock()
defer a.mu.RUnlock() defer a.mu.RUnlock()
@ -88,9 +90,6 @@ func (a *AggregateRoot) Events(new bool) Events {
return lis return lis
} }
func (a *AggregateRoot) Version() uint64 {
return uint64(len(a.events))
}
//lint:ignore U1000 is called by embeded interface //lint:ignore U1000 is called by embeded interface
func (a *AggregateRoot) raise(lis ...Event) { //nolint func (a *AggregateRoot) raise(lis ...Event) { //nolint
@ -122,3 +121,4 @@ func (a *AggregateRoot) posStartAt(lis ...Event) {
} }
var ErrShouldNotExist = errors.New("should not exist") var ErrShouldNotExist = errors.New("should not exist")
var ErrShouldExist = errors.New("should exist")

View File

@ -0,0 +1,56 @@
package event_test
import (
"testing"
"github.com/sour-is/ev/pkg/es/event"
)
type Agg struct {
Value string
event.AggregateRoot
}
var _ event.Aggregate = (*Agg)(nil)
func (a *Agg) streamID() string {
return "value-" + a.Value
}
// ApplyEvent applies the event to the aggrigate state
func (a *Agg) ApplyEvent(lis ...event.Event) {
for _, e := range lis {
switch e := e.(type) {
case *ValueApplied:
a.Value = e.Value
a.SetStreamID(a.streamID())
}
}
}
type ValueApplied struct {
Value string
eventMeta event.Meta
}
var _ event.Event = (*ValueApplied)(nil)
func (e *ValueApplied) EventMeta() event.Meta {
if e == nil {
return event.Meta{}
}
return e.eventMeta
}
func (e *ValueApplied) SetEventMeta(m event.Meta) {
if e != nil {
e.eventMeta = m
}
}
func TestAggregate(t *testing.T) {
agg := &Agg{}
event.Append(agg, &ValueApplied{Value: "one"})
}

View File

@ -1,7 +1,6 @@
package math_test package math_test
import ( import (
"log"
"testing" "testing"
"github.com/matryer/is" "github.com/matryer/is"
@ -82,9 +81,9 @@ func TestPagerBox(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
start, count := math.PagerBox(tt.first, tt.last, tt.pos, tt.n) start, count := math.PagerBox(tt.first, tt.last, tt.pos, tt.n)
if count > 0 { if count > 0 {
log.Print(tt, "|", start, count, int64(start)+count-1) t.Log(tt, "|", start, count, int64(start)+count-1)
} else { } else {
log.Print(tt, "|", start, count, int64(start)+count+1) t.Log(tt, "|", start, count, int64(start)+count+1)
} }
is.Equal(start, tt.start) is.Equal(start, tt.start)

View File

@ -6,7 +6,6 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"log"
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
@ -85,10 +84,10 @@ func (s *service) get(w http.ResponseWriter, r *http.Request) {
count = i count = i
} }
log.Print("GET topic=", name, " idx=", pos, " n=", count) span.AddEvent(fmt.Sprint("GET topic=", name, " idx=", pos, " n=", count))
events, err := s.es.Read(ctx, "post-"+name, pos, count) events, err := s.es.Read(ctx, "post-"+name, pos, count)
if err != nil { if err != nil {
log.Print(err) span.RecordError(err)
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
return return
} }
@ -97,7 +96,7 @@ func (s *service) get(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "application/json") w.Header().Add("Content-Type", "application/json")
if err = encodeJSON(w, first, events...); err != nil { if err = encodeJSON(w, first, events...); err != nil {
log.Print(err) span.RecordError(err)
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
return return
@ -159,7 +158,6 @@ func (s *service) post(w http.ResponseWriter, r *http.Request) {
m := events.First().EventMeta() m := events.First().EventMeta()
span.AddEvent(fmt.Sprint("POST topic=", name, " tags=", tags, " idx=", m.Position, " id=", m.EventID)) span.AddEvent(fmt.Sprint("POST topic=", name, " tags=", tags, " idx=", m.Position, " id=", m.EventID))
// log.Print("POST topic=", name, " tags=", tags, " idx=", m.Position, " id=", m.EventID)
w.WriteHeader(http.StatusAccepted) w.WriteHeader(http.StatusAccepted)
if strings.Contains(r.Header.Get("Accept"), "application/json") { if strings.Contains(r.Header.Get("Accept"), "application/json") {
@ -201,11 +199,11 @@ func (s *service) websocket(w http.ResponseWriter, r *http.Request) {
pos = i - 1 pos = i - 1
} }
log.Print("WS topic=", name, " idx=", pos) span.AddEvent(fmt.Sprint("WS topic=", name, " idx=", pos))
c, err := upgrader.Upgrade(w, r, nil) c, err := upgrader.Upgrade(w, r, nil)
if err != nil { if err != nil {
log.Print("upgrade:", err) span.RecordError(err)
return return
} }
defer c.Close() defer c.Close()
@ -222,54 +220,54 @@ func (s *service) websocket(w http.ResponseWriter, r *http.Request) {
} }
mt, message, err := c.ReadMessage() mt, message, err := c.ReadMessage()
if err != nil { if err != nil {
log.Println("read:", err) span.RecordError(err)
return return
} }
log.Printf("recv: %d %s", mt, message) span.AddEvent(fmt.Sprintf("recv: %d %s", mt, message))
} }
}() }()
es := s.es.EventStream() es := s.es.EventStream()
if es == nil { if es == nil {
log.Println("EventStore does not implement streaming") span.AddEvent(fmt.Sprint("EventStore does not implement streaming"))
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
return return
} }
sub, err := es.Subscribe(ctx, "post-"+name, pos) sub, err := es.Subscribe(ctx, "post-"+name, pos)
if err != nil { if err != nil {
log.Println(err) span.RecordError(err)
return return
} }
defer func() { defer func() {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel() defer cancel()
log.Println("stop ws") span.AddEvent(fmt.Sprint("stop ws"))
sub.Close(ctx) sub.Close(ctx)
}() }()
log.Println("start ws") span.AddEvent(fmt.Sprint("start ws"))
for sub.Recv(ctx) { for sub.Recv(ctx) {
events, err := sub.Events(ctx) events, err := sub.Events(ctx)
if err != nil { if err != nil {
break break
} }
log.Println("got events ", len(events)) span.AddEvent(fmt.Sprint("got events ", len(events)))
for i := range events { for i := range events {
e, ok := events[i].(*PostEvent) e, ok := events[i].(*PostEvent)
if !ok { if !ok {
continue continue
} }
log.Println("send", e.String()) span.AddEvent(fmt.Sprint("send", i, e.String()))
var b bytes.Buffer var b bytes.Buffer
if err = encodeJSON(&b, first, e); err != nil { if err = encodeJSON(&b, first, e); err != nil {
log.Print(err) span.RecordError(err)
} }
err = c.WriteMessage(websocket.TextMessage, b.Bytes()) err = c.WriteMessage(websocket.TextMessage, b.Bytes())
if err != nil { if err != nil {
log.Println("write:", err) span.RecordError(err)
break break
} }
} }