diff --git a/Makefile b/Makefile index c0bbfa2..d53e378 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,7 @@ run/local-dynamo: .PHONY: run/tests run/tests: - go test ./... -cover + go test ./... -cover -race .PHONY: run/lint run/lint: diff --git a/go.mod b/go.mod index 87dc220..c9981b2 100644 --- a/go.mod +++ b/go.mod @@ -1,45 +1,51 @@ module github.com/jdpx/mind-hub-api -go 1.15 +go 1.16 require ( github.com/99designs/gqlgen v0.13.0 - github.com/aws/aws-lambda-go v1.18.0 - github.com/aws/aws-sdk-go v1.35.19 - github.com/aws/aws-sdk-go-v2 v1.0.0 - github.com/aws/aws-sdk-go-v2/config v1.0.0 - github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.0.0 - github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression v1.0.0 - github.com/aws/aws-sdk-go-v2/service/dynamodb v1.0.0 - github.com/awslabs/aws-lambda-go-api-proxy v0.8.1 + github.com/agnivade/levenshtein v1.1.0 // indirect + github.com/aws/aws-lambda-go v1.23.0 + github.com/aws/aws-sdk-go-v2 v1.4.0 + github.com/aws/aws-sdk-go-v2/config v1.1.7 + github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.0.7 + github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression v1.0.7 + github.com/aws/aws-sdk-go-v2/service/dynamodb v1.2.3 + github.com/awslabs/aws-lambda-go-api-proxy v0.10.0 github.com/corpix/uarand v0.1.1 // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/gin-contrib/cors v1.3.1 - github.com/gin-gonic/gin v1.6.3 + github.com/gin-gonic/gin v1.7.1 github.com/gofrs/uuid v3.3.0+incompatible github.com/golang/mock v1.4.4 github.com/golang/protobuf v1.4.3 // indirect github.com/google/uuid v1.1.2 github.com/gorilla/websocket v1.4.2 - github.com/hashicorp/golang-lru v0.5.1 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428 - github.com/json-iterator/go v1.1.10 // indirect github.com/kelseyhightower/envconfig v1.4.0 github.com/labstack/gommon v0.3.0 github.com/machinebox/graphql v0.2.2 github.com/matryer/is v1.4.0 // indirect - github.com/mitchellh/mapstructure v1.1.2 - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.1 // indirect + github.com/matryer/moq v0.2.1 // indirect + github.com/mitchellh/mapstructure v1.4.1 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/onsi/ginkgo v1.14.1 // indirect github.com/onsi/gomega v1.10.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/segmentio/ksuid v1.0.3 - github.com/sirupsen/logrus v1.7.0 + github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.6.1 + github.com/urfave/cli/v2 v2.3.0 // indirect + github.com/vektah/dataloaden v0.3.0 // indirect github.com/vektah/gqlparser/v2 v2.1.0 - golang.org/x/net v0.0.0-20200625001655-4c5254603344 // indirect - golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e // indirect + golang.org/x/mod v0.4.2 // indirect + golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect + golang.org/x/sys v0.0.0-20210507161434-a76c4d0a0096 // indirect golang.org/x/text v0.3.4 // indirect + golang.org/x/tools v0.1.0 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 0e8333b..5abc729 100644 --- a/go.sum +++ b/go.sum @@ -1,87 +1,139 @@ +cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/99designs/gqlgen v0.13.0 h1:haLTcUp3Vwp80xMVEg5KRNwzfUrgFdRmtBY8fuB8scA= github.com/99designs/gqlgen v0.13.0/go.mod h1:NV130r6f4tpRWuAI+zsrSdooO/eWUv+Gyyoi3rEfXIk= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9 h1:HD8gA2tkByhMAwYaFAX9w2l7vxvBQ5NMoxDrkhqhtn4= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= +github.com/CloudyKit/jet/v3 v3.0.0 h1:1PwO5w5VCtlUUl+KTOBsTGZlhjWkcybsGaAau52tOy8= github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/Joker/hpp v1.0.0 h1:65+iuJYdRXv/XyN62C1uEmmOx3432rNG/rKlX6V7Kkc= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/Masterminds/glide v0.13.2 h1:M5MOH04TyRiMBVeWHbifqTpnauxWINIubTCOkhXh+2g= github.com/Masterminds/glide v0.13.2/go.mod h1:STyF5vcenH/rUqTEv+/hBXlSTo7KYwg2oc2f4tzPWic= +github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/vcs v1.13.0 h1:USF5TvZGYgIpcbNAEMLfFhHqP08tFZVlUVrmTSpqnyA= github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398 h1:WDC6ySpJzbxGWFh4aMxFFC28wwGp5pEuoTtvA4q/qQ4= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= -github.com/agnivade/levenshtein v1.0.3 h1:M5ZnqLOoZR8ygVq0FfkXsNOKzMCk0xRiow0R5+5VkQ0= github.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6ie5efyrwRJXs= +github.com/agnivade/levenshtein v1.1.0 h1:n6qGwyHG61v3ABce1rPVZklEYRT8NFpCMrpZdBUbYGM= +github.com/agnivade/levenshtein v1.1.0/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= +github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= +github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/aws/aws-lambda-go v1.18.0 h1:13AfxzFoPlFjOzXHbRnKuTbteCzHbu4YQgKONNhWcmo= -github.com/aws/aws-lambda-go v1.18.0/go.mod h1:FEwgPLE6+8wcGBTe5cJN3JWurd1Ztm9zN4jsXsjzKKw= -github.com/aws/aws-sdk-go v1.35.19 h1:vdIqQnOIqTNtvnOdt9r3Bf/FiCJ7KV/7O2BIj4TPx2w= -github.com/aws/aws-sdk-go v1.35.19/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k= -github.com/aws/aws-sdk-go-v2 v1.0.0 h1:ncEVPoHArsG+HjoDe/3ex/TG1CbLwMQ4eaWj0UGdyTo= -github.com/aws/aws-sdk-go-v2 v1.0.0/go.mod h1:smfAbmpW+tcRVuNUjo3MOArSZmW72t62rkCzc2i0TWM= -github.com/aws/aws-sdk-go-v2/config v1.0.0 h1:x6vSFAwqAvhYPeSu60f0ZUlGHo3PKKmwDOTL8aMXtv4= -github.com/aws/aws-sdk-go-v2/config v1.0.0/go.mod h1:WysE/OpUgE37tjtmtJd8GXgT8s1euilE5XtUkRNUQ1w= -github.com/aws/aws-sdk-go-v2/credentials v1.0.0 h1:0M7netgZ8gCV4v7z1km+Fbl7j6KQYyZL7SS0/l5Jn/4= -github.com/aws/aws-sdk-go-v2/credentials v1.0.0/go.mod h1:/SvsiqBf509hG4Bddigr3NB12MIpfHhZapyBurJe8aY= -github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.0.0 h1:HLQFcEH7jGzJ8iQDfjSEzhYNwawL/0TTI86b3cht/Ec= -github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.0.0/go.mod h1:kekXWCq5z+Fo7rbx0Caha8cxX4L37a+lKZjCYyJyNoc= -github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression v1.0.0 h1:pRO/FYfb3SFK9m6xYWWkN6nj9P0O2qUjuCEizzAT5kQ= -github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression v1.0.0/go.mod h1:uEe1RCl1/C/1JETRqDaDLtMqYV0mVFD4ls2mixt5Ii0= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.0 h1:lO7fH5n7Q1dKcDBpuTmwJylD1bOQiRig8LI6TD9yVQk= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.0/go.mod h1:wpMHDCXvOXZxGCRSidyepa8uJHY4vaBGfY2/+oKU/Bc= -github.com/aws/aws-sdk-go-v2/service/dynamodb v1.0.0 h1:F6OpC3nMScEMLxQfmbae/6sgrAH66SXrgsjpAMQSunI= -github.com/aws/aws-sdk-go-v2/service/dynamodb v1.0.0/go.mod h1:Z50tE5Lvf3Wd7IQw/+GUdqYBm/TLyZUQAStEmkrY4JY= -github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.0.0 h1:PWl71Yx4FslKU3eKfseaUxEED1F46LowU0HCzrrFO18= -github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.0.0/go.mod h1:CVMIQpkn3+FSi9D6VMY4rl9lLj1wISjfYDzc5Rq6PYw= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.0.0 h1:jjZzz89+Uii7XKlgWXNHiLVtJfvCG8oVoMLpiWsjnt8= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.0.0/go.mod h1:cZbnzYflIuoRkuKp4BB4q/R4xklYIwpLYs26vS3/Sac= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.0 h1:IAutMPSrynpvKOpHG6HyWHmh1xmxWAmYOK84NrQVqVQ= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.0/go.mod h1:3jExOmpbjgPnz2FJaMOfbSk1heTkZ66aD3yNtVhnjvI= -github.com/aws/aws-sdk-go-v2/service/sts v1.0.0 h1:6XCgxNfE4L/Fnq+InhVNd16DKc6Ue1f3dJl3IwwJRUQ= -github.com/aws/aws-sdk-go-v2/service/sts v1.0.0/go.mod h1:5f+cELGATgill5Pu3/vK3Ebuigstc+qYEHW5MvGWZO4= -github.com/aws/smithy-go v1.0.0 h1:hkhcRKG9rJ4Fn+RbfXY7Tz7b3ITLDyolBnLLBhwbg/c= -github.com/aws/smithy-go v1.0.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= -github.com/awslabs/aws-lambda-go-api-proxy v0.8.1 h1:eA84rP3SBorVVuvMrpgzWzxot5bAG4mX4N+On6NQCdo= -github.com/awslabs/aws-lambda-go-api-proxy v0.8.1/go.mod h1:V3jj7BZnRY8y2QTKSABIwBc+dTjPkX7vLxz61Id7vsQ= +github.com/aws/aws-lambda-go v1.19.1/go.mod h1:jJmlefzPfGnckuHdXX7/80O3BvUUi12XOkbv4w9SGLU= +github.com/aws/aws-lambda-go v1.23.0 h1:Vjwow5COkFJp7GePkk9kjAo/DyX36b7wVPKwseQZbRo= +github.com/aws/aws-lambda-go v1.23.0/go.mod h1:jJmlefzPfGnckuHdXX7/80O3BvUUi12XOkbv4w9SGLU= +github.com/aws/aws-sdk-go-v2 v1.4.0 h1:Ryh4fNebT9SwLyCKPSk83dyEZj+KB6KzDyb1gXii7EI= +github.com/aws/aws-sdk-go-v2 v1.4.0/go.mod h1:tI4KhsR5VkzlUa2DZAdwx7wCAYGwkZZ1H31PYrBFx1w= +github.com/aws/aws-sdk-go-v2/config v1.1.7 h1:I9AsaodDiw1WbUBn8b4Ktvr2ltPBe7QfLq4UUZY4GsY= +github.com/aws/aws-sdk-go-v2/config v1.1.7/go.mod h1:6GFyKv06rDCBCIOmWe9vLi7ofCkE7y8aqI6a3tFWNQ0= +github.com/aws/aws-sdk-go-v2/credentials v1.1.7 h1:hpg13GGT/j7Zv+xkJ+0p2Pj1NvnRSNIX1XI4WI02kq8= +github.com/aws/aws-sdk-go-v2/credentials v1.1.7/go.mod h1:xYCvIyeVCRC9DmG3Zv/pxlZEEIBYf4fY/jSUVSrr58M= +github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.0.7 h1:Jvros5/MHD7+2C8S8wFzykZVVYs+9ileat8Qp3nLQrs= +github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.0.7/go.mod h1:tQAFdpPneQOzvc2Q6jE69WNV4pORhwcj1y1GdyTGjdk= +github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression v1.0.7 h1:pGENbLNjeQ8Vbfl9gUJUJ/8wPRpCncb8xviapptTorA= +github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression v1.0.7/go.mod h1:ARtLt6NwjmlIotvoyB0dtesYLP8IBpxubwJdQiAjOZI= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.7 h1:WdPPgbL9Kl4UrEdiy6IdQioPuXSBg8HJcU9eihiCWOE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.7/go.mod h1:51hY5nMAiL2EF8ny/pFovWYoKZTcEfOw0WWKcq2E9AQ= +github.com/aws/aws-sdk-go-v2/service/dynamodb v1.2.3 h1:6riWCax3yf7BfWeqnrJb1b50X/qO8nYhqLefVWNdUbc= +github.com/aws/aws-sdk-go-v2/service/dynamodb v1.2.3/go.mod h1:KDrhOqQxtJ4F2wKeF43BS15LZgG5Zx4V1BuUIhPanCc= +github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.1.6 h1:BCnc1qu4PCA1NgQ9jK/nykU5U3J0VND2gH8xwbb/4Ek= +github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.1.6/go.mod h1:LYwl/0iiaro37VjlsnhpjSQ4KeoUkZSEU21qb3hmS5A= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.0.5 h1:+mt5yscnvgVX40gMh4vzZL6DEvwBeG+FQ6Pod+mjBzE= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.0.5/go.mod h1:zdjOOy0ojUn3iNELo6ycIHSMCp4xUbycSHfb8PnbbyM= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.7 h1:/XUEk2eY/QGzCHSX5LH4vp+UMKTSVVCroUfgkzPGIzE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.7/go.mod h1:Fl3kxN4ucBIPuAHKHRn+wTGylFzMCEjRfmfHqZuEh8o= +github.com/aws/aws-sdk-go-v2/service/sso v1.1.6 h1:oS6Jdb6ZwD7U1OqJYqyGbgcU0VJ15E3XbiIIp0clge8= +github.com/aws/aws-sdk-go-v2/service/sso v1.1.6/go.mod h1:EO4s+JzAllrWKgNjS/Q4mj43vGimSvhWCB6BLognegc= +github.com/aws/aws-sdk-go-v2/service/sts v1.3.1 h1:tAn9Kvjfq2F2rCeTbMOLtDBQVjLLSIvm21BTUFoswss= +github.com/aws/aws-sdk-go-v2/service/sts v1.3.1/go.mod h1:QPpnumNNgybBiz3HXGgDRf/QypAMOOsh4+JdOhG5mLU= +github.com/aws/smithy-go v1.4.0 h1:3rsQpgRe+OoQgJhEwGNpIkosl0fJLdmQqF4gSFRjg+4= +github.com/aws/smithy-go v1.4.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= +github.com/awslabs/aws-lambda-go-api-proxy v0.10.0 h1:rLxq/wv26VgVQT/dFmeMoCdkjH79u/S1LtbdL6vkzNg= +github.com/awslabs/aws-lambda-go-api-proxy v0.10.0/go.mod h1:O8jHVv+ga5Kpg8+6i8qSZFp9rnxC1KB/R2yNFNgtFis= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= +github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible h1:Ppm0npCCsmuR9oQaBtRuZcmILVE74aXE+AmrJj8L2ns= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= +github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/chris-ramon/douceur v0.2.0 h1:IDMEdxlEUUBYBKE4z/mJnFyVXox+MjuEVDJNN27glkU= +github.com/chris-ramon/douceur v0.2.0/go.mod h1:wDW5xjJdeoMm1mRt4sD4c/LbF/mWdEpRXQKjTR8nIBE= +github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/codegangsta/cli v1.20.0 h1:iX1FXEgwzd5+XN6wk5cVHOGQj6Q3Dcp20lUeS4lHNTw= github.com/codegangsta/cli v1.20.0/go.mod h1:/qJNoX69yVSKu5o4jLyXAENLRyk1uhi7zkbQ3slBdOA= +github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible h1:bXhRBIXoTm9BYHS3gE0TtQuyNZyeEMux2sDi4oo5YOo= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/corpix/uarand v0.1.1 h1:RMr1TWc9F4n5jiPDzFHtmaUXLKLNUFK0SgCLo4BhX/U= github.com/corpix/uarand v0.1.1/go.mod h1:SFKZvkcRoLqVRFZ4u25xPmp6m9ktANfbpXZ7SJ0/FNU= +github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.6.0 h1:DshxFxZWXUcO0xX476VJC07Xsr6ZCBVRHKZ93Oh7Evo= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c h1:TUuUh0Xgj97tLMNtWtNvI9mIV6isjEb9lBMNv+77IGM= github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= +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/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473 h1:4cmBvAEBNJaGARUEs3/suWRyfyBfhf7I60WBZq+bv2w= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/etcd-io/bbolt v1.3.3 h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 h1:DddqAaWDpywytcG8w/qoQ5sAN8X12d3Z3koB0C3Rxsc= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= 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/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/gavv/httpexpect v2.0.0+incompatible h1:1X9kcRshkSKEjNJJxX9Y9mQ5BRfbxU5kORdjhlA1yX8= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gin-contrib/cors v1.3.1 h1:doAsuITavI4IOcd0Y19U4B+O0dNWihRyX//nn4sEmgA= github.com/gin-contrib/cors v1.3.1/go.mod h1:jjEJ4268OPZUcU7k9Pm653S7lXUGcqMADzFA61xsmDk= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= -github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.7.1 h1:qC89GU3p8TvKWMAVhEpmpB2CIb1hnqt2UdKZaP93mS8= +github.com/gin-gonic/gin v1.7.1/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-chi/chi v3.3.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -91,14 +143,25 @@ github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTM github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.3.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/gofiber/fiber/v2 v2.1.0 h1:gvEQJDxVHFLY4bNb4HSu7nqVWeLeXry8P4tA4zPKfhQ= +github.com/gofiber/fiber/v2 v2.1.0/go.mod h1:aG+lMkwy3LyVit4CnmYUbUdgjpc3UYOltvlJZ78rgQ0= github.com/gofrs/uuid v3.3.0+incompatible h1:8K4tyRfvU1CYPgJsveYFQMhpFd/wXNM7iK6rR7UHz84= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.0.0 h1:2jyBKDKU/8v3v2xVR2PtiWQviFUyiaGk2rpfyFT8rTM= github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -110,38 +173,61 @@ github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:x github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38 h1:y0Wmhvml7cGnzPa9nocn/fMraMH/lMDdeG+rkx4VgYY= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f h1:9oNbS1z4rVpbnkHBdPZU4jo9bSmrLpII768arSyMFgk= github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= +github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428 h1:Mo9W14pwbO9VfRe+ygqZ8dFbPpoIK1HFrG/zjTuQ+nc= github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428/go.mod h1:uhpZMVGznybq1itEKXj6RYw9I71qK4kH+OGMjRC4KEo= +github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/iris-contrib/blackfriday v2.0.0+incompatible h1:o5sHQHHm0ToHUlAJSTjW9UWicjJSDDauOOQ2AHuIVp4= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible h1:XZubAYg61/JwnJNbZilGjf3b3pB80+OQg2qf6c8BfWE= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/jade v1.1.3 h1:p7J/50I0cjo0wq/VWVCDFd8taPJbuFC+bq23SniRFX0= github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= +github.com/iris-contrib/pongo2 v0.0.1 h1:zGP7pW51oi5eQZMIlGA3I+FHY9/HOQWDB+572yin0to= github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= +github.com/iris-contrib/schema v0.0.1 h1:10g/WnoRR+U+XXHWKBHeNy/+tZmM2kcAVGLOsz+yaDA= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -151,56 +237,91 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= +github.com/kataras/golog v0.0.18 h1:Td7hcKN25yzqB/0SO5iohOsMk5Mq5V9kDtM5apaJLY0= +github.com/kataras/golog v0.0.18/go.mod h1:jRYl7dFYqP8aQj9VkwdBUXYZSfUktm+YYg1arJILfyw= +github.com/kataras/iris/v12 v12.1.8 h1:O3gJasjm7ZxpxwTH8tApZsvf274scSGQAUpNe47c37U= github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= +github.com/kataras/neffos v0.0.14 h1:pdJaTvUG3NQfeMbbVCI8JT2T5goPldyyfUB2PJfh1Bs= github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= +github.com/kataras/pio v0.0.8 h1:6pX6nHJk7DAV3x1dEimibQF2CmJLlo0jWVmM9yE9KY8= +github.com/kataras/pio v0.0.8/go.mod h1:NFfMp2kVP1rmV4N6gH6qgWpuoDKlrOeYi3VrAIWCGsE= +github.com/kataras/sitemap v0.0.5 h1:4HCONX5RLgVy6G4RkYOV3vKNcma9p236LdGOipJsaFE= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.1 h1:bPb7nMRdOZYDrpPMTA3EInUQrdgoBinqUuSwlGdKDdE= +github.com/klauspost/compress v1.11.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/labstack/echo/v4 v4.1.16/go.mod h1:awO+5TzAjvL8XpibdsfXxPgHr+orhtXZJZIQCVjogKI= +github.com/labstack/echo/v4 v4.1.17 h1:PQIBaRplyRy3OjwILGkPg89JRtH2x5bssi59G2EL3fo= +github.com/labstack/echo/v4 v4.1.17/go.mod h1:Tn2yRQL/UclUalpb5rPdXDevbkJ+lp/2svdyFBg6CHQ= github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 h1:bqDmpDG49ZRnB5PcgP0RXtQvnMSgIF14M7CBd2shtXs= github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/machinebox/graphql v0.2.2 h1:dWKpJligYKhYKO5A2gvNhkJdQMNZeChZYyBbrZkBZfo= github.com/machinebox/graphql v0.2.2/go.mod h1:F+kbVMHuwrQ5tYgU9JXlnskM8nOaFxCAEolaQybkjWA= +github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/matryer/moq v0.2.1 h1:4roNlIsfEXb7127O3v558H+9jmV70G2FAJPYIZX84lQ= +github.com/matryer/moq v0.2.1/go.mod h1:9RtPYjTnH1bSBIkpvtHkFN7nbWAnO7oRpdJkEIn6UtE= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/goveralls v0.0.2 h1:7eJB6EqsPhRVxvwEXGnqdO2sJI0PTsrWoTMXEk9/OQc= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/mediocregopher/radix/v3 v3.4.2 h1:galbPBjIwmyREgwGCfQEN4X8lxbJnKBYurgz+VfcStA= github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/microcosm-cc/bluemonday v1.0.3 h1:EjVH7OqbU219kdm8acbveoclh2zZFqPJTJw6VUlTLAQ= +github.com/microcosm-cc/bluemonday v1.0.3/go.mod h1:8iwZnFn2CDDNZ0r6UXhF4xawGvzaqzCRa1n3/lO3W2w= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= +github.com/nats-io/jwt v0.3.0 h1:xdnzwFETV++jNc4W1mw//qFyJGb2ABOombmZJQS4+Qo= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/nats.go v1.9.1 h1:ik3HbLhZ0YABLto7iX80pZLPw/6dx3T+++MZJwLnMrQ= github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0 h1:qMd4+pRHgdr1nAClu+2h/2a5F2TmKcCzjCDazVgRoX4= github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/ngdinhtoan/glide-cleanup v0.2.0 h1:kN4sV+0tp2F1BvwU+5SfNRMDndRmvIfnI3kZ7B8Yv4Y= github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -208,40 +329,66 @@ github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4= github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/opentracing/basictracer-go v1.0.0 h1:YyUAhaEfjoWXclZVJ9sGoNct7j4TVk7lZWlQw5UXuoo= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI= github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v2.1.0+incompatible h1:j1Wcmh8OrK4Q7GXY+V7SVSY8nUWQxHW5TkBe7YUl+2s= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/segmentio/ksuid v1.0.3 h1:FoResxvleQwYiPAVKe1tMUlEirodZqlqglIuFsdDntY= github.com/segmentio/ksuid v1.0.3/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371 h1:SWV2fHctRpRrp49VXJ6UZja7gU9QLHwRpIPBN89SKEo= github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0 h1:JJV9CsgM9EC9w2iVkwuz+sMx8yRFe89PJRUrv6hPCIA= github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= -github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -255,39 +402,90 @@ github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljT github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.16.0 h1:9zAqOYLl8Tuy3E5R6ckzGDJ1g8+pw15oQp2iL9Jl6gQ= +github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4= -github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U= +github.com/vektah/dataloaden v0.3.0 h1:ZfVN2QD6swgvp+tDqdH/OIT/wu3Dhu0cus0k5gIZS84= +github.com/vektah/dataloaden v0.3.0/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U= github.com/vektah/gqlparser/v2 v2.1.0 h1:uiKJ+T5HMGGQM2kRKQ8Pxw8+Zq9qhhZhz/lieYvCMns= github.com/vektah/gqlparser/v2 v2.1.0/go.mod h1:SyUiHgLATUR8BiYURfTirrTcGpcE+4XkV2se04Px1Ms= +github.com/vektah/gqlparser/v2 v2.2.0 h1:bAc3slekAAJW6sZTi07aGq0OrfaCjj4jxARAaC7g2EM= +github.com/vektah/gqlparser/v2 v2.2.0/go.mod h1:i3mQIGIrbK2PD1RrCeMTlVbkF2FJ6WkU1KJlJlC+3F4= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4 h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -303,48 +501,93 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e h1:AyodaIpKjppX+cBfTASF2E1US3H2JFBj920Ot3rtDjs= -golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201016160150-f659759dc4ca/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210507161434-a76c4d0a0096 h1:5PbJGn5Sp3GEUjJ61aYbUP6RIo3Z3r2E4Tv9y2z8UHo= +golang.org/x/sys v0.0.0-20210507161434-a76c4d0a0096/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200815165600-90abf76919f3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 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-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc= gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= +gopkg.in/ini.v1 v1.51.1 h1:GyboHr4UqMiLUybYjd22ZjQIKEJEpgtLXtuGbR21Oho= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce h1:xcEWjVhvbDy+nHP67nPDDpbYrY+ILlfndk4bRioVHaU= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +sourcegraph.com/sourcegraph/appdash v0.0.0-20180110180208-2cc67fd64755 h1:d2maSb13hr/ArmfK3rW+wNUKKfytCol7W1/vDHxMPiE= sourcegraph.com/sourcegraph/appdash v0.0.0-20180110180208-2cc67fd64755/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= +sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 h1:e1sMhtVq9AfcEy8AXNb8eSg6gbzfdpYhoNqnPJa+GzI= sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67/go.mod h1:L5q+DGLGOQFpo1snNEkLOJT2d1YTW66rWNzatr3He1k= diff --git a/gqlgen.yml b/gqlgen.yml index 166574f..618b0b5 100644 --- a/gqlgen.yml +++ b/gqlgen.yml @@ -66,6 +66,8 @@ models: resolver: true note: resolver: true + timemaps: + resolver: true Step: fields: progress: diff --git a/pkg/graphcms/mocks/resolvers.go b/pkg/graphcms/mocks/resolvers.go index 317032f..3fa5c89 100644 --- a/pkg/graphcms/mocks/resolvers.go +++ b/pkg/graphcms/mocks/resolvers.go @@ -112,7 +112,7 @@ func (mr *MockCMSResolverMockRecorder) GetStepIDsByCourseID(ctx, id interface{}) // GetStepsByID mocks base method func (m *MockCMSResolver) GetStepsByID(ctx context.Context, id string) (*graphcms.Step, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStepsBySessionID", ctx, id) + ret := m.ctrl.Call(m, "GetStepsByID", ctx, id) ret0, _ := ret[0].(*graphcms.Step) ret1, _ := ret[1].(error) return ret0, ret1 @@ -121,5 +121,5 @@ func (m *MockCMSResolver) GetStepsByID(ctx context.Context, id string) (*graphcm // GetStepsByID indicates an expected call of GetStepsByID func (mr *MockCMSResolverMockRecorder) GetStepsByID(ctx, id interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStepsBySessionID", reflect.TypeOf((*MockCMSResolver)(nil).GetStepsByID), ctx, id) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStepsByID", reflect.TypeOf((*MockCMSResolver)(nil).GetStepsByID), ctx, id) } diff --git a/pkg/graphql/generated/generated.go b/pkg/graphql/generated/generated.go index 10d601b..f9e0b25 100644 --- a/pkg/graphql/generated/generated.go +++ b/pkg/graphql/generated/generated.go @@ -54,6 +54,7 @@ type ComplexityRoot struct { SessionCount func(childComplexity int) int Sessions func(childComplexity int) int StepCount func(childComplexity int) int + Timemaps func(childComplexity int) int Title func(childComplexity int) int } @@ -86,7 +87,8 @@ type ComplexityRoot struct { Session func(childComplexity int, where model.SessionQuery) int SessionsByCourseID func(childComplexity int, where model.SessionsByCourseIDQuery) int Step func(childComplexity int, where model.StepQuery) int - Timemap func(childComplexity int) int + Timemap func(childComplexity int, where model.TimemapQuery) int + TimemapsByCourseID func(childComplexity int, where model.TimemapsByCourseIDQuery) int } Session struct { @@ -125,6 +127,7 @@ type ComplexityRoot struct { } Timemap struct { + Course func(childComplexity int) int ID func(childComplexity int) int Map func(childComplexity int) int UpdatedAt func(childComplexity int) int @@ -138,6 +141,7 @@ type CourseResolver interface { Sessions(ctx context.Context, obj *model.Course) ([]*model.Session, error) Note(ctx context.Context, obj *model.Course) (*model.CourseNote, error) Progress(ctx context.Context, obj *model.Course) (*model.CourseProgress, error) + Timemaps(ctx context.Context, obj *model.Course) ([]*model.Timemap, error) } type MutationResolver interface { CourseStarted(ctx context.Context, input model.CourseStarted) (*model.Course, error) @@ -153,7 +157,8 @@ type QueryResolver interface { Session(ctx context.Context, where model.SessionQuery) (*model.Session, error) Step(ctx context.Context, where model.StepQuery) (*model.Step, error) SessionsByCourseID(ctx context.Context, where model.SessionsByCourseIDQuery) ([]*model.Session, error) - Timemap(ctx context.Context) (*model.Timemap, error) + Timemap(ctx context.Context, where model.TimemapQuery) (*model.Timemap, error) + TimemapsByCourseID(ctx context.Context, where model.TimemapsByCourseIDQuery) ([]*model.Timemap, error) } type StepResolver interface { Note(ctx context.Context, obj *model.Step) (*model.StepNote, error) @@ -231,6 +236,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Course.StepCount(childComplexity), true + case "Course.timemaps": + if e.complexity.Course.Timemaps == nil { + break + } + + return e.complexity.Course.Timemaps(childComplexity), true + case "Course.title": if e.complexity.Course.Title == nil { break @@ -426,7 +438,24 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in break } - return e.complexity.Query.Timemap(childComplexity), true + args, err := ec.field_Query_timemap_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Timemap(childComplexity, args["where"].(model.TimemapQuery)), true + + case "Query.timemapsByCourseID": + if e.complexity.Query.TimemapsByCourseID == nil { + break + } + + args, err := ec.field_Query_timemapsByCourseID_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.TimemapsByCourseID(childComplexity, args["where"].(model.TimemapsByCourseIDQuery)), true case "Session.course": if e.complexity.Session.Course == nil { @@ -589,6 +618,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.StepProgress.State(childComplexity), true + case "Timemap.course": + if e.complexity.Timemap.Course == nil { + break + } + + return e.complexity.Timemap.Course(childComplexity), true + case "Timemap.id": if e.complexity.Timemap.ID == nil { break @@ -690,6 +726,7 @@ type Course { note: CourseNote progress: CourseProgress + timemaps: [Timemap]! } type Session { @@ -699,7 +736,6 @@ type Session { steps: [Step] course: Course! - # progress: SessionProgress } type Step { @@ -723,11 +759,6 @@ type CourseProgress { dateStarted: String! } -# type SessionProgress { -# id: ID! -# dateStarted: String! -# } - type StepProgress { id: ID! state: String! @@ -739,6 +770,8 @@ type Timemap { id: ID! map: String! updatedAt: String! + + course: Course! } input CourseQuery { @@ -757,6 +790,15 @@ input StepQuery { id: ID! } +input TimemapQuery { + id: ID! + courseID: ID! +} + +input TimemapsByCourseIDQuery { + id: ID! +} + type CourseNote { id: ID! courseID: ID! @@ -778,7 +820,8 @@ type Query { session(where: SessionQuery!): Session step(where: StepQuery!): Step sessionsByCourseID(where: SessionsByCourseIDQuery!): [Session] - timemap: Timemap + timemap(where: TimemapQuery!): Timemap + timemapsByCourseID(where: TimemapsByCourseIDQuery!): [Timemap] } input CourseStarted { @@ -806,6 +849,8 @@ input UpdatedStepNote { } input UpdatedTimemap { + id: ID + courseID: ID! map: String! } @@ -991,6 +1036,36 @@ func (ec *executionContext) field_Query_step_args(ctx context.Context, rawArgs m return args, nil } +func (ec *executionContext) field_Query_timemap_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 model.TimemapQuery + if tmp, ok := rawArgs["where"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("where")) + arg0, err = ec.unmarshalNTimemapQuery2githubᚗcomᚋjdpxᚋmindᚑhubᚑapiᚋpkgᚋgraphqlᚋmodelᚐTimemapQuery(ctx, tmp) + if err != nil { + return nil, err + } + } + args["where"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_timemapsByCourseID_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 model.TimemapsByCourseIDQuery + if tmp, ok := rawArgs["where"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("where")) + arg0, err = ec.unmarshalNTimemapsByCourseIDQuery2githubᚗcomᚋjdpxᚋmindᚑhubᚑapiᚋpkgᚋgraphqlᚋmodelᚐTimemapsByCourseIDQuery(ctx, tmp) + if err != nil { + return nil, err + } + } + args["where"] = arg0 + return args, nil +} + func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -1335,6 +1410,41 @@ func (ec *executionContext) _Course_progress(ctx context.Context, field graphql. return ec.marshalOCourseProgress2ᚖgithubᚗcomᚋjdpxᚋmindᚑhubᚑapiᚋpkgᚋgraphqlᚋmodelᚐCourseProgress(ctx, field.Selections, res) } +func (ec *executionContext) _Course_timemaps(ctx context.Context, field graphql.CollectedField, obj *model.Course) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Course", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Course().Timemaps(rctx, obj) + }) + 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.([]*model.Timemap) + fc.Result = res + return ec.marshalNTimemap2ᚕᚖgithubᚗcomᚋjdpxᚋmindᚑhubᚑapiᚋpkgᚋgraphqlᚋmodelᚐTimemap(ctx, field.Selections, res) +} + func (ec *executionContext) _CourseNote_id(ctx context.Context, field graphql.CollectedField, obj *model.CourseNote) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -2074,9 +2184,16 @@ func (ec *executionContext) _Query_timemap(ctx context.Context, field graphql.Co } ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_timemap_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().Timemap(rctx) + return ec.resolvers.Query().Timemap(rctx, args["where"].(model.TimemapQuery)) }) if err != nil { ec.Error(ctx, err) @@ -2090,6 +2207,45 @@ func (ec *executionContext) _Query_timemap(ctx context.Context, field graphql.Co return ec.marshalOTimemap2ᚖgithubᚗcomᚋjdpxᚋmindᚑhubᚑapiᚋpkgᚋgraphqlᚋmodelᚐTimemap(ctx, field.Selections, res) } +func (ec *executionContext) _Query_timemapsByCourseID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_timemapsByCourseID_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().TimemapsByCourseID(rctx, args["where"].(model.TimemapsByCourseIDQuery)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*model.Timemap) + fc.Result = res + return ec.marshalOTimemap2ᚕᚖgithubᚗcomᚋjdpxᚋmindᚑhubᚑapiᚋpkgᚋgraphqlᚋmodelᚐTimemap(ctx, field.Selections, res) +} + func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -3053,6 +3209,41 @@ func (ec *executionContext) _Timemap_updatedAt(ctx context.Context, field graphq return ec.marshalNString2string(ctx, field.Selections, res) } +func (ec *executionContext) _Timemap_course(ctx context.Context, field graphql.CollectedField, obj *model.Timemap) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Timemap", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Course, 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.(*model.Course) + fc.Result = res + return ec.marshalNCourse2ᚖgithubᚗcomᚋjdpxᚋmindᚑhubᚑapiᚋpkgᚋgraphqlᚋmodelᚐCourse(ctx, field.Selections, res) +} + func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -4280,6 +4471,54 @@ func (ec *executionContext) unmarshalInputStepStarted(ctx context.Context, obj i return it, nil } +func (ec *executionContext) unmarshalInputTimemapQuery(ctx context.Context, obj interface{}) (model.TimemapQuery, error) { + var it model.TimemapQuery + var asMap = obj.(map[string]interface{}) + + for k, v := range asMap { + switch k { + case "id": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + it.ID, err = ec.unmarshalNID2string(ctx, v) + if err != nil { + return it, err + } + case "courseID": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("courseID")) + it.CourseID, err = ec.unmarshalNID2string(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputTimemapsByCourseIDQuery(ctx context.Context, obj interface{}) (model.TimemapsByCourseIDQuery, error) { + var it model.TimemapsByCourseIDQuery + var asMap = obj.(map[string]interface{}) + + for k, v := range asMap { + switch k { + case "id": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + it.ID, err = ec.unmarshalNID2string(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputUpdatedCourseNote(ctx context.Context, obj interface{}) (model.UpdatedCourseNote, error) { var it model.UpdatedCourseNote var asMap = obj.(map[string]interface{}) @@ -4358,6 +4597,22 @@ func (ec *executionContext) unmarshalInputUpdatedTimemap(ctx context.Context, ob for k, v := range asMap { switch k { + case "id": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + it.ID, err = ec.unmarshalOID2ᚖstring(ctx, v) + if err != nil { + return it, err + } + case "courseID": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("courseID")) + it.CourseID, err = ec.unmarshalNID2string(ctx, v) + if err != nil { + return it, err + } case "map": var err error @@ -4472,6 +4727,20 @@ func (ec *executionContext) _Course(ctx context.Context, sel ast.SelectionSet, o res = ec._Course_progress(ctx, field, obj) return res }) + case "timemaps": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Course_timemaps(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -4707,6 +4976,17 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr res = ec._Query_timemap(ctx, field) return res }) + case "timemapsByCourseID": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_timemapsByCourseID(ctx, field) + return res + }) case "__type": out.Values[i] = ec._Query___type(ctx, field) case "__schema": @@ -4951,6 +5231,11 @@ func (ec *executionContext) _Timemap(ctx context.Context, sel ast.SelectionSet, if out.Values[i] == graphql.Null { invalids++ } + case "course": + out.Values[i] = ec._Timemap_course(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -5418,6 +5703,43 @@ func (ec *executionContext) marshalNTimemap2githubᚗcomᚋjdpxᚋmindᚑhubᚑa return ec._Timemap(ctx, sel, &v) } +func (ec *executionContext) marshalNTimemap2ᚕᚖgithubᚗcomᚋjdpxᚋmindᚑhubᚑapiᚋpkgᚋgraphqlᚋmodelᚐTimemap(ctx context.Context, sel ast.SelectionSet, v []*model.Timemap) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalOTimemap2ᚖgithubᚗcomᚋjdpxᚋmindᚑhubᚑapiᚋpkgᚋgraphqlᚋmodelᚐTimemap(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + return ret +} + func (ec *executionContext) marshalNTimemap2ᚖgithubᚗcomᚋjdpxᚋmindᚑhubᚑapiᚋpkgᚋgraphqlᚋmodelᚐTimemap(ctx context.Context, sel ast.SelectionSet, v *model.Timemap) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { @@ -5428,6 +5750,16 @@ func (ec *executionContext) marshalNTimemap2ᚖgithubᚗcomᚋjdpxᚋmindᚑhub return ec._Timemap(ctx, sel, v) } +func (ec *executionContext) unmarshalNTimemapQuery2githubᚗcomᚋjdpxᚋmindᚑhubᚑapiᚋpkgᚋgraphqlᚋmodelᚐTimemapQuery(ctx context.Context, v interface{}) (model.TimemapQuery, error) { + res, err := ec.unmarshalInputTimemapQuery(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalNTimemapsByCourseIDQuery2githubᚗcomᚋjdpxᚋmindᚑhubᚑapiᚋpkgᚋgraphqlᚋmodelᚐTimemapsByCourseIDQuery(ctx context.Context, v interface{}) (model.TimemapsByCourseIDQuery, error) { + res, err := ec.unmarshalInputTimemapsByCourseIDQuery(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) unmarshalNUpdatedCourseNote2githubᚗcomᚋjdpxᚋmindᚑhubᚑapiᚋpkgᚋgraphqlᚋmodelᚐUpdatedCourseNote(ctx context.Context, v interface{}) (model.UpdatedCourseNote, error) { res, err := ec.unmarshalInputUpdatedCourseNote(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -5864,6 +6196,46 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as return graphql.MarshalString(*v) } +func (ec *executionContext) marshalOTimemap2ᚕᚖgithubᚗcomᚋjdpxᚋmindᚑhubᚑapiᚋpkgᚋgraphqlᚋmodelᚐTimemap(ctx context.Context, sel ast.SelectionSet, v []*model.Timemap) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalOTimemap2ᚖgithubᚗcomᚋjdpxᚋmindᚑhubᚑapiᚋpkgᚋgraphqlᚋmodelᚐTimemap(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + return ret +} + func (ec *executionContext) marshalOTimemap2ᚖgithubᚗcomᚋjdpxᚋmindᚑhubᚑapiᚋpkgᚋgraphqlᚋmodelᚐTimemap(ctx context.Context, sel ast.SelectionSet, v *model.Timemap) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/pkg/graphql/model/models_gen.go b/pkg/graphql/model/models_gen.go index c927f6d..0ca6640 100644 --- a/pkg/graphql/model/models_gen.go +++ b/pkg/graphql/model/models_gen.go @@ -12,6 +12,7 @@ type Course struct { Sessions []*Session `json:"sessions"` Note *CourseNote `json:"note"` Progress *CourseProgress `json:"progress"` + Timemaps []*Timemap `json:"timemaps"` } type CourseNote struct { @@ -92,9 +93,19 @@ type StepStarted struct { } type Timemap struct { - ID string `json:"id"` - Map string `json:"map"` - UpdatedAt string `json:"updatedAt"` + ID string `json:"id"` + Map string `json:"map"` + UpdatedAt string `json:"updatedAt"` + Course *Course `json:"course"` +} + +type TimemapQuery struct { + ID string `json:"id"` + CourseID string `json:"courseID"` +} + +type TimemapsByCourseIDQuery struct { + ID string `json:"id"` } type UpdatedCourseNote struct { @@ -110,5 +121,7 @@ type UpdatedStepNote struct { } type UpdatedTimemap struct { - Map string `json:"map"` + ID *string `json:"id"` + CourseID string `json:"courseID"` + Map string `json:"map"` } diff --git a/pkg/graphql/responses.go b/pkg/graphql/responses.go index 58c3790..8a44dcc 100644 --- a/pkg/graphql/responses.go +++ b/pkg/graphql/responses.go @@ -5,8 +5,8 @@ import ( "github.com/jdpx/mind-hub-api/pkg/service" ) -// CourseFromCMS ... -func CourseFromCMS(gc *service.Course) *model.Course { +// CourseFromServices ... +func CourseFromServices(gc *service.Course) *model.Course { return &model.Course{ ID: gc.ID, Title: gc.Title, @@ -35,19 +35,19 @@ func CourseNoteFromService(cn *service.CourseNote) *model.CourseNote { } } -// CoursesFromCMS ... -func CoursesFromCMS(gcs []*service.Course) []*model.Course { +// CoursesFromServices ... +func CoursesFromServices(gcs []*service.Course) []*model.Course { cs := []*model.Course{} for _, gc := range gcs { - cs = append(cs, CourseFromCMS(gc)) + cs = append(cs, CourseFromServices(gc)) } return cs } -// SessionFromCMS ... -func SessionFromCMS(gs *service.Session) *model.Session { +// SessionFromServices ... +func SessionFromServices(gs *service.Session) *model.Session { s := &model.Session{ ID: gs.ID, Title: gs.Title, @@ -56,29 +56,29 @@ func SessionFromCMS(gs *service.Session) *model.Session { } for _, step := range gs.Steps { - s.Steps = append(s.Steps, StepFromCMS(step)) + s.Steps = append(s.Steps, StepFromServices(step)) } if gs.Course != nil { - s.Course = CourseFromCMS(gs.Course) + s.Course = CourseFromServices(gs.Course) } return s } -// SessionsFromCMS ... -func SessionsFromCMS(gcs []*service.Session) []*model.Session { +// SessionsFromServices ... +func SessionsFromServices(gcs []*service.Session) []*model.Session { cs := []*model.Session{} for _, gc := range gcs { - cs = append(cs, SessionFromCMS(gc)) + cs = append(cs, SessionFromServices(gc)) } return cs } -// StepFromCMS ... -func StepFromCMS(gc *service.Step) *model.Step { +// StepFromServices ... +func StepFromServices(gc *service.Step) *model.Step { return &model.Step{ ID: gc.ID, Title: gc.Title, @@ -89,3 +89,23 @@ func StepFromCMS(gc *service.Step) *model.Step { Question: gc.Question, } } + +// TimemapsFromServices ... +func TimemapsFromServices(stm []service.Timemap) []*model.Timemap { + tms := []*model.Timemap{} + + for _, gc := range stm { + tms = append(tms, TimemapFromServices(gc)) + } + + return tms +} + +// TimemapFromServices ... +func TimemapFromServices(tm service.Timemap) *model.Timemap { + return &model.Timemap{ + ID: tm.ID, + Map: tm.Map, + UpdatedAt: tm.DateUpdated.String(), + } +} diff --git a/pkg/graphql/schema.graphqls b/pkg/graphql/schema.graphqls index 6f5a49b..092d902 100644 --- a/pkg/graphql/schema.graphqls +++ b/pkg/graphql/schema.graphqls @@ -14,6 +14,7 @@ type Course { note: CourseNote progress: CourseProgress + timemaps: [Timemap]! } type Session { @@ -23,7 +24,6 @@ type Session { steps: [Step] course: Course! - # progress: SessionProgress } type Step { @@ -47,11 +47,6 @@ type CourseProgress { dateStarted: String! } -# type SessionProgress { -# id: ID! -# dateStarted: String! -# } - type StepProgress { id: ID! state: String! @@ -63,6 +58,8 @@ type Timemap { id: ID! map: String! updatedAt: String! + + course: Course! } input CourseQuery { @@ -81,6 +78,15 @@ input StepQuery { id: ID! } +input TimemapQuery { + id: ID! + courseID: ID! +} + +input TimemapsByCourseIDQuery { + id: ID! +} + type CourseNote { id: ID! courseID: ID! @@ -102,7 +108,8 @@ type Query { session(where: SessionQuery!): Session step(where: StepQuery!): Step sessionsByCourseID(where: SessionsByCourseIDQuery!): [Session] - timemap: Timemap + timemap(where: TimemapQuery!): Timemap + timemapsByCourseID(where: TimemapsByCourseIDQuery!): [Timemap] } input CourseStarted { @@ -130,6 +137,8 @@ input UpdatedStepNote { } input UpdatedTimemap { + id: ID + courseID: ID! map: String! } diff --git a/pkg/graphql/schema.resolvers.go b/pkg/graphql/schema.resolvers.go index 6052872..746634b 100644 --- a/pkg/graphql/schema.resolvers.go +++ b/pkg/graphql/schema.resolvers.go @@ -54,7 +54,7 @@ func (r *courseResolver) Sessions(ctx context.Context, obj *model.Course) ([]*mo return nil, err } - ss := SessionsFromCMS(gss) + ss := SessionsFromServices(gss) return ss, nil } @@ -93,7 +93,7 @@ func (r *courseResolver) Progress(ctx context.Context, obj *model.Course) (*mode if err != nil { log.Error("error occurred getting request user", err) - return nil, fmt.Errorf("error occurred getting course progress1 %w", err) + return nil, fmt.Errorf("error occurred getting course progress %w", err) } cp, err := r.service.CourseProgress.Get(ctx, obj.ID, userID) @@ -111,6 +111,27 @@ func (r *courseResolver) Progress(ctx context.Context, obj *model.Course) (*mode return CourseProgressFromService(cp), nil } +func (r *courseResolver) Timemaps(ctx context.Context, obj *model.Course) ([]*model.Timemap, error) { + log := logging.NewFromResolver(ctx) + log.Info("get timemaps by course resolver got called") + + userID, err := request.GetUserID(ctx) + if err != nil { + log.Error("error occurred getting request user", err) + + return nil, fmt.Errorf("error occurred getting course progress %w", err) + } + + tms, err := r.service.Timemap.GetByCourseID(ctx, userID, obj.ID) + if err != nil { + log.Error("error starting Course", err) + + return nil, err + } + + return TimemapsFromServices(tms), nil +} + func (r *mutationResolver) CourseStarted(ctx context.Context, input model.CourseStarted) (*model.Course, error) { log := logging.NewFromResolver(ctx) log.Info("course started resolver got called") @@ -238,7 +259,7 @@ func (r *mutationResolver) UpdateTimemap(ctx context.Context, input model.Update return nil, err } - timemap, err := r.service.Timemap.Update(ctx, userID, input.Map) + timemap, err := r.service.Timemap.Update(ctx, userID, input.CourseID, input.ID, input.Map) if err != nil { log.Error("An error occurred getting Timemap", err) @@ -246,6 +267,7 @@ func (r *mutationResolver) UpdateTimemap(ctx context.Context, input model.Update } return &model.Timemap{ + ID: timemap.ID, Map: timemap.Map, UpdatedAt: timemap.DateUpdated.String(), }, nil @@ -262,7 +284,7 @@ func (r *queryResolver) Courses(ctx context.Context) ([]*model.Course, error) { return nil, err } - cs := CoursesFromCMS(cgs) + cs := CoursesFromServices(cgs) return cs, nil } @@ -284,7 +306,7 @@ func (r *queryResolver) Course(ctx context.Context, where model.CourseQuery) (*m return nil, err } - c := CourseFromCMS(cg) + c := CourseFromServices(cg) return c, nil } @@ -306,7 +328,7 @@ func (r *queryResolver) Session(ctx context.Context, where model.SessionQuery) ( return nil, err } - s := SessionFromCMS(gs) + s := SessionFromServices(gs) return s, nil } @@ -328,7 +350,7 @@ func (r *queryResolver) Step(ctx context.Context, where model.StepQuery) (*model return nil, err } - s := StepFromCMS(gs) + s := StepFromServices(gs) return s, nil } @@ -344,12 +366,12 @@ func (r *queryResolver) SessionsByCourseID(ctx context.Context, where model.Sess return nil, err } - ss := SessionsFromCMS(gss) + ss := SessionsFromServices(gss) return ss, nil } -func (r *queryResolver) Timemap(ctx context.Context) (*model.Timemap, error) { +func (r *queryResolver) Timemap(ctx context.Context, where model.TimemapQuery) (*model.Timemap, error) { log := logging.NewFromResolver(ctx) log.Info("Timemap resolver got called") @@ -360,7 +382,7 @@ func (r *queryResolver) Timemap(ctx context.Context) (*model.Timemap, error) { return nil, fmt.Errorf("error occurred getting request user ID %w", err) } - timemap, err := r.service.Timemap.Get(ctx, userID) + timemap, err := r.service.Timemap.Get(ctx, userID, where.CourseID, where.ID) if err != nil { if errors.Is(err, service.ErrNotFound) { log.Error("timemap not found") @@ -380,6 +402,27 @@ func (r *queryResolver) Timemap(ctx context.Context) (*model.Timemap, error) { }, nil } +func (r *queryResolver) TimemapsByCourseID(ctx context.Context, where model.TimemapsByCourseIDQuery) ([]*model.Timemap, error) { + log := logging.NewFromResolver(ctx) + log.Info("Timemap by courseID resolver got called") + + userID, err := request.GetUserID(ctx) + if err != nil { + log.Error("error occurred getting request user", err) + + return nil, fmt.Errorf("error occurred getting request user ID %w", err) + } + + tms, err := r.service.Timemap.GetByCourseID(ctx, userID, where.ID) + if err != nil { + log.Error("error starting Course", err) + + return nil, err + } + + return TimemapsFromServices(tms), nil +} + func (r *stepResolver) Note(ctx context.Context, obj *model.Step) (*model.StepNote, error) { log := logging.NewFromResolver(ctx) log.Info("Step Note resolver got called", obj.ID) diff --git a/pkg/logging/logger.go b/pkg/logging/logger.go index e41e86c..93fde29 100644 --- a/pkg/logging/logger.go +++ b/pkg/logging/logger.go @@ -30,6 +30,8 @@ const ( StepIDKey = "step_id" // UserKey ... UserIDKey = "user_id" + // TimemapKey ... + TimemapIDKey = "timemap_id" // PKKey ... PKKey = "pk" // SKKey ... diff --git a/pkg/service/mocks/timemap_service.go b/pkg/service/mocks/timemap_service.go index 4692df5..7f48b04 100644 --- a/pkg/service/mocks/timemap_service.go +++ b/pkg/service/mocks/timemap_service.go @@ -35,31 +35,46 @@ func (m *MockTimemapServicer) EXPECT() *MockTimemapServicerMockRecorder { } // Get mocks base method -func (m *MockTimemapServicer) Get(ctx context.Context, uID string) (*service.Timemap, error) { +func (m *MockTimemapServicer) Get(ctx context.Context, uID, cID, tID string) (*service.Timemap, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", ctx, uID) + ret := m.ctrl.Call(m, "Get", ctx, uID, cID, tID) ret0, _ := ret[0].(*service.Timemap) ret1, _ := ret[1].(error) return ret0, ret1 } // Get indicates an expected call of Get -func (mr *MockTimemapServicerMockRecorder) Get(ctx, uID interface{}) *gomock.Call { +func (mr *MockTimemapServicerMockRecorder) Get(ctx, uID, cID, tID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockTimemapServicer)(nil).Get), ctx, uID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockTimemapServicer)(nil).Get), ctx, uID, cID, tID) +} + +// GetByCourseID mocks base method +func (m *MockTimemapServicer) GetByCourseID(ctx context.Context, uID, cID string) ([]service.Timemap, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetByCourseID", ctx, uID, cID) + ret0, _ := ret[0].([]service.Timemap) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetByCourseID indicates an expected call of GetByCourseID +func (mr *MockTimemapServicerMockRecorder) GetByCourseID(ctx, uID, cID interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByCourseID", reflect.TypeOf((*MockTimemapServicer)(nil).GetByCourseID), ctx, uID, cID) } // Update mocks base method -func (m *MockTimemapServicer) Update(ctx context.Context, uID, value string) (*service.Timemap, error) { +func (m *MockTimemapServicer) Update(ctx context.Context, uID, cID string, tID *string, value string) (*service.Timemap, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Update", ctx, uID, value) + ret := m.ctrl.Call(m, "Update", ctx, uID, cID, tID, value) ret0, _ := ret[0].(*service.Timemap) ret1, _ := ret[1].(error) return ret0, ret1 } // Update indicates an expected call of Update -func (mr *MockTimemapServicerMockRecorder) Update(ctx, uID, value interface{}) *gomock.Call { +func (mr *MockTimemapServicerMockRecorder) Update(ctx, uID, cID, tID, value interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockTimemapServicer)(nil).Update), ctx, uID, value) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockTimemapServicer)(nil).Update), ctx, uID, cID, tID, value) } diff --git a/pkg/service/session_service_test.go b/pkg/service/session_service_test.go index 6e02684..d88edf7 100644 --- a/pkg/service/session_service_test.go +++ b/pkg/service/session_service_test.go @@ -107,13 +107,13 @@ func TestSessionServiceGetByCourseID(t *testing.T) { }, expectedSession: []*service.Session{ - &service.Session{ + { ID: cmsSessionOne.ID, Title: cmsSessionOne.Title, Description: cmsSessionOne.Description, Steps: []*service.Step{}, }, - &service.Session{ + { ID: cmsSessionTwo.ID, Title: cmsSessionTwo.Title, Description: cmsSessionTwo.Description, diff --git a/pkg/service/timemap_service.go b/pkg/service/timemap_service.go index 26330d8..0e9e77b 100644 --- a/pkg/service/timemap_service.go +++ b/pkg/service/timemap_service.go @@ -11,8 +11,9 @@ import ( ) type TimemapServicer interface { - Get(ctx context.Context, uID string) (*Timemap, error) - Update(ctx context.Context, uID, value string) (*Timemap, error) + Get(ctx context.Context, uID, cID, tID string) (*Timemap, error) + GetByCourseID(ctx context.Context, uID, cID string) ([]Timemap, error) + Update(ctx context.Context, uID, cID string, tID *string, value string) (*Timemap, error) } type TimemapService struct { @@ -28,12 +29,14 @@ func NewTimemapService(cms store.TimemapRepositor) *TimemapService { return r } -func (s TimemapService) Get(ctx context.Context, uID string) (*Timemap, error) { +func (s TimemapService) Get(ctx context.Context, uID, cID, tID string) (*Timemap, error) { log := logging.NewFromResolver(ctx).WithFields(logrus.Fields{ - logging.UserIDKey: uID, + logging.UserIDKey: uID, + logging.CourseIDKey: cID, + logging.TimemapIDKey: tID, }) - timemap, err := s.store.Get(ctx, uID) + timemap, err := s.store.Get(ctx, uID, cID, tID) if err != nil { log.Error("error getting timemap by id from store", err) @@ -49,6 +52,7 @@ func (s TimemapService) Get(ctx context.Context, uID string) (*Timemap, error) { return &Timemap{ ID: timemap.ID, + CourseID: timemap.CourseID, UserID: timemap.UserID, Map: timemap.Map, DateCreated: timemap.DateCreated, @@ -56,15 +60,58 @@ func (s TimemapService) Get(ctx context.Context, uID string) (*Timemap, error) { }, nil } -func (s TimemapService) Update(ctx context.Context, uID, value string) (*Timemap, error) { +func (s TimemapService) GetByCourseID(ctx context.Context, uID, cID string) ([]Timemap, error) { log := logging.NewFromResolver(ctx).WithFields(logrus.Fields{ - logging.UserIDKey: uID, + logging.UserIDKey: uID, + logging.CourseIDKey: cID, }) - timemap, err := s.store.Update(ctx, &store.Timemap{ - UserID: uID, - Map: value, + tms, err := s.store.GetByCourseID(ctx, uID, cID) + + if err != nil { + log.Error("error getting timemap by courseID from store", err) + + return nil, err + } + + timemaps := []Timemap{} + + if len(tms) == 0 { + return timemaps, nil + } + + for _, tm := range tms { + timemaps = append(timemaps, Timemap{ + ID: tm.ID, + CourseID: tm.CourseID, + UserID: tm.UserID, + Map: tm.Map, + DateCreated: tm.DateCreated, + DateUpdated: tm.DateUpdated, + }) + } + + return timemaps, nil +} + +func (s TimemapService) Update(ctx context.Context, uID, cID string, tID *string, value string) (*Timemap, error) { + log := logging.NewFromResolver(ctx).WithFields(logrus.Fields{ + logging.UserIDKey: uID, + logging.CourseIDKey: cID, + logging.TimemapIDKey: tID, }) + + tm := store.Timemap{ + CourseID: cID, + UserID: uID, + Map: value, + } + + if tID != nil { + tm.ID = *tID + } + + timemap, err := s.store.Update(ctx, tm) if err != nil { log.Error("error updating timemap from store", err) @@ -73,6 +120,7 @@ func (s TimemapService) Update(ctx context.Context, uID, value string) (*Timemap return &Timemap{ ID: timemap.ID, + CourseID: timemap.CourseID, UserID: timemap.UserID, Map: timemap.Map, DateCreated: timemap.DateCreated, diff --git a/pkg/service/timemap_service_test.go b/pkg/service/timemap_service_test.go index 52c06cc..0915bda 100644 --- a/pkg/service/timemap_service_test.go +++ b/pkg/service/timemap_service_test.go @@ -16,8 +16,12 @@ import ( func TestTimemapServiceGet(t *testing.T) { uID := fake.CharactersN(10) + cID := fake.CharactersN(10) + tID := fake.CharactersN(10) timemap := builder.NewTimemapBuilder(). + WithCourseID(cID). WithUserID(uID). + WithID(tID). Build() testCases := []struct { @@ -33,11 +37,14 @@ func TestTimemapServiceGet(t *testing.T) { client.EXPECT().Get( gomock.Any(), uID, + cID, + tID, ).Return(&timemap, nil) }, expectedTimemap: &service.Timemap{ ID: timemap.ID, + CourseID: timemap.CourseID, UserID: timemap.UserID, Map: timemap.Map, DateCreated: timemap.DateCreated, @@ -50,6 +57,8 @@ func TestTimemapServiceGet(t *testing.T) { client.EXPECT().Get( gomock.Any(), uID, + cID, + tID, ).Return(nil, fmt.Errorf("something went wrong")) }, @@ -61,6 +70,8 @@ func TestTimemapServiceGet(t *testing.T) { client.EXPECT().Get( gomock.Any(), uID, + cID, + tID, ).Return(nil, nil) }, @@ -79,7 +90,111 @@ func TestTimemapServiceGet(t *testing.T) { resolver := service.NewTimemapService(clientMock) ctx := context.Background() - n, err := resolver.Get(ctx, uID) + n, err := resolver.Get(ctx, uID, cID, tID) + + if tt.expectedErr != nil { + assert.EqualError(t, err, tt.expectedErr.Error()) + } else { + assert.Nil(t, err) + assert.Equal(t, tt.expectedTimemap, n) + } + }) + } +} + +func TestTimemapServiceGetByCourseID(t *testing.T) { + uID := fake.CharactersN(10) + cID := fake.CharactersN(10) + + timemapOne := builder.NewTimemapBuilder(). + WithCourseID(cID). + WithUserID(uID). + Build() + + timemapTwo := builder.NewTimemapBuilder(). + WithCourseID(cID). + WithUserID(uID). + Build() + + timemaps := []store.Timemap{ + timemapOne, + timemapTwo, + } + + testCases := []struct { + desc string + clientExpectations func(client *storemocks.MockTimemapRepositor) + + expectedTimemap []service.Timemap + expectedErr error + }{ + { + desc: "given map returned from store, map returned", + clientExpectations: func(client *storemocks.MockTimemapRepositor) { + client.EXPECT().GetByCourseID( + gomock.Any(), + uID, + cID, + ).Return(timemaps, nil) + }, + + expectedTimemap: []service.Timemap{ + { + ID: timemapOne.ID, + CourseID: timemapOne.CourseID, + UserID: timemapOne.UserID, + Map: timemapOne.Map, + DateCreated: timemapOne.DateCreated, + DateUpdated: timemapOne.DateUpdated, + }, + { + ID: timemapTwo.ID, + CourseID: timemapTwo.CourseID, + UserID: timemapTwo.UserID, + Map: timemapTwo.Map, + DateCreated: timemapTwo.DateCreated, + DateUpdated: timemapTwo.DateUpdated, + }, + }, + }, + { + desc: "given an error is returned from the store, err returned", + clientExpectations: func(client *storemocks.MockTimemapRepositor) { + client.EXPECT().GetByCourseID( + gomock.Any(), + uID, + cID, + ).Return([]store.Timemap{}, fmt.Errorf("something went wrong")) + }, + + expectedErr: fmt.Errorf("something went wrong"), + }, + { + desc: "given the returned an empty slice of timemaps, empty slice returned", + clientExpectations: func(client *storemocks.MockTimemapRepositor) { + client.EXPECT().GetByCourseID( + gomock.Any(), + uID, + cID, + ).Return([]store.Timemap{}, nil) + }, + + expectedTimemap: []service.Timemap{}, + }, + } + for _, tt := range testCases { + t.Run(tt.desc, func(t *testing.T) { + ctrl := gomock.NewController(t) + clientMock := storemocks.NewMockTimemapRepositor(ctrl) + + if tt.clientExpectations != nil { + tt.clientExpectations(clientMock) + } + + resolver := service.NewTimemapService(clientMock) + ctx := context.Background() + + n, err := resolver.GetByCourseID(ctx, uID, cID) if tt.expectedErr != nil { assert.EqualError(t, err, tt.expectedErr.Error()) @@ -93,15 +208,22 @@ func TestTimemapServiceGet(t *testing.T) { func TestTimemapServiceUpdate(t *testing.T) { uID := fake.CharactersN(10) + cID := fake.CharactersN(10) + tID := fake.CharactersN(10) value := fake.CharactersN(10) + timemap := builder.NewTimemapBuilder(). + WithCourseID(cID). WithUserID(uID). + WithID(tID). WithMap(value). Build() uTimemap := store.Timemap{ - UserID: uID, - Map: value, + ID: tID, + CourseID: cID, + UserID: uID, + Map: value, } testCases := []struct { @@ -116,12 +238,13 @@ func TestTimemapServiceUpdate(t *testing.T) { clientExpectations: func(client *storemocks.MockTimemapRepositor) { client.EXPECT().Update( gomock.Any(), - &uTimemap, + uTimemap, ).Return(&timemap, nil) }, expectedTimemap: &service.Timemap{ ID: timemap.ID, + CourseID: timemap.CourseID, UserID: timemap.UserID, Map: timemap.Map, DateCreated: timemap.DateCreated, @@ -133,7 +256,7 @@ func TestTimemapServiceUpdate(t *testing.T) { clientExpectations: func(client *storemocks.MockTimemapRepositor) { client.EXPECT().Update( gomock.Any(), - &uTimemap, + uTimemap, ).Return(nil, fmt.Errorf("something went wrong")) }, @@ -152,7 +275,7 @@ func TestTimemapServiceUpdate(t *testing.T) { resolver := service.NewTimemapService(clientMock) ctx := context.Background() - n, err := resolver.Update(ctx, uID, value) + n, err := resolver.Update(ctx, uID, cID, &tID, value) if tt.expectedErr != nil { assert.EqualError(t, err, tt.expectedErr.Error()) diff --git a/pkg/service/types.go b/pkg/service/types.go index 15b379f..e3514d4 100644 --- a/pkg/service/types.go +++ b/pkg/service/types.go @@ -87,6 +87,7 @@ type StepNote struct { // Timemap ... type Timemap struct { ID string `json:"id"` + CourseID string `json:"courseID"` UserID string `json:"userID"` Map string `json:"map"` DateCreated time.Time `json:"dateCreated"` diff --git a/pkg/store/builder/timemap.go b/pkg/store/builder/timemap.go index 674cda2..a9e96b8 100644 --- a/pkg/store/builder/timemap.go +++ b/pkg/store/builder/timemap.go @@ -18,6 +18,7 @@ func NewTimemapBuilder() *TimemapBuilder { timemap: store.Timemap{ BaseEntity: store.BaseEntity{}, ID: fake.CharactersN(10), + CourseID: fake.CharactersN(10), UserID: fake.CharactersN(10), Map: fake.CharactersN(10), }, @@ -42,6 +43,12 @@ func (c TimemapBuilder) WithSK(sk string) TimemapBuilder { return c } +// WithCourseID ... +func (c TimemapBuilder) WithCourseID(id string) TimemapBuilder { + c.timemap.CourseID = id + return c +} + // WithUserID ... func (c TimemapBuilder) WithUserID(id string) TimemapBuilder { c.timemap.UserID = id diff --git a/pkg/store/keys.go b/pkg/store/keys.go index ebbe217..af2a06d 100644 --- a/pkg/store/keys.go +++ b/pkg/store/keys.go @@ -3,10 +3,11 @@ package store import "fmt" const ( - usersKey = "USER#%s" - progressKey = "PROGRESS#%s" - noteKey = "NOTE#%s" - timemapKey = "TIMEMAP" + usersKey = "USER#%s" + progressKey = "PROGRESS#%s" + noteKey = "NOTE#%s" + timemapKey = "COURSE#%s#TIMEMAP#%s" + courseTimemapKey = "COURSE#%s#TIMEMAP" ) func UserPK(id string) string { @@ -21,6 +22,10 @@ func NoteSK(id string) string { return fmt.Sprintf(noteKey, id) } -func TimemapSK() string { - return timemapKey +func CourseTimemapsSK(cID string) string { + return fmt.Sprintf(courseTimemapKey, cID) +} + +func TimemapSK(cID, tID string) string { + return fmt.Sprintf(timemapKey, cID, tID) } diff --git a/pkg/store/keys_test.go b/pkg/store/keys_test.go index d110a8f..e6f3076 100644 --- a/pkg/store/keys_test.go +++ b/pkg/store/keys_test.go @@ -12,20 +12,20 @@ func TestUserPK(t *testing.T) { desc string id string - excpected string + expected string }{ { desc: "given id, it returns corret key", id: "Foo", - excpected: "USER#Foo", + expected: "USER#Foo", }, } for _, tt := range testCases { t.Run(tt.desc, func(t *testing.T) { pk := store.UserPK(tt.id) - assert.Equal(t, tt.excpected, pk) + assert.Equal(t, tt.expected, pk) }) } } @@ -35,20 +35,20 @@ func TestUserProgressSK(t *testing.T) { desc string id string - excpected string + expected string }{ { desc: "given id, it returns corret key", id: "Foo", - excpected: "PROGRESS#Foo", + expected: "PROGRESS#Foo", }, } for _, tt := range testCases { t.Run(tt.desc, func(t *testing.T) { pk := store.ProgressSK(tt.id) - assert.Equal(t, tt.excpected, pk) + assert.Equal(t, tt.expected, pk) }) } } @@ -58,41 +58,69 @@ func TestUserNoteSK(t *testing.T) { desc string id string - excpected string + expected string }{ { desc: "given id, it returns corret key", id: "Foo", - excpected: "NOTE#Foo", + expected: "NOTE#Foo", }, } for _, tt := range testCases { t.Run(tt.desc, func(t *testing.T) { pk := store.NoteSK(tt.id) - assert.Equal(t, tt.excpected, pk) + assert.Equal(t, tt.expected, pk) }) } } func TestUserTimemapSK(t *testing.T) { testCases := []struct { - desc string + desc string + courseID string + timemapID string - excpected string + expected string }{ { - desc: "given id, it returns corret key", + desc: "given id, it returns corret key", + courseID: "Foo", + timemapID: "Bar", + + expected: "COURSE#Foo#TIMEMAP#Bar", + }, + } + for _, tt := range testCases { + t.Run(tt.desc, func(t *testing.T) { + pk := store.TimemapSK(tt.courseID, tt.timemapID) + + assert.Equal(t, tt.expected, pk) + }) + } +} + +func TestUserCourseTimemapSK(t *testing.T) { + testCases := []struct { + desc string + courseID string + timemapID string + + expected string + }{ + { + desc: "given id, it returns corret key", + courseID: "Foo", - excpected: "TIMEMAP", + expected: "COURSE#Foo#TIMEMAP", }, } for _, tt := range testCases { t.Run(tt.desc, func(t *testing.T) { - pk := store.TimemapSK() + pk := store.CourseTimemapsSK(tt.courseID) - assert.Equal(t, tt.excpected, pk) + assert.Equal(t, tt.expected, pk) }) } } diff --git a/pkg/store/mocks/timemap_store.go b/pkg/store/mocks/timemap_store.go index 19cd70c..bca6a92 100644 --- a/pkg/store/mocks/timemap_store.go +++ b/pkg/store/mocks/timemap_store.go @@ -35,18 +35,33 @@ func (m *MockTimemapRepositor) EXPECT() *MockTimemapRepositorMockRecorder { } // Get mocks base method -func (m *MockTimemapRepositor) Get(ctx context.Context, uID string) (*store.Timemap, error) { +func (m *MockTimemapRepositor) Get(ctx context.Context, uID, cID, tID string) (*store.Timemap, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", ctx, uID) + ret := m.ctrl.Call(m, "Get", ctx, uID, cID, tID) ret0, _ := ret[0].(*store.Timemap) ret1, _ := ret[1].(error) return ret0, ret1 } // Get indicates an expected call of Get -func (mr *MockTimemapRepositorMockRecorder) Get(ctx, uID interface{}) *gomock.Call { +func (mr *MockTimemapRepositorMockRecorder) Get(ctx, uID, cID, tID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockTimemapRepositor)(nil).Get), ctx, uID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockTimemapRepositor)(nil).Get), ctx, uID, cID, tID) +} + +// GetByCourseID mocks base method +func (m *MockTimemapRepositor) GetByCourseID(ctx context.Context, uID, cID string) ([]store.Timemap, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetByCourseID", ctx, uID, cID) + ret0, _ := ret[0].([]store.Timemap) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetByCourseID indicates an expected call of GetByCourseID +func (mr *MockTimemapRepositorMockRecorder) GetByCourseID(ctx, uID, cID interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByCourseID", reflect.TypeOf((*MockTimemapRepositor)(nil).GetByCourseID), ctx, uID, cID) } // Create mocks base method @@ -65,7 +80,7 @@ func (mr *MockTimemapRepositorMockRecorder) Create(ctx, tm interface{}) *gomock. } // Update mocks base method -func (m *MockTimemapRepositor) Update(ctx context.Context, tm *store.Timemap) (*store.Timemap, error) { +func (m *MockTimemapRepositor) Update(ctx context.Context, tm store.Timemap) (*store.Timemap, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Update", ctx, tm) ret0, _ := ret[0].(*store.Timemap) diff --git a/pkg/store/progress_store.go b/pkg/store/progress_store.go index 7140e97..33defe6 100644 --- a/pkg/store/progress_store.go +++ b/pkg/store/progress_store.go @@ -86,10 +86,6 @@ func (c ProgressStore) GetCompletedByIDs(ctx context.Context, uID string, ids .. err := c.db.BatchGet(ctx, userTableName, UserPK(uID), progressKeys, &res) if err != nil { - if errors.Is(err, ErrNotFound) { - return nil, nil - } - return nil, err } diff --git a/pkg/store/progress_store_test.go b/pkg/store/progress_store_test.go index a2d0c3a..434873a 100644 --- a/pkg/store/progress_store_test.go +++ b/pkg/store/progress_store_test.go @@ -105,6 +105,104 @@ func TestProgressStoreGet(t *testing.T) { } } +func TestProgressStoreGetCompletedByIDs(t *testing.T) { + cID := fake.CharactersN(10) + uID := fake.CharactersN(10) + + progressOne := builder.NewProgressBuilder(). + WithEntityID(cID). + WithUserID(uID). + Completed(). + Build() + + progressTwo := builder.NewProgressBuilder(). + WithEntityID(cID). + WithUserID(uID). + Build() + + inputIDs := []string{ + progressOne.ID, + progressTwo.ID, + } + + skIDs := []string{ + store.ProgressSK(progressOne.ID), + store.ProgressSK(progressTwo.ID), + } + + progresses := []*store.Progress{ + &progressOne, + &progressTwo, + } + + testCases := []struct { + desc string + userID string + courseID string + clientExpectations func(client *storemocks.MockStorer) + + expectedProgress []*store.Progress + expectedErr error + }{ + { + desc: "given a completed progress is returned from store, progresses is returned", + userID: uID, + courseID: cID, + clientExpectations: func(client *storemocks.MockStorer) { + client.EXPECT().BatchGet( + gomock.Any(), + userTableName, + fmt.Sprintf("USER#%s", uID), + skIDs, + gomock.Any(), + ).SetArg(4, progresses) + }, + + expectedProgress: []*store.Progress{ + &progressOne, + }, + }, + { + desc: "given a generic error is returned from the store, error returned", + userID: uID, + courseID: cID, + clientExpectations: func(client *storemocks.MockStorer) { + client.EXPECT().BatchGet( + gomock.Any(), + userTableName, + fmt.Sprintf("USER#%s", uID), + skIDs, + gomock.Any(), + ).Return(fmt.Errorf("error occurred")) + }, + + expectedErr: fmt.Errorf("error occurred"), + }, + } + for _, tt := range testCases { + t.Run(tt.desc, func(t *testing.T) { + ctrl := gomock.NewController(t) + clientMock := storemocks.NewMockStorer(ctrl) + + if tt.clientExpectations != nil { + tt.clientExpectations(clientMock) + } + + resolver := store.NewProgressStore(clientMock) + ctx := context.Background() + + n, err := resolver.GetCompletedByIDs(ctx, uID, inputIDs...) + + if tt.expectedErr != nil { + assert.EqualError(t, err, tt.expectedErr.Error()) + } else { + assert.Nil(t, err) + assert.Equal(t, tt.expectedProgress, n) + } + }) + } +} + func TestProgressStoreCreate(t *testing.T) { now := time.Now() id := fake.CharactersN(10) diff --git a/pkg/store/store.go b/pkg/store/store.go index ea15943..f39cd78 100644 --- a/pkg/store/store.go +++ b/pkg/store/store.go @@ -10,7 +10,6 @@ import ( "github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression" "github.com/aws/aws-sdk-go-v2/service/dynamodb" "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" - "github.com/aws/aws-sdk-go/aws" "github.com/jdpx/mind-hub-api/pkg/logging" "github.com/sirupsen/logrus" ) @@ -55,7 +54,7 @@ func (c Store) Get(ctx context.Context, tableName string, pk, sk string, i inter }) input := dynamodb.GetItemInput{ - TableName: aws.String(tableName), + TableName: &tableName, Key: map[string]types.AttributeValue{ "PK": &types.AttributeValueMemberS{ Value: pk, @@ -168,7 +167,7 @@ func (c Store) Query(ctx context.Context, tableName string, ex expression.Expres ProjectionExpression: ex.Projection(), ExpressionAttributeNames: ex.Names(), ExpressionAttributeValues: ex.Values(), - TableName: aws.String(tableName), + TableName: &tableName, } result, err := c.db.Query(ctx, &queryInput) @@ -210,7 +209,7 @@ func (c Store) Put(ctx context.Context, tableName string, body interface{}) erro } _, err = c.db.PutItem(ctx, &dynamodb.PutItemInput{ - TableName: aws.String(tableName), + TableName: &tableName, Item: av, }) @@ -244,7 +243,7 @@ func (c Store) Update(ctx context.Context, tableName string, pk, sk string, ex e Value: sk, }, }, - TableName: aws.String(tableName), + TableName: &tableName, ExpressionAttributeNames: ex.Names(), ExpressionAttributeValues: ex.Values(), ReturnValues: types.ReturnValueUpdatedNew, diff --git a/pkg/store/timemap_store.go b/pkg/store/timemap_store.go index d2edf2a..db1b0b2 100644 --- a/pkg/store/timemap_store.go +++ b/pkg/store/timemap_store.go @@ -12,9 +12,10 @@ import ( // TimemapRepositor ... type TimemapRepositor interface { - Get(ctx context.Context, uID string) (*Timemap, error) + Get(ctx context.Context, uID, cID, tID string) (*Timemap, error) + GetByCourseID(ctx context.Context, uID, cID string) ([]Timemap, error) Create(ctx context.Context, tm Timemap) (*Timemap, error) - Update(ctx context.Context, tm *Timemap) (*Timemap, error) + Update(ctx context.Context, tm Timemap) (*Timemap, error) } // TimemapStoreOption ... @@ -57,9 +58,9 @@ func WithTimemapTimer(c Timer) func(*TimemapStore) { } // Get ... -func (c TimemapStore) Get(ctx context.Context, uID string) (*Timemap, error) { +func (c TimemapStore) Get(ctx context.Context, uID, cID, tID string) (*Timemap, error) { res := Timemap{} - err := c.db.Get(ctx, userTableName, UserPK(uID), TimemapSK(), &res) + err := c.db.Get(ctx, userTableName, UserPK(uID), TimemapSK(cID, tID), &res) if err != nil { if errors.Is(err, ErrNotFound) { return nil, nil @@ -71,6 +72,22 @@ func (c TimemapStore) Get(ctx context.Context, uID string) (*Timemap, error) { return &res, nil } +// GetByCourseID ... +func (c TimemapStore) GetByCourseID(ctx context.Context, uID, cID string) ([]Timemap, error) { + expr, _ := expression.NewBuilder(). + WithKeyCondition(expression.Key("PK").Equal(expression.Value(UserPK(uID)))). + WithFilter(expression.Name("SK").BeginsWith(CourseTimemapsSK(cID))). + Build() + + res := []Timemap{} + err := c.db.Query(ctx, userTableName, expr, &res) + if err != nil { + return []Timemap{}, err + } + + return res, nil +} + // Create ... func (c TimemapStore) Create(ctx context.Context, tm Timemap) (*Timemap, error) { tm.ID = c.idGenerator() @@ -79,7 +96,7 @@ func (c TimemapStore) Create(ctx context.Context, tm Timemap) (*Timemap, error) tm.BaseEntity = BaseEntity{ PK: UserPK(tm.UserID), - SK: TimemapSK(), + SK: TimemapSK(tm.CourseID, tm.ID), } err := c.db.Put(ctx, userTableName, tm) @@ -89,6 +106,7 @@ func (c TimemapStore) Create(ctx context.Context, tm Timemap) (*Timemap, error) return &Timemap{ ID: tm.ID, + CourseID: tm.CourseID, UserID: tm.UserID, Map: tm.Map, DateCreated: tm.DateCreated, @@ -97,9 +115,14 @@ func (c TimemapStore) Create(ctx context.Context, tm Timemap) (*Timemap, error) } // Update ... -func (c TimemapStore) Update(ctx context.Context, tm *Timemap) (*Timemap, error) { +func (c TimemapStore) Update(ctx context.Context, tm Timemap) (*Timemap, error) { + if tm.ID == "" { + tm.ID = c.idGenerator() + } + upBuilder := expression. - Set(expression.Name("id"), expression.Name("id").IfNotExists(expression.Value(c.idGenerator()))). + Set(expression.Name("id"), expression.Name("id").IfNotExists(expression.Value(tm.ID))). + Set(expression.Name("courseID"), expression.Name("courseID").IfNotExists(expression.Value(tm.CourseID))). Set(expression.Name("userID"), expression.Name("userID").IfNotExists(expression.Value(tm.UserID))). Set(expression.Name("map"), expression.Value(tm.Map)). Set(expression.Name("dateCreated"), expression.Name("dateCreated").IfNotExists(expression.Value(c.timer()))). @@ -111,13 +134,14 @@ func (c TimemapStore) Update(ctx context.Context, tm *Timemap) (*Timemap, error) } res := Timemap{} - err = c.db.Update(ctx, userTableName, UserPK(tm.UserID), TimemapSK(), expr, &res) + err = c.db.Update(ctx, userTableName, UserPK(tm.UserID), TimemapSK(tm.CourseID, tm.ID), expr, &res) if err != nil { return nil, err } return &Timemap{ ID: res.ID, + CourseID: res.CourseID, UserID: res.UserID, Map: res.Map, DateCreated: res.DateCreated, diff --git a/pkg/store/timemap_store_test.go b/pkg/store/timemap_store_test.go index 6ea0952..c88ac17 100644 --- a/pkg/store/timemap_store_test.go +++ b/pkg/store/timemap_store_test.go @@ -16,8 +16,12 @@ import ( ) func TestTimemapStoreGet(t *testing.T) { + tID := fake.CharactersN(10) uID := fake.CharactersN(10) + cID := fake.CharactersN(10) timemap := builder.NewTimemapBuilder(). + WithID(tID). + WithCourseID(cID). WithUserID(uID). Build() @@ -35,7 +39,7 @@ func TestTimemapStoreGet(t *testing.T) { gomock.Any(), userTableName, fmt.Sprintf("USER#%s", uID), - "TIMEMAP", + fmt.Sprintf("COURSE#%s#TIMEMAP#%s", cID, tID), gomock.Any(), ).SetArg(4, timemap) }, @@ -49,7 +53,7 @@ func TestTimemapStoreGet(t *testing.T) { gomock.Any(), userTableName, fmt.Sprintf("USER#%s", uID), - "TIMEMAP", + fmt.Sprintf("COURSE#%s#TIMEMAP#%s", cID, tID), gomock.Any(), ).Return(store.ErrNotFound) }, @@ -63,7 +67,7 @@ func TestTimemapStoreGet(t *testing.T) { gomock.Any(), userTableName, fmt.Sprintf("USER#%s", uID), - "TIMEMAP", + fmt.Sprintf("COURSE#%s#TIMEMAP#%s", cID, tID), gomock.Any(), ).Return(fmt.Errorf("error occurred")) }, @@ -83,7 +87,89 @@ func TestTimemapStoreGet(t *testing.T) { resolver := store.NewTimemapStore(clientMock) ctx := context.Background() - n, err := resolver.Get(ctx, uID) + n, err := resolver.Get(ctx, uID, cID, tID) + + if tt.expectedErr != nil { + assert.EqualError(t, err, tt.expectedErr.Error()) + } else { + assert.Nil(t, err) + assert.Equal(t, tt.expectedTimemap, n) + } + }) + } +} + +func TestTimemapStoreGetByCourseID(t *testing.T) { + uID := fake.CharactersN(10) + cID := fake.CharactersN(10) + + timemapOne := builder.NewTimemapBuilder(). + WithCourseID(cID). + WithUserID(uID). + Build() + + timemapTwo := builder.NewTimemapBuilder(). + WithCourseID(cID). + WithUserID(uID). + Build() + + timemaps := []store.Timemap{ + timemapOne, + timemapTwo, + } + + expectedExpression, _ := expression.NewBuilder(). + WithKeyCondition(expression.Key("PK").Equal(expression.Value(store.UserPK(uID)))). + WithFilter(expression.Name("SK").BeginsWith(store.CourseTimemapsSK(cID))). + Build() + + testCases := []struct { + desc string + clientExpectations func(client *storemocks.MockStorer) + + expectedTimemap []store.Timemap + expectedErr error + }{ + { + desc: "given a timemap is returned from store, timemap is returned", + clientExpectations: func(client *storemocks.MockStorer) { + client.EXPECT().Query( + gomock.Any(), + userTableName, + expectedExpression, + gomock.Any(), + ).SetArg(3, timemaps) + }, + + expectedTimemap: timemaps, + }, + { + desc: "given a generic error is returned from the store, error returned", + clientExpectations: func(client *storemocks.MockStorer) { + client.EXPECT().Query( + gomock.Any(), + userTableName, + expectedExpression, + gomock.Any(), + ).Return(fmt.Errorf("error occurred")) + }, + + expectedErr: fmt.Errorf("error occurred"), + }, + } + for _, tt := range testCases { + t.Run(tt.desc, func(t *testing.T) { + ctrl := gomock.NewController(t) + clientMock := storemocks.NewMockStorer(ctrl) + + if tt.clientExpectations != nil { + tt.clientExpectations(clientMock) + } + + resolver := store.NewTimemapStore(clientMock) + ctx := context.Background() + + n, err := resolver.GetByCourseID(ctx, uID, cID) if tt.expectedErr != nil { assert.EqualError(t, err, tt.expectedErr.Error()) @@ -97,23 +183,31 @@ func TestTimemapStoreGet(t *testing.T) { func TestTimemapStoreCreate(t *testing.T) { now := time.Now() - nID := fake.CharactersN(10) - timemap := builder.NewTimemapBuilder().WithID("").Build() + uID := fake.CharactersN(10) + cID := fake.CharactersN(10) + tID := fake.CharactersN(10) + timemap := builder.NewTimemapBuilder(). + WithCourseID(cID). + WithUserID(uID). + WithID(""). + Build() createTimemap := builder.NewTimemapBuilder(). - WithPK(fmt.Sprintf("USER#%s", timemap.UserID)). - WithSK("TIMEMAP"). - WithUserID(timemap.UserID). + WithPK(fmt.Sprintf("USER#%s", uID)). + WithSK(fmt.Sprintf("COURSE#%s#TIMEMAP#%s", cID, tID)). + WithID(tID). + WithCourseID(cID). + WithUserID(uID). WithMap(timemap.Map). - WithID(nID). WithDateUpdated(now). WithDateCreated(now). Build() expectedTimemap := builder.NewTimemapBuilder(). + WithCourseID(timemap.CourseID). WithUserID(timemap.UserID). WithMap(timemap.Map). - WithID(nID). + WithID(tID). WithDateUpdated(now). WithDateCreated(now). Build() @@ -152,7 +246,7 @@ func TestTimemapStoreCreate(t *testing.T) { } gen := func() string { - return nID + return tID } timer := func() time.Time { @@ -176,44 +270,59 @@ func TestTimemapStoreCreate(t *testing.T) { func TestTimemapStoreUpdate(t *testing.T) { now := time.Now() - id := fake.CharactersN(10) + tID := fake.CharactersN(10) uID := fake.CharactersN(10) - timemap := builder.NewTimemapBuilder(). + cID := fake.CharactersN(10) + + existingTimemap := builder.NewTimemapBuilder(). + WithID(tID). + WithCourseID(cID). WithUserID(uID). Build() + timemapWithoutID := builder.NewTimemapBuilder(). + WithID(""). + WithCourseID(cID). + WithUserID(uID). + WithMap(existingTimemap.Map). + Build() + expectedTimemap := builder.NewTimemapBuilder(). - WithUserID(timemap.UserID). - WithMap(timemap.Map). - WithID(timemap.ID). + WithUserID(uID). + WithCourseID(cID). + WithID(tID). + WithMap(existingTimemap.Map). WithDateCreated(now). WithDateUpdated(now). Build() + expectedExpression := expression. + Set(expression.Name("id"), expression.Name("id").IfNotExists(expression.Value(tID))). + Set(expression.Name("courseID"), expression.Name("courseID").IfNotExists(expression.Value(cID))). + Set(expression.Name("userID"), expression.Name("userID").IfNotExists(expression.Value(uID))). + Set(expression.Name("map"), expression.Value(existingTimemap.Map)). + Set(expression.Name("dateCreated"), expression.Name("dateCreated").IfNotExists(expression.Value(now))). + Set(expression.Name("dateUpdated"), expression.Value(now)) + testCases := []struct { desc string + timemap store.Timemap clientExpectations func(client *storemocks.MockStorer) expectedTimemap *store.Timemap expectedErr error }{ { - desc: "given a timemap is returned from store, timemap is returned", + desc: "given a timemap that has an ID and updated timemap is returned from store, timemap is returned", + timemap: existingTimemap, clientExpectations: func(client *storemocks.MockStorer) { - upBuilder := expression. - Set(expression.Name("id"), expression.Name("id").IfNotExists(expression.Value(id))). - Set(expression.Name("userID"), expression.Name("userID").IfNotExists(expression.Value(timemap.UserID))). - Set(expression.Name("map"), expression.Value(timemap.Map)). - Set(expression.Name("dateCreated"), expression.Name("dateCreated").IfNotExists(expression.Value(now))). - Set(expression.Name("dateUpdated"), expression.Value(now)) - - expr, _ := expression.NewBuilder().WithUpdate(upBuilder).Build() + expr, _ := expression.NewBuilder().WithUpdate(expectedExpression).Build() client.EXPECT().Update( gomock.Any(), userTableName, fmt.Sprintf("USER#%s", uID), - "TIMEMAP", + fmt.Sprintf("COURSE#%s#TIMEMAP#%s", cID, tID), expr, gomock.Any(), ).SetArg(5, expectedTimemap) @@ -222,22 +331,34 @@ func TestTimemapStoreUpdate(t *testing.T) { expectedTimemap: &expectedTimemap, }, { - desc: "given a generic error is returned from the store, error returned", + desc: "given a timemap without an ID and updated timemap is returned from store, timemap is returned", + timemap: timemapWithoutID, clientExpectations: func(client *storemocks.MockStorer) { - upBuilder := expression. - Set(expression.Name("id"), expression.Name("id").IfNotExists(expression.Value(id))). - Set(expression.Name("userID"), expression.Name("userID").IfNotExists(expression.Value(timemap.UserID))). - Set(expression.Name("map"), expression.Value(timemap.Map)). - Set(expression.Name("dateCreated"), expression.Name("dateCreated").IfNotExists(expression.Value(now))). - Set(expression.Name("dateUpdated"), expression.Value(now)) + expr, _ := expression.NewBuilder().WithUpdate(expectedExpression).Build() - expr, _ := expression.NewBuilder().WithUpdate(upBuilder).Build() + client.EXPECT().Update( + gomock.Any(), + userTableName, + fmt.Sprintf("USER#%s", uID), + fmt.Sprintf("COURSE#%s#TIMEMAP#%s", cID, tID), + expr, + gomock.Any(), + ).SetArg(5, expectedTimemap) + }, + + expectedTimemap: &expectedTimemap, + }, + { + desc: "given a generic error is returned from the store, error returned", + timemap: existingTimemap, + clientExpectations: func(client *storemocks.MockStorer) { + expr, _ := expression.NewBuilder().WithUpdate(expectedExpression).Build() client.EXPECT().Update( gomock.Any(), userTableName, fmt.Sprintf("USER#%s", uID), - "TIMEMAP", + fmt.Sprintf("COURSE#%s#TIMEMAP#%s", cID, tID), expr, gomock.Any(), ).Return(fmt.Errorf("error occurred")) @@ -256,17 +377,22 @@ func TestTimemapStoreUpdate(t *testing.T) { } gen := func() string { - return id + return tID } timer := func() time.Time { return now } - resolver := store.NewTimemapStore(clientMock, store.WithTimemapIDGenerator(gen), store.WithTimemapTimer(timer)) + resolver := store.NewTimemapStore( + clientMock, + store.WithTimemapIDGenerator(gen), + store.WithTimemapTimer(timer), + ) + ctx := context.Background() - n, err := resolver.Update(ctx, &timemap) + n, err := resolver.Update(ctx, tt.timemap) if tt.expectedErr != nil { assert.EqualError(t, err, tt.expectedErr.Error()) diff --git a/pkg/store/types.go b/pkg/store/types.go index 8d5d1db..17dfa99 100644 --- a/pkg/store/types.go +++ b/pkg/store/types.go @@ -58,6 +58,7 @@ type StepNote struct { type Timemap struct { BaseEntity ID string `dynamodbav:"id"` + CourseID string `dynamodbav:"courseID,omitempty"` UserID string `dynamodbav:"userID"` Map string `dynamodbav:"map"` DateCreated time.Time `dynamodbav:"dateCreated"`