Explorar o código

Initial commit

Alexey Kim %!s(int64=2) %!d(string=hai) anos
achega
aee75eaee5
Modificáronse 13 ficheiros con 3609 adicións e 0 borrados
  1. 124 0
      .gitignore
  2. 8 0
      .idea/.gitignore
  3. 8 0
      .idea/modules.xml
  4. 11 0
      .idea/products.iml
  5. 7 0
      .idea/sqldialects.xml
  6. 6 0
      .idea/vcs.xml
  7. 14 0
      .idea/webResources.xml
  8. 67 0
      go.mod
  9. 380 0
      go.sum
  10. 29 0
      graphql/gqlgen.yml
  11. 45 0
      graphql/resolver_impl.go
  12. 2901 0
      graphql/schema.graphql
  13. 9 0
      tools.go

+ 124 - 0
.gitignore

@@ -0,0 +1,124 @@
+resources
+graphql/generated/federation.go
+graphql/generated/generated.go
+graphql/generated/models_gen.go
+graphql/generated/resolver.go
+
+### JetBrains template
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn.  Uncomment if using
+# auto-import.
+# .idea/artifacts
+# .idea/compiler.xml
+# .idea/jarRepositories.xml
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+### Go template
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Dependency directories (remove the comment below to include it)
+vendor/
+
+### macOS template
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/products.iml" filepath="$PROJECT_DIR$/.idea/products.iml" />
+    </modules>
+  </component>
+</project>

+ 11 - 0
.idea/products.iml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+  <component name="Go" enabled="true" />
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/resources" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 7 - 0
.idea/sqldialects.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="SqlDialectMappings">
+    <file url="file://$PROJECT_DIR$/db/clickhouse.go" dialect="GenericSQL" />
+    <file url="PROJECT" dialect="ClickHouse" />
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

+ 14 - 0
.idea/webResources.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="WebResourcesPaths">
+    <contentEntries>
+      <entry url="file://$PROJECT_DIR$">
+        <entryData>
+          <resourceRoots>
+            <path value="file://$PROJECT_DIR$/resources" />
+          </resourceRoots>
+        </entryData>
+      </entry>
+    </contentEntries>
+  </component>
+</project>

+ 67 - 0
go.mod

@@ -0,0 +1,67 @@
+module gshopper.com/gshopify/products
+
+go 1.18
+
+require (
+	github.com/99designs/gqlgen v0.17.20
+	github.com/gshopify/service-wrapper v0.0.3-alpha
+	github.com/jellydator/ttlcache/v3 v3.0.0
+	github.com/mailru/dbr v3.0.0+incompatible
+	github.com/mailru/go-clickhouse v0.0.0-00010101000000-000000000000
+	github.com/microcosm-cc/bluemonday v1.0.21
+	github.com/spf13/pflag v1.0.5
+	github.com/vektah/gqlparser/v2 v2.5.1
+)
+
+require (
+	filippo.io/age v1.0.0 // indirect
+	filippo.io/edwards25519 v1.0.0-rc.1 // indirect
+	github.com/Nerzal/gocloak/v12 v12.0.0 // indirect
+	github.com/agnivade/levenshtein v1.1.1 // indirect
+	github.com/aymerick/douceur v0.2.0 // indirect
+	github.com/coreos/go-semver v0.3.0 // indirect
+	github.com/coreos/go-systemd/v22 v22.3.2 // indirect
+	github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
+	github.com/go-resty/resty/v2 v2.7.0 // indirect
+	github.com/go-sql-driver/mysql v1.6.0 // indirect
+	github.com/gogo/protobuf v1.3.2 // indirect
+	github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
+	github.com/golang/protobuf v1.5.2 // indirect
+	github.com/google/go-cmp v0.5.7 // indirect
+	github.com/google/uuid v1.2.0 // indirect
+	github.com/gorilla/css v1.0.0 // indirect
+	github.com/gorilla/mux v1.8.0 // indirect
+	github.com/gorilla/websocket v1.5.0 // indirect
+	github.com/hashicorp/golang-lru v0.5.4 // indirect
+	github.com/lib/pq v1.10.7 // indirect
+	github.com/mattn/go-sqlite3 v1.14.16 // indirect
+	github.com/mitchellh/mapstructure v1.3.1 // indirect
+	github.com/opentracing/opentracing-go v1.2.0 // indirect
+	github.com/pkg/errors v0.9.1 // indirect
+	github.com/russross/blackfriday/v2 v2.1.0 // indirect
+	github.com/segmentio/ksuid v1.0.4 // indirect
+	github.com/urfave/cli/v2 v2.8.1 // indirect
+	github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
+	go.etcd.io/etcd/api/v3 v3.5.5 // indirect
+	go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect
+	go.etcd.io/etcd/client/v3 v3.5.5 // indirect
+	go.uber.org/atomic v1.7.0 // indirect
+	go.uber.org/multierr v1.6.0 // indirect
+	go.uber.org/zap v1.17.0 // indirect
+	golang.org/x/crypto v0.0.0-20221012134737-56aed061732a // indirect
+	golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
+	golang.org/x/net v0.0.0-20221019024206-cb67ada4b0ad // indirect
+	golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
+	golang.org/x/sys v0.0.0-20221010170243-090e33056c14 // indirect
+	golang.org/x/text v0.3.7 // indirect
+	golang.org/x/tools v0.1.12 // indirect
+	google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect
+	google.golang.org/grpc v1.41.0 // indirect
+	google.golang.org/protobuf v1.28.0 // indirect
+	gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
+)
+
+replace github.com/gshopify/service-wrapper => ../service-wrapper
+
+replace github.com/mailru/go-clickhouse => ../../go-clickhouse

+ 380 - 0
go.sum

@@ -0,0 +1,380 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+filippo.io/age v1.0.0 h1:V6q14n0mqYU3qKFkZ6oOaF9oXneOviS3ubXsSVBRSzc=
+filippo.io/age v1.0.0/go.mod h1:PaX+Si/Sd5G8LgfCwldsSba3H1DDQZhIhFGkhbHaBq8=
+filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU=
+filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
+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/Nerzal/gocloak/v12 v12.0.0 h1:oOddyLpf+CxdGHFx5bABn4yCAtIGDwJkvJP4hFSospY=
+github.com/Nerzal/gocloak/v12 v12.0.0/go.mod h1:EAIc7luf3+dwMMHNWC9/X9vAA+KZJl5qfSWDIu7IlSs=
+github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
+github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
+github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
+github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
+github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
+github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
+github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
+github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
+github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
+github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
+github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
+github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI=
+github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
+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/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g=
+github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
+github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
+github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
+github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
+github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
+github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
+github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
+github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
+github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+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/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
+github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
+github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
+github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
+github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+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/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
+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/jellydator/ttlcache/v3 v3.0.0 h1:zmFhqrB/4sKiEiJHhtseJsNRE32IMVmJSs4++4gaQO4=
+github.com/jellydator/ttlcache/v3 v3.0.0/go.mod h1:WwTaEmcXQ3MTjOm4bsZoDFiCu/hMvNWLO1w67RXz6h4=
+github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
+github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
+github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM=
+github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
+github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc=
+github.com/mailru/dbr v3.0.0+incompatible h1:ULJ6NT9jQnDuu3U3WGqMNNGhBru2VvBCrona7Cm4uJQ=
+github.com/mailru/dbr v3.0.0+incompatible/go.mod h1:BkpdT7Xf+wNTWNio663n2Z7n2D+SxuOCfiXIEkL1bVM=
+github.com/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
+github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/microcosm-cc/bluemonday v1.0.21 h1:dNH3e4PSyE4vNX+KlRGHT5KrSvjeUkoNPwEORjffHJg=
+github.com/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM=
+github.com/mitchellh/mapstructure v1.3.1 h1:cCBH2gTD2K0OtLlv/Y5H01VQCqmlDxz30kS5Y5bqfLA=
+github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
+github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
+github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
+github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
+github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
+github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
+github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
+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/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=
+github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=
+github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
+github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+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 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
+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/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/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.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+go.etcd.io/etcd/api/v3 v3.5.5 h1:BX4JIbQ7hl7+jL+g+2j5UAr0o1bctCm6/Ct+ArBGkf0=
+go.etcd.io/etcd/api/v3 v3.5.5/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8=
+go.etcd.io/etcd/client/pkg/v3 v3.5.5 h1:9S0JUVvmrVl7wCF39iTQthdaaNIiAaQbmK75ogO6GU8=
+go.etcd.io/etcd/client/pkg/v3 v3.5.5/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ=
+go.etcd.io/etcd/client/v3 v3.5.5 h1:q++2WTJbUgpQu4B6hCuT7VkdwaTP7Qz6Daak3WzbrlI=
+go.etcd.io/etcd/client/v3 v3.5.5/go.mod h1:aApjR4WGlSumpnJ2kloS75h6aHUmAyaPLjHMxpc7E7c=
+go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
+go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
+go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
+go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
+go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
+go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U=
+go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20221012134737-56aed061732a h1:NmSIgad6KjE6VvHciPZuNRTKxGhlPfD6OA87W/PLkqg=
+golang.org/x/crypto v0.0.0-20221012134737-56aed061732a/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
+golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+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 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
+golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.0.0-20221019024206-cb67ada4b0ad h1:Zx6wVVDwwNJFWXNIvDi7o952w3/1ckSwYk/7eykRmjM=
+golang.org/x/net v0.0.0-20221019024206-cb67ada4b0ad/go.mod h1:RpDiru2p0u2F0lLpEoqnP2+7xs0ifAuOcJ442g6GU2s=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-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-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/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 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+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/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/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-20210603081109-ebe580a85c40/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-20211019181941-9d821ace8654/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-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.0.0-20221010170243-090e33056c14 h1:k5II8e6QD8mITdi+okbbmR/cIyEbeXLBhy5Ha4nevyc=
+golang.org/x/sys v0.0.0-20221010170243-090e33056c14/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 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
+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.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
+golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
+google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0=
+google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
+google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
+google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
+google.golang.org/grpc v1.41.0 h1:f+PlOh7QV4iIJkPrx5NQ7qaNGFQ3OTse67yaDHfju4E=
+google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+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 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
+google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 h1:FVCohIoYO7IJoDDVpV2pdq7SgrMH6wHnuTyrdrxJNoY=
+gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+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.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0/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=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=

