Update dependencies (#1784)
This commit is contained in:
parent
4ab72acec6
commit
c6716e030c
26
go.mod
26
go.mod
@ -21,7 +21,7 @@ require (
|
||||
github.com/jpillora/backoff v1.0.0
|
||||
github.com/keybase/go-keybase-chat-bot v0.0.0-20211201215354-ee4b23828b55
|
||||
github.com/kyokomi/emoji/v2 v2.2.9
|
||||
github.com/labstack/echo/v4 v4.7.0
|
||||
github.com/labstack/echo/v4 v4.7.2
|
||||
github.com/lrstanley/girc v0.0.0-20220321215535-9664730c7858
|
||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20211016222428-79310a412696
|
||||
github.com/matterbridge/go-xmpp v0.0.0-20211030125215-791a06c5f1be
|
||||
@ -30,7 +30,7 @@ require (
|
||||
github.com/matterbridge/logrus-prefixed-formatter v0.5.3-0.20200523233437-d971309a77ba
|
||||
github.com/matterbridge/matterclient v0.0.0-20211107234719-faca3cd42315
|
||||
github.com/mattermost/mattermost-server/v5 v5.39.3
|
||||
github.com/mattermost/mattermost-server/v6 v6.4.2
|
||||
github.com/mattermost/mattermost-server/v6 v6.5.0
|
||||
github.com/mattn/godown v0.0.1
|
||||
github.com/mdp/qrterminal v1.0.1
|
||||
github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9
|
||||
@ -47,7 +47,7 @@ require (
|
||||
github.com/writeas/go-strip-markdown v2.0.1+incompatible
|
||||
github.com/yaegashi/msgraph.go v0.1.4
|
||||
github.com/zfjagann/golang-ring v0.0.0-20210116075443-7c86fdb43134
|
||||
go.mau.fi/whatsmeow v0.0.0-20220319105109-ee347f8c0a14
|
||||
go.mau.fi/whatsmeow v0.0.0-20220329131721-9f73bc00d158
|
||||
golang.org/x/image v0.0.0-20220302094943-723b81ca9867
|
||||
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a
|
||||
golang.org/x/text v0.3.7
|
||||
@ -55,7 +55,7 @@ require (
|
||||
google.golang.org/protobuf v1.27.1
|
||||
gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376
|
||||
layeh.com/gumble v0.0.0-20200818122324-146f9205029b
|
||||
modernc.org/sqlite v1.15.2
|
||||
modernc.org/sqlite v1.15.4
|
||||
)
|
||||
|
||||
require (
|
||||
@ -73,6 +73,7 @@ require (
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gopackage/ddp v0.0.3 // indirect
|
||||
github.com/graph-gophers/graphql-go v1.3.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
@ -80,7 +81,7 @@ require (
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/kettek/apng v0.0.0-20191108220231-414630eed80f // indirect
|
||||
github.com/klauspost/compress v1.14.2 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.11 // indirect
|
||||
github.com/labstack/gommon v0.3.1 // indirect
|
||||
github.com/magiconair/properties v1.8.5 // indirect
|
||||
github.com/mattermost/go-i18n v1.11.1-0.20211013152124-5c415071e404 // indirect
|
||||
@ -92,7 +93,7 @@ require (
|
||||
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.16 // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.21 // indirect
|
||||
github.com/minio/sha256-simd v1.0.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.3 // indirect
|
||||
@ -101,6 +102,7 @@ require (
|
||||
github.com/monaco-io/request v1.0.5 // indirect
|
||||
github.com/mreiferson/go-httpclient v0.0.0-20201222173833-5e475fde3a4d // indirect
|
||||
github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/pborman/uuid v1.2.1 // indirect
|
||||
github.com/pelletier/go-toml v1.9.4 // indirect
|
||||
github.com/philhofer/fwd v1.1.1 // indirect
|
||||
@ -133,22 +135,22 @@ require (
|
||||
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect
|
||||
golang.org/x/mod v0.5.1 // indirect
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
|
||||
golang.org/x/sys v0.0.0-20220207234003-57398862261d // indirect
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 // indirect
|
||||
golang.org/x/tools v0.1.7 // indirect
|
||||
golang.org/x/tools v0.1.9 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
gopkg.in/ini.v1 v1.66.2 // indirect
|
||||
gopkg.in/ini.v1 v1.66.3 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
lukechampine.com/uint128 v1.1.1 // indirect
|
||||
modernc.org/cc/v3 v3.35.24 // indirect
|
||||
modernc.org/ccgo/v3 v3.15.17 // indirect
|
||||
modernc.org/libc v1.14.11 // indirect
|
||||
modernc.org/ccgo/v3 v3.15.18 // indirect
|
||||
modernc.org/libc v1.14.12 // indirect
|
||||
modernc.org/mathutil v1.4.1 // indirect
|
||||
modernc.org/memory v1.0.6 // indirect
|
||||
modernc.org/memory v1.0.7 // indirect
|
||||
modernc.org/opt v0.1.1 // indirect
|
||||
modernc.org/strutil v1.1.1 // indirect
|
||||
modernc.org/token v1.0.0 // indirect
|
||||
|
116
go.sum
116
go.sum
@ -32,6 +32,7 @@ cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aD
|
||||
cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
|
||||
cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
|
||||
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
|
||||
cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM=
|
||||
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
@ -114,7 +115,7 @@ github.com/Masterminds/glide v0.13.2/go.mod h1:STyF5vcenH/rUqTEv+/hBXlSTo7KYwg2o
|
||||
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/Masterminds/squirrel v1.5.0/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||
github.com/Masterminds/squirrel v1.5.1/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||
github.com/Masterminds/squirrel v1.5.2/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||
github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
|
||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
@ -208,7 +209,7 @@ github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN
|
||||
github.com/aws/aws-sdk-go v1.19.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.38.67/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||
github.com/aws/aws-sdk-go v1.42.11/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
|
||||
github.com/aws/aws-sdk-go v1.42.49/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc=
|
||||
github.com/aws/aws-sdk-go-v2 v1.8.0/go.mod h1:xEFuWz+3TYdlPRuo+CqATbeDWIWyaT5uAPwPaWtgse0=
|
||||
github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.6.0/go.mod h1:TNtBVmka80lRPk5+S9ZqVfFszOQAGJJ9KbT3EM3CHNU=
|
||||
@ -236,6 +237,7 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21
|
||||
github.com/aws/smithy-go v1.7.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
|
||||
github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
|
||||
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
|
||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
|
||||
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
|
||||
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
@ -435,6 +437,7 @@ github.com/couchbase/vellum v1.0.2/go.mod h1:FcwrEivFpNi24R3jLOs3n+fs5RnuQnQqCLB
|
||||
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/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
@ -549,13 +552,12 @@ github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYis
|
||||
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
|
||||
github.com/getsentry/sentry-go v0.11.0/go.mod h1:KBQIxiZAetw62Cj8Ri964vAEWVdgfaUCn30Q3bCvANo=
|
||||
github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gigawattio/window v0.0.0-20180317192513-0f5467e35573/go.mod h1:eBvb3i++NHDH4Ugo9qCvMw8t0mTSctaEa5blJbWcNxs=
|
||||
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
||||
github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
|
||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
||||
@ -582,7 +584,7 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
|
||||
github.com/go-morph/morph v0.2.3-0.20220126093237-74bffc135498/go.mod h1:XQh5WcM351wOV3z3zEWRM8RaJ65E2p4P7WWbmFAi8x4=
|
||||
github.com/go-morph/morph v0.2.3-0.20220215130848-76392b135ee5/go.mod h1:XQh5WcM351wOV3z3zEWRM8RaJ65E2p4P7WWbmFAi8x4=
|
||||
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-ole/go-ole v1.2.6-0.20210915003542-8b1f7f90f6b1/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
@ -592,8 +594,6 @@ github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL9
|
||||
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
|
||||
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
|
||||
github.com/go-redis/redis/v8 v8.0.0/go.mod h1:isLoQT/NFSP7V67lyvM9GmdvLdyZ7pEhsXvvyQtnQTo=
|
||||
github.com/go-redis/redis/v8 v8.10.0/go.mod h1:vXLTvigok0VtUX0znvbcEW1SOt4OA9CU1ZfnOtKOaiM=
|
||||
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
|
||||
@ -771,9 +771,10 @@ github.com/gopackage/ddp v0.0.3/go.mod h1:3hUXYG6C/6JsoxKsQaK7st09+GP9RZBFPzyAlU
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20210621113107-84c6004145de/go.mod h1:MtKwTfDNYAP5EtbQSMYjTSqvj1aXJKQRASWq3bwaP+g=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20211111143520-d0d5ecc1a356 h1:d3wWSjdOuGrMHa8+Tvw3z9EGPzATpzVq1BmGK3+IyeU=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20211111143520-d0d5ecc1a356/go.mod h1:cz9oNYuRUWGdHmLF2IodMLkAhcPtXeULvcBNagUrxTI=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20220104163920-15ed2e8cf2bd h1:D/H64OK+VY7O0guGbCQaFKwAZlU5t764R++kgIdAGog=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20220104163920-15ed2e8cf2bd/go.mod h1:cz9oNYuRUWGdHmLF2IodMLkAhcPtXeULvcBNagUrxTI=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
|
||||
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
|
||||
@ -790,6 +791,8 @@ github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0=
|
||||
github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
@ -808,6 +811,7 @@ github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b/go.mod h1:VzxiSdG6j1p
|
||||
github.com/harmony-development/shibshib v0.0.0-20220101224523-c98059d09cfa h1:0EefSRfsNrdEwmoGVz4+cMG8++5M2XhvJ1tTRmmrJu8=
|
||||
github.com/harmony-development/shibshib v0.0.0-20220101224523-c98059d09cfa/go.mod h1:+KEOMb29OC2kRa5BajwNM2NEjHTbQA/Z3gKYARLHREI=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
|
||||
github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
|
||||
@ -822,6 +826,7 @@ github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39
|
||||
github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-hclog v0.16.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-hclog v1.1.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
@ -852,11 +857,15 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
|
||||
github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||
github.com/hashicorp/memberlist v0.2.4/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||
github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||
github.com/hashicorp/memberlist v0.3.1/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
|
||||
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
|
||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
||||
@ -1009,8 +1018,8 @@ github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd
|
||||
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.0.6/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.0.11 h1:i2lw1Pm7Yi/4O6XCSyJWqEHI2MDw2FzUK6o/D21xn2A=
|
||||
github.com/klauspost/cpuid/v2 v2.0.11/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
|
||||
github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/kljensen/snowball v0.6.0/go.mod h1:27N7E8fVU5H68RlUmnWwZCfxgt4POBJfENGMvNRhldw=
|
||||
@ -1035,15 +1044,15 @@ github.com/ktrysmt/go-bitbucket v0.6.4/go.mod h1:9u0v3hsd2rqCHRIpbir1oP7F58uo5dq
|
||||
github.com/kyokomi/emoji/v2 v2.2.9 h1:UWYkjplPZ4rMPvLxc+/e12/xTqoRcn55oUySkpZ554g=
|
||||
github.com/kyokomi/emoji/v2 v2.2.9/go.mod h1:JUcn42DTdsXJo1SWanHh4HKDEyPaR5CqkmoirZZP9qE=
|
||||
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
|
||||
github.com/labstack/echo/v4 v4.7.0 h1:8wHgZhoE9OT1NSLw6sfrX7ZGpWMtO5Zlfr68+BIo180=
|
||||
github.com/labstack/echo/v4 v4.7.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
||||
github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y=
|
||||
github.com/labstack/echo/v4 v4.7.2 h1:Kv2/p8OaQ+M6Ex4eGimg9b9e6icoxA42JSlOR3msKtI=
|
||||
github.com/labstack/echo/v4 v4.7.2/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
||||
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
|
||||
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
|
||||
github.com/ledongthuc/pdf v0.0.0-20210621053716-e28cb8259002/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
|
||||
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
|
||||
github.com/levigross/exp-html v0.0.0-20120902181939-8df60c69a8f5/go.mod h1:QMe2wuKJ0o7zIVE8AqiT8rd8epmm6WDIZ2wyuBqYPzM=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
@ -1100,8 +1109,8 @@ github.com/mattermost/logr/v2 v2.0.15/go.mod h1:mpPp935r5dIkFDo2y9Q87cQWhFR/4xXp
|
||||
github.com/mattermost/mattermost-server/v5 v5.39.3 h1:A5z/NlR4Xcwxx5UnlaNgUGP5hgj4KOV/CwpFg3OtlvQ=
|
||||
github.com/mattermost/mattermost-server/v5 v5.39.3/go.mod h1:MDmVSmsSsqwNkuZ7rQ0osuXVCzrR1IUqGR7I0QU91sY=
|
||||
github.com/mattermost/mattermost-server/v6 v6.0.0/go.mod h1:+S8CsNEPv1FOl1usaPBQ6Gu9+Sm1Cc9YdU/Qh1YMGVI=
|
||||
github.com/mattermost/mattermost-server/v6 v6.4.2 h1:UyrYoBYrV7dB7JWSEOPXKZaTyYZE2PRDysqx/54ayng=
|
||||
github.com/mattermost/mattermost-server/v6 v6.4.2/go.mod h1:5dOl/bx4N9iTytZ4p44xfGiOiZelbdap42FbEjmN+FU=
|
||||
github.com/mattermost/mattermost-server/v6 v6.5.0 h1:9S+/vQirO4XNpT+4TC/MlHNYpd2bgFvoRnBkImRCtNQ=
|
||||
github.com/mattermost/mattermost-server/v6 v6.5.0/go.mod h1:JRRn3uSrynvCY45ystGEJqis/Xo8PFhCDSO4SNDMncU=
|
||||
github.com/mattermost/rsc v0.0.0-20160330161541-bbaefb05eaa0/go.mod h1:nV5bfVpT//+B1RPD2JvRnxbkLmJEYXmRaaVl15fsXjs=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
@ -1138,7 +1147,7 @@ github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vq
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/godown v0.0.1 h1:39uk50ufLVQFs0eapIJVX5fCS74a1Fs2g5f1MVqIHdE=
|
||||
@ -1156,17 +1165,19 @@ github.com/mholt/archiver/v3 v3.5.0/go.mod h1:qqTTPUK/HZPFgFQ/TJ3BzvTpF/dPtFVJXd
|
||||
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
|
||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
|
||||
github.com/microcosm-cc/bluemonday v1.0.18/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
||||
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
||||
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
|
||||
github.com/miekg/dns v1.1.46/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
|
||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||
github.com/minio/minio-go/v7 v7.0.11/go.mod h1:WoyW+ySKAKjY98B9+7ZbI8z8S3jaxaisdcvj9TGlazA=
|
||||
github.com/minio/minio-go/v7 v7.0.16 h1:GspaSBS8lOuEUCAqMe0W3UxSoyOA4b4F8PTspRVI+k4=
|
||||
github.com/minio/minio-go/v7 v7.0.16/go.mod h1:pUV0Pc+hPd1nccgmzQF/EXh48l/Z/yps6QPF1aaie4g=
|
||||
github.com/minio/minio-go/v7 v7.0.21 h1:xrc4BQr1Fa4s5RwY0xfMjPZFJ1bcYBCCHYlngBdWV+k=
|
||||
github.com/minio/minio-go/v7 v7.0.21/go.mod h1:ei5JjmxwHaMrgsMrn4U/+Nmg+d8MKS1U2DAn1ou4+Do=
|
||||
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
||||
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
|
||||
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
|
||||
@ -1282,6 +1293,7 @@ github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7
|
||||
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
|
||||
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/oov/psd v0.0.0-20210618170533-9fb823ddb631/go.mod h1:GHI1bnmAcbp96z6LNfBJvtrjxhaXGkbsk967utPlvL8=
|
||||
github.com/oov/psd v0.0.0-20220121172623-5db5eafcecbb/go.mod h1:GHI1bnmAcbp96z6LNfBJvtrjxhaXGkbsk967utPlvL8=
|
||||
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
@ -1305,6 +1317,8 @@ github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mo
|
||||
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
|
||||
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
|
||||
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
@ -1338,7 +1352,7 @@ github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi
|
||||
github.com/pierrec/lz4/v4 v4.0.3/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.8/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.11/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
||||
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
@ -1366,6 +1380,7 @@ github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3O
|
||||
github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
@ -1405,6 +1420,7 @@ github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qq
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/richardlehane/mscfb v1.0.3/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
|
||||
github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
|
||||
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
||||
github.com/rickb777/date v1.12.4 h1:+6IzcCCS/1t17DrmnEvrznyq7nM8vPwir6/UhlyohKw=
|
||||
github.com/rickb777/date v1.12.4/go.mod h1:xP0eo/I5qmUt97yRGClHZfyLZ3ikMw6v6SU5MOGZTE0=
|
||||
@ -1424,24 +1440,27 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rs/cors v1.8.0/go.mod h1:EBwu+T5AvHOcXwvZIkQFjUN6s8Czyqw12GL/Y0tUyRM=
|
||||
github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/xid v1.3.0 h1:6NjYksEUlhurdVehpc7S7dk6DAmcKv8V9gG0FsVN2U4=
|
||||
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
github.com/rudderlabs/analytics-go v3.3.1+incompatible/go.mod h1:LF8/ty9kUX4PTY3l5c97K3nZZaX5Hwsvt+NBaRL/f30=
|
||||
github.com/rudderlabs/analytics-go v3.3.2+incompatible/go.mod h1:LF8/ty9kUX4PTY3l5c97K3nZZaX5Hwsvt+NBaRL/f30=
|
||||
github.com/russellhaering/goxmldsig v1.1.0/go.mod h1:QK8GhXPB3+AfuCrfo0oRISa9NfzeCpWmxeGnqEpDF9o=
|
||||
github.com/russellhaering/goxmldsig v1.1.1/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
|
||||
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
|
||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
|
||||
github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
|
||||
github.com/sagikazarmark/crypt v0.4.0/go.mod h1:ALv2SRj7GxYV4HO9elxH9nS6M9gW+xDNxqmyJ6RfDFM=
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
||||
@ -1535,6 +1554,7 @@ github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tL
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
||||
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
|
||||
github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
@ -1548,6 +1568,7 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
|
||||
github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM=
|
||||
github.com/spf13/viper v1.10.1 h1:nuJZuYpG7gTj/XqiUwg8bA0cp1+M2mC3J4g5luUYBKk=
|
||||
github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU=
|
||||
github.com/splitio/go-client/v6 v6.1.0/go.mod h1:CEGAEFT99Fwb32ZIRcnZoXTMXddtB6IIpTmt3RP8mnM=
|
||||
@ -1583,7 +1604,7 @@ github.com/tebeka/snowball v0.4.2/go.mod h1:4IfL14h1lvwZcp1sfXuuc7/7yCsvVffTWxWx
|
||||
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8=
|
||||
github.com/throttled/throttled v2.2.5+incompatible/go.mod h1:0BjlrEGQmvxps+HuXLsyRdqpSRvJpq0PNIsOtqP9Nos=
|
||||
github.com/tidwall/gjson v1.8.0/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk=
|
||||
github.com/tidwall/gjson v1.11.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
@ -1607,6 +1628,7 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1
|
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
github.com/tylerb/graceful v1.2.15/go.mod h1:LPYTbOYmUTdabwRt0TGhLllQ0MUNbs0Y5q1WXJOI9II=
|
||||
github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
@ -1688,8 +1710,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.3.8/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.4/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg=
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.5/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg=
|
||||
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
||||
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
||||
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
||||
@ -1711,8 +1733,8 @@ go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsX
|
||||
go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs=
|
||||
go.mau.fi/libsignal v0.0.0-20220315232917-871a40435d3b h1:BGm0ceth6OtoXgBksEyeruiCL2ngZCwt86DUmUI6TmQ=
|
||||
go.mau.fi/libsignal v0.0.0-20220315232917-871a40435d3b/go.mod h1:XYWsswZT1LfDmguWKYDuj+OugtdGX6CP3iwTtOcAGt4=
|
||||
go.mau.fi/whatsmeow v0.0.0-20220319105109-ee347f8c0a14 h1:ExTTrre0VoTljTf08nGeE24i2aqNF4CxQVnlFYEiQUg=
|
||||
go.mau.fi/whatsmeow v0.0.0-20220319105109-ee347f8c0a14/go.mod h1:P7OA9XyJ/0dWHhUPKNESpC1wVOErnhY4pLEaMC1a8yg=
|
||||
go.mau.fi/whatsmeow v0.0.0-20220329131721-9f73bc00d158 h1:FLwtX7WD+SHGaSiHZwSiCCP155A7+oYdQ+6nr1Lvhms=
|
||||
go.mau.fi/whatsmeow v0.0.0-20220329131721-9f73bc00d158/go.mod h1:P7OA9XyJ/0dWHhUPKNESpC1wVOErnhY4pLEaMC1a8yg=
|
||||
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.mongodb.org/mongo-driver v1.7.0/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8=
|
||||
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
|
||||
@ -1793,7 +1815,7 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220208233918-bba287dce954/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38=
|
||||
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@ -1926,14 +1948,15 @@ golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211013171255-e13a2654a71e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@ -2091,7 +2114,6 @@ golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210818153620-00dd8d7831e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@ -2101,11 +2123,15 @@ golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220207234003-57398862261d h1:Bm7BNOQt2Qv7ZqysjeLjgCBanX+88Z/OtdvsrEv1Djc=
|
||||
golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||
@ -2214,8 +2240,9 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8=
|
||||
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@ -2269,6 +2296,7 @@ google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqiv
|
||||
google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
|
||||
google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=
|
||||
google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
|
||||
google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw=
|
||||
google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=
|
||||
google.golang.org/appengine v1.0.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
@ -2360,8 +2388,11 @@ google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ6
|
||||
google.golang.org/genproto v0.0.0-20211013025323-ce878158c4d4/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20220208230804-65c12eb4c068/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
|
||||
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
@ -2401,6 +2432,7 @@ google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K
|
||||
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
|
||||
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
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=
|
||||
@ -2431,16 +2463,15 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy
|
||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
||||
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.64.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI=
|
||||
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.66.3 h1:jRskFVxYaMGAMUbN0UZ7niA9gzL9B49DOqE78vg0k3w=
|
||||
gopkg.in/ini.v1 v1.66.3/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
|
||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
@ -2583,8 +2614,9 @@ modernc.org/ccgo/v3 v3.15.12/go.mod h1:VFePOWoCd8uDGRJpq/zfJ29D0EVzMSyID8LCMWYbX
|
||||
modernc.org/ccgo/v3 v3.15.14/go.mod h1:144Sz2iBCKogb9OKwsu7hQEub3EVgOlyI8wMUPGKUXQ=
|
||||
modernc.org/ccgo/v3 v3.15.15/go.mod h1:z5qltXjU4PJl0pE5nhYQCvA9DhPHiWsl5GWl89+NSYE=
|
||||
modernc.org/ccgo/v3 v3.15.16/go.mod h1:XbKRMeMWMdq712Tr5ECgATYMrzJ+g9zAZEj2ktzBe24=
|
||||
modernc.org/ccgo/v3 v3.15.17 h1:svaDk4rfh7XQPBwkqzjKK8bta/vK4VVL3JP6ZLbcr0w=
|
||||
modernc.org/ccgo/v3 v3.15.17/go.mod h1:bofnFkpRFf5gLY+mBZIyTW6FEcp26xi2lgOFk2Rlvs0=
|
||||
modernc.org/ccgo/v3 v3.15.18 h1:X5ym656Ye7/ubL+wox0SeF9aRX5od1UDFn1tAbQR+90=
|
||||
modernc.org/ccgo/v3 v3.15.18/go.mod h1:/2lv3WjHyanEr2sAPdGKRC38n6f0werut9BRXUjjX+A=
|
||||
modernc.org/ccorpus v1.11.1/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
||||
modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk=
|
||||
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
||||
@ -2642,8 +2674,9 @@ modernc.org/libc v1.14.6/go.mod h1:2PJHINagVxO4QW/5OQdRrvMYo+bm5ClpUFfyXCYl9ak=
|
||||
modernc.org/libc v1.14.7/go.mod h1:f8xfWXW8LW41qb4X5+huVQo5dcfPlq7Cbny2TDheMv0=
|
||||
modernc.org/libc v1.14.8/go.mod h1:9+JCLb1MWSY23smyOpIPbd5ED+rSS/ieiDWUpdyO3mo=
|
||||
modernc.org/libc v1.14.10/go.mod h1:y1MtIWhwpJFpLYm6grAThtuXJKEsY6xkdZmXbRngIdo=
|
||||
modernc.org/libc v1.14.11 h1:ivxNmUkfp5iSGAGMIjylvx5R53s6QTJW9qUru1yrnk4=
|
||||
modernc.org/libc v1.14.11/go.mod h1:l5/Mz/GrZwOqzwRHA3abgSCnSeJzzTl+Ify0bAwKbAw=
|
||||
modernc.org/libc v1.14.12 h1:pUBZTYoISfbb4pCf4PECENpbvwDBxeKc+/dS9LyOWFM=
|
||||
modernc.org/libc v1.14.12/go.mod h1:fJdoe23MHu2ruPQkFPPqCpToDi5cckzsbmkI6Ez0LqQ=
|
||||
modernc.org/lldb v1.0.0/go.mod h1:jcRvJGWfCGodDZz8BPwiKMJxGJngQ/5DrRapkQnLob8=
|
||||
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
|
||||
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
@ -2653,15 +2686,16 @@ modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8=
|
||||
modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
|
||||
modernc.org/memory v1.0.5/go.mod h1:B7OYswTRnfGg+4tDH1t1OeUNnsy2viGTdME4tzd+IjM=
|
||||
modernc.org/memory v1.0.6 h1:5IaT/LChMrMdxLCy/a4qmb+7SzGiU8/ozPgkEOrfvFw=
|
||||
modernc.org/memory v1.0.6/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=
|
||||
modernc.org/memory v1.0.7 h1:UE3cxTRFa5tfUibAV7Jqq8P7zRY0OlJg+yWVIIaluEE=
|
||||
modernc.org/memory v1.0.7/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=
|
||||
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
|
||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/ql v1.0.0/go.mod h1:xGVyrLIatPcO2C1JvI/Co8c0sr6y91HKFNy4pt9JXEY=
|
||||
modernc.org/sortutil v1.1.0/go.mod h1:ZyL98OQHJgH9IEfN71VsamvJgrtRX9Dj2gX+vH86L1k=
|
||||
modernc.org/sqlite v1.10.6/go.mod h1:Z9FEjUtZP4qFEg6/SiADg9XCER7aYy9a/j7Pg9P7CPs=
|
||||
modernc.org/sqlite v1.15.2 h1:Es0SrEJUQHH7rt6uC/Zh2gHQ0AUhgB+F2RQqpXf3MNs=
|
||||
modernc.org/sqlite v1.15.2/go.mod h1:2P9bWfawhYMpYsBELqKREE+LFZo4uPApOuqszlZ7QX8=
|
||||
modernc.org/sqlite v1.15.4 h1:pr3EA3Rety3j1c/9pCyGAe5d3vjF6wQwusHdgGCjIqc=
|
||||
modernc.org/sqlite v1.15.4/go.mod h1:Jwe13ItpESZ+78K5WS6+AjXsUg+JvirsjN3iIDO4C8k=
|
||||
modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
|
||||
modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
|
||||
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
|
||||
|
5
vendor/github.com/graph-gophers/graphql-go/.gitignore
generated
vendored
Normal file
5
vendor/github.com/graph-gophers/graphql-go/.gitignore
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
/.idea
|
||||
/.vscode
|
||||
/internal/validation/testdata/graphql-js
|
||||
/internal/validation/testdata/node_modules
|
||||
/vendor
|
35
vendor/github.com/graph-gophers/graphql-go/.golangci.yml
generated
vendored
Normal file
35
vendor/github.com/graph-gophers/graphql-go/.golangci.yml
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
run:
|
||||
timeout: 5m
|
||||
|
||||
linters-settings:
|
||||
gofmt:
|
||||
simplify: true
|
||||
govet:
|
||||
check-shadowing: true
|
||||
enable-all: true
|
||||
disable:
|
||||
- fieldalignment
|
||||
- deepequalerrors # remove later
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- deadcode
|
||||
- gofmt
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- exportloopref
|
||||
- structcheck
|
||||
- staticcheck
|
||||
- unconvert
|
||||
- unused
|
||||
- varcheck
|
||||
- misspell
|
||||
- goimports
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
- linters:
|
||||
- unused
|
||||
path: "graphql_test.go"
|
10
vendor/github.com/graph-gophers/graphql-go/CHANGELOG.md
generated
vendored
Normal file
10
vendor/github.com/graph-gophers/graphql-go/CHANGELOG.md
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
CHANGELOG
|
||||
|
||||
[v1.1.0](https://github.com/graph-gophers/graphql-go/releases/tag/v1.1.0) Release v1.1.0
|
||||
* [FEATURE] Add types package #437
|
||||
* [FEATURE] Expose `packer.Unmarshaler` as `decode.Unmarshaler` to the public #450
|
||||
* [FEATURE] Add location fields to type definitions #454
|
||||
* [FEATURE] `errors.Errorf` preserves original error similar to `fmt.Errorf` #456
|
||||
* [BUGFIX] Fix duplicated __typename in response (fixes #369) #443
|
||||
|
||||
[v1.0.0](https://github.com/graph-gophers/graphql-go/releases/tag/v1.0.0) Initial release
|
13
vendor/github.com/graph-gophers/graphql-go/CONTRIBUTING.md
generated
vendored
Normal file
13
vendor/github.com/graph-gophers/graphql-go/CONTRIBUTING.md
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
## Contributing
|
||||
|
||||
- With issues:
|
||||
- Use the search tool before opening a new issue.
|
||||
- Please provide source code and commit sha if you found a bug.
|
||||
- Review existing issues and provide feedback or react to them.
|
||||
|
||||
- With pull requests:
|
||||
- Open your pull request against `master`
|
||||
- Your pull request should have no more than two commits, if not you should squash them.
|
||||
- It should pass all tests in the available continuous integrations systems such as TravisCI.
|
||||
- You should add/modify tests to cover your proposed code changes.
|
||||
- If your pull request contains a new feature, please document it on the README.
|
24
vendor/github.com/graph-gophers/graphql-go/LICENSE
generated
vendored
Normal file
24
vendor/github.com/graph-gophers/graphql-go/LICENSE
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
Copyright (c) 2016 Richard Musiol. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
169
vendor/github.com/graph-gophers/graphql-go/README.md
generated
vendored
Normal file
169
vendor/github.com/graph-gophers/graphql-go/README.md
generated
vendored
Normal file
@ -0,0 +1,169 @@
|
||||
# graphql-go [![Sourcegraph](https://sourcegraph.com/github.com/graph-gophers/graphql-go/-/badge.svg)](https://sourcegraph.com/github.com/graph-gophers/graphql-go?badge) [![Build Status](https://graph-gophers.semaphoreci.com/badges/graphql-go/branches/master.svg?style=shields)](https://graph-gophers.semaphoreci.com/projects/graphql-go) [![GoDoc](https://godoc.org/github.com/graph-gophers/graphql-go?status.svg)](https://godoc.org/github.com/graph-gophers/graphql-go)
|
||||
|
||||
<p align="center"><img src="docs/img/logo.png" width="300"></p>
|
||||
|
||||
The goal of this project is to provide full support of the [GraphQL draft specification](https://facebook.github.io/graphql/draft) with a set of idiomatic, easy to use Go packages.
|
||||
|
||||
While still under heavy development (`internal` APIs are almost certainly subject to change), this library is
|
||||
safe for production use.
|
||||
|
||||
## Features
|
||||
|
||||
- minimal API
|
||||
- support for `context.Context`
|
||||
- support for the `OpenTracing` standard
|
||||
- schema type-checking against resolvers
|
||||
- resolvers are matched to the schema based on method sets (can resolve a GraphQL schema with a Go interface or Go struct).
|
||||
- handles panics in resolvers
|
||||
- parallel execution of resolvers
|
||||
- subscriptions
|
||||
- [sample WS transport](https://github.com/graph-gophers/graphql-transport-ws)
|
||||
|
||||
## Roadmap
|
||||
|
||||
We're trying out the GitHub Project feature to manage `graphql-go`'s [development roadmap](https://github.com/graph-gophers/graphql-go/projects/1).
|
||||
Feedback is welcome and appreciated.
|
||||
|
||||
## (Some) Documentation
|
||||
|
||||
### Basic Sample
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
graphql "github.com/graph-gophers/graphql-go"
|
||||
"github.com/graph-gophers/graphql-go/relay"
|
||||
)
|
||||
|
||||
type query struct{}
|
||||
|
||||
func (_ *query) Hello() string { return "Hello, world!" }
|
||||
|
||||
func main() {
|
||||
s := `
|
||||
type Query {
|
||||
hello: String!
|
||||
}
|
||||
`
|
||||
schema := graphql.MustParseSchema(s, &query{})
|
||||
http.Handle("/query", &relay.Handler{Schema: schema})
|
||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}
|
||||
```
|
||||
|
||||
To test:
|
||||
|
||||
```sh
|
||||
curl -XPOST -d '{"query": "{ hello }"}' localhost:8080/query
|
||||
```
|
||||
|
||||
### Resolvers
|
||||
|
||||
A resolver must have one method or field for each field of the GraphQL type it resolves. The method or field name has to be [exported](https://golang.org/ref/spec#Exported_identifiers) and match the schema's field's name in a non-case-sensitive way.
|
||||
You can use struct fields as resolvers by using `SchemaOpt: UseFieldResolvers()`. For example,
|
||||
```
|
||||
opts := []graphql.SchemaOpt{graphql.UseFieldResolvers()}
|
||||
schema := graphql.MustParseSchema(s, &query{}, opts...)
|
||||
```
|
||||
|
||||
When using `UseFieldResolvers` schema option, a struct field will be used *only* when:
|
||||
- there is no method for a struct field
|
||||
- a struct field does not implement an interface method
|
||||
- a struct field does not have arguments
|
||||
|
||||
The method has up to two arguments:
|
||||
|
||||
- Optional `context.Context` argument.
|
||||
- Mandatory `*struct { ... }` argument if the corresponding GraphQL field has arguments. The names of the struct fields have to be [exported](https://golang.org/ref/spec#Exported_identifiers) and have to match the names of the GraphQL arguments in a non-case-sensitive way.
|
||||
|
||||
The method has up to two results:
|
||||
|
||||
- The GraphQL field's value as determined by the resolver.
|
||||
- Optional `error` result.
|
||||
|
||||
Example for a simple resolver method:
|
||||
|
||||
```go
|
||||
func (r *helloWorldResolver) Hello() string {
|
||||
return "Hello world!"
|
||||
}
|
||||
```
|
||||
|
||||
The following signature is also allowed:
|
||||
|
||||
```go
|
||||
func (r *helloWorldResolver) Hello(ctx context.Context) (string, error) {
|
||||
return "Hello world!", nil
|
||||
}
|
||||
```
|
||||
|
||||
### Schema Options
|
||||
|
||||
- `UseStringDescriptions()` enables the usage of double quoted and triple quoted. When this is not enabled, comments are parsed as descriptions instead.
|
||||
- `UseFieldResolvers()` specifies whether to use struct field resolvers.
|
||||
- `MaxDepth(n int)` specifies the maximum field nesting depth in a query. The default is 0 which disables max depth checking.
|
||||
- `MaxParallelism(n int)` specifies the maximum number of resolvers per request allowed to run in parallel. The default is 10.
|
||||
- `Tracer(tracer trace.Tracer)` is used to trace queries and fields. It defaults to `trace.OpenTracingTracer`.
|
||||
- `ValidationTracer(tracer trace.ValidationTracer)` is used to trace validation errors. It defaults to `trace.NoopValidationTracer`.
|
||||
- `Logger(logger log.Logger)` is used to log panics during query execution. It defaults to `exec.DefaultLogger`.
|
||||
- `PanicHandler(panicHandler errors.PanicHandler)` is used to transform panics into errors during query execution. It defaults to `errors.DefaultPanicHandler`.
|
||||
- `DisableIntrospection()` disables introspection queries.
|
||||
|
||||
### Custom Errors
|
||||
|
||||
Errors returned by resolvers can include custom extensions by implementing the `ResolverError` interface:
|
||||
|
||||
```go
|
||||
type ResolverError interface {
|
||||
error
|
||||
Extensions() map[string]interface{}
|
||||
}
|
||||
```
|
||||
|
||||
Example of a simple custom error:
|
||||
|
||||
```go
|
||||
type droidNotFoundError struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func (e droidNotFoundError) Error() string {
|
||||
return fmt.Sprintf("error [%s]: %s", e.Code, e.Message)
|
||||
}
|
||||
|
||||
func (e droidNotFoundError) Extensions() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"code": e.Code,
|
||||
"message": e.Message,
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Which could produce a GraphQL error such as:
|
||||
|
||||
```go
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"message": "error [NotFound]: This is not the droid you are looking for",
|
||||
"path": [
|
||||
"droid"
|
||||
],
|
||||
"extensions": {
|
||||
"code": "NotFound",
|
||||
"message": "This is not the droid you are looking for"
|
||||
}
|
||||
}
|
||||
],
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
### [Examples](https://github.com/graph-gophers/graphql-go/wiki/Examples)
|
||||
|
||||
### [Companies that use this library](https://github.com/graph-gophers/graphql-go/wiki/Users)
|
13
vendor/github.com/graph-gophers/graphql-go/decode/decode.go
generated
vendored
Normal file
13
vendor/github.com/graph-gophers/graphql-go/decode/decode.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
package decode
|
||||
|
||||
// Unmarshaler defines the api of Go types mapped to custom GraphQL scalar types
|
||||
type Unmarshaler interface {
|
||||
// ImplementsGraphQLType maps the implementing custom Go type
|
||||
// to the GraphQL scalar type in the schema.
|
||||
ImplementsGraphQLType(name string) bool
|
||||
// UnmarshalGraphQL is the custom unmarshaler for the implementing type
|
||||
//
|
||||
// This function will be called whenever you use the
|
||||
// custom GraphQL scalar type as an input
|
||||
UnmarshalGraphQL(input interface{}) error
|
||||
}
|
59
vendor/github.com/graph-gophers/graphql-go/errors/errors.go
generated
vendored
Normal file
59
vendor/github.com/graph-gophers/graphql-go/errors/errors.go
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type QueryError struct {
|
||||
Err error `json:"-"` // Err holds underlying if available
|
||||
Message string `json:"message"`
|
||||
Locations []Location `json:"locations,omitempty"`
|
||||
Path []interface{} `json:"path,omitempty"`
|
||||
Rule string `json:"-"`
|
||||
ResolverError error `json:"-"`
|
||||
Extensions map[string]interface{} `json:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
type Location struct {
|
||||
Line int `json:"line"`
|
||||
Column int `json:"column"`
|
||||
}
|
||||
|
||||
func (a Location) Before(b Location) bool {
|
||||
return a.Line < b.Line || (a.Line == b.Line && a.Column < b.Column)
|
||||
}
|
||||
|
||||
func Errorf(format string, a ...interface{}) *QueryError {
|
||||
// similar to fmt.Errorf, Errorf will wrap the last argument if it is an instance of error
|
||||
var err error
|
||||
if n := len(a); n > 0 {
|
||||
if v, ok := a[n-1].(error); ok {
|
||||
err = v
|
||||
}
|
||||
}
|
||||
|
||||
return &QueryError{
|
||||
Err: err,
|
||||
Message: fmt.Sprintf(format, a...),
|
||||
}
|
||||
}
|
||||
|
||||
func (err *QueryError) Error() string {
|
||||
if err == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
str := fmt.Sprintf("graphql: %s", err.Message)
|
||||
for _, loc := range err.Locations {
|
||||
str += fmt.Sprintf(" (line %d, column %d)", loc.Line, loc.Column)
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
func (err *QueryError) Unwrap() error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return err.Err
|
||||
}
|
||||
|
||||
var _ error = &QueryError{}
|
18
vendor/github.com/graph-gophers/graphql-go/errors/panic_handler.go
generated
vendored
Normal file
18
vendor/github.com/graph-gophers/graphql-go/errors/panic_handler.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
// PanicHandler is the interface used to create custom panic errors that occur during query execution
|
||||
type PanicHandler interface {
|
||||
MakePanicError(ctx context.Context, value interface{}) *QueryError
|
||||
}
|
||||
|
||||
// DefaultPanicHandler is the default PanicHandler
|
||||
type DefaultPanicHandler struct{}
|
||||
|
||||
// MakePanicError creates a new QueryError from a panic that occurred during execution
|
||||
func (h *DefaultPanicHandler) MakePanicError(ctx context.Context, value interface{}) *QueryError {
|
||||
return Errorf("panic occurred: %v", value)
|
||||
}
|
339
vendor/github.com/graph-gophers/graphql-go/graphql.go
generated
vendored
Normal file
339
vendor/github.com/graph-gophers/graphql-go/graphql.go
generated
vendored
Normal file
@ -0,0 +1,339 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/graph-gophers/graphql-go/errors"
|
||||
"github.com/graph-gophers/graphql-go/internal/common"
|
||||
"github.com/graph-gophers/graphql-go/internal/exec"
|
||||
"github.com/graph-gophers/graphql-go/internal/exec/resolvable"
|
||||
"github.com/graph-gophers/graphql-go/internal/exec/selected"
|
||||
"github.com/graph-gophers/graphql-go/internal/query"
|
||||
"github.com/graph-gophers/graphql-go/internal/schema"
|
||||
"github.com/graph-gophers/graphql-go/internal/validation"
|
||||
"github.com/graph-gophers/graphql-go/introspection"
|
||||
"github.com/graph-gophers/graphql-go/log"
|
||||
"github.com/graph-gophers/graphql-go/trace"
|
||||
"github.com/graph-gophers/graphql-go/types"
|
||||
)
|
||||
|
||||
// ParseSchema parses a GraphQL schema and attaches the given root resolver. It returns an error if
|
||||
// the Go type signature of the resolvers does not match the schema. If nil is passed as the
|
||||
// resolver, then the schema can not be executed, but it may be inspected (e.g. with ToJSON).
|
||||
func ParseSchema(schemaString string, resolver interface{}, opts ...SchemaOpt) (*Schema, error) {
|
||||
s := &Schema{
|
||||
schema: schema.New(),
|
||||
maxParallelism: 10,
|
||||
tracer: trace.OpenTracingTracer{},
|
||||
logger: &log.DefaultLogger{},
|
||||
panicHandler: &errors.DefaultPanicHandler{},
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(s)
|
||||
}
|
||||
|
||||
if s.validationTracer == nil {
|
||||
if tracer, ok := s.tracer.(trace.ValidationTracerContext); ok {
|
||||
s.validationTracer = tracer
|
||||
} else {
|
||||
s.validationTracer = &validationBridgingTracer{tracer: trace.NoopValidationTracer{}}
|
||||
}
|
||||
}
|
||||
|
||||
if err := schema.Parse(s.schema, schemaString, s.useStringDescriptions); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := s.validateSchema(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r, err := resolvable.ApplyResolver(s.schema, resolver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.res = r
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// MustParseSchema calls ParseSchema and panics on error.
|
||||
func MustParseSchema(schemaString string, resolver interface{}, opts ...SchemaOpt) *Schema {
|
||||
s, err := ParseSchema(schemaString, resolver, opts...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Schema represents a GraphQL schema with an optional resolver.
|
||||
type Schema struct {
|
||||
schema *types.Schema
|
||||
res *resolvable.Schema
|
||||
|
||||
maxDepth int
|
||||
maxParallelism int
|
||||
tracer trace.Tracer
|
||||
validationTracer trace.ValidationTracerContext
|
||||
logger log.Logger
|
||||
panicHandler errors.PanicHandler
|
||||
useStringDescriptions bool
|
||||
disableIntrospection bool
|
||||
subscribeResolverTimeout time.Duration
|
||||
}
|
||||
|
||||
func (s *Schema) ASTSchema() *types.Schema {
|
||||
return s.schema
|
||||
}
|
||||
|
||||
// SchemaOpt is an option to pass to ParseSchema or MustParseSchema.
|
||||
type SchemaOpt func(*Schema)
|
||||
|
||||
// UseStringDescriptions enables the usage of double quoted and triple quoted
|
||||
// strings as descriptions as per the June 2018 spec
|
||||
// https://facebook.github.io/graphql/June2018/. When this is not enabled,
|
||||
// comments are parsed as descriptions instead.
|
||||
func UseStringDescriptions() SchemaOpt {
|
||||
return func(s *Schema) {
|
||||
s.useStringDescriptions = true
|
||||
}
|
||||
}
|
||||
|
||||
// UseFieldResolvers specifies whether to use struct field resolvers
|
||||
func UseFieldResolvers() SchemaOpt {
|
||||
return func(s *Schema) {
|
||||
s.schema.UseFieldResolvers = true
|
||||
}
|
||||
}
|
||||
|
||||
// MaxDepth specifies the maximum field nesting depth in a query. The default is 0 which disables max depth checking.
|
||||
func MaxDepth(n int) SchemaOpt {
|
||||
return func(s *Schema) {
|
||||
s.maxDepth = n
|
||||
}
|
||||
}
|
||||
|
||||
// MaxParallelism specifies the maximum number of resolvers per request allowed to run in parallel. The default is 10.
|
||||
func MaxParallelism(n int) SchemaOpt {
|
||||
return func(s *Schema) {
|
||||
s.maxParallelism = n
|
||||
}
|
||||
}
|
||||
|
||||
// Tracer is used to trace queries and fields. It defaults to trace.OpenTracingTracer.
|
||||
func Tracer(tracer trace.Tracer) SchemaOpt {
|
||||
return func(s *Schema) {
|
||||
s.tracer = tracer
|
||||
}
|
||||
}
|
||||
|
||||
// ValidationTracer is used to trace validation errors. It defaults to trace.NoopValidationTracer.
|
||||
// Deprecated: context is needed to support tracing correctly. Use a Tracer which implements trace.ValidationTracerContext.
|
||||
func ValidationTracer(tracer trace.ValidationTracer) SchemaOpt { //nolint:staticcheck
|
||||
return func(s *Schema) {
|
||||
s.validationTracer = &validationBridgingTracer{tracer: tracer}
|
||||
}
|
||||
}
|
||||
|
||||
// Logger is used to log panics during query execution. It defaults to exec.DefaultLogger.
|
||||
func Logger(logger log.Logger) SchemaOpt {
|
||||
return func(s *Schema) {
|
||||
s.logger = logger
|
||||
}
|
||||
}
|
||||
|
||||
// PanicHandler is used to customize the panic errors during query execution.
|
||||
// It defaults to errors.DefaultPanicHandler.
|
||||
func PanicHandler(panicHandler errors.PanicHandler) SchemaOpt {
|
||||
return func(s *Schema) {
|
||||
s.panicHandler = panicHandler
|
||||
}
|
||||
}
|
||||
|
||||
// DisableIntrospection disables introspection queries.
|
||||
func DisableIntrospection() SchemaOpt {
|
||||
return func(s *Schema) {
|
||||
s.disableIntrospection = true
|
||||
}
|
||||
}
|
||||
|
||||
// SubscribeResolverTimeout is an option to control the amount of time
|
||||
// we allow for a single subscribe message resolver to complete it's job
|
||||
// before it times out and returns an error to the subscriber.
|
||||
func SubscribeResolverTimeout(timeout time.Duration) SchemaOpt {
|
||||
return func(s *Schema) {
|
||||
s.subscribeResolverTimeout = timeout
|
||||
}
|
||||
}
|
||||
|
||||
// Response represents a typical response of a GraphQL server. It may be encoded to JSON directly or
|
||||
// it may be further processed to a custom response type, for example to include custom error data.
|
||||
// Errors are intentionally serialized first based on the advice in https://github.com/facebook/graphql/commit/7b40390d48680b15cb93e02d46ac5eb249689876#diff-757cea6edf0288677a9eea4cfc801d87R107
|
||||
type Response struct {
|
||||
Errors []*errors.QueryError `json:"errors,omitempty"`
|
||||
Data json.RawMessage `json:"data,omitempty"`
|
||||
Extensions map[string]interface{} `json:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates the given query with the schema.
|
||||
func (s *Schema) Validate(queryString string) []*errors.QueryError {
|
||||
return s.ValidateWithVariables(queryString, nil)
|
||||
}
|
||||
|
||||
// ValidateWithVariables validates the given query with the schema and the input variables.
|
||||
func (s *Schema) ValidateWithVariables(queryString string, variables map[string]interface{}) []*errors.QueryError {
|
||||
doc, qErr := query.Parse(queryString)
|
||||
if qErr != nil {
|
||||
return []*errors.QueryError{qErr}
|
||||
}
|
||||
|
||||
return validation.Validate(s.schema, doc, variables, s.maxDepth)
|
||||
}
|
||||
|
||||
// Exec executes the given query with the schema's resolver. It panics if the schema was created
|
||||
// without a resolver. If the context get cancelled, no further resolvers will be called and a
|
||||
// the context error will be returned as soon as possible (not immediately).
|
||||
func (s *Schema) Exec(ctx context.Context, queryString string, operationName string, variables map[string]interface{}) *Response {
|
||||
if !s.res.Resolver.IsValid() {
|
||||
panic("schema created without resolver, can not exec")
|
||||
}
|
||||
return s.exec(ctx, queryString, operationName, variables, s.res)
|
||||
}
|
||||
|
||||
func (s *Schema) exec(ctx context.Context, queryString string, operationName string, variables map[string]interface{}, res *resolvable.Schema) *Response {
|
||||
doc, qErr := query.Parse(queryString)
|
||||
if qErr != nil {
|
||||
return &Response{Errors: []*errors.QueryError{qErr}}
|
||||
}
|
||||
|
||||
validationFinish := s.validationTracer.TraceValidation(ctx)
|
||||
errs := validation.Validate(s.schema, doc, variables, s.maxDepth)
|
||||
validationFinish(errs)
|
||||
if len(errs) != 0 {
|
||||
return &Response{Errors: errs}
|
||||
}
|
||||
|
||||
op, err := getOperation(doc, operationName)
|
||||
if err != nil {
|
||||
return &Response{Errors: []*errors.QueryError{errors.Errorf("%s", err)}}
|
||||
}
|
||||
|
||||
// If the optional "operationName" POST parameter is not provided then
|
||||
// use the query's operation name for improved tracing.
|
||||
if operationName == "" {
|
||||
operationName = op.Name.Name
|
||||
}
|
||||
|
||||
// Subscriptions are not valid in Exec. Use schema.Subscribe() instead.
|
||||
if op.Type == query.Subscription {
|
||||
return &Response{Errors: []*errors.QueryError{{Message: "graphql-ws protocol header is missing"}}}
|
||||
}
|
||||
if op.Type == query.Mutation {
|
||||
if _, ok := s.schema.EntryPoints["mutation"]; !ok {
|
||||
return &Response{Errors: []*errors.QueryError{{Message: "no mutations are offered by the schema"}}}
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in variables with the defaults from the operation
|
||||
if variables == nil {
|
||||
variables = make(map[string]interface{}, len(op.Vars))
|
||||
}
|
||||
for _, v := range op.Vars {
|
||||
if _, ok := variables[v.Name.Name]; !ok && v.Default != nil {
|
||||
variables[v.Name.Name] = v.Default.Deserialize(nil)
|
||||
}
|
||||
}
|
||||
|
||||
r := &exec.Request{
|
||||
Request: selected.Request{
|
||||
Doc: doc,
|
||||
Vars: variables,
|
||||
Schema: s.schema,
|
||||
DisableIntrospection: s.disableIntrospection,
|
||||
},
|
||||
Limiter: make(chan struct{}, s.maxParallelism),
|
||||
Tracer: s.tracer,
|
||||
Logger: s.logger,
|
||||
PanicHandler: s.panicHandler,
|
||||
}
|
||||
varTypes := make(map[string]*introspection.Type)
|
||||
for _, v := range op.Vars {
|
||||
t, err := common.ResolveType(v.Type, s.schema.Resolve)
|
||||
if err != nil {
|
||||
return &Response{Errors: []*errors.QueryError{err}}
|
||||
}
|
||||
varTypes[v.Name.Name] = introspection.WrapType(t)
|
||||
}
|
||||
traceCtx, finish := s.tracer.TraceQuery(ctx, queryString, operationName, variables, varTypes)
|
||||
data, errs := r.Execute(traceCtx, res, op)
|
||||
finish(errs)
|
||||
|
||||
return &Response{
|
||||
Data: data,
|
||||
Errors: errs,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Schema) validateSchema() error {
|
||||
// https://graphql.github.io/graphql-spec/June2018/#sec-Root-Operation-Types
|
||||
// > The query root operation type must be provided and must be an Object type.
|
||||
if err := validateRootOp(s.schema, "query", true); err != nil {
|
||||
return err
|
||||
}
|
||||
// > The mutation root operation type is optional; if it is not provided, the service does not support mutations.
|
||||
// > If it is provided, it must be an Object type.
|
||||
if err := validateRootOp(s.schema, "mutation", false); err != nil {
|
||||
return err
|
||||
}
|
||||
// > Similarly, the subscription root operation type is also optional; if it is not provided, the service does not
|
||||
// > support subscriptions. If it is provided, it must be an Object type.
|
||||
if err := validateRootOp(s.schema, "subscription", false); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type validationBridgingTracer struct {
|
||||
tracer trace.ValidationTracer //nolint:staticcheck
|
||||
}
|
||||
|
||||
func (t *validationBridgingTracer) TraceValidation(context.Context) trace.TraceValidationFinishFunc {
|
||||
return t.tracer.TraceValidation()
|
||||
}
|
||||
|
||||
func validateRootOp(s *types.Schema, name string, mandatory bool) error {
|
||||
t, ok := s.EntryPoints[name]
|
||||
if !ok {
|
||||
if mandatory {
|
||||
return fmt.Errorf("root operation %q must be defined", name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if t.Kind() != "OBJECT" {
|
||||
return fmt.Errorf("root operation %q must be an OBJECT", name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getOperation(document *types.ExecutableDefinition, operationName string) (*types.OperationDefinition, error) {
|
||||
if len(document.Operations) == 0 {
|
||||
return nil, fmt.Errorf("no operations in query document")
|
||||
}
|
||||
|
||||
if operationName == "" {
|
||||
if len(document.Operations) > 1 {
|
||||
return nil, fmt.Errorf("more than one operation in query document and no operation name given")
|
||||
}
|
||||
for _, op := range document.Operations {
|
||||
return op, nil // return the one and only operation
|
||||
}
|
||||
}
|
||||
|
||||
op := document.Operations.Get(operationName)
|
||||
if op == nil {
|
||||
return nil, fmt.Errorf("no operation with name %q", operationName)
|
||||
}
|
||||
return op, nil
|
||||
}
|
30
vendor/github.com/graph-gophers/graphql-go/id.go
generated
vendored
Normal file
30
vendor/github.com/graph-gophers/graphql-go/id.go
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// ID represents GraphQL's "ID" scalar type. A custom type may be used instead.
|
||||
type ID string
|
||||
|
||||
func (ID) ImplementsGraphQLType(name string) bool {
|
||||
return name == "ID"
|
||||
}
|
||||
|
||||
func (id *ID) UnmarshalGraphQL(input interface{}) error {
|
||||
var err error
|
||||
switch input := input.(type) {
|
||||
case string:
|
||||
*id = ID(input)
|
||||
case int32:
|
||||
*id = ID(strconv.Itoa(int(input)))
|
||||
default:
|
||||
err = fmt.Errorf("wrong type for ID: %T", input)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (id ID) MarshalJSON() ([]byte, error) {
|
||||
return strconv.AppendQuote(nil, string(id)), nil
|
||||
}
|
103
vendor/github.com/graph-gophers/graphql-go/internal/common/blockstring.go
generated
vendored
Normal file
103
vendor/github.com/graph-gophers/graphql-go/internal/common/blockstring.go
generated
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2019 GraphQL Contributors
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
// This implementation has been adapted from the graphql-js reference implementation
|
||||
// https://github.com/graphql/graphql-js/blob/5eb7c4ded7ceb83ac742149cbe0dae07a8af9a30/src/language/blockString.js
|
||||
// which is released under the MIT License above.
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Produces the value of a block string from its parsed raw value, similar to
|
||||
// CoffeeScript's block string, Python's docstring trim or Ruby's strip_heredoc.
|
||||
//
|
||||
// This implements the GraphQL spec's BlockStringValue() static algorithm.
|
||||
func blockString(raw string) string {
|
||||
lines := strings.Split(raw, "\n")
|
||||
|
||||
// Remove common indentation from all lines except the first (which has none)
|
||||
ind := blockStringIndentation(lines)
|
||||
if ind > 0 {
|
||||
for i := 1; i < len(lines); i++ {
|
||||
l := lines[i]
|
||||
if len(l) < ind {
|
||||
lines[i] = ""
|
||||
continue
|
||||
}
|
||||
lines[i] = l[ind:]
|
||||
}
|
||||
}
|
||||
|
||||
// Remove leading and trailing blank lines
|
||||
trimStart := 0
|
||||
for i := 0; i < len(lines) && isBlank(lines[i]); i++ {
|
||||
trimStart++
|
||||
}
|
||||
lines = lines[trimStart:]
|
||||
trimEnd := 0
|
||||
for i := len(lines) - 1; i > 0 && isBlank(lines[i]); i-- {
|
||||
trimEnd++
|
||||
}
|
||||
lines = lines[:len(lines)-trimEnd]
|
||||
|
||||
return strings.Join(lines, "\n")
|
||||
}
|
||||
|
||||
func blockStringIndentation(lines []string) int {
|
||||
var commonIndent *int
|
||||
for i := 1; i < len(lines); i++ {
|
||||
l := lines[i]
|
||||
indent := leadingWhitespace(l)
|
||||
if indent == len(l) {
|
||||
// don't consider blank/empty lines
|
||||
continue
|
||||
}
|
||||
if indent == 0 {
|
||||
return 0
|
||||
}
|
||||
if commonIndent == nil || indent < *commonIndent {
|
||||
commonIndent = &indent
|
||||
}
|
||||
}
|
||||
if commonIndent == nil {
|
||||
return 0
|
||||
}
|
||||
return *commonIndent
|
||||
}
|
||||
|
||||
func isBlank(s string) bool {
|
||||
return len(s) == 0 || leadingWhitespace(s) == len(s)
|
||||
}
|
||||
|
||||
func leadingWhitespace(s string) int {
|
||||
i := 0
|
||||
for _, r := range s {
|
||||
if r != '\t' && r != ' ' {
|
||||
break
|
||||
}
|
||||
i++
|
||||
}
|
||||
return i
|
||||
}
|
18
vendor/github.com/graph-gophers/graphql-go/internal/common/directive.go
generated
vendored
Normal file
18
vendor/github.com/graph-gophers/graphql-go/internal/common/directive.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
package common
|
||||
|
||||
import "github.com/graph-gophers/graphql-go/types"
|
||||
|
||||
func ParseDirectives(l *Lexer) types.DirectiveList {
|
||||
var directives types.DirectiveList
|
||||
for l.Peek() == '@' {
|
||||
l.ConsumeToken('@')
|
||||
d := &types.Directive{}
|
||||
d.Name = l.ConsumeIdentWithLoc()
|
||||
d.Name.Loc.Column--
|
||||
if l.Peek() == '(' {
|
||||
d.Arguments = ParseArgumentList(l)
|
||||
}
|
||||
directives = append(directives, d)
|
||||
}
|
||||
return directives
|
||||
}
|
229
vendor/github.com/graph-gophers/graphql-go/internal/common/lexer.go
generated
vendored
Normal file
229
vendor/github.com/graph-gophers/graphql-go/internal/common/lexer.go
generated
vendored
Normal file
@ -0,0 +1,229 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/scanner"
|
||||
|
||||
"github.com/graph-gophers/graphql-go/errors"
|
||||
"github.com/graph-gophers/graphql-go/types"
|
||||
)
|
||||
|
||||
type syntaxError string
|
||||
|
||||
type Lexer struct {
|
||||
sc *scanner.Scanner
|
||||
next rune
|
||||
comment bytes.Buffer
|
||||
useStringDescriptions bool
|
||||
}
|
||||
|
||||
type Ident struct {
|
||||
Name string
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
func NewLexer(s string, useStringDescriptions bool) *Lexer {
|
||||
sc := &scanner.Scanner{
|
||||
Mode: scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanStrings,
|
||||
}
|
||||
sc.Init(strings.NewReader(s))
|
||||
|
||||
l := Lexer{sc: sc, useStringDescriptions: useStringDescriptions}
|
||||
l.sc.Error = l.CatchScannerError
|
||||
|
||||
return &l
|
||||
}
|
||||
|
||||
func (l *Lexer) CatchSyntaxError(f func()) (errRes *errors.QueryError) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
if err, ok := err.(syntaxError); ok {
|
||||
errRes = errors.Errorf("syntax error: %s", err)
|
||||
errRes.Locations = []errors.Location{l.Location()}
|
||||
return
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
f()
|
||||
return
|
||||
}
|
||||
|
||||
func (l *Lexer) Peek() rune {
|
||||
return l.next
|
||||
}
|
||||
|
||||
// ConsumeWhitespace consumes whitespace and tokens equivalent to whitespace (e.g. commas and comments).
|
||||
//
|
||||
// Consumed comment characters will build the description for the next type or field encountered.
|
||||
// The description is available from `DescComment()`, and will be reset every time `ConsumeWhitespace()` is
|
||||
// executed unless l.useStringDescriptions is set.
|
||||
func (l *Lexer) ConsumeWhitespace() {
|
||||
l.comment.Reset()
|
||||
for {
|
||||
l.next = l.sc.Scan()
|
||||
|
||||
if l.next == ',' {
|
||||
// Similar to white space and line terminators, commas (',') are used to improve the
|
||||
// legibility of source text and separate lexical tokens but are otherwise syntactically and
|
||||
// semantically insignificant within GraphQL documents.
|
||||
//
|
||||
// http://facebook.github.io/graphql/draft/#sec-Insignificant-Commas
|
||||
continue
|
||||
}
|
||||
|
||||
if l.next == '#' {
|
||||
// GraphQL source documents may contain single-line comments, starting with the '#' marker.
|
||||
//
|
||||
// A comment can contain any Unicode code point except `LineTerminator` so a comment always
|
||||
// consists of all code points starting with the '#' character up to but not including the
|
||||
// line terminator.
|
||||
l.consumeComment()
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// consumeDescription optionally consumes a description based on the June 2018 graphql spec if any are present.
|
||||
//
|
||||
// Single quote strings are also single line. Triple quote strings can be multi-line. Triple quote strings
|
||||
// whitespace trimmed on both ends.
|
||||
// If a description is found, consume any following comments as well
|
||||
//
|
||||
// http://facebook.github.io/graphql/June2018/#sec-Descriptions
|
||||
func (l *Lexer) consumeDescription() string {
|
||||
// If the next token is not a string, we don't consume it
|
||||
if l.next != scanner.String {
|
||||
return ""
|
||||
}
|
||||
// Triple quote string is an empty "string" followed by an open quote due to the way the parser treats strings as one token
|
||||
var desc string
|
||||
if l.sc.Peek() == '"' {
|
||||
desc = l.consumeTripleQuoteComment()
|
||||
} else {
|
||||
desc = l.consumeStringComment()
|
||||
}
|
||||
l.ConsumeWhitespace()
|
||||
return desc
|
||||
}
|
||||
|
||||
func (l *Lexer) ConsumeIdent() string {
|
||||
name := l.sc.TokenText()
|
||||
l.ConsumeToken(scanner.Ident)
|
||||
return name
|
||||
}
|
||||
|
||||
func (l *Lexer) ConsumeIdentWithLoc() types.Ident {
|
||||
loc := l.Location()
|
||||
name := l.sc.TokenText()
|
||||
l.ConsumeToken(scanner.Ident)
|
||||
return types.Ident{Name: name, Loc: loc}
|
||||
}
|
||||
|
||||
func (l *Lexer) ConsumeKeyword(keyword string) {
|
||||
if l.next != scanner.Ident || l.sc.TokenText() != keyword {
|
||||
l.SyntaxError(fmt.Sprintf("unexpected %q, expecting %q", l.sc.TokenText(), keyword))
|
||||
}
|
||||
l.ConsumeWhitespace()
|
||||
}
|
||||
|
||||
func (l *Lexer) ConsumeLiteral() *types.PrimitiveValue {
|
||||
lit := &types.PrimitiveValue{Type: l.next, Text: l.sc.TokenText()}
|
||||
l.ConsumeWhitespace()
|
||||
return lit
|
||||
}
|
||||
|
||||
func (l *Lexer) ConsumeToken(expected rune) {
|
||||
if l.next != expected {
|
||||
l.SyntaxError(fmt.Sprintf("unexpected %q, expecting %s", l.sc.TokenText(), scanner.TokenString(expected)))
|
||||
}
|
||||
l.ConsumeWhitespace()
|
||||
}
|
||||
|
||||
func (l *Lexer) DescComment() string {
|
||||
comment := l.comment.String()
|
||||
desc := l.consumeDescription()
|
||||
if l.useStringDescriptions {
|
||||
return desc
|
||||
}
|
||||
return comment
|
||||
}
|
||||
|
||||
func (l *Lexer) SyntaxError(message string) {
|
||||
panic(syntaxError(message))
|
||||
}
|
||||
|
||||
func (l *Lexer) Location() errors.Location {
|
||||
return errors.Location{
|
||||
Line: l.sc.Line,
|
||||
Column: l.sc.Column,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Lexer) consumeTripleQuoteComment() string {
|
||||
l.next = l.sc.Next()
|
||||
if l.next != '"' {
|
||||
panic("consumeTripleQuoteComment used in wrong context: no third quote?")
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
var numQuotes int
|
||||
for {
|
||||
l.next = l.sc.Next()
|
||||
if l.next == '"' {
|
||||
numQuotes++
|
||||
} else {
|
||||
numQuotes = 0
|
||||
}
|
||||
buf.WriteRune(l.next)
|
||||
if numQuotes == 3 || l.next == scanner.EOF {
|
||||
break
|
||||
}
|
||||
}
|
||||
val := buf.String()
|
||||
val = val[:len(val)-numQuotes]
|
||||
return blockString(val)
|
||||
}
|
||||
|
||||
func (l *Lexer) consumeStringComment() string {
|
||||
val, err := strconv.Unquote(l.sc.TokenText())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// consumeComment consumes all characters from `#` to the first encountered line terminator.
|
||||
// The characters are appended to `l.comment`.
|
||||
func (l *Lexer) consumeComment() {
|
||||
if l.next != '#' {
|
||||
panic("consumeComment used in wrong context")
|
||||
}
|
||||
|
||||
// TODO: count and trim whitespace so we can dedent any following lines.
|
||||
if l.sc.Peek() == ' ' {
|
||||
l.sc.Next()
|
||||
}
|
||||
|
||||
if l.comment.Len() > 0 {
|
||||
l.comment.WriteRune('\n')
|
||||
}
|
||||
|
||||
for {
|
||||
next := l.sc.Next()
|
||||
if next == '\r' || next == '\n' || next == scanner.EOF {
|
||||
break
|
||||
}
|
||||
l.comment.WriteRune(next)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Lexer) CatchScannerError(s *scanner.Scanner, msg string) {
|
||||
l.SyntaxError(msg)
|
||||
}
|
58
vendor/github.com/graph-gophers/graphql-go/internal/common/literals.go
generated
vendored
Normal file
58
vendor/github.com/graph-gophers/graphql-go/internal/common/literals.go
generated
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"text/scanner"
|
||||
|
||||
"github.com/graph-gophers/graphql-go/types"
|
||||
)
|
||||
|
||||
func ParseLiteral(l *Lexer, constOnly bool) types.Value {
|
||||
loc := l.Location()
|
||||
switch l.Peek() {
|
||||
case '$':
|
||||
if constOnly {
|
||||
l.SyntaxError("variable not allowed")
|
||||
panic("unreachable")
|
||||
}
|
||||
l.ConsumeToken('$')
|
||||
return &types.Variable{Name: l.ConsumeIdent(), Loc: loc}
|
||||
|
||||
case scanner.Int, scanner.Float, scanner.String, scanner.Ident:
|
||||
lit := l.ConsumeLiteral()
|
||||
if lit.Type == scanner.Ident && lit.Text == "null" {
|
||||
return &types.NullValue{Loc: loc}
|
||||
}
|
||||
lit.Loc = loc
|
||||
return lit
|
||||
case '-':
|
||||
l.ConsumeToken('-')
|
||||
lit := l.ConsumeLiteral()
|
||||
lit.Text = "-" + lit.Text
|
||||
lit.Loc = loc
|
||||
return lit
|
||||
case '[':
|
||||
l.ConsumeToken('[')
|
||||
var list []types.Value
|
||||
for l.Peek() != ']' {
|
||||
list = append(list, ParseLiteral(l, constOnly))
|
||||
}
|
||||
l.ConsumeToken(']')
|
||||
return &types.ListValue{Values: list, Loc: loc}
|
||||
|
||||
case '{':
|
||||
l.ConsumeToken('{')
|
||||
var fields []*types.ObjectField
|
||||
for l.Peek() != '}' {
|
||||
name := l.ConsumeIdentWithLoc()
|
||||
l.ConsumeToken(':')
|
||||
value := ParseLiteral(l, constOnly)
|
||||
fields = append(fields, &types.ObjectField{Name: name, Value: value})
|
||||
}
|
||||
l.ConsumeToken('}')
|
||||
return &types.ObjectValue{Fields: fields, Loc: loc}
|
||||
|
||||
default:
|
||||
l.SyntaxError("invalid value")
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
67
vendor/github.com/graph-gophers/graphql-go/internal/common/types.go
generated
vendored
Normal file
67
vendor/github.com/graph-gophers/graphql-go/internal/common/types.go
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"github.com/graph-gophers/graphql-go/errors"
|
||||
"github.com/graph-gophers/graphql-go/types"
|
||||
)
|
||||
|
||||
func ParseType(l *Lexer) types.Type {
|
||||
t := parseNullType(l)
|
||||
if l.Peek() == '!' {
|
||||
l.ConsumeToken('!')
|
||||
return &types.NonNull{OfType: t}
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func parseNullType(l *Lexer) types.Type {
|
||||
if l.Peek() == '[' {
|
||||
l.ConsumeToken('[')
|
||||
ofType := ParseType(l)
|
||||
l.ConsumeToken(']')
|
||||
return &types.List{OfType: ofType}
|
||||
}
|
||||
|
||||
return &types.TypeName{Ident: l.ConsumeIdentWithLoc()}
|
||||
}
|
||||
|
||||
type Resolver func(name string) types.Type
|
||||
|
||||
// ResolveType attempts to resolve a type's name against a resolving function.
|
||||
// This function is used when one needs to check if a TypeName exists in the resolver (typically a Schema).
|
||||
//
|
||||
// In the example below, ResolveType would be used to check if the resolving function
|
||||
// returns a valid type for Dimension:
|
||||
//
|
||||
// type Profile {
|
||||
// picture(dimensions: Dimension): Url
|
||||
// }
|
||||
//
|
||||
// ResolveType recursively unwraps List and NonNull types until a NamedType is reached.
|
||||
func ResolveType(t types.Type, resolver Resolver) (types.Type, *errors.QueryError) {
|
||||
switch t := t.(type) {
|
||||
case *types.List:
|
||||
ofType, err := ResolveType(t.OfType, resolver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &types.List{OfType: ofType}, nil
|
||||
case *types.NonNull:
|
||||
ofType, err := ResolveType(t.OfType, resolver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &types.NonNull{OfType: ofType}, nil
|
||||
case *types.TypeName:
|
||||
refT := resolver(t.Name)
|
||||
if refT == nil {
|
||||
err := errors.Errorf("Unknown type %q.", t.Name)
|
||||
err.Rule = "KnownTypeNames"
|
||||
err.Locations = []errors.Location{t.Loc}
|
||||
return nil, err
|
||||
}
|
||||
return refT, nil
|
||||
default:
|
||||
return t, nil
|
||||
}
|
||||
}
|
37
vendor/github.com/graph-gophers/graphql-go/internal/common/values.go
generated
vendored
Normal file
37
vendor/github.com/graph-gophers/graphql-go/internal/common/values.go
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"github.com/graph-gophers/graphql-go/types"
|
||||
)
|
||||
|
||||
func ParseInputValue(l *Lexer) *types.InputValueDefinition {
|
||||
p := &types.InputValueDefinition{}
|
||||
p.Loc = l.Location()
|
||||
p.Desc = l.DescComment()
|
||||
p.Name = l.ConsumeIdentWithLoc()
|
||||
l.ConsumeToken(':')
|
||||
p.TypeLoc = l.Location()
|
||||
p.Type = ParseType(l)
|
||||
if l.Peek() == '=' {
|
||||
l.ConsumeToken('=')
|
||||
p.Default = ParseLiteral(l, true)
|
||||
}
|
||||
p.Directives = ParseDirectives(l)
|
||||
return p
|
||||
}
|
||||
|
||||
func ParseArgumentList(l *Lexer) types.ArgumentList {
|
||||
var args types.ArgumentList
|
||||
l.ConsumeToken('(')
|
||||
for l.Peek() != ')' {
|
||||
name := l.ConsumeIdentWithLoc()
|
||||
l.ConsumeToken(':')
|
||||
value := ParseLiteral(l, false)
|
||||
args = append(args, &types.Argument{
|
||||
Name: name,
|
||||
Value: value,
|
||||
})
|
||||
}
|
||||
l.ConsumeToken(')')
|
||||
return args
|
||||
}
|
381
vendor/github.com/graph-gophers/graphql-go/internal/exec/exec.go
generated
vendored
Normal file
381
vendor/github.com/graph-gophers/graphql-go/internal/exec/exec.go
generated
vendored
Normal file
@ -0,0 +1,381 @@
|
||||
package exec
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/graph-gophers/graphql-go/errors"
|
||||
"github.com/graph-gophers/graphql-go/internal/exec/resolvable"
|
||||
"github.com/graph-gophers/graphql-go/internal/exec/selected"
|
||||
"github.com/graph-gophers/graphql-go/internal/query"
|
||||
"github.com/graph-gophers/graphql-go/log"
|
||||
"github.com/graph-gophers/graphql-go/trace"
|
||||
"github.com/graph-gophers/graphql-go/types"
|
||||
)
|
||||
|
||||
type Request struct {
|
||||
selected.Request
|
||||
Limiter chan struct{}
|
||||
Tracer trace.Tracer
|
||||
Logger log.Logger
|
||||
PanicHandler errors.PanicHandler
|
||||
SubscribeResolverTimeout time.Duration
|
||||
}
|
||||
|
||||
func (r *Request) handlePanic(ctx context.Context) {
|
||||
if value := recover(); value != nil {
|
||||
r.Logger.LogPanic(ctx, value)
|
||||
r.AddError(r.PanicHandler.MakePanicError(ctx, value))
|
||||
}
|
||||
}
|
||||
|
||||
type extensionser interface {
|
||||
Extensions() map[string]interface{}
|
||||
}
|
||||
|
||||
func (r *Request) Execute(ctx context.Context, s *resolvable.Schema, op *types.OperationDefinition) ([]byte, []*errors.QueryError) {
|
||||
var out bytes.Buffer
|
||||
func() {
|
||||
defer r.handlePanic(ctx)
|
||||
sels := selected.ApplyOperation(&r.Request, s, op)
|
||||
r.execSelections(ctx, sels, nil, s, s.Resolver, &out, op.Type == query.Mutation)
|
||||
}()
|
||||
|
||||
if err := ctx.Err(); err != nil {
|
||||
return nil, []*errors.QueryError{errors.Errorf("%s", err)}
|
||||
}
|
||||
|
||||
return out.Bytes(), r.Errs
|
||||
}
|
||||
|
||||
type fieldToExec struct {
|
||||
field *selected.SchemaField
|
||||
sels []selected.Selection
|
||||
resolver reflect.Value
|
||||
out *bytes.Buffer
|
||||
}
|
||||
|
||||
func resolvedToNull(b *bytes.Buffer) bool {
|
||||
return bytes.Equal(b.Bytes(), []byte("null"))
|
||||
}
|
||||
|
||||
func (r *Request) execSelections(ctx context.Context, sels []selected.Selection, path *pathSegment, s *resolvable.Schema, resolver reflect.Value, out *bytes.Buffer, serially bool) {
|
||||
async := !serially && selected.HasAsyncSel(sels)
|
||||
|
||||
var fields []*fieldToExec
|
||||
collectFieldsToResolve(sels, s, resolver, &fields, make(map[string]*fieldToExec))
|
||||
|
||||
if async {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(len(fields))
|
||||
for _, f := range fields {
|
||||
go func(f *fieldToExec) {
|
||||
defer wg.Done()
|
||||
defer r.handlePanic(ctx)
|
||||
f.out = new(bytes.Buffer)
|
||||
execFieldSelection(ctx, r, s, f, &pathSegment{path, f.field.Alias}, true)
|
||||
}(f)
|
||||
}
|
||||
wg.Wait()
|
||||
} else {
|
||||
for _, f := range fields {
|
||||
f.out = new(bytes.Buffer)
|
||||
execFieldSelection(ctx, r, s, f, &pathSegment{path, f.field.Alias}, true)
|
||||
}
|
||||
}
|
||||
|
||||
out.WriteByte('{')
|
||||
for i, f := range fields {
|
||||
// If a non-nullable child resolved to null, an error was added to the
|
||||
// "errors" list in the response, so this field resolves to null.
|
||||
// If this field is non-nullable, the error is propagated to its parent.
|
||||
if _, ok := f.field.Type.(*types.NonNull); ok && resolvedToNull(f.out) {
|
||||
out.Reset()
|
||||
out.Write([]byte("null"))
|
||||
return
|
||||
}
|
||||
|
||||
if i > 0 {
|
||||
out.WriteByte(',')
|
||||
}
|
||||
out.WriteByte('"')
|
||||
out.WriteString(f.field.Alias)
|
||||
out.WriteByte('"')
|
||||
out.WriteByte(':')
|
||||
out.Write(f.out.Bytes())
|
||||
}
|
||||
out.WriteByte('}')
|
||||
}
|
||||
|
||||
func collectFieldsToResolve(sels []selected.Selection, s *resolvable.Schema, resolver reflect.Value, fields *[]*fieldToExec, fieldByAlias map[string]*fieldToExec) {
|
||||
for _, sel := range sels {
|
||||
switch sel := sel.(type) {
|
||||
case *selected.SchemaField:
|
||||
field, ok := fieldByAlias[sel.Alias]
|
||||
if !ok { // validation already checked for conflict (TODO)
|
||||
field = &fieldToExec{field: sel, resolver: resolver}
|
||||
fieldByAlias[sel.Alias] = field
|
||||
*fields = append(*fields, field)
|
||||
}
|
||||
field.sels = append(field.sels, sel.Sels...)
|
||||
|
||||
case *selected.TypenameField:
|
||||
_, ok := fieldByAlias[sel.Alias]
|
||||
if !ok {
|
||||
res := reflect.ValueOf(typeOf(sel, resolver))
|
||||
f := s.FieldTypename
|
||||
f.TypeName = res.String()
|
||||
|
||||
sf := &selected.SchemaField{
|
||||
Field: f,
|
||||
Alias: sel.Alias,
|
||||
FixedResult: res,
|
||||
}
|
||||
|
||||
field := &fieldToExec{field: sf, resolver: resolver}
|
||||
*fields = append(*fields, field)
|
||||
fieldByAlias[sel.Alias] = field
|
||||
}
|
||||
|
||||
case *selected.TypeAssertion:
|
||||
out := resolver.Method(sel.MethodIndex).Call(nil)
|
||||
if !out[1].Bool() {
|
||||
continue
|
||||
}
|
||||
collectFieldsToResolve(sel.Sels, s, out[0], fields, fieldByAlias)
|
||||
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func typeOf(tf *selected.TypenameField, resolver reflect.Value) string {
|
||||
if len(tf.TypeAssertions) == 0 {
|
||||
return tf.Name
|
||||
}
|
||||
for name, a := range tf.TypeAssertions {
|
||||
out := resolver.Method(a.MethodIndex).Call(nil)
|
||||
if out[1].Bool() {
|
||||
return name
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func execFieldSelection(ctx context.Context, r *Request, s *resolvable.Schema, f *fieldToExec, path *pathSegment, applyLimiter bool) {
|
||||
if applyLimiter {
|
||||
r.Limiter <- struct{}{}
|
||||
}
|
||||
|
||||
var result reflect.Value
|
||||
var err *errors.QueryError
|
||||
|
||||
traceCtx, finish := r.Tracer.TraceField(ctx, f.field.TraceLabel, f.field.TypeName, f.field.Name, !f.field.Async, f.field.Args)
|
||||
defer func() {
|
||||
finish(err)
|
||||
}()
|
||||
|
||||
err = func() (err *errors.QueryError) {
|
||||
defer func() {
|
||||
if panicValue := recover(); panicValue != nil {
|
||||
r.Logger.LogPanic(ctx, panicValue)
|
||||
err = r.PanicHandler.MakePanicError(ctx, panicValue)
|
||||
err.Path = path.toSlice()
|
||||
}
|
||||
}()
|
||||
|
||||
if f.field.FixedResult.IsValid() {
|
||||
result = f.field.FixedResult
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := traceCtx.Err(); err != nil {
|
||||
return errors.Errorf("%s", err) // don't execute any more resolvers if context got cancelled
|
||||
}
|
||||
|
||||
res := f.resolver
|
||||
if f.field.UseMethodResolver() {
|
||||
var in []reflect.Value
|
||||
if f.field.HasContext {
|
||||
in = append(in, reflect.ValueOf(traceCtx))
|
||||
}
|
||||
if f.field.ArgsPacker != nil {
|
||||
in = append(in, f.field.PackedArgs)
|
||||
}
|
||||
callOut := res.Method(f.field.MethodIndex).Call(in)
|
||||
result = callOut[0]
|
||||
if f.field.HasError && !callOut[1].IsNil() {
|
||||
resolverErr := callOut[1].Interface().(error)
|
||||
err := errors.Errorf("%s", resolverErr)
|
||||
err.Path = path.toSlice()
|
||||
err.ResolverError = resolverErr
|
||||
if ex, ok := callOut[1].Interface().(extensionser); ok {
|
||||
err.Extensions = ex.Extensions()
|
||||
}
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// TODO extract out unwrapping ptr logic to a common place
|
||||
if res.Kind() == reflect.Ptr {
|
||||
res = res.Elem()
|
||||
}
|
||||
result = res.FieldByIndex(f.field.FieldIndex)
|
||||
}
|
||||
return nil
|
||||
}()
|
||||
|
||||
if applyLimiter {
|
||||
<-r.Limiter
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// If an error occurred while resolving a field, it should be treated as though the field
|
||||
// returned null, and an error must be added to the "errors" list in the response.
|
||||
r.AddError(err)
|
||||
f.out.WriteString("null")
|
||||
return
|
||||
}
|
||||
|
||||
r.execSelectionSet(traceCtx, f.sels, f.field.Type, path, s, result, f.out)
|
||||
}
|
||||
|
||||
func (r *Request) execSelectionSet(ctx context.Context, sels []selected.Selection, typ types.Type, path *pathSegment, s *resolvable.Schema, resolver reflect.Value, out *bytes.Buffer) {
|
||||
t, nonNull := unwrapNonNull(typ)
|
||||
|
||||
// a reflect.Value of a nil interface will show up as an Invalid value
|
||||
if resolver.Kind() == reflect.Invalid || ((resolver.Kind() == reflect.Ptr || resolver.Kind() == reflect.Interface) && resolver.IsNil()) {
|
||||
// If a field of a non-null type resolves to null (either because the
|
||||
// function to resolve the field returned null or because an error occurred),
|
||||
// add an error to the "errors" list in the response.
|
||||
if nonNull {
|
||||
err := errors.Errorf("graphql: got nil for non-null %q", t)
|
||||
err.Path = path.toSlice()
|
||||
r.AddError(err)
|
||||
}
|
||||
out.WriteString("null")
|
||||
return
|
||||
}
|
||||
|
||||
switch t.(type) {
|
||||
case *types.ObjectTypeDefinition, *types.InterfaceTypeDefinition, *types.Union:
|
||||
r.execSelections(ctx, sels, path, s, resolver, out, false)
|
||||
return
|
||||
}
|
||||
|
||||
// Any pointers or interfaces at this point should be non-nil, so we can get the actual value of them
|
||||
// for serialization
|
||||
if resolver.Kind() == reflect.Ptr || resolver.Kind() == reflect.Interface {
|
||||
resolver = resolver.Elem()
|
||||
}
|
||||
|
||||
switch t := t.(type) {
|
||||
case *types.List:
|
||||
r.execList(ctx, sels, t, path, s, resolver, out)
|
||||
|
||||
case *types.ScalarTypeDefinition:
|
||||
v := resolver.Interface()
|
||||
data, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
panic(errors.Errorf("could not marshal %v: %s", v, err))
|
||||
}
|
||||
out.Write(data)
|
||||
|
||||
case *types.EnumTypeDefinition:
|
||||
var stringer fmt.Stringer = resolver
|
||||
if s, ok := resolver.Interface().(fmt.Stringer); ok {
|
||||
stringer = s
|
||||
}
|
||||
name := stringer.String()
|
||||
var valid bool
|
||||
for _, v := range t.EnumValuesDefinition {
|
||||
if v.EnumValue == name {
|
||||
valid = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !valid {
|
||||
err := errors.Errorf("Invalid value %s.\nExpected type %s, found %s.", name, t.Name, name)
|
||||
err.Path = path.toSlice()
|
||||
r.AddError(err)
|
||||
out.WriteString("null")
|
||||
return
|
||||
}
|
||||
out.WriteByte('"')
|
||||
out.WriteString(name)
|
||||
out.WriteByte('"')
|
||||
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Request) execList(ctx context.Context, sels []selected.Selection, typ *types.List, path *pathSegment, s *resolvable.Schema, resolver reflect.Value, out *bytes.Buffer) {
|
||||
l := resolver.Len()
|
||||
entryouts := make([]bytes.Buffer, l)
|
||||
|
||||
if selected.HasAsyncSel(sels) {
|
||||
// Limit the number of concurrent goroutines spawned as it can lead to large
|
||||
// memory spikes for large lists.
|
||||
concurrency := cap(r.Limiter)
|
||||
sem := make(chan struct{}, concurrency)
|
||||
for i := 0; i < l; i++ {
|
||||
sem <- struct{}{}
|
||||
go func(i int) {
|
||||
defer func() { <-sem }()
|
||||
defer r.handlePanic(ctx)
|
||||
r.execSelectionSet(ctx, sels, typ.OfType, &pathSegment{path, i}, s, resolver.Index(i), &entryouts[i])
|
||||
}(i)
|
||||
}
|
||||
for i := 0; i < concurrency; i++ {
|
||||
sem <- struct{}{}
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < l; i++ {
|
||||
r.execSelectionSet(ctx, sels, typ.OfType, &pathSegment{path, i}, s, resolver.Index(i), &entryouts[i])
|
||||
}
|
||||
}
|
||||
|
||||
_, listOfNonNull := typ.OfType.(*types.NonNull)
|
||||
|
||||
out.WriteByte('[')
|
||||
for i, entryout := range entryouts {
|
||||
// If the list wraps a non-null type and one of the list elements
|
||||
// resolves to null, then the entire list resolves to null.
|
||||
if listOfNonNull && resolvedToNull(&entryout) {
|
||||
out.Reset()
|
||||
out.WriteString("null")
|
||||
return
|
||||
}
|
||||
|
||||
if i > 0 {
|
||||
out.WriteByte(',')
|
||||
}
|
||||
out.Write(entryout.Bytes())
|
||||
}
|
||||
out.WriteByte(']')
|
||||
}
|
||||
|
||||
func unwrapNonNull(t types.Type) (types.Type, bool) {
|
||||
if nn, ok := t.(*types.NonNull); ok {
|
||||
return nn.OfType, true
|
||||
}
|
||||
return t, false
|
||||
}
|
||||
|
||||
type pathSegment struct {
|
||||
parent *pathSegment
|
||||
value interface{}
|
||||
}
|
||||
|
||||
func (p *pathSegment) toSlice() []interface{} {
|
||||
if p == nil {
|
||||
return nil
|
||||
}
|
||||
return append(p.parent.toSlice(), p.value)
|
||||
}
|
390
vendor/github.com/graph-gophers/graphql-go/internal/exec/packer/packer.go
generated
vendored
Normal file
390
vendor/github.com/graph-gophers/graphql-go/internal/exec/packer/packer.go
generated
vendored
Normal file
@ -0,0 +1,390 @@
|
||||
package packer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/graph-gophers/graphql-go/decode"
|
||||
"github.com/graph-gophers/graphql-go/errors"
|
||||
"github.com/graph-gophers/graphql-go/types"
|
||||
)
|
||||
|
||||
type packer interface {
|
||||
Pack(value interface{}) (reflect.Value, error)
|
||||
}
|
||||
|
||||
type Builder struct {
|
||||
packerMap map[typePair]*packerMapEntry
|
||||
structPackers []*StructPacker
|
||||
}
|
||||
|
||||
type typePair struct {
|
||||
graphQLType types.Type
|
||||
resolverType reflect.Type
|
||||
}
|
||||
|
||||
type packerMapEntry struct {
|
||||
packer packer
|
||||
targets []*packer
|
||||
}
|
||||
|
||||
func NewBuilder() *Builder {
|
||||
return &Builder{
|
||||
packerMap: make(map[typePair]*packerMapEntry),
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Builder) Finish() error {
|
||||
for _, entry := range b.packerMap {
|
||||
for _, target := range entry.targets {
|
||||
*target = entry.packer
|
||||
}
|
||||
}
|
||||
|
||||
for _, p := range b.structPackers {
|
||||
p.defaultStruct = reflect.New(p.structType).Elem()
|
||||
for _, f := range p.fields {
|
||||
if defaultVal := f.field.Default; defaultVal != nil {
|
||||
v, err := f.fieldPacker.Pack(defaultVal.Deserialize(nil))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.defaultStruct.FieldByIndex(f.fieldIndex).Set(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Builder) assignPacker(target *packer, schemaType types.Type, reflectType reflect.Type) error {
|
||||
k := typePair{schemaType, reflectType}
|
||||
ref, ok := b.packerMap[k]
|
||||
if !ok {
|
||||
ref = &packerMapEntry{}
|
||||
b.packerMap[k] = ref
|
||||
var err error
|
||||
ref.packer, err = b.makePacker(schemaType, reflectType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
ref.targets = append(ref.targets, target)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Builder) makePacker(schemaType types.Type, reflectType reflect.Type) (packer, error) {
|
||||
t, nonNull := unwrapNonNull(schemaType)
|
||||
if !nonNull {
|
||||
if reflectType.Kind() == reflect.Ptr {
|
||||
elemType := reflectType.Elem()
|
||||
addPtr := true
|
||||
if _, ok := t.(*types.InputObject); ok {
|
||||
elemType = reflectType // keep pointer for input objects
|
||||
addPtr = false
|
||||
}
|
||||
elem, err := b.makeNonNullPacker(t, elemType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &nullPacker{
|
||||
elemPacker: elem,
|
||||
valueType: reflectType,
|
||||
addPtr: addPtr,
|
||||
}, nil
|
||||
} else if isNullable(reflectType) {
|
||||
elemType := reflectType
|
||||
addPtr := false
|
||||
elem, err := b.makeNonNullPacker(t, elemType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &nullPacker{
|
||||
elemPacker: elem,
|
||||
valueType: reflectType,
|
||||
addPtr: addPtr,
|
||||
}, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("%s is not a pointer or a nullable type", reflectType)
|
||||
}
|
||||
}
|
||||
|
||||
return b.makeNonNullPacker(t, reflectType)
|
||||
}
|
||||
|
||||
func (b *Builder) makeNonNullPacker(schemaType types.Type, reflectType reflect.Type) (packer, error) {
|
||||
if u, ok := reflect.New(reflectType).Interface().(decode.Unmarshaler); ok {
|
||||
if !u.ImplementsGraphQLType(schemaType.String()) {
|
||||
return nil, fmt.Errorf("can not unmarshal %s into %s", schemaType, reflectType)
|
||||
}
|
||||
return &unmarshalerPacker{
|
||||
ValueType: reflectType,
|
||||
}, nil
|
||||
}
|
||||
|
||||
switch t := schemaType.(type) {
|
||||
case *types.ScalarTypeDefinition:
|
||||
return &ValuePacker{
|
||||
ValueType: reflectType,
|
||||
}, nil
|
||||
|
||||
case *types.EnumTypeDefinition:
|
||||
if reflectType.Kind() != reflect.String {
|
||||
return nil, fmt.Errorf("wrong type, expected %s", reflect.String)
|
||||
}
|
||||
return &ValuePacker{
|
||||
ValueType: reflectType,
|
||||
}, nil
|
||||
|
||||
case *types.InputObject:
|
||||
e, err := b.MakeStructPacker(t.Values, reflectType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return e, nil
|
||||
|
||||
case *types.List:
|
||||
if reflectType.Kind() != reflect.Slice {
|
||||
return nil, fmt.Errorf("expected slice, got %s", reflectType)
|
||||
}
|
||||
p := &listPacker{
|
||||
sliceType: reflectType,
|
||||
}
|
||||
if err := b.assignPacker(&p.elem, t.OfType, reflectType.Elem()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p, nil
|
||||
|
||||
case *types.ObjectTypeDefinition, *types.InterfaceTypeDefinition, *types.Union:
|
||||
return nil, fmt.Errorf("type of kind %s can not be used as input", t.Kind())
|
||||
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Builder) MakeStructPacker(values []*types.InputValueDefinition, typ reflect.Type) (*StructPacker, error) {
|
||||
structType := typ
|
||||
usePtr := false
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
structType = typ.Elem()
|
||||
usePtr = true
|
||||
}
|
||||
if structType.Kind() != reflect.Struct {
|
||||
return nil, fmt.Errorf("expected struct or pointer to struct, got %s (hint: missing `args struct { ... }` wrapper for field arguments?)", typ)
|
||||
}
|
||||
|
||||
var fields []*structPackerField
|
||||
for _, v := range values {
|
||||
fe := &structPackerField{field: v}
|
||||
fx := func(n string) bool {
|
||||
return strings.EqualFold(stripUnderscore(n), stripUnderscore(v.Name.Name))
|
||||
}
|
||||
|
||||
sf, ok := structType.FieldByNameFunc(fx)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%s does not define field %q (hint: missing `args struct { ... }` wrapper for field arguments, or missing field on input struct)", typ, v.Name.Name)
|
||||
}
|
||||
if sf.PkgPath != "" {
|
||||
return nil, fmt.Errorf("field %q must be exported", sf.Name)
|
||||
}
|
||||
fe.fieldIndex = sf.Index
|
||||
|
||||
ft := v.Type
|
||||
if v.Default != nil {
|
||||
ft, _ = unwrapNonNull(ft)
|
||||
ft = &types.NonNull{OfType: ft}
|
||||
}
|
||||
|
||||
if err := b.assignPacker(&fe.fieldPacker, ft, sf.Type); err != nil {
|
||||
return nil, fmt.Errorf("field %q: %s", sf.Name, err)
|
||||
}
|
||||
|
||||
fields = append(fields, fe)
|
||||
}
|
||||
|
||||
p := &StructPacker{
|
||||
structType: structType,
|
||||
usePtr: usePtr,
|
||||
fields: fields,
|
||||
}
|
||||
b.structPackers = append(b.structPackers, p)
|
||||
return p, nil
|
||||
}
|
||||
|
||||
type StructPacker struct {
|
||||
structType reflect.Type
|
||||
usePtr bool
|
||||
defaultStruct reflect.Value
|
||||
fields []*structPackerField
|
||||
}
|
||||
|
||||
type structPackerField struct {
|
||||
field *types.InputValueDefinition
|
||||
fieldIndex []int
|
||||
fieldPacker packer
|
||||
}
|
||||
|
||||
func (p *StructPacker) Pack(value interface{}) (reflect.Value, error) {
|
||||
if value == nil {
|
||||
return reflect.Value{}, errors.Errorf("got null for non-null")
|
||||
}
|
||||
|
||||
values := value.(map[string]interface{})
|
||||
v := reflect.New(p.structType)
|
||||
v.Elem().Set(p.defaultStruct)
|
||||
for _, f := range p.fields {
|
||||
if value, ok := values[f.field.Name.Name]; ok {
|
||||
packed, err := f.fieldPacker.Pack(value)
|
||||
if err != nil {
|
||||
return reflect.Value{}, err
|
||||
}
|
||||
v.Elem().FieldByIndex(f.fieldIndex).Set(packed)
|
||||
}
|
||||
}
|
||||
if !p.usePtr {
|
||||
return v.Elem(), nil
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
type listPacker struct {
|
||||
sliceType reflect.Type
|
||||
elem packer
|
||||
}
|
||||
|
||||
func (e *listPacker) Pack(value interface{}) (reflect.Value, error) {
|
||||
list, ok := value.([]interface{})
|
||||
if !ok {
|
||||
list = []interface{}{value}
|
||||
}
|
||||
|
||||
v := reflect.MakeSlice(e.sliceType, len(list), len(list))
|
||||
for i := range list {
|
||||
packed, err := e.elem.Pack(list[i])
|
||||
if err != nil {
|
||||
return reflect.Value{}, err
|
||||
}
|
||||
v.Index(i).Set(packed)
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
type nullPacker struct {
|
||||
elemPacker packer
|
||||
valueType reflect.Type
|
||||
addPtr bool
|
||||
}
|
||||
|
||||
func (p *nullPacker) Pack(value interface{}) (reflect.Value, error) {
|
||||
if value == nil && !isNullable(p.valueType) {
|
||||
return reflect.Zero(p.valueType), nil
|
||||
}
|
||||
|
||||
v, err := p.elemPacker.Pack(value)
|
||||
if err != nil {
|
||||
return reflect.Value{}, err
|
||||
}
|
||||
|
||||
if p.addPtr {
|
||||
ptr := reflect.New(p.valueType.Elem())
|
||||
ptr.Elem().Set(v)
|
||||
return ptr, nil
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
type ValuePacker struct {
|
||||
ValueType reflect.Type
|
||||
}
|
||||
|
||||
func (p *ValuePacker) Pack(value interface{}) (reflect.Value, error) {
|
||||
if value == nil {
|
||||
return reflect.Value{}, errors.Errorf("got null for non-null")
|
||||
}
|
||||
|
||||
coerced, err := unmarshalInput(p.ValueType, value)
|
||||
if err != nil {
|
||||
return reflect.Value{}, fmt.Errorf("could not unmarshal %#v (%T) into %s: %s", value, value, p.ValueType, err)
|
||||
}
|
||||
return reflect.ValueOf(coerced), nil
|
||||
}
|
||||
|
||||
type unmarshalerPacker struct {
|
||||
ValueType reflect.Type
|
||||
}
|
||||
|
||||
func (p *unmarshalerPacker) Pack(value interface{}) (reflect.Value, error) {
|
||||
if value == nil && !isNullable(p.ValueType) {
|
||||
return reflect.Value{}, errors.Errorf("got null for non-null")
|
||||
}
|
||||
|
||||
v := reflect.New(p.ValueType)
|
||||
if err := v.Interface().(decode.Unmarshaler).UnmarshalGraphQL(value); err != nil {
|
||||
return reflect.Value{}, err
|
||||
}
|
||||
return v.Elem(), nil
|
||||
}
|
||||
|
||||
func unmarshalInput(typ reflect.Type, input interface{}) (interface{}, error) {
|
||||
if reflect.TypeOf(input) == typ {
|
||||
return input, nil
|
||||
}
|
||||
|
||||
switch typ.Kind() {
|
||||
case reflect.Int32:
|
||||
switch input := input.(type) {
|
||||
case int:
|
||||
if input < math.MinInt32 || input > math.MaxInt32 {
|
||||
return nil, fmt.Errorf("not a 32-bit integer")
|
||||
}
|
||||
return int32(input), nil
|
||||
case float64:
|
||||
coerced := int32(input)
|
||||
if input < math.MinInt32 || input > math.MaxInt32 || float64(coerced) != input {
|
||||
return nil, fmt.Errorf("not a 32-bit integer")
|
||||
}
|
||||
return coerced, nil
|
||||
}
|
||||
|
||||
case reflect.Float64:
|
||||
switch input := input.(type) {
|
||||
case int32:
|
||||
return float64(input), nil
|
||||
case int:
|
||||
return float64(input), nil
|
||||
}
|
||||
|
||||
case reflect.String:
|
||||
if reflect.TypeOf(input).ConvertibleTo(typ) {
|
||||
return reflect.ValueOf(input).Convert(typ).Interface(), nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("incompatible type")
|
||||
}
|
||||
|
||||
func unwrapNonNull(t types.Type) (types.Type, bool) {
|
||||
if nn, ok := t.(*types.NonNull); ok {
|
||||
return nn.OfType, true
|
||||
}
|
||||
return t, false
|
||||
}
|
||||
|
||||
func stripUnderscore(s string) string {
|
||||
return strings.Replace(s, "_", "", -1)
|
||||
}
|
||||
|
||||
// NullUnmarshaller is an unmarshaller that can handle a nil input
|
||||
type NullUnmarshaller interface {
|
||||
decode.Unmarshaler
|
||||
Nullable()
|
||||
}
|
||||
|
||||
func isNullable(t reflect.Type) bool {
|
||||
_, ok := reflect.New(t).Interface().(NullUnmarshaller)
|
||||
return ok
|
||||
}
|
70
vendor/github.com/graph-gophers/graphql-go/internal/exec/resolvable/meta.go
generated
vendored
Normal file
70
vendor/github.com/graph-gophers/graphql-go/internal/exec/resolvable/meta.go
generated
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
package resolvable
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/graph-gophers/graphql-go/introspection"
|
||||
"github.com/graph-gophers/graphql-go/types"
|
||||
)
|
||||
|
||||
// Meta defines the details of the metadata schema for introspection.
|
||||
type Meta struct {
|
||||
FieldSchema Field
|
||||
FieldType Field
|
||||
FieldTypename Field
|
||||
Schema *Object
|
||||
Type *Object
|
||||
}
|
||||
|
||||
func newMeta(s *types.Schema) *Meta {
|
||||
var err error
|
||||
b := newBuilder(s)
|
||||
|
||||
metaSchema := s.Types["__Schema"].(*types.ObjectTypeDefinition)
|
||||
so, err := b.makeObjectExec(metaSchema.Name, metaSchema.Fields, nil, false, reflect.TypeOf(&introspection.Schema{}))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
metaType := s.Types["__Type"].(*types.ObjectTypeDefinition)
|
||||
t, err := b.makeObjectExec(metaType.Name, metaType.Fields, nil, false, reflect.TypeOf(&introspection.Type{}))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := b.finish(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fieldTypename := Field{
|
||||
FieldDefinition: types.FieldDefinition{
|
||||
Name: "__typename",
|
||||
Type: &types.NonNull{OfType: s.Types["String"]},
|
||||
},
|
||||
TraceLabel: "GraphQL field: __typename",
|
||||
}
|
||||
|
||||
fieldSchema := Field{
|
||||
FieldDefinition: types.FieldDefinition{
|
||||
Name: "__schema",
|
||||
Type: s.Types["__Schema"],
|
||||
},
|
||||
TraceLabel: "GraphQL field: __schema",
|
||||
}
|
||||
|
||||
fieldType := Field{
|
||||
FieldDefinition: types.FieldDefinition{
|
||||
Name: "__type",
|
||||
Type: s.Types["__Type"],
|
||||
},
|
||||
TraceLabel: "GraphQL field: __type",
|
||||
}
|
||||
|
||||
return &Meta{
|
||||
FieldSchema: fieldSchema,
|
||||
FieldTypename: fieldTypename,
|
||||
FieldType: fieldType,
|
||||
Schema: so,
|
||||
Type: t,
|
||||
}
|
||||
}
|
453
vendor/github.com/graph-gophers/graphql-go/internal/exec/resolvable/resolvable.go
generated
vendored
Normal file
453
vendor/github.com/graph-gophers/graphql-go/internal/exec/resolvable/resolvable.go
generated
vendored
Normal file
@ -0,0 +1,453 @@
|
||||
package resolvable
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/graph-gophers/graphql-go/decode"
|
||||
"github.com/graph-gophers/graphql-go/internal/exec/packer"
|
||||
"github.com/graph-gophers/graphql-go/types"
|
||||
)
|
||||
|
||||
type Schema struct {
|
||||
*Meta
|
||||
types.Schema
|
||||
Query Resolvable
|
||||
Mutation Resolvable
|
||||
Subscription Resolvable
|
||||
Resolver reflect.Value
|
||||
}
|
||||
|
||||
type Resolvable interface {
|
||||
isResolvable()
|
||||
}
|
||||
|
||||
type Object struct {
|
||||
Name string
|
||||
Fields map[string]*Field
|
||||
TypeAssertions map[string]*TypeAssertion
|
||||
}
|
||||
|
||||
type Field struct {
|
||||
types.FieldDefinition
|
||||
TypeName string
|
||||
MethodIndex int
|
||||
FieldIndex []int
|
||||
HasContext bool
|
||||
HasError bool
|
||||
ArgsPacker *packer.StructPacker
|
||||
ValueExec Resolvable
|
||||
TraceLabel string
|
||||
}
|
||||
|
||||
func (f *Field) UseMethodResolver() bool {
|
||||
return len(f.FieldIndex) == 0
|
||||
}
|
||||
|
||||
type TypeAssertion struct {
|
||||
MethodIndex int
|
||||
TypeExec Resolvable
|
||||
}
|
||||
|
||||
type List struct {
|
||||
Elem Resolvable
|
||||
}
|
||||
|
||||
type Scalar struct{}
|
||||
|
||||
func (*Object) isResolvable() {}
|
||||
func (*List) isResolvable() {}
|
||||
func (*Scalar) isResolvable() {}
|
||||
|
||||
func ApplyResolver(s *types.Schema, resolver interface{}) (*Schema, error) {
|
||||
if resolver == nil {
|
||||
return &Schema{Meta: newMeta(s), Schema: *s}, nil
|
||||
}
|
||||
|
||||
b := newBuilder(s)
|
||||
|
||||
var query, mutation, subscription Resolvable
|
||||
|
||||
if t, ok := s.EntryPoints["query"]; ok {
|
||||
if err := b.assignExec(&query, t, reflect.TypeOf(resolver)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if t, ok := s.EntryPoints["mutation"]; ok {
|
||||
if err := b.assignExec(&mutation, t, reflect.TypeOf(resolver)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if t, ok := s.EntryPoints["subscription"]; ok {
|
||||
if err := b.assignExec(&subscription, t, reflect.TypeOf(resolver)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := b.finish(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Schema{
|
||||
Meta: newMeta(s),
|
||||
Schema: *s,
|
||||
Resolver: reflect.ValueOf(resolver),
|
||||
Query: query,
|
||||
Mutation: mutation,
|
||||
Subscription: subscription,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type execBuilder struct {
|
||||
schema *types.Schema
|
||||
resMap map[typePair]*resMapEntry
|
||||
packerBuilder *packer.Builder
|
||||
}
|
||||
|
||||
type typePair struct {
|
||||
graphQLType types.Type
|
||||
resolverType reflect.Type
|
||||
}
|
||||
|
||||
type resMapEntry struct {
|
||||
exec Resolvable
|
||||
targets []*Resolvable
|
||||
}
|
||||
|
||||
func newBuilder(s *types.Schema) *execBuilder {
|
||||
return &execBuilder{
|
||||
schema: s,
|
||||
resMap: make(map[typePair]*resMapEntry),
|
||||
packerBuilder: packer.NewBuilder(),
|
||||
}
|
||||
}
|
||||
|
||||
func (b *execBuilder) finish() error {
|
||||
for _, entry := range b.resMap {
|
||||
for _, target := range entry.targets {
|
||||
*target = entry.exec
|
||||
}
|
||||
}
|
||||
|
||||
return b.packerBuilder.Finish()
|
||||
}
|
||||
|
||||
func (b *execBuilder) assignExec(target *Resolvable, t types.Type, resolverType reflect.Type) error {
|
||||
k := typePair{t, resolverType}
|
||||
ref, ok := b.resMap[k]
|
||||
if !ok {
|
||||
ref = &resMapEntry{}
|
||||
b.resMap[k] = ref
|
||||
var err error
|
||||
ref.exec, err = b.makeExec(t, resolverType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
ref.targets = append(ref.targets, target)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *execBuilder) makeExec(t types.Type, resolverType reflect.Type) (Resolvable, error) {
|
||||
var nonNull bool
|
||||
t, nonNull = unwrapNonNull(t)
|
||||
|
||||
switch t := t.(type) {
|
||||
case *types.ObjectTypeDefinition:
|
||||
return b.makeObjectExec(t.Name, t.Fields, nil, nonNull, resolverType)
|
||||
|
||||
case *types.InterfaceTypeDefinition:
|
||||
return b.makeObjectExec(t.Name, t.Fields, t.PossibleTypes, nonNull, resolverType)
|
||||
|
||||
case *types.Union:
|
||||
return b.makeObjectExec(t.Name, nil, t.UnionMemberTypes, nonNull, resolverType)
|
||||
}
|
||||
|
||||
if !nonNull {
|
||||
if resolverType.Kind() != reflect.Ptr {
|
||||
return nil, fmt.Errorf("%s is not a pointer", resolverType)
|
||||
}
|
||||
resolverType = resolverType.Elem()
|
||||
}
|
||||
|
||||
switch t := t.(type) {
|
||||
case *types.ScalarTypeDefinition:
|
||||
return makeScalarExec(t, resolverType)
|
||||
|
||||
case *types.EnumTypeDefinition:
|
||||
return &Scalar{}, nil
|
||||
|
||||
case *types.List:
|
||||
if resolverType.Kind() != reflect.Slice {
|
||||
return nil, fmt.Errorf("%s is not a slice", resolverType)
|
||||
}
|
||||
e := &List{}
|
||||
if err := b.assignExec(&e.Elem, t.OfType, resolverType.Elem()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return e, nil
|
||||
|
||||
default:
|
||||
panic("invalid type: " + t.String())
|
||||
}
|
||||
}
|
||||
|
||||
func makeScalarExec(t *types.ScalarTypeDefinition, resolverType reflect.Type) (Resolvable, error) {
|
||||
implementsType := false
|
||||
switch r := reflect.New(resolverType).Interface().(type) {
|
||||
case *int32:
|
||||
implementsType = t.Name == "Int"
|
||||
case *float64:
|
||||
implementsType = t.Name == "Float"
|
||||
case *string:
|
||||
implementsType = t.Name == "String"
|
||||
case *bool:
|
||||
implementsType = t.Name == "Boolean"
|
||||
case decode.Unmarshaler:
|
||||
implementsType = r.ImplementsGraphQLType(t.Name)
|
||||
}
|
||||
|
||||
if !implementsType {
|
||||
return nil, fmt.Errorf("can not use %s as %s", resolverType, t.Name)
|
||||
}
|
||||
return &Scalar{}, nil
|
||||
}
|
||||
|
||||
func (b *execBuilder) makeObjectExec(typeName string, fields types.FieldsDefinition, possibleTypes []*types.ObjectTypeDefinition,
|
||||
nonNull bool, resolverType reflect.Type) (*Object, error) {
|
||||
if !nonNull {
|
||||
if resolverType.Kind() != reflect.Ptr && resolverType.Kind() != reflect.Interface {
|
||||
return nil, fmt.Errorf("%s is not a pointer or interface", resolverType)
|
||||
}
|
||||
}
|
||||
|
||||
methodHasReceiver := resolverType.Kind() != reflect.Interface
|
||||
|
||||
Fields := make(map[string]*Field)
|
||||
rt := unwrapPtr(resolverType)
|
||||
fieldsCount := fieldCount(rt, map[string]int{})
|
||||
for _, f := range fields {
|
||||
var fieldIndex []int
|
||||
methodIndex := findMethod(resolverType, f.Name)
|
||||
if b.schema.UseFieldResolvers && methodIndex == -1 {
|
||||
if fieldsCount[strings.ToLower(stripUnderscore(f.Name))] > 1 {
|
||||
return nil, fmt.Errorf("%s does not resolve %q: ambiguous field %q", resolverType, typeName, f.Name)
|
||||
}
|
||||
fieldIndex = findField(rt, f.Name, []int{})
|
||||
}
|
||||
if methodIndex == -1 && len(fieldIndex) == 0 {
|
||||
hint := ""
|
||||
if findMethod(reflect.PtrTo(resolverType), f.Name) != -1 {
|
||||
hint = " (hint: the method exists on the pointer type)"
|
||||
}
|
||||
return nil, fmt.Errorf("%s does not resolve %q: missing method for field %q%s", resolverType, typeName, f.Name, hint)
|
||||
}
|
||||
|
||||
var m reflect.Method
|
||||
var sf reflect.StructField
|
||||
if methodIndex != -1 {
|
||||
m = resolverType.Method(methodIndex)
|
||||
} else {
|
||||
sf = rt.FieldByIndex(fieldIndex)
|
||||
}
|
||||
fe, err := b.makeFieldExec(typeName, f, m, sf, methodIndex, fieldIndex, methodHasReceiver)
|
||||
if err != nil {
|
||||
var resolverName string
|
||||
if methodIndex != -1 {
|
||||
resolverName = m.Name
|
||||
} else {
|
||||
resolverName = sf.Name
|
||||
}
|
||||
return nil, fmt.Errorf("%s\n\tused by (%s).%s", err, resolverType, resolverName)
|
||||
}
|
||||
Fields[f.Name] = fe
|
||||
}
|
||||
|
||||
// Check type assertions when
|
||||
// 1) using method resolvers
|
||||
// 2) Or resolver is not an interface type
|
||||
typeAssertions := make(map[string]*TypeAssertion)
|
||||
if !b.schema.UseFieldResolvers || resolverType.Kind() != reflect.Interface {
|
||||
for _, impl := range possibleTypes {
|
||||
methodIndex := findMethod(resolverType, "To"+impl.Name)
|
||||
if methodIndex == -1 {
|
||||
return nil, fmt.Errorf("%s does not resolve %q: missing method %q to convert to %q", resolverType, typeName, "To"+impl.Name, impl.Name)
|
||||
}
|
||||
if resolverType.Method(methodIndex).Type.NumOut() != 2 {
|
||||
return nil, fmt.Errorf("%s does not resolve %q: method %q should return a value and a bool indicating success", resolverType, typeName, "To"+impl.Name)
|
||||
}
|
||||
a := &TypeAssertion{
|
||||
MethodIndex: methodIndex,
|
||||
}
|
||||
if err := b.assignExec(&a.TypeExec, impl, resolverType.Method(methodIndex).Type.Out(0)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
typeAssertions[impl.Name] = a
|
||||
}
|
||||
}
|
||||
|
||||
return &Object{
|
||||
Name: typeName,
|
||||
Fields: Fields,
|
||||
TypeAssertions: typeAssertions,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var contextType = reflect.TypeOf((*context.Context)(nil)).Elem()
|
||||
var errorType = reflect.TypeOf((*error)(nil)).Elem()
|
||||
|
||||
func (b *execBuilder) makeFieldExec(typeName string, f *types.FieldDefinition, m reflect.Method, sf reflect.StructField,
|
||||
methodIndex int, fieldIndex []int, methodHasReceiver bool) (*Field, error) {
|
||||
|
||||
var argsPacker *packer.StructPacker
|
||||
var hasError bool
|
||||
var hasContext bool
|
||||
|
||||
// Validate resolver method only when there is one
|
||||
if methodIndex != -1 {
|
||||
in := make([]reflect.Type, m.Type.NumIn())
|
||||
for i := range in {
|
||||
in[i] = m.Type.In(i)
|
||||
}
|
||||
if methodHasReceiver {
|
||||
in = in[1:] // first parameter is receiver
|
||||
}
|
||||
|
||||
hasContext = len(in) > 0 && in[0] == contextType
|
||||
if hasContext {
|
||||
in = in[1:]
|
||||
}
|
||||
|
||||
if len(f.Arguments) > 0 {
|
||||
if len(in) == 0 {
|
||||
return nil, fmt.Errorf("must have parameter for field arguments")
|
||||
}
|
||||
var err error
|
||||
argsPacker, err = b.packerBuilder.MakeStructPacker(f.Arguments, in[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
in = in[1:]
|
||||
}
|
||||
|
||||
if len(in) > 0 {
|
||||
return nil, fmt.Errorf("too many parameters")
|
||||
}
|
||||
|
||||
maxNumOfReturns := 2
|
||||
if m.Type.NumOut() < maxNumOfReturns-1 {
|
||||
return nil, fmt.Errorf("too few return values")
|
||||
}
|
||||
|
||||
if m.Type.NumOut() > maxNumOfReturns {
|
||||
return nil, fmt.Errorf("too many return values")
|
||||
}
|
||||
|
||||
hasError = m.Type.NumOut() == maxNumOfReturns
|
||||
if hasError {
|
||||
if m.Type.Out(maxNumOfReturns-1) != errorType {
|
||||
return nil, fmt.Errorf(`must have "error" as its last return value`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fe := &Field{
|
||||
FieldDefinition: *f,
|
||||
TypeName: typeName,
|
||||
MethodIndex: methodIndex,
|
||||
FieldIndex: fieldIndex,
|
||||
HasContext: hasContext,
|
||||
ArgsPacker: argsPacker,
|
||||
HasError: hasError,
|
||||
TraceLabel: fmt.Sprintf("GraphQL field: %s.%s", typeName, f.Name),
|
||||
}
|
||||
|
||||
var out reflect.Type
|
||||
if methodIndex != -1 {
|
||||
out = m.Type.Out(0)
|
||||
sub, ok := b.schema.EntryPoints["subscription"]
|
||||
if ok && typeName == sub.TypeName() && out.Kind() == reflect.Chan {
|
||||
out = m.Type.Out(0).Elem()
|
||||
}
|
||||
} else {
|
||||
out = sf.Type
|
||||
}
|
||||
if err := b.assignExec(&fe.ValueExec, f.Type, out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return fe, nil
|
||||
}
|
||||
|
||||
func findMethod(t reflect.Type, name string) int {
|
||||
for i := 0; i < t.NumMethod(); i++ {
|
||||
if strings.EqualFold(stripUnderscore(name), stripUnderscore(t.Method(i).Name)) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func findField(t reflect.Type, name string, index []int) []int {
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
|
||||
if field.Type.Kind() == reflect.Struct && field.Anonymous {
|
||||
newIndex := findField(field.Type, name, []int{i})
|
||||
if len(newIndex) > 1 {
|
||||
return append(index, newIndex...)
|
||||
}
|
||||
}
|
||||
|
||||
if strings.EqualFold(stripUnderscore(name), stripUnderscore(field.Name)) {
|
||||
return append(index, i)
|
||||
}
|
||||
}
|
||||
|
||||
return index
|
||||
}
|
||||
|
||||
// fieldCount helps resolve ambiguity when more than one embedded struct contains fields with the same name.
|
||||
func fieldCount(t reflect.Type, count map[string]int) map[string]int {
|
||||
if t.Kind() != reflect.Struct {
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
fieldName := strings.ToLower(stripUnderscore(field.Name))
|
||||
|
||||
if field.Type.Kind() == reflect.Struct && field.Anonymous {
|
||||
count = fieldCount(field.Type, count)
|
||||
} else {
|
||||
if _, ok := count[fieldName]; !ok {
|
||||
count[fieldName] = 0
|
||||
}
|
||||
count[fieldName]++
|
||||
}
|
||||
}
|
||||
|
||||
return count
|
||||
}
|
||||
|
||||
func unwrapNonNull(t types.Type) (types.Type, bool) {
|
||||
if nn, ok := t.(*types.NonNull); ok {
|
||||
return nn.OfType, true
|
||||
}
|
||||
return t, false
|
||||
}
|
||||
|
||||
func stripUnderscore(s string) string {
|
||||
return strings.Replace(s, "_", "", -1)
|
||||
}
|
||||
|
||||
func unwrapPtr(t reflect.Type) reflect.Type {
|
||||
if t.Kind() == reflect.Ptr {
|
||||
return t.Elem()
|
||||
}
|
||||
return t
|
||||
}
|
269
vendor/github.com/graph-gophers/graphql-go/internal/exec/selected/selected.go
generated
vendored
Normal file
269
vendor/github.com/graph-gophers/graphql-go/internal/exec/selected/selected.go
generated
vendored
Normal file
@ -0,0 +1,269 @@
|
||||
package selected
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"github.com/graph-gophers/graphql-go/errors"
|
||||
"github.com/graph-gophers/graphql-go/internal/exec/packer"
|
||||
"github.com/graph-gophers/graphql-go/internal/exec/resolvable"
|
||||
"github.com/graph-gophers/graphql-go/internal/query"
|
||||
"github.com/graph-gophers/graphql-go/introspection"
|
||||
"github.com/graph-gophers/graphql-go/types"
|
||||
)
|
||||
|
||||
type Request struct {
|
||||
Schema *types.Schema
|
||||
Doc *types.ExecutableDefinition
|
||||
Vars map[string]interface{}
|
||||
Mu sync.Mutex
|
||||
Errs []*errors.QueryError
|
||||
DisableIntrospection bool
|
||||
}
|
||||
|
||||
func (r *Request) AddError(err *errors.QueryError) {
|
||||
r.Mu.Lock()
|
||||
r.Errs = append(r.Errs, err)
|
||||
r.Mu.Unlock()
|
||||
}
|
||||
|
||||
func ApplyOperation(r *Request, s *resolvable.Schema, op *types.OperationDefinition) []Selection {
|
||||
var obj *resolvable.Object
|
||||
switch op.Type {
|
||||
case query.Query:
|
||||
obj = s.Query.(*resolvable.Object)
|
||||
case query.Mutation:
|
||||
obj = s.Mutation.(*resolvable.Object)
|
||||
case query.Subscription:
|
||||
obj = s.Subscription.(*resolvable.Object)
|
||||
}
|
||||
return applySelectionSet(r, s, obj, op.Selections)
|
||||
}
|
||||
|
||||
type Selection interface {
|
||||
isSelection()
|
||||
}
|
||||
|
||||
type SchemaField struct {
|
||||
resolvable.Field
|
||||
Alias string
|
||||
Args map[string]interface{}
|
||||
PackedArgs reflect.Value
|
||||
Sels []Selection
|
||||
Async bool
|
||||
FixedResult reflect.Value
|
||||
}
|
||||
|
||||
type TypeAssertion struct {
|
||||
resolvable.TypeAssertion
|
||||
Sels []Selection
|
||||
}
|
||||
|
||||
type TypenameField struct {
|
||||
resolvable.Object
|
||||
Alias string
|
||||
}
|
||||
|
||||
func (*SchemaField) isSelection() {}
|
||||
func (*TypeAssertion) isSelection() {}
|
||||
func (*TypenameField) isSelection() {}
|
||||
|
||||
func applySelectionSet(r *Request, s *resolvable.Schema, e *resolvable.Object, sels []types.Selection) (flattenedSels []Selection) {
|
||||
for _, sel := range sels {
|
||||
switch sel := sel.(type) {
|
||||
case *types.Field:
|
||||
field := sel
|
||||
if skipByDirective(r, field.Directives) {
|
||||
continue
|
||||
}
|
||||
|
||||
switch field.Name.Name {
|
||||
case "__typename":
|
||||
// __typename is available even though r.DisableIntrospection == true
|
||||
// because it is necessary when using union types and interfaces: https://graphql.org/learn/schema/#union-types
|
||||
flattenedSels = append(flattenedSels, &TypenameField{
|
||||
Object: *e,
|
||||
Alias: field.Alias.Name,
|
||||
})
|
||||
|
||||
case "__schema":
|
||||
if !r.DisableIntrospection {
|
||||
flattenedSels = append(flattenedSels, &SchemaField{
|
||||
Field: s.Meta.FieldSchema,
|
||||
Alias: field.Alias.Name,
|
||||
Sels: applySelectionSet(r, s, s.Meta.Schema, field.SelectionSet),
|
||||
Async: true,
|
||||
FixedResult: reflect.ValueOf(introspection.WrapSchema(r.Schema)),
|
||||
})
|
||||
}
|
||||
|
||||
case "__type":
|
||||
if !r.DisableIntrospection {
|
||||
p := packer.ValuePacker{ValueType: reflect.TypeOf("")}
|
||||
v, err := p.Pack(field.Arguments.MustGet("name").Deserialize(r.Vars))
|
||||
if err != nil {
|
||||
r.AddError(errors.Errorf("%s", err))
|
||||
return nil
|
||||
}
|
||||
|
||||
t, ok := r.Schema.Types[v.String()]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
flattenedSels = append(flattenedSels, &SchemaField{
|
||||
Field: s.Meta.FieldType,
|
||||
Alias: field.Alias.Name,
|
||||
Sels: applySelectionSet(r, s, s.Meta.Type, field.SelectionSet),
|
||||
Async: true,
|
||||
FixedResult: reflect.ValueOf(introspection.WrapType(t)),
|
||||
})
|
||||
}
|
||||
|
||||
default:
|
||||
fe := e.Fields[field.Name.Name]
|
||||
|
||||
var args map[string]interface{}
|
||||
var packedArgs reflect.Value
|
||||
if fe.ArgsPacker != nil {
|
||||
args = make(map[string]interface{})
|
||||
for _, arg := range field.Arguments {
|
||||
args[arg.Name.Name] = arg.Value.Deserialize(r.Vars)
|
||||
}
|
||||
var err error
|
||||
packedArgs, err = fe.ArgsPacker.Pack(args)
|
||||
if err != nil {
|
||||
r.AddError(errors.Errorf("%s", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fieldSels := applyField(r, s, fe.ValueExec, field.SelectionSet)
|
||||
flattenedSels = append(flattenedSels, &SchemaField{
|
||||
Field: *fe,
|
||||
Alias: field.Alias.Name,
|
||||
Args: args,
|
||||
PackedArgs: packedArgs,
|
||||
Sels: fieldSels,
|
||||
Async: fe.HasContext || fe.ArgsPacker != nil || fe.HasError || HasAsyncSel(fieldSels),
|
||||
})
|
||||
}
|
||||
|
||||
case *types.InlineFragment:
|
||||
frag := sel
|
||||
if skipByDirective(r, frag.Directives) {
|
||||
continue
|
||||
}
|
||||
flattenedSels = append(flattenedSels, applyFragment(r, s, e, &frag.Fragment)...)
|
||||
|
||||
case *types.FragmentSpread:
|
||||
spread := sel
|
||||
if skipByDirective(r, spread.Directives) {
|
||||
continue
|
||||
}
|
||||
flattenedSels = append(flattenedSels, applyFragment(r, s, e, &r.Doc.Fragments.Get(spread.Name.Name).Fragment)...)
|
||||
|
||||
default:
|
||||
panic("invalid type")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func applyFragment(r *Request, s *resolvable.Schema, e *resolvable.Object, frag *types.Fragment) []Selection {
|
||||
if frag.On.Name != e.Name {
|
||||
t := r.Schema.Resolve(frag.On.Name)
|
||||
face, ok := t.(*types.InterfaceTypeDefinition)
|
||||
if !ok && frag.On.Name != "" {
|
||||
a, ok2 := e.TypeAssertions[frag.On.Name]
|
||||
if !ok2 {
|
||||
panic(fmt.Errorf("%q does not implement %q", frag.On, e.Name)) // TODO proper error handling
|
||||
}
|
||||
|
||||
return []Selection{&TypeAssertion{
|
||||
TypeAssertion: *a,
|
||||
Sels: applySelectionSet(r, s, a.TypeExec.(*resolvable.Object), frag.Selections),
|
||||
}}
|
||||
}
|
||||
if ok && len(face.PossibleTypes) > 0 {
|
||||
sels := []Selection{}
|
||||
for _, t := range face.PossibleTypes {
|
||||
if t.Name == e.Name {
|
||||
return applySelectionSet(r, s, e, frag.Selections)
|
||||
}
|
||||
|
||||
if a, ok := e.TypeAssertions[t.Name]; ok {
|
||||
sels = append(sels, &TypeAssertion{
|
||||
TypeAssertion: *a,
|
||||
Sels: applySelectionSet(r, s, a.TypeExec.(*resolvable.Object), frag.Selections),
|
||||
})
|
||||
}
|
||||
}
|
||||
if len(sels) == 0 {
|
||||
panic(fmt.Errorf("%q does not implement %q", e.Name, frag.On)) // TODO proper error handling
|
||||
}
|
||||
return sels
|
||||
}
|
||||
}
|
||||
return applySelectionSet(r, s, e, frag.Selections)
|
||||
}
|
||||
|
||||
func applyField(r *Request, s *resolvable.Schema, e resolvable.Resolvable, sels []types.Selection) []Selection {
|
||||
switch e := e.(type) {
|
||||
case *resolvable.Object:
|
||||
return applySelectionSet(r, s, e, sels)
|
||||
case *resolvable.List:
|
||||
return applyField(r, s, e.Elem, sels)
|
||||
case *resolvable.Scalar:
|
||||
return nil
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
|
||||
func skipByDirective(r *Request, directives types.DirectiveList) bool {
|
||||
if d := directives.Get("skip"); d != nil {
|
||||
p := packer.ValuePacker{ValueType: reflect.TypeOf(false)}
|
||||
v, err := p.Pack(d.Arguments.MustGet("if").Deserialize(r.Vars))
|
||||
if err != nil {
|
||||
r.AddError(errors.Errorf("%s", err))
|
||||
}
|
||||
if err == nil && v.Bool() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if d := directives.Get("include"); d != nil {
|
||||
p := packer.ValuePacker{ValueType: reflect.TypeOf(false)}
|
||||
v, err := p.Pack(d.Arguments.MustGet("if").Deserialize(r.Vars))
|
||||
if err != nil {
|
||||
r.AddError(errors.Errorf("%s", err))
|
||||
}
|
||||
if err == nil && !v.Bool() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func HasAsyncSel(sels []Selection) bool {
|
||||
for _, sel := range sels {
|
||||
switch sel := sel.(type) {
|
||||
case *SchemaField:
|
||||
if sel.Async {
|
||||
return true
|
||||
}
|
||||
case *TypeAssertion:
|
||||
if HasAsyncSel(sel.Sels) {
|
||||
return true
|
||||
}
|
||||
case *TypenameField:
|
||||
// sync
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
179
vendor/github.com/graph-gophers/graphql-go/internal/exec/subscribe.go
generated
vendored
Normal file
179
vendor/github.com/graph-gophers/graphql-go/internal/exec/subscribe.go
generated
vendored
Normal file
@ -0,0 +1,179 @@
|
||||
package exec
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/graph-gophers/graphql-go/errors"
|
||||
"github.com/graph-gophers/graphql-go/internal/exec/resolvable"
|
||||
"github.com/graph-gophers/graphql-go/internal/exec/selected"
|
||||
"github.com/graph-gophers/graphql-go/types"
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
Data json.RawMessage
|
||||
Errors []*errors.QueryError
|
||||
}
|
||||
|
||||
func (r *Request) Subscribe(ctx context.Context, s *resolvable.Schema, op *types.OperationDefinition) <-chan *Response {
|
||||
var result reflect.Value
|
||||
var f *fieldToExec
|
||||
var err *errors.QueryError
|
||||
func() {
|
||||
defer r.handlePanic(ctx)
|
||||
|
||||
sels := selected.ApplyOperation(&r.Request, s, op)
|
||||
var fields []*fieldToExec
|
||||
collectFieldsToResolve(sels, s, s.Resolver, &fields, make(map[string]*fieldToExec))
|
||||
|
||||
// TODO: move this check into validation.Validate
|
||||
if len(fields) != 1 {
|
||||
err = errors.Errorf("%s", "can subscribe to at most one subscription at a time")
|
||||
return
|
||||
}
|
||||
f = fields[0]
|
||||
|
||||
var in []reflect.Value
|
||||
if f.field.HasContext {
|
||||
in = append(in, reflect.ValueOf(ctx))
|
||||
}
|
||||
if f.field.ArgsPacker != nil {
|
||||
in = append(in, f.field.PackedArgs)
|
||||
}
|
||||
callOut := f.resolver.Method(f.field.MethodIndex).Call(in)
|
||||
result = callOut[0]
|
||||
|
||||
if f.field.HasError && !callOut[1].IsNil() {
|
||||
switch resolverErr := callOut[1].Interface().(type) {
|
||||
case *errors.QueryError:
|
||||
err = resolverErr
|
||||
case error:
|
||||
err = errors.Errorf("%s", resolverErr)
|
||||
err.ResolverError = resolverErr
|
||||
default:
|
||||
panic(fmt.Errorf("can only deal with *QueryError and error types, got %T", resolverErr))
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Handles the case where the locally executed func above panicked
|
||||
if len(r.Request.Errs) > 0 {
|
||||
return sendAndReturnClosed(&Response{Errors: r.Request.Errs})
|
||||
}
|
||||
|
||||
if f == nil {
|
||||
return sendAndReturnClosed(&Response{Errors: []*errors.QueryError{err}})
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if _, nonNullChild := f.field.Type.(*types.NonNull); nonNullChild {
|
||||
return sendAndReturnClosed(&Response{Errors: []*errors.QueryError{err}})
|
||||
}
|
||||
return sendAndReturnClosed(&Response{Data: []byte(fmt.Sprintf(`{"%s":null}`, f.field.Alias)), Errors: []*errors.QueryError{err}})
|
||||
}
|
||||
|
||||
if ctxErr := ctx.Err(); ctxErr != nil {
|
||||
return sendAndReturnClosed(&Response{Errors: []*errors.QueryError{errors.Errorf("%s", ctxErr)}})
|
||||
}
|
||||
|
||||
c := make(chan *Response)
|
||||
// TODO: handle resolver nil channel better?
|
||||
if result.IsZero() {
|
||||
close(c)
|
||||
return c
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
// Check subscription context
|
||||
chosen, resp, ok := reflect.Select([]reflect.SelectCase{
|
||||
{
|
||||
Dir: reflect.SelectRecv,
|
||||
Chan: reflect.ValueOf(ctx.Done()),
|
||||
},
|
||||
{
|
||||
Dir: reflect.SelectRecv,
|
||||
Chan: result,
|
||||
},
|
||||
})
|
||||
switch chosen {
|
||||
// subscription context done
|
||||
case 0:
|
||||
close(c)
|
||||
return
|
||||
// upstream received
|
||||
case 1:
|
||||
// upstream closed
|
||||
if !ok {
|
||||
close(c)
|
||||
return
|
||||
}
|
||||
|
||||
subR := &Request{
|
||||
Request: selected.Request{
|
||||
Doc: r.Request.Doc,
|
||||
Vars: r.Request.Vars,
|
||||
Schema: r.Request.Schema,
|
||||
},
|
||||
Limiter: r.Limiter,
|
||||
Tracer: r.Tracer,
|
||||
Logger: r.Logger,
|
||||
}
|
||||
var out bytes.Buffer
|
||||
func() {
|
||||
timeout := r.SubscribeResolverTimeout
|
||||
if timeout == 0 {
|
||||
timeout = time.Second
|
||||
}
|
||||
|
||||
subCtx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
|
||||
// resolve response
|
||||
func() {
|
||||
defer subR.handlePanic(subCtx)
|
||||
|
||||
var buf bytes.Buffer
|
||||
subR.execSelectionSet(subCtx, f.sels, f.field.Type, &pathSegment{nil, f.field.Alias}, s, resp, &buf)
|
||||
|
||||
propagateChildError := false
|
||||
if _, nonNullChild := f.field.Type.(*types.NonNull); nonNullChild && resolvedToNull(&buf) {
|
||||
propagateChildError = true
|
||||
}
|
||||
|
||||
if !propagateChildError {
|
||||
out.WriteString(fmt.Sprintf(`{"%s":`, f.field.Alias))
|
||||
out.Write(buf.Bytes())
|
||||
out.WriteString(`}`)
|
||||
}
|
||||
}()
|
||||
|
||||
if err := subCtx.Err(); err != nil {
|
||||
c <- &Response{Errors: []*errors.QueryError{errors.Errorf("%s", err)}}
|
||||
return
|
||||
}
|
||||
|
||||
// Send response within timeout
|
||||
// TODO: maybe block until sent?
|
||||
select {
|
||||
case <-subCtx.Done():
|
||||
case c <- &Response{Data: out.Bytes(), Errors: subR.Errs}:
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func sendAndReturnClosed(resp *Response) chan *Response {
|
||||
c := make(chan *Response, 1)
|
||||
c <- resp
|
||||
close(c)
|
||||
return c
|
||||
}
|
156
vendor/github.com/graph-gophers/graphql-go/internal/query/query.go
generated
vendored
Normal file
156
vendor/github.com/graph-gophers/graphql-go/internal/query/query.go
generated
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"text/scanner"
|
||||
|
||||
"github.com/graph-gophers/graphql-go/errors"
|
||||
"github.com/graph-gophers/graphql-go/internal/common"
|
||||
"github.com/graph-gophers/graphql-go/types"
|
||||
)
|
||||
|
||||
const (
|
||||
Query types.OperationType = "QUERY"
|
||||
Mutation types.OperationType = "MUTATION"
|
||||
Subscription types.OperationType = "SUBSCRIPTION"
|
||||
)
|
||||
|
||||
func Parse(queryString string) (*types.ExecutableDefinition, *errors.QueryError) {
|
||||
l := common.NewLexer(queryString, false)
|
||||
|
||||
var execDef *types.ExecutableDefinition
|
||||
err := l.CatchSyntaxError(func() { execDef = parseExecutableDefinition(l) })
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return execDef, nil
|
||||
}
|
||||
|
||||
func parseExecutableDefinition(l *common.Lexer) *types.ExecutableDefinition {
|
||||
ed := &types.ExecutableDefinition{}
|
||||
l.ConsumeWhitespace()
|
||||
for l.Peek() != scanner.EOF {
|
||||
if l.Peek() == '{' {
|
||||
op := &types.OperationDefinition{Type: Query, Loc: l.Location()}
|
||||
op.Selections = parseSelectionSet(l)
|
||||
ed.Operations = append(ed.Operations, op)
|
||||
continue
|
||||
}
|
||||
|
||||
loc := l.Location()
|
||||
switch x := l.ConsumeIdent(); x {
|
||||
case "query":
|
||||
op := parseOperation(l, Query)
|
||||
op.Loc = loc
|
||||
ed.Operations = append(ed.Operations, op)
|
||||
|
||||
case "mutation":
|
||||
ed.Operations = append(ed.Operations, parseOperation(l, Mutation))
|
||||
|
||||
case "subscription":
|
||||
ed.Operations = append(ed.Operations, parseOperation(l, Subscription))
|
||||
|
||||
case "fragment":
|
||||
frag := parseFragment(l)
|
||||
frag.Loc = loc
|
||||
ed.Fragments = append(ed.Fragments, frag)
|
||||
|
||||
default:
|
||||
l.SyntaxError(fmt.Sprintf(`unexpected %q, expecting "fragment"`, x))
|
||||
}
|
||||
}
|
||||
return ed
|
||||
}
|
||||
|
||||
func parseOperation(l *common.Lexer, opType types.OperationType) *types.OperationDefinition {
|
||||
op := &types.OperationDefinition{Type: opType}
|
||||
op.Name.Loc = l.Location()
|
||||
if l.Peek() == scanner.Ident {
|
||||
op.Name = l.ConsumeIdentWithLoc()
|
||||
}
|
||||
op.Directives = common.ParseDirectives(l)
|
||||
if l.Peek() == '(' {
|
||||
l.ConsumeToken('(')
|
||||
for l.Peek() != ')' {
|
||||
loc := l.Location()
|
||||
l.ConsumeToken('$')
|
||||
iv := common.ParseInputValue(l)
|
||||
iv.Loc = loc
|
||||
op.Vars = append(op.Vars, iv)
|
||||
}
|
||||
l.ConsumeToken(')')
|
||||
}
|
||||
op.Selections = parseSelectionSet(l)
|
||||
return op
|
||||
}
|
||||
|
||||
func parseFragment(l *common.Lexer) *types.FragmentDefinition {
|
||||
f := &types.FragmentDefinition{}
|
||||
f.Name = l.ConsumeIdentWithLoc()
|
||||
l.ConsumeKeyword("on")
|
||||
f.On = types.TypeName{Ident: l.ConsumeIdentWithLoc()}
|
||||
f.Directives = common.ParseDirectives(l)
|
||||
f.Selections = parseSelectionSet(l)
|
||||
return f
|
||||
}
|
||||
|
||||
func parseSelectionSet(l *common.Lexer) []types.Selection {
|
||||
var sels []types.Selection
|
||||
l.ConsumeToken('{')
|
||||
for l.Peek() != '}' {
|
||||
sels = append(sels, parseSelection(l))
|
||||
}
|
||||
l.ConsumeToken('}')
|
||||
return sels
|
||||
}
|
||||
|
||||
func parseSelection(l *common.Lexer) types.Selection {
|
||||
if l.Peek() == '.' {
|
||||
return parseSpread(l)
|
||||
}
|
||||
return parseFieldDef(l)
|
||||
}
|
||||
|
||||
func parseFieldDef(l *common.Lexer) *types.Field {
|
||||
f := &types.Field{}
|
||||
f.Alias = l.ConsumeIdentWithLoc()
|
||||
f.Name = f.Alias
|
||||
if l.Peek() == ':' {
|
||||
l.ConsumeToken(':')
|
||||
f.Name = l.ConsumeIdentWithLoc()
|
||||
}
|
||||
if l.Peek() == '(' {
|
||||
f.Arguments = common.ParseArgumentList(l)
|
||||
}
|
||||
f.Directives = common.ParseDirectives(l)
|
||||
if l.Peek() == '{' {
|
||||
f.SelectionSetLoc = l.Location()
|
||||
f.SelectionSet = parseSelectionSet(l)
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func parseSpread(l *common.Lexer) types.Selection {
|
||||
loc := l.Location()
|
||||
l.ConsumeToken('.')
|
||||
l.ConsumeToken('.')
|
||||
l.ConsumeToken('.')
|
||||
|
||||
f := &types.InlineFragment{Loc: loc}
|
||||
if l.Peek() == scanner.Ident {
|
||||
ident := l.ConsumeIdentWithLoc()
|
||||
if ident.Name != "on" {
|
||||
fs := &types.FragmentSpread{
|
||||
Name: ident,
|
||||
Loc: loc,
|
||||
}
|
||||
fs.Directives = common.ParseDirectives(l)
|
||||
return fs
|
||||
}
|
||||
f.On = types.TypeName{Ident: l.ConsumeIdentWithLoc()}
|
||||
}
|
||||
f.Directives = common.ParseDirectives(l)
|
||||
f.Selections = parseSelectionSet(l)
|
||||
return f
|
||||
}
|
203
vendor/github.com/graph-gophers/graphql-go/internal/schema/meta.go
generated
vendored
Normal file
203
vendor/github.com/graph-gophers/graphql-go/internal/schema/meta.go
generated
vendored
Normal file
@ -0,0 +1,203 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"github.com/graph-gophers/graphql-go/types"
|
||||
)
|
||||
|
||||
func init() {
|
||||
_ = newMeta()
|
||||
}
|
||||
|
||||
// newMeta initializes an instance of the meta Schema.
|
||||
func newMeta() *types.Schema {
|
||||
s := &types.Schema{
|
||||
EntryPointNames: make(map[string]string),
|
||||
Types: make(map[string]types.NamedType),
|
||||
Directives: make(map[string]*types.DirectiveDefinition),
|
||||
}
|
||||
|
||||
err := Parse(s, metaSrc, false)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
var metaSrc = `
|
||||
# The ` + "`" + `Int` + "`" + ` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.
|
||||
scalar Int
|
||||
|
||||
# The ` + "`" + `Float` + "`" + ` scalar type represents signed double-precision fractional values as specified by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point).
|
||||
scalar Float
|
||||
|
||||
# The ` + "`" + `String` + "`" + ` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
|
||||
scalar String
|
||||
|
||||
# The ` + "`" + `Boolean` + "`" + ` scalar type represents ` + "`" + `true` + "`" + ` or ` + "`" + `false` + "`" + `.
|
||||
scalar Boolean
|
||||
|
||||
# The ` + "`" + `ID` + "`" + ` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as ` + "`" + `"4"` + "`" + `) or integer (such as ` + "`" + `4` + "`" + `) input value will be accepted as an ID.
|
||||
scalar ID
|
||||
|
||||
# Directs the executor to include this field or fragment only when the ` + "`" + `if` + "`" + ` argument is true.
|
||||
directive @include(
|
||||
# Included when true.
|
||||
if: Boolean!
|
||||
) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
|
||||
|
||||
# Directs the executor to skip this field or fragment when the ` + "`" + `if` + "`" + ` argument is true.
|
||||
directive @skip(
|
||||
# Skipped when true.
|
||||
if: Boolean!
|
||||
) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
|
||||
|
||||
# Marks an element of a GraphQL schema as no longer supported.
|
||||
directive @deprecated(
|
||||
# Explains why this element was deprecated, usually also including a suggestion
|
||||
# for how to access supported similar data. Formatted in
|
||||
# [Markdown](https://daringfireball.net/projects/markdown/).
|
||||
reason: String = "No longer supported"
|
||||
) on FIELD_DEFINITION | ENUM_VALUE
|
||||
|
||||
# A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.
|
||||
#
|
||||
# In some cases, you need to provide options to alter GraphQL's execution behavior
|
||||
# in ways field arguments will not suffice, such as conditionally including or
|
||||
# skipping a field. Directives provide this by describing additional information
|
||||
# to the executor.
|
||||
type __Directive {
|
||||
name: String!
|
||||
description: String
|
||||
locations: [__DirectiveLocation!]!
|
||||
args: [__InputValue!]!
|
||||
}
|
||||
|
||||
# A Directive can be adjacent to many parts of the GraphQL language, a
|
||||
# __DirectiveLocation describes one such possible adjacencies.
|
||||
enum __DirectiveLocation {
|
||||
# Location adjacent to a query operation.
|
||||
QUERY
|
||||
# Location adjacent to a mutation operation.
|
||||
MUTATION
|
||||
# Location adjacent to a subscription operation.
|
||||
SUBSCRIPTION
|
||||
# Location adjacent to a field.
|
||||
FIELD
|
||||
# Location adjacent to a fragment definition.
|
||||
FRAGMENT_DEFINITION
|
||||
# Location adjacent to a fragment spread.
|
||||
FRAGMENT_SPREAD
|
||||
# Location adjacent to an inline fragment.
|
||||
INLINE_FRAGMENT
|
||||
# Location adjacent to a schema definition.
|
||||
SCHEMA
|
||||
# Location adjacent to a scalar definition.
|
||||
SCALAR
|
||||
# Location adjacent to an object type definition.
|
||||
OBJECT
|
||||
# Location adjacent to a field definition.
|
||||
FIELD_DEFINITION
|
||||
# Location adjacent to an argument definition.
|
||||
ARGUMENT_DEFINITION
|
||||
# Location adjacent to an interface definition.
|
||||
INTERFACE
|
||||
# Location adjacent to a union definition.
|
||||
UNION
|
||||
# Location adjacent to an enum definition.
|
||||
ENUM
|
||||
# Location adjacent to an enum value definition.
|
||||
ENUM_VALUE
|
||||
# Location adjacent to an input object type definition.
|
||||
INPUT_OBJECT
|
||||
# Location adjacent to an input object field definition.
|
||||
INPUT_FIELD_DEFINITION
|
||||
}
|
||||
|
||||
# One possible value for a given Enum. Enum values are unique values, not a
|
||||
# placeholder for a string or numeric value. However an Enum value is returned in
|
||||
# a JSON response as a string.
|
||||
type __EnumValue {
|
||||
name: String!
|
||||
description: String
|
||||
isDeprecated: Boolean!
|
||||
deprecationReason: String
|
||||
}
|
||||
|
||||
# Object and Interface types are described by a list of Fields, each of which has
|
||||
# a name, potentially a list of arguments, and a return type.
|
||||
type __Field {
|
||||
name: String!
|
||||
description: String
|
||||
args: [__InputValue!]!
|
||||
type: __Type!
|
||||
isDeprecated: Boolean!
|
||||
deprecationReason: String
|
||||
}
|
||||
|
||||
# Arguments provided to Fields or Directives and the input fields of an
|
||||
# InputObject are represented as Input Values which describe their type and
|
||||
# optionally a default value.
|
||||
type __InputValue {
|
||||
name: String!
|
||||
description: String
|
||||
type: __Type!
|
||||
# A GraphQL-formatted string representing the default value for this input value.
|
||||
defaultValue: String
|
||||
}
|
||||
|
||||
# A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all
|
||||
# available types and directives on the server, as well as the entry points for
|
||||
# query, mutation, and subscription operations.
|
||||
type __Schema {
|
||||
# A list of all types supported by this server.
|
||||
types: [__Type!]!
|
||||
# The type that query operations will be rooted at.
|
||||
queryType: __Type!
|
||||
# If this server supports mutation, the type that mutation operations will be rooted at.
|
||||
mutationType: __Type
|
||||
# If this server support subscription, the type that subscription operations will be rooted at.
|
||||
subscriptionType: __Type
|
||||
# A list of all directives supported by this server.
|
||||
directives: [__Directive!]!
|
||||
}
|
||||
|
||||
# The fundamental unit of any GraphQL Schema is the type. There are many kinds of
|
||||
# types in GraphQL as represented by the ` + "`" + `__TypeKind` + "`" + ` enum.
|
||||
#
|
||||
# Depending on the kind of a type, certain fields describe information about that
|
||||
# type. Scalar types provide no information beyond a name and description, while
|
||||
# Enum types provide their values. Object and Interface types provide the fields
|
||||
# they describe. Abstract types, Union and Interface, provide the Object types
|
||||
# possible at runtime. List and NonNull types compose other types.
|
||||
type __Type {
|
||||
kind: __TypeKind!
|
||||
name: String
|
||||
description: String
|
||||
fields(includeDeprecated: Boolean = false): [__Field!]
|
||||
interfaces: [__Type!]
|
||||
possibleTypes: [__Type!]
|
||||
enumValues(includeDeprecated: Boolean = false): [__EnumValue!]
|
||||
inputFields: [__InputValue!]
|
||||
ofType: __Type
|
||||
}
|
||||
|
||||
# An enum describing what kind of type a given ` + "`" + `__Type` + "`" + ` is.
|
||||
enum __TypeKind {
|
||||
# Indicates this type is a scalar.
|
||||
SCALAR
|
||||
# Indicates this type is an object. ` + "`" + `fields` + "`" + ` and ` + "`" + `interfaces` + "`" + ` are valid fields.
|
||||
OBJECT
|
||||
# Indicates this type is an interface. ` + "`" + `fields` + "`" + ` and ` + "`" + `possibleTypes` + "`" + ` are valid fields.
|
||||
INTERFACE
|
||||
# Indicates this type is a union. ` + "`" + `possibleTypes` + "`" + ` is a valid field.
|
||||
UNION
|
||||
# Indicates this type is an enum. ` + "`" + `enumValues` + "`" + ` is a valid field.
|
||||
ENUM
|
||||
# Indicates this type is an input object. ` + "`" + `inputFields` + "`" + ` is a valid field.
|
||||
INPUT_OBJECT
|
||||
# Indicates this type is a list. ` + "`" + `ofType` + "`" + ` is a valid field.
|
||||
LIST
|
||||
# Indicates this type is a non-null. ` + "`" + `ofType` + "`" + ` is a valid field.
|
||||
NON_NULL
|
||||
}
|
||||
`
|
586
vendor/github.com/graph-gophers/graphql-go/internal/schema/schema.go
generated
vendored
Normal file
586
vendor/github.com/graph-gophers/graphql-go/internal/schema/schema.go
generated
vendored
Normal file
@ -0,0 +1,586 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"text/scanner"
|
||||
|
||||
"github.com/graph-gophers/graphql-go/errors"
|
||||
"github.com/graph-gophers/graphql-go/internal/common"
|
||||
"github.com/graph-gophers/graphql-go/types"
|
||||
)
|
||||
|
||||
// New initializes an instance of Schema.
|
||||
func New() *types.Schema {
|
||||
s := &types.Schema{
|
||||
EntryPointNames: make(map[string]string),
|
||||
Types: make(map[string]types.NamedType),
|
||||
Directives: make(map[string]*types.DirectiveDefinition),
|
||||
}
|
||||
m := newMeta()
|
||||
for n, t := range m.Types {
|
||||
s.Types[n] = t
|
||||
}
|
||||
for n, d := range m.Directives {
|
||||
s.Directives[n] = d
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func Parse(s *types.Schema, schemaString string, useStringDescriptions bool) error {
|
||||
l := common.NewLexer(schemaString, useStringDescriptions)
|
||||
err := l.CatchSyntaxError(func() { parseSchema(s, l) })
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := mergeExtensions(s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, t := range s.Types {
|
||||
if err := resolveNamedType(s, t); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, d := range s.Directives {
|
||||
for _, arg := range d.Arguments {
|
||||
t, err := common.ResolveType(arg.Type, s.Resolve)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
arg.Type = t
|
||||
}
|
||||
}
|
||||
|
||||
// https://graphql.github.io/graphql-spec/June2018/#sec-Root-Operation-Types
|
||||
// > While any type can be the root operation type for a GraphQL operation, the type system definition language can
|
||||
// > omit the schema definition when the query, mutation, and subscription root types are named Query, Mutation,
|
||||
// > and Subscription respectively.
|
||||
if len(s.EntryPointNames) == 0 {
|
||||
if _, ok := s.Types["Query"]; ok {
|
||||
s.EntryPointNames["query"] = "Query"
|
||||
}
|
||||
if _, ok := s.Types["Mutation"]; ok {
|
||||
s.EntryPointNames["mutation"] = "Mutation"
|
||||
}
|
||||
if _, ok := s.Types["Subscription"]; ok {
|
||||
s.EntryPointNames["subscription"] = "Subscription"
|
||||
}
|
||||
}
|
||||
s.EntryPoints = make(map[string]types.NamedType)
|
||||
for key, name := range s.EntryPointNames {
|
||||
t, ok := s.Types[name]
|
||||
if !ok {
|
||||
return errors.Errorf("type %q not found", name)
|
||||
}
|
||||
s.EntryPoints[key] = t
|
||||
}
|
||||
|
||||
// Interface types need validation: https://spec.graphql.org/draft/#sec-Interfaces.Interfaces-Implementing-Interfaces
|
||||
for _, typeDef := range s.Types {
|
||||
switch t := typeDef.(type) {
|
||||
case *types.InterfaceTypeDefinition:
|
||||
for i, implements := range t.Interfaces {
|
||||
typ, ok := s.Types[implements.Name]
|
||||
if !ok {
|
||||
return errors.Errorf("interface %q not found", implements)
|
||||
}
|
||||
inteface, ok := typ.(*types.InterfaceTypeDefinition)
|
||||
if !ok {
|
||||
return errors.Errorf("type %q is not an interface", inteface)
|
||||
}
|
||||
|
||||
for _, f := range inteface.Fields.Names() {
|
||||
if t.Fields.Get(f) == nil {
|
||||
return errors.Errorf("interface %q expects field %q but %q does not provide it", inteface.Name, f, t.Name)
|
||||
}
|
||||
}
|
||||
|
||||
t.Interfaces[i] = inteface
|
||||
}
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
for _, obj := range s.Objects {
|
||||
obj.Interfaces = make([]*types.InterfaceTypeDefinition, len(obj.InterfaceNames))
|
||||
if err := resolveDirectives(s, obj.Directives, "OBJECT"); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, field := range obj.Fields {
|
||||
if err := resolveDirectives(s, field.Directives, "FIELD_DEFINITION"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for i, intfName := range obj.InterfaceNames {
|
||||
t, ok := s.Types[intfName]
|
||||
if !ok {
|
||||
return errors.Errorf("interface %q not found", intfName)
|
||||
}
|
||||
intf, ok := t.(*types.InterfaceTypeDefinition)
|
||||
if !ok {
|
||||
return errors.Errorf("type %q is not an interface", intfName)
|
||||
}
|
||||
for _, f := range intf.Fields.Names() {
|
||||
if obj.Fields.Get(f) == nil {
|
||||
return errors.Errorf("interface %q expects field %q but %q does not provide it", intfName, f, obj.Name)
|
||||
}
|
||||
}
|
||||
obj.Interfaces[i] = intf
|
||||
intf.PossibleTypes = append(intf.PossibleTypes, obj)
|
||||
}
|
||||
}
|
||||
|
||||
for _, union := range s.Unions {
|
||||
if err := resolveDirectives(s, union.Directives, "UNION"); err != nil {
|
||||
return err
|
||||
}
|
||||
union.UnionMemberTypes = make([]*types.ObjectTypeDefinition, len(union.TypeNames))
|
||||
for i, name := range union.TypeNames {
|
||||
t, ok := s.Types[name]
|
||||
if !ok {
|
||||
return errors.Errorf("object type %q not found", name)
|
||||
}
|
||||
obj, ok := t.(*types.ObjectTypeDefinition)
|
||||
if !ok {
|
||||
return errors.Errorf("type %q is not an object", name)
|
||||
}
|
||||
union.UnionMemberTypes[i] = obj
|
||||
}
|
||||
}
|
||||
|
||||
for _, enum := range s.Enums {
|
||||
if err := resolveDirectives(s, enum.Directives, "ENUM"); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, value := range enum.EnumValuesDefinition {
|
||||
if err := resolveDirectives(s, value.Directives, "ENUM_VALUE"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ParseSchema(schemaString string, useStringDescriptions bool) (*types.Schema, error) {
|
||||
s := New()
|
||||
err := Parse(s, schemaString, useStringDescriptions)
|
||||
return s, err
|
||||
}
|
||||
|
||||
func mergeExtensions(s *types.Schema) error {
|
||||
for _, ext := range s.Extensions {
|
||||
typ := s.Types[ext.Type.TypeName()]
|
||||
if typ == nil {
|
||||
return fmt.Errorf("trying to extend unknown type %q", ext.Type.TypeName())
|
||||
}
|
||||
|
||||
if typ.Kind() != ext.Type.Kind() {
|
||||
return fmt.Errorf("trying to extend type %q with type %q", typ.Kind(), ext.Type.Kind())
|
||||
}
|
||||
|
||||
switch og := typ.(type) {
|
||||
case *types.ObjectTypeDefinition:
|
||||
e := ext.Type.(*types.ObjectTypeDefinition)
|
||||
|
||||
for _, field := range e.Fields {
|
||||
if og.Fields.Get(field.Name) != nil {
|
||||
return fmt.Errorf("extended field %q already exists", field.Name)
|
||||
}
|
||||
}
|
||||
og.Fields = append(og.Fields, e.Fields...)
|
||||
|
||||
for _, en := range e.InterfaceNames {
|
||||
for _, on := range og.InterfaceNames {
|
||||
if on == en {
|
||||
return fmt.Errorf("interface %q implemented in the extension is already implemented in %q", on, og.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
og.InterfaceNames = append(og.InterfaceNames, e.InterfaceNames...)
|
||||
|
||||
case *types.InputObject:
|
||||
e := ext.Type.(*types.InputObject)
|
||||
|
||||
for _, field := range e.Values {
|
||||
if og.Values.Get(field.Name.Name) != nil {
|
||||
return fmt.Errorf("extended field %q already exists", field.Name)
|
||||
}
|
||||
}
|
||||
og.Values = append(og.Values, e.Values...)
|
||||
|
||||
case *types.InterfaceTypeDefinition:
|
||||
e := ext.Type.(*types.InterfaceTypeDefinition)
|
||||
|
||||
for _, field := range e.Fields {
|
||||
if og.Fields.Get(field.Name) != nil {
|
||||
return fmt.Errorf("extended field %s already exists", field.Name)
|
||||
}
|
||||
}
|
||||
og.Fields = append(og.Fields, e.Fields...)
|
||||
|
||||
case *types.Union:
|
||||
e := ext.Type.(*types.Union)
|
||||
|
||||
for _, en := range e.TypeNames {
|
||||
for _, on := range og.TypeNames {
|
||||
if on == en {
|
||||
return fmt.Errorf("union type %q already declared in %q", on, og.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
og.TypeNames = append(og.TypeNames, e.TypeNames...)
|
||||
|
||||
case *types.EnumTypeDefinition:
|
||||
e := ext.Type.(*types.EnumTypeDefinition)
|
||||
|
||||
for _, en := range e.EnumValuesDefinition {
|
||||
for _, on := range og.EnumValuesDefinition {
|
||||
if on.EnumValue == en.EnumValue {
|
||||
return fmt.Errorf("enum value %q already declared in %q", on.EnumValue, og.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
og.EnumValuesDefinition = append(og.EnumValuesDefinition, e.EnumValuesDefinition...)
|
||||
default:
|
||||
return fmt.Errorf(`unexpected %q, expecting "schema", "type", "enum", "interface", "union" or "input"`, og.TypeName())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resolveNamedType(s *types.Schema, t types.NamedType) error {
|
||||
switch t := t.(type) {
|
||||
case *types.ObjectTypeDefinition:
|
||||
for _, f := range t.Fields {
|
||||
if err := resolveField(s, f); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case *types.InterfaceTypeDefinition:
|
||||
for _, f := range t.Fields {
|
||||
if err := resolveField(s, f); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case *types.InputObject:
|
||||
if err := resolveInputObject(s, t.Values); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func resolveField(s *types.Schema, f *types.FieldDefinition) error {
|
||||
t, err := common.ResolveType(f.Type, s.Resolve)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.Type = t
|
||||
if err := resolveDirectives(s, f.Directives, "FIELD_DEFINITION"); err != nil {
|
||||
return err
|
||||
}
|
||||
return resolveInputObject(s, f.Arguments)
|
||||
}
|
||||
|
||||
func resolveDirectives(s *types.Schema, directives types.DirectiveList, loc string) error {
|
||||
for _, d := range directives {
|
||||
dirName := d.Name.Name
|
||||
dd, ok := s.Directives[dirName]
|
||||
if !ok {
|
||||
return errors.Errorf("directive %q not found", dirName)
|
||||
}
|
||||
validLoc := false
|
||||
for _, l := range dd.Locations {
|
||||
if l == loc {
|
||||
validLoc = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !validLoc {
|
||||
return errors.Errorf("invalid location %q for directive %q (must be one of %v)", loc, dirName, dd.Locations)
|
||||
}
|
||||
for _, arg := range d.Arguments {
|
||||
if dd.Arguments.Get(arg.Name.Name) == nil {
|
||||
return errors.Errorf("invalid argument %q for directive %q", arg.Name.Name, dirName)
|
||||
}
|
||||
}
|
||||
for _, arg := range dd.Arguments {
|
||||
if _, ok := d.Arguments.Get(arg.Name.Name); !ok {
|
||||
d.Arguments = append(d.Arguments, &types.Argument{Name: arg.Name, Value: arg.Default})
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func resolveInputObject(s *types.Schema, values types.ArgumentsDefinition) error {
|
||||
for _, v := range values {
|
||||
t, err := common.ResolveType(v.Type, s.Resolve)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.Type = t
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseSchema(s *types.Schema, l *common.Lexer) {
|
||||
l.ConsumeWhitespace()
|
||||
|
||||
for l.Peek() != scanner.EOF {
|
||||
desc := l.DescComment()
|
||||
switch x := l.ConsumeIdent(); x {
|
||||
|
||||
case "schema":
|
||||
l.ConsumeToken('{')
|
||||
for l.Peek() != '}' {
|
||||
|
||||
name := l.ConsumeIdent()
|
||||
l.ConsumeToken(':')
|
||||
typ := l.ConsumeIdent()
|
||||
s.EntryPointNames[name] = typ
|
||||
}
|
||||
l.ConsumeToken('}')
|
||||
|
||||
case "type":
|
||||
obj := parseObjectDef(l)
|
||||
obj.Desc = desc
|
||||
s.Types[obj.Name] = obj
|
||||
s.Objects = append(s.Objects, obj)
|
||||
|
||||
case "interface":
|
||||
iface := parseInterfaceDef(l)
|
||||
iface.Desc = desc
|
||||
s.Types[iface.Name] = iface
|
||||
|
||||
case "union":
|
||||
union := parseUnionDef(l)
|
||||
union.Desc = desc
|
||||
s.Types[union.Name] = union
|
||||
s.Unions = append(s.Unions, union)
|
||||
|
||||
case "enum":
|
||||
enum := parseEnumDef(l)
|
||||
enum.Desc = desc
|
||||
s.Types[enum.Name] = enum
|
||||
s.Enums = append(s.Enums, enum)
|
||||
|
||||
case "input":
|
||||
input := parseInputDef(l)
|
||||
input.Desc = desc
|
||||
s.Types[input.Name] = input
|
||||
|
||||
case "scalar":
|
||||
loc := l.Location()
|
||||
name := l.ConsumeIdent()
|
||||
directives := common.ParseDirectives(l)
|
||||
s.Types[name] = &types.ScalarTypeDefinition{Name: name, Desc: desc, Directives: directives, Loc: loc}
|
||||
|
||||
case "directive":
|
||||
directive := parseDirectiveDef(l)
|
||||
directive.Desc = desc
|
||||
s.Directives[directive.Name] = directive
|
||||
|
||||
case "extend":
|
||||
parseExtension(s, l)
|
||||
|
||||
default:
|
||||
// TODO: Add support for type extensions.
|
||||
l.SyntaxError(fmt.Sprintf(`unexpected %q, expecting "schema", "type", "enum", "interface", "union", "input", "scalar" or "directive"`, x))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func parseObjectDef(l *common.Lexer) *types.ObjectTypeDefinition {
|
||||
object := &types.ObjectTypeDefinition{Loc: l.Location(), Name: l.ConsumeIdent()}
|
||||
|
||||
for {
|
||||
if l.Peek() == '{' {
|
||||
break
|
||||
}
|
||||
|
||||
if l.Peek() == '@' {
|
||||
object.Directives = common.ParseDirectives(l)
|
||||
continue
|
||||
}
|
||||
|
||||
if l.Peek() == scanner.Ident {
|
||||
l.ConsumeKeyword("implements")
|
||||
|
||||
for l.Peek() != '{' && l.Peek() != '@' {
|
||||
if l.Peek() == '&' {
|
||||
l.ConsumeToken('&')
|
||||
}
|
||||
|
||||
object.InterfaceNames = append(object.InterfaceNames, l.ConsumeIdent())
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
}
|
||||
l.ConsumeToken('{')
|
||||
object.Fields = parseFieldsDef(l)
|
||||
l.ConsumeToken('}')
|
||||
|
||||
return object
|
||||
|
||||
}
|
||||
|
||||
func parseInterfaceDef(l *common.Lexer) *types.InterfaceTypeDefinition {
|
||||
i := &types.InterfaceTypeDefinition{Loc: l.Location(), Name: l.ConsumeIdent()}
|
||||
|
||||
if l.Peek() == scanner.Ident {
|
||||
l.ConsumeKeyword("implements")
|
||||
i.Interfaces = append(i.Interfaces, &types.InterfaceTypeDefinition{Name: l.ConsumeIdent()})
|
||||
|
||||
for l.Peek() == '&' {
|
||||
l.ConsumeToken('&')
|
||||
i.Interfaces = append(i.Interfaces, &types.InterfaceTypeDefinition{Name: l.ConsumeIdent()})
|
||||
}
|
||||
}
|
||||
|
||||
i.Directives = common.ParseDirectives(l)
|
||||
|
||||
l.ConsumeToken('{')
|
||||
i.Fields = parseFieldsDef(l)
|
||||
l.ConsumeToken('}')
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
func parseUnionDef(l *common.Lexer) *types.Union {
|
||||
union := &types.Union{Loc: l.Location(), Name: l.ConsumeIdent()}
|
||||
|
||||
union.Directives = common.ParseDirectives(l)
|
||||
l.ConsumeToken('=')
|
||||
union.TypeNames = []string{l.ConsumeIdent()}
|
||||
for l.Peek() == '|' {
|
||||
l.ConsumeToken('|')
|
||||
union.TypeNames = append(union.TypeNames, l.ConsumeIdent())
|
||||
}
|
||||
|
||||
return union
|
||||
}
|
||||
|
||||
func parseInputDef(l *common.Lexer) *types.InputObject {
|
||||
i := &types.InputObject{}
|
||||
i.Loc = l.Location()
|
||||
i.Name = l.ConsumeIdent()
|
||||
i.Directives = common.ParseDirectives(l)
|
||||
l.ConsumeToken('{')
|
||||
for l.Peek() != '}' {
|
||||
i.Values = append(i.Values, common.ParseInputValue(l))
|
||||
}
|
||||
l.ConsumeToken('}')
|
||||
return i
|
||||
}
|
||||
|
||||
func parseEnumDef(l *common.Lexer) *types.EnumTypeDefinition {
|
||||
enum := &types.EnumTypeDefinition{Loc: l.Location(), Name: l.ConsumeIdent()}
|
||||
|
||||
enum.Directives = common.ParseDirectives(l)
|
||||
l.ConsumeToken('{')
|
||||
for l.Peek() != '}' {
|
||||
v := &types.EnumValueDefinition{
|
||||
Desc: l.DescComment(),
|
||||
Loc: l.Location(),
|
||||
EnumValue: l.ConsumeIdent(),
|
||||
Directives: common.ParseDirectives(l),
|
||||
}
|
||||
|
||||
enum.EnumValuesDefinition = append(enum.EnumValuesDefinition, v)
|
||||
}
|
||||
l.ConsumeToken('}')
|
||||
return enum
|
||||
}
|
||||
func parseDirectiveDef(l *common.Lexer) *types.DirectiveDefinition {
|
||||
l.ConsumeToken('@')
|
||||
loc := l.Location()
|
||||
d := &types.DirectiveDefinition{Name: l.ConsumeIdent(), Loc: loc}
|
||||
|
||||
if l.Peek() == '(' {
|
||||
l.ConsumeToken('(')
|
||||
for l.Peek() != ')' {
|
||||
v := common.ParseInputValue(l)
|
||||
d.Arguments = append(d.Arguments, v)
|
||||
}
|
||||
l.ConsumeToken(')')
|
||||
}
|
||||
|
||||
l.ConsumeKeyword("on")
|
||||
|
||||
for {
|
||||
loc := l.ConsumeIdent()
|
||||
d.Locations = append(d.Locations, loc)
|
||||
if l.Peek() != '|' {
|
||||
break
|
||||
}
|
||||
l.ConsumeToken('|')
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
func parseExtension(s *types.Schema, l *common.Lexer) {
|
||||
loc := l.Location()
|
||||
switch x := l.ConsumeIdent(); x {
|
||||
case "schema":
|
||||
l.ConsumeToken('{')
|
||||
for l.Peek() != '}' {
|
||||
name := l.ConsumeIdent()
|
||||
l.ConsumeToken(':')
|
||||
typ := l.ConsumeIdent()
|
||||
s.EntryPointNames[name] = typ
|
||||
}
|
||||
l.ConsumeToken('}')
|
||||
|
||||
case "type":
|
||||
obj := parseObjectDef(l)
|
||||
s.Extensions = append(s.Extensions, &types.Extension{Type: obj, Loc: loc})
|
||||
|
||||
case "interface":
|
||||
iface := parseInterfaceDef(l)
|
||||
s.Extensions = append(s.Extensions, &types.Extension{Type: iface, Loc: loc})
|
||||
|
||||
case "union":
|
||||
union := parseUnionDef(l)
|
||||
s.Extensions = append(s.Extensions, &types.Extension{Type: union, Loc: loc})
|
||||
|
||||
case "enum":
|
||||
enum := parseEnumDef(l)
|
||||
s.Extensions = append(s.Extensions, &types.Extension{Type: enum, Loc: loc})
|
||||
|
||||
case "input":
|
||||
input := parseInputDef(l)
|
||||
s.Extensions = append(s.Extensions, &types.Extension{Type: input, Loc: loc})
|
||||
|
||||
default:
|
||||
// TODO: Add ScalarTypeDefinition when adding directives
|
||||
l.SyntaxError(fmt.Sprintf(`unexpected %q, expecting "schema", "type", "enum", "interface", "union" or "input"`, x))
|
||||
}
|
||||
}
|
||||
|
||||
func parseFieldsDef(l *common.Lexer) types.FieldsDefinition {
|
||||
var fields types.FieldsDefinition
|
||||
for l.Peek() != '}' {
|
||||
f := &types.FieldDefinition{}
|
||||
f.Desc = l.DescComment()
|
||||
f.Loc = l.Location()
|
||||
f.Name = l.ConsumeIdent()
|
||||
if l.Peek() == '(' {
|
||||
l.ConsumeToken('(')
|
||||
for l.Peek() != ')' {
|
||||
f.Arguments = append(f.Arguments, common.ParseInputValue(l))
|
||||
}
|
||||
l.ConsumeToken(')')
|
||||
}
|
||||
l.ConsumeToken(':')
|
||||
f.Type = common.ParseType(l)
|
||||
f.Directives = common.ParseDirectives(l)
|
||||
fields = append(fields, f)
|
||||
}
|
||||
return fields
|
||||
}
|
71
vendor/github.com/graph-gophers/graphql-go/internal/validation/suggestion.go
generated
vendored
Normal file
71
vendor/github.com/graph-gophers/graphql-go/internal/validation/suggestion.go
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func makeSuggestion(prefix string, options []string, input string) string {
|
||||
var selected []string
|
||||
distances := make(map[string]int)
|
||||
for _, opt := range options {
|
||||
distance := levenshteinDistance(input, opt)
|
||||
threshold := max(len(input)/2, max(len(opt)/2, 1))
|
||||
if distance < threshold {
|
||||
selected = append(selected, opt)
|
||||
distances[opt] = distance
|
||||
}
|
||||
}
|
||||
|
||||
if len(selected) == 0 {
|
||||
return ""
|
||||
}
|
||||
sort.Slice(selected, func(i, j int) bool {
|
||||
return distances[selected[i]] < distances[selected[j]]
|
||||
})
|
||||
|
||||
parts := make([]string, len(selected))
|
||||
for i, opt := range selected {
|
||||
parts[i] = strconv.Quote(opt)
|
||||
}
|
||||
if len(parts) > 1 {
|
||||
parts[len(parts)-1] = "or " + parts[len(parts)-1]
|
||||
}
|
||||
return fmt.Sprintf(" %s %s?", prefix, strings.Join(parts, ", "))
|
||||
}
|
||||
|
||||
func levenshteinDistance(s1, s2 string) int {
|
||||
column := make([]int, len(s1)+1)
|
||||
for y := range s1 {
|
||||
column[y+1] = y + 1
|
||||
}
|
||||
for x, rx := range s2 {
|
||||
column[0] = x + 1
|
||||
lastdiag := x
|
||||
for y, ry := range s1 {
|
||||
olddiag := column[y+1]
|
||||
if rx != ry {
|
||||
lastdiag++
|
||||
}
|
||||
column[y+1] = min(column[y+1]+1, min(column[y]+1, lastdiag))
|
||||
lastdiag = olddiag
|
||||
}
|
||||
}
|
||||
return column[len(s1)]
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
980
vendor/github.com/graph-gophers/graphql-go/internal/validation/validation.go
generated
vendored
Normal file
980
vendor/github.com/graph-gophers/graphql-go/internal/validation/validation.go
generated
vendored
Normal file
@ -0,0 +1,980 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/scanner"
|
||||
|
||||
"github.com/graph-gophers/graphql-go/errors"
|
||||
"github.com/graph-gophers/graphql-go/internal/common"
|
||||
"github.com/graph-gophers/graphql-go/internal/query"
|
||||
"github.com/graph-gophers/graphql-go/types"
|
||||
)
|
||||
|
||||
type varSet map[*types.InputValueDefinition]struct{}
|
||||
|
||||
type selectionPair struct{ a, b types.Selection }
|
||||
|
||||
type nameSet map[string]errors.Location
|
||||
|
||||
type fieldInfo struct {
|
||||
sf *types.FieldDefinition
|
||||
parent types.NamedType
|
||||
}
|
||||
|
||||
type context struct {
|
||||
schema *types.Schema
|
||||
doc *types.ExecutableDefinition
|
||||
errs []*errors.QueryError
|
||||
opErrs map[*types.OperationDefinition][]*errors.QueryError
|
||||
usedVars map[*types.OperationDefinition]varSet
|
||||
fieldMap map[*types.Field]fieldInfo
|
||||
overlapValidated map[selectionPair]struct{}
|
||||
maxDepth int
|
||||
}
|
||||
|
||||
func (c *context) addErr(loc errors.Location, rule string, format string, a ...interface{}) {
|
||||
c.addErrMultiLoc([]errors.Location{loc}, rule, format, a...)
|
||||
}
|
||||
|
||||
func (c *context) addErrMultiLoc(locs []errors.Location, rule string, format string, a ...interface{}) {
|
||||
c.errs = append(c.errs, &errors.QueryError{
|
||||
Message: fmt.Sprintf(format, a...),
|
||||
Locations: locs,
|
||||
Rule: rule,
|
||||
})
|
||||
}
|
||||
|
||||
type opContext struct {
|
||||
*context
|
||||
ops []*types.OperationDefinition
|
||||
}
|
||||
|
||||
func newContext(s *types.Schema, doc *types.ExecutableDefinition, maxDepth int) *context {
|
||||
return &context{
|
||||
schema: s,
|
||||
doc: doc,
|
||||
opErrs: make(map[*types.OperationDefinition][]*errors.QueryError),
|
||||
usedVars: make(map[*types.OperationDefinition]varSet),
|
||||
fieldMap: make(map[*types.Field]fieldInfo),
|
||||
overlapValidated: make(map[selectionPair]struct{}),
|
||||
maxDepth: maxDepth,
|
||||
}
|
||||
}
|
||||
|
||||
func Validate(s *types.Schema, doc *types.ExecutableDefinition, variables map[string]interface{}, maxDepth int) []*errors.QueryError {
|
||||
c := newContext(s, doc, maxDepth)
|
||||
|
||||
opNames := make(nameSet)
|
||||
fragUsedBy := make(map[*types.FragmentDefinition][]*types.OperationDefinition)
|
||||
for _, op := range doc.Operations {
|
||||
c.usedVars[op] = make(varSet)
|
||||
opc := &opContext{c, []*types.OperationDefinition{op}}
|
||||
|
||||
// Check if max depth is exceeded, if it's set. If max depth is exceeded,
|
||||
// don't continue to validate the document and exit early.
|
||||
if validateMaxDepth(opc, op.Selections, nil, 1) {
|
||||
return c.errs
|
||||
}
|
||||
|
||||
if op.Name.Name == "" && len(doc.Operations) != 1 {
|
||||
c.addErr(op.Loc, "LoneAnonymousOperation", "This anonymous operation must be the only defined operation.")
|
||||
}
|
||||
if op.Name.Name != "" {
|
||||
validateName(c, opNames, op.Name, "UniqueOperationNames", "operation")
|
||||
}
|
||||
|
||||
validateDirectives(opc, string(op.Type), op.Directives)
|
||||
|
||||
varNames := make(nameSet)
|
||||
for _, v := range op.Vars {
|
||||
validateName(c, varNames, v.Name, "UniqueVariableNames", "variable")
|
||||
|
||||
t := resolveType(c, v.Type)
|
||||
if !canBeInput(t) {
|
||||
c.addErr(v.TypeLoc, "VariablesAreInputTypes", "Variable %q cannot be non-input type %q.", "$"+v.Name.Name, t)
|
||||
}
|
||||
validateValue(opc, v, variables[v.Name.Name], t)
|
||||
|
||||
if v.Default != nil {
|
||||
validateLiteral(opc, v.Default)
|
||||
|
||||
if t != nil {
|
||||
if nn, ok := t.(*types.NonNull); ok {
|
||||
c.addErr(v.Default.Location(), "DefaultValuesOfCorrectType", "Variable %q of type %q is required and will not use the default value. Perhaps you meant to use type %q.", "$"+v.Name.Name, t, nn.OfType)
|
||||
}
|
||||
|
||||
if ok, reason := validateValueType(opc, v.Default, t); !ok {
|
||||
c.addErr(v.Default.Location(), "DefaultValuesOfCorrectType", "Variable %q of type %q has invalid default value %s.\n%s", "$"+v.Name.Name, t, v.Default, reason)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var entryPoint types.NamedType
|
||||
switch op.Type {
|
||||
case query.Query:
|
||||
entryPoint = s.EntryPoints["query"]
|
||||
case query.Mutation:
|
||||
entryPoint = s.EntryPoints["mutation"]
|
||||
case query.Subscription:
|
||||
entryPoint = s.EntryPoints["subscription"]
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
validateSelectionSet(opc, op.Selections, entryPoint)
|
||||
|
||||
fragUsed := make(map[*types.FragmentDefinition]struct{})
|
||||
markUsedFragments(c, op.Selections, fragUsed)
|
||||
for frag := range fragUsed {
|
||||
fragUsedBy[frag] = append(fragUsedBy[frag], op)
|
||||
}
|
||||
}
|
||||
|
||||
fragNames := make(nameSet)
|
||||
fragVisited := make(map[*types.FragmentDefinition]struct{})
|
||||
for _, frag := range doc.Fragments {
|
||||
opc := &opContext{c, fragUsedBy[frag]}
|
||||
|
||||
validateName(c, fragNames, frag.Name, "UniqueFragmentNames", "fragment")
|
||||
validateDirectives(opc, "FRAGMENT_DEFINITION", frag.Directives)
|
||||
|
||||
t := unwrapType(resolveType(c, &frag.On))
|
||||
// continue even if t is nil
|
||||
if t != nil && !canBeFragment(t) {
|
||||
c.addErr(frag.On.Loc, "FragmentsOnCompositeTypes", "Fragment %q cannot condition on non composite type %q.", frag.Name.Name, t)
|
||||
continue
|
||||
}
|
||||
|
||||
validateSelectionSet(opc, frag.Selections, t)
|
||||
|
||||
if _, ok := fragVisited[frag]; !ok {
|
||||
detectFragmentCycle(c, frag.Selections, fragVisited, nil, map[string]int{frag.Name.Name: 0})
|
||||
}
|
||||
}
|
||||
|
||||
for _, frag := range doc.Fragments {
|
||||
if len(fragUsedBy[frag]) == 0 {
|
||||
c.addErr(frag.Loc, "NoUnusedFragments", "Fragment %q is never used.", frag.Name.Name)
|
||||
}
|
||||
}
|
||||
|
||||
for _, op := range doc.Operations {
|
||||
c.errs = append(c.errs, c.opErrs[op]...)
|
||||
|
||||
opUsedVars := c.usedVars[op]
|
||||
for _, v := range op.Vars {
|
||||
if _, ok := opUsedVars[v]; !ok {
|
||||
opSuffix := ""
|
||||
if op.Name.Name != "" {
|
||||
opSuffix = fmt.Sprintf(" in operation %q", op.Name.Name)
|
||||
}
|
||||
c.addErr(v.Loc, "NoUnusedVariables", "Variable %q is never used%s.", "$"+v.Name.Name, opSuffix)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return c.errs
|
||||
}
|
||||
|
||||
func validateValue(c *opContext, v *types.InputValueDefinition, val interface{}, t types.Type) {
|
||||
switch t := t.(type) {
|
||||
case *types.NonNull:
|
||||
if val == nil {
|
||||
c.addErr(v.Loc, "VariablesOfCorrectType", "Variable \"%s\" has invalid value null.\nExpected type \"%s\", found null.", v.Name.Name, t)
|
||||
return
|
||||
}
|
||||
validateValue(c, v, val, t.OfType)
|
||||
case *types.List:
|
||||
if val == nil {
|
||||
return
|
||||
}
|
||||
vv, ok := val.([]interface{})
|
||||
if !ok {
|
||||
// Input coercion rules allow single items without wrapping array
|
||||
validateValue(c, v, val, t.OfType)
|
||||
return
|
||||
}
|
||||
for _, elem := range vv {
|
||||
validateValue(c, v, elem, t.OfType)
|
||||
}
|
||||
case *types.EnumTypeDefinition:
|
||||
if val == nil {
|
||||
return
|
||||
}
|
||||
e, ok := val.(string)
|
||||
if !ok {
|
||||
c.addErr(v.Loc, "VariablesOfCorrectType", "Variable \"%s\" has invalid type %T.\nExpected type \"%s\", found %v.", v.Name.Name, val, t, val)
|
||||
return
|
||||
}
|
||||
for _, option := range t.EnumValuesDefinition {
|
||||
if option.EnumValue == e {
|
||||
return
|
||||
}
|
||||
}
|
||||
c.addErr(v.Loc, "VariablesOfCorrectType", "Variable \"%s\" has invalid value %s.\nExpected type \"%s\", found %s.", v.Name.Name, e, t, e)
|
||||
case *types.InputObject:
|
||||
if val == nil {
|
||||
return
|
||||
}
|
||||
in, ok := val.(map[string]interface{})
|
||||
if !ok {
|
||||
c.addErr(v.Loc, "VariablesOfCorrectType", "Variable \"%s\" has invalid type %T.\nExpected type \"%s\", found %s.", v.Name.Name, val, t, val)
|
||||
return
|
||||
}
|
||||
for _, f := range t.Values {
|
||||
fieldVal := in[f.Name.Name]
|
||||
validateValue(c, f, fieldVal, f.Type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// validates the query doesn't go deeper than maxDepth (if set). Returns whether
|
||||
// or not query validated max depth to avoid excessive recursion.
|
||||
//
|
||||
// The visited map is necessary to ensure that max depth validation does not get stuck in cyclical
|
||||
// fragment spreads.
|
||||
func validateMaxDepth(c *opContext, sels []types.Selection, visited map[*types.FragmentDefinition]struct{}, depth int) bool {
|
||||
// maxDepth checking is turned off when maxDepth is 0
|
||||
if c.maxDepth == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
exceededMaxDepth := false
|
||||
if visited == nil {
|
||||
visited = map[*types.FragmentDefinition]struct{}{}
|
||||
}
|
||||
|
||||
for _, sel := range sels {
|
||||
switch sel := sel.(type) {
|
||||
case *types.Field:
|
||||
if depth > c.maxDepth {
|
||||
exceededMaxDepth = true
|
||||
c.addErr(sel.Alias.Loc, "MaxDepthExceeded", "Field %q has depth %d that exceeds max depth %d", sel.Name.Name, depth, c.maxDepth)
|
||||
continue
|
||||
}
|
||||
exceededMaxDepth = exceededMaxDepth || validateMaxDepth(c, sel.SelectionSet, visited, depth+1)
|
||||
|
||||
case *types.InlineFragment:
|
||||
// Depth is not checked because inline fragments resolve to other fields which are checked.
|
||||
// Depth is not incremented because inline fragments have the same depth as neighboring fields
|
||||
exceededMaxDepth = exceededMaxDepth || validateMaxDepth(c, sel.Selections, visited, depth)
|
||||
case *types.FragmentSpread:
|
||||
// Depth is not checked because fragments resolve to other fields which are checked.
|
||||
frag := c.doc.Fragments.Get(sel.Name.Name)
|
||||
if frag == nil {
|
||||
// In case of unknown fragment (invalid request), ignore max depth evaluation
|
||||
c.addErr(sel.Loc, "MaxDepthEvaluationError", "Unknown fragment %q. Unable to evaluate depth.", sel.Name.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := visited[frag]; ok {
|
||||
// we've already seen this fragment, don't check depth again.
|
||||
continue
|
||||
}
|
||||
visited[frag] = struct{}{}
|
||||
|
||||
// Depth is not incremented because fragments have the same depth as surrounding fields
|
||||
exceededMaxDepth = exceededMaxDepth || validateMaxDepth(c, frag.Selections, visited, depth)
|
||||
}
|
||||
}
|
||||
|
||||
return exceededMaxDepth
|
||||
}
|
||||
|
||||
func validateSelectionSet(c *opContext, sels []types.Selection, t types.NamedType) {
|
||||
for _, sel := range sels {
|
||||
validateSelection(c, sel, t)
|
||||
}
|
||||
|
||||
for i, a := range sels {
|
||||
for _, b := range sels[i+1:] {
|
||||
c.validateOverlap(a, b, nil, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func validateSelection(c *opContext, sel types.Selection, t types.NamedType) {
|
||||
switch sel := sel.(type) {
|
||||
case *types.Field:
|
||||
validateDirectives(c, "FIELD", sel.Directives)
|
||||
|
||||
fieldName := sel.Name.Name
|
||||
var f *types.FieldDefinition
|
||||
switch fieldName {
|
||||
case "__typename":
|
||||
f = &types.FieldDefinition{
|
||||
Name: "__typename",
|
||||
Type: c.schema.Types["String"],
|
||||
}
|
||||
case "__schema":
|
||||
f = &types.FieldDefinition{
|
||||
Name: "__schema",
|
||||
Type: c.schema.Types["__Schema"],
|
||||
}
|
||||
case "__type":
|
||||
f = &types.FieldDefinition{
|
||||
Name: "__type",
|
||||
Arguments: types.ArgumentsDefinition{
|
||||
&types.InputValueDefinition{
|
||||
Name: types.Ident{Name: "name"},
|
||||
Type: &types.NonNull{OfType: c.schema.Types["String"]},
|
||||
},
|
||||
},
|
||||
Type: c.schema.Types["__Type"],
|
||||
}
|
||||
default:
|
||||
f = fields(t).Get(fieldName)
|
||||
if f == nil && t != nil {
|
||||
suggestion := makeSuggestion("Did you mean", fields(t).Names(), fieldName)
|
||||
c.addErr(sel.Alias.Loc, "FieldsOnCorrectType", "Cannot query field %q on type %q.%s", fieldName, t, suggestion)
|
||||
}
|
||||
}
|
||||
c.fieldMap[sel] = fieldInfo{sf: f, parent: t}
|
||||
|
||||
validateArgumentLiterals(c, sel.Arguments)
|
||||
if f != nil {
|
||||
validateArgumentTypes(c, sel.Arguments, f.Arguments, sel.Alias.Loc,
|
||||
func() string { return fmt.Sprintf("field %q of type %q", fieldName, t) },
|
||||
func() string { return fmt.Sprintf("Field %q", fieldName) },
|
||||
)
|
||||
}
|
||||
|
||||
var ft types.Type
|
||||
if f != nil {
|
||||
ft = f.Type
|
||||
sf := hasSubfields(ft)
|
||||
if sf && sel.SelectionSet == nil {
|
||||
c.addErr(sel.Alias.Loc, "ScalarLeafs", "Field %q of type %q must have a selection of subfields. Did you mean \"%s { ... }\"?", fieldName, ft, fieldName)
|
||||
}
|
||||
if !sf && sel.SelectionSet != nil {
|
||||
c.addErr(sel.SelectionSetLoc, "ScalarLeafs", "Field %q must not have a selection since type %q has no subfields.", fieldName, ft)
|
||||
}
|
||||
}
|
||||
if sel.SelectionSet != nil {
|
||||
validateSelectionSet(c, sel.SelectionSet, unwrapType(ft))
|
||||
}
|
||||
|
||||
case *types.InlineFragment:
|
||||
validateDirectives(c, "INLINE_FRAGMENT", sel.Directives)
|
||||
if sel.On.Name != "" {
|
||||
fragTyp := unwrapType(resolveType(c.context, &sel.On))
|
||||
if fragTyp != nil && !compatible(t, fragTyp) {
|
||||
c.addErr(sel.Loc, "PossibleFragmentSpreads", "Fragment cannot be spread here as objects of type %q can never be of type %q.", t, fragTyp)
|
||||
}
|
||||
t = fragTyp
|
||||
// continue even if t is nil
|
||||
}
|
||||
if t != nil && !canBeFragment(t) {
|
||||
c.addErr(sel.On.Loc, "FragmentsOnCompositeTypes", "Fragment cannot condition on non composite type %q.", t)
|
||||
return
|
||||
}
|
||||
validateSelectionSet(c, sel.Selections, unwrapType(t))
|
||||
|
||||
case *types.FragmentSpread:
|
||||
validateDirectives(c, "FRAGMENT_SPREAD", sel.Directives)
|
||||
frag := c.doc.Fragments.Get(sel.Name.Name)
|
||||
if frag == nil {
|
||||
c.addErr(sel.Name.Loc, "KnownFragmentNames", "Unknown fragment %q.", sel.Name.Name)
|
||||
return
|
||||
}
|
||||
fragTyp := c.schema.Types[frag.On.Name]
|
||||
if !compatible(t, fragTyp) {
|
||||
c.addErr(sel.Loc, "PossibleFragmentSpreads", "Fragment %q cannot be spread here as objects of type %q can never be of type %q.", frag.Name.Name, t, fragTyp)
|
||||
}
|
||||
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
|
||||
func compatible(a, b types.Type) bool {
|
||||
for _, pta := range possibleTypes(a) {
|
||||
for _, ptb := range possibleTypes(b) {
|
||||
if pta == ptb {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func possibleTypes(t types.Type) []*types.ObjectTypeDefinition {
|
||||
switch t := t.(type) {
|
||||
case *types.ObjectTypeDefinition:
|
||||
return []*types.ObjectTypeDefinition{t}
|
||||
case *types.InterfaceTypeDefinition:
|
||||
return t.PossibleTypes
|
||||
case *types.Union:
|
||||
return t.UnionMemberTypes
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func markUsedFragments(c *context, sels []types.Selection, fragUsed map[*types.FragmentDefinition]struct{}) {
|
||||
for _, sel := range sels {
|
||||
switch sel := sel.(type) {
|
||||
case *types.Field:
|
||||
if sel.SelectionSet != nil {
|
||||
markUsedFragments(c, sel.SelectionSet, fragUsed)
|
||||
}
|
||||
|
||||
case *types.InlineFragment:
|
||||
markUsedFragments(c, sel.Selections, fragUsed)
|
||||
|
||||
case *types.FragmentSpread:
|
||||
frag := c.doc.Fragments.Get(sel.Name.Name)
|
||||
if frag == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, ok := fragUsed[frag]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
fragUsed[frag] = struct{}{}
|
||||
markUsedFragments(c, frag.Selections, fragUsed)
|
||||
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func detectFragmentCycle(c *context, sels []types.Selection, fragVisited map[*types.FragmentDefinition]struct{}, spreadPath []*types.FragmentSpread, spreadPathIndex map[string]int) {
|
||||
for _, sel := range sels {
|
||||
detectFragmentCycleSel(c, sel, fragVisited, spreadPath, spreadPathIndex)
|
||||
}
|
||||
}
|
||||
|
||||
func detectFragmentCycleSel(c *context, sel types.Selection, fragVisited map[*types.FragmentDefinition]struct{}, spreadPath []*types.FragmentSpread, spreadPathIndex map[string]int) {
|
||||
switch sel := sel.(type) {
|
||||
case *types.Field:
|
||||
if sel.SelectionSet != nil {
|
||||
detectFragmentCycle(c, sel.SelectionSet, fragVisited, spreadPath, spreadPathIndex)
|
||||
}
|
||||
|
||||
case *types.InlineFragment:
|
||||
detectFragmentCycle(c, sel.Selections, fragVisited, spreadPath, spreadPathIndex)
|
||||
|
||||
case *types.FragmentSpread:
|
||||
frag := c.doc.Fragments.Get(sel.Name.Name)
|
||||
if frag == nil {
|
||||
return
|
||||
}
|
||||
|
||||
spreadPath = append(spreadPath, sel)
|
||||
if i, ok := spreadPathIndex[frag.Name.Name]; ok {
|
||||
cyclePath := spreadPath[i:]
|
||||
via := ""
|
||||
if len(cyclePath) > 1 {
|
||||
names := make([]string, len(cyclePath)-1)
|
||||
for i, frag := range cyclePath[:len(cyclePath)-1] {
|
||||
names[i] = frag.Name.Name
|
||||
}
|
||||
via = " via " + strings.Join(names, ", ")
|
||||
}
|
||||
|
||||
locs := make([]errors.Location, len(cyclePath))
|
||||
for i, frag := range cyclePath {
|
||||
locs[i] = frag.Loc
|
||||
}
|
||||
c.addErrMultiLoc(locs, "NoFragmentCycles", "Cannot spread fragment %q within itself%s.", frag.Name.Name, via)
|
||||
return
|
||||
}
|
||||
|
||||
if _, ok := fragVisited[frag]; ok {
|
||||
return
|
||||
}
|
||||
fragVisited[frag] = struct{}{}
|
||||
|
||||
spreadPathIndex[frag.Name.Name] = len(spreadPath)
|
||||
detectFragmentCycle(c, frag.Selections, fragVisited, spreadPath, spreadPathIndex)
|
||||
delete(spreadPathIndex, frag.Name.Name)
|
||||
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
|
||||
func (c *context) validateOverlap(a, b types.Selection, reasons *[]string, locs *[]errors.Location) {
|
||||
if a == b {
|
||||
return
|
||||
}
|
||||
|
||||
if _, ok := c.overlapValidated[selectionPair{a, b}]; ok {
|
||||
return
|
||||
}
|
||||
c.overlapValidated[selectionPair{a, b}] = struct{}{}
|
||||
c.overlapValidated[selectionPair{b, a}] = struct{}{}
|
||||
|
||||
switch a := a.(type) {
|
||||
case *types.Field:
|
||||
switch b := b.(type) {
|
||||
case *types.Field:
|
||||
if b.Alias.Loc.Before(a.Alias.Loc) {
|
||||
a, b = b, a
|
||||
}
|
||||
if reasons2, locs2 := c.validateFieldOverlap(a, b); len(reasons2) != 0 {
|
||||
locs2 = append(locs2, a.Alias.Loc, b.Alias.Loc)
|
||||
if reasons == nil {
|
||||
c.addErrMultiLoc(locs2, "OverlappingFieldsCanBeMerged", "Fields %q conflict because %s. Use different aliases on the fields to fetch both if this was intentional.", a.Alias.Name, strings.Join(reasons2, " and "))
|
||||
return
|
||||
}
|
||||
for _, r := range reasons2 {
|
||||
*reasons = append(*reasons, fmt.Sprintf("subfields %q conflict because %s", a.Alias.Name, r))
|
||||
}
|
||||
*locs = append(*locs, locs2...)
|
||||
}
|
||||
|
||||
case *types.InlineFragment:
|
||||
for _, sel := range b.Selections {
|
||||
c.validateOverlap(a, sel, reasons, locs)
|
||||
}
|
||||
|
||||
case *types.FragmentSpread:
|
||||
if frag := c.doc.Fragments.Get(b.Name.Name); frag != nil {
|
||||
for _, sel := range frag.Selections {
|
||||
c.validateOverlap(a, sel, reasons, locs)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
case *types.InlineFragment:
|
||||
for _, sel := range a.Selections {
|
||||
c.validateOverlap(sel, b, reasons, locs)
|
||||
}
|
||||
|
||||
case *types.FragmentSpread:
|
||||
if frag := c.doc.Fragments.Get(a.Name.Name); frag != nil {
|
||||
for _, sel := range frag.Selections {
|
||||
c.validateOverlap(sel, b, reasons, locs)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
|
||||
func (c *context) validateFieldOverlap(a, b *types.Field) ([]string, []errors.Location) {
|
||||
if a.Alias.Name != b.Alias.Name {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if asf := c.fieldMap[a].sf; asf != nil {
|
||||
if bsf := c.fieldMap[b].sf; bsf != nil {
|
||||
if !typesCompatible(asf.Type, bsf.Type) {
|
||||
return []string{fmt.Sprintf("they return conflicting types %s and %s", asf.Type, bsf.Type)}, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
at := c.fieldMap[a].parent
|
||||
bt := c.fieldMap[b].parent
|
||||
if at == nil || bt == nil || at == bt {
|
||||
if a.Name.Name != b.Name.Name {
|
||||
return []string{fmt.Sprintf("%s and %s are different fields", a.Name.Name, b.Name.Name)}, nil
|
||||
}
|
||||
|
||||
if argumentsConflict(a.Arguments, b.Arguments) {
|
||||
return []string{"they have differing arguments"}, nil
|
||||
}
|
||||
}
|
||||
|
||||
var reasons []string
|
||||
var locs []errors.Location
|
||||
for _, a2 := range a.SelectionSet {
|
||||
for _, b2 := range b.SelectionSet {
|
||||
c.validateOverlap(a2, b2, &reasons, &locs)
|
||||
}
|
||||
}
|
||||
return reasons, locs
|
||||
}
|
||||
|
||||
func argumentsConflict(a, b types.ArgumentList) bool {
|
||||
if len(a) != len(b) {
|
||||
return true
|
||||
}
|
||||
for _, argA := range a {
|
||||
valB, ok := b.Get(argA.Name.Name)
|
||||
if !ok || !reflect.DeepEqual(argA.Value.Deserialize(nil), valB.Deserialize(nil)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func fields(t types.Type) types.FieldsDefinition {
|
||||
switch t := t.(type) {
|
||||
case *types.ObjectTypeDefinition:
|
||||
return t.Fields
|
||||
case *types.InterfaceTypeDefinition:
|
||||
return t.Fields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func unwrapType(t types.Type) types.NamedType {
|
||||
if t == nil {
|
||||
return nil
|
||||
}
|
||||
for {
|
||||
switch t2 := t.(type) {
|
||||
case types.NamedType:
|
||||
return t2
|
||||
case *types.List:
|
||||
t = t2.OfType
|
||||
case *types.NonNull:
|
||||
t = t2.OfType
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func resolveType(c *context, t types.Type) types.Type {
|
||||
t2, err := common.ResolveType(t, c.schema.Resolve)
|
||||
if err != nil {
|
||||
c.errs = append(c.errs, err)
|
||||
}
|
||||
return t2
|
||||
}
|
||||
|
||||
func validateDirectives(c *opContext, loc string, directives types.DirectiveList) {
|
||||
directiveNames := make(nameSet)
|
||||
for _, d := range directives {
|
||||
dirName := d.Name.Name
|
||||
validateNameCustomMsg(c.context, directiveNames, d.Name, "UniqueDirectivesPerLocation", func() string {
|
||||
return fmt.Sprintf("The directive %q can only be used once at this location.", dirName)
|
||||
})
|
||||
|
||||
validateArgumentLiterals(c, d.Arguments)
|
||||
|
||||
dd, ok := c.schema.Directives[dirName]
|
||||
if !ok {
|
||||
c.addErr(d.Name.Loc, "KnownDirectives", "Unknown directive %q.", dirName)
|
||||
continue
|
||||
}
|
||||
|
||||
locOK := false
|
||||
for _, allowedLoc := range dd.Locations {
|
||||
if loc == allowedLoc {
|
||||
locOK = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !locOK {
|
||||
c.addErr(d.Name.Loc, "KnownDirectives", "Directive %q may not be used on %s.", dirName, loc)
|
||||
}
|
||||
|
||||
validateArgumentTypes(c, d.Arguments, dd.Arguments, d.Name.Loc,
|
||||
func() string { return fmt.Sprintf("directive %q", "@"+dirName) },
|
||||
func() string { return fmt.Sprintf("Directive %q", "@"+dirName) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func validateName(c *context, set nameSet, name types.Ident, rule string, kind string) {
|
||||
validateNameCustomMsg(c, set, name, rule, func() string {
|
||||
return fmt.Sprintf("There can be only one %s named %q.", kind, name.Name)
|
||||
})
|
||||
}
|
||||
|
||||
func validateNameCustomMsg(c *context, set nameSet, name types.Ident, rule string, msg func() string) {
|
||||
if loc, ok := set[name.Name]; ok {
|
||||
c.addErrMultiLoc([]errors.Location{loc, name.Loc}, rule, msg())
|
||||
return
|
||||
}
|
||||
set[name.Name] = name.Loc
|
||||
}
|
||||
|
||||
func validateArgumentTypes(c *opContext, args types.ArgumentList, argDecls types.ArgumentsDefinition, loc errors.Location, owner1, owner2 func() string) {
|
||||
for _, selArg := range args {
|
||||
arg := argDecls.Get(selArg.Name.Name)
|
||||
if arg == nil {
|
||||
c.addErr(selArg.Name.Loc, "KnownArgumentNames", "Unknown argument %q on %s.", selArg.Name.Name, owner1())
|
||||
continue
|
||||
}
|
||||
value := selArg.Value
|
||||
if ok, reason := validateValueType(c, value, arg.Type); !ok {
|
||||
c.addErr(value.Location(), "ArgumentsOfCorrectType", "Argument %q has invalid value %s.\n%s", arg.Name.Name, value, reason)
|
||||
}
|
||||
}
|
||||
for _, decl := range argDecls {
|
||||
if _, ok := decl.Type.(*types.NonNull); ok {
|
||||
if _, ok := args.Get(decl.Name.Name); !ok {
|
||||
c.addErr(loc, "ProvidedNonNullArguments", "%s argument %q of type %q is required but not provided.", owner2(), decl.Name.Name, decl.Type)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func validateArgumentLiterals(c *opContext, args types.ArgumentList) {
|
||||
argNames := make(nameSet)
|
||||
for _, arg := range args {
|
||||
validateName(c.context, argNames, arg.Name, "UniqueArgumentNames", "argument")
|
||||
validateLiteral(c, arg.Value)
|
||||
}
|
||||
}
|
||||
|
||||
func validateLiteral(c *opContext, l types.Value) {
|
||||
switch l := l.(type) {
|
||||
case *types.ObjectValue:
|
||||
fieldNames := make(nameSet)
|
||||
for _, f := range l.Fields {
|
||||
validateName(c.context, fieldNames, f.Name, "UniqueInputFieldNames", "input field")
|
||||
validateLiteral(c, f.Value)
|
||||
}
|
||||
case *types.ListValue:
|
||||
for _, entry := range l.Values {
|
||||
validateLiteral(c, entry)
|
||||
}
|
||||
case *types.Variable:
|
||||
for _, op := range c.ops {
|
||||
v := op.Vars.Get(l.Name)
|
||||
if v == nil {
|
||||
byOp := ""
|
||||
if op.Name.Name != "" {
|
||||
byOp = fmt.Sprintf(" by operation %q", op.Name.Name)
|
||||
}
|
||||
c.opErrs[op] = append(c.opErrs[op], &errors.QueryError{
|
||||
Message: fmt.Sprintf("Variable %q is not defined%s.", "$"+l.Name, byOp),
|
||||
Locations: []errors.Location{l.Loc, op.Loc},
|
||||
Rule: "NoUndefinedVariables",
|
||||
})
|
||||
continue
|
||||
}
|
||||
validateValueType(c, l, resolveType(c.context, v.Type))
|
||||
c.usedVars[op][v] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func validateValueType(c *opContext, v types.Value, t types.Type) (bool, string) {
|
||||
if v, ok := v.(*types.Variable); ok {
|
||||
for _, op := range c.ops {
|
||||
if v2 := op.Vars.Get(v.Name); v2 != nil {
|
||||
t2, err := common.ResolveType(v2.Type, c.schema.Resolve)
|
||||
if _, ok := t2.(*types.NonNull); !ok && v2.Default != nil {
|
||||
t2 = &types.NonNull{OfType: t2}
|
||||
}
|
||||
if err == nil && !typeCanBeUsedAs(t2, t) {
|
||||
c.addErrMultiLoc([]errors.Location{v2.Loc, v.Loc}, "VariablesInAllowedPosition", "Variable %q of type %q used in position expecting type %q.", "$"+v.Name, t2, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
return true, ""
|
||||
}
|
||||
|
||||
if nn, ok := t.(*types.NonNull); ok {
|
||||
if isNull(v) {
|
||||
return false, fmt.Sprintf("Expected %q, found null.", t)
|
||||
}
|
||||
t = nn.OfType
|
||||
}
|
||||
if isNull(v) {
|
||||
return true, ""
|
||||
}
|
||||
|
||||
switch t := t.(type) {
|
||||
case *types.ScalarTypeDefinition, *types.EnumTypeDefinition:
|
||||
if lit, ok := v.(*types.PrimitiveValue); ok {
|
||||
if validateBasicLit(lit, t) {
|
||||
return true, ""
|
||||
}
|
||||
return false, fmt.Sprintf("Expected type %q, found %s.", t, v)
|
||||
}
|
||||
return true, ""
|
||||
|
||||
case *types.List:
|
||||
list, ok := v.(*types.ListValue)
|
||||
if !ok {
|
||||
return validateValueType(c, v, t.OfType) // single value instead of list
|
||||
}
|
||||
for i, entry := range list.Values {
|
||||
if ok, reason := validateValueType(c, entry, t.OfType); !ok {
|
||||
return false, fmt.Sprintf("In element #%d: %s", i, reason)
|
||||
}
|
||||
}
|
||||
return true, ""
|
||||
|
||||
case *types.InputObject:
|
||||
v, ok := v.(*types.ObjectValue)
|
||||
if !ok {
|
||||
return false, fmt.Sprintf("Expected %q, found not an object.", t)
|
||||
}
|
||||
for _, f := range v.Fields {
|
||||
name := f.Name.Name
|
||||
iv := t.Values.Get(name)
|
||||
if iv == nil {
|
||||
return false, fmt.Sprintf("In field %q: Unknown field.", name)
|
||||
}
|
||||
if ok, reason := validateValueType(c, f.Value, iv.Type); !ok {
|
||||
return false, fmt.Sprintf("In field %q: %s", name, reason)
|
||||
}
|
||||
}
|
||||
for _, iv := range t.Values {
|
||||
found := false
|
||||
for _, f := range v.Fields {
|
||||
if f.Name.Name == iv.Name.Name {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
if _, ok := iv.Type.(*types.NonNull); ok && iv.Default == nil {
|
||||
return false, fmt.Sprintf("In field %q: Expected %q, found null.", iv.Name.Name, iv.Type)
|
||||
}
|
||||
}
|
||||
}
|
||||
return true, ""
|
||||
}
|
||||
|
||||
return false, fmt.Sprintf("Expected type %q, found %s.", t, v)
|
||||
}
|
||||
|
||||
func validateBasicLit(v *types.PrimitiveValue, t types.Type) bool {
|
||||
switch t := t.(type) {
|
||||
case *types.ScalarTypeDefinition:
|
||||
switch t.Name {
|
||||
case "Int":
|
||||
if v.Type != scanner.Int {
|
||||
return false
|
||||
}
|
||||
f, err := strconv.ParseFloat(v.Text, 64)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return f >= math.MinInt32 && f <= math.MaxInt32
|
||||
case "Float":
|
||||
return v.Type == scanner.Int || v.Type == scanner.Float
|
||||
case "String":
|
||||
return v.Type == scanner.String
|
||||
case "Boolean":
|
||||
return v.Type == scanner.Ident && (v.Text == "true" || v.Text == "false")
|
||||
case "ID":
|
||||
return v.Type == scanner.Int || v.Type == scanner.String
|
||||
default:
|
||||
//TODO: Type-check against expected type by Unmarshalling
|
||||
return true
|
||||
}
|
||||
|
||||
case *types.EnumTypeDefinition:
|
||||
if v.Type != scanner.Ident {
|
||||
return false
|
||||
}
|
||||
for _, option := range t.EnumValuesDefinition {
|
||||
if option.EnumValue == v.Text {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func canBeFragment(t types.Type) bool {
|
||||
switch t.(type) {
|
||||
case *types.ObjectTypeDefinition, *types.InterfaceTypeDefinition, *types.Union:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func canBeInput(t types.Type) bool {
|
||||
switch t := t.(type) {
|
||||
case *types.InputObject, *types.ScalarTypeDefinition, *types.EnumTypeDefinition:
|
||||
return true
|
||||
case *types.List:
|
||||
return canBeInput(t.OfType)
|
||||
case *types.NonNull:
|
||||
return canBeInput(t.OfType)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func hasSubfields(t types.Type) bool {
|
||||
switch t := t.(type) {
|
||||
case *types.ObjectTypeDefinition, *types.InterfaceTypeDefinition, *types.Union:
|
||||
return true
|
||||
case *types.List:
|
||||
return hasSubfields(t.OfType)
|
||||
case *types.NonNull:
|
||||
return hasSubfields(t.OfType)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func isLeaf(t types.Type) bool {
|
||||
switch t.(type) {
|
||||
case *types.ScalarTypeDefinition, *types.EnumTypeDefinition:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func isNull(lit interface{}) bool {
|
||||
_, ok := lit.(*types.NullValue)
|
||||
return ok
|
||||
}
|
||||
|
||||
func typesCompatible(a, b types.Type) bool {
|
||||
al, aIsList := a.(*types.List)
|
||||
bl, bIsList := b.(*types.List)
|
||||
if aIsList || bIsList {
|
||||
return aIsList && bIsList && typesCompatible(al.OfType, bl.OfType)
|
||||
}
|
||||
|
||||
ann, aIsNN := a.(*types.NonNull)
|
||||
bnn, bIsNN := b.(*types.NonNull)
|
||||
if aIsNN || bIsNN {
|
||||
return aIsNN && bIsNN && typesCompatible(ann.OfType, bnn.OfType)
|
||||
}
|
||||
|
||||
if isLeaf(a) || isLeaf(b) {
|
||||
return a == b
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func typeCanBeUsedAs(t, as types.Type) bool {
|
||||
nnT, okT := t.(*types.NonNull)
|
||||
if okT {
|
||||
t = nnT.OfType
|
||||
}
|
||||
|
||||
nnAs, okAs := as.(*types.NonNull)
|
||||
if okAs {
|
||||
as = nnAs.OfType
|
||||
if !okT {
|
||||
return false // nullable can not be used as non-null
|
||||
}
|
||||
}
|
||||
|
||||
if t == as {
|
||||
return true
|
||||
}
|
||||
|
||||
if lT, ok := t.(*types.List); ok {
|
||||
if lAs, ok := as.(*types.List); ok {
|
||||
return typeCanBeUsedAs(lT.OfType, lAs.OfType)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
118
vendor/github.com/graph-gophers/graphql-go/introspection.go
generated
vendored
Normal file
118
vendor/github.com/graph-gophers/graphql-go/introspection.go
generated
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/graph-gophers/graphql-go/internal/exec/resolvable"
|
||||
"github.com/graph-gophers/graphql-go/introspection"
|
||||
)
|
||||
|
||||
// Inspect allows inspection of the given schema.
|
||||
func (s *Schema) Inspect() *introspection.Schema {
|
||||
return introspection.WrapSchema(s.schema)
|
||||
}
|
||||
|
||||
// ToJSON encodes the schema in a JSON format used by tools like Relay.
|
||||
func (s *Schema) ToJSON() ([]byte, error) {
|
||||
result := s.exec(context.Background(), introspectionQuery, "", nil, &resolvable.Schema{
|
||||
Meta: s.res.Meta,
|
||||
Query: &resolvable.Object{},
|
||||
Schema: *s.schema,
|
||||
})
|
||||
if len(result.Errors) != 0 {
|
||||
panic(result.Errors[0])
|
||||
}
|
||||
return json.MarshalIndent(result.Data, "", "\t")
|
||||
}
|
||||
|
||||
var introspectionQuery = `
|
||||
query {
|
||||
__schema {
|
||||
queryType { name }
|
||||
mutationType { name }
|
||||
subscriptionType { name }
|
||||
types {
|
||||
...FullType
|
||||
}
|
||||
directives {
|
||||
name
|
||||
description
|
||||
locations
|
||||
args {
|
||||
...InputValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fragment FullType on __Type {
|
||||
kind
|
||||
name
|
||||
description
|
||||
fields(includeDeprecated: true) {
|
||||
name
|
||||
description
|
||||
args {
|
||||
...InputValue
|
||||
}
|
||||
type {
|
||||
...TypeRef
|
||||
}
|
||||
isDeprecated
|
||||
deprecationReason
|
||||
}
|
||||
inputFields {
|
||||
...InputValue
|
||||
}
|
||||
interfaces {
|
||||
...TypeRef
|
||||
}
|
||||
enumValues(includeDeprecated: true) {
|
||||
name
|
||||
description
|
||||
isDeprecated
|
||||
deprecationReason
|
||||
}
|
||||
possibleTypes {
|
||||
...TypeRef
|
||||
}
|
||||
}
|
||||
fragment InputValue on __InputValue {
|
||||
name
|
||||
description
|
||||
type { ...TypeRef }
|
||||
defaultValue
|
||||
}
|
||||
fragment TypeRef on __Type {
|
||||
kind
|
||||
name
|
||||
ofType {
|
||||
kind
|
||||
name
|
||||
ofType {
|
||||
kind
|
||||
name
|
||||
ofType {
|
||||
kind
|
||||
name
|
||||
ofType {
|
||||
kind
|
||||
name
|
||||
ofType {
|
||||
kind
|
||||
name
|
||||
ofType {
|
||||
kind
|
||||
name
|
||||
ofType {
|
||||
kind
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
312
vendor/github.com/graph-gophers/graphql-go/introspection/introspection.go
generated
vendored
Normal file
312
vendor/github.com/graph-gophers/graphql-go/introspection/introspection.go
generated
vendored
Normal file
@ -0,0 +1,312 @@
|
||||
package introspection
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/graph-gophers/graphql-go/types"
|
||||
)
|
||||
|
||||
type Schema struct {
|
||||
schema *types.Schema
|
||||
}
|
||||
|
||||
// WrapSchema is only used internally.
|
||||
func WrapSchema(schema *types.Schema) *Schema {
|
||||
return &Schema{schema}
|
||||
}
|
||||
|
||||
func (r *Schema) Types() []*Type {
|
||||
var names []string
|
||||
for name := range r.schema.Types {
|
||||
names = append(names, name)
|
||||
}
|
||||
sort.Strings(names)
|
||||
|
||||
l := make([]*Type, len(names))
|
||||
for i, name := range names {
|
||||
l[i] = &Type{r.schema.Types[name]}
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func (r *Schema) Directives() []*Directive {
|
||||
var names []string
|
||||
for name := range r.schema.Directives {
|
||||
names = append(names, name)
|
||||
}
|
||||
sort.Strings(names)
|
||||
|
||||
l := make([]*Directive, len(names))
|
||||
for i, name := range names {
|
||||
l[i] = &Directive{r.schema.Directives[name]}
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func (r *Schema) QueryType() *Type {
|
||||
t, ok := r.schema.EntryPoints["query"]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return &Type{t}
|
||||
}
|
||||
|
||||
func (r *Schema) MutationType() *Type {
|
||||
t, ok := r.schema.EntryPoints["mutation"]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return &Type{t}
|
||||
}
|
||||
|
||||
func (r *Schema) SubscriptionType() *Type {
|
||||
t, ok := r.schema.EntryPoints["subscription"]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return &Type{t}
|
||||
}
|
||||
|
||||
type Type struct {
|
||||
typ types.Type
|
||||
}
|
||||
|
||||
// WrapType is only used internally.
|
||||
func WrapType(typ types.Type) *Type {
|
||||
return &Type{typ}
|
||||
}
|
||||
|
||||
func (r *Type) Kind() string {
|
||||
return r.typ.Kind()
|
||||
}
|
||||
|
||||
func (r *Type) Name() *string {
|
||||
if named, ok := r.typ.(types.NamedType); ok {
|
||||
name := named.TypeName()
|
||||
return &name
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Type) Description() *string {
|
||||
if named, ok := r.typ.(types.NamedType); ok {
|
||||
desc := named.Description()
|
||||
if desc == "" {
|
||||
return nil
|
||||
}
|
||||
return &desc
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Type) Fields(args *struct{ IncludeDeprecated bool }) *[]*Field {
|
||||
var fields types.FieldsDefinition
|
||||
switch t := r.typ.(type) {
|
||||
case *types.ObjectTypeDefinition:
|
||||
fields = t.Fields
|
||||
case *types.InterfaceTypeDefinition:
|
||||
fields = t.Fields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
var l []*Field
|
||||
for _, f := range fields {
|
||||
if d := f.Directives.Get("deprecated"); d == nil || args.IncludeDeprecated {
|
||||
l = append(l, &Field{field: f})
|
||||
}
|
||||
}
|
||||
return &l
|
||||
}
|
||||
|
||||
func (r *Type) Interfaces() *[]*Type {
|
||||
t, ok := r.typ.(*types.ObjectTypeDefinition)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
l := make([]*Type, len(t.Interfaces))
|
||||
for i, intf := range t.Interfaces {
|
||||
l[i] = &Type{intf}
|
||||
}
|
||||
return &l
|
||||
}
|
||||
|
||||
func (r *Type) PossibleTypes() *[]*Type {
|
||||
var possibleTypes []*types.ObjectTypeDefinition
|
||||
switch t := r.typ.(type) {
|
||||
case *types.InterfaceTypeDefinition:
|
||||
possibleTypes = t.PossibleTypes
|
||||
case *types.Union:
|
||||
possibleTypes = t.UnionMemberTypes
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
l := make([]*Type, len(possibleTypes))
|
||||
for i, intf := range possibleTypes {
|
||||
l[i] = &Type{intf}
|
||||
}
|
||||
return &l
|
||||
}
|
||||
|
||||
func (r *Type) EnumValues(args *struct{ IncludeDeprecated bool }) *[]*EnumValue {
|
||||
t, ok := r.typ.(*types.EnumTypeDefinition)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
var l []*EnumValue
|
||||
for _, v := range t.EnumValuesDefinition {
|
||||
if d := v.Directives.Get("deprecated"); d == nil || args.IncludeDeprecated {
|
||||
l = append(l, &EnumValue{v})
|
||||
}
|
||||
}
|
||||
return &l
|
||||
}
|
||||
|
||||
func (r *Type) InputFields() *[]*InputValue {
|
||||
t, ok := r.typ.(*types.InputObject)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
l := make([]*InputValue, len(t.Values))
|
||||
for i, v := range t.Values {
|
||||
l[i] = &InputValue{v}
|
||||
}
|
||||
return &l
|
||||
}
|
||||
|
||||
func (r *Type) OfType() *Type {
|
||||
switch t := r.typ.(type) {
|
||||
case *types.List:
|
||||
return &Type{t.OfType}
|
||||
case *types.NonNull:
|
||||
return &Type{t.OfType}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
type Field struct {
|
||||
field *types.FieldDefinition
|
||||
}
|
||||
|
||||
func (r *Field) Name() string {
|
||||
return r.field.Name
|
||||
}
|
||||
|
||||
func (r *Field) Description() *string {
|
||||
if r.field.Desc == "" {
|
||||
return nil
|
||||
}
|
||||
return &r.field.Desc
|
||||
}
|
||||
|
||||
func (r *Field) Args() []*InputValue {
|
||||
l := make([]*InputValue, len(r.field.Arguments))
|
||||
for i, v := range r.field.Arguments {
|
||||
l[i] = &InputValue{v}
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func (r *Field) Type() *Type {
|
||||
return &Type{r.field.Type}
|
||||
}
|
||||
|
||||
func (r *Field) IsDeprecated() bool {
|
||||
return r.field.Directives.Get("deprecated") != nil
|
||||
}
|
||||
|
||||
func (r *Field) DeprecationReason() *string {
|
||||
d := r.field.Directives.Get("deprecated")
|
||||
if d == nil {
|
||||
return nil
|
||||
}
|
||||
reason := d.Arguments.MustGet("reason").Deserialize(nil).(string)
|
||||
return &reason
|
||||
}
|
||||
|
||||
type InputValue struct {
|
||||
value *types.InputValueDefinition
|
||||
}
|
||||
|
||||
func (r *InputValue) Name() string {
|
||||
return r.value.Name.Name
|
||||
}
|
||||
|
||||
func (r *InputValue) Description() *string {
|
||||
if r.value.Desc == "" {
|
||||
return nil
|
||||
}
|
||||
return &r.value.Desc
|
||||
}
|
||||
|
||||
func (r *InputValue) Type() *Type {
|
||||
return &Type{r.value.Type}
|
||||
}
|
||||
|
||||
func (r *InputValue) DefaultValue() *string {
|
||||
if r.value.Default == nil {
|
||||
return nil
|
||||
}
|
||||
s := r.value.Default.String()
|
||||
return &s
|
||||
}
|
||||
|
||||
type EnumValue struct {
|
||||
value *types.EnumValueDefinition
|
||||
}
|
||||
|
||||
func (r *EnumValue) Name() string {
|
||||
return r.value.EnumValue
|
||||
}
|
||||
|
||||
func (r *EnumValue) Description() *string {
|
||||
if r.value.Desc == "" {
|
||||
return nil
|
||||
}
|
||||
return &r.value.Desc
|
||||
}
|
||||
|
||||
func (r *EnumValue) IsDeprecated() bool {
|
||||
return r.value.Directives.Get("deprecated") != nil
|
||||
}
|
||||
|
||||
func (r *EnumValue) DeprecationReason() *string {
|
||||
d := r.value.Directives.Get("deprecated")
|
||||
if d == nil {
|
||||
return nil
|
||||
}
|
||||
reason := d.Arguments.MustGet("reason").Deserialize(nil).(string)
|
||||
return &reason
|
||||
}
|
||||
|
||||
type Directive struct {
|
||||
directive *types.DirectiveDefinition
|
||||
}
|
||||
|
||||
func (r *Directive) Name() string {
|
||||
return r.directive.Name
|
||||
}
|
||||
|
||||
func (r *Directive) Description() *string {
|
||||
if r.directive.Desc == "" {
|
||||
return nil
|
||||
}
|
||||
return &r.directive.Desc
|
||||
}
|
||||
|
||||
func (r *Directive) Locations() []string {
|
||||
return r.directive.Locations
|
||||
}
|
||||
|
||||
func (r *Directive) Args() []*InputValue {
|
||||
l := make([]*InputValue, len(r.directive.Arguments))
|
||||
for i, v := range r.directive.Arguments {
|
||||
l[i] = &InputValue{v}
|
||||
}
|
||||
return l
|
||||
}
|
23
vendor/github.com/graph-gophers/graphql-go/log/log.go
generated
vendored
Normal file
23
vendor/github.com/graph-gophers/graphql-go/log/log.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Logger is the interface used to log panics that occur during query execution. It is settable via graphql.ParseSchema
|
||||
type Logger interface {
|
||||
LogPanic(ctx context.Context, value interface{})
|
||||
}
|
||||
|
||||
// DefaultLogger is the default logger used to log panics that occur during query execution
|
||||
type DefaultLogger struct{}
|
||||
|
||||
// LogPanic is used to log recovered panic values that occur during query execution
|
||||
func (l *DefaultLogger) LogPanic(ctx context.Context, value interface{}) {
|
||||
const size = 64 << 10
|
||||
buf := make([]byte, size)
|
||||
buf = buf[:runtime.Stack(buf, false)]
|
||||
log.Printf("graphql: panic occurred: %v\n%s\ncontext: %v", value, buf, ctx)
|
||||
}
|
166
vendor/github.com/graph-gophers/graphql-go/nullable_types.go
generated
vendored
Normal file
166
vendor/github.com/graph-gophers/graphql-go/nullable_types.go
generated
vendored
Normal file
@ -0,0 +1,166 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
// NullString is a string that can be null. Use it in input structs to
|
||||
// differentiate a value explicitly set to null from an omitted value.
|
||||
// When the value is defined (either null or a value) Set is true.
|
||||
type NullString struct {
|
||||
Value *string
|
||||
Set bool
|
||||
}
|
||||
|
||||
func (NullString) ImplementsGraphQLType(name string) bool {
|
||||
return name == "String"
|
||||
}
|
||||
|
||||
func (s *NullString) UnmarshalGraphQL(input interface{}) error {
|
||||
s.Set = true
|
||||
|
||||
if input == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch v := input.(type) {
|
||||
case string:
|
||||
s.Value = &v
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("wrong type for String: %T", v)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *NullString) Nullable() {}
|
||||
|
||||
// NullBool is a string that can be null. Use it in input structs to
|
||||
// differentiate a value explicitly set to null from an omitted value.
|
||||
// When the value is defined (either null or a value) Set is true.
|
||||
type NullBool struct {
|
||||
Value *bool
|
||||
Set bool
|
||||
}
|
||||
|
||||
func (NullBool) ImplementsGraphQLType(name string) bool {
|
||||
return name == "Boolean"
|
||||
}
|
||||
|
||||
func (s *NullBool) UnmarshalGraphQL(input interface{}) error {
|
||||
s.Set = true
|
||||
|
||||
if input == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch v := input.(type) {
|
||||
case bool:
|
||||
s.Value = &v
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("wrong type for Boolean: %T", v)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *NullBool) Nullable() {}
|
||||
|
||||
// NullInt is a string that can be null. Use it in input structs to
|
||||
// differentiate a value explicitly set to null from an omitted value.
|
||||
// When the value is defined (either null or a value) Set is true.
|
||||
type NullInt struct {
|
||||
Value *int32
|
||||
Set bool
|
||||
}
|
||||
|
||||
func (NullInt) ImplementsGraphQLType(name string) bool {
|
||||
return name == "Int"
|
||||
}
|
||||
|
||||
func (s *NullInt) UnmarshalGraphQL(input interface{}) error {
|
||||
s.Set = true
|
||||
|
||||
if input == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch v := input.(type) {
|
||||
case int32:
|
||||
s.Value = &v
|
||||
return nil
|
||||
case float64:
|
||||
coerced := int32(v)
|
||||
if v < math.MinInt32 || v > math.MaxInt32 || float64(coerced) != v {
|
||||
return fmt.Errorf("not a 32-bit integer")
|
||||
}
|
||||
s.Value = &coerced
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("wrong type for Int: %T", v)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *NullInt) Nullable() {}
|
||||
|
||||
// NullFloat is a string that can be null. Use it in input structs to
|
||||
// differentiate a value explicitly set to null from an omitted value.
|
||||
// When the value is defined (either null or a value) Set is true.
|
||||
type NullFloat struct {
|
||||
Value *float64
|
||||
Set bool
|
||||
}
|
||||
|
||||
func (NullFloat) ImplementsGraphQLType(name string) bool {
|
||||
return name == "Float"
|
||||
}
|
||||
|
||||
func (s *NullFloat) UnmarshalGraphQL(input interface{}) error {
|
||||
s.Set = true
|
||||
|
||||
if input == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch v := input.(type) {
|
||||
case float64:
|
||||
s.Value = &v
|
||||
return nil
|
||||
case int32:
|
||||
coerced := float64(v)
|
||||
s.Value = &coerced
|
||||
return nil
|
||||
case int:
|
||||
coerced := float64(v)
|
||||
s.Value = &coerced
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("wrong type for Float: %T", v)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *NullFloat) Nullable() {}
|
||||
|
||||
// NullTime is a string that can be null. Use it in input structs to
|
||||
// differentiate a value explicitly set to null from an omitted value.
|
||||
// When the value is defined (either null or a value) Set is true.
|
||||
type NullTime struct {
|
||||
Value *Time
|
||||
Set bool
|
||||
}
|
||||
|
||||
func (NullTime) ImplementsGraphQLType(name string) bool {
|
||||
return name == "Time"
|
||||
}
|
||||
|
||||
func (s *NullTime) UnmarshalGraphQL(input interface{}) error {
|
||||
s.Set = true
|
||||
|
||||
if input == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
s.Value = new(Time)
|
||||
return s.Value.UnmarshalGraphQL(input)
|
||||
}
|
||||
|
||||
func (s *NullTime) Nullable() {}
|
96
vendor/github.com/graph-gophers/graphql-go/subscriptions.go
generated
vendored
Normal file
96
vendor/github.com/graph-gophers/graphql-go/subscriptions.go
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
qerrors "github.com/graph-gophers/graphql-go/errors"
|
||||
"github.com/graph-gophers/graphql-go/internal/common"
|
||||
"github.com/graph-gophers/graphql-go/internal/exec"
|
||||
"github.com/graph-gophers/graphql-go/internal/exec/resolvable"
|
||||
"github.com/graph-gophers/graphql-go/internal/exec/selected"
|
||||
"github.com/graph-gophers/graphql-go/internal/query"
|
||||
"github.com/graph-gophers/graphql-go/internal/validation"
|
||||
"github.com/graph-gophers/graphql-go/introspection"
|
||||
)
|
||||
|
||||
// Subscribe returns a response channel for the given subscription with the schema's
|
||||
// resolver. It returns an error if the schema was created without a resolver.
|
||||
// If the context gets cancelled, the response channel will be closed and no
|
||||
// further resolvers will be called. The context error will be returned as soon
|
||||
// as possible (not immediately).
|
||||
func (s *Schema) Subscribe(ctx context.Context, queryString string, operationName string, variables map[string]interface{}) (<-chan interface{}, error) {
|
||||
if !s.res.Resolver.IsValid() {
|
||||
return nil, errors.New("schema created without resolver, can not subscribe")
|
||||
}
|
||||
if _, ok := s.schema.EntryPoints["subscription"]; !ok {
|
||||
return nil, errors.New("no subscriptions are offered by the schema")
|
||||
}
|
||||
return s.subscribe(ctx, queryString, operationName, variables, s.res), nil
|
||||
}
|
||||
|
||||
func (s *Schema) subscribe(ctx context.Context, queryString string, operationName string, variables map[string]interface{}, res *resolvable.Schema) <-chan interface{} {
|
||||
doc, qErr := query.Parse(queryString)
|
||||
if qErr != nil {
|
||||
return sendAndReturnClosed(&Response{Errors: []*qerrors.QueryError{qErr}})
|
||||
}
|
||||
|
||||
validationFinish := s.validationTracer.TraceValidation(ctx)
|
||||
errs := validation.Validate(s.schema, doc, variables, s.maxDepth)
|
||||
validationFinish(errs)
|
||||
if len(errs) != 0 {
|
||||
return sendAndReturnClosed(&Response{Errors: errs})
|
||||
}
|
||||
|
||||
op, err := getOperation(doc, operationName)
|
||||
if err != nil {
|
||||
return sendAndReturnClosed(&Response{Errors: []*qerrors.QueryError{qerrors.Errorf("%s", err)}})
|
||||
}
|
||||
|
||||
r := &exec.Request{
|
||||
Request: selected.Request{
|
||||
Doc: doc,
|
||||
Vars: variables,
|
||||
Schema: s.schema,
|
||||
},
|
||||
Limiter: make(chan struct{}, s.maxParallelism),
|
||||
Tracer: s.tracer,
|
||||
Logger: s.logger,
|
||||
PanicHandler: s.panicHandler,
|
||||
SubscribeResolverTimeout: s.subscribeResolverTimeout,
|
||||
}
|
||||
varTypes := make(map[string]*introspection.Type)
|
||||
for _, v := range op.Vars {
|
||||
t, err := common.ResolveType(v.Type, s.schema.Resolve)
|
||||
if err != nil {
|
||||
return sendAndReturnClosed(&Response{Errors: []*qerrors.QueryError{err}})
|
||||
}
|
||||
varTypes[v.Name.Name] = introspection.WrapType(t)
|
||||
}
|
||||
|
||||
if op.Type == query.Query || op.Type == query.Mutation {
|
||||
data, errs := r.Execute(ctx, res, op)
|
||||
return sendAndReturnClosed(&Response{Data: data, Errors: errs})
|
||||
}
|
||||
|
||||
responses := r.Subscribe(ctx, res, op)
|
||||
c := make(chan interface{})
|
||||
go func() {
|
||||
for resp := range responses {
|
||||
c <- &Response{
|
||||
Data: resp.Data,
|
||||
Errors: resp.Errors,
|
||||
}
|
||||
}
|
||||
close(c)
|
||||
}()
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func sendAndReturnClosed(resp *Response) chan interface{} {
|
||||
c := make(chan interface{}, 1)
|
||||
c <- resp
|
||||
close(c)
|
||||
return c
|
||||
}
|
64
vendor/github.com/graph-gophers/graphql-go/time.go
generated
vendored
Normal file
64
vendor/github.com/graph-gophers/graphql-go/time.go
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Time is a custom GraphQL type to represent an instant in time. It has to be added to a schema
|
||||
// via "scalar Time" since it is not a predeclared GraphQL type like "ID".
|
||||
type Time struct {
|
||||
time.Time
|
||||
}
|
||||
|
||||
// ImplementsGraphQLType maps this custom Go type
|
||||
// to the graphql scalar type in the schema.
|
||||
func (Time) ImplementsGraphQLType(name string) bool {
|
||||
return name == "Time"
|
||||
}
|
||||
|
||||
// UnmarshalGraphQL is a custom unmarshaler for Time
|
||||
//
|
||||
// This function will be called whenever you use the
|
||||
// time scalar as an input
|
||||
func (t *Time) UnmarshalGraphQL(input interface{}) error {
|
||||
switch input := input.(type) {
|
||||
case time.Time:
|
||||
t.Time = input
|
||||
return nil
|
||||
case string:
|
||||
var err error
|
||||
t.Time, err = time.Parse(time.RFC3339, input)
|
||||
return err
|
||||
case []byte:
|
||||
var err error
|
||||
t.Time, err = time.Parse(time.RFC3339, string(input))
|
||||
return err
|
||||
case int32:
|
||||
t.Time = time.Unix(int64(input), 0)
|
||||
return nil
|
||||
case int64:
|
||||
if input >= 1e10 {
|
||||
sec := input / 1e9
|
||||
nsec := input - (sec * 1e9)
|
||||
t.Time = time.Unix(sec, nsec)
|
||||
} else {
|
||||
t.Time = time.Unix(input, 0)
|
||||
}
|
||||
return nil
|
||||
case float64:
|
||||
t.Time = time.Unix(int64(input), 0)
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("wrong type for Time: %T", input)
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshaler for Time
|
||||
//
|
||||
// This function will be called whenever you
|
||||
// query for fields that use the Time type
|
||||
func (t Time) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(t.Time)
|
||||
}
|
96
vendor/github.com/graph-gophers/graphql-go/trace/trace.go
generated
vendored
Normal file
96
vendor/github.com/graph-gophers/graphql-go/trace/trace.go
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
package trace
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/graph-gophers/graphql-go/errors"
|
||||
"github.com/graph-gophers/graphql-go/introspection"
|
||||
opentracing "github.com/opentracing/opentracing-go"
|
||||
"github.com/opentracing/opentracing-go/ext"
|
||||
"github.com/opentracing/opentracing-go/log"
|
||||
)
|
||||
|
||||
type TraceQueryFinishFunc func([]*errors.QueryError)
|
||||
type TraceFieldFinishFunc func(*errors.QueryError)
|
||||
|
||||
type Tracer interface {
|
||||
TraceQuery(ctx context.Context, queryString string, operationName string, variables map[string]interface{}, varTypes map[string]*introspection.Type) (context.Context, TraceQueryFinishFunc)
|
||||
TraceField(ctx context.Context, label, typeName, fieldName string, trivial bool, args map[string]interface{}) (context.Context, TraceFieldFinishFunc)
|
||||
}
|
||||
|
||||
type OpenTracingTracer struct{}
|
||||
|
||||
func (OpenTracingTracer) TraceQuery(ctx context.Context, queryString string, operationName string, variables map[string]interface{}, varTypes map[string]*introspection.Type) (context.Context, TraceQueryFinishFunc) {
|
||||
span, spanCtx := opentracing.StartSpanFromContext(ctx, "GraphQL request")
|
||||
span.SetTag("graphql.query", queryString)
|
||||
|
||||
if operationName != "" {
|
||||
span.SetTag("graphql.operationName", operationName)
|
||||
}
|
||||
|
||||
if len(variables) != 0 {
|
||||
span.LogFields(log.Object("graphql.variables", variables))
|
||||
}
|
||||
|
||||
return spanCtx, func(errs []*errors.QueryError) {
|
||||
if len(errs) > 0 {
|
||||
msg := errs[0].Error()
|
||||
if len(errs) > 1 {
|
||||
msg += fmt.Sprintf(" (and %d more errors)", len(errs)-1)
|
||||
}
|
||||
ext.Error.Set(span, true)
|
||||
span.SetTag("graphql.error", msg)
|
||||
}
|
||||
span.Finish()
|
||||
}
|
||||
}
|
||||
|
||||
func (OpenTracingTracer) TraceField(ctx context.Context, label, typeName, fieldName string, trivial bool, args map[string]interface{}) (context.Context, TraceFieldFinishFunc) {
|
||||
if trivial {
|
||||
return ctx, noop
|
||||
}
|
||||
|
||||
span, spanCtx := opentracing.StartSpanFromContext(ctx, label)
|
||||
span.SetTag("graphql.type", typeName)
|
||||
span.SetTag("graphql.field", fieldName)
|
||||
for name, value := range args {
|
||||
span.SetTag("graphql.args."+name, value)
|
||||
}
|
||||
|
||||
return spanCtx, func(err *errors.QueryError) {
|
||||
if err != nil {
|
||||
ext.Error.Set(span, true)
|
||||
span.SetTag("graphql.error", err.Error())
|
||||
}
|
||||
span.Finish()
|
||||
}
|
||||
}
|
||||
|
||||
func (OpenTracingTracer) TraceValidation(ctx context.Context) TraceValidationFinishFunc {
|
||||
span, _ := opentracing.StartSpanFromContext(ctx, "Validate Query")
|
||||
|
||||
return func(errs []*errors.QueryError) {
|
||||
if len(errs) > 0 {
|
||||
msg := errs[0].Error()
|
||||
if len(errs) > 1 {
|
||||
msg += fmt.Sprintf(" (and %d more errors)", len(errs)-1)
|
||||
}
|
||||
ext.Error.Set(span, true)
|
||||
span.SetTag("graphql.error", msg)
|
||||
}
|
||||
span.Finish()
|
||||
}
|
||||
}
|
||||
|
||||
func noop(*errors.QueryError) {}
|
||||
|
||||
type NoopTracer struct{}
|
||||
|
||||
func (NoopTracer) TraceQuery(ctx context.Context, queryString string, operationName string, variables map[string]interface{}, varTypes map[string]*introspection.Type) (context.Context, TraceQueryFinishFunc) {
|
||||
return ctx, func(errs []*errors.QueryError) {}
|
||||
}
|
||||
|
||||
func (NoopTracer) TraceField(ctx context.Context, label, typeName, fieldName string, trivial bool, args map[string]interface{}) (context.Context, TraceFieldFinishFunc) {
|
||||
return ctx, func(err *errors.QueryError) {}
|
||||
}
|
25
vendor/github.com/graph-gophers/graphql-go/trace/validation_trace.go
generated
vendored
Normal file
25
vendor/github.com/graph-gophers/graphql-go/trace/validation_trace.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
package trace
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/graph-gophers/graphql-go/errors"
|
||||
)
|
||||
|
||||
type TraceValidationFinishFunc = TraceQueryFinishFunc
|
||||
|
||||
// Deprecated: use ValidationTracerContext.
|
||||
type ValidationTracer interface {
|
||||
TraceValidation() TraceValidationFinishFunc
|
||||
}
|
||||
|
||||
type ValidationTracerContext interface {
|
||||
TraceValidation(ctx context.Context) TraceValidationFinishFunc
|
||||
}
|
||||
|
||||
type NoopValidationTracer struct{}
|
||||
|
||||
// Deprecated: use a Tracer which implements ValidationTracerContext.
|
||||
func (NoopValidationTracer) TraceValidation() TraceValidationFinishFunc {
|
||||
return func(errs []*errors.QueryError) {}
|
||||
}
|
44
vendor/github.com/graph-gophers/graphql-go/types/argument.go
generated
vendored
Normal file
44
vendor/github.com/graph-gophers/graphql-go/types/argument.go
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
package types
|
||||
|
||||
// Argument is a representation of the GraphQL Argument.
|
||||
//
|
||||
// https://spec.graphql.org/draft/#sec-Language.Arguments
|
||||
type Argument struct {
|
||||
Name Ident
|
||||
Value Value
|
||||
}
|
||||
|
||||
// ArgumentList is a collection of GraphQL Arguments.
|
||||
type ArgumentList []*Argument
|
||||
|
||||
// Returns a Value in the ArgumentList by name.
|
||||
func (l ArgumentList) Get(name string) (Value, bool) {
|
||||
for _, arg := range l {
|
||||
if arg.Name.Name == name {
|
||||
return arg.Value, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// MustGet returns a Value in the ArgumentList by name.
|
||||
// MustGet will panic if the argument name is not found in the ArgumentList.
|
||||
func (l ArgumentList) MustGet(name string) Value {
|
||||
value, ok := l.Get(name)
|
||||
if !ok {
|
||||
panic("argument not found")
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
type ArgumentsDefinition []*InputValueDefinition
|
||||
|
||||
// Get returns an InputValueDefinition in the ArgumentsDefinition by name or nil if not found.
|
||||
func (a ArgumentsDefinition) Get(name string) *InputValueDefinition {
|
||||
for _, inputValue := range a {
|
||||
if inputValue.Name.Name == name {
|
||||
return inputValue
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
34
vendor/github.com/graph-gophers/graphql-go/types/directive.go
generated
vendored
Normal file
34
vendor/github.com/graph-gophers/graphql-go/types/directive.go
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
package types
|
||||
|
||||
import "github.com/graph-gophers/graphql-go/errors"
|
||||
|
||||
// Directive is a representation of the GraphQL Directive.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#sec-Language.Directives
|
||||
type Directive struct {
|
||||
Name Ident
|
||||
Arguments ArgumentList
|
||||
}
|
||||
|
||||
// DirectiveDefinition is a representation of the GraphQL DirectiveDefinition.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#sec-Type-System.Directives
|
||||
type DirectiveDefinition struct {
|
||||
Name string
|
||||
Desc string
|
||||
Locations []string
|
||||
Arguments ArgumentsDefinition
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
type DirectiveList []*Directive
|
||||
|
||||
// Returns the Directive in the DirectiveList by name or nil if not found.
|
||||
func (l DirectiveList) Get(name string) *Directive {
|
||||
for _, d := range l {
|
||||
if d.Name.Name == name {
|
||||
return d
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
9
vendor/github.com/graph-gophers/graphql-go/types/doc.go
generated
vendored
Normal file
9
vendor/github.com/graph-gophers/graphql-go/types/doc.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
/*
|
||||
Package types represents all types from the GraphQL specification in code.
|
||||
|
||||
|
||||
The names of the Go types, whenever possible, match 1:1 with the names from
|
||||
the specification.
|
||||
|
||||
*/
|
||||
package types
|
32
vendor/github.com/graph-gophers/graphql-go/types/enum.go
generated
vendored
Normal file
32
vendor/github.com/graph-gophers/graphql-go/types/enum.go
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
package types
|
||||
|
||||
import "github.com/graph-gophers/graphql-go/errors"
|
||||
|
||||
// EnumTypeDefinition defines a set of possible enum values.
|
||||
//
|
||||
// Like scalar types, an EnumTypeDefinition also represents a leaf value in a GraphQL type system.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#sec-Enums
|
||||
type EnumTypeDefinition struct {
|
||||
Name string
|
||||
EnumValuesDefinition []*EnumValueDefinition
|
||||
Desc string
|
||||
Directives DirectiveList
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
// EnumValueDefinition are unique values that may be serialized as a string: the name of the
|
||||
// represented value.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#EnumValueDefinition
|
||||
type EnumValueDefinition struct {
|
||||
EnumValue string
|
||||
Directives DirectiveList
|
||||
Desc string
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
func (*EnumTypeDefinition) Kind() string { return "ENUM" }
|
||||
func (t *EnumTypeDefinition) String() string { return t.Name }
|
||||
func (t *EnumTypeDefinition) TypeName() string { return t.Name }
|
||||
func (t *EnumTypeDefinition) Description() string { return t.Desc }
|
13
vendor/github.com/graph-gophers/graphql-go/types/extension.go
generated
vendored
Normal file
13
vendor/github.com/graph-gophers/graphql-go/types/extension.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
package types
|
||||
|
||||
import "github.com/graph-gophers/graphql-go/errors"
|
||||
|
||||
// Extension type defines a GraphQL type extension.
|
||||
// Schemas, Objects, Inputs and Scalars can be extended.
|
||||
//
|
||||
// https://spec.graphql.org/draft/#sec-Type-System-Extensions
|
||||
type Extension struct {
|
||||
Type NamedType
|
||||
Directives DirectiveList
|
||||
Loc errors.Location
|
||||
}
|
39
vendor/github.com/graph-gophers/graphql-go/types/field.go
generated
vendored
Normal file
39
vendor/github.com/graph-gophers/graphql-go/types/field.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
package types
|
||||
|
||||
import "github.com/graph-gophers/graphql-go/errors"
|
||||
|
||||
// FieldDefinition is a representation of a GraphQL FieldDefinition.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#FieldDefinition
|
||||
type FieldDefinition struct {
|
||||
Name string
|
||||
Arguments ArgumentsDefinition
|
||||
Type Type
|
||||
Directives DirectiveList
|
||||
Desc string
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
// FieldsDefinition is a list of an ObjectTypeDefinition's Fields.
|
||||
//
|
||||
// https://spec.graphql.org/draft/#FieldsDefinition
|
||||
type FieldsDefinition []*FieldDefinition
|
||||
|
||||
// Get returns a FieldDefinition in a FieldsDefinition by name or nil if not found.
|
||||
func (l FieldsDefinition) Get(name string) *FieldDefinition {
|
||||
for _, f := range l {
|
||||
if f.Name == name {
|
||||
return f
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Names returns a slice of FieldDefinition names.
|
||||
func (l FieldsDefinition) Names() []string {
|
||||
names := make([]string, len(l))
|
||||
for i, f := range l {
|
||||
names[i] = f.Name
|
||||
}
|
||||
return names
|
||||
}
|
51
vendor/github.com/graph-gophers/graphql-go/types/fragment.go
generated
vendored
Normal file
51
vendor/github.com/graph-gophers/graphql-go/types/fragment.go
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
package types
|
||||
|
||||
import "github.com/graph-gophers/graphql-go/errors"
|
||||
|
||||
type Fragment struct {
|
||||
On TypeName
|
||||
Selections SelectionSet
|
||||
}
|
||||
|
||||
// InlineFragment is a representation of the GraphQL InlineFragment.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#InlineFragment
|
||||
type InlineFragment struct {
|
||||
Fragment
|
||||
Directives DirectiveList
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
// FragmentDefinition is a representation of the GraphQL FragmentDefinition.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#FragmentDefinition
|
||||
type FragmentDefinition struct {
|
||||
Fragment
|
||||
Name Ident
|
||||
Directives DirectiveList
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
// FragmentSpread is a representation of the GraphQL FragmentSpread.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#FragmentSpread
|
||||
type FragmentSpread struct {
|
||||
Name Ident
|
||||
Directives DirectiveList
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
type FragmentList []*FragmentDefinition
|
||||
|
||||
// Returns a FragmentDefinition by name or nil if not found.
|
||||
func (l FragmentList) Get(name string) *FragmentDefinition {
|
||||
for _, f := range l {
|
||||
if f.Name.Name == name {
|
||||
return f
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (InlineFragment) isSelection() {}
|
||||
func (FragmentSpread) isSelection() {}
|
47
vendor/github.com/graph-gophers/graphql-go/types/input.go
generated
vendored
Normal file
47
vendor/github.com/graph-gophers/graphql-go/types/input.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
package types
|
||||
|
||||
import "github.com/graph-gophers/graphql-go/errors"
|
||||
|
||||
// InputValueDefinition is a representation of the GraphQL InputValueDefinition.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#InputValueDefinition
|
||||
type InputValueDefinition struct {
|
||||
Name Ident
|
||||
Type Type
|
||||
Default Value
|
||||
Desc string
|
||||
Directives DirectiveList
|
||||
Loc errors.Location
|
||||
TypeLoc errors.Location
|
||||
}
|
||||
|
||||
type InputValueDefinitionList []*InputValueDefinition
|
||||
|
||||
// Returns an InputValueDefinition by name or nil if not found.
|
||||
func (l InputValueDefinitionList) Get(name string) *InputValueDefinition {
|
||||
for _, v := range l {
|
||||
if v.Name.Name == name {
|
||||
return v
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InputObject types define a set of input fields; the input fields are either scalars, enums, or
|
||||
// other input objects.
|
||||
//
|
||||
// This allows arguments to accept arbitrarily complex structs.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#sec-Input-Objects
|
||||
type InputObject struct {
|
||||
Name string
|
||||
Desc string
|
||||
Values ArgumentsDefinition
|
||||
Directives DirectiveList
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
func (*InputObject) Kind() string { return "INPUT_OBJECT" }
|
||||
func (t *InputObject) String() string { return t.Name }
|
||||
func (t *InputObject) TypeName() string { return t.Name }
|
||||
func (t *InputObject) Description() string { return t.Desc }
|
25
vendor/github.com/graph-gophers/graphql-go/types/interface.go
generated
vendored
Normal file
25
vendor/github.com/graph-gophers/graphql-go/types/interface.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
package types
|
||||
|
||||
import "github.com/graph-gophers/graphql-go/errors"
|
||||
|
||||
// InterfaceTypeDefinition recusrively defines list of named fields with their arguments via the
|
||||
// implementation chain of interfaces.
|
||||
//
|
||||
// GraphQL objects can then implement these interfaces which requires that the object type will
|
||||
// define all fields defined by those interfaces.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#sec-Interfaces
|
||||
type InterfaceTypeDefinition struct {
|
||||
Name string
|
||||
PossibleTypes []*ObjectTypeDefinition
|
||||
Fields FieldsDefinition
|
||||
Desc string
|
||||
Directives DirectiveList
|
||||
Loc errors.Location
|
||||
Interfaces []*InterfaceTypeDefinition
|
||||
}
|
||||
|
||||
func (*InterfaceTypeDefinition) Kind() string { return "INTERFACE" }
|
||||
func (t *InterfaceTypeDefinition) String() string { return t.Name }
|
||||
func (t *InterfaceTypeDefinition) TypeName() string { return t.Name }
|
||||
func (t *InterfaceTypeDefinition) Description() string { return t.Desc }
|
25
vendor/github.com/graph-gophers/graphql-go/types/object.go
generated
vendored
Normal file
25
vendor/github.com/graph-gophers/graphql-go/types/object.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
package types
|
||||
|
||||
import "github.com/graph-gophers/graphql-go/errors"
|
||||
|
||||
// ObjectTypeDefinition represents a GraphQL ObjectTypeDefinition.
|
||||
//
|
||||
// type FooObject {
|
||||
// foo: String
|
||||
// }
|
||||
//
|
||||
// https://spec.graphql.org/draft/#sec-Objects
|
||||
type ObjectTypeDefinition struct {
|
||||
Name string
|
||||
Interfaces []*InterfaceTypeDefinition
|
||||
Fields FieldsDefinition
|
||||
Desc string
|
||||
Directives DirectiveList
|
||||
InterfaceNames []string
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
func (*ObjectTypeDefinition) Kind() string { return "OBJECT" }
|
||||
func (t *ObjectTypeDefinition) String() string { return t.Name }
|
||||
func (t *ObjectTypeDefinition) TypeName() string { return t.Name }
|
||||
func (t *ObjectTypeDefinition) Description() string { return t.Desc }
|
62
vendor/github.com/graph-gophers/graphql-go/types/query.go
generated
vendored
Normal file
62
vendor/github.com/graph-gophers/graphql-go/types/query.go
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
package types
|
||||
|
||||
import "github.com/graph-gophers/graphql-go/errors"
|
||||
|
||||
// ExecutableDefinition represents a set of operations or fragments that can be executed
|
||||
// against a schema.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#ExecutableDefinition
|
||||
type ExecutableDefinition struct {
|
||||
Operations OperationList
|
||||
Fragments FragmentList
|
||||
}
|
||||
|
||||
// OperationDefinition represents a GraphQL Operation.
|
||||
//
|
||||
// https://spec.graphql.org/draft/#sec-Language.Operations
|
||||
type OperationDefinition struct {
|
||||
Type OperationType
|
||||
Name Ident
|
||||
Vars ArgumentsDefinition
|
||||
Selections SelectionSet
|
||||
Directives DirectiveList
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
type OperationType string
|
||||
|
||||
// A Selection is a field requested in a GraphQL operation.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#Selection
|
||||
type Selection interface {
|
||||
isSelection()
|
||||
}
|
||||
|
||||
// A SelectionSet represents a collection of Selections
|
||||
//
|
||||
// http://spec.graphql.org/draft/#sec-Selection-Sets
|
||||
type SelectionSet []Selection
|
||||
|
||||
// Field represents a field used in a query.
|
||||
type Field struct {
|
||||
Alias Ident
|
||||
Name Ident
|
||||
Arguments ArgumentList
|
||||
Directives DirectiveList
|
||||
SelectionSet SelectionSet
|
||||
SelectionSetLoc errors.Location
|
||||
}
|
||||
|
||||
func (Field) isSelection() {}
|
||||
|
||||
type OperationList []*OperationDefinition
|
||||
|
||||
// Get returns an OperationDefinition by name or nil if not found.
|
||||
func (l OperationList) Get(name string) *OperationDefinition {
|
||||
for _, f := range l {
|
||||
if f.Name.Name == name {
|
||||
return f
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
22
vendor/github.com/graph-gophers/graphql-go/types/scalar.go
generated
vendored
Normal file
22
vendor/github.com/graph-gophers/graphql-go/types/scalar.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
package types
|
||||
|
||||
import "github.com/graph-gophers/graphql-go/errors"
|
||||
|
||||
// ScalarTypeDefinition types represent primitive leaf values (e.g. a string or an integer) in a GraphQL type
|
||||
// system.
|
||||
//
|
||||
// GraphQL responses take the form of a hierarchical tree; the leaves on these trees are GraphQL
|
||||
// scalars.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#sec-Scalars
|
||||
type ScalarTypeDefinition struct {
|
||||
Name string
|
||||
Desc string
|
||||
Directives DirectiveList
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
func (*ScalarTypeDefinition) Kind() string { return "SCALAR" }
|
||||
func (t *ScalarTypeDefinition) String() string { return t.Name }
|
||||
func (t *ScalarTypeDefinition) TypeName() string { return t.Name }
|
||||
func (t *ScalarTypeDefinition) Description() string { return t.Desc }
|
42
vendor/github.com/graph-gophers/graphql-go/types/schema.go
generated
vendored
Normal file
42
vendor/github.com/graph-gophers/graphql-go/types/schema.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
package types
|
||||
|
||||
// Schema represents a GraphQL service's collective type system capabilities.
|
||||
// A schema is defined in terms of the types and directives it supports as well as the root
|
||||
// operation types for each kind of operation: `query`, `mutation`, and `subscription`.
|
||||
//
|
||||
// For a more formal definition, read the relevant section in the specification:
|
||||
//
|
||||
// http://spec.graphql.org/draft/#sec-Schema
|
||||
type Schema struct {
|
||||
// EntryPoints determines the place in the type system where `query`, `mutation`, and
|
||||
// `subscription` operations begin.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#sec-Root-Operation-Types
|
||||
//
|
||||
EntryPoints map[string]NamedType
|
||||
|
||||
// Types are the fundamental unit of any GraphQL schema.
|
||||
// There are six kinds of named types, and two wrapping types.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#sec-Types
|
||||
Types map[string]NamedType
|
||||
|
||||
// Directives are used to annotate various parts of a GraphQL document as an indicator that they
|
||||
// should be evaluated differently by a validator, executor, or client tool such as a code
|
||||
// generator.
|
||||
//
|
||||
// http://spec.graphql.org/#sec-Type-System.Directives
|
||||
Directives map[string]*DirectiveDefinition
|
||||
|
||||
UseFieldResolvers bool
|
||||
|
||||
EntryPointNames map[string]string
|
||||
Objects []*ObjectTypeDefinition
|
||||
Unions []*Union
|
||||
Enums []*EnumTypeDefinition
|
||||
Extensions []*Extension
|
||||
}
|
||||
|
||||
func (s *Schema) Resolve(name string) Type {
|
||||
return s.Types[name]
|
||||
}
|
63
vendor/github.com/graph-gophers/graphql-go/types/types.go
generated
vendored
Normal file
63
vendor/github.com/graph-gophers/graphql-go/types/types.go
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/graph-gophers/graphql-go/errors"
|
||||
)
|
||||
|
||||
// TypeName is a base building block for GraphQL type references.
|
||||
type TypeName struct {
|
||||
Ident
|
||||
}
|
||||
|
||||
// NamedType represents a type with a name.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#NamedType
|
||||
type NamedType interface {
|
||||
Type
|
||||
TypeName() string
|
||||
Description() string
|
||||
}
|
||||
|
||||
type Ident struct {
|
||||
Name string
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
type Type interface {
|
||||
// Kind returns one possible GraphQL type kind. A type kind must be
|
||||
// valid as defined by the GraphQL spec.
|
||||
//
|
||||
// https://spec.graphql.org/draft/#sec-Type-Kinds
|
||||
Kind() string
|
||||
|
||||
// String serializes a Type into a GraphQL specification format type.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#sec-Serialization-Format
|
||||
String() string
|
||||
}
|
||||
|
||||
// List represents a GraphQL ListType.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#ListType
|
||||
type List struct {
|
||||
// OfType represents the inner-type of a List type.
|
||||
// For example, the List type `[Foo]` has an OfType of Foo.
|
||||
OfType Type
|
||||
}
|
||||
|
||||
// NonNull represents a GraphQL NonNullType.
|
||||
//
|
||||
// https://spec.graphql.org/draft/#NonNullType
|
||||
type NonNull struct {
|
||||
// OfType represents the inner-type of a NonNull type.
|
||||
// For example, the NonNull type `Foo!` has an OfType of Foo.
|
||||
OfType Type
|
||||
}
|
||||
|
||||
func (*List) Kind() string { return "LIST" }
|
||||
func (*NonNull) Kind() string { return "NON_NULL" }
|
||||
func (*TypeName) Kind() string { panic("TypeName needs to be resolved to actual type") }
|
||||
|
||||
func (t *List) String() string { return "[" + t.OfType.String() + "]" }
|
||||
func (t *NonNull) String() string { return t.OfType.String() + "!" }
|
||||
func (*TypeName) String() string { panic("TypeName needs to be resolved to actual type") }
|
24
vendor/github.com/graph-gophers/graphql-go/types/union.go
generated
vendored
Normal file
24
vendor/github.com/graph-gophers/graphql-go/types/union.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
package types
|
||||
|
||||
import "github.com/graph-gophers/graphql-go/errors"
|
||||
|
||||
// Union types represent objects that could be one of a list of GraphQL object types, but provides no
|
||||
// guaranteed fields between those types.
|
||||
//
|
||||
// They also differ from interfaces in that object types declare what interfaces they implement, but
|
||||
// are not aware of what unions contain them.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#sec-Unions
|
||||
type Union struct {
|
||||
Name string
|
||||
UnionMemberTypes []*ObjectTypeDefinition
|
||||
Desc string
|
||||
Directives DirectiveList
|
||||
TypeNames []string
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
func (*Union) Kind() string { return "UNION" }
|
||||
func (t *Union) String() string { return t.Name }
|
||||
func (t *Union) TypeName() string { return t.Name }
|
||||
func (t *Union) Description() string { return t.Desc }
|
141
vendor/github.com/graph-gophers/graphql-go/types/value.go
generated
vendored
Normal file
141
vendor/github.com/graph-gophers/graphql-go/types/value.go
generated
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/scanner"
|
||||
|
||||
"github.com/graph-gophers/graphql-go/errors"
|
||||
)
|
||||
|
||||
// Value represents a literal input or literal default value in the GraphQL Specification.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#sec-Input-Values
|
||||
type Value interface {
|
||||
// Deserialize transforms a GraphQL specification format literal into a Go type.
|
||||
Deserialize(vars map[string]interface{}) interface{}
|
||||
|
||||
// String serializes a Value into a GraphQL specification format literal.
|
||||
String() string
|
||||
Location() errors.Location
|
||||
}
|
||||
|
||||
// PrimitiveValue represents one of the following GraphQL scalars: Int, Float,
|
||||
// String, or Boolean
|
||||
type PrimitiveValue struct {
|
||||
Type rune
|
||||
Text string
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
func (val *PrimitiveValue) Deserialize(vars map[string]interface{}) interface{} {
|
||||
switch val.Type {
|
||||
case scanner.Int:
|
||||
value, err := strconv.ParseInt(val.Text, 10, 32)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return int32(value)
|
||||
|
||||
case scanner.Float:
|
||||
value, err := strconv.ParseFloat(val.Text, 64)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return value
|
||||
|
||||
case scanner.String:
|
||||
value, err := strconv.Unquote(val.Text)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return value
|
||||
|
||||
case scanner.Ident:
|
||||
switch val.Text {
|
||||
case "true":
|
||||
return true
|
||||
case "false":
|
||||
return false
|
||||
default:
|
||||
return val.Text
|
||||
}
|
||||
|
||||
default:
|
||||
panic("invalid literal value")
|
||||
}
|
||||
}
|
||||
|
||||
func (val *PrimitiveValue) String() string { return val.Text }
|
||||
func (val *PrimitiveValue) Location() errors.Location { return val.Loc }
|
||||
|
||||
// ListValue represents a literal list Value in the GraphQL specification.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#sec-List-Value
|
||||
type ListValue struct {
|
||||
Values []Value
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
func (val *ListValue) Deserialize(vars map[string]interface{}) interface{} {
|
||||
entries := make([]interface{}, len(val.Values))
|
||||
for i, entry := range val.Values {
|
||||
entries[i] = entry.Deserialize(vars)
|
||||
}
|
||||
return entries
|
||||
}
|
||||
|
||||
func (val *ListValue) String() string {
|
||||
entries := make([]string, len(val.Values))
|
||||
for i, entry := range val.Values {
|
||||
entries[i] = entry.String()
|
||||
}
|
||||
return "[" + strings.Join(entries, ", ") + "]"
|
||||
}
|
||||
|
||||
func (val *ListValue) Location() errors.Location { return val.Loc }
|
||||
|
||||
// ObjectValue represents a literal object Value in the GraphQL specification.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#sec-Object-Value
|
||||
type ObjectValue struct {
|
||||
Fields []*ObjectField
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
// ObjectField represents field/value pairs in a literal ObjectValue.
|
||||
type ObjectField struct {
|
||||
Name Ident
|
||||
Value Value
|
||||
}
|
||||
|
||||
func (val *ObjectValue) Deserialize(vars map[string]interface{}) interface{} {
|
||||
fields := make(map[string]interface{}, len(val.Fields))
|
||||
for _, f := range val.Fields {
|
||||
fields[f.Name.Name] = f.Value.Deserialize(vars)
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
func (val *ObjectValue) String() string {
|
||||
entries := make([]string, 0, len(val.Fields))
|
||||
for _, f := range val.Fields {
|
||||
entries = append(entries, f.Name.Name+": "+f.Value.String())
|
||||
}
|
||||
return "{" + strings.Join(entries, ", ") + "}"
|
||||
}
|
||||
|
||||
func (val *ObjectValue) Location() errors.Location {
|
||||
return val.Loc
|
||||
}
|
||||
|
||||
// NullValue represents a literal `null` Value in the GraphQL specification.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#sec-Null-Value
|
||||
type NullValue struct {
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
func (val *NullValue) Deserialize(vars map[string]interface{}) interface{} { return nil }
|
||||
func (val *NullValue) String() string { return "null" }
|
||||
func (val *NullValue) Location() errors.Location { return val.Loc }
|
15
vendor/github.com/graph-gophers/graphql-go/types/variable.go
generated
vendored
Normal file
15
vendor/github.com/graph-gophers/graphql-go/types/variable.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
package types
|
||||
|
||||
import "github.com/graph-gophers/graphql-go/errors"
|
||||
|
||||
// Variable is used in GraphQL operations to parameterize an input value.
|
||||
//
|
||||
// http://spec.graphql.org/draft/#Variable
|
||||
type Variable struct {
|
||||
Name string
|
||||
Loc errors.Location
|
||||
}
|
||||
|
||||
func (v Variable) Deserialize(vars map[string]interface{}) interface{} { return vars[v.Name] }
|
||||
func (v Variable) String() string { return "$" + v.Name }
|
||||
func (v *Variable) Location() errors.Location { return v.Loc }
|
4
vendor/github.com/klauspost/cpuid/v2/README.md
generated
vendored
4
vendor/github.com/klauspost/cpuid/v2/README.md
generated
vendored
@ -39,10 +39,10 @@ func main() {
|
||||
fmt.Println("ThreadsPerCore:", CPU.ThreadsPerCore)
|
||||
fmt.Println("LogicalCores:", CPU.LogicalCores)
|
||||
fmt.Println("Family", CPU.Family, "Model:", CPU.Model, "Vendor ID:", CPU.VendorID)
|
||||
fmt.Println("Features:", fmt.Sprintf(strings.Join(CPU.FeatureSet(), ",")))
|
||||
fmt.Println("Features:", strings.Join(CPU.FeatureSet(), ","))
|
||||
fmt.Println("Cacheline bytes:", CPU.CacheLine)
|
||||
fmt.Println("L1 Data Cache:", CPU.Cache.L1D, "bytes")
|
||||
fmt.Println("L1 Instruction Cache:", CPU.Cache.L1D, "bytes")
|
||||
fmt.Println("L1 Instruction Cache:", CPU.Cache.L1I, "bytes")
|
||||
fmt.Println("L2 Cache:", CPU.Cache.L2, "bytes")
|
||||
fmt.Println("L3 Cache:", CPU.Cache.L3, "bytes")
|
||||
fmt.Println("Frequency", CPU.Hz, "hz")
|
||||
|
74
vendor/github.com/klauspost/cpuid/v2/cpuid.go
generated
vendored
74
vendor/github.com/klauspost/cpuid/v2/cpuid.go
generated
vendored
@ -95,10 +95,13 @@ const (
|
||||
AVXSLOW // Indicates the CPU performs 2 128 bit operations instead of one.
|
||||
BMI1 // Bit Manipulation Instruction Set 1
|
||||
BMI2 // Bit Manipulation Instruction Set 2
|
||||
CETIBT // Intel CET Indirect Branch Tracking
|
||||
CETSS // Intel CET Shadow Stack
|
||||
CLDEMOTE // Cache Line Demote
|
||||
CLMUL // Carry-less Multiplication
|
||||
CLZERO // CLZERO instruction supported
|
||||
CMOV // i686 CMOV
|
||||
CMPXCHG8 // CMPXCHG8 instruction
|
||||
CPBOOST // Core Performance Boost
|
||||
CX16 // CMPXCHG16B Instruction
|
||||
ENQCMD // Enqueue Command
|
||||
@ -106,6 +109,8 @@ const (
|
||||
F16C // Half-precision floating-point conversion
|
||||
FMA3 // Intel FMA 3. Does not imply AVX.
|
||||
FMA4 // Bulldozer FMA4 functions
|
||||
FXSR // FXSAVE, FXRESTOR instructions, CR4 bit 9
|
||||
FXSROPT // FXSAVE/FXRSTOR optimizations
|
||||
GFNI // Galois Field New Instructions
|
||||
HLE // Hardware Lock Elision
|
||||
HTT // Hyperthreading (enabled)
|
||||
@ -123,16 +128,19 @@ const (
|
||||
IBSRIPINVALIDCHK // Instruction Based Sampling Feature (AMD)
|
||||
INT_WBINVD // WBINVD/WBNOINVD are interruptible.
|
||||
INVLPGB // NVLPGB and TLBSYNC instruction supported
|
||||
LAHF // LAHF/SAHF in long mode
|
||||
LZCNT // LZCNT instruction
|
||||
MCAOVERFLOW // MCA overflow recovery support.
|
||||
MCOMMIT // MCOMMIT instruction supported
|
||||
MMX // standard MMX
|
||||
MMXEXT // SSE integer functions or AMD MMX ext
|
||||
MOVBE // MOVBE instruction (big-endian)
|
||||
MOVDIR64B // Move 64 Bytes as Direct Store
|
||||
MOVDIRI // Move Doubleword as Direct Store
|
||||
MPX // Intel MPX (Memory Protection Extensions)
|
||||
MSRIRC // Instruction Retired Counter MSR available
|
||||
NX // NX (No-Execute) bit
|
||||
OSXSAVE // XSAVE enabled by OS
|
||||
POPCNT // POPCNT instruction
|
||||
RDPRU // RDPRU instruction supported
|
||||
RDRAND // RDRAND instruction is available
|
||||
@ -140,6 +148,7 @@ const (
|
||||
RDTSCP // RDTSCP Instruction
|
||||
RTM // Restricted Transactional Memory
|
||||
RTM_ALWAYS_ABORT // Indicates that the loaded microcode is forcing RTM abort.
|
||||
SCE // SYSENTER and SYSEXIT instructions
|
||||
SERIALIZE // Serialize Instruction Execution
|
||||
SGX // Software Guard Extensions
|
||||
SGXLC // Software Guard Extensions Launch Control
|
||||
@ -160,7 +169,9 @@ const (
|
||||
VPCLMULQDQ // Carry-Less Multiplication Quadword
|
||||
WAITPKG // TPAUSE, UMONITOR, UMWAIT
|
||||
WBNOINVD // Write Back and Do Not Invalidate Cache
|
||||
X87 // FPU
|
||||
XOP // Bulldozer XOP functions
|
||||
XSAVE // XSAVE, XRESTOR, XSETBV, XGETBV
|
||||
|
||||
// ARM features:
|
||||
AESARM // AES instructions
|
||||
@ -311,6 +322,31 @@ func (c CPUInfo) Has(id FeatureID) bool {
|
||||
return c.featureSet.inSet(id)
|
||||
}
|
||||
|
||||
// https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels
|
||||
var level1Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SCE, SSE, SSE2)
|
||||
var level2Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SCE, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3)
|
||||
var level3Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SCE, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE)
|
||||
var level4Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SCE, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE, AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL)
|
||||
|
||||
// X64Level returns the microarchitecture level detected on the CPU.
|
||||
// If features are lacking or non x64 mode, 0 is returned.
|
||||
// See https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels
|
||||
func (c CPUInfo) X64Level() int {
|
||||
if c.featureSet.hasSet(level4Features) {
|
||||
return 4
|
||||
}
|
||||
if c.featureSet.hasSet(level3Features) {
|
||||
return 3
|
||||
}
|
||||
if c.featureSet.hasSet(level2Features) {
|
||||
return 2
|
||||
}
|
||||
if c.featureSet.hasSet(level1Features) {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Disable will disable one or several features.
|
||||
func (c *CPUInfo) Disable(ids ...FeatureID) bool {
|
||||
for _, id := range ids {
|
||||
@ -335,9 +371,7 @@ func (c CPUInfo) IsVendor(v Vendor) bool {
|
||||
|
||||
func (c CPUInfo) FeatureSet() []string {
|
||||
s := make([]string, 0)
|
||||
for _, f := range c.featureSet.Strings() {
|
||||
s = append(s, f)
|
||||
}
|
||||
s = append(s, c.featureSet.Strings()...)
|
||||
return s
|
||||
}
|
||||
|
||||
@ -499,6 +533,24 @@ func (s *flagSet) or(other flagSet) {
|
||||
}
|
||||
}
|
||||
|
||||
// hasSet returns whether all features are present.
|
||||
func (s flagSet) hasSet(other flagSet) bool {
|
||||
for i, v := range other[:] {
|
||||
if s[i]&v != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func flagSetWith(feat ...FeatureID) flagSet {
|
||||
var res flagSet
|
||||
for _, f := range feat {
|
||||
res.set(f)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// ParseFeature will parse the string and return the ID of the matching feature.
|
||||
// Will return UNKNOWN if not found.
|
||||
func ParseFeature(s string) FeatureID {
|
||||
@ -708,6 +760,7 @@ func (c *CPUInfo) cacheSize() {
|
||||
if maxFunctionID() < 4 {
|
||||
return
|
||||
}
|
||||
c.Cache.L1I, c.Cache.L1D, c.Cache.L2, c.Cache.L3 = 0, 0, 0, 0
|
||||
for i := uint32(0); ; i++ {
|
||||
eax, ebx, ecx, _ := cpuidex(4, i)
|
||||
cacheType := eax & 15
|
||||
@ -800,8 +853,6 @@ func (c *CPUInfo) cacheSize() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type SGXEPCSection struct {
|
||||
@ -865,9 +916,14 @@ func support() flagSet {
|
||||
family, model := familyModel()
|
||||
|
||||
_, _, c, d := cpuid(1)
|
||||
fs.setIf((d&(1<<0)) != 0, X87)
|
||||
fs.setIf((d&(1<<8)) != 0, CMPXCHG8)
|
||||
fs.setIf((d&(1<<11)) != 0, SCE)
|
||||
fs.setIf((d&(1<<15)) != 0, CMOV)
|
||||
fs.setIf((d&(1<<22)) != 0, MMXEXT)
|
||||
fs.setIf((d&(1<<23)) != 0, MMX)
|
||||
fs.setIf((d&(1<<25)) != 0, MMXEXT)
|
||||
fs.setIf((d&(1<<24)) != 0, FXSR)
|
||||
fs.setIf((d&(1<<25)) != 0, FXSROPT)
|
||||
fs.setIf((d&(1<<25)) != 0, SSE)
|
||||
fs.setIf((d&(1<<26)) != 0, SSE2)
|
||||
fs.setIf((c&1) != 0, SSE3)
|
||||
@ -877,6 +933,7 @@ func support() flagSet {
|
||||
fs.setIf((c&0x00100000) != 0, SSE42)
|
||||
fs.setIf((c&(1<<25)) != 0, AESNI)
|
||||
fs.setIf((c&(1<<1)) != 0, CLMUL)
|
||||
fs.setIf(c&(1<<22) != 0, MOVBE)
|
||||
fs.setIf(c&(1<<23) != 0, POPCNT)
|
||||
fs.setIf(c&(1<<30) != 0, RDRAND)
|
||||
|
||||
@ -892,6 +949,8 @@ func support() flagSet {
|
||||
if vend == AMD && (d&(1<<28)) != 0 && mfi >= 4 {
|
||||
fs.setIf(threadsPerCore() > 1, HTT)
|
||||
}
|
||||
fs.setIf(c&1<<26 != 0, XSAVE)
|
||||
fs.setIf(c&1<<27 != 0, OSXSAVE)
|
||||
// Check XGETBV/XSAVE (26), OXSAVE (27) and AVX (28) bits
|
||||
const avxCheck = 1<<26 | 1<<27 | 1<<28
|
||||
if c&avxCheck == avxCheck {
|
||||
@ -936,6 +995,7 @@ func support() flagSet {
|
||||
fs.setIf(ebx&(1<<29) != 0, SHA)
|
||||
// CPUID.(EAX=7, ECX=0).ECX
|
||||
fs.setIf(ecx&(1<<5) != 0, WAITPKG)
|
||||
fs.setIf(ecx&(1<<7) != 0, CETSS)
|
||||
fs.setIf(ecx&(1<<25) != 0, CLDEMOTE)
|
||||
fs.setIf(ecx&(1<<27) != 0, MOVDIRI)
|
||||
fs.setIf(ecx&(1<<28) != 0, MOVDIR64B)
|
||||
@ -945,6 +1005,7 @@ func support() flagSet {
|
||||
fs.setIf(edx&(1<<11) != 0, RTM_ALWAYS_ABORT)
|
||||
fs.setIf(edx&(1<<14) != 0, SERIALIZE)
|
||||
fs.setIf(edx&(1<<16) != 0, TSXLDTRK)
|
||||
fs.setIf(edx&(1<<20) != 0, CETIBT)
|
||||
fs.setIf(edx&(1<<26) != 0, IBPB)
|
||||
fs.setIf(edx&(1<<27) != 0, STIBP)
|
||||
|
||||
@ -996,6 +1057,7 @@ func support() flagSet {
|
||||
fs.set(LZCNT)
|
||||
fs.set(POPCNT)
|
||||
}
|
||||
fs.setIf((c&(1<<0)) != 0, LAHF)
|
||||
fs.setIf((c&(1<<10)) != 0, IBS)
|
||||
fs.setIf((d&(1<<31)) != 0, AMD3DNOW)
|
||||
fs.setIf((d&(1<<30)) != 0, AMD3DNOWEXT)
|
||||
|
3
vendor/github.com/klauspost/cpuid/v2/detect_arm64.go
generated
vendored
3
vendor/github.com/klauspost/cpuid/v2/detect_arm64.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file.
|
||||
|
||||
//+build arm64,!gccgo,!noasm,!appengine
|
||||
//go:build arm64 && !gccgo && !noasm && !appengine
|
||||
// +build arm64,!gccgo,!noasm,!appengine
|
||||
|
||||
package cpuid
|
||||
|
||||
|
3
vendor/github.com/klauspost/cpuid/v2/detect_ref.go
generated
vendored
3
vendor/github.com/klauspost/cpuid/v2/detect_ref.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file.
|
||||
|
||||
//+build !amd64,!386,!arm64 gccgo noasm appengine
|
||||
//go:build (!amd64 && !386 && !arm64) || gccgo || noasm || appengine
|
||||
// +build !amd64,!386,!arm64 gccgo noasm appengine
|
||||
|
||||
package cpuid
|
||||
|
||||
|
3
vendor/github.com/klauspost/cpuid/v2/detect_x86.go
generated
vendored
3
vendor/github.com/klauspost/cpuid/v2/detect_x86.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file.
|
||||
|
||||
//+build 386,!gccgo,!noasm,!appengine amd64,!gccgo,!noasm,!appengine
|
||||
//go:build (386 && !gccgo && !noasm && !appengine) || (amd64 && !gccgo && !noasm && !appengine)
|
||||
// +build 386,!gccgo,!noasm,!appengine amd64,!gccgo,!noasm,!appengine
|
||||
|
||||
package cpuid
|
||||
|
||||
|
197
vendor/github.com/klauspost/cpuid/v2/featureid_string.go
generated
vendored
197
vendor/github.com/klauspost/cpuid/v2/featureid_string.go
generated
vendored
@ -36,103 +36,114 @@ func _() {
|
||||
_ = x[AVXSLOW-26]
|
||||
_ = x[BMI1-27]
|
||||
_ = x[BMI2-28]
|
||||
_ = x[CLDEMOTE-29]
|
||||
_ = x[CLMUL-30]
|
||||
_ = x[CLZERO-31]
|
||||
_ = x[CMOV-32]
|
||||
_ = x[CPBOOST-33]
|
||||
_ = x[CX16-34]
|
||||
_ = x[ENQCMD-35]
|
||||
_ = x[ERMS-36]
|
||||
_ = x[F16C-37]
|
||||
_ = x[FMA3-38]
|
||||
_ = x[FMA4-39]
|
||||
_ = x[GFNI-40]
|
||||
_ = x[HLE-41]
|
||||
_ = x[HTT-42]
|
||||
_ = x[HWA-43]
|
||||
_ = x[HYPERVISOR-44]
|
||||
_ = x[IBPB-45]
|
||||
_ = x[IBS-46]
|
||||
_ = x[IBSBRNTRGT-47]
|
||||
_ = x[IBSFETCHSAM-48]
|
||||
_ = x[IBSFFV-49]
|
||||
_ = x[IBSOPCNT-50]
|
||||
_ = x[IBSOPCNTEXT-51]
|
||||
_ = x[IBSOPSAM-52]
|
||||
_ = x[IBSRDWROPCNT-53]
|
||||
_ = x[IBSRIPINVALIDCHK-54]
|
||||
_ = x[INT_WBINVD-55]
|
||||
_ = x[INVLPGB-56]
|
||||
_ = x[LZCNT-57]
|
||||
_ = x[MCAOVERFLOW-58]
|
||||
_ = x[MCOMMIT-59]
|
||||
_ = x[MMX-60]
|
||||
_ = x[MMXEXT-61]
|
||||
_ = x[MOVDIR64B-62]
|
||||
_ = x[MOVDIRI-63]
|
||||
_ = x[MPX-64]
|
||||
_ = x[MSRIRC-65]
|
||||
_ = x[NX-66]
|
||||
_ = x[POPCNT-67]
|
||||
_ = x[RDPRU-68]
|
||||
_ = x[RDRAND-69]
|
||||
_ = x[RDSEED-70]
|
||||
_ = x[RDTSCP-71]
|
||||
_ = x[RTM-72]
|
||||
_ = x[RTM_ALWAYS_ABORT-73]
|
||||
_ = x[SERIALIZE-74]
|
||||
_ = x[SGX-75]
|
||||
_ = x[SGXLC-76]
|
||||
_ = x[SHA-77]
|
||||
_ = x[SSE-78]
|
||||
_ = x[SSE2-79]
|
||||
_ = x[SSE3-80]
|
||||
_ = x[SSE4-81]
|
||||
_ = x[SSE42-82]
|
||||
_ = x[SSE4A-83]
|
||||
_ = x[SSSE3-84]
|
||||
_ = x[STIBP-85]
|
||||
_ = x[SUCCOR-86]
|
||||
_ = x[TBM-87]
|
||||
_ = x[TSXLDTRK-88]
|
||||
_ = x[VAES-89]
|
||||
_ = x[VMX-90]
|
||||
_ = x[VPCLMULQDQ-91]
|
||||
_ = x[WAITPKG-92]
|
||||
_ = x[WBNOINVD-93]
|
||||
_ = x[XOP-94]
|
||||
_ = x[AESARM-95]
|
||||
_ = x[ARMCPUID-96]
|
||||
_ = x[ASIMD-97]
|
||||
_ = x[ASIMDDP-98]
|
||||
_ = x[ASIMDHP-99]
|
||||
_ = x[ASIMDRDM-100]
|
||||
_ = x[ATOMICS-101]
|
||||
_ = x[CRC32-102]
|
||||
_ = x[DCPOP-103]
|
||||
_ = x[EVTSTRM-104]
|
||||
_ = x[FCMA-105]
|
||||
_ = x[FP-106]
|
||||
_ = x[FPHP-107]
|
||||
_ = x[GPA-108]
|
||||
_ = x[JSCVT-109]
|
||||
_ = x[LRCPC-110]
|
||||
_ = x[PMULL-111]
|
||||
_ = x[SHA1-112]
|
||||
_ = x[SHA2-113]
|
||||
_ = x[SHA3-114]
|
||||
_ = x[SHA512-115]
|
||||
_ = x[SM3-116]
|
||||
_ = x[SM4-117]
|
||||
_ = x[SVE-118]
|
||||
_ = x[lastID-119]
|
||||
_ = x[CETIBT-29]
|
||||
_ = x[CETSS-30]
|
||||
_ = x[CLDEMOTE-31]
|
||||
_ = x[CLMUL-32]
|
||||
_ = x[CLZERO-33]
|
||||
_ = x[CMOV-34]
|
||||
_ = x[CMPXCHG8-35]
|
||||
_ = x[CPBOOST-36]
|
||||
_ = x[CX16-37]
|
||||
_ = x[ENQCMD-38]
|
||||
_ = x[ERMS-39]
|
||||
_ = x[F16C-40]
|
||||
_ = x[FMA3-41]
|
||||
_ = x[FMA4-42]
|
||||
_ = x[FXSR-43]
|
||||
_ = x[FXSROPT-44]
|
||||
_ = x[GFNI-45]
|
||||
_ = x[HLE-46]
|
||||
_ = x[HTT-47]
|
||||
_ = x[HWA-48]
|
||||
_ = x[HYPERVISOR-49]
|
||||
_ = x[IBPB-50]
|
||||
_ = x[IBS-51]
|
||||
_ = x[IBSBRNTRGT-52]
|
||||
_ = x[IBSFETCHSAM-53]
|
||||
_ = x[IBSFFV-54]
|
||||
_ = x[IBSOPCNT-55]
|
||||
_ = x[IBSOPCNTEXT-56]
|
||||
_ = x[IBSOPSAM-57]
|
||||
_ = x[IBSRDWROPCNT-58]
|
||||
_ = x[IBSRIPINVALIDCHK-59]
|
||||
_ = x[INT_WBINVD-60]
|
||||
_ = x[INVLPGB-61]
|
||||
_ = x[LAHF-62]
|
||||
_ = x[LZCNT-63]
|
||||
_ = x[MCAOVERFLOW-64]
|
||||
_ = x[MCOMMIT-65]
|
||||
_ = x[MMX-66]
|
||||
_ = x[MMXEXT-67]
|
||||
_ = x[MOVBE-68]
|
||||
_ = x[MOVDIR64B-69]
|
||||
_ = x[MOVDIRI-70]
|
||||
_ = x[MPX-71]
|
||||
_ = x[MSRIRC-72]
|
||||
_ = x[NX-73]
|
||||
_ = x[OSXSAVE-74]
|
||||
_ = x[POPCNT-75]
|
||||
_ = x[RDPRU-76]
|
||||
_ = x[RDRAND-77]
|
||||
_ = x[RDSEED-78]
|
||||
_ = x[RDTSCP-79]
|
||||
_ = x[RTM-80]
|
||||
_ = x[RTM_ALWAYS_ABORT-81]
|
||||
_ = x[SCE-82]
|
||||
_ = x[SERIALIZE-83]
|
||||
_ = x[SGX-84]
|
||||
_ = x[SGXLC-85]
|
||||
_ = x[SHA-86]
|
||||
_ = x[SSE-87]
|
||||
_ = x[SSE2-88]
|
||||
_ = x[SSE3-89]
|
||||
_ = x[SSE4-90]
|
||||
_ = x[SSE42-91]
|
||||
_ = x[SSE4A-92]
|
||||
_ = x[SSSE3-93]
|
||||
_ = x[STIBP-94]
|
||||
_ = x[SUCCOR-95]
|
||||
_ = x[TBM-96]
|
||||
_ = x[TSXLDTRK-97]
|
||||
_ = x[VAES-98]
|
||||
_ = x[VMX-99]
|
||||
_ = x[VPCLMULQDQ-100]
|
||||
_ = x[WAITPKG-101]
|
||||
_ = x[WBNOINVD-102]
|
||||
_ = x[X87-103]
|
||||
_ = x[XOP-104]
|
||||
_ = x[XSAVE-105]
|
||||
_ = x[AESARM-106]
|
||||
_ = x[ARMCPUID-107]
|
||||
_ = x[ASIMD-108]
|
||||
_ = x[ASIMDDP-109]
|
||||
_ = x[ASIMDHP-110]
|
||||
_ = x[ASIMDRDM-111]
|
||||
_ = x[ATOMICS-112]
|
||||
_ = x[CRC32-113]
|
||||
_ = x[DCPOP-114]
|
||||
_ = x[EVTSTRM-115]
|
||||
_ = x[FCMA-116]
|
||||
_ = x[FP-117]
|
||||
_ = x[FPHP-118]
|
||||
_ = x[GPA-119]
|
||||
_ = x[JSCVT-120]
|
||||
_ = x[LRCPC-121]
|
||||
_ = x[PMULL-122]
|
||||
_ = x[SHA1-123]
|
||||
_ = x[SHA2-124]
|
||||
_ = x[SHA3-125]
|
||||
_ = x[SHA512-126]
|
||||
_ = x[SM3-127]
|
||||
_ = x[SM4-128]
|
||||
_ = x[SVE-129]
|
||||
_ = x[lastID-130]
|
||||
_ = x[firstID-0]
|
||||
}
|
||||
|
||||
const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXINT8AMXTILEAVXAVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXSLOWBMI1BMI2CLDEMOTECLMULCLZEROCMOVCPBOOSTCX16ENQCMDERMSF16CFMA3FMA4GFNIHLEHTTHWAHYPERVISORIBPBIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKINT_WBINVDINVLPGBLZCNTMCAOVERFLOWMCOMMITMMXMMXEXTMOVDIR64BMOVDIRIMPXMSRIRCNXPOPCNTRDPRURDRANDRDSEEDRDTSCPRTMRTM_ALWAYS_ABORTSERIALIZESGXSGXLCSHASSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSUCCORTBMTSXLDTRKVAESVMXVPCLMULQDQWAITPKGWBNOINVDXOPAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFPFPHPGPAJSCVTLRCPCPMULLSHA1SHA2SHA3SHA512SM3SM4SVElastID"
|
||||
const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXINT8AMXTILEAVXAVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXSLOWBMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPXCHG8CPBOOSTCX16ENQCMDERMSF16CFMA3FMA4FXSRFXSROPTGFNIHLEHTTHWAHYPERVISORIBPBIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKINT_WBINVDINVLPGBLAHFLZCNTMCAOVERFLOWMCOMMITMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMPXMSRIRCNXOSXSAVEPOPCNTRDPRURDRANDRDSEEDRDTSCPRTMRTM_ALWAYS_ABORTSCESERIALIZESGXSGXLCSHASSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSUCCORTBMTSXLDTRKVAESVMXVPCLMULQDQWAITPKGWBNOINVDX87XOPXSAVEAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFPFPHPGPAJSCVTLRCPCPMULLSHA1SHA2SHA3SHA512SM3SM4SVElastID"
|
||||
|
||||
var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 58, 62, 72, 84, 92, 100, 108, 116, 123, 133, 143, 151, 161, 172, 180, 190, 208, 223, 230, 234, 238, 246, 251, 257, 261, 268, 272, 278, 282, 286, 290, 294, 298, 301, 304, 307, 317, 321, 324, 334, 345, 351, 359, 370, 378, 390, 406, 416, 423, 428, 439, 446, 449, 455, 464, 471, 474, 480, 482, 488, 493, 499, 505, 511, 514, 530, 539, 542, 547, 550, 553, 557, 561, 565, 570, 575, 580, 585, 591, 594, 602, 606, 609, 619, 626, 634, 637, 643, 651, 656, 663, 670, 678, 685, 690, 695, 702, 706, 708, 712, 715, 720, 725, 730, 734, 738, 742, 748, 751, 754, 757, 763}
|
||||
var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 58, 62, 72, 84, 92, 100, 108, 116, 123, 133, 143, 151, 161, 172, 180, 190, 208, 223, 230, 234, 238, 244, 249, 257, 262, 268, 272, 280, 287, 291, 297, 301, 305, 309, 313, 317, 324, 328, 331, 334, 337, 347, 351, 354, 364, 375, 381, 389, 400, 408, 420, 436, 446, 453, 457, 462, 473, 480, 483, 489, 494, 503, 510, 513, 519, 521, 528, 534, 539, 545, 551, 557, 560, 576, 579, 588, 591, 596, 599, 602, 606, 610, 614, 619, 624, 629, 634, 640, 643, 651, 655, 658, 668, 675, 683, 686, 689, 694, 700, 708, 713, 720, 727, 735, 742, 747, 752, 759, 763, 765, 769, 772, 777, 782, 787, 791, 795, 799, 805, 808, 811, 814, 820}
|
||||
|
||||
func (i FeatureID) String() string {
|
||||
if i < 0 || i >= FeatureID(len(_FeatureID_index)-1) {
|
||||
|
5
vendor/github.com/klauspost/cpuid/v2/os_other_arm64.go
generated
vendored
5
vendor/github.com/klauspost/cpuid/v2/os_other_arm64.go
generated
vendored
@ -1,8 +1,7 @@
|
||||
// Copyright (c) 2020 Klaus Post, released under MIT License. See LICENSE file.
|
||||
|
||||
// +build arm64
|
||||
// +build !linux
|
||||
// +build !darwin
|
||||
//go:build arm64 && !linux && !darwin
|
||||
// +build arm64,!linux,!darwin
|
||||
|
||||
package cpuid
|
||||
|
||||
|
3
vendor/github.com/klauspost/cpuid/v2/os_safe_linux_arm64.go
generated
vendored
3
vendor/github.com/klauspost/cpuid/v2/os_safe_linux_arm64.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2021 Klaus Post, released under MIT License. See LICENSE file.
|
||||
|
||||
//+build nounsafe
|
||||
//go:build nounsafe
|
||||
// +build nounsafe
|
||||
|
||||
package cpuid
|
||||
|
||||
|
3
vendor/github.com/klauspost/cpuid/v2/os_unsafe_linux_arm64.go
generated
vendored
3
vendor/github.com/klauspost/cpuid/v2/os_unsafe_linux_arm64.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2021 Klaus Post, released under MIT License. See LICENSE file.
|
||||
|
||||
//+build !nounsafe
|
||||
//go:build !nounsafe
|
||||
// +build !nounsafe
|
||||
|
||||
package cpuid
|
||||
|
||||
|
24
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
24
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
@ -1,5 +1,29 @@
|
||||
# Changelog
|
||||
|
||||
## v4.7.2 - 2022-03-16
|
||||
|
||||
**Fixes**
|
||||
|
||||
* Fix nil pointer exception when calling Start again after address binding error [#2131](https://github.com/labstack/echo/pull/2131)
|
||||
* Fix CSRF middleware not being able to extract token from multipart/form-data form [#2136](https://github.com/labstack/echo/pull/2136)
|
||||
* Fix Timeout middleware write race [#2126](https://github.com/labstack/echo/pull/2126)
|
||||
|
||||
**Enhancements**
|
||||
|
||||
* Recover middleware should not log panic for aborted handler [#2134](https://github.com/labstack/echo/pull/2134)
|
||||
|
||||
|
||||
## v4.7.1 - 2022-03-13
|
||||
|
||||
**Fixes**
|
||||
|
||||
* Fix `e.Static`, `.File()`, `c.Attachment()` being picky with paths starting with `./`, `../` and `/` after 4.7.0 introduced echo.Filesystem support (Go1.16+) [#2123](https://github.com/labstack/echo/pull/2123)
|
||||
|
||||
**Enhancements**
|
||||
|
||||
* Remove some unused code [#2116](https://github.com/labstack/echo/pull/2116)
|
||||
|
||||
|
||||
## v4.7.0 - 2022-03-01
|
||||
|
||||
**Enhancements**
|
||||
|
12
vendor/github.com/labstack/echo/v4/echo.go
generated
vendored
12
vendor/github.com/labstack/echo/v4/echo.go
generated
vendored
@ -246,7 +246,7 @@ const (
|
||||
|
||||
const (
|
||||
// Version of Echo
|
||||
Version = "4.7.0"
|
||||
Version = "4.7.2"
|
||||
website = "https://echo.labstack.com"
|
||||
// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
|
||||
banner = `
|
||||
@ -732,7 +732,7 @@ func (e *Echo) StartServer(s *http.Server) (err error) {
|
||||
return s.Serve(e.Listener)
|
||||
}
|
||||
|
||||
func (e *Echo) configureServer(s *http.Server) (err error) {
|
||||
func (e *Echo) configureServer(s *http.Server) error {
|
||||
// Setup
|
||||
e.colorer.SetOutput(e.Logger.Output())
|
||||
s.ErrorLog = e.StdLogger
|
||||
@ -747,10 +747,11 @@ func (e *Echo) configureServer(s *http.Server) (err error) {
|
||||
|
||||
if s.TLSConfig == nil {
|
||||
if e.Listener == nil {
|
||||
e.Listener, err = newListener(s.Addr, e.ListenerNetwork)
|
||||
l, err := newListener(s.Addr, e.ListenerNetwork)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e.Listener = l
|
||||
}
|
||||
if !e.HidePort {
|
||||
e.colorer.Printf("⇨ http server started on %s\n", e.colorer.Green(e.Listener.Addr()))
|
||||
@ -791,7 +792,7 @@ func (e *Echo) TLSListenerAddr() net.Addr {
|
||||
}
|
||||
|
||||
// StartH2CServer starts a custom http/2 server with h2c (HTTP/2 Cleartext).
|
||||
func (e *Echo) StartH2CServer(address string, h2s *http2.Server) (err error) {
|
||||
func (e *Echo) StartH2CServer(address string, h2s *http2.Server) error {
|
||||
e.startupMutex.Lock()
|
||||
// Setup
|
||||
s := e.Server
|
||||
@ -808,11 +809,12 @@ func (e *Echo) StartH2CServer(address string, h2s *http2.Server) (err error) {
|
||||
}
|
||||
|
||||
if e.Listener == nil {
|
||||
e.Listener, err = newListener(s.Addr, e.ListenerNetwork)
|
||||
l, err := newListener(s.Addr, e.ListenerNetwork)
|
||||
if err != nil {
|
||||
e.startupMutex.Unlock()
|
||||
return err
|
||||
}
|
||||
e.Listener = l
|
||||
}
|
||||
if !e.HidePort {
|
||||
e.colorer.Printf("⇨ http server started on %s\n", e.colorer.Green(e.Listener.Addr()))
|
||||
|
40
vendor/github.com/labstack/echo/v4/echo_fs_go1.16.go
generated
vendored
40
vendor/github.com/labstack/echo/v4/echo_fs_go1.16.go
generated
vendored
@ -10,6 +10,7 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -94,10 +95,12 @@ func StaticFileHandler(file string, filesystem fs.FS) HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// defaultFS emulates os.Open behaviour with filesystem opened by `os.DirFs`. Difference between `os.Open` and `fs.Open`
|
||||
// is that FS does not allow to open path that start with `..` or `/` etc. For example previously you could have `../images`
|
||||
// in your application but `fs := os.DirFS("./")` would not allow you to use `fs.Open("../images")` and this would break
|
||||
// all old applications that rely on being able to traverse up from current executable run path.
|
||||
// defaultFS exists to preserve pre v4.7.0 behaviour where files were open by `os.Open`.
|
||||
// v4.7 introduced `echo.Filesystem` field which is Go1.16+ `fs.Fs` interface.
|
||||
// Difference between `os.Open` and `fs.Open` is that FS does not allow opening path that start with `.`, `..` or `/`
|
||||
// etc. For example previously you could have `../images` in your application but `fs := os.DirFS("./")` would not
|
||||
// allow you to use `fs.Open("../images")` and this would break all old applications that rely on being able to
|
||||
// traverse up from current executable run path.
|
||||
// NB: private because you really should use fs.FS implementation instances
|
||||
type defaultFS struct {
|
||||
prefix string
|
||||
@ -108,20 +111,26 @@ func newDefaultFS() *defaultFS {
|
||||
dir, _ := os.Getwd()
|
||||
return &defaultFS{
|
||||
prefix: dir,
|
||||
fs: os.DirFS(dir),
|
||||
fs: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func (fs defaultFS) Open(name string) (fs.File, error) {
|
||||
if fs.fs == nil {
|
||||
return os.Open(name)
|
||||
}
|
||||
return fs.fs.Open(name)
|
||||
}
|
||||
|
||||
func subFS(currentFs fs.FS, root string) (fs.FS, error) {
|
||||
root = filepath.ToSlash(filepath.Clean(root)) // note: fs.FS operates only with slashes. `ToSlash` is necessary for Windows
|
||||
if dFS, ok := currentFs.(*defaultFS); ok {
|
||||
// we need to make exception for `defaultFS` instances as it interprets root prefix differently from fs.FS to
|
||||
// allow cases when root is given as `../somepath` which is not valid for fs.FS
|
||||
root = filepath.Join(dFS.prefix, root)
|
||||
// we need to make exception for `defaultFS` instances as it interprets root prefix differently from fs.FS.
|
||||
// fs.Fs.Open does not like relative paths ("./", "../") and absolute paths at all but prior echo.Filesystem we
|
||||
// were able to use paths like `./myfile.log`, `/etc/hosts` and these would work fine with `os.Open` but not with fs.Fs
|
||||
if isRelativePath(root) {
|
||||
root = filepath.Join(dFS.prefix, root)
|
||||
}
|
||||
return &defaultFS{
|
||||
prefix: root,
|
||||
fs: os.DirFS(root),
|
||||
@ -130,6 +139,21 @@ func subFS(currentFs fs.FS, root string) (fs.FS, error) {
|
||||
return fs.Sub(currentFs, root)
|
||||
}
|
||||
|
||||
func isRelativePath(path string) bool {
|
||||
if path == "" {
|
||||
return true
|
||||
}
|
||||
if path[0] == '/' {
|
||||
return false
|
||||
}
|
||||
if runtime.GOOS == "windows" && strings.IndexByte(path, ':') != -1 {
|
||||
// https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN#file_and_directory_names
|
||||
// https://docs.microsoft.com/en-us/dotnet/standard/io/file-path-formats
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// MustSubFS creates sub FS from current filesystem or panic on failure.
|
||||
// Panic happens when `fsRoot` contains invalid path according to `fs.ValidPath` rules.
|
||||
//
|
||||
|
4
vendor/github.com/labstack/echo/v4/middleware/extractor.go
generated
vendored
4
vendor/github.com/labstack/echo/v4/middleware/extractor.go
generated
vendored
@ -168,8 +168,8 @@ func valuesFromCookie(name string) ValuesExtractor {
|
||||
// valuesFromForm returns a function that extracts values from the form field.
|
||||
func valuesFromForm(name string) ValuesExtractor {
|
||||
return func(c echo.Context) ([]string, error) {
|
||||
if parseErr := c.Request().ParseForm(); parseErr != nil {
|
||||
return nil, fmt.Errorf("valuesFromForm parse form failed: %w", parseErr)
|
||||
if c.Request().Form == nil {
|
||||
_ = c.Request().ParseMultipartForm(32 << 20) // same what `c.Request().FormValue(name)` does
|
||||
}
|
||||
values := c.Request().Form[name]
|
||||
if len(values) == 0 {
|
||||
|
4
vendor/github.com/labstack/echo/v4/middleware/recover.go
generated
vendored
4
vendor/github.com/labstack/echo/v4/middleware/recover.go
generated
vendored
@ -2,6 +2,7 @@ package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"runtime"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
@ -77,6 +78,9 @@ func RecoverWithConfig(config RecoverConfig) echo.MiddlewareFunc {
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
if r == http.ErrAbortHandler {
|
||||
panic(r)
|
||||
}
|
||||
err, ok := r.(error)
|
||||
if !ok {
|
||||
err = fmt.Errorf("%v", r)
|
||||
|
126
vendor/github.com/labstack/echo/v4/middleware/timeout.go
generated
vendored
126
vendor/github.com/labstack/echo/v4/middleware/timeout.go
generated
vendored
@ -2,10 +2,10 @@ package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
@ -55,29 +55,27 @@ import (
|
||||
// })
|
||||
//
|
||||
|
||||
type (
|
||||
// TimeoutConfig defines the config for Timeout middleware.
|
||||
TimeoutConfig struct {
|
||||
// Skipper defines a function to skip middleware.
|
||||
Skipper Skipper
|
||||
// TimeoutConfig defines the config for Timeout middleware.
|
||||
type TimeoutConfig struct {
|
||||
// Skipper defines a function to skip middleware.
|
||||
Skipper Skipper
|
||||
|
||||
// ErrorMessage is written to response on timeout in addition to http.StatusServiceUnavailable (503) status code
|
||||
// It can be used to define a custom timeout error message
|
||||
ErrorMessage string
|
||||
// ErrorMessage is written to response on timeout in addition to http.StatusServiceUnavailable (503) status code
|
||||
// It can be used to define a custom timeout error message
|
||||
ErrorMessage string
|
||||
|
||||
// OnTimeoutRouteErrorHandler is an error handler that is executed for error that was returned from wrapped route after
|
||||
// request timeouted and we already had sent the error code (503) and message response to the client.
|
||||
// NB: do not write headers/body inside this handler. The response has already been sent to the client and response writer
|
||||
// will not accept anything no more. If you want to know what actual route middleware timeouted use `c.Path()`
|
||||
OnTimeoutRouteErrorHandler func(err error, c echo.Context)
|
||||
// OnTimeoutRouteErrorHandler is an error handler that is executed for error that was returned from wrapped route after
|
||||
// request timeouted and we already had sent the error code (503) and message response to the client.
|
||||
// NB: do not write headers/body inside this handler. The response has already been sent to the client and response writer
|
||||
// will not accept anything no more. If you want to know what actual route middleware timeouted use `c.Path()`
|
||||
OnTimeoutRouteErrorHandler func(err error, c echo.Context)
|
||||
|
||||
// Timeout configures a timeout for the middleware, defaults to 0 for no timeout
|
||||
// NOTE: when difference between timeout duration and handler execution time is almost the same (in range of 100microseconds)
|
||||
// the result of timeout does not seem to be reliable - could respond timeout, could respond handler output
|
||||
// difference over 500microseconds (0.5millisecond) response seems to be reliable
|
||||
Timeout time.Duration
|
||||
}
|
||||
)
|
||||
// Timeout configures a timeout for the middleware, defaults to 0 for no timeout
|
||||
// NOTE: when difference between timeout duration and handler execution time is almost the same (in range of 100microseconds)
|
||||
// the result of timeout does not seem to be reliable - could respond timeout, could respond handler output
|
||||
// difference over 500microseconds (0.5millisecond) response seems to be reliable
|
||||
Timeout time.Duration
|
||||
}
|
||||
|
||||
var (
|
||||
// DefaultTimeoutConfig is the default Timeout middleware config.
|
||||
@ -94,10 +92,17 @@ func Timeout() echo.MiddlewareFunc {
|
||||
return TimeoutWithConfig(DefaultTimeoutConfig)
|
||||
}
|
||||
|
||||
// TimeoutWithConfig returns a Timeout middleware with config.
|
||||
// See: `Timeout()`.
|
||||
// TimeoutWithConfig returns a Timeout middleware with config or panics on invalid configuration.
|
||||
func TimeoutWithConfig(config TimeoutConfig) echo.MiddlewareFunc {
|
||||
// Defaults
|
||||
mw, err := config.ToMiddleware()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return mw
|
||||
}
|
||||
|
||||
// ToMiddleware converts Config to middleware or returns an error for invalid configuration
|
||||
func (config TimeoutConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
|
||||
if config.Skipper == nil {
|
||||
config.Skipper = DefaultTimeoutConfig.Skipper
|
||||
}
|
||||
@ -108,26 +113,29 @@ func TimeoutWithConfig(config TimeoutConfig) echo.MiddlewareFunc {
|
||||
return next(c)
|
||||
}
|
||||
|
||||
errChan := make(chan error, 1)
|
||||
handlerWrapper := echoHandlerFuncWrapper{
|
||||
writer: &ignorableWriter{ResponseWriter: c.Response().Writer},
|
||||
ctx: c,
|
||||
handler: next,
|
||||
errChan: make(chan error, 1),
|
||||
errChan: errChan,
|
||||
errHandler: config.OnTimeoutRouteErrorHandler,
|
||||
}
|
||||
handler := http.TimeoutHandler(handlerWrapper, config.Timeout, config.ErrorMessage)
|
||||
handler.ServeHTTP(c.Response().Writer, c.Request())
|
||||
handler.ServeHTTP(handlerWrapper.writer, c.Request())
|
||||
|
||||
select {
|
||||
case err := <-handlerWrapper.errChan:
|
||||
case err := <-errChan:
|
||||
return err
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
type echoHandlerFuncWrapper struct {
|
||||
writer *ignorableWriter
|
||||
ctx echo.Context
|
||||
handler echo.HandlerFunc
|
||||
errHandler func(err error, c echo.Context)
|
||||
@ -160,23 +168,53 @@ func (t echoHandlerFuncWrapper) ServeHTTP(rw http.ResponseWriter, r *http.Reques
|
||||
}
|
||||
return // on timeout we can not send handler error to client because `http.TimeoutHandler` has already sent headers
|
||||
}
|
||||
// we restore original writer only for cases we did not timeout. On timeout we have already sent response to client
|
||||
// and should not anymore send additional headers/data
|
||||
// so on timeout writer stays what http.TimeoutHandler uses and prevents writing headers/body
|
||||
if err != nil {
|
||||
// Error must be written into Writer created in `http.TimeoutHandler` so to get Response into `commited` state.
|
||||
// So call global error handler to write error to the client. This is needed or `http.TimeoutHandler` will send
|
||||
// status code by itself and after that our tries to write status code will not work anymore and/or create errors in
|
||||
// log about `superfluous response.WriteHeader call from`
|
||||
t.ctx.Error(err)
|
||||
// we pass error from handler to middlewares up in handler chain to act on it if needed. But this means that
|
||||
// global error handler is probably be called twice as `t.ctx.Error` already does that.
|
||||
|
||||
// NB: later call of the global error handler or middlewares will not take any effect, as echo.Response will be
|
||||
// already marked as `committed` because we called global error handler above.
|
||||
t.ctx.Response().Writer = originalWriter // make sure we restore before we signal original coroutine about the error
|
||||
// This is needed as `http.TimeoutHandler` will write status code by itself on error and after that our tries to write
|
||||
// status code will not work anymore as Echo.Response thinks it has been already "committed" and further writes
|
||||
// create errors in log about `superfluous response.WriteHeader call from`
|
||||
t.writer.Ignore(true)
|
||||
t.ctx.Response().Writer = originalWriter // make sure we restore writer before we signal original coroutine about the error
|
||||
// we pass error from handler to middlewares up in handler chain to act on it if needed.
|
||||
t.errChan <- err
|
||||
return
|
||||
}
|
||||
// we restore original writer only for cases we did not timeout. On timeout we have already sent response to client
|
||||
// and should not anymore send additional headers/data
|
||||
// so on timeout writer stays what http.TimeoutHandler uses and prevents writing headers/body
|
||||
t.ctx.Response().Writer = originalWriter
|
||||
}
|
||||
|
||||
// ignorableWriter is ResponseWriter implementations that allows us to mark writer to ignore further write calls. This
|
||||
// is handy in cases when you do not have direct control of code being executed (3rd party middleware) but want to make
|
||||
// sure that external code will not be able to write response to the client.
|
||||
// Writer is coroutine safe for writes.
|
||||
type ignorableWriter struct {
|
||||
http.ResponseWriter
|
||||
|
||||
lock sync.Mutex
|
||||
ignoreWrites bool
|
||||
}
|
||||
|
||||
func (w *ignorableWriter) Ignore(ignore bool) {
|
||||
w.lock.Lock()
|
||||
w.ignoreWrites = ignore
|
||||
w.lock.Unlock()
|
||||
}
|
||||
|
||||
func (w *ignorableWriter) WriteHeader(code int) {
|
||||
w.lock.Lock()
|
||||
defer w.lock.Unlock()
|
||||
if w.ignoreWrites {
|
||||
return
|
||||
}
|
||||
w.ResponseWriter.WriteHeader(code)
|
||||
}
|
||||
|
||||
func (w *ignorableWriter) Write(b []byte) (int, error) {
|
||||
w.lock.Lock()
|
||||
defer w.lock.Unlock()
|
||||
if w.ignoreWrites {
|
||||
return len(b), nil
|
||||
}
|
||||
return w.ResponseWriter.Write(b)
|
||||
}
|
||||
|
13
vendor/github.com/mattermost/mattermost-server/v6/model/bulk_export.go
generated
vendored
Normal file
13
vendor/github.com/mattermost/mattermost-server/v6/model/bulk_export.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
// ExportDataDir is the name of the directory were to store additional data
|
||||
// included with the export (e.g. file attachments).
|
||||
const ExportDataDir = "data"
|
||||
|
||||
type BulkExportOpts struct {
|
||||
IncludeAttachments bool
|
||||
CreateArchive bool
|
||||
}
|
43
vendor/github.com/mattermost/mattermost-server/v6/model/channel.go
generated
vendored
43
vendor/github.com/mattermost/mattermost-server/v6/model/channel.go
generated
vendored
@ -6,6 +6,8 @@ package model
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"sort"
|
||||
@ -51,11 +53,11 @@ type Channel struct {
|
||||
ExtraUpdateAt int64 `json:"extra_update_at"`
|
||||
CreatorId string `json:"creator_id"`
|
||||
SchemeId *string `json:"scheme_id"`
|
||||
Props map[string]interface{} `json:"props" db:"-"`
|
||||
Props map[string]interface{} `json:"props"`
|
||||
GroupConstrained *bool `json:"group_constrained"`
|
||||
Shared *bool `json:"shared"`
|
||||
TotalMsgCountRoot int64 `json:"total_msg_count_root"`
|
||||
PolicyID *string `json:"policy_id" db:"-"`
|
||||
PolicyID *string `json:"policy_id"`
|
||||
LastRootPostAt int64 `json:"last_root_post_at"`
|
||||
}
|
||||
|
||||
@ -141,6 +143,8 @@ type ChannelSearchOpts struct {
|
||||
Private bool
|
||||
Page *int
|
||||
PerPage *int
|
||||
LastDeleteAt int
|
||||
LastUpdateAt int
|
||||
}
|
||||
|
||||
type ChannelMemberCountByGroup struct {
|
||||
@ -157,6 +161,23 @@ func WithID(ID string) ChannelOption {
|
||||
}
|
||||
}
|
||||
|
||||
// The following are some GraphQL methods necessary to return the
|
||||
// data in float64 type. The spec doesn't support 64 bit integers,
|
||||
// so we have to pass the data in float64. The _ at the end is
|
||||
// a hack to keep the attribute name same in GraphQL schema.
|
||||
|
||||
func (o *Channel) CreateAt_() float64 {
|
||||
return float64(o.CreateAt)
|
||||
}
|
||||
|
||||
func (o *Channel) UpdateAt_() float64 {
|
||||
return float64(o.UpdateAt)
|
||||
}
|
||||
|
||||
func (o *Channel) DeleteAt_() float64 {
|
||||
return float64(o.DeleteAt)
|
||||
}
|
||||
|
||||
func (o *Channel) DeepCopy() *Channel {
|
||||
copy := *o
|
||||
if copy.SchemeId != nil {
|
||||
@ -303,6 +324,24 @@ func (o *Channel) GetOtherUserIdForDM(userId string) string {
|
||||
return otherUserId
|
||||
}
|
||||
|
||||
func (ChannelType) ImplementsGraphQLType(name string) bool {
|
||||
return name == "ChannelType"
|
||||
}
|
||||
|
||||
func (t ChannelType) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(string(t))
|
||||
}
|
||||
|
||||
func (t *ChannelType) UnmarshalGraphQL(input interface{}) error {
|
||||
chType, ok := input.(string)
|
||||
if !ok {
|
||||
return errors.New("wrong type")
|
||||
}
|
||||
|
||||
*t = ChannelType(chType)
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetDMNameFromIds(userId1, userId2 string) string {
|
||||
if userId1 > userId2 {
|
||||
return userId2 + "__" + userId1
|
||||
|
25
vendor/github.com/mattermost/mattermost-server/v6/model/channel_member.go
generated
vendored
25
vendor/github.com/mattermost/mattermost-server/v6/model/channel_member.go
generated
vendored
@ -60,6 +60,31 @@ type ChannelMember struct {
|
||||
ExplicitRoles string `json:"explicit_roles"`
|
||||
}
|
||||
|
||||
// The following are some GraphQL methods necessary to return the
|
||||
// data in float64 type. The spec doesn't support 64 bit integers,
|
||||
// so we have to pass the data in float64. The _ at the end is
|
||||
// a hack to keep the attribute name same in GraphQL schema.
|
||||
|
||||
func (o *ChannelMember) LastViewedAt_() float64 {
|
||||
return float64(o.LastViewedAt)
|
||||
}
|
||||
|
||||
func (o *ChannelMember) MsgCount_() float64 {
|
||||
return float64(o.MsgCount)
|
||||
}
|
||||
|
||||
func (o *ChannelMember) MentionCount_() float64 {
|
||||
return float64(o.MentionCount)
|
||||
}
|
||||
|
||||
func (o *ChannelMember) MentionCountRoot_() float64 {
|
||||
return float64(o.MentionCountRoot)
|
||||
}
|
||||
|
||||
func (o *ChannelMember) LastUpdateAt_() float64 {
|
||||
return float64(o.LastUpdateAt)
|
||||
}
|
||||
|
||||
// ChannelMemberWithTeamData contains ChannelMember appended with extra team information
|
||||
// as well.
|
||||
type ChannelMemberWithTeamData struct {
|
||||
|
42
vendor/github.com/mattermost/mattermost-server/v6/model/channel_sidebar.go
generated
vendored
42
vendor/github.com/mattermost/mattermost-server/v6/model/channel_sidebar.go
generated
vendored
@ -4,6 +4,8 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
@ -54,6 +56,10 @@ type SidebarCategoryWithChannels struct {
|
||||
Channels []string `json:"channel_ids"`
|
||||
}
|
||||
|
||||
func (sc SidebarCategoryWithChannels) ChannelIds() []string {
|
||||
return sc.Channels
|
||||
}
|
||||
|
||||
type SidebarCategoryOrder []string
|
||||
|
||||
// OrderedSidebarCategories combines categories, their channel IDs and an array of Category IDs, sorted
|
||||
@ -83,3 +89,39 @@ func IsValidCategoryId(s string) bool {
|
||||
// Or default categories can follow the pattern {type}_{userID}_{teamID}
|
||||
return categoryIdPattern.MatchString(s)
|
||||
}
|
||||
|
||||
func (SidebarCategoryType) ImplementsGraphQLType(name string) bool {
|
||||
return name == "SidebarCategoryType"
|
||||
}
|
||||
|
||||
func (t SidebarCategoryType) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(string(t))
|
||||
}
|
||||
|
||||
func (t *SidebarCategoryType) UnmarshalGraphQL(input interface{}) error {
|
||||
chType, ok := input.(string)
|
||||
if !ok {
|
||||
return errors.New("wrong type")
|
||||
}
|
||||
|
||||
*t = SidebarCategoryType(chType)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (SidebarCategorySorting) ImplementsGraphQLType(name string) bool {
|
||||
return name == "SidebarCategorySorting"
|
||||
}
|
||||
|
||||
func (t SidebarCategorySorting) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(string(t))
|
||||
}
|
||||
|
||||
func (t *SidebarCategorySorting) UnmarshalGraphQL(input interface{}) error {
|
||||
chType, ok := input.(string)
|
||||
if !ok {
|
||||
return errors.New("wrong type")
|
||||
}
|
||||
|
||||
*t = SidebarCategorySorting(chType)
|
||||
return nil
|
||||
}
|
||||
|
99
vendor/github.com/mattermost/mattermost-server/v6/model/client4.go
generated
vendored
99
vendor/github.com/mattermost/mattermost-server/v6/model/client4.go
generated
vendored
@ -46,6 +46,7 @@ const (
|
||||
|
||||
APIURLSuffixV1 = "/api/v1"
|
||||
APIURLSuffixV4 = "/api/v4"
|
||||
APIURLSuffixV5 = "/api/v5"
|
||||
APIURLSuffix = APIURLSuffixV4
|
||||
)
|
||||
|
||||
@ -5252,7 +5253,7 @@ func (c *Client4) GetGroupsAssociatedToChannelsByTeam(teamId string, opts GroupS
|
||||
// GetGroups retrieves Mattermost Groups
|
||||
func (c *Client4) GetGroups(opts GroupSearchOpts) ([]*Group, *Response, error) {
|
||||
path := fmt.Sprintf(
|
||||
"%s?include_member_count=%v¬_associated_to_team=%v¬_associated_to_channel=%v&filter_allow_reference=%v&q=%v&filter_parent_team_permitted=%v",
|
||||
"%s?include_member_count=%v¬_associated_to_team=%v¬_associated_to_channel=%v&filter_allow_reference=%v&q=%v&filter_parent_team_permitted=%v&group_source=%v",
|
||||
c.groupsRoute(),
|
||||
opts.IncludeMemberCount,
|
||||
opts.NotAssociatedToTeam,
|
||||
@ -5260,6 +5261,7 @@ func (c *Client4) GetGroups(opts GroupSearchOpts) ([]*Group, *Response, error) {
|
||||
opts.FilterAllowReference,
|
||||
opts.Q,
|
||||
opts.FilterParentTeamPermitted,
|
||||
opts.Source,
|
||||
)
|
||||
if opts.Since > 0 {
|
||||
path = fmt.Sprintf("%s&since=%v", path, opts.Since)
|
||||
@ -7071,6 +7073,36 @@ func (c *Client4) GetGroup(groupID, etag string) (*Group, *Response, error) {
|
||||
return &g, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
func (c *Client4) CreateGroup(group *Group) (*Group, *Response, error) {
|
||||
groupJSON, jsonErr := json.Marshal(group)
|
||||
if jsonErr != nil {
|
||||
return nil, nil, NewAppError("CreateGroup", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
r, err := c.DoAPIPostBytes("/groups", groupJSON)
|
||||
if err != nil {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
var p Group
|
||||
if jsonErr := json.NewDecoder(r.Body).Decode(&p); jsonErr != nil {
|
||||
return nil, nil, NewAppError("CreateGroup", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return &p, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
func (c *Client4) DeleteGroup(groupID string) (*Group, *Response, error) {
|
||||
r, err := c.DoAPIDelete(c.groupRoute(groupID))
|
||||
if err != nil {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
var p Group
|
||||
if jsonErr := json.NewDecoder(r.Body).Decode(&p); jsonErr != nil {
|
||||
return nil, nil, NewAppError("DeleteGroup", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return &p, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
func (c *Client4) PatchGroup(groupID string, patch *GroupPatch) (*Group, *Response, error) {
|
||||
payload, _ := json.Marshal(patch)
|
||||
r, err := c.DoAPIPut(c.groupRoute(groupID)+"/patch", string(payload))
|
||||
@ -7085,6 +7117,40 @@ func (c *Client4) PatchGroup(groupID string, patch *GroupPatch) (*Group, *Respon
|
||||
return &g, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
func (c *Client4) UpsertGroupMembers(groupID string, userIds *GroupModifyMembers) ([]*GroupMember, *Response, error) {
|
||||
payload, jsonErr := json.Marshal(userIds)
|
||||
if jsonErr != nil {
|
||||
return nil, nil, NewAppError("UpsertGroupMembers", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
r, err := c.DoAPIPostBytes(c.groupRoute(groupID)+"/members", payload)
|
||||
if err != nil {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
var g []*GroupMember
|
||||
if jsonErr := json.NewDecoder(r.Body).Decode(&g); jsonErr != nil {
|
||||
return nil, nil, NewAppError("UpsertGroupMembers", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return g, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
func (c *Client4) DeleteGroupMembers(groupID string, userIds *GroupModifyMembers) ([]*GroupMember, *Response, error) {
|
||||
payload, jsonErr := json.Marshal(userIds)
|
||||
if jsonErr != nil {
|
||||
return nil, nil, NewAppError("DeleteGroupMembers", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
r, err := c.DoAPIDeleteBytes(c.groupRoute(groupID)+"/members", payload)
|
||||
if err != nil {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
var g []*GroupMember
|
||||
if jsonErr := json.NewDecoder(r.Body).Decode(&g); jsonErr != nil {
|
||||
return nil, nil, NewAppError("DeleteGroupMembers", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return g, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
func (c *Client4) LinkGroupSyncable(groupID, syncableID string, syncableType GroupSyncableType, patch *GroupSyncablePatch) (*GroupSyncable, *Response, error) {
|
||||
payload, _ := json.Marshal(patch)
|
||||
url := fmt.Sprintf("%s/link", c.groupSyncableRoute(groupID, syncableID, syncableType))
|
||||
@ -7435,6 +7501,20 @@ func (c *Client4) MarkNoticesViewed(ids []string) (*Response, error) {
|
||||
return BuildResponse(r), nil
|
||||
}
|
||||
|
||||
func (c *Client4) CompleteOnboarding(request *CompleteOnboardingRequest) (*Response, error) {
|
||||
buf, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, NewAppError("CompleteOnboarding", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
r, err := c.DoAPIPost(c.systemRoute()+"/onboarding/complete", string(buf))
|
||||
if err != nil {
|
||||
return BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
|
||||
return BuildResponse(r), nil
|
||||
}
|
||||
|
||||
// CreateUpload creates a new upload session.
|
||||
func (c *Client4) CreateUpload(us *UploadSession) (*UploadSession, *Response, error) {
|
||||
buf, err := json.Marshal(us)
|
||||
@ -7834,3 +7914,20 @@ func (c *Client4) GetAncillaryPermissions(subsectionPermissions []string) ([]str
|
||||
json.NewDecoder(r.Body).Decode(&returnedPermissions)
|
||||
return returnedPermissions, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
func (c *Client4) GetUsersWithInvalidEmails(page, perPage int) ([]*User, *Response, error) {
|
||||
query := fmt.Sprintf("/invalid_emails?page=%v&per_page=%v", page, perPage)
|
||||
r, err := c.DoAPIGet(c.usersRoute()+query, "")
|
||||
if err != nil {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
var list []*User
|
||||
if r.StatusCode == http.StatusNotModified {
|
||||
return list, BuildResponse(r), nil
|
||||
}
|
||||
if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil {
|
||||
return nil, nil, NewAppError("GetUsers", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return list, BuildResponse(r), nil
|
||||
}
|
||||
|
12
vendor/github.com/mattermost/mattermost-server/v6/model/config.go
generated
vendored
12
vendor/github.com/mattermost/mattermost-server/v6/model/config.go
generated
vendored
@ -114,7 +114,7 @@ const (
|
||||
TeamSettingsDefaultCustomDescriptionText = ""
|
||||
TeamSettingsDefaultUserStatusAwayTimeout = 300
|
||||
|
||||
SqlSettingsDefaultDataSource = "postgres://mmuser:mostest@localhost/mattermost_test?sslmode=disable&connect_timeout=10"
|
||||
SqlSettingsDefaultDataSource = "postgres://mmuser:mostest@localhost/mattermost_test?sslmode=disable&connect_timeout=10&binary_parameters=yes"
|
||||
|
||||
FileSettingsDefaultDirectory = "./data/"
|
||||
|
||||
@ -305,6 +305,7 @@ type ServiceSettings struct {
|
||||
EnableTesting *bool `access:"environment_developer,write_restrictable,cloud_restrictable"`
|
||||
EnableDeveloper *bool `access:"environment_developer,write_restrictable,cloud_restrictable"`
|
||||
DeveloperFlags *string `access:"environment_developer"`
|
||||
EnableClientPerformanceDebugging *bool `access:"environment_developer,write_restrictable,cloud_restrictable"`
|
||||
EnableOpenTracing *bool `access:"write_restrictable,cloud_restrictable"`
|
||||
EnableSecurityFixAlert *bool `access:"environment_smtp,write_restrictable,cloud_restrictable"`
|
||||
EnableInsecureOutgoingConnections *bool `access:"environment_web_server,write_restrictable,cloud_restrictable"`
|
||||
@ -366,6 +367,7 @@ type ServiceSettings struct {
|
||||
ThreadAutoFollow *bool `access:"experimental_features"`
|
||||
CollapsedThreads *string `access:"experimental_features"`
|
||||
ManagedResourcePaths *string `access:"environment_web_server,write_restrictable,cloud_restrictable"`
|
||||
EnableCustomGroups *bool `access:"site_users_and_teams"`
|
||||
}
|
||||
|
||||
func (s *ServiceSettings) SetDefaults(isUpdate bool) {
|
||||
@ -422,6 +424,10 @@ func (s *ServiceSettings) SetDefaults(isUpdate bool) {
|
||||
s.DeveloperFlags = NewString("")
|
||||
}
|
||||
|
||||
if s.EnableClientPerformanceDebugging == nil {
|
||||
s.EnableClientPerformanceDebugging = NewBool(false)
|
||||
}
|
||||
|
||||
if s.EnableOpenTracing == nil {
|
||||
s.EnableOpenTracing = NewBool(false)
|
||||
}
|
||||
@ -782,6 +788,10 @@ func (s *ServiceSettings) SetDefaults(isUpdate bool) {
|
||||
if s.ManagedResourcePaths == nil {
|
||||
s.ManagedResourcePaths = NewString("")
|
||||
}
|
||||
|
||||
if s.EnableCustomGroups == nil {
|
||||
s.EnableCustomGroups = NewBool(true)
|
||||
}
|
||||
}
|
||||
|
||||
type ClusterSettings struct {
|
||||
|
8
vendor/github.com/mattermost/mattermost-server/v6/model/custom_status.go
generated
vendored
8
vendor/github.com/mattermost/mattermost-server/v6/model/custom_status.go
generated
vendored
@ -8,6 +8,8 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/graph-gophers/graphql-go"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -61,6 +63,12 @@ func (cs *CustomStatus) AreDurationAndExpirationTimeValid() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ExpiresAt_ returns the time in a type that has the marshal/unmarshal methods
|
||||
// attached to it.
|
||||
func (cs *CustomStatus) ExpiresAt_() graphql.Time {
|
||||
return graphql.Time{Time: cs.ExpiresAt}
|
||||
}
|
||||
|
||||
func RuneToHexadecimalString(r rune) string {
|
||||
return fmt.Sprintf("%04x", r)
|
||||
}
|
||||
|
5
vendor/github.com/mattermost/mattermost-server/v6/model/emoji.go
generated
vendored
5
vendor/github.com/mattermost/mattermost-server/v6/model/emoji.go
generated
vendored
@ -78,9 +78,12 @@ func (emoji *Emoji) IsValid() *AppError {
|
||||
}
|
||||
|
||||
func IsValidEmojiName(name string) *AppError {
|
||||
if name == "" || len(name) > EmojiNameMaxLength || !IsValidAlphaNumHyphenUnderscorePlus(name) || inSystemEmoji(name) {
|
||||
if name == "" || len(name) > EmojiNameMaxLength || !IsValidAlphaNumHyphenUnderscorePlus(name) {
|
||||
return NewAppError("Emoji.IsValid", "model.emoji.name.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
if inSystemEmoji(name) {
|
||||
return NewAppError("Emoji.IsValid", "model.emoji.system_emoji_name.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
27
vendor/github.com/mattermost/mattermost-server/v6/model/feature_flags.go
generated
vendored
27
vendor/github.com/mattermost/mattermost-server/v6/model/feature_flags.go
generated
vendored
@ -41,18 +41,12 @@ type FeatureFlags struct {
|
||||
// Enable the Global Header
|
||||
GlobalHeader bool
|
||||
|
||||
// Enable different team menu button treatments, possible values = ("none", "by_team_name", "inverted_sidebar_bg_color")
|
||||
AddChannelButton string
|
||||
|
||||
// Determine whether when a user gets created, they'll have noisy notifications e.g. Send desktop notifications for all activity
|
||||
NewAccountNoisy bool
|
||||
|
||||
// Enable Calls plugin support in the mobile app
|
||||
CallsMobile bool
|
||||
|
||||
// Start A/B tour tips automatically, possible values = ("none", "auto")
|
||||
AutoTour string
|
||||
|
||||
// A dash separated list for feature flags to turn on for Boards
|
||||
BoardsFeatureFlags string
|
||||
|
||||
@ -68,6 +62,8 @@ type FeatureFlags struct {
|
||||
// A/B test for whether radio buttons or toggle button is more effective in in-screen invite to team modal ("none", "toggle")
|
||||
InviteToTeam string
|
||||
|
||||
CustomGroups bool
|
||||
|
||||
// Enable inline post editing
|
||||
InlinePostEditing bool
|
||||
|
||||
@ -75,6 +71,17 @@ type FeatureFlags struct {
|
||||
BoardsDataRetention bool
|
||||
|
||||
NormalizeLdapDNs bool
|
||||
|
||||
EnableInactivityCheckJob bool
|
||||
|
||||
// Enable special onboarding flow for first admin
|
||||
UseCaseOnboarding bool
|
||||
|
||||
// Enable Workspace optimization dashboard
|
||||
WorkspaceOptimizationDashboard bool
|
||||
|
||||
// Enable GraphQL feature
|
||||
GraphQL bool
|
||||
}
|
||||
|
||||
func (f *FeatureFlags) SetDefaults() {
|
||||
@ -89,20 +96,22 @@ func (f *FeatureFlags) SetDefaults() {
|
||||
f.PluginFocalboard = ""
|
||||
f.PermalinkPreviews = true
|
||||
f.GlobalHeader = true
|
||||
f.AddChannelButton = "by_team_name"
|
||||
f.NewAccountNoisy = false
|
||||
f.CallsMobile = false
|
||||
f.AutoTour = "none"
|
||||
f.BoardsFeatureFlags = ""
|
||||
f.AddMembersToChannel = "top"
|
||||
f.GuidedChannelCreation = false
|
||||
f.ResendInviteEmailInterval = ""
|
||||
f.InviteToTeam = "none"
|
||||
f.CustomGroups = true
|
||||
f.InlinePostEditing = false
|
||||
f.BoardsDataRetention = false
|
||||
f.NormalizeLdapDNs = false
|
||||
f.EnableInactivityCheckJob = true
|
||||
f.UseCaseOnboarding = true
|
||||
f.WorkspaceOptimizationDashboard = true
|
||||
f.GraphQL = false
|
||||
}
|
||||
|
||||
func (f *FeatureFlags) Plugins() map[string]string {
|
||||
rFFVal := reflect.ValueOf(f).Elem()
|
||||
rFFType := reflect.TypeOf(f).Elem()
|
||||
|
26
vendor/github.com/mattermost/mattermost-server/v6/model/github_release.go
generated
vendored
Normal file
26
vendor/github.com/mattermost/mattermost-server/v6/model/github_release.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type GithubReleaseInfo struct {
|
||||
Id int `json:"id"`
|
||||
TagName string `json:"tag_name"`
|
||||
Name string `json:"name"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
PublishedAt string `json:"published_at"`
|
||||
Body string `json:"body"`
|
||||
Url string `json:"html_url"`
|
||||
}
|
||||
|
||||
func (g *GithubReleaseInfo) IsValid() *AppError {
|
||||
if g.Id == 0 {
|
||||
return NewAppError("GithubReleaseInfo.IsValid", "model.github_release_info.is_valid.id.app_error", nil, "", http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
47
vendor/github.com/mattermost/mattermost-server/v6/model/group.go
generated
vendored
47
vendor/github.com/mattermost/mattermost-server/v6/model/group.go
generated
vendored
@ -9,7 +9,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
GroupSourceLdap GroupSource = "ldap"
|
||||
GroupSourceLdap GroupSource = "ldap"
|
||||
GroupSourceCustom GroupSource = "custom"
|
||||
|
||||
GroupNameMaxLength = 64
|
||||
GroupSourceMaxLength = 64
|
||||
@ -22,6 +23,7 @@ type GroupSource string
|
||||
|
||||
var allGroupSources = []GroupSource{
|
||||
GroupSourceLdap,
|
||||
GroupSourceCustom,
|
||||
}
|
||||
|
||||
var groupSourcesRequiringRemoteID = []GroupSource{
|
||||
@ -34,7 +36,7 @@ type Group struct {
|
||||
DisplayName string `json:"display_name"`
|
||||
Description string `json:"description"`
|
||||
Source GroupSource `json:"source"`
|
||||
RemoteId string `json:"remote_id"`
|
||||
RemoteId *string `json:"remote_id"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
UpdateAt int64 `json:"update_at"`
|
||||
DeleteAt int64 `json:"delete_at"`
|
||||
@ -43,6 +45,11 @@ type Group struct {
|
||||
AllowReference bool `json:"allow_reference"`
|
||||
}
|
||||
|
||||
type GroupWithUserIds struct {
|
||||
Group
|
||||
UserIds []string `json:"user_ids"`
|
||||
}
|
||||
|
||||
type GroupWithSchemeAdmin struct {
|
||||
Group
|
||||
SchemeAdmin *bool `db:"SyncableSchemeAdmin" json:"scheme_admin,omitempty"`
|
||||
@ -63,6 +70,8 @@ type GroupPatch struct {
|
||||
DisplayName *string `json:"display_name"`
|
||||
Description *string `json:"description"`
|
||||
AllowReference *bool `json:"allow_reference"`
|
||||
// For security reasons (including preventing unintended LDAP group synchronization) do no allow a Group's RemoteId or Source field to be
|
||||
// included in patches.
|
||||
}
|
||||
|
||||
type LdapGroupSearchOpts struct {
|
||||
@ -79,12 +88,21 @@ type GroupSearchOpts struct {
|
||||
FilterAllowReference bool
|
||||
PageOpts *PageOpts
|
||||
Since int64
|
||||
Source GroupSource
|
||||
|
||||
// FilterParentTeamPermitted filters the groups to the intersect of the
|
||||
// set associated to the parent team and those returned by the query.
|
||||
// If the parent team is not group-constrained or if NotAssociatedToChannel
|
||||
// is not set then this option is ignored.
|
||||
FilterParentTeamPermitted bool
|
||||
|
||||
// FilterHasMember filters the groups to the intersect of the
|
||||
// set returned by the query and those that have the given user as a member.
|
||||
FilterHasMember string
|
||||
}
|
||||
|
||||
type GetGroupOpts struct {
|
||||
IncludeMemberCount bool
|
||||
}
|
||||
|
||||
type PageOpts struct {
|
||||
@ -97,6 +115,10 @@ type GroupStats struct {
|
||||
TotalMemberCount int64 `json:"total_member_count"`
|
||||
}
|
||||
|
||||
type GroupModifyMembers struct {
|
||||
UserIds []string `json:"user_ids"`
|
||||
}
|
||||
|
||||
func (group *Group) Patch(patch *GroupPatch) {
|
||||
if patch.Name != nil {
|
||||
group.Name = patch.Name
|
||||
@ -137,7 +159,7 @@ func (group *Group) IsValidForCreate() *AppError {
|
||||
return NewAppError("Group.IsValidForCreate", "model.group.source.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if len(group.RemoteId) > GroupRemoteIDMaxLength || (group.RemoteId == "" && group.requiresRemoteId()) {
|
||||
if (group.GetRemoteId() == "" && group.requiresRemoteId()) || len(group.GetRemoteId()) > GroupRemoteIDMaxLength {
|
||||
return NewAppError("Group.IsValidForCreate", "model.group.remote_id.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@ -188,3 +210,22 @@ func (group *Group) IsValidName() *AppError {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (group *Group) GetName() string {
|
||||
if group.Name == nil {
|
||||
return ""
|
||||
}
|
||||
return *group.Name
|
||||
}
|
||||
|
||||
func (group *Group) GetRemoteId() string {
|
||||
if group.RemoteId == nil {
|
||||
return ""
|
||||
}
|
||||
return *group.RemoteId
|
||||
}
|
||||
|
||||
type GroupsWithCount struct {
|
||||
Groups []*Group `json:"groups"`
|
||||
TotalCount int64 `json:"total_count"`
|
||||
}
|
||||
|
26
vendor/github.com/mattermost/mattermost-server/v6/model/job.go
generated
vendored
26
vendor/github.com/mattermost/mattermost-server/v6/model/job.go
generated
vendored
@ -78,29 +78,6 @@ func (j *Job) IsValid() *AppError {
|
||||
return NewAppError("Job.IsValid", "model.job.is_valid.create_at.app_error", nil, "id="+j.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
switch j.Type {
|
||||
case JobTypeDataRetention:
|
||||
case JobTypeElasticsearchPostIndexing:
|
||||
case JobTypeElasticsearchPostAggregation:
|
||||
case JobTypeBlevePostIndexing:
|
||||
case JobTypeLdapSync:
|
||||
case JobTypeMessageExport:
|
||||
case JobTypeMigrations:
|
||||
case JobTypePlugins:
|
||||
case JobTypeProductNotices:
|
||||
case JobTypeExpiryNotify:
|
||||
case JobTypeActiveUsers:
|
||||
case JobTypeImportProcess:
|
||||
case JobTypeImportDelete:
|
||||
case JobTypeExportProcess:
|
||||
case JobTypeExportDelete:
|
||||
case JobTypeCloud:
|
||||
case JobTypeResendInvitationEmail:
|
||||
case JobTypeExtractContent:
|
||||
default:
|
||||
return NewAppError("Job.IsValid", "model.job.is_valid.type.app_error", nil, "id="+j.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
switch j.Status {
|
||||
case JobStatusPending:
|
||||
case JobStatusInProgress:
|
||||
@ -119,11 +96,10 @@ type Worker interface {
|
||||
Run()
|
||||
Stop()
|
||||
JobChannel() chan<- Job
|
||||
IsEnabled(cfg *Config) bool
|
||||
}
|
||||
|
||||
type Scheduler interface {
|
||||
Name() string
|
||||
JobType() string
|
||||
Enabled(cfg *Config) bool
|
||||
NextScheduleTime(cfg *Config, now time.Time, pendingJobs bool, lastSuccessfulJob *Job) *time.Time
|
||||
ScheduleJob(cfg *Config, pendingJobs bool, lastSuccessfulJob *Job) (*Job, *AppError)
|
||||
|
6
vendor/github.com/mattermost/mattermost-server/v6/model/license.go
generated
vendored
6
vendor/github.com/mattermost/mattermost-server/v6/model/license.go
generated
vendored
@ -323,6 +323,12 @@ func NewTestLicense(features ...string) *License {
|
||||
return ret
|
||||
}
|
||||
|
||||
func NewTestLicenseSKU(skuShortName string, features ...string) *License {
|
||||
lic := NewTestLicense(features...)
|
||||
lic.SkuShortName = skuShortName
|
||||
return lic
|
||||
}
|
||||
|
||||
func (lr *LicenseRecord) IsValid() *AppError {
|
||||
if !IsValidId(lr.Id) {
|
||||
return NewAppError("LicenseRecord.IsValid", "model.license_record.is_valid.id.app_error", nil, "", http.StatusBadRequest)
|
||||
|
1
vendor/github.com/mattermost/mattermost-server/v6/model/migration.go
generated
vendored
1
vendor/github.com/mattermost/mattermost-server/v6/model/migration.go
generated
vendored
@ -36,4 +36,5 @@ const (
|
||||
MigrationKeyAddAboutSubsectionPermissions = "about_subsection_permissions"
|
||||
MigrationKeyAddIntegrationsSubsectionPermissions = "integrations_subsection_permissions"
|
||||
MigrationKeyAddPlaybooksPermissions = "playbooks_permissions"
|
||||
MigrationKeyAddCustomUserGroupsPermissions = "custom_groups_permissions"
|
||||
)
|
||||
|
25
vendor/github.com/mattermost/mattermost-server/v6/model/onboarding.go
generated
vendored
Normal file
25
vendor/github.com/mattermost/mattermost-server/v6/model/onboarding.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
// CompleteOnboardingRequest describes parameters of the requested plugin.
|
||||
type CompleteOnboardingRequest struct {
|
||||
InstallPlugins []string `json:"install_plugins"` // InstallPlugins is a list of plugins to be installed
|
||||
}
|
||||
|
||||
// CompleteOnboardingRequest decodes a json-encoded request from the given io.Reader.
|
||||
func CompleteOnboardingRequestFromReader(reader io.Reader) (*CompleteOnboardingRequest, error) {
|
||||
var r *CompleteOnboardingRequest
|
||||
err := json.NewDecoder(reader).Decode(&r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
42
vendor/github.com/mattermost/mattermost-server/v6/model/permission.go
generated
vendored
42
vendor/github.com/mattermost/mattermost-server/v6/model/permission.go
generated
vendored
@ -7,6 +7,7 @@ const (
|
||||
PermissionScopeSystem = "system_scope"
|
||||
PermissionScopeTeam = "team_scope"
|
||||
PermissionScopeChannel = "channel_scope"
|
||||
PermissionScopeGroup = "group_scope"
|
||||
PermissionScopePlaybook = "playbook_scope"
|
||||
PermissionScopeRun = "run_scope"
|
||||
)
|
||||
@ -355,6 +356,11 @@ var PermissionRunView *Permission
|
||||
// admin functions but not others
|
||||
var PermissionManageSystem *Permission
|
||||
|
||||
var PermissionCreateCustomGroup *Permission
|
||||
var PermissionManageCustomGroupMembers *Permission
|
||||
var PermissionEditCustomGroup *Permission
|
||||
var PermissionDeleteCustomGroup *Permission
|
||||
|
||||
var AllPermissions []*Permission
|
||||
var DeprecatedPermissions []*Permission
|
||||
|
||||
@ -1914,6 +1920,34 @@ func initializePermissions() {
|
||||
PermissionScopeSystem,
|
||||
}
|
||||
|
||||
PermissionCreateCustomGroup = &Permission{
|
||||
"create_custom_group",
|
||||
"authentication.permissions.create_custom_group.name",
|
||||
"authentication.permissions.create_custom_group.description",
|
||||
PermissionScopeSystem,
|
||||
}
|
||||
|
||||
PermissionManageCustomGroupMembers = &Permission{
|
||||
"manage_custom_group_members",
|
||||
"authentication.permissions.manage_custom_group_members.name",
|
||||
"authentication.permissions.manage_custom_group_members.description",
|
||||
PermissionScopeGroup,
|
||||
}
|
||||
|
||||
PermissionEditCustomGroup = &Permission{
|
||||
"edit_custom_group",
|
||||
"authentication.permissions.edit_custom_group.name",
|
||||
"authentication.permissions.edit_custom_group.description",
|
||||
PermissionScopeGroup,
|
||||
}
|
||||
|
||||
PermissionDeleteCustomGroup = &Permission{
|
||||
"delete_custom_group",
|
||||
"authentication.permissions.delete_custom_group.name",
|
||||
"authentication.permissions.delete_custom_group.description",
|
||||
PermissionScopeGroup,
|
||||
}
|
||||
|
||||
// Playbooks
|
||||
PermissionPublicPlaybookCreate = &Permission{
|
||||
"playbook_public_create",
|
||||
@ -2200,6 +2234,7 @@ func initializePermissions() {
|
||||
PermissionGetLogs,
|
||||
PermissionReadLicenseInformation,
|
||||
PermissionManageLicenseInformation,
|
||||
PermissionCreateCustomGroup,
|
||||
}
|
||||
|
||||
TeamScopedPermissions := []*Permission{
|
||||
@ -2259,6 +2294,12 @@ func initializePermissions() {
|
||||
PermissionUseGroupMentions,
|
||||
}
|
||||
|
||||
GroupScopedPermissions := []*Permission{
|
||||
PermissionManageCustomGroupMembers,
|
||||
PermissionEditCustomGroup,
|
||||
PermissionDeleteCustomGroup,
|
||||
}
|
||||
|
||||
DeprecatedPermissions = []*Permission{
|
||||
PermissionPermanentDeleteUser,
|
||||
PermissionManageWebhooks,
|
||||
@ -2307,6 +2348,7 @@ func initializePermissions() {
|
||||
AllPermissions = append(AllPermissions, ChannelScopedPermissions...)
|
||||
AllPermissions = append(AllPermissions, SysconsoleReadPermissions...)
|
||||
AllPermissions = append(AllPermissions, SysconsoleWritePermissions...)
|
||||
AllPermissions = append(AllPermissions, GroupScopedPermissions...)
|
||||
AllPermissions = append(AllPermissions, PlaybookScopedPermissions...)
|
||||
AllPermissions = append(AllPermissions, RunScopedPermissions...)
|
||||
|
||||
|
9
vendor/github.com/mattermost/mattermost-server/v6/model/plugin_on_install_event.go
generated
vendored
Normal file
9
vendor/github.com/mattermost/mattermost-server/v6/model/plugin_on_install_event.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
// OnInstallEvent is sent to the plugin when it gets installed.
|
||||
type OnInstallEvent struct {
|
||||
UserId string // The user who installed the plugin
|
||||
}
|
14
vendor/github.com/mattermost/mattermost-server/v6/model/post.go
generated
vendored
14
vendor/github.com/mattermost/mattermost-server/v6/model/post.go
generated
vendored
@ -87,7 +87,7 @@ type Post struct {
|
||||
// MessageSource will contain the message as submitted by the user if Message has been modified
|
||||
// by Mattermost for presentation (e.g if an image proxy is being used). It should be used to
|
||||
// populate edit boxes if present.
|
||||
MessageSource string `json:"message_source,omitempty" db:"-"`
|
||||
MessageSource string `json:"message_source,omitempty"`
|
||||
|
||||
Type string `json:"type"`
|
||||
propsMu sync.RWMutex `db:"-"` // Unexported mutex used to guard Post.Props.
|
||||
@ -95,16 +95,16 @@ type Post struct {
|
||||
Hashtags string `json:"hashtags"`
|
||||
Filenames StringArray `json:"-"` // Deprecated, do not use this field any more
|
||||
FileIds StringArray `json:"file_ids,omitempty"`
|
||||
PendingPostId string `json:"pending_post_id" db:"-"`
|
||||
PendingPostId string `json:"pending_post_id"`
|
||||
HasReactions bool `json:"has_reactions,omitempty"`
|
||||
RemoteId *string `json:"remote_id,omitempty"`
|
||||
|
||||
// Transient data populated before sending a post to the client
|
||||
ReplyCount int64 `json:"reply_count" db:"-"`
|
||||
LastReplyAt int64 `json:"last_reply_at" db:"-"`
|
||||
Participants []*User `json:"participants" db:"-"`
|
||||
IsFollowing *bool `json:"is_following,omitempty" db:"-"` // for root posts in collapsed thread mode indicates if the current user is following this thread
|
||||
Metadata *PostMetadata `json:"metadata,omitempty" db:"-"`
|
||||
ReplyCount int64 `json:"reply_count"`
|
||||
LastReplyAt int64 `json:"last_reply_at"`
|
||||
Participants []*User `json:"participants"`
|
||||
IsFollowing *bool `json:"is_following,omitempty"` // for root posts in collapsed thread mode indicates if the current user is following this thread
|
||||
Metadata *PostMetadata `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
type PostEphemeral struct {
|
||||
|
17
vendor/github.com/mattermost/mattermost-server/v6/model/role.go
generated
vendored
17
vendor/github.com/mattermost/mattermost-server/v6/model/role.go
generated
vendored
@ -4,6 +4,7 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -42,6 +43,8 @@ func init() {
|
||||
ChannelUserRoleId,
|
||||
ChannelAdminRoleId,
|
||||
|
||||
CustomGroupUserRoleId,
|
||||
|
||||
PlaybookAdminRoleId,
|
||||
PlaybookMemberRoleId,
|
||||
RunAdminRoleId,
|
||||
@ -367,6 +370,8 @@ const (
|
||||
ChannelUserRoleId = "channel_user"
|
||||
ChannelAdminRoleId = "channel_admin"
|
||||
|
||||
CustomGroupUserRoleId = "custom_group_user"
|
||||
|
||||
PlaybookAdminRoleId = "playbook_admin"
|
||||
PlaybookMemberRoleId = "playbook_member"
|
||||
RunAdminRoleId = "run_admin"
|
||||
@ -379,6 +384,7 @@ const (
|
||||
RoleScopeSystem RoleScope = "System"
|
||||
RoleScopeTeam RoleScope = "Team"
|
||||
RoleScopeChannel RoleScope = "Channel"
|
||||
RoleScopeGroup RoleScope = "Group"
|
||||
|
||||
RoleTypeGuest RoleType = "Guest"
|
||||
RoleTypeUser RoleType = "User"
|
||||
@ -683,6 +689,13 @@ func IsValidRoleName(roleName string) bool {
|
||||
func MakeDefaultRoles() map[string]*Role {
|
||||
roles := make(map[string]*Role)
|
||||
|
||||
roles[CustomGroupUserRoleId] = &Role{
|
||||
Name: CustomGroupUserRoleId,
|
||||
DisplayName: fmt.Sprintf("authentication.roles.%s.name", CustomGroupUserRoleId),
|
||||
Description: fmt.Sprintf("authentication.roles.%s.description", CustomGroupUserRoleId),
|
||||
Permissions: []string{},
|
||||
}
|
||||
|
||||
roles[ChannelGuestRoleId] = &Role{
|
||||
Name: "channel_guest",
|
||||
DisplayName: "authentication.roles.channel_guest.name",
|
||||
@ -895,6 +908,10 @@ func MakeDefaultRoles() map[string]*Role {
|
||||
PermissionCreateGroupChannel.Id,
|
||||
PermissionViewMembers.Id,
|
||||
PermissionCreateTeam.Id,
|
||||
PermissionCreateCustomGroup.Id,
|
||||
PermissionEditCustomGroup.Id,
|
||||
PermissionDeleteCustomGroup.Id,
|
||||
PermissionManageCustomGroupMembers.Id,
|
||||
},
|
||||
SchemeManaged: true,
|
||||
BuiltIn: true,
|
||||
|
13
vendor/github.com/mattermost/mattermost-server/v6/model/status.go
generated
vendored
13
vendor/github.com/mattermost/mattermost-server/v6/model/status.go
generated
vendored
@ -34,6 +34,19 @@ func (s *Status) ToJSON() ([]byte, error) {
|
||||
return json.Marshal(sCopy)
|
||||
}
|
||||
|
||||
// The following are some GraphQL methods necessary to return the
|
||||
// data in float64 type. The spec doesn't support 64 bit integers,
|
||||
// so we have to pass the data in float64. The _ at the end is
|
||||
// a hack to keep the attribute name same in GraphQL schema.
|
||||
|
||||
func (s *Status) LastActivityAt_() float64 {
|
||||
return float64(s.LastActivityAt)
|
||||
}
|
||||
|
||||
func (s *Status) DNDEndTime_() float64 {
|
||||
return float64(s.DNDEndTime)
|
||||
}
|
||||
|
||||
func StatusListToJSON(u []*Status) ([]byte, error) {
|
||||
list := make([]Status, len(u))
|
||||
for i, s := range u {
|
||||
|
9
vendor/github.com/mattermost/mattermost-server/v6/model/system.go
generated
vendored
9
vendor/github.com/mattermost/mattermost-server/v6/model/system.go
generated
vendored
@ -30,8 +30,8 @@ const (
|
||||
SystemWarnMetricNumberOfActiveUsers500 = "warn_metric_number_of_active_users_500"
|
||||
SystemWarnMetricNumberOfPosts2m = "warn_metric_number_of_posts_2M"
|
||||
SystemWarnMetricLastRunTimestampKey = "LastWarnMetricRunTimestamp"
|
||||
SystemMetricSupportEmailNotConfigured = "warn_metric_support_email_not_configured"
|
||||
SystemFirstAdminVisitMarketplace = "FirstAdminVisitMarketplace"
|
||||
SystemFirstAdminSetupComplete = "FirstAdminSetupComplete"
|
||||
AwsMeteringReportInterval = 1
|
||||
AwsMeteringDimensionUsageHrs = "UsageHrs"
|
||||
UserLimitOverageCycleEndDate = "UserLimitOverageCycleEndDate"
|
||||
@ -147,13 +147,6 @@ var WarnMetricsTable = map[string]WarnMetric{
|
||||
IsBotOnly: false,
|
||||
IsRunOnce: true,
|
||||
},
|
||||
SystemMetricSupportEmailNotConfigured: {
|
||||
Id: SystemMetricSupportEmailNotConfigured,
|
||||
Limit: -1,
|
||||
IsBotOnly: true,
|
||||
IsRunOnce: false,
|
||||
SkipAction: true,
|
||||
},
|
||||
}
|
||||
|
||||
type WarnMetric struct {
|
||||
|
2
vendor/github.com/mattermost/mattermost-server/v6/model/team.go
generated
vendored
2
vendor/github.com/mattermost/mattermost-server/v6/model/team.go
generated
vendored
@ -40,7 +40,7 @@ type Team struct {
|
||||
LastTeamIconUpdate int64 `json:"last_team_icon_update,omitempty"`
|
||||
SchemeId *string `json:"scheme_id"`
|
||||
GroupConstrained *bool `json:"group_constrained"`
|
||||
PolicyID *string `json:"policy_id" db:"-"`
|
||||
PolicyID *string `json:"policy_id"`
|
||||
}
|
||||
|
||||
type TeamPatch struct {
|
||||
|
6
vendor/github.com/mattermost/mattermost-server/v6/model/team_member.go
generated
vendored
6
vendor/github.com/mattermost/mattermost-server/v6/model/team_member.go
generated
vendored
@ -125,3 +125,9 @@ func (o *TeamMember) PreUpdate() {
|
||||
func (o *TeamMember) GetRoles() []string {
|
||||
return strings.Fields(o.Roles)
|
||||
}
|
||||
|
||||
// DeleteAt_ returns the deleteAt value in float64. This is necessary to work
|
||||
// with GraphQL since it doesn't support 64 bit integers.
|
||||
func (o *TeamMember) DeleteAt_() float64 {
|
||||
return float64(o.DeleteAt)
|
||||
}
|
||||
|
59
vendor/github.com/mattermost/mattermost-server/v6/model/thread.go
generated
vendored
59
vendor/github.com/mattermost/mattermost-server/v6/model/thread.go
generated
vendored
@ -3,11 +3,24 @@
|
||||
|
||||
package model
|
||||
|
||||
// Thread tracks the metadata associated with a root post and its reply posts.
|
||||
//
|
||||
// Note that Thread metadata does not exist until the first reply to a root post.
|
||||
type Thread struct {
|
||||
PostId string `json:"id"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
ReplyCount int64 `json:"reply_count"`
|
||||
LastReplyAt int64 `json:"last_reply_at"`
|
||||
// PostId is the root post of the thread.
|
||||
PostId string `json:"id"`
|
||||
|
||||
// ChannelId is the channel in which the thread was posted.
|
||||
ChannelId string `json:"channel_id"`
|
||||
|
||||
// ReplyCount is the number of replies to the thread (excluding deleted posts).
|
||||
ReplyCount int64 `json:"reply_count"`
|
||||
|
||||
// LastReplyAt is the timestamp of the most recent post to the thread.
|
||||
LastReplyAt int64 `json:"last_reply_at"`
|
||||
|
||||
// Participants is a list of user ids that have replied to the thread, sorted by the oldest
|
||||
// to newest. Note that the root post author is not included in this list until they reply.
|
||||
Participants StringArray `json:"participants"`
|
||||
}
|
||||
|
||||
@ -62,11 +75,37 @@ func (o *Thread) Etag() string {
|
||||
return Etag(o.PostId, o.LastReplyAt)
|
||||
}
|
||||
|
||||
// ThreadMembership models the relationship between a user and a thread of posts, with a similar
|
||||
// data structure as ChannelMembership.
|
||||
type ThreadMembership struct {
|
||||
PostId string `json:"post_id"`
|
||||
UserId string `json:"user_id"`
|
||||
Following bool `json:"following"`
|
||||
LastViewed int64 `json:"last_view_at"`
|
||||
LastUpdated int64 `json:"last_update_at"`
|
||||
UnreadMentions int64 `json:"unread_mentions"`
|
||||
// PostId is the root post id of the thread in question.
|
||||
PostId string `json:"post_id"`
|
||||
|
||||
// UserId is the user whose membership in the thread is being tracked.
|
||||
UserId string `json:"user_id"`
|
||||
|
||||
// Following tracks whether the user is following the given thread. This defaults to true
|
||||
// when a ThreadMembership record is created (a record doesn't exist until the user first
|
||||
// starts following the thread), but the user can stop following or resume following at
|
||||
// will.
|
||||
Following bool `json:"following"`
|
||||
|
||||
// LastUpdated is either the creation time of the membership record, or the last time the
|
||||
// membership record was changed (e.g. started/stopped following, viewed thread, mention
|
||||
// count change).
|
||||
//
|
||||
// This field is used to constrain queries of thread memberships to those updated after
|
||||
// a given timestamp (e.g. on websocket reconnect). It's also used as the time column for
|
||||
// deletion decisions during any configured retention policy.
|
||||
LastUpdated int64 `json:"last_update_at"`
|
||||
|
||||
// LastViewed is the last time the user viewed this thread. It is the thread analogue to
|
||||
// the ChannelMembership's LastViewedAt and is used to decide when there are new replies
|
||||
// for the user and where the user should start reading.
|
||||
LastViewed int64 `json:"last_view_at"`
|
||||
|
||||
// UnreadMentions is the number of unseen at-mentions for the user in the given thread. It
|
||||
// is the thread analogue to the ChannelMembership's MentionCount, and is used to highlight
|
||||
// threads with the mention count.
|
||||
UnreadMentions int64 `json:"unread_mentions"`
|
||||
}
|
||||
|
5
vendor/github.com/mattermost/mattermost-server/v6/model/upload_session.go
generated
vendored
5
vendor/github.com/mattermost/mattermost-server/v6/model/upload_session.go
generated
vendored
@ -12,8 +12,9 @@ import (
|
||||
type UploadType string
|
||||
|
||||
const (
|
||||
UploadTypeAttachment UploadType = "attachment"
|
||||
UploadTypeImport UploadType = "import"
|
||||
UploadTypeAttachment UploadType = "attachment"
|
||||
UploadTypeImport UploadType = "import"
|
||||
IncompleteUploadSuffix = ".tmp"
|
||||
)
|
||||
|
||||
// UploadNoUserID is a "fake" user id used by the API layer when in local mode.
|
||||
|
40
vendor/github.com/mattermost/mattermost-server/v6/model/user.go
generated
vendored
40
vendor/github.com/mattermost/mattermost-server/v6/model/user.go
generated
vendored
@ -95,13 +95,13 @@ type User struct {
|
||||
MfaActive bool `json:"mfa_active,omitempty"`
|
||||
MfaSecret string `json:"mfa_secret,omitempty"`
|
||||
RemoteId *string `json:"remote_id,omitempty"`
|
||||
LastActivityAt int64 `db:"-" json:"last_activity_at,omitempty"`
|
||||
IsBot bool `db:"-" json:"is_bot,omitempty"`
|
||||
BotDescription string `db:"-" json:"bot_description,omitempty"`
|
||||
BotLastIconUpdate int64 `db:"-" json:"bot_last_icon_update,omitempty"`
|
||||
TermsOfServiceId string `db:"-" json:"terms_of_service_id,omitempty"`
|
||||
TermsOfServiceCreateAt int64 `db:"-" json:"terms_of_service_create_at,omitempty"`
|
||||
DisableWelcomeEmail bool `db:"-" json:"disable_welcome_email"`
|
||||
LastActivityAt int64 `json:"last_activity_at,omitempty"`
|
||||
IsBot bool `json:"is_bot,omitempty"`
|
||||
BotDescription string `json:"bot_description,omitempty"`
|
||||
BotLastIconUpdate int64 `json:"bot_last_icon_update,omitempty"`
|
||||
TermsOfServiceId string `json:"terms_of_service_id,omitempty"`
|
||||
TermsOfServiceCreateAt int64 `json:"terms_of_service_create_at,omitempty"`
|
||||
DisableWelcomeEmail bool `json:"disable_welcome_email"`
|
||||
}
|
||||
|
||||
//msgp UserMap
|
||||
@ -409,6 +409,23 @@ func (u *User) PreSave() {
|
||||
}
|
||||
}
|
||||
|
||||
// The following are some GraphQL methods necessary to return the
|
||||
// data in float64 type. The spec doesn't support 64 bit integers,
|
||||
// so we have to pass the data in float64. The _ at the end is
|
||||
// a hack to keep the attribute name same in GraphQL schema.
|
||||
|
||||
func (u *User) CreateAt_() float64 {
|
||||
return float64(u.CreateAt)
|
||||
}
|
||||
|
||||
func (u *User) DeleteAt_() float64 {
|
||||
return float64(u.DeleteAt)
|
||||
}
|
||||
|
||||
func (u *User) LastPictureUpdateAt() float64 {
|
||||
return float64(u.LastPictureUpdate)
|
||||
}
|
||||
|
||||
// PreUpdate should be run before updating the user in the db.
|
||||
func (u *User) PreUpdate() {
|
||||
u.Username = SanitizeUnicode(u.Username)
|
||||
@ -630,6 +647,15 @@ func (u *User) GetCustomStatus() *CustomStatus {
|
||||
return o
|
||||
}
|
||||
|
||||
func (u *User) CustomStatus() *CustomStatus {
|
||||
var o *CustomStatus
|
||||
|
||||
data := u.Props[UserPropsKeyCustomStatus]
|
||||
_ = json.Unmarshal([]byte(data), &o)
|
||||
|
||||
return o
|
||||
}
|
||||
|
||||
func (u *User) ClearCustomStatus() {
|
||||
u.MakeNonNil()
|
||||
u.Props[UserPropsKeyCustomStatus] = ""
|
||||
|
2
vendor/github.com/mattermost/mattermost-server/v6/model/user_get.go
generated
vendored
2
vendor/github.com/mattermost/mattermost-server/v6/model/user_get.go
generated
vendored
@ -14,6 +14,8 @@ type UserGetOptions struct {
|
||||
NotInChannelId string
|
||||
// Filters the users in the group
|
||||
InGroupId string
|
||||
// Filters the users not in the group
|
||||
NotInGroupId string
|
||||
// Filters the users group constrained
|
||||
GroupConstrained bool
|
||||
// Filters the users without a team
|
||||
|
1
vendor/github.com/mattermost/mattermost-server/v6/model/user_search.go
generated
vendored
1
vendor/github.com/mattermost/mattermost-server/v6/model/user_search.go
generated
vendored
@ -22,6 +22,7 @@ type UserSearch struct {
|
||||
Roles []string `json:"roles"`
|
||||
ChannelRoles []string `json:"channel_roles"`
|
||||
TeamRoles []string `json:"team_roles"`
|
||||
NotInGroupId string `json:"not_in_group_id"`
|
||||
}
|
||||
|
||||
// UserSearchOptions captures internal parameters derived from the user's permissions and a
|
||||
|
18
vendor/github.com/mattermost/mattermost-server/v6/model/utils.go
generated
vendored
18
vendor/github.com/mattermost/mattermost-server/v6/model/utils.go
generated
vendored
@ -132,6 +132,24 @@ func (m StringMap) Value() (driver.Value, error) {
|
||||
return string(j), err
|
||||
}
|
||||
|
||||
func (StringMap) ImplementsGraphQLType(name string) bool {
|
||||
return name == "StringMap"
|
||||
}
|
||||
|
||||
func (m StringMap) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal((map[string]string)(m))
|
||||
}
|
||||
|
||||
func (m *StringMap) UnmarshalGraphQL(input interface{}) error {
|
||||
json, ok := input.(map[string]string)
|
||||
if !ok {
|
||||
return errors.New("wrong type")
|
||||
}
|
||||
|
||||
*m = json
|
||||
return nil
|
||||
}
|
||||
|
||||
func (si *StringInterface) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
return nil
|
||||
|
3
vendor/github.com/mattermost/mattermost-server/v6/model/version.go
generated
vendored
3
vendor/github.com/mattermost/mattermost-server/v6/model/version.go
generated
vendored
@ -13,8 +13,7 @@ import (
|
||||
// It should be maintained in chronological order with most current
|
||||
// release at the front of the list.
|
||||
var versions = []string{
|
||||
"6.4.2",
|
||||
"6.4.1",
|
||||
"6.5.0",
|
||||
"6.4.0",
|
||||
"6.3.0",
|
||||
"6.2.0",
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user