Update dependencies
This commit is contained in:
parent
7fa68778b7
commit
f6d5064211
116
go.mod
116
go.mod
@ -3,32 +3,33 @@ module github.com/datarhei/core/v16
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/99designs/gqlgen v0.17.20
|
||||
github.com/Masterminds/semver/v3 v3.1.1
|
||||
github.com/99designs/gqlgen v0.17.36
|
||||
github.com/Masterminds/semver/v3 v3.2.1
|
||||
github.com/atrox/haikunatorgo/v2 v2.0.1
|
||||
github.com/caddyserver/certmagic v0.17.2
|
||||
github.com/datarhei/gosrt v0.5.2
|
||||
github.com/caddyserver/certmagic v0.19.2
|
||||
github.com/datarhei/gosrt v0.5.4
|
||||
github.com/datarhei/joy4 v0.0.0-20230505074825-fde05957445a
|
||||
github.com/go-playground/validator/v10 v10.11.1
|
||||
github.com/go-playground/validator/v10 v10.15.3
|
||||
github.com/gobwas/glob v0.2.3
|
||||
github.com/golang-jwt/jwt/v4 v4.4.3
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0
|
||||
github.com/google/uuid v1.3.1
|
||||
github.com/invopop/jsonschema v0.4.0
|
||||
github.com/joho/godotenv v1.4.0
|
||||
github.com/labstack/echo/v4 v4.9.1
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/labstack/echo-jwt v0.0.0-20221127215225-c84d41a71003
|
||||
github.com/labstack/echo/v4 v4.11.1
|
||||
github.com/lithammer/shortuuid/v4 v4.0.0
|
||||
github.com/mattn/go-isatty v0.0.17
|
||||
github.com/minio/minio-go/v7 v7.0.47
|
||||
github.com/mattn/go-isatty v0.0.19
|
||||
github.com/minio/minio-go/v7 v7.0.63
|
||||
github.com/prep/average v0.0.0-20200506183628-d26c465f48c3
|
||||
github.com/prometheus/client_golang v1.14.0
|
||||
github.com/shirou/gopsutil/v3 v3.23.3
|
||||
github.com/prometheus/client_golang v1.16.0
|
||||
github.com/shirou/gopsutil/v3 v3.23.8
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/swaggo/echo-swagger v1.3.5
|
||||
github.com/swaggo/swag v1.8.7
|
||||
github.com/vektah/gqlparser/v2 v2.5.1
|
||||
github.com/swaggo/echo-swagger v1.4.1
|
||||
github.com/swaggo/swag v1.16.2
|
||||
github.com/vektah/gqlparser/v2 v2.5.8
|
||||
github.com/xeipuuv/gojsonschema v1.2.0
|
||||
go.uber.org/zap v1.24.0
|
||||
golang.org/x/mod v0.8.0
|
||||
go.uber.org/zap v1.25.0
|
||||
golang.org/x/mod v0.12.0
|
||||
)
|
||||
|
||||
require (
|
||||
@ -37,70 +38,71 @@ require (
|
||||
github.com/benburkert/openpgp v0.0.0-20160410205803-c2471f86866c // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.0 // indirect
|
||||
github.com/go-openapi/spec v0.20.8 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
github.com/go-playground/locales v0.14.0 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.20.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/spec v0.20.9 // indirect
|
||||
github.com/go-openapi/swag v0.22.4 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.6 // indirect
|
||||
github.com/iancoleman/orderedmap v0.2.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.15.15 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.3 // indirect
|
||||
github.com/klauspost/compress v1.16.7 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
||||
github.com/labstack/gommon v0.4.0 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/libdns/libdns v0.2.1 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mholt/acmez v1.0.4 // indirect
|
||||
github.com/miekg/dns v1.1.50 // indirect
|
||||
github.com/mholt/acmez v1.2.0 // indirect
|
||||
github.com/miekg/dns v1.1.55 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/minio/sha256-simd v1.0.0 // indirect
|
||||
github.com/minio/sha256-simd v1.0.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.39.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.8.1 // indirect
|
||||
github.com/rs/xid v1.4.0 // indirect
|
||||
github.com/prometheus/client_model v0.4.0 // indirect
|
||||
github.com/prometheus/common v0.44.0 // indirect
|
||||
github.com/prometheus/procfs v0.11.1 // indirect
|
||||
github.com/rs/xid v1.5.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.4 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
||||
github.com/tklauser/numcpus v0.6.0 // indirect
|
||||
github.com/urfave/cli/v2 v2.8.1 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/swaggo/files/v2 v2.0.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/urfave/cli/v2 v2.25.5 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/goleak v1.1.12 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
golang.org/x/crypto v0.10.0 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/sys v0.9.0 // indirect
|
||||
golang.org/x/text v0.10.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
github.com/zeebo/blake3 v0.2.3 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.12.0 // indirect
|
||||
golang.org/x/net v0.14.0 // indirect
|
||||
golang.org/x/sys v0.12.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.6.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
golang.org/x/tools v0.12.0 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
365
go.sum
365
go.sum
@ -1,15 +1,9 @@
|
||||
github.com/99designs/gqlgen v0.17.20 h1:O7WzccIhKB1dm+7g6dhQcULINftfiLSBg2l/mwbpJMw=
|
||||
github.com/99designs/gqlgen v0.17.20/go.mod h1:Mja2HI23kWT1VRH09hvWshFgOzKswpO20o4ScpJIES4=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/99designs/gqlgen v0.17.36 h1:u/o/rv2SZ9s5280dyUOOrkpIIkr/7kITMXYD3rkJ9go=
|
||||
github.com/99designs/gqlgen v0.17.36/go.mod h1:6RdyY8puhCoWAQVr2qzF2OMVfudQzc8ACxzpzluoQm4=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY=
|
||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
||||
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
|
||||
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
|
||||
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
|
||||
@ -18,22 +12,20 @@ github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
|
||||
github.com/atrox/haikunatorgo/v2 v2.0.1 h1:FCVx2KL2YvZtI1rI9WeEHxeLRrKGr0Dd4wfCJiUXupc=
|
||||
github.com/atrox/haikunatorgo/v2 v2.0.1/go.mod h1:BBQmx2o+1Z5poziaHRgddAZKOpijwfKdAmMnSYlFK70=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||
github.com/benburkert/openpgp v0.0.0-20160410205803-c2471f86866c h1:8XZeJrs4+ZYhJeJ2aZxADI2tGADS15AzIF8MQ8XAhT4=
|
||||
github.com/benburkert/openpgp v0.0.0-20160410205803-c2471f86866c/go.mod h1:x1vxHcL/9AVzuk5HOloOEPrtJY0MaalYr78afXZ+pWI=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/caddyserver/certmagic v0.17.2 h1:o30seC1T/dBqBCNNGNHWwj2i5/I/FMjBbTAhjADP3nE=
|
||||
github.com/caddyserver/certmagic v0.17.2/go.mod h1:ouWUuC490GOLJzkyN35eXfV8bSbwMwSf4bdhkIxtdQE=
|
||||
github.com/caddyserver/certmagic v0.19.2 h1:HZd1AKLx4592MalEGQS39DKs2ZOAJCEM/xYPMQ2/ui0=
|
||||
github.com/caddyserver/certmagic v0.19.2/go.mod h1:fsL01NomQ6N+kE2j37ZCnig2MFosG+MIO4ztnmG/zz8=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
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.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/datarhei/gosrt v0.5.2 h1:eagqZwEIiGPNJW0rLep3gwceObyaZ17+iKRc+l4VEpc=
|
||||
github.com/datarhei/gosrt v0.5.2/go.mod h1:0308GQhAu5hxe2KYdbss901aKceSSKXnwCr8Vs++eiw=
|
||||
github.com/datarhei/gosrt v0.5.4 h1:dE3mmSB+n1GeviGM8xQAW3+UD3mKeFmd84iefDul5Vs=
|
||||
github.com/datarhei/gosrt v0.5.4/go.mod h1:MiUCwCG+LzFMzLM/kTA+3wiTtlnkVvGbW/F0XzyhtG8=
|
||||
github.com/datarhei/joy4 v0.0.0-20230505074825-fde05957445a h1:Tf4DSHY1xruBglr+yYP5Wct7czM86GKMYgbXH8a7OFo=
|
||||
github.com/datarhei/joy4 v0.0.0-20230505074825-fde05957445a/go.mod h1:Jcw/6jZDQQmPx8A7INEkXmuEF7E9jjBbSTfVSLwmiQw=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -43,122 +35,122 @@ github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+
|
||||
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
|
||||
github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA=
|
||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||
github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ=
|
||||
github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA=
|
||||
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
|
||||
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
|
||||
github.com/go-openapi/spec v0.20.8 h1:ubHmXNY3FCIOinT8RNrrPfGc9t7I1qhPtdOGoG2AxRU=
|
||||
github.com/go-openapi/spec v0.20.8/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
|
||||
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
||||
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
||||
github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8=
|
||||
github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
|
||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
|
||||
github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
|
||||
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
|
||||
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.15.3 h1:S+sSpunYjNPDuXkWbK+x+bA7iXiW296KG4dL3X7xUZo=
|
||||
github.com/go-playground/validator/v10 v10.15.3/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
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/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.6 h1:3xi/Cafd1NaoEnS/yDssIiuVeDVywU0QdFGl3aQaQHM=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.6/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
|
||||
github.com/iancoleman/orderedmap v0.2.0 h1:sq1N/TFpYH++aViPcaKjys3bDClUEU7s5B+z6jq8pNA=
|
||||
github.com/iancoleman/orderedmap v0.2.0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
|
||||
github.com/invopop/jsonschema v0.4.0 h1:Yuy/unfgCnfV5Wl7H0HgFufp/rlurqPOOuacqyByrws=
|
||||
github.com/invopop/jsonschema v0.4.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0=
|
||||
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
|
||||
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM=
|
||||
github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw=
|
||||
github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4=
|
||||
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
|
||||
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
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.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU=
|
||||
github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
||||
github.com/labstack/echo/v4 v4.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+Y=
|
||||
github.com/labstack/echo/v4 v4.9.1/go.mod h1:Pop5HLc+xoc4qhTZ1ip6C0RtP7Z+4VzRLWZZFKqbbjo=
|
||||
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/labstack/echo-jwt v0.0.0-20221127215225-c84d41a71003 h1:FyalHKl9hnJvhNbrABJXXjC2hG7gvIF0ioW9i0xHNQU=
|
||||
github.com/labstack/echo-jwt v0.0.0-20221127215225-c84d41a71003/go.mod h1:ovRFgyKvi73jQIFCWz9ByQwzhIyohkzY0MFAlPGyr8Q=
|
||||
github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4=
|
||||
github.com/labstack/echo/v4 v4.11.1/go.mod h1:YuYRTSM3CHs2ybfrL8Px48bO6BAnYIN4l8wSTMP6BDQ=
|
||||
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
|
||||
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis=
|
||||
github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
|
||||
github.com/lithammer/shortuuid/v4 v4.0.0 h1:QRbbVkfgNippHOS8PXDkti4NaWeyYfcBTHtw7k08o4c=
|
||||
github.com/lithammer/shortuuid/v4 v4.0.0/go.mod h1:Zs8puNcrvf2rV9rTH51ZLLcj7ZXqQI3lv67aw4KiB1Y=
|
||||
github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c h1:VtwQ41oftZwlMnOEbMWQtSEUgU64U4s+GHk7hZK+jtY=
|
||||
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE=
|
||||
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a h1:N9zuLhTvBSRt0gWSiJswwQ2HqDmtX/ZCDJURnKUt1Ik=
|
||||
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk=
|
||||
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/mholt/acmez v1.0.4 h1:N3cE4Pek+dSolbsofIkAYz6H1d3pE+2G0os7QHslf80=
|
||||
github.com/mholt/acmez v1.0.4/go.mod h1:qFGLZ4u+ehWINeJZjzPlsnjJBCPAADWTcIqE/7DAYQY=
|
||||
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
||||
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30=
|
||||
github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE=
|
||||
github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo=
|
||||
github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
|
||||
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.47 h1:sLiuCKGSIcn/MI6lREmTzX91DX/oRau4ia0j6e6eOSs=
|
||||
github.com/minio/minio-go/v7 v7.0.47/go.mod h1:nCrRzjoSUQh8hgKKtu3Y708OLvRLtuASMg2/nvmbarw=
|
||||
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
|
||||
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
|
||||
github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/minio/minio-go/v7 v7.0.63 h1:GbZ2oCvaUdgT5640WJOpyDhhDxvknAJU2/T3yurwcbQ=
|
||||
github.com/minio/minio-go/v7 v7.0.63/go.mod h1:Q6X7Qjb7WMhvG65qKf4gUgA5XaiSox74kR1uAEjxRS4=
|
||||
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
|
||||
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@ -167,15 +159,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U=
|
||||
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
|
||||
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
|
||||
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
|
||||
github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
@ -184,36 +167,29 @@ github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3g
|
||||
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/prep/average v0.0.0-20200506183628-d26c465f48c3 h1:Y7qCvg282QmlyrVQuL2fgGwebuw7zvfnRym09r+dUGc=
|
||||
github.com/prep/average v0.0.0-20200506183628-d26c465f48c3/go.mod h1:0ZE5gcyWKS151WBDIpmLshHY0l+3edpuKnBUWVVbWKk=
|
||||
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
|
||||
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
|
||||
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
||||
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
||||
github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI=
|
||||
github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y=
|
||||
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
|
||||
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
|
||||
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
|
||||
github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY=
|
||||
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
|
||||
github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
|
||||
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
|
||||
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
|
||||
github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
|
||||
github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
|
||||
github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI=
|
||||
github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shirou/gopsutil/v3 v3.23.3 h1:Syt5vVZXUDXPEXpIBt5ziWsJ4LdSAAxF4l/xZeQgSEE=
|
||||
github.com/shirou/gopsutil/v3 v3.23.3/go.mod h1:lSBNN6t3+D6W5e5nXTxc8KIMMVxAcS+6IJlffjRRlMU=
|
||||
github.com/shoenig/go-m1cpu v0.1.4 h1:SZPIgRM2sEF9NJy50mRHu9PKGwxyyTTJIWvCtgVbozs=
|
||||
github.com/shoenig/go-m1cpu v0.1.4/go.mod h1:Wwvst4LR89UxjeFtLRMrpgRiyY4xPsejnVZym39dbAQ=
|
||||
github.com/shoenig/test v0.6.3 h1:GVXWJFk9PiOjN0KoJ7VrJGH6uLPnqxR7/fe3HUPfE0c=
|
||||
github.com/shoenig/test v0.6.3/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
|
||||
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
|
||||
github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE=
|
||||
github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ=
|
||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
@ -224,30 +200,29 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/swaggo/echo-swagger v1.3.5 h1:kCx1wvX5AKhjI6Ykt48l3PTsfL9UD40ZROOx/tYzWyY=
|
||||
github.com/swaggo/echo-swagger v1.3.5/go.mod h1:3IMHd2Z8KftdWFEEjGmv6QpWj370LwMCOfovuh7vF34=
|
||||
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a h1:kAe4YSu0O0UFn1DowNo2MY5p6xzqtJ/wQ7LZynSvGaY=
|
||||
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w=
|
||||
github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ=
|
||||
github.com/swaggo/swag v1.8.7 h1:2K9ivTD3teEO+2fXV6zrZKDqk5IuU2aJtBDo8U7omWU=
|
||||
github.com/swaggo/swag v1.8.7/go.mod h1:ezQVUUhly8dludpVk+/PuwJWvLLanB13ygV5Pr9enSk=
|
||||
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
|
||||
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
|
||||
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
|
||||
github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/urfave/cli/v2 v2.8.1 h1:CGuYNZF9IKZY/rfBe3lJpccSoIY1ytfvmgQT90cNOl4=
|
||||
github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY=
|
||||
github.com/swaggo/echo-swagger v1.4.1 h1:Yf0uPaJWp1uRtDloZALyLnvdBeoEL5Kc7DtnjzO/TUk=
|
||||
github.com/swaggo/echo-swagger v1.4.1/go.mod h1:C8bSi+9yH2FLZsnhqMZLIZddpUxZdBYuNHbtaS1Hljc=
|
||||
github.com/swaggo/files/v2 v2.0.0 h1:hmAt8Dkynw7Ssz46F6pn8ok6YmGZqHSVLZ+HQM7i0kw=
|
||||
github.com/swaggo/files/v2 v2.0.0/go.mod h1:24kk2Y9NYEJ5lHuCra6iVwkMjIekMCaFq/0JQj66kyM=
|
||||
github.com/swaggo/swag v1.16.2 h1:28Pp+8DkQoV+HLzLx8RGJZXNGKbFqnuvSbAAtoxiY04=
|
||||
github.com/swaggo/swag v1.16.2/go.mod h1:6YzXnDcpr0767iOejs318CwYkCQqyGer6BizOg03f+E=
|
||||
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||
github.com/urfave/cli/v2 v2.25.5 h1:d0NIAyhh5shGscroL7ek/Ya9QYQE0KNabJgiUinIQkc=
|
||||
github.com/urfave/cli/v2 v2.25.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/vektah/gqlparser/v2 v2.5.1 h1:ZGu+bquAY23jsxDRcYpWjttRZrUz07LbiY77gUOHcr4=
|
||||
github.com/vektah/gqlparser/v2 v2.5.1/go.mod h1:mPgqFBu/woKTVYWyNk8cO3kh4S/f4aRFZrvOnp3hmCs=
|
||||
github.com/vektah/gqlparser/v2 v2.5.8 h1:pm6WOnGdzFOCfcQo9L3+xzW51mKrlwTEg4Wr7AH1JW4=
|
||||
github.com/vektah/gqlparser/v2 v2.5.8/go.mod h1:z8xXUff237NntSuH8mLFijZ+1tjV1swDbpDqjJmk6ME=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
@ -257,129 +232,61 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
|
||||
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
|
||||
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
|
||||
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
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-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
|
||||
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
||||
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
|
||||
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
|
||||
github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg=
|
||||
github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ=
|
||||
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
|
||||
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
|
||||
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c=
|
||||
go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk=
|
||||
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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-20210927094055-39ccf1dd6fa6/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-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
|
||||
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss=
|
||||
golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -13,6 +13,9 @@ import (
|
||||
|
||||
type IProcessReportHistoryEntry interface {
|
||||
IsIProcessReportHistoryEntry()
|
||||
GetCreatedAt() time.Time
|
||||
GetPrelude() []string
|
||||
GetLog() []*ProcessReportLogEntry
|
||||
}
|
||||
|
||||
type AVStream struct {
|
||||
@ -55,24 +58,24 @@ type AboutVersion struct {
|
||||
|
||||
type Metric struct {
|
||||
Name string `json:"name"`
|
||||
Labels map[string]interface{} `json:"labels"`
|
||||
Labels map[string]interface{} `json:"labels,omitempty"`
|
||||
Values []*scalars.MetricsResponseValue `json:"values"`
|
||||
}
|
||||
|
||||
type MetricInput struct {
|
||||
Name string `json:"name"`
|
||||
Labels map[string]interface{} `json:"labels"`
|
||||
Labels map[string]interface{} `json:"labels,omitempty"`
|
||||
}
|
||||
|
||||
type Metrics struct {
|
||||
TimerangeSeconds *int `json:"timerange_seconds"`
|
||||
IntervalSeconds *int `json:"interval_seconds"`
|
||||
TimerangeSeconds *int `json:"timerange_seconds,omitempty"`
|
||||
IntervalSeconds *int `json:"interval_seconds,omitempty"`
|
||||
Metrics []*Metric `json:"metrics"`
|
||||
}
|
||||
|
||||
type MetricsInput struct {
|
||||
TimerangeSeconds *int `json:"timerange_seconds"`
|
||||
IntervalSeconds *int `json:"interval_seconds"`
|
||||
TimerangeSeconds *int `json:"timerange_seconds,omitempty"`
|
||||
IntervalSeconds *int `json:"interval_seconds,omitempty"`
|
||||
Metrics []*MetricInput `json:"metrics"`
|
||||
}
|
||||
|
||||
@ -108,7 +111,7 @@ type Process struct {
|
||||
Config *ProcessConfig `json:"config"`
|
||||
State *ProcessState `json:"state"`
|
||||
Report *ProcessReport `json:"report"`
|
||||
Metadata map[string]interface{} `json:"metadata"`
|
||||
Metadata map[string]interface{} `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
type ProcessConfig struct {
|
||||
@ -145,6 +148,27 @@ type ProcessReport struct {
|
||||
}
|
||||
|
||||
func (ProcessReport) IsIProcessReportHistoryEntry() {}
|
||||
func (this ProcessReport) GetCreatedAt() time.Time { return this.CreatedAt }
|
||||
func (this ProcessReport) GetPrelude() []string {
|
||||
if this.Prelude == nil {
|
||||
return nil
|
||||
}
|
||||
interfaceSlice := make([]string, 0, len(this.Prelude))
|
||||
for _, concrete := range this.Prelude {
|
||||
interfaceSlice = append(interfaceSlice, concrete)
|
||||
}
|
||||
return interfaceSlice
|
||||
}
|
||||
func (this ProcessReport) GetLog() []*ProcessReportLogEntry {
|
||||
if this.Log == nil {
|
||||
return nil
|
||||
}
|
||||
interfaceSlice := make([]*ProcessReportLogEntry, 0, len(this.Log))
|
||||
for _, concrete := range this.Log {
|
||||
interfaceSlice = append(interfaceSlice, concrete)
|
||||
}
|
||||
return interfaceSlice
|
||||
}
|
||||
|
||||
type ProcessReportHistoryEntry struct {
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
@ -153,6 +177,27 @@ type ProcessReportHistoryEntry struct {
|
||||
}
|
||||
|
||||
func (ProcessReportHistoryEntry) IsIProcessReportHistoryEntry() {}
|
||||
func (this ProcessReportHistoryEntry) GetCreatedAt() time.Time { return this.CreatedAt }
|
||||
func (this ProcessReportHistoryEntry) GetPrelude() []string {
|
||||
if this.Prelude == nil {
|
||||
return nil
|
||||
}
|
||||
interfaceSlice := make([]string, 0, len(this.Prelude))
|
||||
for _, concrete := range this.Prelude {
|
||||
interfaceSlice = append(interfaceSlice, concrete)
|
||||
}
|
||||
return interfaceSlice
|
||||
}
|
||||
func (this ProcessReportHistoryEntry) GetLog() []*ProcessReportLogEntry {
|
||||
if this.Log == nil {
|
||||
return nil
|
||||
}
|
||||
interfaceSlice := make([]*ProcessReportLogEntry, 0, len(this.Log))
|
||||
for _, concrete := range this.Log {
|
||||
interfaceSlice = append(interfaceSlice, concrete)
|
||||
}
|
||||
return interfaceSlice
|
||||
}
|
||||
|
||||
type ProcessReportLogEntry struct {
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
@ -208,7 +253,7 @@ type ProgressIo struct {
|
||||
Sampling scalars.Uint64 `json:"sampling"`
|
||||
Layout string `json:"layout"`
|
||||
Channels scalars.Uint64 `json:"channels"`
|
||||
Avstream *AVStream `json:"avstream"`
|
||||
Avstream *AVStream `json:"avstream,omitempty"`
|
||||
}
|
||||
|
||||
type RawAVstream struct {
|
||||
@ -223,7 +268,7 @@ type RawAVstream struct {
|
||||
Looping bool `json:"looping"`
|
||||
Duplicating bool `json:"duplicating"`
|
||||
Gop string `json:"gop"`
|
||||
Debug interface{} `json:"debug"`
|
||||
Debug interface{} `json:"debug,omitempty"`
|
||||
Input *RawAVstreamIo `json:"input"`
|
||||
Output *RawAVstreamIo `json:"output"`
|
||||
Swap *RawAVstreamSwap `json:"swap"`
|
||||
@ -292,17 +337,17 @@ type State string
|
||||
|
||||
const (
|
||||
StateRunning State = "RUNNING"
|
||||
StateIDLe State = "IDLE"
|
||||
StateIdle State = "IDLE"
|
||||
)
|
||||
|
||||
var AllState = []State{
|
||||
StateRunning,
|
||||
StateIDLe,
|
||||
StateIdle,
|
||||
}
|
||||
|
||||
func (e State) IsValid() bool {
|
||||
switch e {
|
||||
case StateRunning, StateIDLe:
|
||||
case StateRunning, StateIdle:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
@ -2,6 +2,7 @@ package resolver
|
||||
|
||||
// This file will be automatically regenerated based on the schema, any resolver implementations
|
||||
// will be copied through when generating and any unknown code will be moved to the end.
|
||||
// Code generated by github.com/99designs/gqlgen version v0.17.36
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -12,6 +13,7 @@ import (
|
||||
"github.com/datarhei/core/v16/http/graph/scalars"
|
||||
)
|
||||
|
||||
// About is the resolver for the about field.
|
||||
func (r *queryResolver) About(ctx context.Context) (*models.About, error) {
|
||||
createdAt := r.Restream.CreatedAt()
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ package resolver
|
||||
|
||||
// This file will be automatically regenerated based on the schema, any resolver implementations
|
||||
// will be copied through when generating and any unknown code will be moved to the end.
|
||||
// Code generated by github.com/99designs/gqlgen version v0.17.36
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -10,6 +11,7 @@ import (
|
||||
"github.com/datarhei/core/v16/log"
|
||||
)
|
||||
|
||||
// Log is the resolver for the log field.
|
||||
func (r *queryResolver) Log(ctx context.Context) ([]string, error) {
|
||||
if r.LogBuffer == nil {
|
||||
r.LogBuffer = log.NewBufferWriter(log.Lsilent, 1)
|
||||
|
||||
@ -2,6 +2,7 @@ package resolver
|
||||
|
||||
// This file will be automatically regenerated based on the schema, any resolver implementations
|
||||
// will be copied through when generating and any unknown code will be moved to the end.
|
||||
// Code generated by github.com/99designs/gqlgen version v0.17.36
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -12,6 +13,7 @@ import (
|
||||
"github.com/datarhei/core/v16/monitor/metric"
|
||||
)
|
||||
|
||||
// Metrics is the resolver for the metrics field.
|
||||
func (r *queryResolver) Metrics(ctx context.Context, query models.MetricsInput) (*models.Metrics, error) {
|
||||
patterns := []metric.Pattern{}
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ package resolver
|
||||
|
||||
// This file will be automatically regenerated based on the schema, any resolver implementations
|
||||
// will be copied through when generating and any unknown code will be moved to the end.
|
||||
// Code generated by github.com/99designs/gqlgen version v0.17.36
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -13,6 +14,7 @@ import (
|
||||
"github.com/datarhei/core/v16/playout"
|
||||
)
|
||||
|
||||
// PlayoutStatus is the resolver for the playoutStatus field.
|
||||
func (r *queryResolver) PlayoutStatus(ctx context.Context, id string, input string) (*models.RawAVstream, error) {
|
||||
addr, err := r.Restream.GetPlayout(id, input)
|
||||
if err != nil {
|
||||
|
||||
@ -2,6 +2,7 @@ package resolver
|
||||
|
||||
// This file will be automatically regenerated based on the schema, any resolver implementations
|
||||
// will be copied through when generating and any unknown code will be moved to the end.
|
||||
// Code generated by github.com/99designs/gqlgen version v0.17.36
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -9,6 +10,7 @@ import (
|
||||
"github.com/datarhei/core/v16/http/graph/models"
|
||||
)
|
||||
|
||||
// Processes is the resolver for the processes field.
|
||||
func (r *queryResolver) Processes(ctx context.Context) ([]*models.Process, error) {
|
||||
ids := r.Restream.GetProcessIDs("", "")
|
||||
|
||||
@ -26,10 +28,12 @@ func (r *queryResolver) Processes(ctx context.Context) ([]*models.Process, error
|
||||
return procs, nil
|
||||
}
|
||||
|
||||
// Process is the resolver for the process field.
|
||||
func (r *queryResolver) Process(ctx context.Context, id string) (*models.Process, error) {
|
||||
return r.getProcess(id)
|
||||
}
|
||||
|
||||
// Probe is the resolver for the probe field.
|
||||
func (r *queryResolver) Probe(ctx context.Context, id string) (*models.Probe, error) {
|
||||
probe := r.Restream.Probe(id)
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ package resolver
|
||||
|
||||
// This file will be automatically regenerated based on the schema, any resolver implementations
|
||||
// will be copied through when generating and any unknown code will be moved to the end.
|
||||
// Code generated by github.com/99designs/gqlgen version v0.17.36
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -9,10 +10,12 @@ import (
|
||||
"github.com/datarhei/core/v16/http/graph/graph"
|
||||
)
|
||||
|
||||
// Ping is the resolver for the ping field.
|
||||
func (r *mutationResolver) Ping(ctx context.Context) (string, error) {
|
||||
return "pong", nil
|
||||
}
|
||||
|
||||
// Ping is the resolver for the ping field.
|
||||
func (r *queryResolver) Ping(ctx context.Context) (string, error) {
|
||||
return "pong", nil
|
||||
}
|
||||
|
||||
@ -10,8 +10,9 @@ import (
|
||||
"github.com/datarhei/core/v16/app"
|
||||
"github.com/datarhei/core/v16/http/api"
|
||||
|
||||
jwtgo "github.com/golang-jwt/jwt/v4"
|
||||
jwtgo "github.com/golang-jwt/jwt/v5"
|
||||
"github.com/google/uuid"
|
||||
echojwt "github.com/labstack/echo-jwt"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
)
|
||||
@ -47,10 +48,10 @@ type jwt struct {
|
||||
skipLocalhost bool
|
||||
secret []byte
|
||||
accessValidFor time.Duration
|
||||
accessConfig middleware.JWTConfig
|
||||
accessConfig echojwt.Config
|
||||
accessMiddleware echo.MiddlewareFunc
|
||||
refreshValidFor time.Duration
|
||||
refreshConfig middleware.JWTConfig
|
||||
refreshConfig echojwt.Config
|
||||
refreshMiddleware echo.MiddlewareFunc
|
||||
// Validators is a map of all recognized issuers to their specific validators. The key is the value of
|
||||
// the "iss" field in the claims. Somewhat required because otherwise the token cannot be verified.
|
||||
@ -84,35 +85,31 @@ func New(config Config) (JWT, error) {
|
||||
return false
|
||||
}
|
||||
|
||||
j.accessConfig = middleware.JWTConfig{
|
||||
Skipper: skipperFunc,
|
||||
SigningMethod: middleware.AlgorithmHS256,
|
||||
ContextKey: "user",
|
||||
TokenLookup: "header:" + echo.HeaderAuthorization,
|
||||
AuthScheme: "Bearer",
|
||||
Claims: jwtgo.MapClaims{},
|
||||
ErrorHandlerWithContext: j.ErrorHandler,
|
||||
ParseTokenFunc: j.parseToken("access"),
|
||||
j.accessConfig = echojwt.Config{
|
||||
Skipper: skipperFunc,
|
||||
SigningMethod: middleware.AlgorithmHS256,
|
||||
ContextKey: "user",
|
||||
TokenLookup: "header:Authorization:Bearer ",
|
||||
ErrorHandler: j.ErrorHandler,
|
||||
ParseTokenFunc: j.parseToken("access"),
|
||||
}
|
||||
|
||||
j.refreshConfig = middleware.JWTConfig{
|
||||
Skipper: skipperFunc,
|
||||
SigningMethod: middleware.AlgorithmHS256,
|
||||
ContextKey: "user",
|
||||
TokenLookup: "header:" + echo.HeaderAuthorization,
|
||||
AuthScheme: "Bearer",
|
||||
Claims: jwtgo.MapClaims{},
|
||||
ErrorHandlerWithContext: j.ErrorHandler,
|
||||
ParseTokenFunc: j.parseToken("refresh"),
|
||||
j.refreshConfig = echojwt.Config{
|
||||
Skipper: skipperFunc,
|
||||
SigningMethod: middleware.AlgorithmHS256,
|
||||
ContextKey: "user",
|
||||
TokenLookup: "header:Authorization:Bearer ",
|
||||
ErrorHandler: j.ErrorHandler,
|
||||
ParseTokenFunc: j.parseToken("refresh"),
|
||||
}
|
||||
|
||||
return j, nil
|
||||
}
|
||||
|
||||
func (j *jwt) parseToken(use string) func(auth string, c echo.Context) (interface{}, error) {
|
||||
func (j *jwt) parseToken(use string) func(c echo.Context, auth string) (interface{}, error) {
|
||||
keyFunc := func(*jwtgo.Token) (interface{}, error) { return j.secret, nil }
|
||||
|
||||
return func(auth string, c echo.Context) (interface{}, error) {
|
||||
return func(c echo.Context, auth string) (interface{}, error) {
|
||||
var token *jwtgo.Token
|
||||
var err error
|
||||
|
||||
@ -184,7 +181,7 @@ func (j *jwt) ClearValidators() {
|
||||
j.validators = nil
|
||||
}
|
||||
|
||||
func (j *jwt) ErrorHandler(err error, c echo.Context) error {
|
||||
func (j *jwt) ErrorHandler(c echo.Context, err error) error {
|
||||
if c.Request().URL.Path == "/api" {
|
||||
return c.JSON(http.StatusOK, api.MinimalAbout{
|
||||
App: app.Name,
|
||||
@ -195,12 +192,12 @@ func (j *jwt) ErrorHandler(err error, c echo.Context) error {
|
||||
})
|
||||
}
|
||||
|
||||
return api.Err(http.StatusUnauthorized, "Missing or invalid JWT token")
|
||||
return api.Err(http.StatusUnauthorized, "", "Missing or invalid JWT token")
|
||||
}
|
||||
|
||||
func (j *jwt) AccessMiddleware() echo.MiddlewareFunc {
|
||||
if j.accessMiddleware == nil {
|
||||
j.accessMiddleware = middleware.JWTWithConfig(j.accessConfig)
|
||||
j.accessMiddleware = echojwt.WithConfig(j.accessConfig)
|
||||
}
|
||||
|
||||
return j.accessMiddleware
|
||||
@ -208,7 +205,7 @@ func (j *jwt) AccessMiddleware() echo.MiddlewareFunc {
|
||||
|
||||
func (j *jwt) RefreshMiddleware() echo.MiddlewareFunc {
|
||||
if j.refreshMiddleware == nil {
|
||||
j.refreshMiddleware = middleware.JWTWithConfig(j.refreshConfig)
|
||||
j.refreshMiddleware = echojwt.WithConfig(j.refreshConfig)
|
||||
}
|
||||
|
||||
return j.refreshMiddleware
|
||||
@ -243,16 +240,16 @@ func (j *jwt) LoginHandler(c echo.Context) error {
|
||||
if ok {
|
||||
if err != nil {
|
||||
time.Sleep(5 * time.Second)
|
||||
return api.Err(http.StatusUnauthorized, "Invalid authorization credentials", "%s", err)
|
||||
return api.Err(http.StatusUnauthorized, "", "Invalid authorization credentials: %s", err.Error())
|
||||
}
|
||||
} else {
|
||||
time.Sleep(5 * time.Second)
|
||||
return api.Err(http.StatusBadRequest, "Missing authorization credentials")
|
||||
return api.Err(http.StatusBadRequest, "", "Missing authorization credentials")
|
||||
}
|
||||
|
||||
at, rt, err := j.createToken(subject)
|
||||
if err != nil {
|
||||
return api.Err(http.StatusInternalServerError, "Failed to create JWT", "%s", err)
|
||||
return api.Err(http.StatusInternalServerError, "", "Failed to create JWT: %s", err.Error())
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, api.JWT{
|
||||
@ -273,14 +270,17 @@ func (j *jwt) LoginHandler(c echo.Context) error {
|
||||
func (j *jwt) RefreshHandler(c echo.Context) error {
|
||||
token, ok := c.Get("user").(*jwtgo.Token)
|
||||
if !ok {
|
||||
return api.Err(http.StatusForbidden, "Invalid token")
|
||||
return api.Err(http.StatusForbidden, "", "Invalid token")
|
||||
}
|
||||
|
||||
subject := token.Claims.(jwtgo.MapClaims)["sub"].(string)
|
||||
subject, err := token.Claims.GetSubject()
|
||||
if err != nil {
|
||||
return api.Err(http.StatusForbidden, "", "Invalid subject: %s", err.Error())
|
||||
}
|
||||
|
||||
at, _, err := j.createToken(subject)
|
||||
if err != nil {
|
||||
return api.Err(http.StatusInternalServerError, "Failed to create JWT", "%s", err)
|
||||
return api.Err(http.StatusInternalServerError, "", "Failed to create JWT: %s", err.Error())
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, api.JWTRefresh{
|
||||
|
||||
@ -8,7 +8,7 @@ import (
|
||||
"github.com/datarhei/core/v16/http/handler/util"
|
||||
"github.com/datarhei/core/v16/http/jwt/jwks"
|
||||
|
||||
jwtgo "github.com/golang-jwt/jwt/v4"
|
||||
jwtgo "github.com/golang-jwt/jwt/v5"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
@ -148,23 +148,21 @@ func (v *auth0Validator) Validate(c echo.Context) (bool, string, error) {
|
||||
|
||||
func (v *auth0Validator) keyFunc(token *jwtgo.Token) (interface{}, error) {
|
||||
// Verify 'aud' claim
|
||||
checkAud := token.Claims.(jwtgo.MapClaims).VerifyAudience(v.audience, false)
|
||||
if !checkAud {
|
||||
return nil, fmt.Errorf("invalid audience")
|
||||
if _, err := token.Claims.GetAudience(); err != nil {
|
||||
return nil, fmt.Errorf("invalid audience: %w", err)
|
||||
}
|
||||
|
||||
// Verify 'iss' claim
|
||||
checkIss := token.Claims.(jwtgo.MapClaims).VerifyIssuer(v.issuer, false)
|
||||
if !checkIss {
|
||||
return nil, fmt.Errorf("invalid issuer")
|
||||
if _, err := token.Claims.GetIssuer(); err != nil {
|
||||
return nil, fmt.Errorf("invalid issuer: %w", err)
|
||||
}
|
||||
|
||||
// Verify 'sub' claim
|
||||
if _, ok := token.Claims.(jwtgo.MapClaims)["sub"]; !ok {
|
||||
return nil, fmt.Errorf("sub claim is required")
|
||||
sub, err := token.Claims.GetSubject()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid subject: %w", err)
|
||||
}
|
||||
|
||||
sub := token.Claims.(jwtgo.MapClaims)["sub"].(string)
|
||||
found := false
|
||||
for _, u := range v.users {
|
||||
if sub == u {
|
||||
|
||||
4
vendor/github.com/99designs/gqlgen/.golangci.yml
generated
vendored
4
vendor/github.com/99designs/gqlgen/.golangci.yml
generated
vendored
@ -11,8 +11,6 @@ linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- bodyclose
|
||||
- deadcode
|
||||
- depguard
|
||||
- dupl
|
||||
- errcheck
|
||||
- gocritic
|
||||
@ -25,11 +23,9 @@ linters:
|
||||
- nakedret
|
||||
- prealloc
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- typecheck
|
||||
- unconvert
|
||||
- unused
|
||||
- varcheck
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
|
||||
1115
vendor/github.com/99designs/gqlgen/CHANGELOG.md
generated
vendored
1115
vendor/github.com/99designs/gqlgen/CHANGELOG.md
generated
vendored
File diff suppressed because it is too large
Load Diff
7
vendor/github.com/99designs/gqlgen/README.md
generated
vendored
7
vendor/github.com/99designs/gqlgen/README.md
generated
vendored
@ -22,13 +22,16 @@ Still not convinced enough to use **gqlgen**? Compare **gqlgen** with other Go g
|
||||
|
||||
2. Add `github.com/99designs/gqlgen` to your [project's tools.go](https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module)
|
||||
|
||||
printf '// +build tools\npackage tools\nimport _ "github.com/99designs/gqlgen"' | gofmt > tools.go
|
||||
printf '// +build tools\npackage tools\nimport (_ "github.com/99designs/gqlgen"\n _ "github.com/99designs/gqlgen/graphql/introspection")' | gofmt > tools.go
|
||||
|
||||
go mod tidy
|
||||
|
||||
3. Initialise gqlgen config and generate models
|
||||
|
||||
go run github.com/99designs/gqlgen init
|
||||
|
||||
go mod tidy
|
||||
|
||||
4. Start the graphql server
|
||||
|
||||
go run server.go
|
||||
@ -113,7 +116,7 @@ directive @goModel(model: String, models: [String!]) on OBJECT
|
||||
| INTERFACE
|
||||
| UNION
|
||||
|
||||
directive @goField(forceResolver: Boolean, name: String) on INPUT_FIELD_DEFINITION
|
||||
directive @goField(forceResolver: Boolean, name: String, omittable: Boolean) on INPUT_FIELD_DEFINITION
|
||||
| FIELD_DEFINITION
|
||||
|
||||
type User @goModel(model: "github.com/you/pkg/model.User") {
|
||||
|
||||
7
vendor/github.com/99designs/gqlgen/RELEASE-CHECKLIST.md
generated
vendored
7
vendor/github.com/99designs/gqlgen/RELEASE-CHECKLIST.md
generated
vendored
@ -6,9 +6,10 @@ Assuming the next version is $NEW_VERSION=v0.16.0 or something like that.
|
||||
./bin/release $NEW_VERSION
|
||||
```
|
||||
2. git-chglog -o CHANGELOG.md
|
||||
3. git commit and push the CHANGELOG.md
|
||||
4. Go to https://github.com/99designs/gqlgen/releases and draft new release, autogenerate the release notes, and Create a discussion for this release
|
||||
5. Comment on the release discussion with any really important notes (breaking changes)
|
||||
3. go generate ./...; cd _examples; go generate ./...; cd ..
|
||||
4. git commit and push the CHANGELOG.md
|
||||
5. Go to https://github.com/99designs/gqlgen/releases and draft new release, autogenerate the release notes, and Create a discussion for this release
|
||||
6. Comment on the release discussion with any really important notes (breaking changes)
|
||||
|
||||
I used https://github.com/git-chglog/git-chglog to automate the changelog maintenance process for now. We could just as easily use go releaser to make the whole thing automated.
|
||||
|
||||
|
||||
3
vendor/github.com/99designs/gqlgen/TESTING.md
generated
vendored
3
vendor/github.com/99designs/gqlgen/TESTING.md
generated
vendored
@ -36,5 +36,4 @@ npm install
|
||||
|
||||
will write the schema to `integration/schema-fetched.graphql`, compare that with `schema-expected.graphql`
|
||||
|
||||
CI will run this and fail the build if the two files dont match.
|
||||
|
||||
CI will run this and fail the build if the two files don't match.
|
||||
|
||||
6
vendor/github.com/99designs/gqlgen/api/generate.go
generated
vendored
6
vendor/github.com/99designs/gqlgen/api/generate.go
generated
vendored
@ -83,7 +83,11 @@ func Generate(cfg *config.Config, option ...Option) error {
|
||||
}
|
||||
}
|
||||
// Merge again now that the generated models have been injected into the typemap
|
||||
data, err := codegen.BuildData(cfg)
|
||||
data_plugins := make([]interface{}, len(plugins))
|
||||
for index := range plugins {
|
||||
data_plugins[index] = plugins[index]
|
||||
}
|
||||
data, err := codegen.BuildData(cfg, data_plugins...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("merging type systems failed: %w", err)
|
||||
}
|
||||
|
||||
10
vendor/github.com/99designs/gqlgen/codegen/args.go
generated
vendored
10
vendor/github.com/99designs/gqlgen/codegen/args.go
generated
vendored
@ -103,9 +103,9 @@ nextArg:
|
||||
return newArgs, nil
|
||||
}
|
||||
|
||||
func (a *Data) Args() map[string][]*FieldArgument {
|
||||
func (d *Data) Args() map[string][]*FieldArgument {
|
||||
ret := map[string][]*FieldArgument{}
|
||||
for _, o := range a.Objects {
|
||||
for _, o := range d.Objects {
|
||||
for _, f := range o.Fields {
|
||||
if len(f.Args) > 0 {
|
||||
ret[f.ArgsFunc()] = f.Args
|
||||
@ -113,9 +113,9 @@ func (a *Data) Args() map[string][]*FieldArgument {
|
||||
}
|
||||
}
|
||||
|
||||
for _, d := range a.Directives() {
|
||||
if len(d.Args) > 0 {
|
||||
ret[d.ArgsFunc()] = d.Args
|
||||
for _, directive := range d.Directives() {
|
||||
if len(directive.Args) > 0 {
|
||||
ret[directive.ArgsFunc()] = directive.Args
|
||||
}
|
||||
}
|
||||
return ret
|
||||
|
||||
175
vendor/github.com/99designs/gqlgen/codegen/config/binder.go
generated
vendored
175
vendor/github.com/99designs/gqlgen/codegen/config/binder.go
generated
vendored
@ -5,10 +5,10 @@ import (
|
||||
"fmt"
|
||||
"go/token"
|
||||
"go/types"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
|
||||
"github.com/99designs/gqlgen/codegen/templates"
|
||||
"github.com/99designs/gqlgen/internal/code"
|
||||
"github.com/vektah/gqlparser/v2/ast"
|
||||
)
|
||||
@ -20,6 +20,7 @@ type Binder struct {
|
||||
pkgs *code.Packages
|
||||
schema *ast.Schema
|
||||
cfg *Config
|
||||
tctx *types.Context
|
||||
References []*TypeReference
|
||||
SawInvalid bool
|
||||
objectCache map[string]map[string]types.Object
|
||||
@ -81,6 +82,14 @@ func (b *Binder) FindType(pkgName string, typeName string) (types.Type, error) {
|
||||
return obj.Type(), nil
|
||||
}
|
||||
|
||||
func (b *Binder) InstantiateType(orig types.Type, targs []types.Type) (types.Type, error) {
|
||||
if b.tctx == nil {
|
||||
b.tctx = types.NewContext()
|
||||
}
|
||||
|
||||
return types.Instantiate(b.tctx, orig, targs, false)
|
||||
}
|
||||
|
||||
var (
|
||||
MapType = types.NewMap(types.Typ[types.String], types.NewInterfaceType(nil, nil).Complete())
|
||||
InterfaceType = types.NewInterfaceType(nil, nil)
|
||||
@ -183,15 +192,17 @@ func (b *Binder) PointerTo(ref *TypeReference) *TypeReference {
|
||||
|
||||
// TypeReference is used by args and field types. The Definition can refer to both input and output types.
|
||||
type TypeReference struct {
|
||||
Definition *ast.Definition
|
||||
GQL *ast.Type
|
||||
GO types.Type // Type of the field being bound. Could be a pointer or a value type of Target.
|
||||
Target types.Type // The actual type that we know how to bind to. May require pointer juggling when traversing to fields.
|
||||
CastType types.Type // Before calling marshalling functions cast from/to this base type
|
||||
Marshaler *types.Func // When using external marshalling functions this will point to the Marshal function
|
||||
Unmarshaler *types.Func // When using external marshalling functions this will point to the Unmarshal function
|
||||
IsMarshaler bool // Does the type implement graphql.Marshaler and graphql.Unmarshaler
|
||||
IsContext bool // Is the Marshaler/Unmarshaller the context version; applies to either the method or interface variety.
|
||||
Definition *ast.Definition
|
||||
GQL *ast.Type
|
||||
GO types.Type // Type of the field being bound. Could be a pointer or a value type of Target.
|
||||
Target types.Type // The actual type that we know how to bind to. May require pointer juggling when traversing to fields.
|
||||
CastType types.Type // Before calling marshalling functions cast from/to this base type
|
||||
Marshaler *types.Func // When using external marshalling functions this will point to the Marshal function
|
||||
Unmarshaler *types.Func // When using external marshalling functions this will point to the Unmarshal function
|
||||
IsMarshaler bool // Does the type implement graphql.Marshaler and graphql.Unmarshaler
|
||||
IsOmittable bool // Is the type wrapped with Omittable
|
||||
IsContext bool // Is the Marshaler/Unmarshaller the context version; applies to either the method or interface variety.
|
||||
PointersInUmarshalInput bool // Inverse values and pointers in return.
|
||||
}
|
||||
|
||||
func (ref *TypeReference) Elem() *TypeReference {
|
||||
@ -210,91 +221,99 @@ func (ref *TypeReference) Elem() *TypeReference {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TypeReference) IsPtr() bool {
|
||||
_, isPtr := t.GO.(*types.Pointer)
|
||||
func (ref *TypeReference) IsPtr() bool {
|
||||
_, isPtr := ref.GO.(*types.Pointer)
|
||||
return isPtr
|
||||
}
|
||||
|
||||
// fix for https://github.com/golang/go/issues/31103 may make it possible to remove this (may still be useful)
|
||||
func (t *TypeReference) IsPtrToPtr() bool {
|
||||
if p, isPtr := t.GO.(*types.Pointer); isPtr {
|
||||
func (ref *TypeReference) IsPtrToPtr() bool {
|
||||
if p, isPtr := ref.GO.(*types.Pointer); isPtr {
|
||||
_, isPtr := p.Elem().(*types.Pointer)
|
||||
return isPtr
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *TypeReference) IsNilable() bool {
|
||||
return IsNilable(t.GO)
|
||||
func (ref *TypeReference) IsNilable() bool {
|
||||
return IsNilable(ref.GO)
|
||||
}
|
||||
|
||||
func (t *TypeReference) IsSlice() bool {
|
||||
_, isSlice := t.GO.(*types.Slice)
|
||||
return t.GQL.Elem != nil && isSlice
|
||||
func (ref *TypeReference) IsSlice() bool {
|
||||
_, isSlice := ref.GO.(*types.Slice)
|
||||
return ref.GQL.Elem != nil && isSlice
|
||||
}
|
||||
|
||||
func (t *TypeReference) IsPtrToSlice() bool {
|
||||
if t.IsPtr() {
|
||||
_, isPointerToSlice := t.GO.(*types.Pointer).Elem().(*types.Slice)
|
||||
func (ref *TypeReference) IsPtrToSlice() bool {
|
||||
if ref.IsPtr() {
|
||||
_, isPointerToSlice := ref.GO.(*types.Pointer).Elem().(*types.Slice)
|
||||
return isPointerToSlice
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *TypeReference) IsNamed() bool {
|
||||
_, isSlice := t.GO.(*types.Named)
|
||||
func (ref *TypeReference) IsPtrToIntf() bool {
|
||||
if ref.IsPtr() {
|
||||
_, isPointerToInterface := ref.GO.(*types.Pointer).Elem().(*types.Interface)
|
||||
return isPointerToInterface
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (ref *TypeReference) IsNamed() bool {
|
||||
_, isSlice := ref.GO.(*types.Named)
|
||||
return isSlice
|
||||
}
|
||||
|
||||
func (t *TypeReference) IsStruct() bool {
|
||||
_, isStruct := t.GO.Underlying().(*types.Struct)
|
||||
func (ref *TypeReference) IsStruct() bool {
|
||||
_, isStruct := ref.GO.Underlying().(*types.Struct)
|
||||
return isStruct
|
||||
}
|
||||
|
||||
func (t *TypeReference) IsScalar() bool {
|
||||
return t.Definition.Kind == ast.Scalar
|
||||
func (ref *TypeReference) IsScalar() bool {
|
||||
return ref.Definition.Kind == ast.Scalar
|
||||
}
|
||||
|
||||
func (t *TypeReference) UniquenessKey() string {
|
||||
func (ref *TypeReference) UniquenessKey() string {
|
||||
nullability := "O"
|
||||
if t.GQL.NonNull {
|
||||
if ref.GQL.NonNull {
|
||||
nullability = "N"
|
||||
}
|
||||
|
||||
elemNullability := ""
|
||||
if t.GQL.Elem != nil && t.GQL.Elem.NonNull {
|
||||
if ref.GQL.Elem != nil && ref.GQL.Elem.NonNull {
|
||||
// Fix for #896
|
||||
elemNullability = "ᚄ"
|
||||
}
|
||||
return nullability + t.Definition.Name + "2" + templates.TypeIdentifier(t.GO) + elemNullability
|
||||
return nullability + ref.Definition.Name + "2" + TypeIdentifier(ref.GO) + elemNullability
|
||||
}
|
||||
|
||||
func (t *TypeReference) MarshalFunc() string {
|
||||
if t.Definition == nil {
|
||||
panic(errors.New("Definition missing for " + t.GQL.Name()))
|
||||
func (ref *TypeReference) MarshalFunc() string {
|
||||
if ref.Definition == nil {
|
||||
panic(errors.New("Definition missing for " + ref.GQL.Name()))
|
||||
}
|
||||
|
||||
if t.Definition.Kind == ast.InputObject {
|
||||
if ref.Definition.Kind == ast.InputObject {
|
||||
return ""
|
||||
}
|
||||
|
||||
return "marshal" + t.UniquenessKey()
|
||||
return "marshal" + ref.UniquenessKey()
|
||||
}
|
||||
|
||||
func (t *TypeReference) UnmarshalFunc() string {
|
||||
if t.Definition == nil {
|
||||
panic(errors.New("Definition missing for " + t.GQL.Name()))
|
||||
func (ref *TypeReference) UnmarshalFunc() string {
|
||||
if ref.Definition == nil {
|
||||
panic(errors.New("Definition missing for " + ref.GQL.Name()))
|
||||
}
|
||||
|
||||
if !t.Definition.IsInputType() {
|
||||
if !ref.Definition.IsInputType() {
|
||||
return ""
|
||||
}
|
||||
|
||||
return "unmarshal" + t.UniquenessKey()
|
||||
return "unmarshal" + ref.UniquenessKey()
|
||||
}
|
||||
|
||||
func (t *TypeReference) IsTargetNilable() bool {
|
||||
return IsNilable(t.Target)
|
||||
func (ref *TypeReference) IsTargetNilable() bool {
|
||||
return IsNilable(ref.Target)
|
||||
}
|
||||
|
||||
func (b *Binder) PushRef(ret *TypeReference) {
|
||||
@ -317,7 +336,35 @@ func isIntf(t types.Type) bool {
|
||||
return ok
|
||||
}
|
||||
|
||||
func unwrapOmittable(t types.Type) (types.Type, bool) {
|
||||
if t == nil {
|
||||
return t, false
|
||||
}
|
||||
named, ok := t.(*types.Named)
|
||||
if !ok {
|
||||
return t, false
|
||||
}
|
||||
if named.Origin().String() != "github.com/99designs/gqlgen/graphql.Omittable[T any]" {
|
||||
return t, false
|
||||
}
|
||||
return named.TypeArgs().At(0), true
|
||||
}
|
||||
|
||||
func (b *Binder) TypeReference(schemaType *ast.Type, bindTarget types.Type) (ret *TypeReference, err error) {
|
||||
if innerType, ok := unwrapOmittable(bindTarget); ok {
|
||||
if schemaType.NonNull {
|
||||
return nil, fmt.Errorf("%s is wrapped with Omittable but non-null", schemaType.Name())
|
||||
}
|
||||
|
||||
ref, err := b.TypeReference(schemaType, innerType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ref.IsOmittable = true
|
||||
return ref, err
|
||||
}
|
||||
|
||||
if !isValid(bindTarget) {
|
||||
b.SawInvalid = true
|
||||
return nil, fmt.Errorf("%s has an invalid type", schemaType.Name())
|
||||
@ -412,6 +459,8 @@ func (b *Binder) TypeReference(schemaType *ast.Type, bindTarget types.Type) (ret
|
||||
ref.GO = bindTarget
|
||||
}
|
||||
|
||||
ref.PointersInUmarshalInput = b.cfg.ReturnPointersInUmarshalInput
|
||||
|
||||
return ref, nil
|
||||
}
|
||||
|
||||
@ -491,3 +540,41 @@ func basicUnderlying(it types.Type) *types.Basic {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var pkgReplacer = strings.NewReplacer(
|
||||
"/", "ᚋ",
|
||||
".", "ᚗ",
|
||||
"-", "ᚑ",
|
||||
"~", "א",
|
||||
)
|
||||
|
||||
func TypeIdentifier(t types.Type) string {
|
||||
res := ""
|
||||
for {
|
||||
switch it := t.(type) {
|
||||
case *types.Pointer:
|
||||
t.Underlying()
|
||||
res += "ᚖ"
|
||||
t = it.Elem()
|
||||
case *types.Slice:
|
||||
res += "ᚕ"
|
||||
t = it.Elem()
|
||||
case *types.Named:
|
||||
res += pkgReplacer.Replace(it.Obj().Pkg().Path())
|
||||
res += "ᚐ"
|
||||
res += it.Obj().Name()
|
||||
return res
|
||||
case *types.Basic:
|
||||
res += it.Name()
|
||||
return res
|
||||
case *types.Map:
|
||||
res += "map"
|
||||
return res
|
||||
case *types.Interface:
|
||||
res += "interface"
|
||||
return res
|
||||
default:
|
||||
panic(fmt.Errorf("unexpected type %T", it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
58
vendor/github.com/99designs/gqlgen/codegen/config/config.go
generated
vendored
58
vendor/github.com/99designs/gqlgen/codegen/config/config.go
generated
vendored
@ -3,6 +3,7 @@ package config
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
@ -25,10 +26,18 @@ type Config struct {
|
||||
Models TypeMap `yaml:"models,omitempty"`
|
||||
StructTag string `yaml:"struct_tag,omitempty"`
|
||||
Directives map[string]DirectiveConfig `yaml:"directives,omitempty"`
|
||||
GoInitialisms GoInitialismsConfig `yaml:"go_initialisms,omitempty"`
|
||||
OmitSliceElementPointers bool `yaml:"omit_slice_element_pointers,omitempty"`
|
||||
OmitGetters bool `yaml:"omit_getters,omitempty"`
|
||||
OmitInterfaceChecks bool `yaml:"omit_interface_checks,omitempty"`
|
||||
OmitComplexity bool `yaml:"omit_complexity,omitempty"`
|
||||
OmitGQLGenFileNotice bool `yaml:"omit_gqlgen_file_notice,omitempty"`
|
||||
OmitGQLGenVersionInFileNotice bool `yaml:"omit_gqlgen_version_in_file_notice,omitempty"`
|
||||
StructFieldsAlwaysPointers bool `yaml:"struct_fields_always_pointers,omitempty"`
|
||||
ReturnPointersInUmarshalInput bool `yaml:"return_pointers_in_unmarshalinput,omitempty"`
|
||||
ResolversAlwaysReturnPointers bool `yaml:"resolvers_always_return_pointers,omitempty"`
|
||||
NullableInputOmittable bool `yaml:"nullable_input_omittable,omitempty"`
|
||||
EnableModelJsonOmitemptyTag *bool `yaml:"enable_model_json_omitempty_tag,omitempty"`
|
||||
SkipValidation bool `yaml:"skip_validation,omitempty"`
|
||||
SkipModTidy bool `yaml:"skip_mod_tidy,omitempty"`
|
||||
Sources []*ast.Source `yaml:"-"`
|
||||
@ -50,7 +59,9 @@ func DefaultConfig() *Config {
|
||||
Directives: map[string]DirectiveConfig{},
|
||||
Models: TypeMap{},
|
||||
StructFieldsAlwaysPointers: true,
|
||||
ReturnPointersInUmarshalInput: false,
|
||||
ResolversAlwaysReturnPointers: true,
|
||||
NullableInputOmittable: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,14 +108,18 @@ var path2regex = strings.NewReplacer(
|
||||
|
||||
// LoadConfig reads the gqlgen.yml config file
|
||||
func LoadConfig(filename string) (*Config, error) {
|
||||
config := DefaultConfig()
|
||||
|
||||
b, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to read config: %w", err)
|
||||
}
|
||||
|
||||
dec := yaml.NewDecoder(bytes.NewReader(b))
|
||||
return ReadConfig(bytes.NewReader(b))
|
||||
}
|
||||
|
||||
func ReadConfig(cfgFile io.Reader) (*Config, error) {
|
||||
config := DefaultConfig()
|
||||
|
||||
dec := yaml.NewDecoder(cfgFile)
|
||||
dec.KnownFields(true)
|
||||
|
||||
if err := dec.Decode(config); err != nil {
|
||||
@ -188,6 +203,9 @@ func CompleteConfig(config *Config) error {
|
||||
|
||||
config.Sources = append(config.Sources, &ast.Source{Name: filename, Input: string(schemaRaw)})
|
||||
}
|
||||
|
||||
config.GoInitialisms.setInitialisms()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -292,8 +310,9 @@ func (c *Config) injectTypesFromSchema() error {
|
||||
|
||||
if c.Models[schemaType.Name].Fields == nil {
|
||||
c.Models[schemaType.Name] = TypeMapEntry{
|
||||
Model: c.Models[schemaType.Name].Model,
|
||||
Fields: map[string]TypeMapField{},
|
||||
Model: c.Models[schemaType.Name].Model,
|
||||
ExtraFields: c.Models[schemaType.Name].ExtraFields,
|
||||
Fields: map[string]TypeMapField{},
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,6 +331,9 @@ func (c *Config) injectTypesFromSchema() error {
|
||||
type TypeMapEntry struct {
|
||||
Model StringList `yaml:"model"`
|
||||
Fields map[string]TypeMapField `yaml:"fields,omitempty"`
|
||||
|
||||
// Key is the Go name of the field.
|
||||
ExtraFields map[string]ModelExtraField `yaml:"extraFields,omitempty"`
|
||||
}
|
||||
|
||||
type TypeMapField struct {
|
||||
@ -320,6 +342,32 @@ type TypeMapField struct {
|
||||
GeneratedMethod string `yaml:"-"`
|
||||
}
|
||||
|
||||
type ModelExtraField struct {
|
||||
// Type is the Go type of the field.
|
||||
//
|
||||
// It supports the builtin basic types (like string or int64), named types
|
||||
// (qualified by the full package path), pointers to those types (prefixed
|
||||
// with `*`), and slices of those types (prefixed with `[]`).
|
||||
//
|
||||
// For example, the following are valid types:
|
||||
// string
|
||||
// *github.com/author/package.Type
|
||||
// []string
|
||||
// []*github.com/author/package.Type
|
||||
//
|
||||
// Note that the type will be referenced from the generated/graphql, which
|
||||
// means the package it lives in must not reference the generated/graphql
|
||||
// package to avoid circular imports.
|
||||
// restrictions.
|
||||
Type string `yaml:"type"`
|
||||
|
||||
// OverrideTags is an optional override of the Go field tag.
|
||||
OverrideTags string `yaml:"overrideTags"`
|
||||
|
||||
// Description is an optional the Go field doc-comment.
|
||||
Description string `yaml:"description"`
|
||||
}
|
||||
|
||||
type StringList []string
|
||||
|
||||
func (a *StringList) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
|
||||
94
vendor/github.com/99designs/gqlgen/codegen/config/initialisms.go
generated
vendored
Normal file
94
vendor/github.com/99designs/gqlgen/codegen/config/initialisms.go
generated
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
package config
|
||||
|
||||
import "strings"
|
||||
|
||||
// commonInitialisms is a set of common initialisms.
|
||||
// Only add entries that are highly unlikely to be non-initialisms.
|
||||
// For instance, "ID" is fine (Freudian code is rare), but "AND" is not.
|
||||
var commonInitialisms = map[string]bool{
|
||||
"ACL": true,
|
||||
"API": true,
|
||||
"ASCII": true,
|
||||
"CPU": true,
|
||||
"CSS": true,
|
||||
"CSV": true,
|
||||
"DNS": true,
|
||||
"EOF": true,
|
||||
"GUID": true,
|
||||
"HTML": true,
|
||||
"HTTP": true,
|
||||
"HTTPS": true,
|
||||
"ICMP": true,
|
||||
"ID": true,
|
||||
"IP": true,
|
||||
"JSON": true,
|
||||
"KVK": true,
|
||||
"LHS": true,
|
||||
"PDF": true,
|
||||
"PGP": true,
|
||||
"QPS": true,
|
||||
"QR": true,
|
||||
"RAM": true,
|
||||
"RHS": true,
|
||||
"RPC": true,
|
||||
"SLA": true,
|
||||
"SMTP": true,
|
||||
"SQL": true,
|
||||
"SSH": true,
|
||||
"SVG": true,
|
||||
"TCP": true,
|
||||
"TLS": true,
|
||||
"TTL": true,
|
||||
"UDP": true,
|
||||
"UI": true,
|
||||
"UID": true,
|
||||
"URI": true,
|
||||
"URL": true,
|
||||
"UTF8": true,
|
||||
"UUID": true,
|
||||
"VM": true,
|
||||
"XML": true,
|
||||
"XMPP": true,
|
||||
"XSRF": true,
|
||||
"XSS": true,
|
||||
}
|
||||
|
||||
// GetInitialisms returns the initialisms to capitalize in Go names. If unchanged, default initialisms will be returned
|
||||
var GetInitialisms = func() map[string]bool {
|
||||
return commonInitialisms
|
||||
}
|
||||
|
||||
// GoInitialismsConfig allows to modify the default behavior of naming Go methods, types and properties
|
||||
type GoInitialismsConfig struct {
|
||||
// If true, the Initialisms won't get appended to the default ones but replace them
|
||||
ReplaceDefaults bool `yaml:"replace_defaults"`
|
||||
// Custom initialisms to be added or to replace the default ones
|
||||
Initialisms []string `yaml:"initialisms"`
|
||||
}
|
||||
|
||||
// setInitialisms adjustes GetInitialisms based on its settings.
|
||||
func (i GoInitialismsConfig) setInitialisms() {
|
||||
toUse := i.determineGoInitialisms()
|
||||
GetInitialisms = func() map[string]bool {
|
||||
return toUse
|
||||
}
|
||||
}
|
||||
|
||||
// determineGoInitialisms returns the Go initialims to be used, based on its settings.
|
||||
func (i GoInitialismsConfig) determineGoInitialisms() (initialismsToUse map[string]bool) {
|
||||
if i.ReplaceDefaults {
|
||||
initialismsToUse = make(map[string]bool, len(i.Initialisms))
|
||||
for _, initialism := range i.Initialisms {
|
||||
initialismsToUse[strings.ToUpper(initialism)] = true
|
||||
}
|
||||
} else {
|
||||
initialismsToUse = make(map[string]bool, len(commonInitialisms)+len(i.Initialisms))
|
||||
for initialism, value := range commonInitialisms {
|
||||
initialismsToUse[strings.ToUpper(initialism)] = value
|
||||
}
|
||||
for _, initialism := range i.Initialisms {
|
||||
initialismsToUse[strings.ToUpper(initialism)] = true
|
||||
}
|
||||
}
|
||||
return initialismsToUse
|
||||
}
|
||||
7
vendor/github.com/99designs/gqlgen/codegen/config/package.go
generated
vendored
7
vendor/github.com/99designs/gqlgen/codegen/config/package.go
generated
vendored
@ -10,9 +10,10 @@ import (
|
||||
)
|
||||
|
||||
type PackageConfig struct {
|
||||
Filename string `yaml:"filename,omitempty"`
|
||||
Package string `yaml:"package,omitempty"`
|
||||
Version int `yaml:"version,omitempty"`
|
||||
Filename string `yaml:"filename,omitempty"`
|
||||
Package string `yaml:"package,omitempty"`
|
||||
Version int `yaml:"version,omitempty"`
|
||||
ModelTemplate string `yaml:"model_template,omitempty"`
|
||||
}
|
||||
|
||||
func (c *PackageConfig) ImportPath() string {
|
||||
|
||||
14
vendor/github.com/99designs/gqlgen/codegen/config/resolver.go
generated
vendored
14
vendor/github.com/99designs/gqlgen/codegen/config/resolver.go
generated
vendored
@ -10,12 +10,14 @@ import (
|
||||
)
|
||||
|
||||
type ResolverConfig struct {
|
||||
Filename string `yaml:"filename,omitempty"`
|
||||
FilenameTemplate string `yaml:"filename_template,omitempty"`
|
||||
Package string `yaml:"package,omitempty"`
|
||||
Type string `yaml:"type,omitempty"`
|
||||
Layout ResolverLayout `yaml:"layout,omitempty"`
|
||||
DirName string `yaml:"dir"`
|
||||
Filename string `yaml:"filename,omitempty"`
|
||||
FilenameTemplate string `yaml:"filename_template,omitempty"`
|
||||
Package string `yaml:"package,omitempty"`
|
||||
Type string `yaml:"type,omitempty"`
|
||||
Layout ResolverLayout `yaml:"layout,omitempty"`
|
||||
DirName string `yaml:"dir"`
|
||||
OmitTemplateComment bool `yaml:"omit_template_comment,omitempty"`
|
||||
ResolverTemplate string `yaml:"resolver_template,omitempty"`
|
||||
}
|
||||
|
||||
type ResolverLayout string
|
||||
|
||||
4
vendor/github.com/99designs/gqlgen/codegen/data.go
generated
vendored
4
vendor/github.com/99designs/gqlgen/codegen/data.go
generated
vendored
@ -34,6 +34,7 @@ type Data struct {
|
||||
MutationRoot *Object
|
||||
SubscriptionRoot *Object
|
||||
AugmentedSources []AugmentedSource
|
||||
Plugins []interface{}
|
||||
}
|
||||
|
||||
func (d *Data) HasEmbeddableSources() bool {
|
||||
@ -76,7 +77,7 @@ func (d *Data) Directives() DirectiveList {
|
||||
return res
|
||||
}
|
||||
|
||||
func BuildData(cfg *config.Config) (*Data, error) {
|
||||
func BuildData(cfg *config.Config, plugins ...interface{}) (*Data, error) {
|
||||
// We reload all packages to allow packages to be compared correctly.
|
||||
cfg.ReloadAllPackages()
|
||||
|
||||
@ -105,6 +106,7 @@ func BuildData(cfg *config.Config) (*Data, error) {
|
||||
AllDirectives: dataDirectives,
|
||||
Schema: b.Schema,
|
||||
Interfaces: map[string]*Interface{},
|
||||
Plugins: plugins,
|
||||
}
|
||||
|
||||
for _, schemaType := range b.Schema.Types {
|
||||
|
||||
35
vendor/github.com/99designs/gqlgen/codegen/field.go
generated
vendored
35
vendor/github.com/99designs/gqlgen/codegen/field.go
generated
vendored
@ -3,6 +3,7 @@ package codegen
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
goast "go/ast"
|
||||
"go/types"
|
||||
"log"
|
||||
"reflect"
|
||||
@ -502,7 +503,21 @@ func (f *Field) ResolverType() string {
|
||||
return fmt.Sprintf("%s().%s(%s)", f.Object.Definition.Name, f.GoFieldName, f.CallArgs())
|
||||
}
|
||||
|
||||
func (f *Field) IsInputObject() bool {
|
||||
return f.Object.Kind == ast.InputObject
|
||||
}
|
||||
|
||||
func (f *Field) IsRoot() bool {
|
||||
return f.Object.Root
|
||||
}
|
||||
|
||||
func (f *Field) ShortResolverDeclaration() string {
|
||||
return f.ShortResolverSignature(nil)
|
||||
}
|
||||
|
||||
// ShortResolverSignature is identical to ShortResolverDeclaration,
|
||||
// but respects previous naming (return) conventions, if any.
|
||||
func (f *Field) ShortResolverSignature(ft *goast.FuncType) string {
|
||||
if f.Object.Kind == ast.InputObject {
|
||||
return fmt.Sprintf("(ctx context.Context, obj %s, data %s) error",
|
||||
templates.CurrentImports.LookupType(f.Object.Reference()),
|
||||
@ -523,11 +538,27 @@ func (f *Field) ShortResolverDeclaration() string {
|
||||
if f.Object.Stream {
|
||||
result = "<-chan " + result
|
||||
}
|
||||
|
||||
res += fmt.Sprintf(") (%s, error)", result)
|
||||
// Named return.
|
||||
var namedV, namedE string
|
||||
if ft != nil {
|
||||
if ft.Results != nil && len(ft.Results.List) > 0 && len(ft.Results.List[0].Names) > 0 {
|
||||
namedV = ft.Results.List[0].Names[0].Name
|
||||
}
|
||||
if ft.Results != nil && len(ft.Results.List) > 1 && len(ft.Results.List[1].Names) > 0 {
|
||||
namedE = ft.Results.List[1].Names[0].Name
|
||||
}
|
||||
}
|
||||
res += fmt.Sprintf(") (%s %s, %s error)", namedV, result, namedE)
|
||||
return res
|
||||
}
|
||||
|
||||
func (f *Field) GoResultName() (string, bool) {
|
||||
name := fmt.Sprintf("%v", f.TypeReference.GO)
|
||||
splits := strings.Split(name, "/")
|
||||
|
||||
return splits[len(splits)-1], strings.HasPrefix(name, "[]")
|
||||
}
|
||||
|
||||
func (f *Field) ComplexitySignature() string {
|
||||
res := "func(childComplexity int"
|
||||
for _, arg := range f.Args {
|
||||
|
||||
2
vendor/github.com/99designs/gqlgen/codegen/field.gotpl
generated
vendored
2
vendor/github.com/99designs/gqlgen/codegen/field.gotpl
generated
vendored
@ -94,7 +94,7 @@ func (ec *executionContext) {{ $field.FieldContextFunc }}(ctx context.Context, f
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
if fc.Args, err = ec.{{ $field.ArgsFunc }}(ctx, field.ArgumentMap(ec.Variables)); err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return
|
||||
return fc, err
|
||||
}
|
||||
{{- end }}
|
||||
return fc, nil
|
||||
|
||||
74
vendor/github.com/99designs/gqlgen/codegen/generated!.gotpl
generated
vendored
74
vendor/github.com/99designs/gqlgen/codegen/generated!.gotpl
generated
vendored
@ -14,7 +14,6 @@
|
||||
{{ reserveImport "github.com/99designs/gqlgen/graphql" }}
|
||||
{{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }}
|
||||
|
||||
|
||||
{{ if eq .Config.Exec.Layout "single-file" }}
|
||||
// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface.
|
||||
func NewExecutableSchema(cfg Config) graphql.ExecutableSchema {
|
||||
@ -51,6 +50,7 @@
|
||||
}
|
||||
|
||||
type ComplexityRoot struct {
|
||||
{{- if not .Config.OmitComplexity }}
|
||||
{{ range $object := .Objects }}
|
||||
{{ if not $object.IsReserved -}}
|
||||
{{ ucFirst $object.Name }} struct {
|
||||
@ -63,6 +63,7 @@
|
||||
}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
{{- end }}
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
@ -102,8 +103,9 @@
|
||||
}
|
||||
|
||||
func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) {
|
||||
ec := executionContext{nil, e}
|
||||
ec := executionContext{nil, e, 0, 0, nil}
|
||||
_ = ec
|
||||
{{ if not .Config.OmitComplexity -}}
|
||||
switch typeName + "." + field {
|
||||
{{ range $object := .Objects }}
|
||||
{{ if not $object.IsReserved }}
|
||||
@ -130,12 +132,13 @@
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
}
|
||||
{{- end }}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
|
||||
rc := graphql.GetOperationContext(ctx)
|
||||
ec := executionContext{rc, e}
|
||||
ec := executionContext{rc, e, 0, 0, make(chan graphql.DeferredResult)}
|
||||
inputUnmarshalMap := graphql.BuildUnmarshalerMap(
|
||||
{{- range $input := .Inputs -}}
|
||||
{{ if not $input.HasUnmarshal }}
|
||||
@ -148,22 +151,39 @@
|
||||
switch rc.Operation.Operation {
|
||||
{{- if .QueryRoot }} case ast.Query:
|
||||
return func(ctx context.Context) *graphql.Response {
|
||||
if !first { return nil }
|
||||
first = false
|
||||
ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap)
|
||||
{{ if .Directives.LocationDirectives "QUERY" -}}
|
||||
data := ec._queryMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){
|
||||
return ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet), nil
|
||||
})
|
||||
{{- else -}}
|
||||
data := ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet)
|
||||
{{- end }}
|
||||
var response graphql.Response
|
||||
var data graphql.Marshaler
|
||||
if first {
|
||||
first = false
|
||||
ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap)
|
||||
{{ if .Directives.LocationDirectives "QUERY" -}}
|
||||
data = ec._queryMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){
|
||||
return ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet), nil
|
||||
})
|
||||
{{- else -}}
|
||||
data = ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet)
|
||||
{{- end }}
|
||||
} else {
|
||||
if atomic.LoadInt32(&ec.pendingDeferred) > 0 {
|
||||
result := <-ec.deferredResults
|
||||
atomic.AddInt32(&ec.pendingDeferred, -1)
|
||||
data = result.Result
|
||||
response.Path = result.Path
|
||||
response.Label = result.Label
|
||||
response.Errors = result.Errors
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
data.MarshalGQL(&buf)
|
||||
|
||||
return &graphql.Response{
|
||||
Data: buf.Bytes(),
|
||||
response.Data = buf.Bytes()
|
||||
if atomic.LoadInt32(&ec.deferred) > 0 {
|
||||
hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0
|
||||
response.HasNext = &hasNext
|
||||
}
|
||||
|
||||
return &response
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
@ -220,6 +240,28 @@
|
||||
type executionContext struct {
|
||||
*graphql.OperationContext
|
||||
*executableSchema
|
||||
deferred int32
|
||||
pendingDeferred int32
|
||||
deferredResults chan graphql.DeferredResult
|
||||
}
|
||||
|
||||
func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) {
|
||||
atomic.AddInt32(&ec.pendingDeferred, 1)
|
||||
go func () {
|
||||
ctx := graphql.WithFreshResponseContext(dg.Context)
|
||||
dg.FieldSet.Dispatch(ctx)
|
||||
ds := graphql.DeferredResult{
|
||||
Path: dg.Path,
|
||||
Label: dg.Label,
|
||||
Result: dg.FieldSet,
|
||||
Errors: graphql.GetErrors(ctx),
|
||||
}
|
||||
// null fields should bubble up
|
||||
if dg.FieldSet.Invalids > 0 {
|
||||
ds.Result = graphql.Null
|
||||
}
|
||||
ec.deferredResults <- ds
|
||||
}()
|
||||
}
|
||||
|
||||
func (ec *executionContext) introspectSchema() (*introspection.Schema, error) {
|
||||
|
||||
39
vendor/github.com/99designs/gqlgen/codegen/input.gotpl
generated
vendored
39
vendor/github.com/99designs/gqlgen/codegen/input.gotpl
generated
vendored
@ -1,6 +1,10 @@
|
||||
{{- range $input := .Inputs }}
|
||||
{{- if not .HasUnmarshal }}
|
||||
func (ec *executionContext) unmarshalInput{{ .Name }}(ctx context.Context, obj interface{}) ({{.Type | ref}}, error) {
|
||||
{{- $it := "it" }}
|
||||
{{- if .PointersInUmarshalInput }}
|
||||
{{- $it = "&it" }}
|
||||
{{- end }}
|
||||
func (ec *executionContext) unmarshalInput{{ .Name }}(ctx context.Context, obj interface{}) ({{ if .PointersInUmarshalInput }}*{{ end }}{{.Type | ref}}, error) {
|
||||
var it {{.Type | ref}}
|
||||
asMap := map[string]interface{}{}
|
||||
for k, v := range obj.(map[string]interface{}) {
|
||||
@ -31,47 +35,60 @@
|
||||
{{ template "implDirectives" $field }}
|
||||
tmp, err := directive{{$field.ImplDirectives|len}}(ctx)
|
||||
if err != nil {
|
||||
return it, graphql.ErrorOnPath(ctx, err)
|
||||
return {{$it}}, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
if data, ok := tmp.({{ $field.TypeReference.GO | ref }}) ; ok {
|
||||
{{- if $field.IsResolver }}
|
||||
if err = ec.resolvers.{{ $field.ShortInvocation }}; err != nil {
|
||||
return it, err
|
||||
return {{$it}}, err
|
||||
}
|
||||
{{- else }}
|
||||
it.{{$field.GoFieldName}} = data
|
||||
{{- if $field.TypeReference.IsOmittable }}
|
||||
it.{{$field.GoFieldName}} = graphql.OmittableOf(data)
|
||||
{{- else }}
|
||||
it.{{$field.GoFieldName}} = data
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if $field.TypeReference.IsNilable }}
|
||||
{{- if not $field.IsResolver }}
|
||||
} else if tmp == nil {
|
||||
it.{{$field.GoFieldName}} = nil
|
||||
{{- if $field.TypeReference.IsOmittable }}
|
||||
it.{{$field.GoFieldName}} = graphql.OmittableOf[{{ $field.TypeReference.GO | ref }}](nil)
|
||||
{{- else }}
|
||||
it.{{$field.GoFieldName}} = nil
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
} else {
|
||||
err := fmt.Errorf(`unexpected type %T from directive, should be {{ $field.TypeReference.GO }}`, tmp)
|
||||
return it, graphql.ErrorOnPath(ctx, err)
|
||||
return {{$it}}, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
{{- else }}
|
||||
{{- if $field.IsResolver }}
|
||||
data, err := ec.{{ $field.TypeReference.UnmarshalFunc }}(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
return {{$it}}, err
|
||||
}
|
||||
if err = ec.resolvers.{{ $field.ShortInvocation }}; err != nil {
|
||||
return it, err
|
||||
return {{$it}}, err
|
||||
}
|
||||
{{- else }}
|
||||
it.{{$field.GoFieldName}}, err = ec.{{ $field.TypeReference.UnmarshalFunc }}(ctx, v)
|
||||
data, err := ec.{{ $field.TypeReference.UnmarshalFunc }}(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
return {{$it}}, err
|
||||
}
|
||||
{{- if $field.TypeReference.IsOmittable }}
|
||||
it.{{$field.GoFieldName}} = graphql.OmittableOf(data)
|
||||
{{- else }}
|
||||
it.{{$field.GoFieldName}} = data
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
|
||||
return it, nil
|
||||
return {{$it}}, nil
|
||||
}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
|
||||
38
vendor/github.com/99designs/gqlgen/codegen/object.go
generated
vendored
38
vendor/github.com/99designs/gqlgen/codegen/object.go
generated
vendored
@ -25,14 +25,15 @@ const (
|
||||
type Object struct {
|
||||
*ast.Definition
|
||||
|
||||
Type types.Type
|
||||
ResolverInterface types.Type
|
||||
Root bool
|
||||
Fields []*Field
|
||||
Implements []*ast.Definition
|
||||
DisableConcurrency bool
|
||||
Stream bool
|
||||
Directives []*Directive
|
||||
Type types.Type
|
||||
ResolverInterface types.Type
|
||||
Root bool
|
||||
Fields []*Field
|
||||
Implements []*ast.Definition
|
||||
DisableConcurrency bool
|
||||
Stream bool
|
||||
Directives []*Directive
|
||||
PointersInUmarshalInput bool
|
||||
}
|
||||
|
||||
func (b *builder) buildObject(typ *ast.Definition) (*Object, error) {
|
||||
@ -42,11 +43,12 @@ func (b *builder) buildObject(typ *ast.Definition) (*Object, error) {
|
||||
}
|
||||
caser := cases.Title(language.English, cases.NoLower)
|
||||
obj := &Object{
|
||||
Definition: typ,
|
||||
Root: b.Schema.Query == typ || b.Schema.Mutation == typ || b.Schema.Subscription == typ,
|
||||
DisableConcurrency: typ == b.Schema.Mutation,
|
||||
Stream: typ == b.Schema.Subscription,
|
||||
Directives: dirs,
|
||||
Definition: typ,
|
||||
Root: b.Schema.Query == typ || b.Schema.Mutation == typ || b.Schema.Subscription == typ,
|
||||
DisableConcurrency: typ == b.Schema.Mutation,
|
||||
Stream: typ == b.Schema.Subscription,
|
||||
Directives: dirs,
|
||||
PointersInUmarshalInput: b.Config.ReturnPointersInUmarshalInput,
|
||||
ResolverInterface: types.NewNamed(
|
||||
types.NewTypeName(0, b.Config.Exec.Pkg(), caser.String(typ.Name)+"Resolver", nil),
|
||||
nil,
|
||||
@ -151,6 +153,16 @@ func (o *Object) Description() string {
|
||||
return o.Definition.Description
|
||||
}
|
||||
|
||||
func (o *Object) HasField(name string) bool {
|
||||
for _, f := range o.Fields {
|
||||
if f.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (os Objects) ByName(name string) *Object {
|
||||
for i, o := range os {
|
||||
if strings.EqualFold(o.Definition.Name, name) {
|
||||
|
||||
181
vendor/github.com/99designs/gqlgen/codegen/object.gotpl
generated
vendored
181
vendor/github.com/99designs/gqlgen/codegen/object.gotpl
generated
vendored
@ -25,86 +25,121 @@ func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.Selec
|
||||
{{- else }}
|
||||
func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.SelectionSet{{ if not $object.Root }},obj {{$object.Reference | ref }}{{ end }}) graphql.Marshaler {
|
||||
fields := graphql.CollectFields(ec.OperationContext, sel, {{$object.Name|lcFirst}}Implementors)
|
||||
{{- if $object.Root }}
|
||||
ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{
|
||||
Object: {{$object.Name|quote}},
|
||||
})
|
||||
{{end}}
|
||||
{{- if $object.Root }}
|
||||
ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{
|
||||
Object: {{$object.Name|quote}},
|
||||
})
|
||||
{{end}}
|
||||
|
||||
out := graphql.NewFieldSet(fields)
|
||||
var invalids uint32
|
||||
deferred := make(map[string]*graphql.FieldSet)
|
||||
for i, field := range fields {
|
||||
{{- if $object.Root }}
|
||||
innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{
|
||||
Object: field.Name,
|
||||
Field: field,
|
||||
})
|
||||
{{end}}
|
||||
switch field.Name {
|
||||
case "__typename":
|
||||
out.Values[i] = graphql.MarshalString({{$object.Name|quote}})
|
||||
{{- range $field := $object.Fields }}
|
||||
case "{{$field.Name}}":
|
||||
{{- if $field.IsConcurrent }}
|
||||
field := field
|
||||
{{- if $object.Root }}
|
||||
innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{
|
||||
Object: field.Name,
|
||||
Field: field,
|
||||
})
|
||||
{{end}}
|
||||
switch field.Name {
|
||||
case "__typename":
|
||||
out.Values[i] = graphql.MarshalString({{$object.Name|quote}})
|
||||
{{- range $field := $object.Fields }}
|
||||
case "{{$field.Name}}":
|
||||
{{- if $field.IsConcurrent }}
|
||||
field := field
|
||||
|
||||
innerFunc := func(ctx context.Context) (res graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
}
|
||||
}()
|
||||
res = ec._{{$object.Name}}_{{$field.Name}}(ctx, field{{if not $object.Root}}, obj{{end}})
|
||||
{{- if $field.TypeReference.GQL.NonNull }}
|
||||
if res == graphql.Null {
|
||||
{{- if $object.IsConcurrent }}
|
||||
atomic.AddUint32(&invalids, 1)
|
||||
{{- else }}
|
||||
invalids++
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}
|
||||
return res
|
||||
}
|
||||
innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
}
|
||||
}()
|
||||
res = ec._{{$object.Name}}_{{$field.Name}}(ctx, field{{if not $object.Root}}, obj{{end}})
|
||||
{{- if $field.TypeReference.GQL.NonNull }}
|
||||
if res == graphql.Null {
|
||||
{{- if $object.IsConcurrent }}
|
||||
atomic.AddUint32(&fs.Invalids, 1)
|
||||
{{- else }}
|
||||
fs.Invalids++
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}
|
||||
return res
|
||||
}
|
||||
|
||||
{{if $object.Root}}
|
||||
rrm := func(ctx context.Context) graphql.Marshaler {
|
||||
return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc)
|
||||
}
|
||||
{{end}}
|
||||
{{if $object.Root}}
|
||||
rrm := func(ctx context.Context) graphql.Marshaler {
|
||||
return ec.OperationContext.RootResolverMiddleware(ctx,
|
||||
func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
|
||||
}
|
||||
{{end}}
|
||||
|
||||
out.Concurrently(i, func() graphql.Marshaler {
|
||||
{{- if $object.Root -}}
|
||||
return rrm(innerCtx)
|
||||
{{- else -}}
|
||||
return innerFunc(ctx)
|
||||
{{end}}
|
||||
})
|
||||
{{- else }}
|
||||
{{if $object.Root}}
|
||||
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
|
||||
return ec._{{$object.Name}}_{{$field.Name}}(ctx, field)
|
||||
})
|
||||
{{else}}
|
||||
out.Values[i] = ec._{{$object.Name}}_{{$field.Name}}(ctx, field, obj)
|
||||
{{end}}
|
||||
{{if not $object.Root}}
|
||||
if field.Deferrable != nil {
|
||||
dfs, ok := deferred[field.Deferrable.Label]
|
||||
di := 0
|
||||
if ok {
|
||||
dfs.AddField(field)
|
||||
di = len(dfs.Values) - 1
|
||||
} else {
|
||||
dfs = graphql.NewFieldSet([]graphql.CollectedField{field})
|
||||
deferred[field.Deferrable.Label] = dfs
|
||||
}
|
||||
dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler {
|
||||
return innerFunc(ctx, dfs)
|
||||
})
|
||||
|
||||
{{- if $field.TypeReference.GQL.NonNull }}
|
||||
if out.Values[i] == graphql.Null {
|
||||
{{- if $object.IsConcurrent }}
|
||||
atomic.AddUint32(&invalids, 1)
|
||||
{{- else }}
|
||||
invalids++
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
default:
|
||||
panic("unknown field " + strconv.Quote(field.Name))
|
||||
}
|
||||
// don't run the out.Concurrently() call below
|
||||
out.Values[i] = graphql.Null
|
||||
continue
|
||||
}
|
||||
{{end}}
|
||||
|
||||
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler {
|
||||
{{- if $object.Root -}}
|
||||
return rrm(innerCtx)
|
||||
{{- else -}}
|
||||
return innerFunc(ctx, out)
|
||||
{{- end -}}
|
||||
})
|
||||
{{- else }}
|
||||
{{- if $object.Root -}}
|
||||
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
|
||||
return ec._{{$object.Name}}_{{$field.Name}}(ctx, field)
|
||||
})
|
||||
{{- else -}}
|
||||
out.Values[i] = ec._{{$object.Name}}_{{$field.Name}}(ctx, field, obj)
|
||||
{{- end -}}
|
||||
|
||||
{{- if $field.TypeReference.GQL.NonNull }}
|
||||
if out.Values[i] == graphql.Null {
|
||||
{{- if $object.IsConcurrent }}
|
||||
atomic.AddUint32(&out.Invalids, 1)
|
||||
{{- else }}
|
||||
out.Invalids++
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
default:
|
||||
panic("unknown field " + strconv.Quote(field.Name))
|
||||
}
|
||||
}
|
||||
out.Dispatch()
|
||||
if invalids > 0 { return graphql.Null }
|
||||
out.Dispatch(ctx)
|
||||
if out.Invalids > 0 { return graphql.Null }
|
||||
|
||||
atomic.AddInt32(&ec.deferred, int32(len(deferred)))
|
||||
|
||||
for label, dfs := range deferred {
|
||||
ec.processDeferredGroup(graphql.DeferredGroup{
|
||||
Label: label,
|
||||
Path: graphql.GetPath(ctx),
|
||||
FieldSet: dfs,
|
||||
Context: ctx,
|
||||
})
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
73
vendor/github.com/99designs/gqlgen/codegen/root_.gotpl
generated
vendored
73
vendor/github.com/99designs/gqlgen/codegen/root_.gotpl
generated
vendored
@ -49,6 +49,7 @@ type DirectiveRoot struct {
|
||||
}
|
||||
|
||||
type ComplexityRoot struct {
|
||||
{{- if not .Config.OmitComplexity }}
|
||||
{{ range $object := .Objects }}
|
||||
{{ if not $object.IsReserved -}}
|
||||
{{ ucFirst $object.Name }} struct {
|
||||
@ -61,6 +62,7 @@ type ComplexityRoot struct {
|
||||
}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
type executableSchema struct {
|
||||
@ -74,8 +76,9 @@ func (e *executableSchema) Schema() *ast.Schema {
|
||||
}
|
||||
|
||||
func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) {
|
||||
ec := executionContext{nil, e}
|
||||
ec := executionContext{nil, e, 0, 0, nil}
|
||||
_ = ec
|
||||
{{- if not .Config.OmitComplexity }}
|
||||
switch typeName + "." + field {
|
||||
{{ range $object := .Objects }}
|
||||
{{ if not $object.IsReserved }}
|
||||
@ -102,12 +105,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
}
|
||||
{{- end }}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
|
||||
rc := graphql.GetOperationContext(ctx)
|
||||
ec := executionContext{rc, e}
|
||||
ec := executionContext{rc, e, 0, 0, make(chan graphql.DeferredResult)}
|
||||
inputUnmarshalMap := graphql.BuildUnmarshalerMap(
|
||||
{{- range $input := .Inputs -}}
|
||||
{{ if not $input.HasUnmarshal }}
|
||||
@ -120,22 +124,39 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
|
||||
switch rc.Operation.Operation {
|
||||
{{- if .QueryRoot }} case ast.Query:
|
||||
return func(ctx context.Context) *graphql.Response {
|
||||
if !first { return nil }
|
||||
first = false
|
||||
ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap)
|
||||
{{ if .Directives.LocationDirectives "QUERY" -}}
|
||||
data := ec._queryMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){
|
||||
return ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet), nil
|
||||
})
|
||||
{{- else -}}
|
||||
data := ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet)
|
||||
{{- end }}
|
||||
var response graphql.Response
|
||||
var data graphql.Marshaler
|
||||
if first {
|
||||
first = false
|
||||
ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap)
|
||||
{{ if .Directives.LocationDirectives "QUERY" -}}
|
||||
data = ec._queryMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){
|
||||
return ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet), nil
|
||||
})
|
||||
{{- else -}}
|
||||
data = ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet)
|
||||
{{- end }}
|
||||
} else {
|
||||
if atomic.LoadInt32(&ec.pendingDeferred) > 0 {
|
||||
result := <-ec.deferredResults
|
||||
atomic.AddInt32(&ec.pendingDeferred, -1)
|
||||
data = result.Result
|
||||
response.Path = result.Path
|
||||
response.Label = result.Label
|
||||
response.Errors = result.Errors
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
data.MarshalGQL(&buf)
|
||||
|
||||
return &graphql.Response{
|
||||
Data: buf.Bytes(),
|
||||
response.Data = buf.Bytes()
|
||||
if atomic.LoadInt32(&ec.deferred) > 0 {
|
||||
hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0
|
||||
response.HasNext = &hasNext
|
||||
}
|
||||
|
||||
return &response
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
@ -192,6 +213,28 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
|
||||
type executionContext struct {
|
||||
*graphql.OperationContext
|
||||
*executableSchema
|
||||
deferred int32
|
||||
pendingDeferred int32
|
||||
deferredResults chan graphql.DeferredResult
|
||||
}
|
||||
|
||||
func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) {
|
||||
atomic.AddInt32(&ec.pendingDeferred, 1)
|
||||
go func () {
|
||||
ctx := graphql.WithFreshResponseContext(dg.Context)
|
||||
dg.FieldSet.Dispatch(ctx)
|
||||
ds := graphql.DeferredResult{
|
||||
Path: dg.Path,
|
||||
Label: dg.Label,
|
||||
Result: dg.FieldSet,
|
||||
Errors: graphql.GetErrors(ctx),
|
||||
}
|
||||
// null fields should bubble up
|
||||
if dg.FieldSet.Invalids > 0 {
|
||||
ds.Result = graphql.Null
|
||||
}
|
||||
ec.deferredResults <- ds
|
||||
}()
|
||||
}
|
||||
|
||||
func (ec *executionContext) introspectSchema() (*introspection.Schema, error) {
|
||||
|
||||
4
vendor/github.com/99designs/gqlgen/codegen/templates/import.go
generated
vendored
4
vendor/github.com/99designs/gqlgen/codegen/templates/import.go
generated
vendored
@ -45,7 +45,7 @@ func (s *Imports) Reserve(path string, aliases ...string) (string, error) {
|
||||
panic("empty ambient import")
|
||||
}
|
||||
|
||||
// if we are referencing our own package we dont need an import
|
||||
// if we are referencing our own package we don't need an import
|
||||
if code.ImportPathForDir(s.destDir) == path {
|
||||
return "", nil
|
||||
}
|
||||
@ -85,7 +85,7 @@ func (s *Imports) Lookup(path string) string {
|
||||
|
||||
path = code.NormalizeVendor(path)
|
||||
|
||||
// if we are referencing our own package we dont need an import
|
||||
// if we are referencing our own package we don't need an import
|
||||
if code.ImportPathForDir(s.destDir) == path {
|
||||
return ""
|
||||
}
|
||||
|
||||
120
vendor/github.com/99designs/gqlgen/codegen/templates/templates.go
generated
vendored
120
vendor/github.com/99designs/gqlgen/codegen/templates/templates.go
generated
vendored
@ -17,8 +17,8 @@ import (
|
||||
"text/template"
|
||||
"unicode"
|
||||
|
||||
"github.com/99designs/gqlgen/codegen/config"
|
||||
"github.com/99designs/gqlgen/internal/code"
|
||||
|
||||
"github.com/99designs/gqlgen/internal/imports"
|
||||
)
|
||||
|
||||
@ -172,7 +172,7 @@ func parseTemplates(cfg Options, t *template.Template) (*template.Template, erro
|
||||
fileSystem = cfg.TemplateFS
|
||||
} else {
|
||||
// load path relative to calling source file
|
||||
_, callerFile, _, _ := runtime.Caller(1)
|
||||
_, callerFile, _, _ := runtime.Caller(2)
|
||||
rootDir := filepath.Dir(callerFile)
|
||||
fileSystem = os.DirFS(rootDir)
|
||||
}
|
||||
@ -202,7 +202,7 @@ func Funcs() template.FuncMap {
|
||||
"rawQuote": rawQuote,
|
||||
"dump": Dump,
|
||||
"ref": ref,
|
||||
"ts": TypeIdentifier,
|
||||
"ts": config.TypeIdentifier,
|
||||
"call": Call,
|
||||
"prefixLines": prefixLines,
|
||||
"notNil": notNil,
|
||||
@ -248,44 +248,6 @@ func ref(p types.Type) string {
|
||||
return CurrentImports.LookupType(p)
|
||||
}
|
||||
|
||||
var pkgReplacer = strings.NewReplacer(
|
||||
"/", "ᚋ",
|
||||
".", "ᚗ",
|
||||
"-", "ᚑ",
|
||||
"~", "א",
|
||||
)
|
||||
|
||||
func TypeIdentifier(t types.Type) string {
|
||||
res := ""
|
||||
for {
|
||||
switch it := t.(type) {
|
||||
case *types.Pointer:
|
||||
t.Underlying()
|
||||
res += "ᚖ"
|
||||
t = it.Elem()
|
||||
case *types.Slice:
|
||||
res += "ᚕ"
|
||||
t = it.Elem()
|
||||
case *types.Named:
|
||||
res += pkgReplacer.Replace(it.Obj().Pkg().Path())
|
||||
res += "ᚐ"
|
||||
res += it.Obj().Name()
|
||||
return res
|
||||
case *types.Basic:
|
||||
res += it.Name()
|
||||
return res
|
||||
case *types.Map:
|
||||
res += "map"
|
||||
return res
|
||||
case *types.Interface:
|
||||
res += "interface"
|
||||
return res
|
||||
default:
|
||||
panic(fmt.Errorf("unexpected type %T", it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Call(p *types.Func) string {
|
||||
pkg := CurrentImports.Lookup(p.Pkg().Path())
|
||||
|
||||
@ -503,21 +465,40 @@ func wordWalker(str string, f func(*wordInfo)) {
|
||||
}
|
||||
i++
|
||||
|
||||
initialisms := config.GetInitialisms()
|
||||
// [w,i) is a word.
|
||||
word := string(runes[w:i])
|
||||
if !eow && commonInitialisms[word] && !unicode.IsLower(runes[i]) {
|
||||
if !eow && initialisms[word] && !unicode.IsLower(runes[i]) {
|
||||
// through
|
||||
// split IDFoo → ID, Foo
|
||||
// but URLs → URLs
|
||||
} else if !eow {
|
||||
if commonInitialisms[word] {
|
||||
if initialisms[word] {
|
||||
hasCommonInitial = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
matchCommonInitial := false
|
||||
if commonInitialisms[strings.ToUpper(word)] {
|
||||
upperWord := strings.ToUpper(word)
|
||||
if initialisms[upperWord] {
|
||||
// If the uppercase word (string(runes[w:i]) is "ID" or "IP"
|
||||
// AND
|
||||
// the word is the first two characters of the str
|
||||
// AND
|
||||
// that is not the end of the word
|
||||
// AND
|
||||
// the length of the string is greater than 3
|
||||
// AND
|
||||
// the third rune is an uppercase one
|
||||
// THEN
|
||||
// do NOT count this as an initialism.
|
||||
switch upperWord {
|
||||
case "ID", "IP":
|
||||
if word == str[:2] && !eow && len(str) > 3 && unicode.IsUpper(runes[3]) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
hasCommonInitial = true
|
||||
matchCommonInitial = true
|
||||
}
|
||||
@ -573,57 +554,6 @@ func sanitizeKeywords(name string) string {
|
||||
return name
|
||||
}
|
||||
|
||||
// commonInitialisms is a set of common initialisms.
|
||||
// Only add entries that are highly unlikely to be non-initialisms.
|
||||
// For instance, "ID" is fine (Freudian code is rare), but "AND" is not.
|
||||
var commonInitialisms = map[string]bool{
|
||||
"ACL": true,
|
||||
"API": true,
|
||||
"ASCII": true,
|
||||
"CPU": true,
|
||||
"CSS": true,
|
||||
"CSV": true,
|
||||
"DNS": true,
|
||||
"EOF": true,
|
||||
"GUID": true,
|
||||
"HTML": true,
|
||||
"HTTP": true,
|
||||
"HTTPS": true,
|
||||
"ICMP": true,
|
||||
"ID": true,
|
||||
"IP": true,
|
||||
"JSON": true,
|
||||
"KVK": true,
|
||||
"LHS": true,
|
||||
"PDF": true,
|
||||
"PGP": true,
|
||||
"QPS": true,
|
||||
"QR": true,
|
||||
"RAM": true,
|
||||
"RHS": true,
|
||||
"RPC": true,
|
||||
"SLA": true,
|
||||
"SMTP": true,
|
||||
"SQL": true,
|
||||
"SSH": true,
|
||||
"SVG": true,
|
||||
"TCP": true,
|
||||
"TLS": true,
|
||||
"TTL": true,
|
||||
"UDP": true,
|
||||
"UI": true,
|
||||
"UID": true,
|
||||
"URI": true,
|
||||
"URL": true,
|
||||
"UTF8": true,
|
||||
"UUID": true,
|
||||
"VM": true,
|
||||
"XML": true,
|
||||
"XMPP": true,
|
||||
"XSRF": true,
|
||||
"XSS": true,
|
||||
}
|
||||
|
||||
func rawQuote(s string) string {
|
||||
return "`" + strings.ReplaceAll(s, "`", "`+\"`\"+`") + "`"
|
||||
}
|
||||
|
||||
2
vendor/github.com/99designs/gqlgen/codegen/type.go
generated
vendored
2
vendor/github.com/99designs/gqlgen/codegen/type.go
generated
vendored
@ -26,7 +26,7 @@ func processType(ret map[string]*config.TypeReference, ref *config.TypeReference
|
||||
}
|
||||
ret[key] = ref
|
||||
|
||||
if ref.IsSlice() || ref.IsPtrToSlice() || ref.IsPtrToPtr() {
|
||||
if ref.IsSlice() || ref.IsPtrToSlice() || ref.IsPtrToPtr() || ref.IsPtrToIntf() {
|
||||
processType(ret, ref.Elem())
|
||||
}
|
||||
}
|
||||
|
||||
10
vendor/github.com/99designs/gqlgen/codegen/type.gotpl
generated
vendored
10
vendor/github.com/99designs/gqlgen/codegen/type.gotpl
generated
vendored
@ -4,7 +4,7 @@
|
||||
{{- if and $type.IsNilable (not $type.GQL.NonNull) (not $type.IsPtrToPtr) }}
|
||||
if v == nil { return nil, nil }
|
||||
{{- end }}
|
||||
{{- if $type.IsPtrToSlice }}
|
||||
{{- if or $type.IsPtrToSlice $type.IsPtrToIntf }}
|
||||
res, err := ec.{{ $type.Elem.UnmarshalFunc }}(ctx, v)
|
||||
return &res, graphql.ErrorOnPath(ctx, err)
|
||||
{{- else if $type.IsSlice }}
|
||||
@ -75,9 +75,11 @@
|
||||
return res, graphql.ErrorOnPath(ctx, err)
|
||||
{{- else }}
|
||||
res, err := ec.unmarshalInput{{ $type.GQL.Name }}(ctx, v)
|
||||
{{- if $type.IsNilable }}
|
||||
{{- if and $type.IsNilable (not $type.PointersInUmarshalInput) }}
|
||||
return &res, graphql.ErrorOnPath(ctx, err)
|
||||
{{- else}}
|
||||
{{- else if and (not $type.IsNilable) $type.PointersInUmarshalInput }}
|
||||
return *res, graphql.ErrorOnPath(ctx, err)
|
||||
{{- else }}
|
||||
return res, graphql.ErrorOnPath(ctx, err)
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@ -87,7 +89,7 @@
|
||||
|
||||
{{ with $type.MarshalFunc }}
|
||||
func (ec *executionContext) {{ . }}(ctx context.Context, sel ast.SelectionSet, v {{ $type.GO | ref }}) graphql.Marshaler {
|
||||
{{- if $type.IsPtrToSlice }}
|
||||
{{- if or $type.IsPtrToSlice $type.IsPtrToIntf }}
|
||||
return ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, *v)
|
||||
{{- else if $type.IsSlice }}
|
||||
{{- if not $type.GQL.NonNull }}
|
||||
|
||||
1
vendor/github.com/99designs/gqlgen/codegen/util.go
generated
vendored
1
vendor/github.com/99designs/gqlgen/codegen/util.go
generated
vendored
@ -41,6 +41,7 @@ func findGoInterface(def types.Type) (*types.Interface, error) {
|
||||
|
||||
func equalFieldName(source, target string) bool {
|
||||
source = strings.ReplaceAll(source, "_", "")
|
||||
source = strings.ReplaceAll(source, ",omitempty", "")
|
||||
target = strings.ReplaceAll(target, "_", "")
|
||||
return strings.EqualFold(source, target)
|
||||
}
|
||||
|
||||
8
vendor/github.com/99designs/gqlgen/graphql/cache.go
generated
vendored
8
vendor/github.com/99designs/gqlgen/graphql/cache.go
generated
vendored
@ -15,15 +15,15 @@ type Cache interface {
|
||||
type MapCache map[string]interface{}
|
||||
|
||||
// Get looks up a key's value from the cache.
|
||||
func (m MapCache) Get(ctx context.Context, key string) (value interface{}, ok bool) {
|
||||
func (m MapCache) Get(_ context.Context, key string) (value interface{}, ok bool) {
|
||||
v, ok := m[key]
|
||||
return v, ok
|
||||
}
|
||||
|
||||
// Add adds a value to the cache.
|
||||
func (m MapCache) Add(ctx context.Context, key string, value interface{}) { m[key] = value }
|
||||
func (m MapCache) Add(_ context.Context, key string, value interface{}) { m[key] = value }
|
||||
|
||||
type NoCache struct{}
|
||||
|
||||
func (n NoCache) Get(ctx context.Context, key string) (value interface{}, ok bool) { return nil, false }
|
||||
func (n NoCache) Add(ctx context.Context, key string, value interface{}) {}
|
||||
func (n NoCache) Get(_ context.Context, _ string) (value interface{}, ok bool) { return nil, false }
|
||||
func (n NoCache) Add(_ context.Context, _ string, _ interface{}) {}
|
||||
|
||||
12
vendor/github.com/99designs/gqlgen/graphql/context_operation.go
generated
vendored
12
vendor/github.com/99designs/gqlgen/graphql/context_operation.go
generated
vendored
@ -6,6 +6,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/vektah/gqlparser/v2/ast"
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
)
|
||||
|
||||
// Deprecated: Please update all references to OperationContext instead
|
||||
@ -106,9 +107,16 @@ func (c *OperationContext) Errorf(ctx context.Context, format string, args ...in
|
||||
AddErrorf(ctx, format, args...)
|
||||
}
|
||||
|
||||
// Error sends an error to the client, passing it through the formatter.
|
||||
// Deprecated: use graphql.AddError(ctx, err) instead
|
||||
// Error add error or multiple errors (if underlaying type is gqlerror.List) into the stack.
|
||||
// Then it will be sends to the client, passing it through the formatter.
|
||||
func (c *OperationContext) Error(ctx context.Context, err error) {
|
||||
if errList, ok := err.(gqlerror.List); ok {
|
||||
for _, e := range errList {
|
||||
AddError(ctx, e)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
AddError(ctx, err)
|
||||
}
|
||||
|
||||
|
||||
8
vendor/github.com/99designs/gqlgen/graphql/context_response.go
generated
vendored
8
vendor/github.com/99designs/gqlgen/graphql/context_response.go
generated
vendored
@ -36,6 +36,14 @@ func WithResponseContext(ctx context.Context, presenterFunc ErrorPresenterFunc,
|
||||
})
|
||||
}
|
||||
|
||||
func WithFreshResponseContext(ctx context.Context) context.Context {
|
||||
e := getResponseContext(ctx)
|
||||
return context.WithValue(ctx, resultCtx, &responseContext{
|
||||
errorPresenter: e.errorPresenter,
|
||||
recover: e.recover,
|
||||
})
|
||||
}
|
||||
|
||||
// AddErrorf writes a formatted error to the client, first passing it through the error presenter.
|
||||
func AddErrorf(ctx context.Context, format string, args ...interface{}) {
|
||||
AddError(ctx, fmt.Errorf(format, args...))
|
||||
|
||||
26
vendor/github.com/99designs/gqlgen/graphql/deferred.go
generated
vendored
Normal file
26
vendor/github.com/99designs/gqlgen/graphql/deferred.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/vektah/gqlparser/v2/ast"
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
)
|
||||
|
||||
type Deferrable struct {
|
||||
Label string
|
||||
}
|
||||
|
||||
type DeferredGroup struct {
|
||||
Path ast.Path
|
||||
Label string
|
||||
FieldSet *FieldSet
|
||||
Context context.Context
|
||||
}
|
||||
|
||||
type DeferredResult struct {
|
||||
Path ast.Path
|
||||
Label string
|
||||
Result Marshaler
|
||||
Errors gqlerror.List
|
||||
}
|
||||
48
vendor/github.com/99designs/gqlgen/graphql/executable_schema.go
generated
vendored
48
vendor/github.com/99designs/gqlgen/graphql/executable_schema.go
generated
vendored
@ -45,9 +45,19 @@ func collectFields(reqCtx *OperationContext, selSet ast.SelectionSet, satisfies
|
||||
if len(satisfies) > 0 && !instanceOf(sel.TypeCondition, satisfies) {
|
||||
continue
|
||||
}
|
||||
|
||||
shouldDefer, label := deferrable(sel.Directives, reqCtx.Variables)
|
||||
|
||||
for _, childField := range collectFields(reqCtx, sel.SelectionSet, satisfies, visited) {
|
||||
f := getOrCreateAndAppendField(&groupedFields, childField.Name, childField.Alias, childField.ObjectDefinition, func() CollectedField { return childField })
|
||||
f := getOrCreateAndAppendField(
|
||||
&groupedFields, childField.Name, childField.Alias, childField.ObjectDefinition,
|
||||
func() CollectedField { return childField })
|
||||
f.Selections = append(f.Selections, childField.Selections...)
|
||||
if shouldDefer {
|
||||
f.Deferrable = &Deferrable{
|
||||
Label: label,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case *ast.FragmentSpread:
|
||||
@ -70,9 +80,16 @@ func collectFields(reqCtx *OperationContext, selSet ast.SelectionSet, satisfies
|
||||
continue
|
||||
}
|
||||
|
||||
shouldDefer, label := deferrable(sel.Directives, reqCtx.Variables)
|
||||
|
||||
for _, childField := range collectFields(reqCtx, fragment.SelectionSet, satisfies, visited) {
|
||||
f := getOrCreateAndAppendField(&groupedFields, childField.Name, childField.Alias, childField.ObjectDefinition, func() CollectedField { return childField })
|
||||
f := getOrCreateAndAppendField(&groupedFields,
|
||||
childField.Name, childField.Alias, childField.ObjectDefinition,
|
||||
func() CollectedField { return childField })
|
||||
f.Selections = append(f.Selections, childField.Selections...)
|
||||
if shouldDefer {
|
||||
f.Deferrable = &Deferrable{Label: label}
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
@ -87,6 +104,7 @@ type CollectedField struct {
|
||||
*ast.Field
|
||||
|
||||
Selections ast.SelectionSet
|
||||
Deferrable *Deferrable
|
||||
}
|
||||
|
||||
func instanceOf(val string, satisfies []string) bool {
|
||||
@ -150,6 +168,32 @@ func shouldIncludeNode(directives ast.DirectiveList, variables map[string]interf
|
||||
return !skip && include
|
||||
}
|
||||
|
||||
func deferrable(directives ast.DirectiveList, variables map[string]interface{}) (shouldDefer bool, label string) {
|
||||
d := directives.ForName("defer")
|
||||
if d == nil {
|
||||
return false, ""
|
||||
}
|
||||
|
||||
shouldDefer = true
|
||||
|
||||
for _, arg := range d.Arguments {
|
||||
switch arg.Name {
|
||||
case "if":
|
||||
if value, err := arg.Value.Value(variables); err == nil {
|
||||
shouldDefer, _ = value.(bool)
|
||||
}
|
||||
case "label":
|
||||
if value, err := arg.Value.Value(variables); err == nil {
|
||||
label, _ = value.(string)
|
||||
}
|
||||
default:
|
||||
panic(fmt.Sprintf("defer: argument '%s' not supported", arg.Name))
|
||||
}
|
||||
}
|
||||
|
||||
return shouldDefer, label
|
||||
}
|
||||
|
||||
func resolveIfArgument(d *ast.Directive, variables map[string]interface{}) bool {
|
||||
arg := d.Arguments.ForName("if")
|
||||
if arg == nil {
|
||||
|
||||
41
vendor/github.com/99designs/gqlgen/graphql/executable_schema_mock.go
generated
vendored
41
vendor/github.com/99designs/gqlgen/graphql/executable_schema_mock.go
generated
vendored
@ -15,25 +15,25 @@ var _ ExecutableSchema = &ExecutableSchemaMock{}
|
||||
|
||||
// ExecutableSchemaMock is a mock implementation of ExecutableSchema.
|
||||
//
|
||||
// func TestSomethingThatUsesExecutableSchema(t *testing.T) {
|
||||
// func TestSomethingThatUsesExecutableSchema(t *testing.T) {
|
||||
//
|
||||
// // make and configure a mocked ExecutableSchema
|
||||
// mockedExecutableSchema := &ExecutableSchemaMock{
|
||||
// ComplexityFunc: func(typeName string, fieldName string, childComplexity int, args map[string]interface{}) (int, bool) {
|
||||
// panic("mock out the Complexity method")
|
||||
// },
|
||||
// ExecFunc: func(ctx context.Context) ResponseHandler {
|
||||
// panic("mock out the Exec method")
|
||||
// },
|
||||
// SchemaFunc: func() *ast.Schema {
|
||||
// panic("mock out the Schema method")
|
||||
// },
|
||||
// }
|
||||
// // make and configure a mocked ExecutableSchema
|
||||
// mockedExecutableSchema := &ExecutableSchemaMock{
|
||||
// ComplexityFunc: func(typeName string, fieldName string, childComplexity int, args map[string]interface{}) (int, bool) {
|
||||
// panic("mock out the Complexity method")
|
||||
// },
|
||||
// ExecFunc: func(ctx context.Context) ResponseHandler {
|
||||
// panic("mock out the Exec method")
|
||||
// },
|
||||
// SchemaFunc: func() *ast.Schema {
|
||||
// panic("mock out the Schema method")
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// // use mockedExecutableSchema in code that requires ExecutableSchema
|
||||
// // and then make assertions.
|
||||
// // use mockedExecutableSchema in code that requires ExecutableSchema
|
||||
// // and then make assertions.
|
||||
//
|
||||
// }
|
||||
// }
|
||||
type ExecutableSchemaMock struct {
|
||||
// ComplexityFunc mocks the Complexity method.
|
||||
ComplexityFunc func(typeName string, fieldName string, childComplexity int, args map[string]interface{}) (int, bool)
|
||||
@ -95,7 +95,8 @@ func (mock *ExecutableSchemaMock) Complexity(typeName string, fieldName string,
|
||||
|
||||
// ComplexityCalls gets all the calls that were made to Complexity.
|
||||
// Check the length with:
|
||||
// len(mockedExecutableSchema.ComplexityCalls())
|
||||
//
|
||||
// len(mockedExecutableSchema.ComplexityCalls())
|
||||
func (mock *ExecutableSchemaMock) ComplexityCalls() []struct {
|
||||
TypeName string
|
||||
FieldName string
|
||||
@ -132,7 +133,8 @@ func (mock *ExecutableSchemaMock) Exec(ctx context.Context) ResponseHandler {
|
||||
|
||||
// ExecCalls gets all the calls that were made to Exec.
|
||||
// Check the length with:
|
||||
// len(mockedExecutableSchema.ExecCalls())
|
||||
//
|
||||
// len(mockedExecutableSchema.ExecCalls())
|
||||
func (mock *ExecutableSchemaMock) ExecCalls() []struct {
|
||||
Ctx context.Context
|
||||
} {
|
||||
@ -160,7 +162,8 @@ func (mock *ExecutableSchemaMock) Schema() *ast.Schema {
|
||||
|
||||
// SchemaCalls gets all the calls that were made to Schema.
|
||||
// Check the length with:
|
||||
// len(mockedExecutableSchema.SchemaCalls())
|
||||
//
|
||||
// len(mockedExecutableSchema.SchemaCalls())
|
||||
func (mock *ExecutableSchemaMock) SchemaCalls() []struct {
|
||||
} {
|
||||
var calls []struct {
|
||||
|
||||
25
vendor/github.com/99designs/gqlgen/graphql/fieldset.go
generated
vendored
25
vendor/github.com/99designs/gqlgen/graphql/fieldset.go
generated
vendored
@ -1,19 +1,21 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type FieldSet struct {
|
||||
fields []CollectedField
|
||||
Values []Marshaler
|
||||
delayed []delayedResult
|
||||
fields []CollectedField
|
||||
Values []Marshaler
|
||||
Invalids uint32
|
||||
delayed []delayedResult
|
||||
}
|
||||
|
||||
type delayedResult struct {
|
||||
i int
|
||||
f func() Marshaler
|
||||
f func(context.Context) Marshaler
|
||||
}
|
||||
|
||||
func NewFieldSet(fields []CollectedField) *FieldSet {
|
||||
@ -23,15 +25,20 @@ func NewFieldSet(fields []CollectedField) *FieldSet {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *FieldSet) Concurrently(i int, f func() Marshaler) {
|
||||
func (m *FieldSet) AddField(field CollectedField) {
|
||||
m.fields = append(m.fields, field)
|
||||
m.Values = append(m.Values, nil)
|
||||
}
|
||||
|
||||
func (m *FieldSet) Concurrently(i int, f func(context.Context) Marshaler) {
|
||||
m.delayed = append(m.delayed, delayedResult{i: i, f: f})
|
||||
}
|
||||
|
||||
func (m *FieldSet) Dispatch() {
|
||||
func (m *FieldSet) Dispatch(ctx context.Context) {
|
||||
if len(m.delayed) == 1 {
|
||||
// only one concurrent task, no need to spawn a goroutine or deal create waitgroups
|
||||
d := m.delayed[0]
|
||||
m.Values[d.i] = d.f()
|
||||
m.Values[d.i] = d.f(ctx)
|
||||
} else if len(m.delayed) > 1 {
|
||||
// more than one concurrent task, use the main goroutine to do one, only spawn goroutines for the others
|
||||
|
||||
@ -39,12 +46,12 @@ func (m *FieldSet) Dispatch() {
|
||||
for _, d := range m.delayed[1:] {
|
||||
wg.Add(1)
|
||||
go func(d delayedResult) {
|
||||
m.Values[d.i] = d.f()
|
||||
m.Values[d.i] = d.f(ctx)
|
||||
wg.Done()
|
||||
}(d)
|
||||
}
|
||||
|
||||
m.Values[m.delayed[0].i] = m.delayed[0].f()
|
||||
m.Values[m.delayed[0].i] = m.delayed[0].f(ctx)
|
||||
wg.Wait()
|
||||
}
|
||||
}
|
||||
|
||||
8
vendor/github.com/99designs/gqlgen/graphql/handler/extension/complexity.go
generated
vendored
8
vendor/github.com/99designs/gqlgen/graphql/handler/extension/complexity.go
generated
vendored
@ -59,17 +59,17 @@ func (c *ComplexityLimit) Validate(schema graphql.ExecutableSchema) error {
|
||||
|
||||
func (c ComplexityLimit) MutateOperationContext(ctx context.Context, rc *graphql.OperationContext) *gqlerror.Error {
|
||||
op := rc.Doc.Operations.ForName(rc.OperationName)
|
||||
complexity := complexity.Calculate(c.es, op, rc.Variables)
|
||||
complexityCalcs := complexity.Calculate(c.es, op, rc.Variables)
|
||||
|
||||
limit := c.Func(ctx, rc)
|
||||
|
||||
rc.Stats.SetExtension(complexityExtension, &ComplexityStats{
|
||||
Complexity: complexity,
|
||||
Complexity: complexityCalcs,
|
||||
ComplexityLimit: limit,
|
||||
})
|
||||
|
||||
if complexity > limit {
|
||||
err := gqlerror.Errorf("operation has complexity %d, which exceeds the limit of %d", complexity, limit)
|
||||
if complexityCalcs > limit {
|
||||
err := gqlerror.Errorf("operation has complexity %d, which exceeds the limit of %d", complexityCalcs, limit)
|
||||
errcode.Set(err, errComplexityLimit)
|
||||
return err
|
||||
}
|
||||
|
||||
6
vendor/github.com/99designs/gqlgen/graphql/handler/lru/lru.go
generated
vendored
6
vendor/github.com/99designs/gqlgen/graphql/handler/lru/lru.go
generated
vendored
@ -4,17 +4,17 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
lru "github.com/hashicorp/golang-lru/v2"
|
||||
)
|
||||
|
||||
type LRU struct {
|
||||
lru *lru.Cache
|
||||
lru *lru.Cache[string, any]
|
||||
}
|
||||
|
||||
var _ graphql.Cache = &LRU{}
|
||||
|
||||
func New(size int) *LRU {
|
||||
cache, err := lru.New(size)
|
||||
cache, err := lru.New[string, any](size)
|
||||
if err != nil {
|
||||
// An error is only returned for non-positive cache size
|
||||
// and we already checked for that.
|
||||
|
||||
17
vendor/github.com/99designs/gqlgen/graphql/handler/transport/headers.go
generated
vendored
Normal file
17
vendor/github.com/99designs/gqlgen/graphql/handler/transport/headers.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
package transport
|
||||
|
||||
import "net/http"
|
||||
|
||||
func writeHeaders(w http.ResponseWriter, headers map[string][]string) {
|
||||
if len(headers) == 0 {
|
||||
headers = map[string][]string{
|
||||
"Content-Type": {"application/json"},
|
||||
}
|
||||
}
|
||||
|
||||
for key, values := range headers {
|
||||
for _, value := range values {
|
||||
w.Header().Add(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -20,6 +20,10 @@ type MultipartForm struct {
|
||||
// as multipart/form-data in memory, with the remainder stored on disk in
|
||||
// temporary files.
|
||||
MaxMemory int64
|
||||
|
||||
// Map of all headers that are added to graphql response. If not
|
||||
// set, only one header: Content-Type: application/json will be set.
|
||||
ResponseHeaders map[string][]string
|
||||
}
|
||||
|
||||
var _ graphql.Transport = MultipartForm{}
|
||||
@ -52,7 +56,7 @@ func (f MultipartForm) maxMemory() int64 {
|
||||
}
|
||||
|
||||
func (f MultipartForm) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
writeHeaders(w, f.ResponseHeaders)
|
||||
|
||||
start := graphql.Now()
|
||||
|
||||
119
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form_urlencoded.go
generated
vendored
Normal file
119
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form_urlencoded.go
generated
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"io"
|
||||
"mime"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
)
|
||||
|
||||
// FORM implements the application/x-www-form-urlencoded side of the default HTTP transport
|
||||
type UrlEncodedForm struct {
|
||||
// Map of all headers that are added to graphql response. If not
|
||||
// set, only one header: Content-Type: application/json will be set.
|
||||
ResponseHeaders map[string][]string
|
||||
}
|
||||
|
||||
var _ graphql.Transport = UrlEncodedForm{}
|
||||
|
||||
func (h UrlEncodedForm) Supports(r *http.Request) bool {
|
||||
if r.Header.Get("Upgrade") != "" {
|
||||
return false
|
||||
}
|
||||
|
||||
mediaType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return r.Method == "POST" && mediaType == "application/x-www-form-urlencoded"
|
||||
}
|
||||
|
||||
func (h UrlEncodedForm) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) {
|
||||
ctx := r.Context()
|
||||
writeHeaders(w, h.ResponseHeaders)
|
||||
params := &graphql.RawParams{}
|
||||
start := graphql.Now()
|
||||
params.Headers = r.Header
|
||||
params.ReadTime = graphql.TraceTiming{
|
||||
Start: start,
|
||||
End: graphql.Now(),
|
||||
}
|
||||
|
||||
bodyString, err := getRequestBody(r)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
gqlErr := gqlerror.Errorf("could not get form body: %+v", err)
|
||||
resp := exec.DispatchError(ctx, gqlerror.List{gqlErr})
|
||||
writeJson(w, resp)
|
||||
return
|
||||
}
|
||||
|
||||
params, err = h.parseBody(bodyString)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
gqlErr := gqlerror.Errorf("could not cleanup body: %+v", err)
|
||||
resp := exec.DispatchError(ctx, gqlerror.List{gqlErr})
|
||||
writeJson(w, resp)
|
||||
return
|
||||
}
|
||||
|
||||
rc, OpErr := exec.CreateOperationContext(ctx, params)
|
||||
if OpErr != nil {
|
||||
w.WriteHeader(statusFor(OpErr))
|
||||
resp := exec.DispatchError(graphql.WithOperationContext(ctx, rc), OpErr)
|
||||
writeJson(w, resp)
|
||||
return
|
||||
}
|
||||
|
||||
var responses graphql.ResponseHandler
|
||||
responses, ctx = exec.DispatchOperation(ctx, rc)
|
||||
writeJson(w, responses(ctx))
|
||||
}
|
||||
|
||||
func (h UrlEncodedForm) parseBody(bodyString string) (*graphql.RawParams, error) {
|
||||
switch {
|
||||
case strings.Contains(bodyString, "\"query\":"):
|
||||
// body is json
|
||||
return h.parseJson(bodyString)
|
||||
case strings.HasPrefix(bodyString, "query=%7B"):
|
||||
// body is urlencoded
|
||||
return h.parseEncoded(bodyString)
|
||||
default:
|
||||
// body is plain text
|
||||
params := &graphql.RawParams{}
|
||||
params.Query = strings.TrimPrefix(bodyString, "query=")
|
||||
|
||||
return params, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (h UrlEncodedForm) parseEncoded(bodyString string) (*graphql.RawParams, error) {
|
||||
params := &graphql.RawParams{}
|
||||
|
||||
query, err := url.QueryUnescape(bodyString)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
params.Query = strings.TrimPrefix(query, "query=")
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func (h UrlEncodedForm) parseJson(bodyString string) (*graphql.RawParams, error) {
|
||||
params := &graphql.RawParams{}
|
||||
bodyReader := io.NopCloser(strings.NewReader(bodyString))
|
||||
|
||||
err := jsonDecode(bodyReader, ¶ms)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
8
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_get.go
generated
vendored
8
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_get.go
generated
vendored
@ -15,7 +15,11 @@ import (
|
||||
|
||||
// GET implements the GET side of the default HTTP transport
|
||||
// defined in https://github.com/APIs-guru/graphql-over-http#get
|
||||
type GET struct{}
|
||||
type GET struct {
|
||||
// Map of all headers that are added to graphql response. If not
|
||||
// set, only one header: Content-Type: application/json will be set.
|
||||
ResponseHeaders map[string][]string
|
||||
}
|
||||
|
||||
var _ graphql.Transport = GET{}
|
||||
|
||||
@ -34,7 +38,7 @@ func (h GET) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecut
|
||||
writeJsonError(w, err.Error())
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
writeHeaders(w, h.ResponseHeaders)
|
||||
|
||||
raw := &graphql.RawParams{
|
||||
Query: query.Get("query"),
|
||||
|
||||
98
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_graphql.go
generated
vendored
Normal file
98
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_graphql.go
generated
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"mime"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
)
|
||||
|
||||
// GRAPHQL implements the application/graphql side of the HTTP transport
|
||||
// see: https://graphql.org/learn/serving-over-http/#post-request
|
||||
// If the "application/graphql" Content-Type header is present, treat
|
||||
// the HTTP POST body contents as the GraphQL query string.
|
||||
type GRAPHQL struct {
|
||||
// Map of all headers that are added to graphql response. If not
|
||||
// set, only one header: Content-Type: application/json will be set.
|
||||
ResponseHeaders map[string][]string
|
||||
}
|
||||
|
||||
var _ graphql.Transport = GRAPHQL{}
|
||||
|
||||
func (h GRAPHQL) Supports(r *http.Request) bool {
|
||||
if r.Header.Get("Upgrade") != "" {
|
||||
return false
|
||||
}
|
||||
|
||||
mediaType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return r.Method == "POST" && mediaType == "application/graphql"
|
||||
}
|
||||
|
||||
func (h GRAPHQL) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) {
|
||||
ctx := r.Context()
|
||||
writeHeaders(w, h.ResponseHeaders)
|
||||
params := &graphql.RawParams{}
|
||||
start := graphql.Now()
|
||||
params.Headers = r.Header
|
||||
params.ReadTime = graphql.TraceTiming{
|
||||
Start: start,
|
||||
End: graphql.Now(),
|
||||
}
|
||||
|
||||
bodyString, err := getRequestBody(r)
|
||||
if err != nil {
|
||||
gqlErr := gqlerror.Errorf("could not get request body: %+v", err)
|
||||
resp := exec.DispatchError(ctx, gqlerror.List{gqlErr})
|
||||
writeJson(w, resp)
|
||||
return
|
||||
}
|
||||
|
||||
params.Query, err = cleanupBody(bodyString)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
gqlErr := gqlerror.Errorf("could not cleanup body: %+v", err)
|
||||
resp := exec.DispatchError(ctx, gqlerror.List{gqlErr})
|
||||
writeJson(w, resp)
|
||||
return
|
||||
}
|
||||
|
||||
rc, OpErr := exec.CreateOperationContext(ctx, params)
|
||||
if OpErr != nil {
|
||||
w.WriteHeader(statusFor(OpErr))
|
||||
resp := exec.DispatchError(graphql.WithOperationContext(ctx, rc), OpErr)
|
||||
writeJson(w, resp)
|
||||
return
|
||||
}
|
||||
|
||||
var responses graphql.ResponseHandler
|
||||
responses, ctx = exec.DispatchOperation(ctx, rc)
|
||||
writeJson(w, responses(ctx))
|
||||
}
|
||||
|
||||
// Makes sure we strip "query=" keyword from body and
|
||||
// that body is not url escaped
|
||||
func cleanupBody(body string) (out string, err error) {
|
||||
// Some clients send 'query=' at the start of body payload. Let's remove
|
||||
// it to get GQL query only.
|
||||
body = strings.TrimPrefix(body, "query=")
|
||||
|
||||
// Body payload can be url encoded or not. We check if %7B - "{" character
|
||||
// is where query starts. If it is, query is url encoded.
|
||||
if strings.HasPrefix(body, "%7B") {
|
||||
body, err = url.QueryUnescape(body)
|
||||
|
||||
if err != nil {
|
||||
return body, err
|
||||
}
|
||||
}
|
||||
|
||||
return body, err
|
||||
}
|
||||
66
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go
generated
vendored
66
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go
generated
vendored
@ -1,15 +1,24 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
)
|
||||
|
||||
// POST implements the POST side of the default HTTP transport
|
||||
// defined in https://github.com/APIs-guru/graphql-over-http#post
|
||||
type POST struct{}
|
||||
type POST struct {
|
||||
// Map of all headers that are added to graphql response. If not
|
||||
// set, only one header: Content-Type: application/json will be set.
|
||||
ResponseHeaders map[string][]string
|
||||
}
|
||||
|
||||
var _ graphql.Transport = POST{}
|
||||
|
||||
@ -26,31 +35,58 @@ func (h POST) Supports(r *http.Request) bool {
|
||||
return r.Method == "POST" && mediaType == "application/json"
|
||||
}
|
||||
|
||||
func (h POST) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
var params *graphql.RawParams
|
||||
start := graphql.Now()
|
||||
if err := jsonDecode(r.Body, ¶ms); err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
writeJsonErrorf(w, "json body could not be decoded: "+err.Error())
|
||||
return
|
||||
func getRequestBody(r *http.Request) (string, error) {
|
||||
if r == nil || r.Body == nil {
|
||||
return "", nil
|
||||
}
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unable to get Request Body %w", err)
|
||||
}
|
||||
return string(body), nil
|
||||
}
|
||||
|
||||
func (h POST) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) {
|
||||
ctx := r.Context()
|
||||
writeHeaders(w, h.ResponseHeaders)
|
||||
params := &graphql.RawParams{}
|
||||
start := graphql.Now()
|
||||
params.Headers = r.Header
|
||||
|
||||
params.ReadTime = graphql.TraceTiming{
|
||||
Start: start,
|
||||
End: graphql.Now(),
|
||||
}
|
||||
|
||||
rc, err := exec.CreateOperationContext(r.Context(), params)
|
||||
bodyString, err := getRequestBody(r)
|
||||
if err != nil {
|
||||
w.WriteHeader(statusFor(err))
|
||||
resp := exec.DispatchError(graphql.WithOperationContext(r.Context(), rc), err)
|
||||
gqlErr := gqlerror.Errorf("could not get json request body: %+v", err)
|
||||
resp := exec.DispatchError(ctx, gqlerror.List{gqlErr})
|
||||
writeJson(w, resp)
|
||||
return
|
||||
}
|
||||
responses, ctx := exec.DispatchOperation(r.Context(), rc)
|
||||
|
||||
bodyReader := io.NopCloser(strings.NewReader(bodyString))
|
||||
if err = jsonDecode(bodyReader, ¶ms); err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
gqlErr := gqlerror.Errorf(
|
||||
"json request body could not be decoded: %+v body:%s",
|
||||
err,
|
||||
bodyString,
|
||||
)
|
||||
resp := exec.DispatchError(ctx, gqlerror.List{gqlErr})
|
||||
writeJson(w, resp)
|
||||
return
|
||||
}
|
||||
|
||||
rc, OpErr := exec.CreateOperationContext(ctx, params)
|
||||
if OpErr != nil {
|
||||
w.WriteHeader(statusFor(OpErr))
|
||||
resp := exec.DispatchError(graphql.WithOperationContext(ctx, rc), OpErr)
|
||||
writeJson(w, resp)
|
||||
return
|
||||
}
|
||||
|
||||
var responses graphql.ResponseHandler
|
||||
responses, ctx = exec.DispatchOperation(ctx, rc)
|
||||
writeJson(w, responses(ctx))
|
||||
}
|
||||
|
||||
107
vendor/github.com/99designs/gqlgen/graphql/handler/transport/sse.go
generated
vendored
Normal file
107
vendor/github.com/99designs/gqlgen/graphql/handler/transport/sse.go
generated
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"mime"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
)
|
||||
|
||||
type SSE struct{}
|
||||
|
||||
var _ graphql.Transport = SSE{}
|
||||
|
||||
func (t SSE) Supports(r *http.Request) bool {
|
||||
if !strings.Contains(r.Header.Get("Accept"), "text/event-stream") {
|
||||
return false
|
||||
}
|
||||
mediaType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return r.Method == http.MethodPost && mediaType == "application/json"
|
||||
}
|
||||
|
||||
func (t SSE) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) {
|
||||
ctx := r.Context()
|
||||
flusher, ok := w.(http.Flusher)
|
||||
if !ok {
|
||||
SendErrorf(w, http.StatusInternalServerError, "streaming unsupported")
|
||||
return
|
||||
}
|
||||
defer flusher.Flush()
|
||||
|
||||
w.Header().Set("Cache-Control", "no-cache")
|
||||
w.Header().Set("Connection", "keep-alive")
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
params := &graphql.RawParams{}
|
||||
start := graphql.Now()
|
||||
params.Headers = r.Header
|
||||
params.ReadTime = graphql.TraceTiming{
|
||||
Start: start,
|
||||
End: graphql.Now(),
|
||||
}
|
||||
|
||||
bodyString, err := getRequestBody(r)
|
||||
if err != nil {
|
||||
gqlErr := gqlerror.Errorf("could not get json request body: %+v", err)
|
||||
resp := exec.DispatchError(ctx, gqlerror.List{gqlErr})
|
||||
log.Printf("could not get json request body: %+v", err.Error())
|
||||
writeJson(w, resp)
|
||||
return
|
||||
}
|
||||
|
||||
bodyReader := io.NopCloser(strings.NewReader(bodyString))
|
||||
if err = jsonDecode(bodyReader, ¶ms); err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
gqlErr := gqlerror.Errorf(
|
||||
"json request body could not be decoded: %+v body:%s",
|
||||
err,
|
||||
bodyString,
|
||||
)
|
||||
resp := exec.DispatchError(ctx, gqlerror.List{gqlErr})
|
||||
log.Printf("decoding error: %+v body:%s", err.Error(), bodyString)
|
||||
writeJson(w, resp)
|
||||
return
|
||||
}
|
||||
|
||||
rc, opErr := exec.CreateOperationContext(ctx, params)
|
||||
ctx = graphql.WithOperationContext(ctx, rc)
|
||||
|
||||
w.Header().Set("Content-Type", "text/event-stream")
|
||||
fmt.Fprint(w, ":\n\n")
|
||||
flusher.Flush()
|
||||
|
||||
if opErr != nil {
|
||||
resp := exec.DispatchError(ctx, opErr)
|
||||
writeJsonWithSSE(w, resp)
|
||||
} else {
|
||||
responses, ctx := exec.DispatchOperation(ctx, rc)
|
||||
for {
|
||||
response := responses(ctx)
|
||||
if response == nil {
|
||||
break
|
||||
}
|
||||
writeJsonWithSSE(w, response)
|
||||
flusher.Flush()
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprint(w, "event: complete\n\n")
|
||||
}
|
||||
|
||||
func writeJsonWithSSE(w io.Writer, response *graphql.Response) {
|
||||
b, err := json.Marshal(response)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Fprintf(w, "event: next\ndata: %s\n\n", b)
|
||||
}
|
||||
15
vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go
generated
vendored
15
vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go
generated
vendored
@ -24,6 +24,7 @@ type (
|
||||
InitFunc WebsocketInitFunc
|
||||
InitTimeout time.Duration
|
||||
ErrorFunc WebsocketErrorFunc
|
||||
CloseFunc WebsocketCloseFunc
|
||||
KeepAlivePingInterval time.Duration
|
||||
PingPongInterval time.Duration
|
||||
|
||||
@ -45,6 +46,9 @@ type (
|
||||
|
||||
WebsocketInitFunc func(ctx context.Context, initPayload InitPayload) (context.Context, error)
|
||||
WebsocketErrorFunc func(ctx context.Context, err error)
|
||||
|
||||
// Callback called when websocket is closed.
|
||||
WebsocketCloseFunc func(ctx context.Context, closeCode int)
|
||||
)
|
||||
|
||||
var errReadTimeout = errors.New("read timeout")
|
||||
@ -350,6 +354,7 @@ func (c *wsConnection) subscribe(start time.Time, msg *message) {
|
||||
c.mu.Unlock()
|
||||
|
||||
go func() {
|
||||
ctx = withSubscriptionErrorContext(ctx)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err := rc.Recover(ctx, r)
|
||||
@ -362,7 +367,11 @@ func (c *wsConnection) subscribe(start time.Time, msg *message) {
|
||||
}
|
||||
c.sendError(msg.id, gqlerr)
|
||||
}
|
||||
c.complete(msg.id)
|
||||
if errs := getSubscriptionError(ctx); len(errs) != 0 {
|
||||
c.sendError(msg.id, errs...)
|
||||
} else {
|
||||
c.complete(msg.id)
|
||||
}
|
||||
c.mu.Lock()
|
||||
delete(c.active, msg.id)
|
||||
c.mu.Unlock()
|
||||
@ -428,4 +437,8 @@ func (c *wsConnection) close(closeCode int, message string) {
|
||||
}
|
||||
c.mu.Unlock()
|
||||
_ = c.conn.Close()
|
||||
|
||||
if c.CloseFunc != nil {
|
||||
c.CloseFunc(c.ctx, closeCode)
|
||||
}
|
||||
}
|
||||
|
||||
69
vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_resolver_error.go
generated
vendored
Normal file
69
vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_resolver_error.go
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
)
|
||||
|
||||
// A private key for context that only this package can access. This is important
|
||||
// to prevent collisions between different context uses
|
||||
var wsSubscriptionErrorCtxKey = &wsSubscriptionErrorContextKey{"subscription-error"}
|
||||
|
||||
type wsSubscriptionErrorContextKey struct {
|
||||
name string
|
||||
}
|
||||
|
||||
type subscriptionError struct {
|
||||
errs []*gqlerror.Error
|
||||
}
|
||||
|
||||
// AddSubscriptionError is used to let websocket return an error message after subscription resolver returns a channel.
|
||||
// for example:
|
||||
//
|
||||
// func (r *subscriptionResolver) Method(ctx context.Context) (<-chan *model.Message, error) {
|
||||
// ch := make(chan *model.Message)
|
||||
// go func() {
|
||||
// defer func() {
|
||||
// close(ch)
|
||||
// }
|
||||
// // some kind of block processing (e.g.: gRPC client streaming)
|
||||
// stream, err := gRPCClientStreamRequest(ctx)
|
||||
// if err != nil {
|
||||
// transport.AddSubscriptionError(ctx, err)
|
||||
// return // must return and close channel so websocket can send error back
|
||||
// }
|
||||
// for {
|
||||
// m, err := stream.Recv()
|
||||
// if err == io.EOF {
|
||||
// return
|
||||
// }
|
||||
// if err != nil {
|
||||
// transport.AddSubscriptionError(ctx, err)
|
||||
// return // must return and close channel so websocket can send error back
|
||||
// }
|
||||
// ch <- m
|
||||
// }
|
||||
// }()
|
||||
//
|
||||
// return ch, nil
|
||||
// }
|
||||
//
|
||||
// see https://github.com/99designs/gqlgen/pull/2506 for more details
|
||||
func AddSubscriptionError(ctx context.Context, err *gqlerror.Error) {
|
||||
subscriptionErrStruct := getSubscriptionErrorStruct(ctx)
|
||||
subscriptionErrStruct.errs = append(subscriptionErrStruct.errs, err)
|
||||
}
|
||||
|
||||
func withSubscriptionErrorContext(ctx context.Context) context.Context {
|
||||
return context.WithValue(ctx, wsSubscriptionErrorCtxKey, &subscriptionError{})
|
||||
}
|
||||
|
||||
func getSubscriptionErrorStruct(ctx context.Context) *subscriptionError {
|
||||
v, _ := ctx.Value(wsSubscriptionErrorCtxKey).(*subscriptionError)
|
||||
return v
|
||||
}
|
||||
|
||||
func getSubscriptionError(ctx context.Context) []*gqlerror.Error {
|
||||
return getSubscriptionErrorStruct(ctx).errs
|
||||
}
|
||||
6
vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go
generated
vendored
6
vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go
generated
vendored
@ -74,13 +74,15 @@ func (f *Field) IsDeprecated() bool {
|
||||
}
|
||||
|
||||
func (f *Field) DeprecationReason() *string {
|
||||
if f.deprecation == nil {
|
||||
if f.deprecation == nil || !f.IsDeprecated() {
|
||||
return nil
|
||||
}
|
||||
|
||||
reason := f.deprecation.Arguments.ForName("reason")
|
||||
|
||||
if reason == nil {
|
||||
return nil
|
||||
defaultReason := "No longer supported"
|
||||
return &defaultReason
|
||||
}
|
||||
|
||||
return &reason.Value.Raw
|
||||
|
||||
35
vendor/github.com/99designs/gqlgen/graphql/omittable.go
generated
vendored
Normal file
35
vendor/github.com/99designs/gqlgen/graphql/omittable.go
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
package graphql
|
||||
|
||||
// Omittable is a wrapper around a value that also stores whether it is set
|
||||
// or not.
|
||||
type Omittable[T any] struct {
|
||||
value T
|
||||
set bool
|
||||
}
|
||||
|
||||
func OmittableOf[T any](value T) Omittable[T] {
|
||||
return Omittable[T]{
|
||||
value: value,
|
||||
set: true,
|
||||
}
|
||||
}
|
||||
|
||||
func (o Omittable[T]) Value() T {
|
||||
if !o.set {
|
||||
var zero T
|
||||
return zero
|
||||
}
|
||||
return o.value
|
||||
}
|
||||
|
||||
func (o Omittable[T]) ValueOK() (T, bool) {
|
||||
if !o.set {
|
||||
var zero T
|
||||
return zero, false
|
||||
}
|
||||
return o.value, true
|
||||
}
|
||||
|
||||
func (o Omittable[T]) IsSet() bool {
|
||||
return o.set
|
||||
}
|
||||
84
vendor/github.com/99designs/gqlgen/graphql/playground/altair_playground.go
generated
vendored
Normal file
84
vendor/github.com/99designs/gqlgen/graphql/playground/altair_playground.go
generated
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
package playground
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var altairPage = template.Must(template.New("altair").Parse(`<!doctype html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{{.title}}</title>
|
||||
<base href="https://cdn.jsdelivr.net/npm/altair-static@{{.version}}/build/dist/">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<link href="styles.css" rel="stylesheet" crossorigin="anonymous" integrity="{{.cssSRI}}"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<app-root>
|
||||
<style>
|
||||
.loading-screen {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<div class="loading-screen styled">
|
||||
<div class="loading-screen-inner">
|
||||
<div class="loading-screen-logo-container">
|
||||
<img src="assets/img/logo_350.svg" alt="Altair">
|
||||
</div>
|
||||
<div class="loading-screen-loading-indicator">
|
||||
<span class="loading-indicator-dot"></span>
|
||||
<span class="loading-indicator-dot"></span>
|
||||
<span class="loading-indicator-dot"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</app-root>
|
||||
|
||||
<script rel="preload" as="script" type="text/javascript" crossorigin="anonymous" integrity="{{.mainSRI}}" src="main.js"></script>
|
||||
<script rel="preload" as="script" type="text/javascript" crossorigin="anonymous" integrity="{{.polyfillsSRI}}" src="polyfills.js"></script>
|
||||
<script rel="preload" as="script" type="text/javascript" crossorigin="anonymous" integrity="{{.runtimeSRI}}" src="runtime.js"></script>
|
||||
|
||||
<script>
|
||||
{{- if .endpointIsAbsolute}}
|
||||
const url = {{.endpoint}};
|
||||
const subscriptionUrl = {{.subscriptionEndpoint}};
|
||||
{{- else}}
|
||||
const url = location.protocol + '//' + location.host + {{.endpoint}};
|
||||
const wsProto = location.protocol == 'https:' ? 'wss:' : 'ws:';
|
||||
const subscriptionUrl = wsProto + '//' + location.host + {{.endpoint}};
|
||||
{{- end}}
|
||||
var altairOptions = {
|
||||
endpointURL: url,
|
||||
subscriptionsEndpoint: subscriptionUrl,
|
||||
};
|
||||
window.addEventListener("load", function() {
|
||||
AltairGraphQL.init(altairOptions);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>`))
|
||||
|
||||
// AltairHandler responsible for setting up the altair playground
|
||||
func AltairHandler(title, endpoint string) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
err := altairPage.Execute(w, map[string]interface{}{
|
||||
"title": title,
|
||||
"endpoint": endpoint,
|
||||
"endpointIsAbsolute": endpointHasScheme(endpoint),
|
||||
"subscriptionEndpoint": getSubscriptionEndpoint(endpoint),
|
||||
"version": "5.0.5",
|
||||
"cssSRI": "sha256-kZ35e5mdMYN5ALEbnsrA2CLn85Oe4hBodfsih9BqNxs=",
|
||||
"mainSRI": "sha256-nWdVTcGTlBDV1L04UQnqod+AJedzBCnKHv6Ct65liHE=",
|
||||
"polyfillsSRI": "sha256-1aVEg2sROcCQ/RxU3AlcPaRZhZdIWA92q2M+mdd/R4c=",
|
||||
"runtimeSRI": "sha256-cK2XhXqQr0WS1Z5eKNdac0rJxTD6miC3ubd+aEVMQDk=",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
62
vendor/github.com/99designs/gqlgen/graphql/playground/apollo_sandbox_playground.go
generated
vendored
Normal file
62
vendor/github.com/99designs/gqlgen/graphql/playground/apollo_sandbox_playground.go
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
package playground
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var apolloSandboxPage = template.Must(template.New("ApolloSandbox").Parse(`<!doctype html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{{.title}}</title>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link rel="icon" href="https://embeddable-sandbox.cdn.apollographql.com/_latest/public/assets/favicon-dark.png">
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div style="width: 100vw; height: 100vh;" id='embedded-sandbox'></div>
|
||||
<!-- NOTE: New version available at https://embeddable-sandbox.cdn.apollographql.com/ -->
|
||||
<script rel="preload" as="script" crossorigin="anonymous" integrity="{{.mainSRI}}" type="text/javascript" src="https://embeddable-sandbox.cdn.apollographql.com/7212121cad97028b007e974956dc951ce89d683c/embeddable-sandbox.umd.production.min.js"></script>
|
||||
<script>
|
||||
{{- if .endpointIsAbsolute}}
|
||||
const url = {{.endpoint}};
|
||||
{{- else}}
|
||||
const url = location.protocol + '//' + location.host + {{.endpoint}};
|
||||
{{- end}}
|
||||
<!-- See https://www.apollographql.com/docs/graphos/explorer/sandbox/#options -->
|
||||
new window.EmbeddedSandbox({
|
||||
target: '#embedded-sandbox',
|
||||
initialEndpoint: url,
|
||||
persistExplorerState: true,
|
||||
initialState: {
|
||||
includeCookies: true,
|
||||
pollForSchemaUpdates: false,
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>`))
|
||||
|
||||
// ApolloSandboxHandler responsible for setting up the altair playground
|
||||
func ApolloSandboxHandler(title, endpoint string) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
err := apolloSandboxPage.Execute(w, map[string]interface{}{
|
||||
"title": title,
|
||||
"endpoint": endpoint,
|
||||
"endpointIsAbsolute": endpointHasScheme(endpoint),
|
||||
"mainSRI": "sha256-ldbSJ7EovavF815TfCN50qKB9AMvzskb9xiG71bmg2I=",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
14
vendor/github.com/99designs/gqlgen/graphql/playground/playground.go
generated
vendored
14
vendor/github.com/99designs/gqlgen/graphql/playground/playground.go
generated
vendored
@ -24,12 +24,12 @@ var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
|
||||
}
|
||||
</style>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/react@17.0.2/umd/react.production.min.js"
|
||||
src="https://cdn.jsdelivr.net/npm/react@18.2.0/umd/react.production.min.js"
|
||||
integrity="{{.reactSRI}}"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/react-dom@17.0.2/umd/react-dom.production.min.js"
|
||||
src="https://cdn.jsdelivr.net/npm/react-dom@18.2.0/umd/react-dom.production.min.js"
|
||||
integrity="{{.reactDOMSRI}}"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
@ -82,11 +82,11 @@ func Handler(title string, endpoint string) http.HandlerFunc {
|
||||
"endpoint": endpoint,
|
||||
"endpointIsAbsolute": endpointHasScheme(endpoint),
|
||||
"subscriptionEndpoint": getSubscriptionEndpoint(endpoint),
|
||||
"version": "2.0.7",
|
||||
"cssSRI": "sha256-gQryfbGYeYFxnJYnfPStPYFt0+uv8RP8Dm++eh00G9c=",
|
||||
"jsSRI": "sha256-qQ6pw7LwTLC+GfzN+cJsYXfVWRKH9O5o7+5H96gTJhQ=",
|
||||
"reactSRI": "sha256-Ipu/TQ50iCCVZBUsZyNJfxrDk0E2yhaEIz0vqI+kFG8=",
|
||||
"reactDOMSRI": "sha256-nbMykgB6tsOFJ7OdVmPpdqMFVk4ZsqWocT6issAPUF0=",
|
||||
"version": "3.0.1",
|
||||
"cssSRI": "sha256-wTzfn13a+pLMB5rMeysPPR1hO7x0SwSeQI+cnw7VdbE=",
|
||||
"jsSRI": "sha256-dLnxjV+d2rFUCtYKjbPy413/8O+Ahy7QqAhaPNlL8fk=",
|
||||
"reactSRI": "sha256-S0lp+k7zWUMk2ixteM6HZvu8L9Eh//OVrt+ZfbCpmgY=",
|
||||
"reactDOMSRI": "sha256-IXWO0ITNDjfnNXIu5POVfqlgYoop36bDzhodR6LW5Pc=",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
4
vendor/github.com/99designs/gqlgen/graphql/response.go
generated
vendored
4
vendor/github.com/99designs/gqlgen/graphql/response.go
generated
vendored
@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/vektah/gqlparser/v2/ast"
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
)
|
||||
|
||||
@ -14,6 +15,9 @@ import (
|
||||
type Response struct {
|
||||
Errors gqlerror.List `json:"errors,omitempty"`
|
||||
Data json.RawMessage `json:"data"`
|
||||
Label string `json:"label,omitempty"`
|
||||
Path ast.Path `json:"path,omitempty"`
|
||||
HasNext *bool `json:"hasNext,omitempty"`
|
||||
Extensions map[string]interface{} `json:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
4
vendor/github.com/99designs/gqlgen/graphql/stats.go
generated
vendored
4
vendor/github.com/99designs/gqlgen/graphql/stats.go
generated
vendored
@ -12,7 +12,7 @@ type Stats struct {
|
||||
Parsing TraceTiming
|
||||
Validation TraceTiming
|
||||
|
||||
// Stats collected by handler extensions. Dont use directly, the extension should provide a type safe way to
|
||||
// Stats collected by handler extensions. Don't use directly, the extension should provide a type safe way to
|
||||
// access this.
|
||||
extension map[string]interface{}
|
||||
}
|
||||
@ -26,7 +26,7 @@ var ctxTraceStart key = "trace_start"
|
||||
|
||||
// StartOperationTrace captures the current time and stores it in context. This will eventually be added to request
|
||||
// context but we want to grab it as soon as possible. For transports that can only handle a single graphql query
|
||||
// per http requests you dont need to call this at all, the server will do it for you. For transports that handle
|
||||
// per http requests you don't need to call this at all, the server will do it for you. For transports that handle
|
||||
// multiple (eg batching, subscriptions) this should be called before decoding each request.
|
||||
func StartOperationTrace(ctx context.Context) context.Context {
|
||||
return context.WithValue(ctx, ctxTraceStart, Now())
|
||||
|
||||
5
vendor/github.com/99designs/gqlgen/graphql/string.go
generated
vendored
5
vendor/github.com/99designs/gqlgen/graphql/string.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
@ -55,7 +56,9 @@ func UnmarshalString(v interface{}) (string, error) {
|
||||
case int64:
|
||||
return strconv.FormatInt(v, 10), nil
|
||||
case float64:
|
||||
return fmt.Sprintf("%f", v), nil
|
||||
return strconv.FormatFloat(v, 'f', -1, 64), nil
|
||||
case json.Number:
|
||||
return string(v), nil
|
||||
case bool:
|
||||
if v {
|
||||
return "true", nil
|
||||
|
||||
2
vendor/github.com/99designs/gqlgen/graphql/uint.go
generated
vendored
2
vendor/github.com/99designs/gqlgen/graphql/uint.go
generated
vendored
@ -60,7 +60,7 @@ func MarshalUint32(i uint32) Marshaler {
|
||||
func UnmarshalUint32(v interface{}) (uint32, error) {
|
||||
switch v := v.(type) {
|
||||
case string:
|
||||
iv, err := strconv.ParseInt(v, 10, 32)
|
||||
iv, err := strconv.ParseUint(v, 10, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
2
vendor/github.com/99designs/gqlgen/graphql/version.go
generated
vendored
2
vendor/github.com/99designs/gqlgen/graphql/version.go
generated
vendored
@ -1,3 +1,3 @@
|
||||
package graphql
|
||||
|
||||
const Version = "v0.17.20"
|
||||
const Version = "v0.17.36"
|
||||
|
||||
32
vendor/github.com/99designs/gqlgen/init-templates/gqlgen.yml.gotmpl
generated
vendored
32
vendor/github.com/99designs/gqlgen/init-templates/gqlgen.yml.gotmpl
generated
vendored
@ -4,13 +4,13 @@ schema:
|
||||
|
||||
# Where should the generated server code go?
|
||||
exec:
|
||||
filename: graph/generated/generated.go
|
||||
package: generated
|
||||
filename: graph/generated.go
|
||||
package: graph
|
||||
|
||||
# Uncomment to enable federation
|
||||
# federation:
|
||||
# filename: graph/generated/federation.go
|
||||
# package: generated
|
||||
# filename: graph/federation.go
|
||||
# package: graph
|
||||
|
||||
# Where should any generated models go?
|
||||
model:
|
||||
@ -22,6 +22,9 @@ resolver:
|
||||
layout: follow-schema
|
||||
dir: graph
|
||||
package: graph
|
||||
filename_template: "{name}.resolvers.go"
|
||||
# Optional: turn on to not generate template comments above resolvers
|
||||
# omit_template_comment: false
|
||||
|
||||
# Optional: turn on use ` + "`" + `gqlgen:"fieldName"` + "`" + ` tags in your models
|
||||
# struct_tag: json
|
||||
@ -29,6 +32,18 @@ resolver:
|
||||
# Optional: turn on to use []Thing instead of []*Thing
|
||||
# omit_slice_element_pointers: false
|
||||
|
||||
# Optional: turn on to omit Is<Name>() methods to interface and unions
|
||||
# omit_interface_checks : true
|
||||
|
||||
# Optional: turn on to skip generation of ComplexityRoot struct content and Complexity function
|
||||
# omit_complexity: false
|
||||
|
||||
# Optional: turn on to not generate any file notice comments in generated files
|
||||
# omit_gqlgen_file_notice: false
|
||||
|
||||
# Optional: turn on to exclude the gqlgen version in the generated file notice. No effect if `omit_gqlgen_file_notice` is true.
|
||||
# omit_gqlgen_version_in_file_notice: false
|
||||
|
||||
# Optional: turn off to make struct-type struct fields not use pointers
|
||||
# e.g. type Thing struct { FieldA OtherThing } instead of { FieldA *OtherThing }
|
||||
# struct_fields_always_pointers: true
|
||||
@ -36,9 +51,18 @@ resolver:
|
||||
# Optional: turn off to make resolvers return values instead of pointers for structs
|
||||
# resolvers_always_return_pointers: true
|
||||
|
||||
# Optional: turn on to return pointers instead of values in unmarshalInput
|
||||
# return_pointers_in_unmarshalinput: false
|
||||
|
||||
# Optional: wrap nullable input fields with Omittable
|
||||
# nullable_input_omittable: true
|
||||
|
||||
# Optional: set to speed up generation time by not performing a final validation pass.
|
||||
# skip_validation: true
|
||||
|
||||
# Optional: set to skip running `go mod tidy` when generating server code
|
||||
# skip_mod_tidy: true
|
||||
|
||||
# gqlgen will search for any type names in the schema in these go packages
|
||||
# if they match it will use them, otherwise it will generate them.
|
||||
autobind:
|
||||
|
||||
16
vendor/github.com/99designs/gqlgen/internal/code/compare.go
generated
vendored
16
vendor/github.com/99designs/gqlgen/internal/code/compare.go
generated
vendored
@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
// CompatibleTypes isnt a strict comparison, it allows for pointer differences
|
||||
func CompatibleTypes(expected types.Type, actual types.Type) error {
|
||||
func CompatibleTypes(expected, actual types.Type) error {
|
||||
// Special case to deal with pointer mismatches
|
||||
{
|
||||
expectedPtr, expectedIsPtr := expected.(*types.Pointer)
|
||||
@ -84,11 +84,8 @@ func CompatibleTypes(expected types.Type, actual types.Type) error {
|
||||
if err := CompatibleTypes(expected.Params(), actual.Params()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := CompatibleTypes(expected.Results(), actual.Results()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
err := CompatibleTypes(expected.Results(), actual.Results())
|
||||
return err
|
||||
}
|
||||
case *types.Interface:
|
||||
if actual, ok := actual.(*types.Interface); ok {
|
||||
@ -114,11 +111,8 @@ func CompatibleTypes(expected types.Type, actual types.Type) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := CompatibleTypes(expected.Elem(), actual.Elem()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
err := CompatibleTypes(expected.Elem(), actual.Elem())
|
||||
return err
|
||||
}
|
||||
|
||||
case *types.Chan:
|
||||
|
||||
4
vendor/github.com/99designs/gqlgen/internal/code/imports.go
generated
vendored
4
vendor/github.com/99designs/gqlgen/internal/code/imports.go
generated
vendored
@ -138,7 +138,7 @@ func extractModuleName(content []byte) string {
|
||||
break
|
||||
}
|
||||
s := strings.Trim(string(tkn), " \t")
|
||||
if len(s) != 0 && !strings.HasPrefix(s, "//") {
|
||||
if s != "" && !strings.HasPrefix(s, "//") {
|
||||
break
|
||||
}
|
||||
if advance <= len(content) {
|
||||
@ -171,4 +171,4 @@ func ImportPathForDir(dir string) (res string) {
|
||||
return ""
|
||||
}
|
||||
|
||||
var modregex = regexp.MustCompile(`module ([^\s]*)`)
|
||||
var modregex = regexp.MustCompile(`module (\S*)`)
|
||||
|
||||
56
vendor/github.com/99designs/gqlgen/internal/code/packages.go
generated
vendored
56
vendor/github.com/99designs/gqlgen/internal/code/packages.go
generated
vendored
@ -7,10 +7,18 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
var (
|
||||
once = sync.Once{}
|
||||
modInfo *debug.BuildInfo
|
||||
)
|
||||
|
||||
var mode = packages.NeedName |
|
||||
packages.NeedFiles |
|
||||
packages.NeedImports |
|
||||
@ -31,20 +39,39 @@ type Packages struct {
|
||||
numNameCalls int // stupid test steam. ignore.
|
||||
}
|
||||
|
||||
func (p *Packages) CleanupUserPackages() {
|
||||
once.Do(func() {
|
||||
var ok bool
|
||||
modInfo, ok = debug.ReadBuildInfo()
|
||||
if !ok {
|
||||
modInfo = nil
|
||||
}
|
||||
})
|
||||
|
||||
// Don't cleanup github.com/99designs/gqlgen prefixed packages, they haven't changed and do not need to be reloaded
|
||||
if modInfo != nil {
|
||||
var toRemove []string
|
||||
for k := range p.packages {
|
||||
if !strings.HasPrefix(k, modInfo.Main.Path) {
|
||||
toRemove = append(toRemove, k)
|
||||
}
|
||||
}
|
||||
|
||||
for _, k := range toRemove {
|
||||
delete(p.packages, k)
|
||||
}
|
||||
} else {
|
||||
p.packages = nil // Cleanup all packages if we don't know for some reason which ones to keep
|
||||
}
|
||||
}
|
||||
|
||||
// ReloadAll will call LoadAll after clearing the package cache, so we can reload
|
||||
// packages in the case that the packages have changed
|
||||
func (p *Packages) ReloadAll(importPaths ...string) []*packages.Package {
|
||||
p.packages = nil
|
||||
return p.LoadAll(importPaths...)
|
||||
}
|
||||
|
||||
func (p *Packages) checkModuleLoaded(pkgs []*packages.Package) bool {
|
||||
for i := range pkgs {
|
||||
if pkgs[i] == nil || pkgs[i].Module == nil {
|
||||
return false
|
||||
}
|
||||
if p.packages != nil {
|
||||
p.CleanupUserPackages()
|
||||
}
|
||||
return true
|
||||
return p.LoadAll(importPaths...)
|
||||
}
|
||||
|
||||
// LoadAll will call packages.Load and return the package data for the given packages,
|
||||
@ -65,13 +92,6 @@ func (p *Packages) LoadAll(importPaths ...string) []*packages.Package {
|
||||
if len(missing) > 0 {
|
||||
p.numLoadCalls++
|
||||
pkgs, err := packages.Load(&packages.Config{Mode: mode}, missing...)
|
||||
|
||||
// Sometimes packages.Load not loaded the module info. Call it again to reload it.
|
||||
if !p.checkModuleLoaded(pkgs) {
|
||||
fmt.Println("reloading module info")
|
||||
pkgs, err = packages.Load(&packages.Config{Mode: mode}, missing...)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
p.loadErrors = append(p.loadErrors, err)
|
||||
}
|
||||
@ -151,7 +171,7 @@ func (p *Packages) NameForPackage(importPath string) string {
|
||||
pkg := p.packages[importPath]
|
||||
|
||||
if pkg == nil {
|
||||
// otherwise do a name only lookup for it but dont put it in the package cache.
|
||||
// otherwise do a name only lookup for it but don't put it in the package cache.
|
||||
p.numNameCalls++
|
||||
pkgs, err := packages.Load(&packages.Config{Mode: packages.NeedName}, importPath)
|
||||
if err != nil {
|
||||
|
||||
2
vendor/github.com/99designs/gqlgen/internal/code/util.go
generated
vendored
2
vendor/github.com/99designs/gqlgen/internal/code/util.go
generated
vendored
@ -54,7 +54,7 @@ func QualifyPackagePath(importPath string) string {
|
||||
return pkg.ImportPath
|
||||
}
|
||||
|
||||
var invalidPackageNameChar = regexp.MustCompile(`[^\w]`)
|
||||
var invalidPackageNameChar = regexp.MustCompile(`\W`)
|
||||
|
||||
func SanitizePackageName(pkg string) string {
|
||||
return invalidPackageNameChar.ReplaceAllLiteralString(filepath.Base(pkg), "_")
|
||||
|
||||
47
vendor/github.com/99designs/gqlgen/internal/rewrite/rewriter.go
generated
vendored
47
vendor/github.com/99designs/gqlgen/internal/rewrite/rewriter.go
generated
vendored
@ -68,7 +68,7 @@ func (r *Rewriter) getFile(filename string) string {
|
||||
return r.files[filename]
|
||||
}
|
||||
|
||||
func (r *Rewriter) GetMethodComment(structname string, methodname string) string {
|
||||
func (r *Rewriter) GetPrevDecl(structname, methodname string) *ast.FuncDecl {
|
||||
for _, f := range r.pkg.Syntax {
|
||||
for _, d := range f.Decls {
|
||||
d, isFunc := d.(*ast.FuncDecl)
|
||||
@ -89,48 +89,29 @@ func (r *Rewriter) GetMethodComment(structname string, methodname string) string
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if ident.Name != structname {
|
||||
continue
|
||||
}
|
||||
return d.Doc.Text()
|
||||
r.copied[d] = true
|
||||
return d
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Rewriter) GetMethodComment(structname, methodname string) string {
|
||||
d := r.GetPrevDecl(structname, methodname)
|
||||
if d != nil {
|
||||
return d.Doc.Text()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
func (r *Rewriter) GetMethodBody(structname string, methodname string) string {
|
||||
for _, f := range r.pkg.Syntax {
|
||||
for _, d := range f.Decls {
|
||||
d, isFunc := d.(*ast.FuncDecl)
|
||||
if !isFunc {
|
||||
continue
|
||||
}
|
||||
if d.Name.Name != methodname {
|
||||
continue
|
||||
}
|
||||
if d.Recv == nil || len(d.Recv.List) == 0 {
|
||||
continue
|
||||
}
|
||||
recv := d.Recv.List[0].Type
|
||||
if star, isStar := recv.(*ast.StarExpr); isStar {
|
||||
recv = star.X
|
||||
}
|
||||
ident, ok := recv.(*ast.Ident)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if ident.Name != structname {
|
||||
continue
|
||||
}
|
||||
|
||||
r.copied[d] = true
|
||||
|
||||
return r.getSource(d.Body.Pos()+1, d.Body.End()-1)
|
||||
}
|
||||
func (r *Rewriter) GetMethodBody(structname, methodname string) string {
|
||||
d := r.GetPrevDecl(structname, methodname)
|
||||
if d != nil {
|
||||
return r.getSource(d.Body.Pos()+1, d.Body.End()-1)
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
51
vendor/github.com/99designs/gqlgen/main.go
generated
vendored
51
vendor/github.com/99designs/gqlgen/main.go
generated
vendored
@ -39,6 +39,28 @@ func fileExists(filename string) bool {
|
||||
return !errors.Is(err, fs.ErrNotExist)
|
||||
}
|
||||
|
||||
// see Go source code:
|
||||
// https://github.com/golang/go/blob/f57ebed35132d02e5cf016f324853217fb545e91/src/cmd/go/internal/modload/init.go#L1283
|
||||
func findModuleRoot(dir string) (roots string) {
|
||||
if dir == "" {
|
||||
panic("dir not set")
|
||||
}
|
||||
dir = filepath.Clean(dir)
|
||||
|
||||
// Look for enclosing go.mod.
|
||||
for {
|
||||
if fi, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil && !fi.IsDir() {
|
||||
return dir
|
||||
}
|
||||
d := filepath.Dir(dir)
|
||||
if d == dir { // the parent of the root is itself, so we can go no further
|
||||
break
|
||||
}
|
||||
dir = d
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func initFile(filename, contents string) error {
|
||||
if err := os.MkdirAll(filepath.Dir(filename), 0o755); err != nil {
|
||||
return fmt.Errorf("unable to create directory for file '%s': %w\n", filename, err)
|
||||
@ -56,17 +78,36 @@ var initCmd = &cli.Command{
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{Name: "verbose, v", Usage: "show logs"},
|
||||
&cli.StringFlag{Name: "config, c", Usage: "the config filename", Value: "gqlgen.yml"},
|
||||
&cli.StringFlag{Name: "server", Usage: "where to write the server stub to", Value: "server.go"},
|
||||
&cli.StringFlag{Name: "schema", Usage: "where to write the schema stub to", Value: "graph/schema.graphqls"},
|
||||
&cli.StringFlag{
|
||||
Name: "server",
|
||||
Usage: "where to write the server stub to",
|
||||
Value: "server.go",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "schema",
|
||||
Usage: "where to write the schema stub to",
|
||||
Value: "graph/schema.graphqls",
|
||||
},
|
||||
},
|
||||
Action: func(ctx *cli.Context) error {
|
||||
configFilename := ctx.String("config")
|
||||
serverFilename := ctx.String("server")
|
||||
schemaFilename := ctx.String("schema")
|
||||
|
||||
pkgName := code.ImportPathForDir(".")
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return fmt.Errorf("unable to determine current directory:%w", err)
|
||||
}
|
||||
pkgName := code.ImportPathForDir(cwd)
|
||||
if pkgName == "" {
|
||||
return fmt.Errorf("unable to determine import path for current directory, you probably need to run 'go mod init' first")
|
||||
return fmt.Errorf(
|
||||
"unable to determine import path for current directory, you probably need to run 'go mod init' first",
|
||||
)
|
||||
}
|
||||
modRoot := findModuleRoot(cwd)
|
||||
if modRoot == "" {
|
||||
return fmt.Errorf("go.mod is missing. Please, do 'go mod init' first\n")
|
||||
}
|
||||
|
||||
// check schema and config don't already exist
|
||||
@ -75,7 +116,7 @@ var initCmd = &cli.Command{
|
||||
return fmt.Errorf("%s already exists", filename)
|
||||
}
|
||||
}
|
||||
_, err := config.LoadConfigFromDefaultLocations()
|
||||
_, err = config.LoadConfigFromDefaultLocations()
|
||||
if err == nil {
|
||||
return fmt.Errorf("gqlgen.yml already exists in a parent directory\n")
|
||||
}
|
||||
|
||||
117
vendor/github.com/99designs/gqlgen/plugin/federation/entity.go
generated
vendored
Normal file
117
vendor/github.com/99designs/gqlgen/plugin/federation/entity.go
generated
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
package federation
|
||||
|
||||
import (
|
||||
"go/types"
|
||||
|
||||
"github.com/99designs/gqlgen/codegen/config"
|
||||
"github.com/99designs/gqlgen/codegen/templates"
|
||||
"github.com/99designs/gqlgen/plugin/federation/fieldset"
|
||||
"github.com/vektah/gqlparser/v2/ast"
|
||||
)
|
||||
|
||||
// Entity represents a federated type
|
||||
// that was declared in the GQL schema.
|
||||
type Entity struct {
|
||||
Name string // The same name as the type declaration
|
||||
Def *ast.Definition
|
||||
Resolvers []*EntityResolver
|
||||
Requires []*Requires
|
||||
Multi bool
|
||||
}
|
||||
|
||||
type EntityResolver struct {
|
||||
ResolverName string // The resolver name, such as FindUserByID
|
||||
KeyFields []*KeyField // The fields declared in @key.
|
||||
InputType types.Type // The Go generated input type for multi entity resolvers
|
||||
InputTypeName string
|
||||
}
|
||||
|
||||
func (e *EntityResolver) LookupInputType() string {
|
||||
return templates.CurrentImports.LookupType(e.InputType)
|
||||
}
|
||||
|
||||
type KeyField struct {
|
||||
Definition *ast.FieldDefinition
|
||||
Field fieldset.Field // len > 1 for nested fields
|
||||
Type *config.TypeReference // The Go representation of that field type
|
||||
}
|
||||
|
||||
// Requires represents an @requires clause
|
||||
type Requires struct {
|
||||
Name string // the name of the field
|
||||
Field fieldset.Field // source Field, len > 1 for nested fields
|
||||
Type *config.TypeReference // The Go representation of that field type
|
||||
}
|
||||
|
||||
func (e *Entity) allFieldsAreExternal(federationVersion int) bool {
|
||||
for _, field := range e.Def.Fields {
|
||||
if !e.isFieldImplicitlyExternal(field, federationVersion) && field.Directives.ForName("external") == nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// In federation v2, key fields are implicitly external.
|
||||
func (e *Entity) isFieldImplicitlyExternal(field *ast.FieldDefinition, federationVersion int) bool {
|
||||
// Key fields are only implicitly external in Federation 2
|
||||
if federationVersion != 2 {
|
||||
return false
|
||||
}
|
||||
// TODO: From the spec, it seems like if an entity is not resolvable then it should not only not have a resolver, but should not appear in the _Entitiy union.
|
||||
// The current implementation is a less drastic departure from the previous behavior, but should probably be reviewed.
|
||||
// See https://www.apollographql.com/docs/federation/subgraph-spec/
|
||||
if e.isResolvable() {
|
||||
return false
|
||||
}
|
||||
// If the field is a key field, it is implicitly external
|
||||
if e.isKeyField(field) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Determine if the entity is resolvable.
|
||||
func (e *Entity) isResolvable() bool {
|
||||
key := e.Def.Directives.ForName("key")
|
||||
if key == nil {
|
||||
// If there is no key directive, the entity is resolvable.
|
||||
return true
|
||||
}
|
||||
resolvable := key.Arguments.ForName("resolvable")
|
||||
if resolvable == nil {
|
||||
// If there is no resolvable argument, the entity is resolvable.
|
||||
return true
|
||||
}
|
||||
// only if resolvable: false has been set on the @key directive do we consider the entity non-resolvable.
|
||||
return resolvable.Value.Raw != "false"
|
||||
}
|
||||
|
||||
// Determine if a field is part of the entities key.
|
||||
func (e *Entity) isKeyField(field *ast.FieldDefinition) bool {
|
||||
for _, keyField := range e.keyFields() {
|
||||
if keyField == field.Name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Get the key fields for this entity.
|
||||
func (e *Entity) keyFields() []string {
|
||||
key := e.Def.Directives.ForName("key")
|
||||
if key == nil {
|
||||
return []string{}
|
||||
}
|
||||
fields := key.Arguments.ForName("fields")
|
||||
if fields == nil {
|
||||
return []string{}
|
||||
}
|
||||
fieldSet := fieldset.New(fields.Value.Raw, nil)
|
||||
keyFields := make([]string, len(fieldSet))
|
||||
for i, field := range fieldSet {
|
||||
keyFields[i] = field[0]
|
||||
}
|
||||
return keyFields
|
||||
}
|
||||
159
vendor/github.com/99designs/gqlgen/plugin/federation/federation.go
generated
vendored
159
vendor/github.com/99designs/gqlgen/plugin/federation/federation.go
generated
vendored
@ -86,28 +86,55 @@ func (f *federation) MutateConfig(cfg *config.Config) error {
|
||||
}
|
||||
|
||||
func (f *federation) InjectSourceEarly() *ast.Source {
|
||||
input := `
|
||||
scalar _Any
|
||||
scalar _FieldSet
|
||||
input := ``
|
||||
|
||||
directive @external on FIELD_DEFINITION
|
||||
directive @requires(fields: _FieldSet!) on FIELD_DEFINITION
|
||||
directive @provides(fields: _FieldSet!) on FIELD_DEFINITION
|
||||
directive @extends on OBJECT | INTERFACE
|
||||
`
|
||||
// add version-specific changes on key directive, as well as adding the new directives for federation 2
|
||||
if f.Version == 1 {
|
||||
input += `
|
||||
directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE
|
||||
directive @requires(fields: _FieldSet!) on FIELD_DEFINITION
|
||||
directive @provides(fields: _FieldSet!) on FIELD_DEFINITION
|
||||
directive @extends on OBJECT | INTERFACE
|
||||
directive @external on FIELD_DEFINITION
|
||||
scalar _Any
|
||||
scalar _FieldSet
|
||||
`
|
||||
} else if f.Version == 2 {
|
||||
input += `
|
||||
directive @key(fields: _FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
|
||||
directive @composeDirective(name: String!) repeatable on SCHEMA
|
||||
directive @extends on OBJECT | INTERFACE
|
||||
directive @external on OBJECT | FIELD_DEFINITION
|
||||
directive @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
|
||||
directive @inaccessible on
|
||||
| ARGUMENT_DEFINITION
|
||||
| ENUM
|
||||
| ENUM_VALUE
|
||||
| FIELD_DEFINITION
|
||||
| INPUT_FIELD_DEFINITION
|
||||
| INPUT_OBJECT
|
||||
| INTERFACE
|
||||
| OBJECT
|
||||
| SCALAR
|
||||
| UNION
|
||||
directive @interfaceObject on OBJECT
|
||||
directive @link(import: [String!], url: String!) repeatable on SCHEMA
|
||||
directive @shareable on OBJECT | FIELD_DEFINITION
|
||||
directive @tag(name: String!) repeatable on FIELD_DEFINITION | INTERFACE | OBJECT | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
|
||||
directive @override(from: String!) on FIELD_DEFINITION
|
||||
directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
|
||||
directive @provides(fields: FieldSet!) on FIELD_DEFINITION
|
||||
directive @requires(fields: FieldSet!) on FIELD_DEFINITION
|
||||
directive @shareable repeatable on FIELD_DEFINITION | OBJECT
|
||||
directive @tag(name: String!) repeatable on
|
||||
| ARGUMENT_DEFINITION
|
||||
| ENUM
|
||||
| ENUM_VALUE
|
||||
| FIELD_DEFINITION
|
||||
| INPUT_FIELD_DEFINITION
|
||||
| INPUT_OBJECT
|
||||
| INTERFACE
|
||||
| OBJECT
|
||||
| SCALAR
|
||||
| UNION
|
||||
scalar _Any
|
||||
scalar FieldSet
|
||||
`
|
||||
}
|
||||
return &ast.Source{
|
||||
@ -117,29 +144,36 @@ func (f *federation) InjectSourceEarly() *ast.Source {
|
||||
}
|
||||
}
|
||||
|
||||
// InjectSources creates a GraphQL Entity type with all
|
||||
// InjectSourceLate creates a GraphQL Entity type with all
|
||||
// the fields that had the @key directive
|
||||
func (f *federation) InjectSourceLate(schema *ast.Schema) *ast.Source {
|
||||
f.setEntities(schema)
|
||||
|
||||
var entities, resolvers, entityResolverInputDefinitions string
|
||||
for i, e := range f.Entities {
|
||||
if i != 0 {
|
||||
entities += " | "
|
||||
for _, e := range f.Entities {
|
||||
|
||||
if e.Def.Kind != ast.Interface {
|
||||
if entities != "" {
|
||||
entities += " | "
|
||||
}
|
||||
entities += e.Name
|
||||
} else if len(schema.GetPossibleTypes(e.Def)) == 0 {
|
||||
fmt.Println(
|
||||
"skipping @key field on interface " + e.Def.Name + " as no types implement it",
|
||||
)
|
||||
}
|
||||
entities += e.Name
|
||||
|
||||
for _, r := range e.Resolvers {
|
||||
if e.Multi {
|
||||
if entityResolverInputDefinitions != "" {
|
||||
entityResolverInputDefinitions += "\n\n"
|
||||
}
|
||||
entityResolverInputDefinitions += "input " + r.InputType + " {\n"
|
||||
entityResolverInputDefinitions += "input " + r.InputTypeName + " {\n"
|
||||
for _, keyField := range r.KeyFields {
|
||||
entityResolverInputDefinitions += fmt.Sprintf("\t%s: %s\n", keyField.Field.ToGo(), keyField.Definition.Type.String())
|
||||
}
|
||||
entityResolverInputDefinitions += "}"
|
||||
resolvers += fmt.Sprintf("\t%s(reps: [%s!]!): [%s]\n", r.ResolverName, r.InputType, e.Name)
|
||||
resolvers += fmt.Sprintf("\t%s(reps: [%s!]!): [%s]\n", r.ResolverName, r.InputTypeName, e.Name)
|
||||
} else {
|
||||
resolverArgs := ""
|
||||
for _, keyField := range r.KeyFields {
|
||||
@ -198,44 +232,6 @@ type Entity {
|
||||
}
|
||||
}
|
||||
|
||||
// Entity represents a federated type
|
||||
// that was declared in the GQL schema.
|
||||
type Entity struct {
|
||||
Name string // The same name as the type declaration
|
||||
Def *ast.Definition
|
||||
Resolvers []*EntityResolver
|
||||
Requires []*Requires
|
||||
Multi bool
|
||||
}
|
||||
|
||||
type EntityResolver struct {
|
||||
ResolverName string // The resolver name, such as FindUserByID
|
||||
KeyFields []*KeyField // The fields declared in @key.
|
||||
InputType string // The Go generated input type for multi entity resolvers
|
||||
}
|
||||
|
||||
type KeyField struct {
|
||||
Definition *ast.FieldDefinition
|
||||
Field fieldset.Field // len > 1 for nested fields
|
||||
Type *config.TypeReference // The Go representation of that field type
|
||||
}
|
||||
|
||||
// Requires represents an @requires clause
|
||||
type Requires struct {
|
||||
Name string // the name of the field
|
||||
Field fieldset.Field // source Field, len > 1 for nested fields
|
||||
Type *config.TypeReference // The Go representation of that field type
|
||||
}
|
||||
|
||||
func (e *Entity) allFieldsAreExternal() bool {
|
||||
for _, field := range e.Def.Fields {
|
||||
if field.Directives.ForName("external") == nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (f *federation) GenerateCode(data *codegen.Data) error {
|
||||
if len(f.Entities) > 0 {
|
||||
if data.Objects.ByName("Entity") != nil {
|
||||
@ -244,6 +240,16 @@ func (f *federation) GenerateCode(data *codegen.Data) error {
|
||||
for _, e := range f.Entities {
|
||||
obj := data.Objects.ByName(e.Def.Name)
|
||||
|
||||
if e.Def.Kind == ast.Interface {
|
||||
if len(data.Interfaces[e.Def.Name].Implementors) == 0 {
|
||||
fmt.Println(
|
||||
"skipping @key field on interface " + e.Def.Name + " as no types implement it",
|
||||
)
|
||||
continue
|
||||
}
|
||||
obj = data.Objects.ByName(data.Interfaces[e.Def.Name].Implementors[0].Name)
|
||||
}
|
||||
|
||||
for _, r := range e.Resolvers {
|
||||
// fill in types for key fields
|
||||
//
|
||||
@ -272,6 +278,23 @@ func (f *federation) GenerateCode(data *codegen.Data) error {
|
||||
}
|
||||
}
|
||||
|
||||
// fill in types for resolver inputs
|
||||
//
|
||||
for _, entity := range f.Entities {
|
||||
if !entity.Multi {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, resolver := range entity.Resolvers {
|
||||
obj := data.Inputs.ByName(resolver.InputTypeName)
|
||||
if obj == nil {
|
||||
return fmt.Errorf("input object %s not found", resolver.InputTypeName)
|
||||
}
|
||||
|
||||
resolver.InputType = obj.Type
|
||||
}
|
||||
}
|
||||
|
||||
return templates.Render(templates.Options{
|
||||
PackageName: data.Config.Federation.Package,
|
||||
Filename: data.Config.Federation.Filename,
|
||||
@ -288,6 +311,12 @@ func (f *federation) setEntities(schema *ast.Schema) {
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if (schemaType.Kind == ast.Interface) && (len(schema.GetPossibleTypes(schemaType)) == 0) {
|
||||
fmt.Printf("@key directive found on unused \"interface %s\". Will be ignored.\n", schemaType.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
e := &Entity{
|
||||
Name: schemaType.Name,
|
||||
Def: schemaType,
|
||||
@ -323,7 +352,7 @@ func (f *federation) setEntities(schema *ast.Schema) {
|
||||
// extend TypeDefinedInOtherService @key(fields: "id") {
|
||||
// id: ID @external
|
||||
// }
|
||||
if !e.allFieldsAreExternal() {
|
||||
if !e.allFieldsAreExternal(f.Version) {
|
||||
for _, dir := range keys {
|
||||
if len(dir.Arguments) > 2 {
|
||||
panic("More than two arguments provided for @key declaration.")
|
||||
@ -365,9 +394,9 @@ func (f *federation) setEntities(schema *ast.Schema) {
|
||||
}
|
||||
|
||||
e.Resolvers = append(e.Resolvers, &EntityResolver{
|
||||
ResolverName: resolverName,
|
||||
KeyFields: keyFields,
|
||||
InputType: resolverFieldsToGo + "Input",
|
||||
ResolverName: resolverName,
|
||||
KeyFields: keyFields,
|
||||
InputTypeName: resolverFieldsToGo + "Input",
|
||||
})
|
||||
}
|
||||
|
||||
@ -406,10 +435,12 @@ func isFederatedEntity(schemaType *ast.Definition) ([]*ast.Directive, bool) {
|
||||
return keys, true
|
||||
}
|
||||
case ast.Interface:
|
||||
// TODO: support @key and @extends for interfaces
|
||||
if dir := schemaType.Directives.ForName("key"); dir != nil {
|
||||
fmt.Printf("@key directive found on \"interface %s\". Will be ignored.\n", schemaType.Name)
|
||||
keys := schemaType.Directives.ForNames("key")
|
||||
if len(keys) > 0 {
|
||||
return keys, true
|
||||
}
|
||||
|
||||
// TODO: support @extends for interfaces
|
||||
if dir := schemaType.Directives.ForName("extends"); dir != nil {
|
||||
panic(
|
||||
fmt.Sprintf(
|
||||
|
||||
4
vendor/github.com/99designs/gqlgen/plugin/federation/federation.gotpl
generated
vendored
4
vendor/github.com/99designs/gqlgen/plugin/federation/federation.gotpl
generated
vendored
@ -133,7 +133,7 @@ func (ec *executionContext) __resolve_entities(ctx context.Context, representati
|
||||
{{ if and .Resolvers .Multi -}}
|
||||
case "{{.Def.Name}}":
|
||||
{{range $i, $_ := .Resolvers -}}
|
||||
_reps := make([]*{{.InputType}}, len(reps))
|
||||
_reps := make([]*{{.LookupInputType}}, len(reps))
|
||||
|
||||
for i, rep := range reps {
|
||||
{{ range $i, $keyField := .KeyFields -}}
|
||||
@ -143,7 +143,7 @@ func (ec *executionContext) __resolve_entities(ctx context.Context, representati
|
||||
}
|
||||
{{end}}
|
||||
|
||||
_reps[i] = &{{.InputType}} {
|
||||
_reps[i] = &{{.LookupInputType}} {
|
||||
{{ range $i, $keyField := .KeyFields -}}
|
||||
{{$keyField.Field.ToGo}}: id{{$i}},
|
||||
{{end}}
|
||||
|
||||
224
vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go
generated
vendored
224
vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go
generated
vendored
@ -4,6 +4,7 @@ import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"go/types"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
@ -17,16 +18,23 @@ import (
|
||||
//go:embed models.gotpl
|
||||
var modelTemplate string
|
||||
|
||||
type BuildMutateHook = func(b *ModelBuild) *ModelBuild
|
||||
type (
|
||||
BuildMutateHook = func(b *ModelBuild) *ModelBuild
|
||||
FieldMutateHook = func(td *ast.Definition, fd *ast.FieldDefinition, f *Field) (*Field, error)
|
||||
)
|
||||
|
||||
type FieldMutateHook = func(td *ast.Definition, fd *ast.FieldDefinition, f *Field) (*Field, error)
|
||||
|
||||
// defaultFieldMutateHook is the default hook for the Plugin which applies the GoTagFieldHook.
|
||||
func defaultFieldMutateHook(td *ast.Definition, fd *ast.FieldDefinition, f *Field) (*Field, error) {
|
||||
// DefaultFieldMutateHook is the default hook for the Plugin which applies the GoFieldHook and GoTagFieldHook.
|
||||
func DefaultFieldMutateHook(td *ast.Definition, fd *ast.FieldDefinition, f *Field) (*Field, error) {
|
||||
var err error
|
||||
f, err = GoFieldHook(td, fd, f)
|
||||
if err != nil {
|
||||
return f, err
|
||||
}
|
||||
return GoTagFieldHook(td, fd, f)
|
||||
}
|
||||
|
||||
func defaultBuildMutateHook(b *ModelBuild) *ModelBuild {
|
||||
// DefaultBuildMutateHook is the default hook for the Plugin which mutate ModelBuild.
|
||||
func DefaultBuildMutateHook(b *ModelBuild) *ModelBuild {
|
||||
return b
|
||||
}
|
||||
|
||||
@ -43,6 +51,7 @@ type Interface struct {
|
||||
Name string
|
||||
Fields []*Field
|
||||
Implements []string
|
||||
OmitCheck bool
|
||||
}
|
||||
|
||||
type Object struct {
|
||||
@ -57,9 +66,10 @@ type Field struct {
|
||||
// Name is the field's name as it appears in the schema
|
||||
Name string
|
||||
// GoName is the field's name as it appears in the generated Go code
|
||||
GoName string
|
||||
Type types.Type
|
||||
Tag string
|
||||
GoName string
|
||||
Type types.Type
|
||||
Tag string
|
||||
Omittable bool
|
||||
}
|
||||
|
||||
type Enum struct {
|
||||
@ -75,8 +85,8 @@ type EnumValue struct {
|
||||
|
||||
func New() plugin.Plugin {
|
||||
return &Plugin{
|
||||
MutateHook: defaultBuildMutateHook,
|
||||
FieldHook: defaultFieldMutateHook,
|
||||
MutateHook: DefaultBuildMutateHook,
|
||||
FieldHook: DefaultFieldMutateHook,
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,7 +102,6 @@ func (m *Plugin) Name() string {
|
||||
}
|
||||
|
||||
func (m *Plugin) MutateConfig(cfg *config.Config) error {
|
||||
|
||||
b := &ModelBuild{
|
||||
PackageName: cfg.Model.Package,
|
||||
}
|
||||
@ -117,6 +126,7 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error {
|
||||
Name: schemaType.Name,
|
||||
Implements: schemaType.Interfaces,
|
||||
Fields: fields,
|
||||
OmitCheck: cfg.OmitInterfaceChecks,
|
||||
}
|
||||
|
||||
b.Interfaces = append(b.Interfaces, it)
|
||||
@ -273,6 +283,10 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error {
|
||||
"getInterfaceByName": getInterfaceByName,
|
||||
"generateGetter": generateGetter,
|
||||
}
|
||||
newModelTemplate := modelTemplate
|
||||
if cfg.Model.ModelTemplate != "" {
|
||||
newModelTemplate = readModelTemplate(cfg.Model.ModelTemplate)
|
||||
}
|
||||
|
||||
err := templates.Render(templates.Options{
|
||||
PackageName: cfg.Model.Package,
|
||||
@ -280,7 +294,7 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error {
|
||||
Data: b,
|
||||
GeneratedHeader: true,
|
||||
Packages: cfg.Packages,
|
||||
Template: modelTemplate,
|
||||
Template: newModelTemplate,
|
||||
Funcs: funcMap,
|
||||
})
|
||||
if err != nil {
|
||||
@ -298,6 +312,8 @@ func (m *Plugin) generateFields(cfg *config.Config, schemaType *ast.Definition)
|
||||
binder := cfg.NewBinder()
|
||||
fields := make([]*Field, 0)
|
||||
|
||||
var omittableType types.Type
|
||||
|
||||
for _, field := range schemaType.Fields {
|
||||
var typ types.Type
|
||||
fieldDef := cfg.Schema.Types[field.Type.Name()]
|
||||
@ -365,7 +381,8 @@ func (m *Plugin) generateFields(cfg *config.Config, schemaType *ast.Definition)
|
||||
GoName: name,
|
||||
Type: typ,
|
||||
Description: field.Description,
|
||||
Tag: `json:"` + field.Name + `"`,
|
||||
Tag: getStructTagFromField(cfg, field),
|
||||
Omittable: cfg.NullableInputOmittable && schemaType.Kind == ast.InputObject && !field.Type.NonNull,
|
||||
}
|
||||
|
||||
if m.FieldHook != nil {
|
||||
@ -376,14 +393,71 @@ func (m *Plugin) generateFields(cfg *config.Config, schemaType *ast.Definition)
|
||||
f = mf
|
||||
}
|
||||
|
||||
if f.Omittable {
|
||||
if schemaType.Kind != ast.InputObject || field.Type.NonNull {
|
||||
return nil, fmt.Errorf("generror: field %v.%v: omittable is only applicable to nullable input fields", schemaType.Name, field.Name)
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
if omittableType == nil {
|
||||
omittableType, err = binder.FindTypeFromName("github.com/99designs/gqlgen/graphql.Omittable")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
f.Type, err = binder.InstantiateType(omittableType, []types.Type{f.Type})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("generror: field %v.%v: %w", schemaType.Name, field.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
fields = append(fields, f)
|
||||
}
|
||||
|
||||
// appending extra fields at the end of the fields list.
|
||||
modelcfg := cfg.Models[schemaType.Name]
|
||||
if len(modelcfg.ExtraFields) > 0 {
|
||||
ff := make([]*Field, 0, len(modelcfg.ExtraFields))
|
||||
for fname, fspec := range modelcfg.ExtraFields {
|
||||
ftype := buildType(fspec.Type)
|
||||
|
||||
tag := `json:"-"`
|
||||
if fspec.OverrideTags != "" {
|
||||
tag = fspec.OverrideTags
|
||||
}
|
||||
|
||||
ff = append(ff,
|
||||
&Field{
|
||||
Name: fname,
|
||||
GoName: fname,
|
||||
Type: ftype,
|
||||
Description: fspec.Description,
|
||||
Tag: tag,
|
||||
})
|
||||
}
|
||||
|
||||
sort.Slice(ff, func(i, j int) bool {
|
||||
return ff[i].Name < ff[j].Name
|
||||
})
|
||||
|
||||
fields = append(fields, ff...)
|
||||
}
|
||||
|
||||
return fields, nil
|
||||
}
|
||||
|
||||
// GoTagFieldHook applies the goTag directive to the generated Field f. When applying the Tag to the field, the field
|
||||
// name is used when no value argument is present.
|
||||
func getStructTagFromField(cfg *config.Config, field *ast.FieldDefinition) string {
|
||||
if !field.Type.NonNull && (cfg.EnableModelJsonOmitemptyTag == nil || *cfg.EnableModelJsonOmitemptyTag) {
|
||||
return `json:"` + field.Name + `,omitempty"`
|
||||
}
|
||||
return `json:"` + field.Name + `"`
|
||||
}
|
||||
|
||||
// GoTagFieldHook prepends the goTag directive to the generated Field f.
|
||||
// When applying the Tag to the field, the field
|
||||
// name is used if no value argument is present.
|
||||
func GoTagFieldHook(td *ast.Definition, fd *ast.FieldDefinition, f *Field) (*Field, error) {
|
||||
args := make([]string, 0)
|
||||
for _, goTag := range fd.Directives.ForNames("goTag") {
|
||||
@ -406,12 +480,120 @@ func GoTagFieldHook(td *ast.Definition, fd *ast.FieldDefinition, f *Field) (*Fie
|
||||
}
|
||||
|
||||
if len(args) > 0 {
|
||||
f.Tag = f.Tag + " " + strings.Join(args, " ")
|
||||
f.Tag = removeDuplicateTags(f.Tag + " " + strings.Join(args, " "))
|
||||
}
|
||||
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// splitTagsBySpace split tags by space, except when space is inside quotes
|
||||
func splitTagsBySpace(tagsString string) []string {
|
||||
var tags []string
|
||||
var currentTag string
|
||||
inQuotes := false
|
||||
|
||||
for _, c := range tagsString {
|
||||
if c == '"' {
|
||||
inQuotes = !inQuotes
|
||||
}
|
||||
if c == ' ' && !inQuotes {
|
||||
tags = append(tags, currentTag)
|
||||
currentTag = ""
|
||||
} else {
|
||||
currentTag += string(c)
|
||||
}
|
||||
}
|
||||
tags = append(tags, currentTag)
|
||||
|
||||
return tags
|
||||
}
|
||||
|
||||
// containsInvalidSpace checks if the tagsString contains invalid space
|
||||
func containsInvalidSpace(valuesString string) bool {
|
||||
// get rid of quotes
|
||||
valuesString = strings.ReplaceAll(valuesString, "\"", "")
|
||||
if strings.Contains(valuesString, ",") {
|
||||
// split by comma,
|
||||
values := strings.Split(valuesString, ",")
|
||||
for _, value := range values {
|
||||
if strings.TrimSpace(value) != value {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
if strings.Contains(valuesString, ";") {
|
||||
// split by semicolon, which is common in gorm
|
||||
values := strings.Split(valuesString, ";")
|
||||
for _, value := range values {
|
||||
if strings.TrimSpace(value) != value {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
// single value
|
||||
if strings.TrimSpace(valuesString) != valuesString {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func removeDuplicateTags(t string) string {
|
||||
processed := make(map[string]bool)
|
||||
tt := splitTagsBySpace(t)
|
||||
returnTags := ""
|
||||
|
||||
// iterate backwards through tags so appended goTag directives are prioritized
|
||||
for i := len(tt) - 1; i >= 0; i-- {
|
||||
ti := tt[i]
|
||||
// check if ti contains ":", and not contains any empty space. if not, tag is in wrong format
|
||||
// correct example: json:"name"
|
||||
if !strings.Contains(ti, ":") {
|
||||
panic(fmt.Errorf("wrong format of tags: %s. goTag directive should be in format: @goTag(key: \"something\", value:\"value\"), ", t))
|
||||
}
|
||||
|
||||
kv := strings.Split(ti, ":")
|
||||
if len(kv) == 0 || processed[kv[0]] {
|
||||
continue
|
||||
}
|
||||
|
||||
processed[kv[0]] = true
|
||||
if len(returnTags) > 0 {
|
||||
returnTags = " " + returnTags
|
||||
}
|
||||
|
||||
isContained := containsInvalidSpace(kv[1])
|
||||
if isContained {
|
||||
panic(fmt.Errorf("tag value should not contain any leading or trailing spaces: %s", kv[1]))
|
||||
}
|
||||
|
||||
returnTags = kv[0] + ":" + kv[1] + returnTags
|
||||
}
|
||||
|
||||
return returnTags
|
||||
}
|
||||
|
||||
// GoFieldHook applies the goField directive to the generated Field f.
|
||||
func GoFieldHook(td *ast.Definition, fd *ast.FieldDefinition, f *Field) (*Field, error) {
|
||||
args := make([]string, 0)
|
||||
_ = args
|
||||
for _, goField := range fd.Directives.ForNames("goField") {
|
||||
if arg := goField.Arguments.ForName("name"); arg != nil {
|
||||
if k, err := arg.Value.Value(nil); err == nil {
|
||||
f.GoName = k.(string)
|
||||
}
|
||||
}
|
||||
|
||||
if arg := goField.Arguments.ForName("omittable"); arg != nil {
|
||||
if k, err := arg.Value.Value(nil); err == nil {
|
||||
f.Omittable = k.(bool)
|
||||
}
|
||||
}
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func isStruct(t types.Type) bool {
|
||||
_, is := t.Underlying().(*types.Struct)
|
||||
return is
|
||||
@ -468,3 +650,11 @@ func findAndHandleCyclicalRelationships(b *ModelBuild) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func readModelTemplate(customModelTemplate string) string {
|
||||
contentBytes, err := os.ReadFile(customModelTemplate)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return string(contentBytes)
|
||||
}
|
||||
|
||||
8
vendor/github.com/99designs/gqlgen/plugin/modelgen/models.gotpl
generated
vendored
8
vendor/github.com/99designs/gqlgen/plugin/modelgen/models.gotpl
generated
vendored
@ -15,10 +15,12 @@
|
||||
{{- range $model := .Interfaces }}
|
||||
{{ with .Description }} {{.|prefixLines "// "}} {{ end }}
|
||||
type {{ goModelName .Name }} interface {
|
||||
{{- range $impl := .Implements }}
|
||||
Is{{ goModelName $impl }}()
|
||||
{{- if not .OmitCheck }}
|
||||
{{- range $impl := .Implements }}
|
||||
Is{{ goModelName $impl }}()
|
||||
{{- end }}
|
||||
Is{{ goModelName .Name }}()
|
||||
{{- end }}
|
||||
Is{{ goModelName .Name }}()
|
||||
{{- range $field := .Fields }}
|
||||
{{- with .Description }}
|
||||
{{.|prefixLines "// "}}
|
||||
|
||||
47
vendor/github.com/99designs/gqlgen/plugin/modelgen/types.go
generated
vendored
Normal file
47
vendor/github.com/99designs/gqlgen/plugin/modelgen/types.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
package modelgen
|
||||
|
||||
import (
|
||||
"go/types"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// buildType constructs a types.Type for the given string (using the syntax
|
||||
// from the extra field config Type field).
|
||||
func buildType(typeString string) types.Type {
|
||||
switch {
|
||||
case typeString[0] == '*':
|
||||
return types.NewPointer(buildType(typeString[1:]))
|
||||
case strings.HasPrefix(typeString, "[]"):
|
||||
return types.NewSlice(buildType(typeString[2:]))
|
||||
default:
|
||||
return buildNamedType(typeString)
|
||||
}
|
||||
}
|
||||
|
||||
// buildNamedType returns the specified named or builtin type.
|
||||
//
|
||||
// Note that we don't look up the full types.Type object from the appropriate
|
||||
// package -- gqlgen doesn't give us the package-map we'd need to do so.
|
||||
// Instead we construct a placeholder type that has all the fields gqlgen
|
||||
// wants. This is roughly what gqlgen itself does, anyway:
|
||||
// https://github.com/99designs/gqlgen/blob/master/plugin/modelgen/models.go#L119
|
||||
func buildNamedType(fullName string) types.Type {
|
||||
dotIndex := strings.LastIndex(fullName, ".")
|
||||
if dotIndex == -1 { // builtinType
|
||||
return types.Universe.Lookup(fullName).Type()
|
||||
}
|
||||
|
||||
// type is pkg.Name
|
||||
pkgPath := fullName[:dotIndex]
|
||||
typeName := fullName[dotIndex+1:]
|
||||
|
||||
pkgName := pkgPath
|
||||
slashIndex := strings.LastIndex(pkgPath, "/")
|
||||
if slashIndex != -1 {
|
||||
pkgName = pkgPath[slashIndex+1:]
|
||||
}
|
||||
|
||||
pkg := types.NewPackage(pkgPath, pkgName)
|
||||
// gqlgen doesn't use some of the fields, so we leave them 0/nil
|
||||
return types.NewNamed(types.NewTypeName(0, pkg, typeName, nil), nil, nil)
|
||||
}
|
||||
5
vendor/github.com/99designs/gqlgen/plugin/plugin.go
generated
vendored
5
vendor/github.com/99designs/gqlgen/plugin/plugin.go
generated
vendored
@ -29,3 +29,8 @@ type EarlySourceInjector interface {
|
||||
type LateSourceInjector interface {
|
||||
InjectSourceLate(schema *ast.Schema) *ast.Source
|
||||
}
|
||||
|
||||
// Implementer is used to generate code inside resolvers
|
||||
type ResolverImplementer interface {
|
||||
Implement(field *codegen.Field) string
|
||||
}
|
||||
|
||||
105
vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go
generated
vendored
105
vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go
generated
vendored
@ -4,18 +4,21 @@ import (
|
||||
_ "embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/99designs/gqlgen/codegen"
|
||||
"github.com/99designs/gqlgen/codegen/config"
|
||||
"github.com/99designs/gqlgen/codegen/templates"
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
"github.com/99designs/gqlgen/internal/rewrite"
|
||||
"github.com/99designs/gqlgen/plugin"
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
//go:embed resolver.gotpl
|
||||
@ -52,7 +55,7 @@ func (m *Plugin) generateSingleFile(data *codegen.Data) error {
|
||||
file := File{}
|
||||
|
||||
if _, err := os.Stat(data.Config.Resolver.Filename); err == nil {
|
||||
// file already exists and we dont support updating resolvers with layout = single so just return
|
||||
// file already exists and we do not support updating resolvers with layout = single so just return
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -65,16 +68,22 @@ func (m *Plugin) generateSingleFile(data *codegen.Data) error {
|
||||
continue
|
||||
}
|
||||
|
||||
resolver := Resolver{o, f, "// foo", `panic("not implemented")`}
|
||||
resolver := Resolver{o, f, nil, "", `panic("not implemented")`}
|
||||
file.Resolvers = append(file.Resolvers, &resolver)
|
||||
}
|
||||
}
|
||||
|
||||
resolverBuild := &ResolverBuild{
|
||||
File: &file,
|
||||
PackageName: data.Config.Resolver.Package,
|
||||
ResolverType: data.Config.Resolver.Type,
|
||||
HasRoot: true,
|
||||
File: &file,
|
||||
PackageName: data.Config.Resolver.Package,
|
||||
ResolverType: data.Config.Resolver.Type,
|
||||
HasRoot: true,
|
||||
OmitTemplateComment: data.Config.Resolver.OmitTemplateComment,
|
||||
}
|
||||
|
||||
newResolverTemplate := resolverTemplate
|
||||
if data.Config.Resolver.ResolverTemplate != "" {
|
||||
newResolverTemplate = readResolverTemplate(data.Config.Resolver.ResolverTemplate)
|
||||
}
|
||||
|
||||
return templates.Render(templates.Options{
|
||||
@ -83,7 +92,7 @@ func (m *Plugin) generateSingleFile(data *codegen.Data) error {
|
||||
Filename: data.Config.Resolver.Filename,
|
||||
Data: resolverBuild,
|
||||
Packages: data.Config.Packages,
|
||||
Template: resolverTemplate,
|
||||
Template: newResolverTemplate,
|
||||
})
|
||||
}
|
||||
|
||||
@ -117,16 +126,30 @@ func (m *Plugin) generatePerSchema(data *codegen.Data) error {
|
||||
}
|
||||
|
||||
structName := templates.LcFirst(o.Name) + templates.UcFirst(data.Config.Resolver.Type)
|
||||
implementation := strings.TrimSpace(rewriter.GetMethodBody(structName, f.GoFieldName))
|
||||
comment := strings.TrimSpace(strings.TrimLeft(rewriter.GetMethodComment(structName, f.GoFieldName), `\`))
|
||||
|
||||
implementation := strings.TrimSpace(rewriter.GetMethodBody(structName, f.GoFieldName))
|
||||
if implementation == "" {
|
||||
implementation = fmt.Sprintf("panic(fmt.Errorf(\"not implemented: %v - %v\"))", f.GoFieldName, f.Name)
|
||||
}
|
||||
if comment == "" {
|
||||
comment = fmt.Sprintf("%v is the resolver for the %v field.", f.GoFieldName, f.Name)
|
||||
// Check for Implementer Plugin
|
||||
var resolver_implementer plugin.ResolverImplementer
|
||||
var exists bool
|
||||
for _, p := range data.Plugins {
|
||||
if p_cast, ok := p.(plugin.ResolverImplementer); ok {
|
||||
resolver_implementer = p_cast
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if exists {
|
||||
implementation = resolver_implementer.Implement(f)
|
||||
} else {
|
||||
implementation = fmt.Sprintf("panic(fmt.Errorf(\"not implemented: %v - %v\"))", f.GoFieldName, f.Name)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
resolver := Resolver{o, f, comment, implementation}
|
||||
resolver := Resolver{o, f, rewriter.GetPrevDecl(structName, f.GoFieldName), comment, implementation}
|
||||
fn := gqlToResolverName(data.Config.Resolver.Dir(), f.Position.Src.Name, data.Config.Resolver.FilenameTemplate)
|
||||
if files[fn] == nil {
|
||||
files[fn] = &File{}
|
||||
@ -140,23 +163,39 @@ func (m *Plugin) generatePerSchema(data *codegen.Data) error {
|
||||
file.imports = rewriter.ExistingImports(filename)
|
||||
file.RemainingSource = rewriter.RemainingSource(filename)
|
||||
}
|
||||
newResolverTemplate := resolverTemplate
|
||||
if data.Config.Resolver.ResolverTemplate != "" {
|
||||
newResolverTemplate = readResolverTemplate(data.Config.Resolver.ResolverTemplate)
|
||||
}
|
||||
|
||||
for filename, file := range files {
|
||||
resolverBuild := &ResolverBuild{
|
||||
File: file,
|
||||
PackageName: data.Config.Resolver.Package,
|
||||
ResolverType: data.Config.Resolver.Type,
|
||||
File: file,
|
||||
PackageName: data.Config.Resolver.Package,
|
||||
ResolverType: data.Config.Resolver.Type,
|
||||
OmitTemplateComment: data.Config.Resolver.OmitTemplateComment,
|
||||
}
|
||||
|
||||
var fileNotice strings.Builder
|
||||
if !data.Config.OmitGQLGenFileNotice {
|
||||
fileNotice.WriteString(`
|
||||
// This file will be automatically regenerated based on the schema, any resolver implementations
|
||||
// will be copied through when generating and any unknown code will be moved to the end.
|
||||
// Code generated by github.com/99designs/gqlgen`,
|
||||
)
|
||||
if !data.Config.OmitGQLGenVersionInFileNotice {
|
||||
fileNotice.WriteString(` version `)
|
||||
fileNotice.WriteString(graphql.Version)
|
||||
}
|
||||
}
|
||||
|
||||
err := templates.Render(templates.Options{
|
||||
PackageName: data.Config.Resolver.Package,
|
||||
FileNotice: `
|
||||
// This file will be automatically regenerated based on the schema, any resolver implementations
|
||||
// will be copied through when generating and any unknown code will be moved to the end.`,
|
||||
Filename: filename,
|
||||
Data: resolverBuild,
|
||||
Packages: data.Config.Packages,
|
||||
Template: resolverTemplate,
|
||||
FileNotice: fileNotice.String(),
|
||||
Filename: filename,
|
||||
Data: resolverBuild,
|
||||
Packages: data.Config.Packages,
|
||||
Template: newResolverTemplate,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
@ -184,9 +223,10 @@ func (m *Plugin) generatePerSchema(data *codegen.Data) error {
|
||||
|
||||
type ResolverBuild struct {
|
||||
*File
|
||||
HasRoot bool
|
||||
PackageName string
|
||||
ResolverType string
|
||||
HasRoot bool
|
||||
PackageName string
|
||||
ResolverType string
|
||||
OmitTemplateComment bool
|
||||
}
|
||||
|
||||
type File struct {
|
||||
@ -212,6 +252,7 @@ func (f *File) Imports() string {
|
||||
type Resolver struct {
|
||||
Object *codegen.Object
|
||||
Field *codegen.Field
|
||||
PrevDecl *ast.FuncDecl
|
||||
Comment string
|
||||
Implementation string
|
||||
}
|
||||
@ -225,3 +266,11 @@ func gqlToResolverName(base string, gqlname, filenameTmpl string) string {
|
||||
filename := strings.ReplaceAll(filenameTmpl, "{name}", strings.TrimSuffix(gqlname, ext))
|
||||
return filepath.Join(base, filename)
|
||||
}
|
||||
|
||||
func readResolverTemplate(customResolverTemplate string) string {
|
||||
contentBytes, err := os.ReadFile(customResolverTemplate)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return string(contentBytes)
|
||||
}
|
||||
|
||||
12
vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.gotpl
generated
vendored
12
vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.gotpl
generated
vendored
@ -19,15 +19,21 @@
|
||||
{{ end }}
|
||||
|
||||
{{ range $resolver := .Resolvers -}}
|
||||
// {{ $resolver.Comment }}
|
||||
func (r *{{lcFirst $resolver.Object.Name}}{{ucFirst $.ResolverType}}) {{$resolver.Field.GoFieldName}}{{ $resolver.Field.ShortResolverDeclaration }} {
|
||||
{{ if $resolver.Comment -}}
|
||||
// {{ $resolver.Comment }}
|
||||
{{- else if not $.OmitTemplateComment -}}
|
||||
// {{ $resolver.Field.GoFieldName }} is the resolver for the {{ $resolver.Field.Name }} field.
|
||||
{{- end }}
|
||||
func (r *{{lcFirst $resolver.Object.Name}}{{ucFirst $.ResolverType}}) {{$resolver.Field.GoFieldName}}{{ with $resolver.PrevDecl }}{{ $resolver.Field.ShortResolverSignature .Type }}{{ else }}{{ $resolver.Field.ShortResolverDeclaration }}{{ end }}{
|
||||
{{ $resolver.Implementation }}
|
||||
}
|
||||
|
||||
{{ end }}
|
||||
|
||||
{{ range $object := .Objects -}}
|
||||
// {{ucFirst $object.Name}} returns {{ $object.ResolverInterface | ref }} implementation.
|
||||
{{ if not $.OmitTemplateComment -}}
|
||||
// {{ucFirst $object.Name}} returns {{ $object.ResolverInterface | ref }} implementation.
|
||||
{{- end }}
|
||||
func (r *{{$.ResolverType}}) {{ucFirst $object.Name}}() {{ $object.ResolverInterface | ref }} { return &{{lcFirst $object.Name}}{{ucFirst $.ResolverType}}{r} }
|
||||
{{ end }}
|
||||
|
||||
|
||||
25
vendor/github.com/Masterminds/semver/v3/.golangci.yml
generated
vendored
25
vendor/github.com/Masterminds/semver/v3/.golangci.yml
generated
vendored
@ -4,23 +4,24 @@ run:
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- deadcode
|
||||
- dupl
|
||||
- errcheck
|
||||
- gofmt
|
||||
- goimports
|
||||
- golint
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- misspell
|
||||
- govet
|
||||
- staticcheck
|
||||
- errcheck
|
||||
- unparam
|
||||
- ineffassign
|
||||
- nakedret
|
||||
- structcheck
|
||||
- gocyclo
|
||||
- dupl
|
||||
- goimports
|
||||
- revive
|
||||
- gosec
|
||||
- gosimple
|
||||
- typecheck
|
||||
- unused
|
||||
- varcheck
|
||||
|
||||
linters-settings:
|
||||
gofmt:
|
||||
simplify: true
|
||||
dupl:
|
||||
threshold: 400
|
||||
threshold: 600
|
||||
|
||||
20
vendor/github.com/Masterminds/semver/v3/CHANGELOG.md
generated
vendored
20
vendor/github.com/Masterminds/semver/v3/CHANGELOG.md
generated
vendored
@ -1,5 +1,25 @@
|
||||
# Changelog
|
||||
|
||||
## 3.2.0 (2022-11-28)
|
||||
|
||||
### Added
|
||||
|
||||
- #190: Added text marshaling and unmarshaling
|
||||
- #167: Added JSON marshalling for constraints (thanks @SimonTheLeg)
|
||||
- #173: Implement encoding.TextMarshaler and encoding.TextUnmarshaler on Version (thanks @MarkRosemaker)
|
||||
- #179: Added New() version constructor (thanks @kazhuravlev)
|
||||
|
||||
### Changed
|
||||
|
||||
- #182/#183: Updated CI testing setup
|
||||
|
||||
### Fixed
|
||||
|
||||
- #186: Fixing issue where validation of constraint section gave false positives
|
||||
- #176: Fix constraints check with *-0 (thanks @mtt0)
|
||||
- #181: Fixed Caret operator (^) gives unexpected results when the minor version in constraint is 0 (thanks @arshchimni)
|
||||
- #161: Fixed godoc (thanks @afirth)
|
||||
|
||||
## 3.1.1 (2020-11-23)
|
||||
|
||||
### Fixed
|
||||
|
||||
17
vendor/github.com/Masterminds/semver/v3/Makefile
generated
vendored
17
vendor/github.com/Masterminds/semver/v3/Makefile
generated
vendored
@ -1,7 +1,5 @@
|
||||
GOPATH=$(shell go env GOPATH)
|
||||
GOLANGCI_LINT=$(GOPATH)/bin/golangci-lint
|
||||
GOFUZZBUILD = $(GOPATH)/bin/go-fuzz-build
|
||||
GOFUZZ = $(GOPATH)/bin/go-fuzz
|
||||
|
||||
.PHONY: lint
|
||||
lint: $(GOLANGCI_LINT)
|
||||
@ -19,19 +17,14 @@ test-cover:
|
||||
GO111MODULE=on go test -cover .
|
||||
|
||||
.PHONY: fuzz
|
||||
fuzz: $(GOFUZZBUILD) $(GOFUZZ)
|
||||
@echo "==> Fuzz testing"
|
||||
$(GOFUZZBUILD)
|
||||
$(GOFUZZ) -workdir=_fuzz
|
||||
fuzz:
|
||||
@echo "==> Running Fuzz Tests"
|
||||
go test -fuzz=FuzzNewVersion -fuzztime=15s .
|
||||
go test -fuzz=FuzzStrictNewVersion -fuzztime=15s .
|
||||
go test -fuzz=FuzzNewConstraint -fuzztime=15s .
|
||||
|
||||
$(GOLANGCI_LINT):
|
||||
# Install golangci-lint. The configuration for it is in the .golangci.yml
|
||||
# file in the root of the repository
|
||||
echo ${GOPATH}
|
||||
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.17.1
|
||||
|
||||
$(GOFUZZBUILD):
|
||||
cd / && go get -u github.com/dvyukov/go-fuzz/go-fuzz-build
|
||||
|
||||
$(GOFUZZ):
|
||||
cd / && go get -u github.com/dvyukov/go-fuzz/go-fuzz github.com/dvyukov/go-fuzz/go-fuzz-dep
|
||||
22
vendor/github.com/Masterminds/semver/v3/README.md
generated
vendored
22
vendor/github.com/Masterminds/semver/v3/README.md
generated
vendored
@ -18,18 +18,20 @@ If you are looking for a command line tool for version comparisons please see
|
||||
|
||||
## Package Versions
|
||||
|
||||
Note, import `github.com/github.com/Masterminds/semver/v3` to use the latest version.
|
||||
|
||||
There are three major versions fo the `semver` package.
|
||||
|
||||
* 3.x.x is the new stable and active version. This version is focused on constraint
|
||||
* 3.x.x is the stable and active version. This version is focused on constraint
|
||||
compatibility for range handling in other tools from other languages. It has
|
||||
a similar API to the v1 releases. The development of this version is on the master
|
||||
branch. The documentation for this version is below.
|
||||
* 2.x was developed primarily for [dep](https://github.com/golang/dep). There are
|
||||
no tagged releases and the development was performed by [@sdboyer](https://github.com/sdboyer).
|
||||
There are API breaking changes from v1. This version lives on the [2.x branch](https://github.com/Masterminds/semver/tree/2.x).
|
||||
* 1.x.x is the most widely used version with numerous tagged releases. This is the
|
||||
previous stable and is still maintained for bug fixes. The development, to fix
|
||||
bugs, occurs on the release-1 branch. You can read the documentation [here](https://github.com/Masterminds/semver/blob/release-1/README.md).
|
||||
* 1.x.x is the original release. It is no longer maintained. You should use the
|
||||
v3 release instead. You can read the documentation for the 1.x.x release
|
||||
[here](https://github.com/Masterminds/semver/blob/release-1/README.md).
|
||||
|
||||
## Parsing Semantic Versions
|
||||
|
||||
@ -242,3 +244,15 @@ for _, m := range msgs {
|
||||
|
||||
If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues)
|
||||
or [create a pull request](https://github.com/Masterminds/semver/pulls).
|
||||
|
||||
## Security
|
||||
|
||||
Security is an important consideration for this project. The project currently
|
||||
uses the following tools to help discover security issues:
|
||||
|
||||
* [CodeQL](https://github.com/Masterminds/semver)
|
||||
* [gosec](https://github.com/securego/gosec)
|
||||
* Daily Fuzz testing
|
||||
|
||||
If you believe you have found a security vulnerability you can privately disclose
|
||||
it through the [GitHub security page](https://github.com/Masterminds/semver/security).
|
||||
|
||||
19
vendor/github.com/Masterminds/semver/v3/SECURITY.md
generated
vendored
Normal file
19
vendor/github.com/Masterminds/semver/v3/SECURITY.md
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
The following versions of semver are currently supported:
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 3.x | :white_check_mark: |
|
||||
| 2.x | :x: |
|
||||
| 1.x | :x: |
|
||||
|
||||
Fixes are only released for the latest minor version in the form of a patch release.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
You can privately disclose a vulnerability through GitHubs
|
||||
[private vulnerability reporting](https://github.com/Masterminds/semver/security/advisories)
|
||||
mechanism.
|
||||
32
vendor/github.com/Masterminds/semver/v3/constraints.go
generated
vendored
32
vendor/github.com/Masterminds/semver/v3/constraints.go
generated
vendored
@ -134,6 +134,23 @@ func (cs Constraints) String() string {
|
||||
return strings.Join(buf, " || ")
|
||||
}
|
||||
|
||||
// UnmarshalText implements the encoding.TextUnmarshaler interface.
|
||||
func (cs *Constraints) UnmarshalText(text []byte) error {
|
||||
temp, err := NewConstraint(string(text))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*cs = *temp
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalText implements the encoding.TextMarshaler interface.
|
||||
func (cs Constraints) MarshalText() ([]byte, error) {
|
||||
return []byte(cs.String()), nil
|
||||
}
|
||||
|
||||
var constraintOps map[string]cfunc
|
||||
var constraintRegex *regexp.Regexp
|
||||
var constraintRangeRegex *regexp.Regexp
|
||||
@ -180,8 +197,13 @@ func init() {
|
||||
ops,
|
||||
cvRegex))
|
||||
|
||||
// The first time a constraint shows up will look slightly different from
|
||||
// future times it shows up due to a leading space or comma in a given
|
||||
// string.
|
||||
validConstraintRegex = regexp.MustCompile(fmt.Sprintf(
|
||||
`^(\s*(%s)\s*(%s)\s*\,?)+$`,
|
||||
`^(\s*(%s)\s*(%s)\s*)((?:\s+|,\s*)(%s)\s*(%s)\s*)*$`,
|
||||
ops,
|
||||
cvRegex,
|
||||
ops,
|
||||
cvRegex))
|
||||
}
|
||||
@ -233,7 +255,7 @@ func parseConstraint(c string) (*constraint, error) {
|
||||
patchDirty := false
|
||||
dirty := false
|
||||
if isX(m[3]) || m[3] == "" {
|
||||
ver = "0.0.0"
|
||||
ver = fmt.Sprintf("0.0.0%s", m[6])
|
||||
dirty = true
|
||||
} else if isX(strings.TrimPrefix(m[4], ".")) || m[4] == "" {
|
||||
minorDirty = true
|
||||
@ -534,6 +556,10 @@ func constraintCaret(v *Version, c *constraint) (bool, error) {
|
||||
}
|
||||
return false, fmt.Errorf("%s does not have same minor version as %s. Expected minor versions to match when constraint major version is 0", v, c.orig)
|
||||
}
|
||||
// ^ when the minor is 0 and minor > 0 is =0.0.z
|
||||
if c.con.Minor() == 0 && v.Minor() > 0 {
|
||||
return false, fmt.Errorf("%s does not have same minor version as %s", v, c.orig)
|
||||
}
|
||||
|
||||
// At this point the major is 0 and the minor is 0 and not dirty. The patch
|
||||
// is not dirty so we need to check if they are equal. If they are not equal
|
||||
@ -560,7 +586,7 @@ func rewriteRange(i string) string {
|
||||
}
|
||||
o := i
|
||||
for _, v := range m {
|
||||
t := fmt.Sprintf(">= %s, <= %s", v[1], v[11])
|
||||
t := fmt.Sprintf(">= %s, <= %s ", v[1], v[11])
|
||||
o = strings.Replace(o, v[0], t, 1)
|
||||
}
|
||||
|
||||
|
||||
172
vendor/github.com/Masterminds/semver/v3/doc.go
generated
vendored
172
vendor/github.com/Masterminds/semver/v3/doc.go
generated
vendored
@ -3,12 +3,12 @@ Package semver provides the ability to work with Semantic Versions (http://semve
|
||||
|
||||
Specifically it provides the ability to:
|
||||
|
||||
* Parse semantic versions
|
||||
* Sort semantic versions
|
||||
* Check if a semantic version fits within a set of constraints
|
||||
* Optionally work with a `v` prefix
|
||||
- Parse semantic versions
|
||||
- Sort semantic versions
|
||||
- Check if a semantic version fits within a set of constraints
|
||||
- Optionally work with a `v` prefix
|
||||
|
||||
Parsing Semantic Versions
|
||||
# Parsing Semantic Versions
|
||||
|
||||
There are two functions that can parse semantic versions. The `StrictNewVersion`
|
||||
function only parses valid version 2 semantic versions as outlined in the
|
||||
@ -21,48 +21,48 @@ that can be sorted, compared, and used in constraints.
|
||||
When parsing a version an optional error can be returned if there is an issue
|
||||
parsing the version. For example,
|
||||
|
||||
v, err := semver.NewVersion("1.2.3-beta.1+b345")
|
||||
v, err := semver.NewVersion("1.2.3-beta.1+b345")
|
||||
|
||||
The version object has methods to get the parts of the version, compare it to
|
||||
other versions, convert the version back into a string, and get the original
|
||||
string. For more details please see the documentation
|
||||
at https://godoc.org/github.com/Masterminds/semver.
|
||||
|
||||
Sorting Semantic Versions
|
||||
# Sorting Semantic Versions
|
||||
|
||||
A set of versions can be sorted using the `sort` package from the standard library.
|
||||
For example,
|
||||
|
||||
raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
|
||||
vs := make([]*semver.Version, len(raw))
|
||||
for i, r := range raw {
|
||||
v, err := semver.NewVersion(r)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version: %s", err)
|
||||
raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
|
||||
vs := make([]*semver.Version, len(raw))
|
||||
for i, r := range raw {
|
||||
v, err := semver.NewVersion(r)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version: %s", err)
|
||||
}
|
||||
|
||||
vs[i] = v
|
||||
}
|
||||
|
||||
vs[i] = v
|
||||
}
|
||||
sort.Sort(semver.Collection(vs))
|
||||
|
||||
sort.Sort(semver.Collection(vs))
|
||||
|
||||
Checking Version Constraints and Comparing Versions
|
||||
# Checking Version Constraints and Comparing Versions
|
||||
|
||||
There are two methods for comparing versions. One uses comparison methods on
|
||||
`Version` instances and the other is using Constraints. There are some important
|
||||
differences to notes between these two methods of comparison.
|
||||
|
||||
1. When two versions are compared using functions such as `Compare`, `LessThan`,
|
||||
and others it will follow the specification and always include prereleases
|
||||
within the comparison. It will provide an answer valid with the comparison
|
||||
spec section at https://semver.org/#spec-item-11
|
||||
2. When constraint checking is used for checks or validation it will follow a
|
||||
different set of rules that are common for ranges with tools like npm/js
|
||||
and Rust/Cargo. This includes considering prereleases to be invalid if the
|
||||
ranges does not include on. If you want to have it include pre-releases a
|
||||
simple solution is to include `-0` in your range.
|
||||
3. Constraint ranges can have some complex rules including the shorthard use of
|
||||
~ and ^. For more details on those see the options below.
|
||||
1. When two versions are compared using functions such as `Compare`, `LessThan`,
|
||||
and others it will follow the specification and always include prereleases
|
||||
within the comparison. It will provide an answer valid with the comparison
|
||||
spec section at https://semver.org/#spec-item-11
|
||||
2. When constraint checking is used for checks or validation it will follow a
|
||||
different set of rules that are common for ranges with tools like npm/js
|
||||
and Rust/Cargo. This includes considering prereleases to be invalid if the
|
||||
ranges does not include on. If you want to have it include pre-releases a
|
||||
simple solution is to include `-0` in your range.
|
||||
3. Constraint ranges can have some complex rules including the shorthard use of
|
||||
~ and ^. For more details on those see the options below.
|
||||
|
||||
There are differences between the two methods or checking versions because the
|
||||
comparison methods on `Version` follow the specification while comparison ranges
|
||||
@ -76,19 +76,19 @@ patters with their versions.
|
||||
Checking a version against version constraints is one of the most featureful
|
||||
parts of the package.
|
||||
|
||||
c, err := semver.NewConstraint(">= 1.2.3")
|
||||
if err != nil {
|
||||
// Handle constraint not being parsable.
|
||||
}
|
||||
c, err := semver.NewConstraint(">= 1.2.3")
|
||||
if err != nil {
|
||||
// Handle constraint not being parsable.
|
||||
}
|
||||
|
||||
v, err := semver.NewVersion("1.3")
|
||||
if err != nil {
|
||||
// Handle version not being parsable.
|
||||
}
|
||||
// Check if the version meets the constraints. The a variable will be true.
|
||||
a := c.Check(v)
|
||||
v, err := semver.NewVersion("1.3")
|
||||
if err != nil {
|
||||
// Handle version not being parsable.
|
||||
}
|
||||
// Check if the version meets the constraints. The a variable will be true.
|
||||
a := c.Check(v)
|
||||
|
||||
Basic Comparisons
|
||||
# Basic Comparisons
|
||||
|
||||
There are two elements to the comparisons. First, a comparison string is a list
|
||||
of comma or space separated AND comparisons. These are then separated by || (OR)
|
||||
@ -99,31 +99,31 @@ greater than or equal to 4.2.3. This can also be written as
|
||||
|
||||
The basic comparisons are:
|
||||
|
||||
* `=`: equal (aliased to no operator)
|
||||
* `!=`: not equal
|
||||
* `>`: greater than
|
||||
* `<`: less than
|
||||
* `>=`: greater than or equal to
|
||||
* `<=`: less than or equal to
|
||||
- `=`: equal (aliased to no operator)
|
||||
- `!=`: not equal
|
||||
- `>`: greater than
|
||||
- `<`: less than
|
||||
- `>=`: greater than or equal to
|
||||
- `<=`: less than or equal to
|
||||
|
||||
Hyphen Range Comparisons
|
||||
# Hyphen Range Comparisons
|
||||
|
||||
There are multiple methods to handle ranges and the first is hyphens ranges.
|
||||
These look like:
|
||||
|
||||
* `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5`
|
||||
* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5`
|
||||
- `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5`
|
||||
- `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5`
|
||||
|
||||
Wildcards In Comparisons
|
||||
# Wildcards In Comparisons
|
||||
|
||||
The `x`, `X`, and `*` characters can be used as a wildcard character. This works
|
||||
for all comparison operators. When used on the `=` operator it falls
|
||||
back to the tilde operation. For example,
|
||||
|
||||
* `1.2.x` is equivalent to `>= 1.2.0 < 1.3.0`
|
||||
* `>= 1.2.x` is equivalent to `>= 1.2.0`
|
||||
* `<= 2.x` is equivalent to `<= 3`
|
||||
* `*` is equivalent to `>= 0.0.0`
|
||||
- `1.2.x` is equivalent to `>= 1.2.0 < 1.3.0`
|
||||
- `>= 1.2.x` is equivalent to `>= 1.2.0`
|
||||
- `<= 2.x` is equivalent to `<= 3`
|
||||
- `*` is equivalent to `>= 0.0.0`
|
||||
|
||||
Tilde Range Comparisons (Patch)
|
||||
|
||||
@ -131,11 +131,11 @@ The tilde (`~`) comparison operator is for patch level ranges when a minor
|
||||
version is specified and major level changes when the minor number is missing.
|
||||
For example,
|
||||
|
||||
* `~1.2.3` is equivalent to `>= 1.2.3 < 1.3.0`
|
||||
* `~1` is equivalent to `>= 1, < 2`
|
||||
* `~2.3` is equivalent to `>= 2.3 < 2.4`
|
||||
* `~1.2.x` is equivalent to `>= 1.2.0 < 1.3.0`
|
||||
* `~1.x` is equivalent to `>= 1 < 2`
|
||||
- `~1.2.3` is equivalent to `>= 1.2.3 < 1.3.0`
|
||||
- `~1` is equivalent to `>= 1, < 2`
|
||||
- `~2.3` is equivalent to `>= 2.3 < 2.4`
|
||||
- `~1.2.x` is equivalent to `>= 1.2.0 < 1.3.0`
|
||||
- `~1.x` is equivalent to `>= 1 < 2`
|
||||
|
||||
Caret Range Comparisons (Major)
|
||||
|
||||
@ -144,41 +144,41 @@ The caret (`^`) comparison operator is for major level changes once a stable
|
||||
as the API stability level. This is useful when comparisons of API versions as a
|
||||
major change is API breaking. For example,
|
||||
|
||||
* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
|
||||
* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
|
||||
* `^2.3` is equivalent to `>= 2.3, < 3`
|
||||
* `^2.x` is equivalent to `>= 2.0.0, < 3`
|
||||
* `^0.2.3` is equivalent to `>=0.2.3 <0.3.0`
|
||||
* `^0.2` is equivalent to `>=0.2.0 <0.3.0`
|
||||
* `^0.0.3` is equivalent to `>=0.0.3 <0.0.4`
|
||||
* `^0.0` is equivalent to `>=0.0.0 <0.1.0`
|
||||
* `^0` is equivalent to `>=0.0.0 <1.0.0`
|
||||
- `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
|
||||
- `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
|
||||
- `^2.3` is equivalent to `>= 2.3, < 3`
|
||||
- `^2.x` is equivalent to `>= 2.0.0, < 3`
|
||||
- `^0.2.3` is equivalent to `>=0.2.3 <0.3.0`
|
||||
- `^0.2` is equivalent to `>=0.2.0 <0.3.0`
|
||||
- `^0.0.3` is equivalent to `>=0.0.3 <0.0.4`
|
||||
- `^0.0` is equivalent to `>=0.0.0 <0.1.0`
|
||||
- `^0` is equivalent to `>=0.0.0 <1.0.0`
|
||||
|
||||
Validation
|
||||
# Validation
|
||||
|
||||
In addition to testing a version against a constraint, a version can be validated
|
||||
against a constraint. When validation fails a slice of errors containing why a
|
||||
version didn't meet the constraint is returned. For example,
|
||||
|
||||
c, err := semver.NewConstraint("<= 1.2.3, >= 1.4")
|
||||
if err != nil {
|
||||
// Handle constraint not being parseable.
|
||||
}
|
||||
c, err := semver.NewConstraint("<= 1.2.3, >= 1.4")
|
||||
if err != nil {
|
||||
// Handle constraint not being parseable.
|
||||
}
|
||||
|
||||
v, _ := semver.NewVersion("1.3")
|
||||
if err != nil {
|
||||
// Handle version not being parseable.
|
||||
}
|
||||
v, _ := semver.NewVersion("1.3")
|
||||
if err != nil {
|
||||
// Handle version not being parseable.
|
||||
}
|
||||
|
||||
// Validate a version against a constraint.
|
||||
a, msgs := c.Validate(v)
|
||||
// a is false
|
||||
for _, m := range msgs {
|
||||
fmt.Println(m)
|
||||
// Validate a version against a constraint.
|
||||
a, msgs := c.Validate(v)
|
||||
// a is false
|
||||
for _, m := range msgs {
|
||||
fmt.Println(m)
|
||||
|
||||
// Loops over the errors which would read
|
||||
// "1.3 is greater than 1.2.3"
|
||||
// "1.3 is less than 1.4"
|
||||
}
|
||||
// Loops over the errors which would read
|
||||
// "1.3 is greater than 1.2.3"
|
||||
// "1.3 is less than 1.4"
|
||||
}
|
||||
*/
|
||||
package semver
|
||||
|
||||
22
vendor/github.com/Masterminds/semver/v3/fuzz.go
generated
vendored
22
vendor/github.com/Masterminds/semver/v3/fuzz.go
generated
vendored
@ -1,22 +0,0 @@
|
||||
// +build gofuzz
|
||||
|
||||
package semver
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
d := string(data)
|
||||
|
||||
// Test NewVersion
|
||||
_, _ = NewVersion(d)
|
||||
|
||||
// Test StrictNewVersion
|
||||
_, _ = StrictNewVersion(d)
|
||||
|
||||
// Test NewConstraint
|
||||
_, _ = NewConstraint(d)
|
||||
|
||||
// The return value should be 0 normally, 1 if the priority in future tests
|
||||
// should be increased, and -1 if future tests should skip passing in that
|
||||
// data. We do not have a reason to change priority so 0 is always returned.
|
||||
// There are example tests that do this.
|
||||
return 0
|
||||
}
|
||||
47
vendor/github.com/Masterminds/semver/v3/version.go
generated
vendored
47
vendor/github.com/Masterminds/semver/v3/version.go
generated
vendored
@ -55,14 +55,16 @@ func init() {
|
||||
versionRegex = regexp.MustCompile("^" + semVerRegex + "$")
|
||||
}
|
||||
|
||||
const num string = "0123456789"
|
||||
const allowed string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-" + num
|
||||
const (
|
||||
num string = "0123456789"
|
||||
allowed string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-" + num
|
||||
)
|
||||
|
||||
// StrictNewVersion parses a given version and returns an instance of Version or
|
||||
// an error if unable to parse the version. Only parses valid semantic versions.
|
||||
// Performs checking that can find errors within the version.
|
||||
// If you want to coerce a version, such as 1 or 1.2, and perse that as the 1.x
|
||||
// releases of semver provided use the NewSemver() function.
|
||||
// If you want to coerce a version such as 1 or 1.2 and parse it as the 1.x
|
||||
// releases of semver did, use the NewVersion() function.
|
||||
func StrictNewVersion(v string) (*Version, error) {
|
||||
// Parsing here does not use RegEx in order to increase performance and reduce
|
||||
// allocations.
|
||||
@ -207,6 +209,23 @@ func NewVersion(v string) (*Version, error) {
|
||||
return sv, nil
|
||||
}
|
||||
|
||||
// New creates a new instance of Version with each of the parts passed in as
|
||||
// arguments instead of parsing a version string.
|
||||
func New(major, minor, patch uint64, pre, metadata string) *Version {
|
||||
v := Version{
|
||||
major: major,
|
||||
minor: minor,
|
||||
patch: patch,
|
||||
pre: pre,
|
||||
metadata: metadata,
|
||||
original: "",
|
||||
}
|
||||
|
||||
v.original = v.String()
|
||||
|
||||
return &v
|
||||
}
|
||||
|
||||
// MustParse parses a given version and panics on error.
|
||||
func MustParse(v string) *Version {
|
||||
sv, err := NewVersion(v)
|
||||
@ -267,7 +286,6 @@ func (v Version) Metadata() string {
|
||||
|
||||
// originalVPrefix returns the original 'v' prefix if any.
|
||||
func (v Version) originalVPrefix() string {
|
||||
|
||||
// Note, only lowercase v is supported as a prefix by the parser.
|
||||
if v.original != "" && v.original[:1] == "v" {
|
||||
return v.original[:1]
|
||||
@ -436,6 +454,23 @@ func (v Version) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v.String())
|
||||
}
|
||||
|
||||
// UnmarshalText implements the encoding.TextUnmarshaler interface.
|
||||
func (v *Version) UnmarshalText(text []byte) error {
|
||||
temp, err := NewVersion(string(text))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = *temp
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalText implements the encoding.TextMarshaler interface.
|
||||
func (v Version) MarshalText() ([]byte, error) {
|
||||
return []byte(v.String()), nil
|
||||
}
|
||||
|
||||
// Scan implements the SQL.Scanner interface.
|
||||
func (v *Version) Scan(value interface{}) error {
|
||||
var s string
|
||||
@ -470,7 +505,6 @@ func compareSegment(v, o uint64) int {
|
||||
}
|
||||
|
||||
func comparePrerelease(v, o string) int {
|
||||
|
||||
// split the prelease versions by their part. The separator, per the spec,
|
||||
// is a .
|
||||
sparts := strings.Split(v, ".")
|
||||
@ -562,7 +596,6 @@ func comparePrePart(s, o string) int {
|
||||
return 1
|
||||
}
|
||||
return -1
|
||||
|
||||
}
|
||||
|
||||
// Like strings.ContainsAny but does an only instead of any.
|
||||
|
||||
38
vendor/github.com/caddyserver/certmagic/README.md
generated
vendored
38
vendor/github.com/caddyserver/certmagic/README.md
generated
vendored
@ -75,10 +75,11 @@ CertMagic - Automatic HTTPS using Let's Encrypt
|
||||
## Features
|
||||
|
||||
- Fully automated certificate management including issuance and renewal
|
||||
- One-liner, fully managed HTTPS servers
|
||||
- One-line, fully managed HTTPS servers
|
||||
- Full control over almost every aspect of the system
|
||||
- HTTP->HTTPS redirects
|
||||
- Solves all 3 ACME challenges: HTTP, TLS-ALPN, and DNS
|
||||
- Multiple issuers supported: get certificates from multiple sources/CAs for redundancy and resiliency
|
||||
- Solves all 3 common ACME challenges: HTTP, TLS-ALPN, and DNS (and capable of others)
|
||||
- Most robust error handling of _any_ ACME client
|
||||
- Challenges are randomized to avoid accidental dependence
|
||||
- Challenges are rotated to overcome certain network blockages
|
||||
@ -88,7 +89,8 @@ CertMagic - Automatic HTTPS using Let's Encrypt
|
||||
- Written in Go, a language with memory-safety guarantees
|
||||
- Powered by [ACMEz](https://github.com/mholt/acmez), _the_ premier ACME client library for Go
|
||||
- All [libdns](https://github.com/libdns) DNS providers work out-of-the-box
|
||||
- Pluggable storage implementations (default: file system)
|
||||
- Pluggable storage backends (default: file system)
|
||||
- Pluggable key sources
|
||||
- Wildcard certificates
|
||||
- Automatic OCSP stapling ([done right](https://gist.github.com/sleevi/5efe9ef98961ecfb4da8#gistcomment-2336055)) [keeps your sites online!](https://twitter.com/caddyserver/status/1234874273724084226)
|
||||
- Will [automatically attempt](https://twitter.com/mholt6/status/1235577699541762048) to replace [revoked certificates](https://community.letsencrypt.org/t/2020-02-29-caa-rechecking-bug/114591/3?u=mholt)!
|
||||
@ -101,7 +103,8 @@ CertMagic - Automatic HTTPS using Let's Encrypt
|
||||
- Caddy / CertMagic pioneered this technology
|
||||
- Custom decision functions to regulate and throttle on-demand behavior
|
||||
- Optional event hooks for observation
|
||||
- Works with any certificate authority (CA) compliant with the ACME specification
|
||||
- One-time private keys by default (new key for each cert) to discourage pinning and reduce scope of key compromise
|
||||
- Works with any certificate authority (CA) compliant with the ACME specification RFC 8555
|
||||
- Certificate revocation (please, only if private key is compromised)
|
||||
- Must-Staple (optional; not default)
|
||||
- Cross-platform support! Mac, Windows, Linux, BSD, Android...
|
||||
@ -238,16 +241,17 @@ if err != nil {
|
||||
For more control (particularly, if you need a different way of managing each certificate), you'll make and use a `Cache` and a `Config` like so:
|
||||
|
||||
```go
|
||||
cache := certmagic.NewCache(certmagic.CacheOptions{
|
||||
// First make a pointer to a Cache as we need to reference the same Cache in
|
||||
// GetConfigForCert below.
|
||||
var cache *certmagic.Cache
|
||||
cache = certmagic.NewCache(certmagic.CacheOptions{
|
||||
GetConfigForCert: func(cert certmagic.Certificate) (*certmagic.Config, error) {
|
||||
// do whatever you need to do to get the right
|
||||
// configuration for this certificate; keep in
|
||||
// mind that this config value is used as a
|
||||
// template, and will be completed with any
|
||||
// defaults that are set in the Default config
|
||||
return &certmagic.Config{
|
||||
// Here we use New to get a valid Config associated with the same cache.
|
||||
// The provided Config is used as a template and will be completed with
|
||||
// any defaults that are set in the Default config.
|
||||
return certmagic.New(cache, certmagic.Config{
|
||||
// ...
|
||||
}, nil
|
||||
}), nil
|
||||
},
|
||||
...
|
||||
})
|
||||
@ -263,7 +267,7 @@ myACME := certmagic.NewACMEIssuer(magic, certmagic.ACMEIssuer{
|
||||
// plus any other customizations you need
|
||||
})
|
||||
|
||||
magic.Issuer = myACME
|
||||
magic.Issuers = []certmagic.Issuer{myACME}
|
||||
|
||||
// this obtains certificates or renews them if necessary
|
||||
err := magic.ManageSync(context.TODO(), []string{"example.com", "sub.example.com"})
|
||||
@ -477,13 +481,15 @@ CertMagic emits events when possible things of interest happen. Set the [`OnEven
|
||||
- `identifier`: The name on the certificate
|
||||
- `remaining`: Time left on the certificate (if renewal)
|
||||
- `issuer`: The previous or current issuer
|
||||
- `storage_key`: The path to the cert resources within storage
|
||||
- `storage_path`: The path to the folder containing the cert resources within storage
|
||||
- `private_key_path`: The path to the private key file in storage
|
||||
- `certificate_path`: The path to the public key file in storage
|
||||
- `metadata_path`: The path to the metadata file in storage
|
||||
- **`cert_failed`** An attempt to obtain a certificate failed
|
||||
- `renewal`: Whether this is a renewal
|
||||
- `identifier`: The name on the certificate
|
||||
- `remaining`: Time left on the certificate (if renewal)
|
||||
- `issuer`: The previous or current issuer
|
||||
- `storage_key`: The path to the cert resources within storage
|
||||
- `issuers`: The issuer(s) tried
|
||||
- `error`: The (final) error message
|
||||
- **`tls_get_certificate`** The GetCertificate phase of a TLS handshake is under way
|
||||
- `client_hello`: The tls.ClientHelloInfo struct
|
||||
|
||||
3
vendor/github.com/caddyserver/certmagic/acmeclient.go
generated
vendored
3
vendor/github.com/caddyserver/certmagic/acmeclient.go
generated
vendored
@ -68,7 +68,10 @@ func (iss *ACMEIssuer) newACMEClientWithAccount(ctx context.Context, useTestCA,
|
||||
// register account if it is new
|
||||
if account.Status == "" {
|
||||
if iss.NewAccountFunc != nil {
|
||||
// obtain lock here, since NewAccountFunc calls happen concurrently and they typically read and change the issuer
|
||||
iss.mu.Lock()
|
||||
account, err = iss.NewAccountFunc(ctx, iss, account)
|
||||
iss.mu.Unlock()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("account pre-registration callback: %v", err)
|
||||
}
|
||||
|
||||
24
vendor/github.com/caddyserver/certmagic/acmeissuer.go
generated
vendored
24
vendor/github.com/caddyserver/certmagic/acmeissuer.go
generated
vendored
@ -115,6 +115,10 @@ type ACMEIssuer struct {
|
||||
// desired, set this to zap.NewNop().
|
||||
Logger *zap.Logger
|
||||
|
||||
// Set a http proxy to use when issuing a certificate.
|
||||
// Default is http.ProxyFromEnvironment
|
||||
HTTPProxy func(*http.Request) (*url.URL, error)
|
||||
|
||||
config *Config
|
||||
httpClient *http.Client
|
||||
|
||||
@ -128,7 +132,7 @@ type ACMEIssuer struct {
|
||||
// synchronize properly.
|
||||
email string
|
||||
agreed bool
|
||||
mu *sync.Mutex // protects the above grouped fields
|
||||
mu *sync.Mutex // protects the above grouped fields, as well as entire struct during NewAccountFunc calls
|
||||
}
|
||||
|
||||
// NewACMEIssuer constructs a valid ACMEIssuer based on a template
|
||||
@ -204,6 +208,13 @@ func NewACMEIssuer(cfg *Config, template ACMEIssuer) *ACMEIssuer {
|
||||
template.Logger = defaultLogger
|
||||
}
|
||||
|
||||
if template.HTTPProxy == nil {
|
||||
template.HTTPProxy = DefaultACME.HTTPProxy
|
||||
}
|
||||
if template.HTTPProxy == nil {
|
||||
template.HTTPProxy = http.ProxyFromEnvironment
|
||||
}
|
||||
|
||||
template.config = cfg
|
||||
template.mu = new(sync.Mutex)
|
||||
|
||||
@ -223,7 +234,7 @@ func NewACMEIssuer(cfg *Config, template ACMEIssuer) *ACMEIssuer {
|
||||
}
|
||||
}
|
||||
transport := &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
Proxy: template.HTTPProxy,
|
||||
DialContext: dialer.DialContext,
|
||||
TLSHandshakeTimeout: 30 * time.Second, // increase to 30s requested in #175
|
||||
ResponseHeaderTimeout: 30 * time.Second, // increase to 30s requested in #175
|
||||
@ -288,7 +299,7 @@ func (iss *ACMEIssuer) isAgreed() bool {
|
||||
// batch is eligible for certificates if using Let's Encrypt.
|
||||
// It also ensures that an email address is available.
|
||||
func (am *ACMEIssuer) PreCheck(ctx context.Context, names []string, interactive bool) error {
|
||||
publicCA := strings.Contains(am.CA, "api.letsencrypt.org") || strings.Contains(am.CA, "acme.zerossl.com")
|
||||
publicCA := strings.Contains(am.CA, "api.letsencrypt.org") || strings.Contains(am.CA, "acme.zerossl.com") || strings.Contains(am.CA, "api.pki.goog")
|
||||
if publicCA {
|
||||
for _, name := range names {
|
||||
if !SubjectQualifiesForPublicCert(name) {
|
||||
@ -506,9 +517,10 @@ type ChainPreference struct {
|
||||
// DefaultACME specifies default settings to use for ACMEIssuers.
|
||||
// Using this value is optional but can be convenient.
|
||||
var DefaultACME = ACMEIssuer{
|
||||
CA: LetsEncryptProductionCA,
|
||||
TestCA: LetsEncryptStagingCA,
|
||||
Logger: defaultLogger,
|
||||
CA: LetsEncryptProductionCA,
|
||||
TestCA: LetsEncryptStagingCA,
|
||||
Logger: defaultLogger,
|
||||
HTTPProxy: http.ProxyFromEnvironment,
|
||||
}
|
||||
|
||||
// Some well-known CA endpoints available to use.
|
||||
|
||||
92
vendor/github.com/caddyserver/certmagic/cache.go
generated
vendored
92
vendor/github.com/caddyserver/certmagic/cache.go
generated
vendored
@ -48,7 +48,8 @@ import (
|
||||
// differently.
|
||||
type Cache struct {
|
||||
// User configuration of the cache
|
||||
options CacheOptions
|
||||
options CacheOptions
|
||||
optionsMu sync.RWMutex
|
||||
|
||||
// The cache is keyed by certificate hash
|
||||
cache map[string]Certificate
|
||||
@ -56,7 +57,7 @@ type Cache struct {
|
||||
// cacheIndex is a map of SAN to cache key (cert hash)
|
||||
cacheIndex map[string][]string
|
||||
|
||||
// Protects the cache and index maps
|
||||
// Protects the cache and cacheIndex maps
|
||||
mu sync.RWMutex
|
||||
|
||||
// Close this channel to cancel asset maintenance
|
||||
@ -128,6 +129,12 @@ func NewCache(opts CacheOptions) *Cache {
|
||||
return c
|
||||
}
|
||||
|
||||
func (certCache *Cache) SetOptions(opts CacheOptions) {
|
||||
certCache.optionsMu.Lock()
|
||||
certCache.options = opts
|
||||
certCache.optionsMu.Unlock()
|
||||
}
|
||||
|
||||
// Stop stops the maintenance goroutine for
|
||||
// certificates in certCache. It blocks until
|
||||
// stopping is complete. Once a cache is
|
||||
@ -145,7 +152,8 @@ type CacheOptions struct {
|
||||
// used for managing a certificate, or for accessing
|
||||
// that certificate's asset storage (e.g. for
|
||||
// OCSP staples, etc). The returned Config MUST
|
||||
// be associated with the same Cache as the caller.
|
||||
// be associated with the same Cache as the caller,
|
||||
// use New to obtain a valid Config.
|
||||
//
|
||||
// The reason this is a callback function, dynamically
|
||||
// returning a Config (instead of attaching a static
|
||||
@ -197,20 +205,39 @@ func (certCache *Cache) cacheCertificate(cert Certificate) {
|
||||
// This function is NOT safe for concurrent use. Callers MUST acquire
|
||||
// a write lock on certCache.mu first.
|
||||
func (certCache *Cache) unsyncedCacheCertificate(cert Certificate) {
|
||||
// no-op if this certificate already exists in the cache
|
||||
if _, ok := certCache.cache[cert.hash]; ok {
|
||||
certCache.logger.Debug("certificate already cached",
|
||||
// if this certificate already exists in the cache, this is basically
|
||||
// a no-op so we reuse existing cert (prevent duplication), but we do
|
||||
// modify the cert to add tags it may be missing (see issue #211)
|
||||
if existingCert, ok := certCache.cache[cert.hash]; ok {
|
||||
logMsg := "certificate already cached"
|
||||
|
||||
if len(cert.Tags) > 0 {
|
||||
for _, tag := range cert.Tags {
|
||||
if !existingCert.HasTag(tag) {
|
||||
existingCert.Tags = append(existingCert.Tags, tag)
|
||||
}
|
||||
}
|
||||
certCache.cache[cert.hash] = existingCert
|
||||
logMsg += "; appended any missing tags to cert"
|
||||
}
|
||||
|
||||
certCache.logger.Debug(logMsg,
|
||||
zap.Strings("subjects", cert.Names),
|
||||
zap.Time("expiration", expiresAt(cert.Leaf)),
|
||||
zap.Bool("managed", cert.managed),
|
||||
zap.String("issuer_key", cert.issuerKey),
|
||||
zap.String("hash", cert.hash))
|
||||
zap.String("hash", cert.hash),
|
||||
zap.Strings("tags", cert.Tags))
|
||||
return
|
||||
}
|
||||
|
||||
// if the cache is at capacity, make room for new cert
|
||||
cacheSize := len(certCache.cache)
|
||||
if certCache.options.Capacity > 0 && cacheSize >= certCache.options.Capacity {
|
||||
certCache.optionsMu.RLock()
|
||||
atCapacity := certCache.options.Capacity > 0 && cacheSize >= certCache.options.Capacity
|
||||
certCache.optionsMu.RUnlock()
|
||||
|
||||
if atCapacity {
|
||||
// Go maps are "nondeterministic" but not actually random,
|
||||
// so although we could just chop off the "front" of the
|
||||
// map with less code, that is a heavily skewed eviction
|
||||
@ -240,6 +267,7 @@ func (certCache *Cache) unsyncedCacheCertificate(cert Certificate) {
|
||||
certCache.cacheIndex[name] = append(certCache.cacheIndex[name], cert.hash)
|
||||
}
|
||||
|
||||
certCache.optionsMu.RLock()
|
||||
certCache.logger.Debug("added certificate to cache",
|
||||
zap.Strings("subjects", cert.Names),
|
||||
zap.Time("expiration", expiresAt(cert.Leaf)),
|
||||
@ -248,6 +276,7 @@ func (certCache *Cache) unsyncedCacheCertificate(cert Certificate) {
|
||||
zap.String("hash", cert.hash),
|
||||
zap.Int("cache_size", len(certCache.cache)),
|
||||
zap.Int("cache_capacity", certCache.options.Capacity))
|
||||
certCache.optionsMu.RUnlock()
|
||||
}
|
||||
|
||||
// removeCertificate removes cert from the cache.
|
||||
@ -274,6 +303,7 @@ func (certCache *Cache) removeCertificate(cert Certificate) {
|
||||
// delete the actual cert from the cache
|
||||
delete(certCache.cache, cert.hash)
|
||||
|
||||
certCache.optionsMu.RLock()
|
||||
certCache.logger.Debug("removed certificate from cache",
|
||||
zap.Strings("subjects", cert.Names),
|
||||
zap.Time("expiration", expiresAt(cert.Leaf)),
|
||||
@ -282,6 +312,7 @@ func (certCache *Cache) removeCertificate(cert Certificate) {
|
||||
zap.String("hash", cert.hash),
|
||||
zap.Int("cache_size", len(certCache.cache)),
|
||||
zap.Int("cache_capacity", certCache.options.Capacity))
|
||||
certCache.optionsMu.RUnlock()
|
||||
}
|
||||
|
||||
// replaceCertificate atomically replaces oldCert with newCert in
|
||||
@ -298,11 +329,13 @@ func (certCache *Cache) replaceCertificate(oldCert, newCert Certificate) {
|
||||
zap.Time("new_expiration", expiresAt(newCert.Leaf)))
|
||||
}
|
||||
|
||||
func (certCache *Cache) getAllMatchingCerts(name string) []Certificate {
|
||||
// getAllMatchingCerts returns all certificates with exactly this subject
|
||||
// (wildcards are NOT expanded).
|
||||
func (certCache *Cache) getAllMatchingCerts(subject string) []Certificate {
|
||||
certCache.mu.RLock()
|
||||
defer certCache.mu.RUnlock()
|
||||
|
||||
allCertKeys := certCache.cacheIndex[name]
|
||||
allCertKeys := certCache.cacheIndex[subject]
|
||||
|
||||
certs := make([]Certificate, len(allCertKeys))
|
||||
for i := range allCertKeys {
|
||||
@ -323,11 +356,19 @@ func (certCache *Cache) getAllCerts() []Certificate {
|
||||
}
|
||||
|
||||
func (certCache *Cache) getConfig(cert Certificate) (*Config, error) {
|
||||
cfg, err := certCache.options.GetConfigForCert(cert)
|
||||
certCache.optionsMu.RLock()
|
||||
getCert := certCache.options.GetConfigForCert
|
||||
certCache.optionsMu.RUnlock()
|
||||
|
||||
cfg, err := getCert(cert)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cfg.certCache != nil && cfg.certCache != certCache {
|
||||
if cfg.certCache == nil {
|
||||
return nil, fmt.Errorf("config returned for certificate %v has nil cache; expected %p (this one)",
|
||||
cert.Names, certCache)
|
||||
}
|
||||
if cfg.certCache != certCache {
|
||||
return nil, fmt.Errorf("config returned for certificate %v is not nil and points to different cache; got %p, expected %p (this one)",
|
||||
cert.Names, cfg.certCache, certCache)
|
||||
}
|
||||
@ -353,6 +394,33 @@ func (certCache *Cache) AllMatchingCertificates(name string) []Certificate {
|
||||
return certs
|
||||
}
|
||||
|
||||
// RemoveManaged removes managed certificates for the given subjects from the cache.
|
||||
// This effectively stops maintenance of those certificates.
|
||||
func (certCache *Cache) RemoveManaged(subjects []string) {
|
||||
deleteQueue := make([]string, 0, len(subjects))
|
||||
for _, subject := range subjects {
|
||||
certs := certCache.getAllMatchingCerts(subject) // does NOT expand wildcards; exact matches only
|
||||
for _, cert := range certs {
|
||||
if !cert.managed {
|
||||
continue
|
||||
}
|
||||
deleteQueue = append(deleteQueue, cert.hash)
|
||||
}
|
||||
}
|
||||
certCache.Remove(deleteQueue)
|
||||
}
|
||||
|
||||
// Remove removes certificates with the given hashes from the cache.
|
||||
// This is effectively used to unload manually-loaded certificates.
|
||||
func (certCache *Cache) Remove(hashes []string) {
|
||||
certCache.mu.Lock()
|
||||
for _, h := range hashes {
|
||||
cert := certCache.cache[h]
|
||||
certCache.removeCertificate(cert)
|
||||
}
|
||||
certCache.mu.Unlock()
|
||||
}
|
||||
|
||||
var (
|
||||
defaultCache *Cache
|
||||
defaultCacheMu sync.Mutex
|
||||
|
||||
36
vendor/github.com/caddyserver/certmagic/certificates.go
generated
vendored
36
vendor/github.com/caddyserver/certmagic/certificates.go
generated
vendored
@ -48,7 +48,7 @@ type Certificate struct {
|
||||
// most recent OCSP response we have for this certificate.
|
||||
ocsp *ocsp.Response
|
||||
|
||||
// The hex-encoded hash of this cert's chain's bytes.
|
||||
// The hex-encoded hash of this cert's chain's DER bytes.
|
||||
hash string
|
||||
|
||||
// Whether this certificate is under our management.
|
||||
@ -64,6 +64,9 @@ func (cert Certificate) Empty() bool {
|
||||
return len(cert.Certificate.Certificate) == 0
|
||||
}
|
||||
|
||||
// Hash returns a checksum of the certificate chain's DER-encoded bytes.
|
||||
func (cert Certificate) Hash() string { return cert.hash }
|
||||
|
||||
// NeedsRenewal returns true if the certificate is
|
||||
// expiring soon (according to cfg) or has expired.
|
||||
func (cert Certificate) NeedsRenewal(cfg *Config) bool {
|
||||
@ -113,6 +116,9 @@ func (cert Certificate) HasTag(tag string) bool {
|
||||
// resolution of ASN.1 UTCTime/GeneralizedTime by including the extra fraction
|
||||
// of a second of certificate validity beyond the NotAfter value.
|
||||
func expiresAt(cert *x509.Certificate) time.Time {
|
||||
if cert == nil {
|
||||
return time.Time{}
|
||||
}
|
||||
return cert.NotAfter.Truncate(time.Second).Add(1 * time.Second)
|
||||
}
|
||||
|
||||
@ -152,29 +158,32 @@ func (cfg *Config) loadManagedCertificate(ctx context.Context, domain string) (C
|
||||
|
||||
// CacheUnmanagedCertificatePEMFile loads a certificate for host using certFile
|
||||
// and keyFile, which must be in PEM format. It stores the certificate in
|
||||
// the in-memory cache.
|
||||
// the in-memory cache and returns the hash, useful for removing from the cache.
|
||||
//
|
||||
// This method is safe for concurrent use.
|
||||
func (cfg *Config) CacheUnmanagedCertificatePEMFile(ctx context.Context, certFile, keyFile string, tags []string) error {
|
||||
func (cfg *Config) CacheUnmanagedCertificatePEMFile(ctx context.Context, certFile, keyFile string, tags []string) (string, error) {
|
||||
cert, err := cfg.makeCertificateFromDiskWithOCSP(ctx, cfg.Storage, certFile, keyFile)
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
cert.Tags = tags
|
||||
cfg.certCache.cacheCertificate(cert)
|
||||
cfg.emit(ctx, "cached_unmanaged_cert", map[string]any{"sans": cert.Names})
|
||||
return nil
|
||||
return cert.hash, nil
|
||||
}
|
||||
|
||||
// CacheUnmanagedTLSCertificate adds tlsCert to the certificate cache.
|
||||
// CacheUnmanagedTLSCertificate adds tlsCert to the certificate cache
|
||||
//
|
||||
// and returns the hash, useful for removing from the cache.
|
||||
//
|
||||
// It staples OCSP if possible.
|
||||
//
|
||||
// This method is safe for concurrent use.
|
||||
func (cfg *Config) CacheUnmanagedTLSCertificate(ctx context.Context, tlsCert tls.Certificate, tags []string) error {
|
||||
func (cfg *Config) CacheUnmanagedTLSCertificate(ctx context.Context, tlsCert tls.Certificate, tags []string) (string, error) {
|
||||
var cert Certificate
|
||||
err := fillCertFromLeaf(&cert, tlsCert)
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
err = stapleOCSP(ctx, cfg.OCSP, cfg.Storage, &cert, nil)
|
||||
if err != nil {
|
||||
@ -183,22 +192,23 @@ func (cfg *Config) CacheUnmanagedTLSCertificate(ctx context.Context, tlsCert tls
|
||||
cfg.emit(ctx, "cached_unmanaged_cert", map[string]any{"sans": cert.Names})
|
||||
cert.Tags = tags
|
||||
cfg.certCache.cacheCertificate(cert)
|
||||
return nil
|
||||
return cert.hash, nil
|
||||
}
|
||||
|
||||
// CacheUnmanagedCertificatePEMBytes makes a certificate out of the PEM bytes
|
||||
// of the certificate and key, then caches it in memory.
|
||||
// of the certificate and key, then caches it in memory, and returns the hash,
|
||||
// which is useful for removing from the cache.
|
||||
//
|
||||
// This method is safe for concurrent use.
|
||||
func (cfg *Config) CacheUnmanagedCertificatePEMBytes(ctx context.Context, certBytes, keyBytes []byte, tags []string) error {
|
||||
func (cfg *Config) CacheUnmanagedCertificatePEMBytes(ctx context.Context, certBytes, keyBytes []byte, tags []string) (string, error) {
|
||||
cert, err := cfg.makeCertificateWithOCSP(ctx, certBytes, keyBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
cert.Tags = tags
|
||||
cfg.certCache.cacheCertificate(cert)
|
||||
cfg.emit(ctx, "cached_unmanaged_cert", map[string]any{"sans": cert.Names})
|
||||
return nil
|
||||
return cert.hash, nil
|
||||
}
|
||||
|
||||
// makeCertificateFromDiskWithOCSP makes a Certificate by loading the
|
||||
|
||||
53
vendor/github.com/caddyserver/certmagic/certmagic.go
generated
vendored
53
vendor/github.com/caddyserver/certmagic/certmagic.go
generated
vendored
@ -270,7 +270,16 @@ type OnDemandConfig struct {
|
||||
// request will be denied.
|
||||
DecisionFunc func(name string) error
|
||||
|
||||
// List of whitelisted hostnames (SNI values) for
|
||||
// Sources for getting new, unmanaged certificates.
|
||||
// They will be invoked only during TLS handshakes
|
||||
// before on-demand certificate management occurs,
|
||||
// for certificates that are not already loaded into
|
||||
// the in-memory cache.
|
||||
//
|
||||
// TODO: EXPERIMENTAL: subject to change and/or removal.
|
||||
Managers []Manager
|
||||
|
||||
// List of allowed hostnames (SNI values) for
|
||||
// deferred (on-demand) obtaining of certificates.
|
||||
// Used only by higher-level functions in this
|
||||
// package to persist the list of hostnames that
|
||||
@ -282,20 +291,15 @@ type OnDemandConfig struct {
|
||||
// for higher-level convenience functions to be
|
||||
// able to retain their convenience (alternative
|
||||
// is: the user manually creates a DecisionFunc
|
||||
// that whitelists the same names it already
|
||||
// passed into Manage) and without letting clients
|
||||
// have their run of any domain names they want.
|
||||
// Only enforced if len > 0.
|
||||
hostWhitelist []string
|
||||
}
|
||||
|
||||
func (o *OnDemandConfig) whitelistContains(name string) bool {
|
||||
for _, n := range o.hostWhitelist {
|
||||
if strings.EqualFold(n, name) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
// that allows the same names it already passed
|
||||
// into Manage) and without letting clients have
|
||||
// their run of any domain names they want.
|
||||
// Only enforced if len > 0. (This is a map to
|
||||
// avoid O(n^2) performance; when it was a slice,
|
||||
// we saw a 30s CPU profile for a config managing
|
||||
// 110K names where 29s was spent checking for
|
||||
// duplicates. Order is not important here.)
|
||||
hostAllowlist map[string]struct{}
|
||||
}
|
||||
|
||||
// isLoopback returns true if the hostname of addr looks
|
||||
@ -402,6 +406,23 @@ type KeyGenerator interface {
|
||||
GenerateKey() (crypto.PrivateKey, error)
|
||||
}
|
||||
|
||||
// IssuerPolicy is a type that enumerates how to
|
||||
// choose which issuer to use. EXPERIMENTAL and
|
||||
// subject to change.
|
||||
type IssuerPolicy string
|
||||
|
||||
// Supported issuer policies. These are subject to change.
|
||||
const (
|
||||
// UseFirstIssuer uses the first issuer that
|
||||
// successfully returns a certificate.
|
||||
UseFirstIssuer = "first"
|
||||
|
||||
// UseFirstRandomIssuer shuffles the list of
|
||||
// configured issuers, then uses the first one
|
||||
// that successfully returns a certificate.
|
||||
UseFirstRandomIssuer = "first_random"
|
||||
)
|
||||
|
||||
// IssuedCertificate represents a certificate that was just issued.
|
||||
type IssuedCertificate struct {
|
||||
// The PEM-encoding of DER-encoded ASN.1 data.
|
||||
@ -433,7 +454,7 @@ type CertificateResource struct {
|
||||
|
||||
// The unique string identifying the issuer of the
|
||||
// certificate; internally useful for storage access.
|
||||
issuerKey string `json:"-"`
|
||||
issuerKey string
|
||||
}
|
||||
|
||||
// NamesKey returns the list of SANs as a single string,
|
||||
|
||||
194
vendor/github.com/caddyserver/certmagic/config.go
generated
vendored
194
vendor/github.com/caddyserver/certmagic/config.go
generated
vendored
@ -72,6 +72,13 @@ type Config struct {
|
||||
// ClientHello's ServerName field is empty.
|
||||
DefaultServerName string
|
||||
|
||||
// FallbackServerName specifies a server name
|
||||
// to use when choosing a certificate if the
|
||||
// ClientHello's ServerName field doesn't match
|
||||
// any available certificate.
|
||||
// EXPERIMENTAL: Subject to change or removal.
|
||||
FallbackServerName string
|
||||
|
||||
// The state needed to operate on-demand TLS;
|
||||
// if non-nil, on-demand TLS is enabled and
|
||||
// certificate operations are deferred to
|
||||
@ -88,14 +95,16 @@ type Config struct {
|
||||
// turn until one succeeds.
|
||||
Issuers []Issuer
|
||||
|
||||
// Sources for getting new, unmanaged certificates.
|
||||
// They will be invoked only during TLS handshakes
|
||||
// before on-demand certificate management occurs,
|
||||
// for certificates that are not already loaded into
|
||||
// the in-memory cache.
|
||||
//
|
||||
// TODO: EXPERIMENTAL: subject to change and/or removal.
|
||||
Managers []Manager
|
||||
// How to select which issuer to use.
|
||||
// Default: UseFirstIssuer (subject to change).
|
||||
IssuerPolicy IssuerPolicy
|
||||
|
||||
// If true, private keys already existing in storage
|
||||
// will be reused. Otherwise, a new key will be
|
||||
// created for every new certificate to mitigate
|
||||
// pinning and reduce the scope of key compromise.
|
||||
// Default: false (do not reuse keys).
|
||||
ReusePrivateKeys bool
|
||||
|
||||
// The source of new private keys for certificates;
|
||||
// the default KeySource is StandardKeyGenerator.
|
||||
@ -119,6 +128,16 @@ type Config struct {
|
||||
// TLS assets. Default is the local file system.
|
||||
Storage Storage
|
||||
|
||||
// CertMagic will verify the storage configuration
|
||||
// is acceptable before obtaining a certificate
|
||||
// to avoid information loss after an expensive
|
||||
// operation. If you are absolutely 100% sure your
|
||||
// storage is properly configured and has sufficient
|
||||
// space, you can disable this check to reduce I/O
|
||||
// if that is expensive for you.
|
||||
// EXPERIMENTAL: Option subject to change or removal.
|
||||
DisableStorageCheck bool
|
||||
|
||||
// Set a logger to enable logging. If not set,
|
||||
// a default logger will be created.
|
||||
Logger *zap.Logger
|
||||
@ -162,6 +181,7 @@ func NewDefault() *Config {
|
||||
GetConfigForCert: func(Certificate) (*Config, error) {
|
||||
return NewDefault(), nil
|
||||
},
|
||||
Logger: Default.Logger,
|
||||
})
|
||||
}
|
||||
certCache := defaultCache
|
||||
@ -189,7 +209,10 @@ func New(certCache *Cache, cfg Config) *Config {
|
||||
if certCache == nil {
|
||||
panic("a certificate cache is required")
|
||||
}
|
||||
if certCache.options.GetConfigForCert == nil {
|
||||
certCache.optionsMu.RLock()
|
||||
getConfigForCert := certCache.options.GetConfigForCert
|
||||
defer certCache.optionsMu.RUnlock()
|
||||
if getConfigForCert == nil {
|
||||
panic("cache must have GetConfigForCert set in its options")
|
||||
}
|
||||
return newWithCache(certCache, cfg)
|
||||
@ -209,10 +232,10 @@ func newWithCache(certCache *Cache, cfg Config) *Config {
|
||||
if !cfg.MustStaple {
|
||||
cfg.MustStaple = Default.MustStaple
|
||||
}
|
||||
if len(cfg.Issuers) == 0 {
|
||||
if cfg.Issuers == nil {
|
||||
cfg.Issuers = Default.Issuers
|
||||
if len(cfg.Issuers) == 0 {
|
||||
// at least one issuer is absolutely required
|
||||
if cfg.Issuers == nil {
|
||||
// at least one issuer is absolutely required if not nil
|
||||
cfg.Issuers = []Issuer{NewACMEIssuer(&cfg, DefaultACME)}
|
||||
}
|
||||
}
|
||||
@ -228,6 +251,9 @@ func newWithCache(certCache *Cache, cfg Config) *Config {
|
||||
if cfg.DefaultServerName == "" {
|
||||
cfg.DefaultServerName = Default.DefaultServerName
|
||||
}
|
||||
if cfg.FallbackServerName == "" {
|
||||
cfg.FallbackServerName = Default.FallbackServerName
|
||||
}
|
||||
if cfg.Storage == nil {
|
||||
cfg.Storage = Default.Storage
|
||||
}
|
||||
@ -255,17 +281,20 @@ func newWithCache(certCache *Cache, cfg Config) *Config {
|
||||
|
||||
// ManageSync causes the certificates for domainNames to be managed
|
||||
// according to cfg. If cfg.OnDemand is not nil, then this simply
|
||||
// whitelists the domain names and defers the certificate operations
|
||||
// allowlists the domain names and defers the certificate operations
|
||||
// to when they are needed. Otherwise, the certificates for each
|
||||
// name are loaded from storage or obtained from the CA. If loaded
|
||||
// from storage, they are renewed if they are expiring or expired.
|
||||
// It then caches the certificate in memory and is prepared to serve
|
||||
// them up during TLS handshakes.
|
||||
// name are loaded from storage or obtained from the CA if not already
|
||||
// in the cache associated with the Config. If loaded from storage,
|
||||
// they are renewed if they are expiring or expired. It then caches
|
||||
// the certificate in memory and is prepared to serve them up during
|
||||
// TLS handshakes. To change how an already-loaded certificate is
|
||||
// managed, update the cache options relating to getting a config for
|
||||
// a cert.
|
||||
//
|
||||
// Note that name whitelisting for on-demand management only takes
|
||||
// Note that name allowlisting for on-demand management only takes
|
||||
// effect if cfg.OnDemand.DecisionFunc is not set (is nil); it will
|
||||
// not overwrite an existing DecisionFunc, nor will it overwrite
|
||||
// its decision; i.e. the implicit whitelist is only used if no
|
||||
// its decision; i.e. the implicit allowlist is only used if no
|
||||
// DecisionFunc is set.
|
||||
//
|
||||
// This method is synchronous, meaning that certificates for all
|
||||
@ -325,16 +354,18 @@ func (cfg *Config) manageAll(ctx context.Context, domainNames []string, async bo
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
if cfg.OnDemand != nil && cfg.OnDemand.hostAllowlist == nil {
|
||||
cfg.OnDemand.hostAllowlist = make(map[string]struct{})
|
||||
}
|
||||
|
||||
for _, domainName := range domainNames {
|
||||
// if on-demand is configured, defer obtain and renew operations
|
||||
if cfg.OnDemand != nil {
|
||||
if !cfg.OnDemand.whitelistContains(domainName) {
|
||||
cfg.OnDemand.hostWhitelist = append(cfg.OnDemand.hostWhitelist, domainName)
|
||||
}
|
||||
cfg.OnDemand.hostAllowlist[normalizedName(domainName)] = struct{}{}
|
||||
continue
|
||||
}
|
||||
|
||||
// TODO: consider doing this in a goroutine if async, to utilize multiple cores while loading certs
|
||||
// otherwise, begin management immediately
|
||||
err := cfg.manageOne(ctx, domainName, async)
|
||||
if err != nil {
|
||||
@ -346,6 +377,14 @@ func (cfg *Config) manageAll(ctx context.Context, domainNames []string, async bo
|
||||
}
|
||||
|
||||
func (cfg *Config) manageOne(ctx context.Context, domainName string, async bool) error {
|
||||
// if certificate is already being managed, nothing to do; maintenance will continue
|
||||
certs := cfg.certCache.getAllMatchingCerts(domainName)
|
||||
for _, cert := range certs {
|
||||
if cert.managed {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// first try loading existing certificate from storage
|
||||
cert, err := cfg.CacheManagedCertificate(ctx, domainName)
|
||||
if err != nil {
|
||||
@ -425,28 +464,6 @@ func (cfg *Config) manageOne(ctx context.Context, domainName string, async bool)
|
||||
return renew()
|
||||
}
|
||||
|
||||
// Unmanage causes the certificates for domainNames to stop being managed.
|
||||
// If there are certificates for the supplied domain names in the cache, they
|
||||
// are evicted from the cache.
|
||||
func (cfg *Config) Unmanage(domainNames []string) {
|
||||
var deleteQueue []Certificate
|
||||
for _, domainName := range domainNames {
|
||||
certs := cfg.certCache.AllMatchingCertificates(domainName)
|
||||
for _, cert := range certs {
|
||||
if !cert.managed {
|
||||
continue
|
||||
}
|
||||
deleteQueue = append(deleteQueue, cert)
|
||||
}
|
||||
}
|
||||
|
||||
cfg.certCache.mu.Lock()
|
||||
for _, cert := range deleteQueue {
|
||||
cfg.certCache.removeCertificate(cert)
|
||||
}
|
||||
cfg.certCache.mu.Unlock()
|
||||
}
|
||||
|
||||
// ObtainCertSync generates a new private key and obtains a certificate for
|
||||
// name using cfg in the foreground; i.e. interactively and without retries.
|
||||
// It stows the renewed certificate and its assets in storage if successful.
|
||||
@ -513,10 +530,25 @@ func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool
|
||||
return fmt.Errorf("obtaining certificate aborted by event handler: %w", err)
|
||||
}
|
||||
|
||||
// if storage has a private key already, use it; otherwise we'll generate our own
|
||||
privKey, privKeyPEM, issuers, err := cfg.reusePrivateKey(ctx, name)
|
||||
if err != nil {
|
||||
return err
|
||||
// If storage has a private key already, use it; otherwise we'll generate our own.
|
||||
// Also create the slice of issuers we will try using according to any issuer
|
||||
// selection policy (it must be a copy of the slice so we don't mutate original).
|
||||
var privKey crypto.PrivateKey
|
||||
var privKeyPEM []byte
|
||||
var issuers []Issuer
|
||||
if cfg.ReusePrivateKeys {
|
||||
privKey, privKeyPEM, issuers, err = cfg.reusePrivateKey(ctx, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
issuers = make([]Issuer, len(cfg.Issuers))
|
||||
copy(issuers, cfg.Issuers)
|
||||
}
|
||||
if cfg.IssuerPolicy == UseFirstRandomIssuer {
|
||||
weakrand.Shuffle(len(issuers), func(i, j int) {
|
||||
issuers[i], issuers[j] = issuers[j], issuers[i]
|
||||
})
|
||||
}
|
||||
if privKey == nil {
|
||||
privKey, err = cfg.KeySource.GenerateKey()
|
||||
@ -580,6 +612,7 @@ func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool
|
||||
// only the error from the last issuer will be returned, but we logged the others
|
||||
return fmt.Errorf("[%s] Obtain: %w", name, err)
|
||||
}
|
||||
issuerKey := issuerUsed.IssuerKey()
|
||||
|
||||
// success - immediately save the certificate resource
|
||||
certRes := CertificateResource{
|
||||
@ -587,6 +620,7 @@ func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool
|
||||
CertificatePEM: issuedCert.Certificate,
|
||||
PrivateKeyPEM: privKeyPEM,
|
||||
IssuerData: issuedCert.Metadata,
|
||||
issuerKey: issuerUsed.IssuerKey(),
|
||||
}
|
||||
err = cfg.saveCertResource(ctx, issuerUsed, certRes)
|
||||
if err != nil {
|
||||
@ -595,11 +629,16 @@ func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool
|
||||
|
||||
log.Info("certificate obtained successfully", zap.String("identifier", name))
|
||||
|
||||
certKey := certRes.NamesKey()
|
||||
|
||||
cfg.emit(ctx, "cert_obtained", map[string]any{
|
||||
"renewal": false,
|
||||
"identifier": name,
|
||||
"issuers": issuerUsed.IssuerKey(),
|
||||
"storage_key": certRes.NamesKey(),
|
||||
"renewal": false,
|
||||
"identifier": name,
|
||||
"issuer": issuerUsed.IssuerKey(),
|
||||
"storage_path": StorageKeys.CertsSitePrefix(issuerKey, certKey),
|
||||
"private_key_path": StorageKeys.SitePrivateKey(issuerKey, certKey),
|
||||
"certificate_path": StorageKeys.SiteCert(issuerKey, certKey),
|
||||
"metadata_path": StorageKeys.SiteMeta(issuerKey, certKey),
|
||||
})
|
||||
|
||||
return nil
|
||||
@ -669,9 +708,6 @@ func (cfg *Config) storageHasCertResourcesAnyIssuer(ctx context.Context, name st
|
||||
// and its assets in storage if successful. It DOES NOT update the in-memory
|
||||
// cache with the new certificate. The certificate will not be renewed if it
|
||||
// is not close to expiring unless force is true.
|
||||
//
|
||||
// Renewing a certificate is the same as obtaining a certificate, except that
|
||||
// the existing private key already in storage is reused.
|
||||
func (cfg *Config) RenewCertSync(ctx context.Context, name string, force bool) error {
|
||||
return cfg.renewCert(ctx, name, force, true)
|
||||
}
|
||||
@ -752,10 +788,25 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
|
||||
return fmt.Errorf("renewing certificate aborted by event handler: %w", err)
|
||||
}
|
||||
|
||||
privateKey, err := PEMDecodePrivateKey(certRes.PrivateKeyPEM)
|
||||
// reuse or generate new private key for CSR
|
||||
var privateKey crypto.PrivateKey
|
||||
if cfg.ReusePrivateKeys {
|
||||
privateKey, err = PEMDecodePrivateKey(certRes.PrivateKeyPEM)
|
||||
} else {
|
||||
privateKey, err = cfg.KeySource.GenerateKey()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if we generated a new key, make sure to replace its PEM encoding too!
|
||||
if !cfg.ReusePrivateKeys {
|
||||
certRes.PrivateKeyPEM, err = PEMEncodePrivateKey(privateKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
csr, err := cfg.generateCSR(privateKey, []string{name})
|
||||
if err != nil {
|
||||
return err
|
||||
@ -794,17 +845,17 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
|
||||
}
|
||||
if err != nil {
|
||||
cfg.emit(ctx, "cert_failed", map[string]any{
|
||||
"renewal": true,
|
||||
"identifier": name,
|
||||
"remaining": timeLeft,
|
||||
"issuers": issuerKeys,
|
||||
"storage_key": certRes.NamesKey(),
|
||||
"error": err,
|
||||
"renewal": true,
|
||||
"identifier": name,
|
||||
"remaining": timeLeft,
|
||||
"issuers": issuerKeys,
|
||||
"error": err,
|
||||
})
|
||||
|
||||
// only the error from the last issuer will be returned, but we logged the others
|
||||
return fmt.Errorf("[%s] Renew: %w", name, err)
|
||||
}
|
||||
issuerKey := issuerUsed.IssuerKey()
|
||||
|
||||
// success - immediately save the renewed certificate resource
|
||||
newCertRes := CertificateResource{
|
||||
@ -812,6 +863,7 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
|
||||
CertificatePEM: issuedCert.Certificate,
|
||||
PrivateKeyPEM: certRes.PrivateKeyPEM,
|
||||
IssuerData: issuedCert.Metadata,
|
||||
issuerKey: issuerKey,
|
||||
}
|
||||
err = cfg.saveCertResource(ctx, issuerUsed, newCertRes)
|
||||
if err != nil {
|
||||
@ -820,12 +872,17 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
|
||||
|
||||
log.Info("certificate renewed successfully", zap.String("identifier", name))
|
||||
|
||||
certKey := newCertRes.NamesKey()
|
||||
|
||||
cfg.emit(ctx, "cert_obtained", map[string]any{
|
||||
"renewal": true,
|
||||
"remaining": timeLeft,
|
||||
"identifier": name,
|
||||
"issuer": issuerUsed.IssuerKey(),
|
||||
"storage_key": certRes.NamesKey(),
|
||||
"renewal": true,
|
||||
"remaining": timeLeft,
|
||||
"identifier": name,
|
||||
"issuer": issuerKey,
|
||||
"storage_path": StorageKeys.CertsSitePrefix(issuerKey, certKey),
|
||||
"private_key_path": StorageKeys.SitePrivateKey(issuerKey, certKey),
|
||||
"certificate_path": StorageKeys.SiteCert(issuerKey, certKey),
|
||||
"metadata_path": StorageKeys.SiteMeta(issuerKey, certKey),
|
||||
})
|
||||
|
||||
return nil
|
||||
@ -1000,6 +1057,9 @@ func (cfg *Config) getChallengeInfo(ctx context.Context, identifier string) (Cha
|
||||
// comparing the loaded value. If this fails, the provided
|
||||
// cfg.Storage mechanism should not be used.
|
||||
func (cfg *Config) checkStorage(ctx context.Context) error {
|
||||
if cfg.DisableStorageCheck {
|
||||
return nil
|
||||
}
|
||||
key := fmt.Sprintf("rw_test_%d", weakrand.Int())
|
||||
contents := make([]byte, 1024*10) // size sufficient for one or two ACME resources
|
||||
_, err := weakrand.Read(contents)
|
||||
|
||||
4
vendor/github.com/caddyserver/certmagic/crypto.go
generated
vendored
4
vendor/github.com/caddyserver/certmagic/crypto.go
generated
vendored
@ -22,7 +22,6 @@ import (
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
@ -35,6 +34,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/klauspost/cpuid/v2"
|
||||
"github.com/zeebo/blake3"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/net/idna"
|
||||
)
|
||||
@ -271,7 +271,7 @@ func (cfg *Config) loadCertResource(ctx context.Context, issuer Issuer, certName
|
||||
// which is the chain of DER-encoded bytes. It returns the
|
||||
// hex encoding of the hash.
|
||||
func hashCertificateChain(certChain [][]byte) string {
|
||||
h := sha256.New()
|
||||
h := blake3.New()
|
||||
for _, certInChain := range certChain {
|
||||
h.Write(certInChain)
|
||||
}
|
||||
|
||||
2
vendor/github.com/caddyserver/certmagic/dnsutil.go
generated
vendored
2
vendor/github.com/caddyserver/certmagic/dnsutil.go
generated
vendored
@ -237,7 +237,7 @@ func checkDNSPropagation(fqdn, value string, resolvers []string) (bool, error) {
|
||||
// checkAuthoritativeNss queries each of the given nameservers for the expected TXT record.
|
||||
func checkAuthoritativeNss(fqdn, value string, nameservers []string) (bool, error) {
|
||||
for _, ns := range nameservers {
|
||||
r, err := dnsQuery(fqdn, dns.TypeTXT, []string{net.JoinHostPort(ns, "53")}, false)
|
||||
r, err := dnsQuery(fqdn, dns.TypeTXT, []string{net.JoinHostPort(ns, "53")}, true)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
29
vendor/github.com/caddyserver/certmagic/filestorage.go
generated
vendored
29
vendor/github.com/caddyserver/certmagic/filestorage.go
generated
vendored
@ -154,6 +154,11 @@ func (s *FileStorage) Filename(key string) string {
|
||||
func (s *FileStorage) Lock(ctx context.Context, name string) error {
|
||||
filename := s.lockFilename(name)
|
||||
|
||||
// sometimes the lockfiles read as empty (size 0) - this is either a stale lock or it
|
||||
// is currently being written; we can retry a few times in this case, as it has been
|
||||
// shown to help (issue #232)
|
||||
var emptyCount int
|
||||
|
||||
for {
|
||||
err := createLockfile(filename)
|
||||
if err == nil {
|
||||
@ -173,11 +178,23 @@ func (s *FileStorage) Lock(ctx context.Context, name string) error {
|
||||
err2 := json.NewDecoder(f).Decode(&meta)
|
||||
f.Close()
|
||||
if errors.Is(err2, io.EOF) {
|
||||
// lockfile is empty or truncated; I *think* we can assume the previous
|
||||
// acquirer either crashed or had some sort of failure that caused them
|
||||
// to be unable to fully acquire or retain the lock, therefore we should
|
||||
// treat it as if the lockfile did not exist
|
||||
log.Printf("[INFO][%s] %s: Empty lockfile (%v) - likely previous process crashed or storage medium failure; treating as stale", s, filename, err2)
|
||||
emptyCount++
|
||||
if emptyCount < 8 {
|
||||
// wait for brief time and retry; could be that the file is in the process
|
||||
// of being written or updated (which involves truncating) - see issue #232
|
||||
select {
|
||||
case <-time.After(250 * time.Millisecond):
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
continue
|
||||
} else {
|
||||
// lockfile is empty or truncated multiple times; I *think* we can assume
|
||||
// the previous acquirer either crashed or had some sort of failure that
|
||||
// caused them to be unable to fully acquire or retain the lock, therefore
|
||||
// we should treat it as if the lockfile did not exist
|
||||
log.Printf("[INFO][%s] %s: Empty lockfile (%v) - likely previous process crashed or storage medium failure; treating as stale", s, filename, err2)
|
||||
}
|
||||
} else if err2 != nil {
|
||||
return fmt.Errorf("decoding lockfile contents: %w", err2)
|
||||
}
|
||||
@ -311,6 +328,8 @@ func updateLockfileFreshness(filename string) (bool, error) {
|
||||
}
|
||||
var meta lockMeta
|
||||
if err := json.Unmarshal(metaBytes, &meta); err != nil {
|
||||
// see issue #232: this can error if the file is empty,
|
||||
// which happens sometimes when the disk is REALLY slow
|
||||
return true, err
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user