+ 29 - 0
graphql/gqlgen.yml

@@ -0,0 +1,29 @@
+federation:
+  filename: generated/federation.go
+  package: generated
+  version: 2
+schema:
+  - schema.graphql
+exec:
+  filename: generated/generated.go
+model:
+  filename: generated/models_gen.go
+resolver:
+  filename: generated/resolver.go
+  type: Resolver
+autobind: []
+#omit_getters: true
+#omit_slice_element_pointers: true
+models:
+  DateTime:
+    model: github.com/gshopify/service-wrapper/scalar.DateTime
+  LanguageCode:
+    model: github.com/gshopify/service-wrapper/model.LanguageCode
+  CountryCode:
+    model: github.com/gshopify/service-wrapper/model.CountryCode
+  UnsignedInt64:
+    model: github.com/gshopify/service-wrapper/model.UInt
+  HTML:
+    model: github.com/gshopify/service-wrapper/scalar.Html
+  JSON:
+    model: github.com/gshopify/service-wrapper/scalar.Json

+ 45 - 0
graphql/resolver_impl.go

@@ -0,0 +1,45 @@
+package graphql
+
+import (
+	"context"
+	"gshopper.com/gshopify/products/db"
+	"gshopper.com/gshopify/products/graphql/generated"
+)
+
+type Resolver struct {
+	db db.Database
+}
+
+func New(ctx context.Context, debug bool) (*Resolver, error) {
+	r := Resolver{}
+
+	var err error
+	if r.db, err = db.New(ctx, debug); err != nil {
+		return nil, err
+	}
+
+	return &r, nil
+}
+
+// Query returns QueryResolver implementation.
+func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
+
+// Product returns ProductResolver implementation.
+func (r *Resolver) Product() generated.ProductResolver { return &productResolver{r} }
+
+// Collection returns CollectionResolver implementation.
+func (r *Resolver) Collection() generated.CollectionResolver { return &collectionResolver{r} }
+
+func (r *Resolver) Close() error {
+	var err error
+
+	if r.db != nil {
+		err = r.db.Close()
+	}
+
+	return err
+}
+
+type queryResolver struct{ *Resolver }
+type productResolver struct{ *Resolver }
+type collectionResolver struct{ *Resolver }

+ 2901 - 0
graphql/schema.graphql

@@ -0,0 +1,2901 @@
+directive @goTag(
+    key: String!
+    value: String
+) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION
+
+directive @goField(
+    forceResolver: Boolean,
+    name: String
+) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION
+
+scalar DateTime
+scalar UnsignedInt64
+scalar HTML
+
+# A JSON object.
+scalar JSON
+
+# A signed decimal number, which supports arbitrary precision and is serialized as a string.
+scalar Decimal
+
+# Represents an RFC 3986 and
+# RFC 3987-compliant URI string.
+#
+# For example, 'https://johns-apparel.myshopify.com' is a valid URL. It includes a scheme (https) and a host
+# (johns-apparel.myshopify.com).
+scalar URL
+
+union MetafieldParentResource = Collection | Product | ProductVariant
+
+union MetafieldReference = Collection | Product | ProductVariant
+
+union SellingPlanCheckoutChargeValue = MoneyV2 | SellingPlanCheckoutChargePercentageValue
+
+# Represents by how much the price of a variant associated with a selling plan is adjusted. Each variant can have up to two price adjustments.
+union SellingPlanPriceAdjustmentValue = SellingPlanFixedAmountPriceAdjustment | SellingPlanFixedPriceAdjustment | SellingPlanPercentagePriceAdjustment
+
+type Query {
+    collections(
+        after: String,
+        before: String,
+        first: Int,
+        last: Int,
+        query: String,
+        reverse: Boolean = false,
+        sortKey: CollectionSortKeys = ID
+    ): CollectionConnection!
+
+    product(handle: String id: ID): Product
+}
+
+# An auto-generated type for paginating through multiple Collections.
+type CollectionConnection {
+    # A list of edges.
+    edges: [CollectionEdge!]!
+
+    # A list of the nodes contained in CollectionEdge.
+    nodes: [Collection!]!
+
+    # Information to aid in pagination.
+    pageInfo: PageInfo!
+}
+
+type CollectionEdge {
+    # A cursor for use in pagination.
+    cursor: String!
+
+    # The item at the end of CollectionEdge.
+    node: Collection!
+}
+
+# A collection represents a grouping of products that a shop owner can create to organize them or make their shops easier to browse.
+type Collection implements HasMetafields&Node&OnlineStorePublishable {
+    # Stripped description of the collection, single line with HTML tags removed.
+    description(truncateAt: Int): String! @goField(forceResolver: true)
+
+    # The description of the collection, complete with HTML formatting.
+    descriptionHtml: HTML!
+
+    # A human-friendly unique string for the collection automatically generated from its title. Limit of 255 characters.
+    handle: String!
+
+    # A globally-unique identifier.
+    id: ID!
+
+    # Image associated with the collection.
+    image: Image
+
+    # Returns a metafield found by namespace and key.
+    metafield(key: String! namespace: String!): Metafield
+
+    # The metafields associated with the resource matching the supplied list of namespaces and keys.
+    metafields(identifiers: [HasMetafieldsIdentifier!]!): [Metafield]!
+
+    # The URL used for viewing the resource on the shop's Online Store. Returns null if the resource is currently not published to the Online Store sales channel.
+    onlineStoreUrl: URL
+
+    # List of products in the collection.
+    products(
+        after: String
+        before: String
+        filters: [ProductFilter!]
+        first: Int
+        last: Int
+        reverse: Boolean = false
+        sortKey: ProductCollectionSortKeys = COLLECTION_DEFAULT
+    ): ProductConnection! @goField(forceResolver: true)
+
+    # The collection's SEO information.
+    seo: SEO!
+
+    # The collection’s name. Limit of 255 characters.
+    title: String!
+
+    # The date and time when the collection was last modified.
+    updatedAt: DateTime!
+}
+
+# An object with an ID field to support global identification, in accordance with the
+# Relay specification.
+# This interface is used by the node
+# and nodes queries.
+interface Node {
+    # A globally-unique identifier.
+    id: ID!
+}
+
+# Represents information about the metafields associated to the specified resource.
+interface HasMetafields {
+    # Returns a metafield found by namespace and key.
+    metafield(namespace: String!key: String!): Metafield
+
+    # The metafields associated with the resource matching the supplied list of namespaces and keys.
+    metafields(identifiers: [HasMetafieldsIdentifier!]!): [Metafield]!
+}
+
+# Represents a resource that can be published to the Online Store sales channel.
+interface OnlineStorePublishable {
+    # The URL used for viewing the resource on the shop's Online Store. Returns `null` if the resource is currently not published to the Online Store sales channel.
+    onlineStoreUrl: URL
+}
+
+# Represents a media interface.
+interface Media {
+    # A word or phrase to share the nature or contents of a media.
+    alt: String
+
+    # The media content type.
+    mediaContentType: MediaContentType!
+
+    # The preview image for the media.
+    previewImage: Image
+}
+
+type ProductConnection {
+    # A list of edges.
+    edges: [ProductEdge!]!
+
+    # A list of available filters.
+    filters: [Filter!]!
+
+    # A list of the nodes contained in ProductEdge.
+    nodes: [Product!]!
+
+    # Information to aid in pagination.
+    pageInfo: PageInfo!
+}
+
+type ProductEdge {
+    # A cursor for use in pagination.
+    cursor: String!
+
+    # The item at the end of ProductEdge.
+    node: Product!
+}
+
+# A product represents an individual item for sale in a Shopify store. Products are often physical, but they don't have to be.
+# For example, a digital download (such as a movie, music or ebook file) also qualifies as a product, as do services (such as equipment rental, work for hire, customization of another product or an extended warranty).
+type Product implements HasMetafields&Node&OnlineStorePublishable {
+    # Indicates if at least one product variant is available for sale.
+    availableForSale: Boolean!
+
+    # List of collections a product belongs to.
+    collections(
+        after: String
+        before: String
+        first: Int
+        last: Int
+        reverse: Boolean = false
+    ): CollectionConnection! @goField(forceResolver: true)
+
+    # The compare at price of the product across all variants.
+    compareAtPriceRange: ProductPriceRange!
+
+    # The date and time when the product was created.
+    createdAt: DateTime!
+
+    # Stripped description of the product, single line with HTML tags removed.
+    description(truncateAt: Int): String! @goField(forceResolver: true)
+
+    # The description of the product, complete with HTML formatting.
+    descriptionHtml: HTML!
+
+    # The featured image for the product. This field is functionally equivalent to images(first: 1).
+    featuredImage: Image
+
+    # A human-friendly unique string for the Product automatically generated from its title. They are used by the Liquid templating language to refer to objects.
+    handle: String!
+
+    # A globally-unique identifier.
+    id: ID!
+
+    # List of images associated with the product.
+    images(
+        after: String
+        before: String
+        first: Int
+        last: Int
+        reverse: Boolean = false
+        sortKey: ProductImageSortKeys = POSITION
+    ): ImageConnection!
+
+    # Whether the product is a gift card.
+    isGiftCard: Boolean!
+
+    # The media associated with the product.
+    media(
+        after: String
+        before: String
+        first: Int
+        last: Int
+        reverse: Boolean = false
+        sortKey: ProductMediaSortKeys = POSITION
+    ): MediaConnection!
+
+    # Returns a metafield found by namespace and key.
+    metafield(key: String!namespace: String!): Metafield
+
+    # The metafields associated with the resource matching the supplied list of namespaces and keys.
+    metafields(identifiers: [HasMetafieldsIdentifier!]!): [Metafield]!
+
+    # The URL used for viewing the resource on the shop's Online Store. Returns `null` if the resource is currently not published to the Online Store sales channel.
+    onlineStoreUrl: URL
+
+    # List of product options.
+    options(first: Int): [ProductOption!]! @goField(forceResolver: true)
+
+    # The price range.
+    priceRange: ProductPriceRange!
+
+    # A categorization that a product can be tagged with, commonly used for filtering and searching.
+    productType: String!
+
+    # The date and time when the product was published to the channel.
+    publishedAt: DateTime!
+
+    # Whether the product can only be purchased with a selling plan.
+    requiresSellingPlan: Boolean!
+
+    # A list of a product's available selling plan groups. A selling plan group represents a selling method. For example, 'Subscribe and save' is a selling method where customers pay for goods or services per delivery. A selling plan group contains individual selling plans.
+    sellingPlanGroups(
+        first: Int
+        after: String
+        last: Int
+        before: String
+        reverse: Boolean = false
+    ): SellingPlanGroupConnection!
+
+    # The product's SEO information.
+    seo: SEO!
+
+    # A comma separated list of tags that have been added to the product. Additional access scope required for private apps: unauthenticated_read_product_tags.
+    tags: [String!]!
+
+    # The product’s title.
+    title: String!
+
+    # The total quantity of inventory in stock for this Product.
+    totalInventory: Int
+
+    # The date and time when the product was last modified.
+    # A product's `updatedAt` value can change for different reasons. For example, if an order
+    # is placed for a product that has inventory tracking set up, then the inventory adjustment
+    # is counted as an update.
+    updatedAt: DateTime!
+
+    # Find a product’s variant based on its selected options.
+    # This is useful for converting a user’s selection of product options into a single matching variant.
+    # If there is not a variant for the selected options, `null` will be returned.
+    variantBySelectedOptions(selectedOptions: [SelectedOptionInput!]!): ProductVariant
+
+    # List of the product’s variants.
+    variants(
+        first: Int
+        after: String
+        last: Int
+        before: String
+        reverse: Boolean = false
+        sortKey: ProductVariantSortKeys = POSITION
+    ): ProductVariantConnection! @goField(forceResolver: true)
+
+    # The product’s vendor name.
+    vendor: String!
+}
+
+# The price range of the product.
+type ProductPriceRange {
+    # The highest variant's price.
+    maxVariantPrice: MoneyV2!
+
+    # The lowest variant's price.
+    minVariantPrice: MoneyV2!
+}
+
+# Product property names like 'Size', 'Color', and 'Material' that the customers can select.
+# Variants are selected based on permutations of these options.
+# 255 characters limit each.
+type ProductOption implements Node {
+    # A globally-unique identifier.
+    id: ID!
+
+    # The product option’s name.
+    name: String!
+
+    # The corresponding value to the product option name.
+    values: [String!]!
+}
+
+# A monetary value with currency.
+type MoneyV2 {
+    # Decimal money amount.
+    amount: Decimal!
+
+    # Currency of the money.
+    currencyCode: CurrencyCode!
+}
+
+# A filter that is supported on the parent field.
+type Filter {
+    # A unique identifier.
+    id: String!
+
+    # A human-friendly string for this filter.
+    label: String!
+
+    # An enumeration that denotes the type of data this filter represents.
+    type: FilterType!
+}
+
+# SEO information.
+type SEO {
+    # The meta description.
+    description: String
+
+    # The SEO title.
+    title: String
+}
+
+# An auto-generated type for paginating through multiple Media.
+type MediaConnection {
+    # A list of edges.
+    edges: [MediaEdge!]!
+
+    # A list of the nodes contained in MediaEdge.
+    nodes: [Media!]!
+
+    # Information to aid in pagination.
+    pageInfo: PageInfo!
+}
+
+# An auto-generated type which holds one Media and a cursor during pagination.
+type MediaEdge {
+    # A cursor for use in pagination.
+    cursor: String!
+
+    # The item at the end of MediaEdge.
+    node: Media!
+}
+
+# Represents an image resource.
+type Image {
+    # A word or phrase to share the nature or contents of an image.
+    altText: String
+
+    # The original height of the image in pixels. Returns `null` if the image is not hosted by Shopify.
+    height: Int
+
+    # A unique identifier for the image.
+    id: ID
+
+    # The location of the image as a URL.
+    # If no transform options are specified, then the original image will be preserved including any pre-applied transforms.
+    # All transformation options are considered 'best-effort'. Any transformation that the original image type doesn't support will be ignored.
+    # If you need multiple variations of the same image, then you can use GraphQL aliases.
+    url(transform: ImageTransformInput): URL!
+
+    # The original width of the image in pixels. Returns null if the image is not hosted by Shopify.
+    width: Int
+
+    # The location of the original image as a URL.
+    #
+    # If there are any existing transformations in the original source URL, they will remain and not be stripped. Use url instead.
+    originalSrc: URL! @deprecated
+
+    # The location of the image as a URL. Use url instead.
+    src: URL! @deprecated
+
+    # The location of the transformed image as a URL.
+    # All transformation arguments are considered 'best-effort'. If they can be applied to an image, they will be. Otherwise any transformations which an image type does not support will be ignored. Use `url(transform:)` instead
+    transformedSrc: URL! @deprecated
+}
+
+# An auto-generated type for paginating through multiple Images.
+type ImageConnection {
+    # A list of edges.
+    edges: [ImageEdge!]!
+
+    # A list of the nodes contained in ImageEdge.
+    nodes: [Image!]!
+
+    # Information to aid in pagination.
+    pageInfo: PageInfo!
+}
+
+# An auto-generated type which holds one Image and a cursor during pagination.
+type ImageEdge {
+    # A cursor for use in pagination.
+    cursor: String!
+
+    # The item at the end of ImageEdge.
+    node: Image!
+}
+
+# An auto-generated type for paginating through multiple SellingPlanGroups.
+type SellingPlanGroupConnection {
+    # A list of edges.
+    edges: [SellingPlanGroupEdge!]!
+
+    # A list of the nodes contained in SellingPlanGroupEdge.
+    nodes: [SellingPlanGroup!]!
+
+    # Information to aid in pagination.
+    pageInfo: PageInfo!
+}
+
+# An auto-generated type which holds one SellingPlanGroup and a cursor during pagination.
+type SellingPlanGroupEdge {
+    # A cursor for use in pagination.
+    cursor: String!
+
+    # The item at the end of SellingPlanGroupEdge.
+    node: SellingPlanGroup!
+}
+
+# Represents a selling method. For example, 'Subscribe and save' is a selling method where customers pay for goods or services per delivery. A selling plan group contains individual selling plans.
+type SellingPlanGroup {
+    # A display friendly name for the app that created the selling plan group.
+    appName: String
+
+    # The name of the selling plan group.
+    name: String!
+
+    # Represents the selling plan options available in the drop-down list in the storefront. For example, 'Delivery every week' or 'Delivery every 2 weeks' specifies the delivery frequency options for the product.
+    options: [SellingPlanGroupOption!]!
+
+    # A list of selling plans in a selling plan group. A selling plan is a representation of how products and variants can be sold and purchased. For example, an individual selling plan could be '6 weeks of prepaid granola, delivered weekly'.
+    sellingPlans(
+        first: Int
+        after: String
+        last: Int
+        before: String
+        reverse: Boolean = false
+    ): SellingPlanConnection!
+}
+
+# Represents an option on a selling plan group that's available in the drop-down list in the storefront.
+#
+# Individual selling plans contribute their options to the associated selling plan group. For example, a selling plan group might have an option called option1: Delivery every. One selling plan in that group could contribute option1: 2 weeks with the pricing for that option, and another selling plan could contribute option1: 4 weeks, with different pricing.
+type SellingPlanGroupOption {
+    # The name of the option. For example, 'Delivery every'.
+    name: String!
+
+    # The values for the options specified by the selling plans in the selling plan group. For example, '1 week', '2 weeks', '3 weeks'.
+    values: [String!]!
+}
+
+# An auto-generated type for paginating through multiple SellingPlans.
+type SellingPlanConnection {
+    # A list of edges.
+    edges: [SellingPlanEdge!]!
+
+    # A list of the nodes contained in SellingPlanEdge.
+    nodes: [SellingPlan!]!
+
+    # Information to aid in pagination.
+    pageInfo: PageInfo!
+}
+
+# An auto-generated type which holds one SellingPlan and a cursor during pagination.
+type SellingPlanEdge {
+    # A cursor for use in pagination.
+    cursor: String!
+
+    # The item at the end of SellingPlanEdge.
+    node: SellingPlan!
+}
+
+# Represents how products and variants can be sold and purchased.
+type SellingPlan implements Node {
+    # The initial payment due for the purchase.
+    checkoutCharge: SellingPlanCheckoutCharge!
+
+    # The description of the selling plan.
+    description: String
+
+    # A globally-unique identifier.
+    id: ID!
+
+    # The name of the selling plan. For example, '6 weeks of prepaid granola, delivered weekly'.
+    name: String!
+
+    # The selling plan options available in the drop-down list in the storefront. For example, 'Delivery every week' or 'Delivery every 2 weeks' specifies the delivery frequency options for the product. Individual selling plans contribute their options to the associated selling plan group. For example, a selling plan group might have an option called option1: Delivery every. One selling plan in that group could contribute option1: 2 weeks with the pricing for that option, and another selling plan could contribute option1: 4 weeks, with different pricing.
+    options: [SellingPlanOption!]!
+
+    # The price adjustments that a selling plan makes when a variant is purchased with a selling plan.
+    priceAdjustments: [SellingPlanPriceAdjustment!]!
+
+    # Whether purchasing the selling plan will result in multiple deliveries.
+    recurringDeliveries: Boolean!
+}
+
+# The initial payment due for the purchase.
+type SellingPlanCheckoutCharge {
+    # The charge type for the checkout charge.
+    type: SellingPlanCheckoutChargeType!
+
+    # The charge value for the checkout charge.
+    value: SellingPlanCheckoutChargeValue!
+}
+
+# The percentage value of the price used for checkout charge.
+type SellingPlanCheckoutChargePercentageValue {
+    # The percentage value of the price used for checkout charge.
+    percentage: Float!
+}
+
+# An option provided by a Selling Plan.
+type SellingPlanOption {
+    # The name of the option (ie 'Delivery every').
+    name: String
+
+    # The value of the option (ie 'Month').
+    value: String
+}
+
+# Represents by how much the price of a variant associated with a selling plan is adjusted. Each variant can have up to two price adjustments. If a variant has multiple price adjustments, then the first price adjustment applies when the variant is initially purchased. The second price adjustment applies after a certain number of orders (specified by the `orderCount` field) are made. If a selling plan doesn't have any price adjustments, then the unadjusted price of the variant is the effective price.
+type SellingPlanPriceAdjustment {
+    # The type of price adjustment. An adjustment value can have one of three types: percentage, amount off, or a new price.
+    adjustmentValue: SellingPlanPriceAdjustmentValue!
+
+    # The number of orders that the price adjustment applies to. If the price adjustment always applies, then this field is `null`.
+    orderCount: Int
+}
+
+# A fixed amount that's deducted from the original variant price. For example, $10.00 off.
+type SellingPlanFixedAmountPriceAdjustment {
+    # The money value of the price adjustment.
+    adjustmentAmount: MoneyV2!
+}
+
+# A fixed price adjustment for a variant that's purchased with a selling plan.
+type SellingPlanFixedPriceAdjustment {
+    # A new price of the variant when it's purchased with the selling plan.
+    price: MoneyV2!
+}
+
+# A percentage amount that's deducted from the original variant price. For example, 10% off.
+type SellingPlanPercentagePriceAdjustment {
+    # The percentage value of the price adjustment.
+    adjustmentPercentage: Int!
+}
+
+# A product variant represents a different version of a product, such as differing sizes or differing colors.
+type ProductVariant implements Node&HasMetafields {
+    # Indicates if the product variant is available for sale.
+    availableForSale: Boolean!
+
+    # The barcode (for example, ISBN, UPC, or GTIN) associated with the variant.
+    barcode: String
+
+    # The compare at price of the variant. This can be used to mark a variant as on sale, when `compareAtPrice` is higher than `price`.
+    compareAtPrice: MoneyV2
+
+    # Whether a product is out of stock but still available for purchase (used for backorders).
+    currentlyNotInStock: Boolean!
+
+    # A globally-unique identifier.
+    id: ID!
+
+    # Image associated with the product variant. This field falls back to the product image if no image is available.
+    image: Image
+
+    # Returns a metafield found by namespace and key.
+    metafield(namespace: String!key: String!): Metafield
+
+    # The metafields associated with the resource matching the supplied list of namespaces and keys.
+    metafields(identifiers: [HasMetafieldsIdentifier!]!): [Metafield]!
+
+    # The product variant’s price.
+    price: MoneyV2!
+
+    # The product object that the product variant belongs to.
+    product: Product!
+
+    # The total sellable quantity of the variant for online sales channels.
+    quantityAvailable: Int
+
+    # Whether a customer needs to provide a shipping address when placing an order for the product variant.
+    requiresShipping: Boolean!
+
+    # List of product options applied to the variant.
+    selectedOptions: [SelectedOption!]!
+
+    # Represents an association between a variant and a selling plan. Selling plan allocations describe which selling plans are available for each variant, and what their impact is on pricing.
+    sellingPlanAllocations(
+        first: Int
+        after: String
+        last: Int
+        before: String
+        reverse: Boolean = false
+    ): SellingPlanAllocationConnection!
+
+    # The SKU (stock keeping unit) associated with the variant.
+    sku: String
+
+    # The in-store pickup availability of this variant by location.
+    storeAvailability(
+        first: Int
+        after: String
+        last: Int
+        before: String
+        reverse: Boolean = false
+    ): StoreAvailabilityConnection!
+
+    # The product variant’s title.
+    title: String!
+
+    # The unit price value for the variant based on the variant's measurement.
+    unitPrice: MoneyV2
+
+    # The unit price measurement for the variant.
+    unitPriceMeasurement: UnitPriceMeasurement
+
+    # The weight of the product variant in the unit system specified with `weight_unit`.
+    weight: Float
+
+    # Unit of measurement for weight.
+    weightUnit: WeightUnit!
+}
+
+# Properties used by customers to select a product variant.
+# Products can have multiple options, like different sizes or colors.
+type SelectedOption {
+    # The product option’s name.
+    name: String!
+
+    # The product option’s value.
+    value: String!
+}
+
+# An auto-generated type for paginating through multiple SellingPlanAllocations.
+type SellingPlanAllocationConnection {
+    # A list of edges.
+    edges: [SellingPlanAllocationEdge!]!
+
+    # A list of the nodes contained in SellingPlanAllocationEdge.
+    nodes: [SellingPlanAllocation!]!
+
+    # Information to aid in pagination.
+    pageInfo: PageInfo!
+}
+
+# An auto-generated type which holds one SellingPlanAllocation and a cursor during pagination.
+type SellingPlanAllocationEdge {
+    # A cursor for use in pagination.
+    cursor: String!
+
+    # The item at the end of SellingPlanAllocationEdge.
+    node: SellingPlanAllocation!
+}
+
+# Represents an association between a variant and a selling plan. Selling plan allocations describe the options offered for each variant, and the price of the variant when purchased with a selling plan.
+type SellingPlanAllocation {
+    # The checkout charge amount due for the purchase.
+    checkoutChargeAmount: MoneyV2!
+
+    # A list of price adjustments, with a maximum of two. When there are two, the first price adjustment goes into effect at the time of purchase, while the second one starts after a certain number of orders. A price adjustment represents how a selling plan affects pricing when a variant is purchased with a selling plan. Prices display in the customer's currency if the shop is configured for it.
+    priceAdjustments: [SellingPlanAllocationPriceAdjustment!]!
+
+    # The remaining balance charge amount due for the purchase.
+    remainingBalanceChargeAmount: MoneyV2!
+
+    # A representation of how products and variants can be sold and purchased. For example, an individual selling plan could be '6 weeks of prepaid granola, delivered weekly'.
+    sellingPlan: SellingPlan!
+}
+
+# The resulting prices for variants when they're purchased with a specific selling plan.
+type SellingPlanAllocationPriceAdjustment {
+    # The price of the variant when it's purchased without a selling plan for the same number of deliveries. For example, if a customer purchases 6 deliveries of $10.00 granola separately, then the price is 6 x $10.00 = $60.00.
+    compareAtPrice: MoneyV2!
+
+    # The effective price for a single delivery. For example, for a prepaid subscription plan that includes 6 deliveries at the price of $48.00, the per delivery price is $8.00.
+    perDeliveryPrice: MoneyV2!
+
+    # The price of the variant when it's purchased with a selling plan For example, for a prepaid subscription plan that includes 6 deliveries of $10.00 granola, where the customer gets 20% off, the price is 6 x $10.00 x 0.80 = $48.00.
+    price: MoneyV2!
+
+    # The resulting price per unit for the variant associated with the selling plan. If the variant isn't sold by quantity or measurement, then this field returns `null`.
+    unitPrice: MoneyV2
+}
+
+# An auto-generated type for paginating through multiple StoreAvailabilities.
+type StoreAvailabilityConnection {
+    # A list of edges.
+    edges: [StoreAvailabilityEdge!]!
+
+    # A list of the nodes contained in StoreAvailabilityEdge.
+    nodes: [StoreAvailability!]!
+
+    # Information to aid in pagination.
+    pageInfo: PageInfo!
+}
+
+# An auto-generated type which holds one StoreAvailability and a cursor during pagination.
+type StoreAvailabilityEdge {
+    # A cursor for use in pagination.
+    cursor: String!
+
+    # The item at the end of StoreAvailabilityEdge.
+    node: StoreAvailability!
+}
+
+# The availability of a product variant at a particular location.
+# Local pick-up must be enabled in the store's shipping settings, otherwise this will return an empty result.
+type StoreAvailability {
+    # Whether the product variant is in-stock at this location.
+    available: Boolean!
+
+    # The location where this product variant is stocked at.
+    location: Location!
+
+    # Returns the estimated amount of time it takes for pickup to be ready (Example: Usually ready in 24 hours).
+    pickUpTime: String!
+}
+
+# Represents a location where product inventory is held.
+type Location implements Node {
+    # The address of the location.
+    address: LocationAddress!
+
+    # A globally-unique identifier.
+    id: ID!
+
+    # The name of the location.
+    name: String!
+}
+
+# Represents the address of a location.
+type LocationAddress {
+    # The first line of the address for the location.
+    address1: String
+
+    # The second line of the address for the location.
+    address2: String
+
+    # The city of the location.
+    city: String
+
+    # The country of the location.
+    country: String
+
+    # The country code of the location.
+    countryCode: String
+
+    # A formatted version of the address for the location.
+    formatted: [String!]!
+
+    # The latitude coordinates of the location.
+    latitude: Float
+
+    # The longitude coordinates of the location.
+    longitude: Float
+
+    # The phone number of the location.
+    phone: String
+
+    # The province of the location.
+    province: String
+
+    # The code for the province, state, or district of the address of the location.
+    provinceCode: String
+
+    # The ZIP code of the location.
+    zip: String
+}
+
+# The measurement used to calculate a unit price for a product variant (e.g. $9.99 / 100ml).
+type UnitPriceMeasurement {
+    # The type of unit of measurement for the unit price measurement.
+    measuredType: UnitPriceMeasurementMeasuredType
+
+    # The quantity unit for the unit price measurement.
+    quantityUnit: UnitPriceMeasurementMeasuredUnit
+
+    # The quantity value for the unit price measurement.
+    quantityValue: Float!
+
+    # The reference unit for the unit price measurement.
+    referenceUnit: UnitPriceMeasurementMeasuredUnit
+
+    # The reference value for the unit price measurement.
+    referenceValue: Int!
+}
+
+# The available options for transforming an image.
+# All transformation options are considered best effort. Any transformation that the original image type doesn't support will be ignored.
+input ImageTransformInput {
+    # The region of the image to remain after cropping.
+    # Must be used in conjunction with the maxWidth and/or maxHeight fields, where the maxWidth and maxHeight aren't equal.
+    # The crop argument should coincide with the smaller value. A smaller maxWidth indicates a LEFT or RIGHT crop, while
+    # a smaller maxHeight indicates a TOP or BOTTOM crop. For example, { maxWidth: 5, maxHeight: 10, crop: LEFT } will result
+    # in an image with a width of 5 and height of 10, where the right side of the image is removed.
+    crop: CropRegion
+
+    # Image width in pixels between 1 and 5760.
+    maxWidth: Int
+
+    # Image height in pixels between 1 and 5760.
+    maxHeight: Int
+
+    # Image size multiplier for high-resolution retina displays. Must be within 1..3.
+    scale: Int = 1
+
+    # Convert the source image into the preferred content type.
+    # Supported conversions: .svg to .png, any file type to .jpg, and any file type to .webp.
+    preferredContentType: ImageContentType
+}
+
+# Identifies a metafield on an owner resource by namespace and key.
+input HasMetafieldsIdentifier {
+    # A container for a set of metafields.
+    namespace: String!
+
+    # The identifier for the metafield.
+    key: String!
+}
+
+input ProductFilter {
+    # Filter on if the product is available for sale.
+    available: Boolean
+
+    # A variant option to filter on.
+    variantOption: VariantOptionFilter
+
+    # The product type to filter on.
+    productType: String
+
+    # The product vendor to filter on.
+    productVendor: String
+
+    # A range of prices to filter with-in.
+    price: PriceRangeFilter
+
+    # A product metafield to filter on.
+    productMetafield: MetafieldFilter
+
+    # A variant metafield to filter on.
+    variantMetafield: MetafieldFilter
+}
+
+# A filter used to view a subset of products in a collection matching a specific price range.
+input PriceRangeFilter {
+    # The minimum price in the range. Defaults to zero.
+    min: Float = 0
+
+    # The maximum price in the range. Empty indicates no max price.
+    max: Float
+}
+
+input VariantOptionFilter {
+    # The name of the variant option to filter on.
+    name: String!
+
+    # The value of the variant option to filter on.
+    value: String!
+}
+
+# Specifies the input fields required for a selected option.
+input SelectedOptionInput {
+    # The product option’s name.
+    name: String!
+
+    # The product option’s value.
+    value: String!
+}
+
+# Metafields represent custom metadata attached to a resource.
+# Metafields can be sorted into namespaces and are comprised of keys, values, and value types.
+type Metafield implements Node {
+    # The date and time when the storefront metafield was created.
+    createdAt: DateTime!
+
+    # The description of a metafield.
+    description: String
+
+    # A globally-unique identifier.
+    id: ID!
+
+    # The key name for a metafield.
+    key: String!
+
+    # The namespace for a metafield.
+    namespace: String!
+
+    # The parent object that the metafield belongs to.
+    parentResource: MetafieldParentResource!
+
+    # Returns a reference object if the metafield definition's type is a resource reference.
+    reference: MetafieldReference
+
+    # A list of reference objects if the metafield's type is a resource reference list.
+    references(
+        first: Int
+        after: String
+        last: Int
+        before: String
+    ): MetafieldReferenceConnection
+
+    # The type name of the metafield. See the list of supported types.
+    type: String!
+
+    # The date and time when the storefront metafield was updated.
+    updatedAt: DateTime!
+
+    # The value of a metafield.
+    value: String!
+}
+
+# An auto-generated type for paginating through multiple MetafieldReferences.
+type MetafieldReferenceConnection {
+    # A list of edges.
+    edges: [MetafieldReferenceEdge!]!
+
+    # A list of the nodes contained in MetafieldReferenceEdge.
+    nodes: [MetafieldReference!]!
+
+    # Information to aid in pagination.
+    pageInfo: PageInfo!
+}
+
+# Returns information about pagination in a connection, in accordance with the Relay specification.
+type PageInfo {
+    # The cursor corresponding to the last node in edges.
+    endCursor: String
+
+    # Whether there are more pages to fetch following the current page.
+    hasNextPage: Boolean!
+
+    # Whether there are any pages prior to the current page.
+    hasPreviousPage: Boolean!
+
+    # The cursor corresponding to the first node in edges.
+    startCursor: String
+}
+
+type MetafieldReferenceEdge {
+    # A cursor for use in pagination.
+    cursor: String!
+
+    # The item at the end of MetafieldReferenceEdge.
+    node: MetafieldReference!
+}
+
+# A filter used to view a subset of products in a collection matching a specific metafield value.
+#
+# Only the following metafield types are currently supported:
+#
+# number_integer
+# number_decimal
+# single_line_text_field
+# boolean as of 2022-04.
+input MetafieldFilter {
+    # The namespace of the metafield to filter on.
+    namespace: String!
+
+    # The key of the metafield to filter on.
+    key: String!
+
+    # The value of the metafield.
+    value: String!
+}
+
+enum CollectionSortKeys {
+    # Sort by the `id` value.
+    ID,
+
+    # Sort by relevance to the search terms when the `query` parameter is specified on the connection. Don't use this sort key when no search query is specified.
+    RELEVANCE,
+
+    # Sort by the `title` value.
+    TITLE,
+
+    # Sort by the `updated_at` value.
+    UPDATED_AT
+}
+
+enum CollectionSortOrder {
+    # Alphabetically, in ascending order (A - Z).
+    ALPHA_ASC,
+
+    # Alphabetically, in descending order (Z - A).
+    ALPHA_DESC,
+
+    # By best-selling products.
+    BEST_SELLING,
+
+    # By date created, in ascending order (oldest - newest).
+    CREATED,
+
+    # By date created, in descending order (newest - oldest).
+    CREATED_DESC,
+
+    # In the order set manually by the merchant.
+    MANUAL,
+
+    # By price, in ascending order (lowest - highest).
+    PRICE_ASC,
+
+    # By price, in descending order (highest - lowest).
+    PRICE_DESC
+}
+
+enum ProductCollectionSortKeys {
+    # Sort by the `best-selling` value.
+    BEST_SELLING,
+
+    # Sort by the `collection-default` value.
+    COLLECTION_DEFAULT,
+
+    # Sort by the `created` value.
+    CREATED,
+
+    # Sort by the `id` value.
+    ID,
+
+    # Sort by the `manual` value.
+    MANUAL,
+
+    # Sort by the `price` value.
+    PRICE,
+
+    # Sort by relevance to the search terms when the `query` parameter is specified on the connection. Don't use this sort key when no search query is specified.
+    RELEVANCE,
+
+    # Sort by the `title` value.
+    TITLE
+}
+
+# List of supported image content types.
+enum ImageContentType {
+    # A PNG image.
+    PNG
+
+    # A JPG image.
+    JPG
+
+    # A WEBP image.
+    WEBP
+}
+
+# The part of the image that should remain after cropping.
+enum CropRegion {
+    # Keep the center of the image.
+    CENTER
+
+    # Keep the top of the image.
+    TOP
+
+    # Keep the bottom of the image.
+    BOTTOM
+
+    # Keep the left of the image.
+    LEFT
+
+    # Keep the right of the image.
+    RIGHT
+}
+
+# The type of data that the filter group represents.
+#
+# For more information, refer to [Filter products in a collection with the Storefront API]
+# (https://shopify.dev/custom-storefronts/products-collections/filter-products).
+enum FilterType {
+    # A list of selectable values.
+    LIST
+
+    # A range of prices.
+    PRICE_RANGE
+
+    # A boolean value.
+    BOOLEAN
+}
+
+# The three-letter currency codes that represent the world currencies used in stores. These include standard ISO 4217 codes, legacy codes, and non-standard codes.
+enum CurrencyCode {
+    # United Arab Emirates Dirham (AED).
+    AED
+
+    # Afghan Afghani (AFN).
+    AFN
+
+    # Albanian Lek (ALL).
+    ALL
+
+    # Armenian Dram (AMD).
+    AMD
+
+    # Netherlands Antillean Guilder.
+    ANG
+
+    # Angolan Kwanza (AOA).
+    AOA
+
+    # Argentine Pesos (ARS).
+    ARS
+
+    # Australian Dollars (AUD).
+    AUD
+
+    # Aruban Florin (AWG).
+    AWG
+
+    # Azerbaijani Manat (AZN).
+    AZN
+
+    # Bosnia and Herzegovina Convertible Mark (BAM).
+    BAM
+
+    # Barbadian Dollar (BBD).
+    BBD
+
+    # Bangladesh Taka (BDT).
+    BDT
+
+    # Bulgarian Lev (BGN).
+    BGN
+
+    # Bahraini Dinar (BHD).
+    BHD
+
+    # Burundian Franc (BIF).
+    BIF
+
+    # Bermudian Dollar (BMD).
+    BMD
+
+    # Brunei Dollar (BND).
+    BND
+
+    # Bolivian Boliviano (BOB).
+    BOB
+
+    # Brazilian Real (BRL).
+    BRL
+
+    # Bahamian Dollar (BSD).
+    BSD
+
+    # Bhutanese Ngultrum (BTN).
+    BTN
+
+    # Botswana Pula (BWP).
+    BWP
+
+    # Belarusian Ruble (BYN).
+    BYN
+
+    # Belize Dollar (BZD).
+    BZD
+
+    # Canadian Dollars (CAD).
+    CAD
+
+    # Congolese franc (CDF).
+    CDF
+
+    # Swiss Francs (CHF).
+    CHF
+
+    # Chilean Peso (CLP).
+    CLP
+
+    # Chinese Yuan Renminbi (CNY).
+    CNY
+
+    # Colombian Peso (COP).
+    COP
+
+    # Costa Rican Colones (CRC).
+    CRC
+
+    # Cape Verdean escudo (CVE).
+    CVE
+
+    # Czech Koruny (CZK).
+    CZK
+
+    # Djiboutian Franc (DJF).
+    DJF
+
+    # Danish Kroner (DKK).
+    DKK
+
+    # Dominican Peso (DOP).
+    DOP
+
+    # Algerian Dinar (DZD).
+    DZD
+
+    # Egyptian Pound (EGP).
+    EGP
+
+    # Eritrean Nakfa (ERN).
+    ERN
+
+    # Ethiopian Birr (ETB).
+    ETB
+
+    # Euro (EUR).
+    EUR
+
+    # Fijian Dollars (FJD).
+    FJD
+
+    # Falkland Islands Pounds (FKP).
+    FKP
+
+    # United Kingdom Pounds (GBP).
+    GBP
+
+    # Georgian Lari (GEL).
+    GEL
+
+    # Ghanaian Cedi (GHS).
+    GHS
+
+    # Gibraltar Pounds (GIP).
+    GIP
+
+    # Gambian Dalasi (GMD).
+    GMD
+
+    # Guinean Franc (GNF).
+    GNF
+
+    # Guatemalan Quetzal (GTQ).
+    GTQ
+
+    # Guyanese Dollar (GYD).
+    GYD
+
+    # Hong Kong Dollars (HKD).
+    HKD
+
+    # Honduran Lempira (HNL).
+    HNL
+
+    # Croatian Kuna (HRK).
+    HRK
+
+    # Haitian Gourde (HTG).
+    HTG
+
+    # Hungarian Forint (HUF).
+    HUF
+
+    # Indonesian Rupiah (IDR).
+    IDR
+
+    # Israeli New Shekel (NIS).
+    ILS
+
+    # Indian Rupees (INR).
+    INR
+
+    # Iraqi Dinar (IQD).
+    IQD
+
+    # Iranian Rial (IRR).
+    IRR
+
+    # Icelandic Kronur (ISK).
+    ISK
+
+    # Jersey Pound.
+    JEP
+
+    # Jamaican Dollars (JMD).
+    JMD
+
+    # Jordanian Dinar (JOD).
+    JOD
+
+    # Japanese Yen (JPY).
+    JPY
+
+    # Kenyan Shilling (KES).
+    KES
+
+    # Kyrgyzstani Som (KGS).
+    KGS
+
+    # Cambodian Riel.
+    KHR
+
+    # Kiribati Dollar (KID).
+    KID
+
+    # Comorian Franc (KMF).
+    KMF
+
+    # South Korean Won (KRW).
+    KRW
+
+    # Kuwaiti Dinar (KWD).
+    KWD
+
+    # Cayman Dollars (KYD).
+    KYD
+
+    # Kazakhstani Tenge (KZT).
+    KZT
+
+    # Laotian Kip (LAK).
+    LAK
+
+    # Lebanese Pounds (LBP).
+    LBP
+
+    # Sri Lankan Rupees (LKR).
+    LKR
+
+    # Liberian Dollar (LRD).
+    LRD
+
+    # Lesotho Loti (LSL).
+    LSL
+
+    # Lithuanian Litai (LTL).
+    LTL
+
+    # Latvian Lati (LVL).
+    LVL
+
+    # Libyan Dinar (LYD).
+    LYD
+
+    # Moroccan Dirham.
+    MAD
+
+    # Moldovan Leu (MDL).
+    MDL
+
+    # Malagasy Ariary (MGA).
+    MGA
+
+    # Macedonia Denar (MKD).
+    MKD
+
+    # Burmese Kyat (MMK).
+    MMK
+
+    # Mongolian Tugrik.
+    MNT
+
+    # Macanese Pataca (MOP).
+    MOP
+
+    # Mauritanian Ouguiya (MRU).
+    MRU
+
+    # Mauritian Rupee (MUR).
+    MUR
+
+    # Maldivian Rufiyaa (MVR).
+    MVR
+
+    # Malawian Kwacha (MWK).
+    MWK
+
+    # Mexican Pesos (MXN).
+    MXN
+
+    # Malaysian Ringgits (MYR).
+    MYR
+
+    # Mozambican Metical.
+    MZN
+
+    # Namibian Dollar.
+    NAD
+
+    # Nigerian Naira (NGN).
+    NGN
+
+    # Nicaraguan Córdoba (NIO).
+    NIO
+
+    # Norwegian Kroner (NOK).
+    NOK
+
+    # Nepalese Rupee (NPR).
+    NPR
+
+    # New Zealand Dollars (NZD).
+    NZD
+
+    # Omani Rial (OMR).
+    OMR
+
+    # Panamian Balboa (PAB).
+    PAB
+
+    # Peruvian Nuevo Sol (PEN).
+    PEN
+
+    # Papua New Guinean Kina (PGK).
+    PGK
+
+    # Philippine Peso (PHP).
+    PHP
+
+    # Pakistani Rupee (PKR).
+    PKR
+
+    # Polish Zlotych (PLN).
+    PLN
+
+    # Paraguayan Guarani (PYG).
+    PYG
+
+    # Qatari Rial (QAR).
+    QAR
+
+    # Romanian Lei (RON).
+    RON
+
+    # Serbian dinar (RSD).
+    RSD
+
+    # Russian Rubles (RUB).
+    RUB
+
+    # Rwandan Franc (RWF).
+    RWF
+
+    # Saudi Riyal (SAR).
+    SAR
+
+    # Solomon Islands Dollar (SBD).
+    SBD
+
+    # Seychellois Rupee (SCR).
+    SCR
+
+    # Sudanese Pound (SDG).
+    SDG
+
+    # Swedish Kronor (SEK).
+    SEK
+
+    # Singapore Dollars (SGD).
+    SGD
+
+    # Saint Helena Pounds (SHP).
+    SHP
+
+    # Sierra Leonean Leone (SLL).
+    SLL
+
+    # Somali Shilling (SOS).
+    SOS
+
+    # Surinamese Dollar (SRD).
+    SRD
+
+    # South Sudanese Pound (SSP).
+    SSP
+
+    # Sao Tome And Principe Dobra (STN).
+    STN
+
+    # Syrian Pound (SYP).
+    SYP
+
+    # Swazi Lilangeni (SZL).
+    SZL
+
+    # Thai baht (THB).
+    THB
+
+    # Tajikistani Somoni (TJS).
+    TJS
+
+    # Turkmenistani Manat (TMT).
+    TMT
+
+    # Tunisian Dinar (TND).
+    TND
+
+    # Tongan Pa'anga (TOP).
+    TOP
+
+    # Turkish Lira (TRY).
+    TRY
+
+    # Trinidad and Tobago Dollars (TTD).
+    TTD
+
+    # Taiwan Dollars (TWD).
+    TWD
+
+    # Tanzanian Shilling (TZS).
+    TZS
+
+    # Ukrainian Hryvnia (UAH).
+    UAH
+
+    # Ugandan Shilling (UGX).
+    UGX
+
+    # United States Dollars (USD).
+    USD
+
+    # Uruguayan Pesos (UYU).
+    UYU
+
+    # Uzbekistan som (UZS).
+    UZS
+
+    # Venezuelan Bolivares (VED).
+    VED
+
+    # Venezuelan Bolivares (VES).
+    VES
+
+    # Vietnamese đồng (VND).
+    VND
+
+    # Vanuatu Vatu (VUV).
+    VUV
+
+    # Samoan Tala (WST).
+    WST
+
+    # Central African CFA Franc (XAF).
+    XAF
+
+    # East Caribbean Dollar (XCD).
+    XCD
+
+    # West African CFA franc (XOF).
+    XOF
+
+    # CFP Franc (XPF).
+    XPF
+
+    # Unrecognized currency.
+    XXX
+
+    # Yemeni Rial (YER).
+    YER
+
+    # South African Rand (ZAR).
+    ZAR
+
+    # Zambian Kwacha (ZMW).
+    ZMW
+
+    # Belarusian Ruble (BYR).
+    BYR @deprecated
+}
+
+type ProductVariantConnection {
+    # A list of edges.
+    edges: [ProductVariantEdge!]!
+
+    # A list of the nodes contained in ProductVariantEdge.
+    nodes: [ProductVariant!]!
+
+    # Information to aid in pagination.
+    pageInfo: PageInfo!
+}
+
+type ProductVariantEdge {
+    # A cursor for use in pagination.
+    cursor: String!
+
+    # The item at the end of ProductVariantEdge.
+    node: ProductVariant!
+}
+
+# The set of valid sort keys for the ProductVariant query.
+enum ProductVariantSortKeys {
+    # Sort by the `title` value.
+    TITLE
+
+    # Sort by the `sku` value.
+    SKU
+
+    # Sort by the `position` value.
+    POSITION
+
+    # Sort by the `id` value.
+    ID
+
+    # Sort by relevance to the search terms when the `query` parameter is specified on the connection.
+    # Don't use this sort key when no search query is specified.
+    RELEVANCE
+}
+
+# The set of valid sort keys for the ProductImage query.
+enum ProductImageSortKeys {
+    # Sort by the `created_at` value.
+    CREATED_AT
+
+    # Sort by the `id` value.
+    ID
+
+    # Sort by the `position` value.
+    POSITION
+
+    # Sort by relevance to the search terms when the `query` parameter is specified on the connection. Don't use this sort key when no search query is specified.
+    RELEVANCE
+}
+
+# The set of valid sort keys for the ProductMedia query.
+enum ProductMediaSortKeys {
+    # Sort by the `id` value.
+    ID
+
+    # Sort by the `position` value.
+    POSITION
+
+    # Sort by relevance to the search terms when the `query` parameter is specified on the connection. Don't use this sort key when no search query is specified.
+    RELEVANCE
+}
+
+# The possible content types for a media object.
+enum MediaContentType {
+    # An externally hosted video.
+    EXTERNAL_VIDEO
+
+    # A Shopify hosted image.
+    IMAGE
+
+    # A 3d model.
+    MODEL_3D
+
+    # A Shopify hosted video.
+    VIDEO
+}
+
+# The checkout charge when the full amount isn't charged at checkout.
+enum SellingPlanCheckoutChargeType {
+    # The checkout charge is a percentage of the product or variant price.
+    PERCENTAGE
+
+    # The checkout charge is a fixed price amount.
+    PRICE
+}
+
+# Units of measurement for weight.
+enum WeightUnit {
+    # 1 kilogram equals 1000 grams.
+    KILOGRAMS
+
+    # Metric system unit of mass.
+    GRAMS
+
+    # 1 pound equals 16 ounces.
+    POUNDS
+
+    # Imperial system unit of mass.
+    OUNCES
+}
+
+# The accepted types of unit of measurement.
+enum UnitPriceMeasurementMeasuredType {
+    # Unit of measurements representing areas.
+    AREA
+
+    # Unit of measurements representing lengths.
+    LENGTH
+
+    # Unit of measurements representing volumes.
+    VOLUME
+
+    # Unit of measurements representing weights.
+    WEIGHT
+}
+
+# The valid units of measurement for a unit price measurement.
+enum UnitPriceMeasurementMeasuredUnit {
+    # 100 centiliters equals 1 liter.
+    CL
+
+    # 100 centimeters equals 1 meter.
+    CM
+
+    # Metric system unit of weight.
+    G
+
+    # 1 kilogram equals 1000 grams.
+    KG
+
+    # Metric system unit of volume.
+    L
+
+    # Metric system unit of length.
+    M
+
+    # Metric system unit of area.
+    M2
+
+    # 1 cubic meter equals 1000 liters.
+    M3
+
+    # 1000 milligrams equals 1 gram.
+    MG
+
+    # 1000 milliliters equals 1 liter.
+    ML
+
+    # 1000 millimeters equals 1 meter.
+    MM
+}
+
+# ISO 639-1 language codes supported by Shopify.
+enum LanguageCode {
+    # Afrikaans
+    AF
+
+    # Akan
+    AK
+
+    # Amharic
+    AM
+
+    # Arabic
+    AR
+
+    # Assamese
+    AS
+
+    # Azerbaijani
+    AZ
+
+    # Belarusian
+    BE
+
+    # Bulgarian
+    BG
+
+    # Bambara
+    BM
+
+    # Bangla
+    BN
+
+    # Tibetan
+    BO
+
+    # Breton
+    BR
+
+    # Bosnian
+    BS
+
+    # Catalan
+    CA
+
+    # Chechen
+    CE
+
+    # Czech
+    CS
+
+    # Church Slavic
+    CU
+
+    # Welsh
+    CY
+
+    # Danish
+    DA
+
+    # German
+    DE
+
+    # Dzongkha
+    DZ
+
+    # Ewe
+    EE
+
+    # Greek
+    EL
+
+    # English
+    EN
+
+    # Esperanto
+    EO
+
+    # Spanish
+    ES
+
+    # Estonian
+    ET
+
+    # Basque
+    EU
+
+    # Persian
+    FA
+
+    # Fulah
+    FF
+
+    # Finnish
+    FI
+
+    # Faroese
+    FO
+
+    # French
+    FR
+
+    # Western Frisian
+    FY
+
+    # Irish
+    GA
+
+    # Scottish Gaelic
+    GD
+
+    # Galician
+    GL
+
+    # Gujarati
+    GU
+
+    # Manx
+    GV
+
+    # Hausa
+    HA
+
+    # Hebrew
+    HE
+
+    # Hindi
+    HI
+
+    # Croatian
+    HR
+
+    # Hungarian
+    HU
+
+    # Armenian
+    HY
+
+    # Interlingua
+    IA
+
+    # Indonesian
+    ID
+
+    # Igbo
+    IG
+
+    # Sichuan Yi
+    II
+
+    # Icelandic
+    IS
+
+    # Italian
+    IT
+
+    # Japanese
+    JA
+
+    # Javanese
+    JV
+
+    # Georgian.
+    KA
+
+    # Kikuyu.
+    KI
+
+    # Kazakh.
+    KK
+
+    # Kalaallisut.
+    KL
+
+    # Khmer.
+    KM
+
+    # Kannada.
+    KN
+
+    # Korean.
+    KO
+
+    # Kashmiri.
+    KS
+
+    # Kurdish.
+    KU
+
+    # Cornish.
+    KW
+
+    # Kyrgyz.
+    KY
+
+    # Luxembourgish.
+    LB
+
+    # Ganda.
+    LG
+
+    # Lingala.
+    LN
+
+    # Lao.
+    LO
+
+    # Lithuanian.
+    LT
+
+    # Luba-Katanga.
+    LU
+
+    # Latvian.
+    LV
+
+    # Malagasy.
+    MG
+
+    # Māori.
+    MI
+
+    # Macedonian.
+    MK
+
+    # Malayalam.
+    ML
+
+    # Mongolian.
+    MN
+
+    # Marathi.
+    MR
+
+    # Malay.
+    MS
+
+    # Maltese.
+    MT
+
+    # Burmese.
+    MY
+
+    # Norwegian (Bokmål).
+    NB
+
+    # North Ndebele.
+    ND
+
+    # Nepali.
+    NE
+
+    # Dutch.
+    NL
+
+    # Norwegian Nynorsk.
+    NN
+
+    # Norwegian.
+    NO
+
+    # Oromo.
+    OM
+
+    # Odia.
+    OR
+
+    # Ossetic.
+    OS
+
+    # Punjabi.
+    PA
+
+    # Polish.
+    PL
+
+    # Pashto.
+    PS
+
+    # Portuguese (Brazil).
+    PT_BR
+
+    # Portuguese (Portugal).
+    PT_PT
+
+    QU
+    # Quechua.
+
+    # Romansh.
+    RM
+
+    # Rundi.
+    RN
+
+    # Romanian.
+    RO
+
+    # Russian.
+    RU
+
+    # Kinyarwanda.
+    RW
+
+    # Sindhi.
+    SD
+
+    # Northern Sami.
+    SE
+
+    # Sango.
+    SG
+
+    # Sinhala.
+    SI
+
+    # Slovak.
+    SK
+
+    # Slovenian.
+    SL
+
+    # Shona.
+    SN
+
+    # Somali.
+    SO
+
+    # Albanian.
+    SQ
+
+    # Serbian.
+    SR
+
+    # Sundanese.
+    SU
+
+    # Swedish.
+    SV
+
+    # Swahili.
+    SW
+
+    # Tamil.
+    TA
+
+    # Telugu.
+    TE
+
+    # Tajik.
+    TG
+
+    # Thai.
+    TH
+
+    # Tigrinya.
+    TI
+
+    # Turkmen.
+    TK
+
+    # Tongan.
+    TO
+
+    # Turkish.
+    TR
+
+    # Tatar.
+    TT
+
+    # Uyghur.
+    UG
+
+    # Ukrainian.
+    UK
+
+    # Urdu.
+    UR
+
+    # Uzbek.
+    UZ
+
+    # Vietnamese.
+    VI
+
+    # Wolof.
+    WO
+
+    # Xhosa.
+    XH
+
+    # Yiddish.
+    YI
+
+    # Yoruba.
+    YO
+
+    # Chinese (Simplified).
+    ZH_CN
+
+    # Chinese (Traditional).
+    ZH_TW
+
+    # Zulu.
+    ZU
+
+    # Chinese.
+    ZH
+
+    # Portuguese.
+    PT
+
+    # Volapük.
+    VO
+}
+
+# The code designating a country/region, which generally follows ISO 3166-1 alpha-2 guidelines.
+# If a territory doesn't have a country code value in the CountryCode enum, then it might be considered a subdivision
+# of another country. For example, the territories associated with Spain are represented by the country code ES,
+# and the territories associated with the United States of America are represented by the country code US.
+enum CountryCode {
+    # Afghanistan.
+    AF
+
+    # Åland Islands.
+    AX
+
+    # Albania.
+    AL
+
+    # Algeria.
+    DZ
+
+    # Andorra.
+    AD
+
+    # Angola.
+    AO
+
+    # Anguilla.
+    AI
+
+    # Antigua & Barbuda.
+    AG
+
+    # Argentina.
+    AR
+
+    # Armenia.
+    AM
+
+    # Aruba.
+    AW
+
+    # Ascension Island.
+    AC
+
+    # Australia.
+    AU
+
+    # Austria.
+    AT
+
+    # Azerbaijan.
+    AZ
+
+    # Bahamas.
+    BS
+
+    # Bahrain.
+    BH
+
+    # Bangladesh.
+    BD
+
+    # Barbados.
+    BB
+
+    # Belarus.
+    BY
+
+    # Belgium.
+    BE
+
+    # Belize.
+    BZ
+
+    # Benin.
+    BJ
+
+    # Bermuda.
+    BM
+
+    # Bhutan.
+    BT
+
+    # Bolivia.
+    BO
+
+    # Bosnia & Herzegovina.
+    BA
+
+    # Botswana.
+    BW
+
+    # Bouvet Island.
+    BV
+
+    # Brazil.
+    BR
+
+    # British Indian Ocean Territory.
+    IO
+
+    # Brunei.
+    BN
+
+    # Bulgaria.
+    BG
+
+    # Burkina Faso.
+    BF
+
+    # Burundi.
+    BI
+
+    # Cambodia.
+    KH
+
+    # Canada.
+    CA
+
+    # Cape Verde.
+    CV
+
+    # Caribbean Netherlands.
+    BQ
+
+    # Cayman Islands.
+    KY
+
+    # Central African Republic.
+    CF
+
+    # Chad.
+    TD
+
+    # Chile.
+    CL
+
+    # China.
+    CN
+
+    # Christmas Island.
+    CX
+
+    # Cocos (Keeling) Islands.
+    CC
+
+    # Colombia.
+    CO
+
+    # Comoros.
+    KM
+
+    # Congo - Brazzaville.
+    CG
+
+    # Congo - Kinshasa.
+    CD
+
+    # Cook Islands.
+    CK
+
+    # Costa Rica.
+    CR
+
+    # Croatia.
+    HR
+
+    # Cuba.
+    CU
+
+    # Curaçao.
+    CW
+
+    # Cyprus.
+    CY
+
+    # Czechia.
+    CZ
+
+    # Côte d’Ivoire.
+    CI
+
+    # Denmark.
+    DK
+
+    # Djibouti.
+    DJ
+
+    # Dominica.
+    DM
+
+    # Dominican Republic.
+    DO
+
+    # Ecuador.
+    EC
+
+    # Egypt.
+    EG
+
+    # El Salvador.
+    SV
+
+    # Equatorial Guinea.
+    GQ
+
+    # Eritrea.
+    ER
+
+    # Estonia.
+    EE
+
+    # Eswatini.
+    SZ
+
+    # Ethiopia.
+    ET
+
+    # Falkland Islands.
+    FK
+
+    # Faroe Islands.
+    FO
+
+    # Fiji.
+    FJ
+
+    # Finland.
+    FI
+
+    # France.
+    FR
+
+    # French Guiana.
+    GF
+
+    # French Polynesia.
+    PF
+
+    # French Southern Territories.
+    TF
+
+    # Gabon.
+    GA
+
+    # Gambia.
+    GM
+
+    # Georgia.
+    GE
+
+    # Germany.
+    DE
+
+    # Ghana.
+    GH
+
+    # Gibraltar.
+    GI
+
+    # Greece.
+    GR
+
+    # Greenland.
+    GL
+
+    # Grenada.
+    GD
+
+    # Guadeloupe.
+    GP
+
+    # Guatemala.
+    GT
+
+    # Guernsey.
+    GG
+
+    # Guinea.
+    GN
+
+    # Guinea-Bissau.
+    GW
+
+    # Guyana.
+    GY
+
+    # Haiti.
+    HT
+
+    # Heard & McDonald Islands.
+    HM
+
+    # Vatican City.
+    VA
+
+    # Honduras.
+    HN
+
+    # Hong Kong SAR.
+    HK
+
+    # Hungary.
+    HU
+
+    # Iceland.
+    IS
+
+    # India.
+    IN
+
+    # Indonesia.
+    ID
+
+    # Iran.
+    IR
+
+    # Iraq.
+    IQ
+
+    # Ireland.
+    IE
+
+    # Isle of Man.
+    IM
+
+    # Israel.
+    IL
+
+    # Italy.
+    IT
+
+    # Jamaica.
+    JM
+
+    # Japan.
+    JP
+
+    # Jersey.
+    JE
+
+    # Jordan.
+    JO
+
+    # Kazakhstan.
+    KZ
+
+    # Kenya.
+    KE
+
+    # Kiribati.
+    KI
+
+    # North Korea.
+    KP
+
+    # Kosovo.
+    XK
+
+    # Kuwait.
+    KW
+
+    # Kyrgyzstan.
+    KG
+
+    # Laos.
+    LA
+
+    # Latvia.
+    LV
+
+    # Lebanon.
+    LB
+
+    # Lesotho.
+    LS
+
+    # Liberia.
+    LR
+
+    # Libya.
+    LY
+
+    # Liechtenstein.
+    LI
+
+    # Lithuania.
+    LT
+
+    # Luxembourg.
+    LU
+
+    # Macao SAR.
+    MO
+
+    # Madagascar.
+    MG
+
+    # Malawi.
+    MW
+
+    # Malaysia.
+    MY
+
+    # Maldives.
+    MV
+
+    # Mali.
+    ML
+
+    # Malta.
+    MT
+
+    # Martinique.
+    MQ
+
+    # Mauritania.
+    MR
+
+    # Mauritius.
+    MU
+
+    # Mayotte.
+    YT
+
+    # Mexico.
+    MX
+
+    # Moldova.
+    MD
+
+    # Monaco.
+    MC
+
+    # Mongolia.
+    MN
+
+    # Montenegro.
+    ME
+
+    # Montserrat.
+    MS
+
+    # Morocco.
+    MA
+
+    # Mozambique.
+    MZ
+
+    # Myanmar (Burma).
+    MM
+
+    # Namibia.
+    NA
+
+    # Nauru.
+    NR
+
+    # Nepal.
+    NP
+
+    # Netherlands.
+    NL
+
+    # Netherlands Antilles.
+    AN
+
+    # New Caledonia.
+    NC
+
+    # New Zealand.
+    NZ
+
+    # Nicaragua.
+    NI
+
+    # Niger.
+    NE
+
+    # Nigeria.
+    NG
+
+    # Niue.
+    NU
+
+    # Norfolk Island.
+    NF
+
+    # North Macedonia.
+    MK
+
+    # Norway.
+    NO
+
+    # Oman.
+    OM
+
+    # Pakistan.
+    PK
+
+    # Palestinian Territories.
+    PS
+
+    # Panama.
+    PA
+
+    # Papua New Guinea.
+    PG
+
+    # Paraguay.
+    PY
+
+    # Peru.
+    PE
+
+    # Philippines.
+    PH
+
+    # Pitcairn Islands.
+    PN
+
+    # Poland.
+    PL
+
+    # Portugal.
+    PT
+
+    # Qatar.
+    QA
+
+    # Cameroon.
+    CM
+
+    # Réunion.
+    RE
+
+    # Romania.
+    RO
+
+    # Russia.
+    RU
+
+    # Rwanda.
+    RW
+
+    # St. Barthélemy.
+    BL
+
+    # St. Helena.
+    SH
+
+    # St. Kitts & Nevis.
+    KN
+
+    # St. Lucia.
+    LC
+
+    # St. Martin.
+    MF
+
+    # St. Pierre & Miquelon.
+    PM
+
+    # Samoa.
+    WS
+
+    # San Marino.
+    SM
+
+    # São Tomé & Príncipe.
+    ST
+
+    # Saudi Arabia.
+    SA
+
+    # Senegal.
+    SN
+
+    # Serbia.
+    RS
+
+    # Seychelles.
+    SC
+
+    # Sierra Leone.
+    SL
+
+    # Singapore.
+    SG
+
+    # Sint Maarten.
+    SX
+
+    # Slovakia.
+    SK
+
+    # Slovenia.
+    SI
+
+    # Solomon Islands.
+    SB
+
+    # Somalia.
+    SO
+
+    # South Africa.
+    ZA
+
+    # South Georgia & South Sandwich Islands.
+    GS
+
+    # South Korea.
+    KR
+
+    # South Sudan.
+    SS
+
+    # Spain.
+    ES
+
+    # Sri Lanka.
+    LK
+
+    # St. Vincent & Grenadines.
+    VC
+
+    # Sudan.
+    SD
+
+    # Suriname.
+    SR
+
+    # Svalbard & Jan Mayen.
+    SJ
+
+    # Sweden.
+    SE
+
+    # Switzerland.
+    CH
+
+    # Syria.
+    SY
+
+    # Taiwan.
+    TW
+
+    # Tajikistan.
+    TJ
+
+    # Tanzania.
+    TZ
+
+    # Thailand.
+    TH
+
+    # Timor-Leste.
+    TL
+
+    # Togo.
+    TG
+
+    # Tokelau.
+    TK
+
+    # Tonga.
+    TO
+
+    # Trinidad & Tobago.
+    TT
+
+    # Tristan da Cunha.
+    TA
+
+    # Tunisia.
+    TN
+
+    # Turkey.
+    TR
+
+    # Turkmenistan.
+    TM
+
+    # Turks & Caicos Islands.
+    TC
+
+    # Tuvalu.
+    TV
+
+    # Uganda.
+    UG
+
+    # Ukraine.
+    UA
+
+    # United Arab Emirates.
+    AE
+
+    # United Kingdom.
+    GB
+
+    # United States.
+    US
+
+    # U.S. Outlying Islands.
+    UM
+
+    # Uruguay.
+    UY
+
+    # Uzbekistan.
+    UZ
+
+    # Vanuatu.
+    VU
+
+    # Venezuela.
+    VE
+
+    # Vietnam.
+    VN
+
+    # British Virgin Islands.
+    VG
+
+    # Wallis & Futuna.
+    WF
+
+    # Western Sahara.
+    EH
+
+    # Yemen.
+    YE
+
+    # Zambia.
+    ZM
+
+    # Zimbabwe.
+    ZW
+
+    # Unknown Region.
+    ZZ
+}

+ 9 - 0
tools.go

@@ -0,0 +1,9 @@
+//go:build tools
+// +build tools
+
+package customer
+
+import (
+	_ "github.com/99designs/gqlgen"
+	_ "github.com/99designs/gqlgen/graphql/introspection"
+)