mirror of
https://github.com/MichaelMure/git-bug.git
synced 2024-12-14 17:51:44 +03:00
Merge pull request #305 from MichaelMure/gomod
migrate to go modules, update gqlgen
This commit is contained in:
commit
1a3cbdc418
21
.travis.yml
21
.travis.yml
@ -1,13 +1,11 @@
|
||||
matrix:
|
||||
include:
|
||||
- language: go
|
||||
go: "1.10"
|
||||
go: 1.11.x
|
||||
- language: go
|
||||
go: "1.11"
|
||||
go: 1.12.x
|
||||
- language: go
|
||||
go: "1.12"
|
||||
- language: go
|
||||
go: "1.13"
|
||||
go: 1.13.x
|
||||
- language: node_js
|
||||
node_js: 8
|
||||
before_install:
|
||||
@ -28,6 +26,19 @@ matrix:
|
||||
before_install:
|
||||
- cd webui
|
||||
after_success: []
|
||||
- language: node_js
|
||||
node_js: 12
|
||||
before_install:
|
||||
- cd webui
|
||||
after_success: []
|
||||
- language: node_js
|
||||
node_js: 13
|
||||
before_install:
|
||||
- cd webui
|
||||
after_success: []
|
||||
|
||||
env:
|
||||
GO111MODULE=on
|
||||
|
||||
install:
|
||||
- make install
|
||||
|
524
Gopkg.lock
generated
524
Gopkg.lock
generated
@ -1,524 +0,0 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
digest = "1:25c825a120e8ae421b807f06eaa30f4d30ad3700fc103b7aaa24af8358498d31"
|
||||
name = "github.com/99designs/gqlgen"
|
||||
packages = [
|
||||
"api",
|
||||
"codegen",
|
||||
"codegen/config",
|
||||
"codegen/templates",
|
||||
"complexity",
|
||||
"graphql",
|
||||
"graphql/introspection",
|
||||
"handler",
|
||||
"internal/code",
|
||||
"internal/imports",
|
||||
"plugin",
|
||||
"plugin/modelgen",
|
||||
"plugin/resolvergen",
|
||||
"plugin/schemaconfig",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "4eeacc6e4cb7bedc7c5312b6a3947697ad5cfb55"
|
||||
version = "v0.9.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:364c89f564ef045872f82ff2f156fd3cb09274e4a3bdbf89aef2c2370c955f95"
|
||||
name = "github.com/MichaelMure/go-term-text"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "6d868251433124ef4ed19c9f8e973ac610d42ef5"
|
||||
version = "v0.2.4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:897d91c431ce469d35a5e6030e60e617dccd9a0e95bdffa6a80594f5c5800d29"
|
||||
name = "github.com/agnivade/levenshtein"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "3d21ba515fe27b856f230847e856431ae1724adc"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:fdfcd99fd77a0d3e3228d4d0b5061d9a611d40cd369ea44e333401b06936fdc4"
|
||||
name = "github.com/araddon/dateparse"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "0fb0a474d195a3449cf412ae0176faa193f0ef0b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:1bd56b71a75f4df8aae1d65feb3aee6742ed1a2ff00fa9aaf74b40d9fadc4440"
|
||||
name = "github.com/awesome-gocui/gocui"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "a34ffb055986a3f9461735162c9a2d235b95b8cb"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:237f3e0692e330851b8b5a53117cfcea1beba09aec7668d34db91b809879c296"
|
||||
name = "github.com/awesome-gocui/termbox-go"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "c0aef3d18bcc218a92e318293310ca0191f29654"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:b6d886569181ec96ca83d529f4d6ba0cbf92ace7bb6f633f90c5f34d9bba7aab"
|
||||
name = "github.com/blang/semver"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "ba2c2ddd89069b46a7011d4106f6868f17ee1705"
|
||||
version = "v3.6.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:f438d91be142877c3ad83157992c91de787ddfbddcc2a7da1ef6ef61606cadc4"
|
||||
name = "github.com/cheekybits/genny"
|
||||
packages = ["generic"]
|
||||
pruneopts = "UT"
|
||||
revision = "9127e812e1e9e501ce899a18121d316ecb52e4ba"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:cc439e1d9d8cff3d575642f5401033b00f2b8d0cd9f859db45604701c990879a"
|
||||
name = "github.com/corpix/uarand"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "2b8494104d86337cdd41d0a49cbed8e4583c0ab4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7cb4fdca4c251b3ef8027c90ea35f70c7b661a593b9eeae34753c65499098bb1"
|
||||
name = "github.com/cpuguy83/go-md2man"
|
||||
packages = ["md2man"]
|
||||
pruneopts = "UT"
|
||||
revision = "20f5889cbdc3c73dbd2862796665e7c465ade7d1"
|
||||
version = "v1.0.8"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec"
|
||||
name = "github.com/davecgh/go-spew"
|
||||
packages = ["spew"]
|
||||
pruneopts = "UT"
|
||||
revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:6f9339c912bbdda81302633ad7e99a28dfa5a639c864061f1929510a9a64aa74"
|
||||
name = "github.com/dustin/go-humanize"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "9f541cc9db5d55bce703bd99987c9d5cb8eea45e"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:865079840386857c809b72ce300be7580cb50d3d3129ce11bf9aa6ca2bc1934a"
|
||||
name = "github.com/fatih/color"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "5b77d2a35fb0ede96d138fc9a99f5c9b6aef11b4"
|
||||
version = "v1.7.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:aacef5f5e45685f2aeda5534d0a750dee6859de7e9088cdd06192787bb01ae6d"
|
||||
name = "github.com/go-errors/errors"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "a6af135bd4e28680facf08a3d206b454abc877a4"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:97df918963298c287643883209a2c3f642e6593379f97ab400c2a2e219ab647d"
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = ["proto"]
|
||||
pruneopts = "UT"
|
||||
revision = "aa810b61a9c79d51363740d207bb46cf8e620ed5"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a63cff6b5d8b95638bfe300385d93b2a6d9d687734b863da8e09dc834510a690"
|
||||
name = "github.com/google/go-querystring"
|
||||
packages = ["query"]
|
||||
pruneopts = "UT"
|
||||
revision = "44c6ddd0a2342c386950e880b658017258da92fc"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:cbec35fe4d5a4fba369a656a8cd65e244ea2c743007d8f6c1ccb132acf9d1296"
|
||||
name = "github.com/gorilla/mux"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "00bdffe0f3c77e27d2cf6f5c70232a2d3e4d9c15"
|
||||
version = "v1.7.3"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:43dd08a10854b2056e615d1b1d22ac94559d822e1f8b6fcc92c1a1057e85188e"
|
||||
name = "github.com/gorilla/websocket"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:8ec8d88c248041a6df5f6574b87bc00e7e0b493881dad2e7ef47b11dc69093b5"
|
||||
name = "github.com/hashicorp/golang-lru"
|
||||
packages = [
|
||||
".",
|
||||
"simplelru",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "20f1fb78b0740ba8c3cb143a61e86ba5c8669768"
|
||||
version = "v0.5.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:22725c01ecd8ed0c0f0078944305a57053340d92878b02db925c660cc4accf64"
|
||||
name = "github.com/icrowley/fake"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "4178557ae428460c3780a381c824a1f3aceb6325"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:870d441fe217b8e689d7949fef6e43efbc787e50f200cb1e70dbca9204a1d6be"
|
||||
name = "github.com/inconshreveable/mousetrap"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
|
||||
version = "v1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c658e84ad3916da105a761660dcaeb01e63416c8ec7bc62256a9b411a05fcd67"
|
||||
name = "github.com/mattn/go-colorable"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072"
|
||||
version = "v0.0.9"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d4d17353dbd05cb52a2a52b7fe1771883b682806f68db442b436294926bbfafb"
|
||||
name = "github.com/mattn/go-isatty"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39"
|
||||
version = "v0.0.3"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e2d1d410fb367567c2b53ed9e2d719d3c1f0891397bb2fa49afd747cfbf1e8e4"
|
||||
name = "github.com/mattn/go-runewidth"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "9e777a8366cce605130a531d2cd6363d07ad7317"
|
||||
version = "v0.0.2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:645110e089152bd0f4a011a2648fbb0e4df5977be73ca605781157ac297f50c4"
|
||||
name = "github.com/mitchellh/mapstructure"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "fa473d140ef3c6adf42d6b391fe76707f1f243c8"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7413525ee648f20b4181be7fe8103d0cb98be9e141926a03ee082dc207061e4e"
|
||||
name = "github.com/phayes/freeport"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "b8543db493a5ed890c5499e935e2cad7504f3a04"
|
||||
version = "1.0.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:40e195917a951a8bf867cd05de2a46aaf1806c50cf92eebf4c16f78cd196f747"
|
||||
name = "github.com/pkg/errors"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
|
||||
version = "v0.8.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe"
|
||||
name = "github.com/pmezard/go-difflib"
|
||||
packages = ["difflib"]
|
||||
pruneopts = "UT"
|
||||
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:8bc629776d035c003c7814d4369521afe67fdb8efc4b5f66540d29343b98cf23"
|
||||
name = "github.com/russross/blackfriday"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "55d61fa8aa702f59229e6cff85793c22e580eaf5"
|
||||
version = "v1.5.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:2befa342040f385b214cfd400887b584d5eba4e4b25a0ebaea839ddb0d59c586"
|
||||
name = "github.com/shurcooL/githubv4"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "068505affed7d8555196a48eb3e0ed43410aa8e8"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:ddaa79b37808fbd09a1c3f484bba6320c884664dfc25ccc5f2d7d5a82222177c"
|
||||
name = "github.com/shurcooL/go"
|
||||
packages = ["ctxhttp"]
|
||||
pruneopts = "UT"
|
||||
revision = "9e1955d9fb6e1ee2345ba1f5e71669263e719e27"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:b69bc7c0c0489f6f3467b737e243620b1a545dbeaf7623a9432b658f7b7ecc58"
|
||||
name = "github.com/shurcooL/graphql"
|
||||
packages = [
|
||||
".",
|
||||
"ident",
|
||||
"internal/jsonutil",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "365899397c9ad12805631fe4c9b2a64be9d74818"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:9d29b003dc5f98647a5dd6754d65c07171fcd35761102ea56ecd3d6993adee7f"
|
||||
name = "github.com/shurcooL/httpfs"
|
||||
packages = [
|
||||
"filter",
|
||||
"vfsutil",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "809beceb23714880abc4a382a00c05f89d13b1cc"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:98450c86949b8cdc4637b80c1c686ca955e503d3fbae9296d1f49c532895d281"
|
||||
name = "github.com/shurcooL/vfsgen"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "6a9ea43bcacdf716a5c1b38efff722c07adf0069"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:519621a373ae7d96a16415a6356d7b97722ed3a292f73409b361b7c0322971e3"
|
||||
name = "github.com/skratchdot/open-golang"
|
||||
packages = ["open"]
|
||||
pruneopts = "UT"
|
||||
revision = "79abb63cd66e41cb1473e26d11ebdcd68b04c8e5"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:abe9f3f23399646a6263682cacc9e86969f6c7e768f0ef036449926aa24cbbef"
|
||||
name = "github.com/spf13/cobra"
|
||||
packages = [
|
||||
".",
|
||||
"doc",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "f2b07da1e2c38d5f12845a4f607e2e1018cbb1f5"
|
||||
version = "v0.0.5"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:9424f440bba8f7508b69414634aef3b2b3a877e522d8a4624692412805407bb7"
|
||||
name = "github.com/spf13/pflag"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "583c0c0531f06d5278b7d917446061adc344b5cd"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c40d65817cdd41fac9aa7af8bed56927bb2d6d47e4fea566a74880f5c2b1c41e"
|
||||
name = "github.com/stretchr/testify"
|
||||
packages = [
|
||||
"assert",
|
||||
"require",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686"
|
||||
version = "v1.2.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:8d784da270f610f505e2c9785faec4c81d4a6a6a1034412685a4bf2cffe24cef"
|
||||
name = "github.com/theckman/goconstraint"
|
||||
packages = ["go1.10/gte"]
|
||||
pruneopts = "UT"
|
||||
revision = "93babf24513d0e8277635da8169fcc5a46ae3f6a"
|
||||
version = "v1.11.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:895fa0f564003de2498fbaf00be596fa814655ab445ce7cc215f7724bb6831ae"
|
||||
name = "github.com/vektah/gqlgen"
|
||||
packages = ["client"]
|
||||
pruneopts = "UT"
|
||||
revision = "636435b68700211441303f1a5ed92f3768ba5774"
|
||||
version = "v0.5.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ed6a41de3eedd8d4868eea057837860453ebbe08c5e385fd50d4c24e5642ec18"
|
||||
name = "github.com/vektah/gqlparser"
|
||||
packages = [
|
||||
".",
|
||||
"ast",
|
||||
"gqlerror",
|
||||
"lexer",
|
||||
"parser",
|
||||
"validator",
|
||||
"validator/rules",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "e805d08bb209b1accdea76bd2327811858d81985"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3254b94c092d3b29b828cc4c457723ac875f4318bf801745b71ef437459a90e9"
|
||||
name = "github.com/xanzy/go-gitlab"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "d8e9de1d4b4477fe420696e10cd97491d518d90f"
|
||||
version = "v0.22.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:3f3a05ae0b95893d90b9b3b5afdb79a9b3d96e4e36e099d841ae602e4aca0da8"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = ["ssh/terminal"]
|
||||
pruneopts = "UT"
|
||||
revision = "0e37d006457bf46f9e6692014ba72ef82c33022c"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:d6b719875cf8091fbab38527d81d34e71f4521b9ee9ccfbd4a32cff2ac5af96e"
|
||||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"context",
|
||||
"context/ctxhttp",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "2f5d2388922f370f4355f327fcf4cfe9f5583908"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:363b547c971a2b07474c598b6e9ebcb238d556d8a27f37b3895ad20cd50e7281"
|
||||
name = "golang.org/x/oauth2"
|
||||
packages = [
|
||||
".",
|
||||
"internal",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "d2e6202438beef2727060aa7cabdd924d92ebfd9"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:b521f10a2d8fa85c04a8ef4e62f2d1e14d303599a55d64dabf9f5a02f84d35eb"
|
||||
name = "golang.org/x/sync"
|
||||
packages = ["errgroup"]
|
||||
pruneopts = "UT"
|
||||
revision = "cd5d95a43a6e21273425c7ae415d3df9ea832eeb"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:3364d01296ce7eeca363e3d530ae63a2092d6f8efb85fb3d101e8f6d7de83452"
|
||||
name = "golang.org/x/sys"
|
||||
packages = [
|
||||
"unix",
|
||||
"windows",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "ac767d655b305d4e9612f5f6e33120b9176c4ad4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:86cb348528a842f96e651ca3f8197070e9ebc315f8c73e71d0df7a60e92a6db1"
|
||||
name = "golang.org/x/text"
|
||||
packages = [
|
||||
"runes",
|
||||
"transform",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "342b2e1fbaa52c93f31447ad2c6abc048c63e475"
|
||||
version = "v0.3.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:71850ac10bbeb4d8dd06ce0743fe57654daf28510b0f6cbd9692aaf0d269360e"
|
||||
name = "golang.org/x/tools"
|
||||
packages = [
|
||||
"go/ast/astutil",
|
||||
"go/gcexportdata",
|
||||
"go/internal/gcimporter",
|
||||
"go/internal/packagesdriver",
|
||||
"go/packages",
|
||||
"go/types/typeutil",
|
||||
"imports",
|
||||
"internal/fastwalk",
|
||||
"internal/gopathwalk",
|
||||
"internal/module",
|
||||
"internal/semver",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "7e5bf9270d7061560865b8847c378236480f47e3"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:6247f76e55a1e1a5c19a81e2d4b4dff6730461eeb5bbb0a16dd4a8ec8637ee93"
|
||||
name = "google.golang.org/appengine"
|
||||
packages = [
|
||||
"internal",
|
||||
"internal/base",
|
||||
"internal/datastore",
|
||||
"internal/log",
|
||||
"internal/remote_api",
|
||||
"internal/urlfetch",
|
||||
"urlfetch",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "ae0ab99deb4dc413a2b4bd6c8bdd0eb67f1e4d06"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:342378ac4dcb378a5448dd723f0784ae519383532f5e70ade24132c4c8693202"
|
||||
name = "gopkg.in/yaml.v2"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
|
||||
version = "v2.2.1"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
input-imports = [
|
||||
"github.com/99designs/gqlgen/api",
|
||||
"github.com/99designs/gqlgen/codegen/config",
|
||||
"github.com/99designs/gqlgen/graphql",
|
||||
"github.com/99designs/gqlgen/graphql/introspection",
|
||||
"github.com/99designs/gqlgen/handler",
|
||||
"github.com/MichaelMure/go-term-text",
|
||||
"github.com/araddon/dateparse",
|
||||
"github.com/awesome-gocui/gocui",
|
||||
"github.com/blang/semver",
|
||||
"github.com/cheekybits/genny/generic",
|
||||
"github.com/dustin/go-humanize",
|
||||
"github.com/fatih/color",
|
||||
"github.com/go-errors/errors",
|
||||
"github.com/gorilla/mux",
|
||||
"github.com/icrowley/fake",
|
||||
"github.com/mattn/go-isatty",
|
||||
"github.com/phayes/freeport",
|
||||
"github.com/pkg/errors",
|
||||
"github.com/shurcooL/githubv4",
|
||||
"github.com/shurcooL/httpfs/filter",
|
||||
"github.com/shurcooL/vfsgen",
|
||||
"github.com/skratchdot/open-golang/open",
|
||||
"github.com/spf13/cobra",
|
||||
"github.com/spf13/cobra/doc",
|
||||
"github.com/stretchr/testify/assert",
|
||||
"github.com/stretchr/testify/require",
|
||||
"github.com/theckman/goconstraint/go1.10/gte",
|
||||
"github.com/vektah/gqlgen/client",
|
||||
"github.com/vektah/gqlparser",
|
||||
"github.com/vektah/gqlparser/ast",
|
||||
"github.com/xanzy/go-gitlab",
|
||||
"golang.org/x/crypto/ssh/terminal",
|
||||
"golang.org/x/oauth2",
|
||||
"golang.org/x/sync/errgroup",
|
||||
"golang.org/x/text/runes",
|
||||
"golang.org/x/text/transform",
|
||||
]
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
89
Gopkg.toml
89
Gopkg.toml
@ -1,89 +0,0 @@
|
||||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
#
|
||||
# [prune]
|
||||
# non-go = false
|
||||
# go-tests = true
|
||||
# unused-packages = true
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/gorilla/mux"
|
||||
version = "1.7.3"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/phayes/freeport"
|
||||
version = "1.0.2"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/shurcooL/vfsgen"
|
||||
branch = "master"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/skratchdot/open-golang"
|
||||
branch = "master"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/fatih/color"
|
||||
version = "1.7.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/spf13/cobra"
|
||||
version = "v0.0.5"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/dustin/go-humanize"
|
||||
branch = "master"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/99designs/gqlgen"
|
||||
version = "0.9.2"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/awesome-gocui/gocui"
|
||||
branch = "master"
|
||||
|
||||
[[override]]
|
||||
name = "golang.org/x/tools"
|
||||
revision = "7e5bf9270d7061560865b8847c378236480f47e3"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/blang/semver"
|
||||
version = "3.6.1"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/xanzy/go-gitlab"
|
||||
version = "0.22.1"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sync"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/MichaelMure/go-term-text"
|
||||
version = "0.2.4"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/araddon/dateparse"
|
@ -12,7 +12,7 @@ import (
|
||||
"os/signal"
|
||||
"time"
|
||||
|
||||
"github.com/99designs/gqlgen/handler"
|
||||
"github.com/99designs/gqlgen/graphql/playground"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/phayes/freeport"
|
||||
"github.com/skratchdot/open-golang/open"
|
||||
@ -57,7 +57,7 @@ func runWebUI(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
// Routes
|
||||
router.Path("/playground").Handler(handler.Playground("git-bug", "/graphql"))
|
||||
router.Path("/playground").Handler(playground.Handler("git-bug", "/graphql"))
|
||||
router.Path("/graphql").Handler(graphqlHandler)
|
||||
router.Path("/gitfile/{hash}").Handler(newGitFileHandler(repo))
|
||||
router.Path("/upload").Methods("POST").Handler(newGitUploadFileHandler(repo))
|
||||
|
@ -9,8 +9,8 @@ package main
|
||||
import (
|
||||
"github.com/MichaelMure/git-bug/commands"
|
||||
|
||||
// minimal go version is 1.10
|
||||
_ "github.com/theckman/goconstraint/go1.10/gte"
|
||||
// minimal go version is 1.11
|
||||
_ "github.com/theckman/goconstraint/go1.11/gte"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
35
go.mod
Normal file
35
go.mod
Normal file
@ -0,0 +1,35 @@
|
||||
module github.com/MichaelMure/git-bug
|
||||
|
||||
go 1.11
|
||||
|
||||
require (
|
||||
github.com/99designs/gqlgen v0.10.3-0.20200205113530-b941b970f0b6
|
||||
github.com/MichaelMure/go-term-text v0.2.4
|
||||
github.com/araddon/dateparse v0.0.0-20190622164848-0fb0a474d195
|
||||
github.com/awesome-gocui/gocui v0.6.1-0.20191115151952-a34ffb055986
|
||||
github.com/blang/semver v3.5.1+incompatible
|
||||
github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9
|
||||
github.com/corpix/uarand v0.1.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/fatih/color v1.7.0
|
||||
github.com/go-errors/errors v1.0.1
|
||||
github.com/gorilla/mux v1.7.3
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428
|
||||
github.com/mattn/go-colorable v0.1.4 // indirect
|
||||
github.com/mattn/go-isatty v0.0.8
|
||||
github.com/phayes/freeport v0.0.0-20171002181615-b8543db493a5
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/shurcooL/githubv4 v0.0.0-20190601194912-068505affed7
|
||||
github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f // indirect
|
||||
github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e
|
||||
github.com/spf13/cobra v0.0.5
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/theckman/goconstraint v1.11.0
|
||||
github.com/vektah/gqlparser v1.2.1
|
||||
github.com/xanzy/go-gitlab v0.22.1
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
|
||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58
|
||||
golang.org/x/text v0.3.0
|
||||
)
|
168
go.sum
Normal file
168
go.sum
Normal file
@ -0,0 +1,168 @@
|
||||
github.com/99designs/gqlgen v0.10.3-0.20200205113530-b941b970f0b6 h1:WU+9Z7AoCyl+HlB2kE0O+4/3BaVqLQfnX5dHigV5p8A=
|
||||
github.com/99designs/gqlgen v0.10.3-0.20200205113530-b941b970f0b6/go.mod h1:28v/ATDVwPUriwNtAIrQEhRHXJjdi5dVGqxSqPna1I8=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Masterminds/glide v0.13.2/go.mod h1:STyF5vcenH/rUqTEv+/hBXlSTo7KYwg2oc2f4tzPWic=
|
||||
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
|
||||
github.com/MichaelMure/go-term-text v0.2.4 h1:h+lAsjG5o3oNvaJeh7OzE8zdSiB/VyJo9JzSnncrZv4=
|
||||
github.com/MichaelMure/go-term-text v0.2.4/go.mod h1:o2Z5T3b28F4kwAojGvvNdbzjHf9t18vbQ7E2pmTe2Ww=
|
||||
github.com/agnivade/levenshtein v1.0.1 h1:3oJU7J3FGFmyhn8KHjmVaZCN5hxTr7GxgRue+sxIXdQ=
|
||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
||||
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/araddon/dateparse v0.0.0-20190622164848-0fb0a474d195 h1:c4mLfegoDw6OhSJXTd2jUEQgZUQuJWtocudb97Qn9EM=
|
||||
github.com/araddon/dateparse v0.0.0-20190622164848-0fb0a474d195/go.mod h1:SLqhdZcd+dF3TEVL2RMoob5bBP5R1P1qkox+HtCBgGI=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/awesome-gocui/gocui v0.6.1-0.20191115151952-a34ffb055986 h1:QvIfX96O11qjX1Zr3hKkG0dI12JBRBGABWffyZ1GI60=
|
||||
github.com/awesome-gocui/gocui v0.6.1-0.20191115151952-a34ffb055986/go.mod h1:1QikxFaPhe2frKeKvEwZEIGia3haiOxOUXKinrv17mA=
|
||||
github.com/awesome-gocui/termbox-go v0.0.0-20190427202837-c0aef3d18bcc h1:wGNpKcHU8Aadr9yOzsT3GEsFLS7HQu8HxQIomnekqf0=
|
||||
github.com/awesome-gocui/termbox-go v0.0.0-20190427202837-c0aef3d18bcc/go.mod h1:tOy3o5Nf1bA17mnK4W41gD7PS3u4Cv0P0pqFcoWMy8s=
|
||||
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9 h1:a1zrFsLFac2xoM6zG1u72DWJwZG3ayttYLfmLbxVETk=
|
||||
github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
|
||||
github.com/codegangsta/cli v1.20.0/go.mod h1:/qJNoX69yVSKu5o4jLyXAENLRyk1uhi7zkbQ3slBdOA=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/corpix/uarand v0.1.1 h1:RMr1TWc9F4n5jiPDzFHtmaUXLKLNUFK0SgCLo4BhX/U=
|
||||
github.com/corpix/uarand v0.1.1/go.mod h1:SFKZvkcRoLqVRFZ4u25xPmp6m9ktANfbpXZ7SJ0/FNU=
|
||||
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/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/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-chi/chi v3.3.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
|
||||
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ=
|
||||
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428 h1:Mo9W14pwbO9VfRe+ygqZ8dFbPpoIK1HFrG/zjTuQ+nc=
|
||||
github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428/go.mod h1:uhpZMVGznybq1itEKXj6RYw9I71qK4kH+OGMjRC4KEo=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
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/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
|
||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.6 h1:V2iyH+aX9C5fsYCpK60U8BYIvmhqxuOL3JZcqc1NB7k=
|
||||
github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/phayes/freeport v0.0.0-20171002181615-b8543db493a5 h1:rZQtoozkfsiNs36c7Tdv/gyGNzD1X1XWKO8rptVNZuM=
|
||||
github.com/phayes/freeport v0.0.0-20171002181615-b8543db493a5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.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/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shurcooL/githubv4 v0.0.0-20190601194912-068505affed7 h1:Vk3RiBQpF0Ja+OqbFG7lYTk79+l8Cm2QESLXB0x6u6U=
|
||||
github.com/shurcooL/githubv4 v0.0.0-20190601194912-068505affed7/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo=
|
||||
github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f h1:tygelZueB1EtXkPI6mQ4o9DQ0+FKW41hTbunoXZCTqk=
|
||||
github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg=
|
||||
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||
github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e h1:VAzdS5Nw68fbf5RZ8RDVlUvPXNU6Z3jtPCK/qvm4FoQ=
|
||||
github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/theckman/goconstraint v1.11.0 h1:oBUwN5wpE4dwyPhRGraEgJsFTr+JtLWiDnaJZJeeXI0=
|
||||
github.com/theckman/goconstraint v1.11.0/go.mod h1:zkCR/f2kOULTk/h1ujgyB9BlCNLaqlQ6GN2Zl4mg81g=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U=
|
||||
github.com/vektah/gqlparser v1.2.1 h1:C+L7Go/eUbN0w6Y0kaiq2W6p2wN5j8wU82EdDXxDivc=
|
||||
github.com/vektah/gqlparser v1.2.1/go.mod h1:bkVf0FX+Stjg/MHnm8mEyubuaArhNEqfQhF+OTiAL74=
|
||||
github.com/xanzy/go-gitlab v0.22.1 h1:TVxgHmoa35jQL+9FCkG0nwPDxU9dQZXknBTDtGaSFno=
|
||||
github.com/xanzy/go-gitlab v0.22.1/go.mod h1:t4Bmvnxj7k37S4Y17lfLx+nLqkf/oQwT2HagfWKv5Og=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288 h1:JIqe8uIcRBHXDQVvZtHwp80ai3Lw3IJAeJEs55Dc1W0=
|
||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589 h1:rjUrONFu4kLchcZTfp3/96bR8bW8dIa8uz3cR5n0cgM=
|
||||
golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20180110180208-2cc67fd64755/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
||||
sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67/go.mod h1:L5q+DGLGOQFpo1snNEkLOJT2d1YTW66rWNzatr3He1k=
|
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,9 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/vektah/gqlgen/client"
|
||||
"github.com/99designs/gqlgen/client"
|
||||
|
||||
"github.com/MichaelMure/git-bug/graphql/models"
|
||||
"github.com/MichaelMure/git-bug/misc/random_bugs"
|
||||
@ -22,8 +21,7 @@ func TestQueries(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
srv := httptest.NewServer(handler)
|
||||
c := client.New(srv.URL)
|
||||
c := client.New(handler)
|
||||
|
||||
query := `
|
||||
query {
|
||||
|
@ -6,7 +6,8 @@ package graphql
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/99designs/gqlgen/handler"
|
||||
"github.com/99designs/gqlgen/graphql/handler"
|
||||
|
||||
"github.com/MichaelMure/git-bug/graphql/graph"
|
||||
"github.com/MichaelMure/git-bug/graphql/resolvers"
|
||||
"github.com/MichaelMure/git-bug/repository"
|
||||
@ -14,7 +15,7 @@ import (
|
||||
|
||||
// Handler is the root GraphQL http handler
|
||||
type Handler struct {
|
||||
http.HandlerFunc
|
||||
http.Handler
|
||||
*resolvers.RootResolver
|
||||
}
|
||||
|
||||
@ -32,7 +33,7 @@ func NewHandler(repo repository.ClockedRepo) (Handler, error) {
|
||||
Resolvers: h.RootResolver,
|
||||
}
|
||||
|
||||
h.HandlerFunc = handler.GraphQL(graph.NewExecutableSchema(config))
|
||||
h.Handler = handler.NewDefaultServer(graph.NewExecutableSchema(config))
|
||||
|
||||
return h, nil
|
||||
}
|
||||
|
@ -11,41 +11,10 @@ var _ graph.IdentityResolver = &identityResolver{}
|
||||
|
||||
type identityResolver struct{}
|
||||
|
||||
func (identityResolver) ID(ctx context.Context, obj *identity.Interface) (string, error) {
|
||||
return (*obj).Id().String(), nil
|
||||
func (identityResolver) ID(ctx context.Context, obj identity.Interface) (string, error) {
|
||||
return obj.Id().String(), nil
|
||||
}
|
||||
|
||||
func (identityResolver) HumanID(ctx context.Context, obj *identity.Interface) (string, error) {
|
||||
return (*obj).Id().Human(), nil
|
||||
}
|
||||
|
||||
func (identityResolver) Name(ctx context.Context, obj *identity.Interface) (*string, error) {
|
||||
return nilIfEmpty((*obj).Name())
|
||||
}
|
||||
|
||||
func (identityResolver) Email(ctx context.Context, obj *identity.Interface) (*string, error) {
|
||||
return nilIfEmpty((*obj).Email())
|
||||
}
|
||||
|
||||
func (identityResolver) Login(ctx context.Context, obj *identity.Interface) (*string, error) {
|
||||
return nilIfEmpty((*obj).Login())
|
||||
}
|
||||
|
||||
func (identityResolver) DisplayName(ctx context.Context, obj *identity.Interface) (string, error) {
|
||||
return (*obj).DisplayName(), nil
|
||||
}
|
||||
|
||||
func (identityResolver) AvatarURL(ctx context.Context, obj *identity.Interface) (*string, error) {
|
||||
return nilIfEmpty((*obj).AvatarUrl())
|
||||
}
|
||||
|
||||
func (identityResolver) IsProtected(ctx context.Context, obj *identity.Interface) (bool, error) {
|
||||
return (*obj).IsProtected(), nil
|
||||
}
|
||||
|
||||
func nilIfEmpty(s string) (*string, error) {
|
||||
if s == "" {
|
||||
return nil, nil
|
||||
}
|
||||
return &s, nil
|
||||
func (identityResolver) HumanID(ctx context.Context, obj identity.Interface) (string, error) {
|
||||
return obj.Id().Human(), nil
|
||||
}
|
||||
|
19
vendor/github.com/99designs/gqlgen/LICENSE
generated
vendored
19
vendor/github.com/99designs/gqlgen/LICENSE
generated
vendored
@ -1,19 +0,0 @@
|
||||
Copyright (c) 2018 Adam Scarr
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
78
vendor/github.com/99designs/gqlgen/api/generate.go
generated
vendored
78
vendor/github.com/99designs/gqlgen/api/generate.go
generated
vendored
@ -1,78 +0,0 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
"github.com/99designs/gqlgen/codegen"
|
||||
"github.com/99designs/gqlgen/codegen/config"
|
||||
"github.com/99designs/gqlgen/plugin"
|
||||
"github.com/99designs/gqlgen/plugin/modelgen"
|
||||
"github.com/99designs/gqlgen/plugin/resolvergen"
|
||||
"github.com/99designs/gqlgen/plugin/schemaconfig"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
func Generate(cfg *config.Config, option ...Option) error {
|
||||
_ = syscall.Unlink(cfg.Exec.Filename)
|
||||
_ = syscall.Unlink(cfg.Model.Filename)
|
||||
|
||||
plugins := []plugin.Plugin{
|
||||
schemaconfig.New(),
|
||||
modelgen.New(),
|
||||
resolvergen.New(),
|
||||
}
|
||||
|
||||
for _, o := range option {
|
||||
o(cfg, &plugins)
|
||||
}
|
||||
|
||||
for _, p := range plugins {
|
||||
if mut, ok := p.(plugin.ConfigMutator); ok {
|
||||
err := mut.MutateConfig(cfg)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, p.Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
// Merge again now that the generated models have been injected into the typemap
|
||||
data, err := codegen.BuildData(cfg)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "merging failed")
|
||||
}
|
||||
|
||||
if err = codegen.GenerateCode(data); err != nil {
|
||||
return errors.Wrap(err, "generating core failed")
|
||||
}
|
||||
|
||||
for _, p := range plugins {
|
||||
if mut, ok := p.(plugin.CodeGenerator); ok {
|
||||
err := mut.GenerateCode(data)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, p.Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := validate(cfg); err != nil {
|
||||
return errors.Wrap(err, "validation failed")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validate(cfg *config.Config) error {
|
||||
roots := []string{cfg.Exec.ImportPath()}
|
||||
if cfg.Model.IsDefined() {
|
||||
roots = append(roots, cfg.Model.ImportPath())
|
||||
}
|
||||
|
||||
if cfg.Resolver.IsDefined() {
|
||||
roots = append(roots, cfg.Resolver.ImportPath())
|
||||
}
|
||||
_, err := packages.Load(&packages.Config{Mode: packages.LoadTypes | packages.LoadSyntax}, roots...)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "validation failed")
|
||||
}
|
||||
return nil
|
||||
}
|
20
vendor/github.com/99designs/gqlgen/api/option.go
generated
vendored
20
vendor/github.com/99designs/gqlgen/api/option.go
generated
vendored
@ -1,20 +0,0 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/99designs/gqlgen/codegen/config"
|
||||
"github.com/99designs/gqlgen/plugin"
|
||||
)
|
||||
|
||||
type Option func(cfg *config.Config, plugins *[]plugin.Plugin)
|
||||
|
||||
func NoPlugins() Option {
|
||||
return func(cfg *config.Config, plugins *[]plugin.Plugin) {
|
||||
*plugins = nil
|
||||
}
|
||||
}
|
||||
|
||||
func AddPlugin(p plugin.Plugin) Option {
|
||||
return func(cfg *config.Config, plugins *[]plugin.Plugin) {
|
||||
*plugins = append(*plugins, p)
|
||||
}
|
||||
}
|
120
vendor/github.com/99designs/gqlgen/codegen/args.go
generated
vendored
120
vendor/github.com/99designs/gqlgen/codegen/args.go
generated
vendored
@ -1,120 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/types"
|
||||
"strings"
|
||||
|
||||
"github.com/99designs/gqlgen/codegen/config"
|
||||
"github.com/99designs/gqlgen/codegen/templates"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
)
|
||||
|
||||
type ArgSet struct {
|
||||
Args []*FieldArgument
|
||||
FuncDecl string
|
||||
}
|
||||
|
||||
type FieldArgument struct {
|
||||
*ast.ArgumentDefinition
|
||||
TypeReference *config.TypeReference
|
||||
VarName string // The name of the var in go
|
||||
Object *Object // A link back to the parent object
|
||||
Default interface{} // The default value
|
||||
Directives []*Directive
|
||||
Value interface{} // value set in Data
|
||||
}
|
||||
|
||||
//ImplDirectives get not Builtin and location ARGUMENT_DEFINITION directive
|
||||
func (f *FieldArgument) ImplDirectives() []*Directive {
|
||||
d := make([]*Directive, 0)
|
||||
for i := range f.Directives {
|
||||
if !f.Directives[i].Builtin && f.Directives[i].IsLocation(ast.LocationArgumentDefinition) {
|
||||
d = append(d, f.Directives[i])
|
||||
}
|
||||
}
|
||||
|
||||
return d
|
||||
}
|
||||
|
||||
func (f *FieldArgument) DirectiveObjName() string {
|
||||
return "rawArgs"
|
||||
}
|
||||
|
||||
func (f *FieldArgument) Stream() bool {
|
||||
return f.Object != nil && f.Object.Stream
|
||||
}
|
||||
|
||||
func (b *builder) buildArg(obj *Object, arg *ast.ArgumentDefinition) (*FieldArgument, error) {
|
||||
tr, err := b.Binder.TypeReference(arg.Type, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
argDirs, err := b.getDirectives(arg.Directives)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newArg := FieldArgument{
|
||||
ArgumentDefinition: arg,
|
||||
TypeReference: tr,
|
||||
Object: obj,
|
||||
VarName: templates.ToGoPrivate(arg.Name),
|
||||
Directives: argDirs,
|
||||
}
|
||||
|
||||
if arg.DefaultValue != nil {
|
||||
newArg.Default, err = arg.DefaultValue.Value(nil)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("default value is not valid: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return &newArg, nil
|
||||
}
|
||||
|
||||
func (b *builder) bindArgs(field *Field, params *types.Tuple) error {
|
||||
var newArgs []*FieldArgument
|
||||
|
||||
nextArg:
|
||||
for j := 0; j < params.Len(); j++ {
|
||||
param := params.At(j)
|
||||
for _, oldArg := range field.Args {
|
||||
if strings.EqualFold(oldArg.Name, param.Name()) {
|
||||
tr, err := b.Binder.TypeReference(oldArg.Type, param.Type())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
oldArg.TypeReference = tr
|
||||
|
||||
newArgs = append(newArgs, oldArg)
|
||||
continue nextArg
|
||||
}
|
||||
}
|
||||
|
||||
// no matching arg found, abort
|
||||
return fmt.Errorf("arg %s not in schema", param.Name())
|
||||
}
|
||||
|
||||
field.Args = newArgs
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Data) Args() map[string][]*FieldArgument {
|
||||
ret := map[string][]*FieldArgument{}
|
||||
for _, o := range a.Objects {
|
||||
for _, f := range o.Fields {
|
||||
if len(f.Args) > 0 {
|
||||
ret[f.ArgsFunc()] = f.Args
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, d := range a.Directives {
|
||||
if len(d.Args) > 0 {
|
||||
ret[d.ArgsFunc()] = d.Args
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
35
vendor/github.com/99designs/gqlgen/codegen/args.gotpl
generated
vendored
35
vendor/github.com/99designs/gqlgen/codegen/args.gotpl
generated
vendored
@ -1,35 +0,0 @@
|
||||
{{ range $name, $args := .Args }}
|
||||
func (ec *executionContext) {{ $name }}(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
{{- range $i, $arg := . }}
|
||||
var arg{{$i}} {{ $arg.TypeReference.GO | ref}}
|
||||
if tmp, ok := rawArgs[{{$arg.Name|quote}}]; ok {
|
||||
{{- if $arg.ImplDirectives }}
|
||||
directive0 := func(ctx context.Context) (interface{}, error) { return ec.{{ $arg.TypeReference.UnmarshalFunc }}(ctx, tmp) }
|
||||
{{ template "implDirectives" $arg }}
|
||||
tmp, err = directive{{$arg.ImplDirectives|len}}(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if data, ok := tmp.({{ $arg.TypeReference.GO | ref }}) ; ok {
|
||||
arg{{$i}} = data
|
||||
{{- if $arg.TypeReference.IsNilable }}
|
||||
} else if tmp == nil {
|
||||
arg{{$i}} = nil
|
||||
{{- end }}
|
||||
} else {
|
||||
return nil, fmt.Errorf(`unexpected type %T from directive, should be {{ $arg.TypeReference.GO }}`, tmp)
|
||||
}
|
||||
{{- else }}
|
||||
arg{{$i}}, err = ec.{{ $arg.TypeReference.UnmarshalFunc }}(ctx, tmp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
{{- end }}
|
||||
}
|
||||
args[{{$arg.Name|quote}}] = arg{{$i}}
|
||||
{{- end }}
|
||||
return args, nil
|
||||
}
|
||||
{{ end }}
|
11
vendor/github.com/99designs/gqlgen/codegen/complexity.go
generated
vendored
11
vendor/github.com/99designs/gqlgen/codegen/complexity.go
generated
vendored
@ -1,11 +0,0 @@
|
||||
package codegen
|
||||
|
||||
func (o *Object) UniqueFields() map[string][]*Field {
|
||||
m := map[string][]*Field{}
|
||||
|
||||
for _, f := range o.Fields {
|
||||
m[f.GoFieldName] = append(m[f.GoFieldName], f)
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
448
vendor/github.com/99designs/gqlgen/codegen/config/binder.go
generated
vendored
448
vendor/github.com/99designs/gqlgen/codegen/config/binder.go
generated
vendored
@ -1,448 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/token"
|
||||
"go/types"
|
||||
|
||||
"github.com/99designs/gqlgen/codegen/templates"
|
||||
"github.com/99designs/gqlgen/internal/code"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
// Binder connects graphql types to golang types using static analysis
|
||||
type Binder struct {
|
||||
pkgs map[string]*packages.Package
|
||||
schema *ast.Schema
|
||||
cfg *Config
|
||||
References []*TypeReference
|
||||
}
|
||||
|
||||
func (c *Config) NewBinder(s *ast.Schema) (*Binder, error) {
|
||||
pkgs, err := packages.Load(&packages.Config{Mode: packages.LoadTypes | packages.LoadSyntax}, c.Models.ReferencedPackages()...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mp := map[string]*packages.Package{}
|
||||
for _, p := range pkgs {
|
||||
populatePkg(mp, p)
|
||||
for _, e := range p.Errors {
|
||||
if e.Kind == packages.ListError {
|
||||
return nil, p.Errors[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &Binder{
|
||||
pkgs: mp,
|
||||
schema: s,
|
||||
cfg: c,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func populatePkg(mp map[string]*packages.Package, p *packages.Package) {
|
||||
imp := code.NormalizeVendor(p.PkgPath)
|
||||
if _, ok := mp[imp]; ok {
|
||||
return
|
||||
}
|
||||
mp[imp] = p
|
||||
for _, p := range p.Imports {
|
||||
populatePkg(mp, p)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Binder) TypePosition(typ types.Type) token.Position {
|
||||
named, isNamed := typ.(*types.Named)
|
||||
if !isNamed {
|
||||
return token.Position{
|
||||
Filename: "unknown",
|
||||
}
|
||||
}
|
||||
|
||||
return b.ObjectPosition(named.Obj())
|
||||
}
|
||||
|
||||
func (b *Binder) ObjectPosition(typ types.Object) token.Position {
|
||||
if typ == nil {
|
||||
return token.Position{
|
||||
Filename: "unknown",
|
||||
}
|
||||
}
|
||||
pkg := b.getPkg(typ.Pkg().Path())
|
||||
return pkg.Fset.Position(typ.Pos())
|
||||
}
|
||||
|
||||
func (b *Binder) FindType(pkgName string, typeName string) (types.Type, error) {
|
||||
obj, err := b.FindObject(pkgName, typeName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if fun, isFunc := obj.(*types.Func); isFunc {
|
||||
return fun.Type().(*types.Signature).Params().At(0).Type(), nil
|
||||
}
|
||||
return obj.Type(), nil
|
||||
}
|
||||
|
||||
func (b *Binder) getPkg(find string) *packages.Package {
|
||||
imp := code.NormalizeVendor(find)
|
||||
if p, ok := b.pkgs[imp]; ok {
|
||||
return p
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var MapType = types.NewMap(types.Typ[types.String], types.NewInterfaceType(nil, nil).Complete())
|
||||
var InterfaceType = types.NewInterfaceType(nil, nil)
|
||||
|
||||
func (b *Binder) DefaultUserObject(name string) (types.Type, error) {
|
||||
models := b.cfg.Models[name].Model
|
||||
if len(models) == 0 {
|
||||
return nil, fmt.Errorf(name + " not found in typemap")
|
||||
}
|
||||
|
||||
if models[0] == "map[string]interface{}" {
|
||||
return MapType, nil
|
||||
}
|
||||
|
||||
if models[0] == "interface{}" {
|
||||
return InterfaceType, nil
|
||||
}
|
||||
|
||||
pkgName, typeName := code.PkgAndType(models[0])
|
||||
if pkgName == "" {
|
||||
return nil, fmt.Errorf("missing package name for %s", name)
|
||||
}
|
||||
|
||||
obj, err := b.FindObject(pkgName, typeName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.Type(), nil
|
||||
}
|
||||
|
||||
func (b *Binder) FindObject(pkgName string, typeName string) (types.Object, error) {
|
||||
if pkgName == "" {
|
||||
return nil, fmt.Errorf("package cannot be nil")
|
||||
}
|
||||
fullName := typeName
|
||||
if pkgName != "" {
|
||||
fullName = pkgName + "." + typeName
|
||||
}
|
||||
|
||||
pkg := b.getPkg(pkgName)
|
||||
if pkg == nil {
|
||||
return nil, errors.Errorf("required package was not loaded: %s", fullName)
|
||||
}
|
||||
|
||||
// function based marshalers take precedence
|
||||
for astNode, def := range pkg.TypesInfo.Defs {
|
||||
// only look at defs in the top scope
|
||||
if def == nil || def.Parent() == nil || def.Parent() != pkg.Types.Scope() {
|
||||
continue
|
||||
}
|
||||
|
||||
if astNode.Name == "Marshal"+typeName {
|
||||
return def, nil
|
||||
}
|
||||
}
|
||||
|
||||
// then look for types directly
|
||||
for astNode, def := range pkg.TypesInfo.Defs {
|
||||
// only look at defs in the top scope
|
||||
if def == nil || def.Parent() == nil || def.Parent() != pkg.Types.Scope() {
|
||||
continue
|
||||
}
|
||||
|
||||
if astNode.Name == typeName {
|
||||
return def, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.Errorf("unable to find type %s\n", fullName)
|
||||
}
|
||||
|
||||
func (b *Binder) PointerTo(ref *TypeReference) *TypeReference {
|
||||
newRef := &TypeReference{
|
||||
GO: types.NewPointer(ref.GO),
|
||||
GQL: ref.GQL,
|
||||
CastType: ref.CastType,
|
||||
Definition: ref.Definition,
|
||||
Unmarshaler: ref.Unmarshaler,
|
||||
Marshaler: ref.Marshaler,
|
||||
IsMarshaler: ref.IsMarshaler,
|
||||
}
|
||||
|
||||
b.References = append(b.References, newRef)
|
||||
return newRef
|
||||
}
|
||||
|
||||
// TypeReference is used by args and field types. The Definition can refer to both input and output types.
|
||||
type TypeReference struct {
|
||||
Definition *ast.Definition
|
||||
GQL *ast.Type
|
||||
GO types.Type
|
||||
CastType types.Type // Before calling marshalling functions cast from/to this base type
|
||||
Marshaler *types.Func // When using external marshalling functions this will point to the Marshal function
|
||||
Unmarshaler *types.Func // When using external marshalling functions this will point to the Unmarshal function
|
||||
IsMarshaler bool // Does the type implement graphql.Marshaler and graphql.Unmarshaler
|
||||
}
|
||||
|
||||
func (ref *TypeReference) Elem() *TypeReference {
|
||||
if p, isPtr := ref.GO.(*types.Pointer); isPtr {
|
||||
return &TypeReference{
|
||||
GO: p.Elem(),
|
||||
GQL: ref.GQL,
|
||||
CastType: ref.CastType,
|
||||
Definition: ref.Definition,
|
||||
Unmarshaler: ref.Unmarshaler,
|
||||
Marshaler: ref.Marshaler,
|
||||
IsMarshaler: ref.IsMarshaler,
|
||||
}
|
||||
}
|
||||
|
||||
if ref.IsSlice() {
|
||||
return &TypeReference{
|
||||
GO: ref.GO.(*types.Slice).Elem(),
|
||||
GQL: ref.GQL.Elem,
|
||||
CastType: ref.CastType,
|
||||
Definition: ref.Definition,
|
||||
Unmarshaler: ref.Unmarshaler,
|
||||
Marshaler: ref.Marshaler,
|
||||
IsMarshaler: ref.IsMarshaler,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TypeReference) IsPtr() bool {
|
||||
_, isPtr := t.GO.(*types.Pointer)
|
||||
return isPtr
|
||||
}
|
||||
|
||||
func (t *TypeReference) IsNilable() bool {
|
||||
_, isPtr := t.GO.(*types.Pointer)
|
||||
_, isMap := t.GO.(*types.Map)
|
||||
_, isInterface := t.GO.(*types.Interface)
|
||||
return isPtr || isMap || isInterface
|
||||
}
|
||||
|
||||
func (t *TypeReference) IsSlice() bool {
|
||||
_, isSlice := t.GO.(*types.Slice)
|
||||
return t.GQL.Elem != nil && isSlice
|
||||
}
|
||||
|
||||
func (t *TypeReference) IsNamed() bool {
|
||||
_, isSlice := t.GO.(*types.Named)
|
||||
return isSlice
|
||||
}
|
||||
|
||||
func (t *TypeReference) IsStruct() bool {
|
||||
_, isStruct := t.GO.Underlying().(*types.Struct)
|
||||
return isStruct
|
||||
}
|
||||
|
||||
func (t *TypeReference) IsScalar() bool {
|
||||
return t.Definition.Kind == ast.Scalar
|
||||
}
|
||||
|
||||
func (t *TypeReference) UniquenessKey() string {
|
||||
var nullability = "O"
|
||||
if t.GQL.NonNull {
|
||||
nullability = "N"
|
||||
}
|
||||
|
||||
return nullability + t.Definition.Name + "2" + templates.TypeIdentifier(t.GO)
|
||||
}
|
||||
|
||||
func (t *TypeReference) MarshalFunc() string {
|
||||
if t.Definition == nil {
|
||||
panic(errors.New("Definition missing for " + t.GQL.Name()))
|
||||
}
|
||||
|
||||
if t.Definition.Kind == ast.InputObject {
|
||||
return ""
|
||||
}
|
||||
|
||||
return "marshal" + t.UniquenessKey()
|
||||
}
|
||||
|
||||
func (t *TypeReference) UnmarshalFunc() string {
|
||||
if t.Definition == nil {
|
||||
panic(errors.New("Definition missing for " + t.GQL.Name()))
|
||||
}
|
||||
|
||||
if !t.Definition.IsInputType() {
|
||||
return ""
|
||||
}
|
||||
|
||||
return "unmarshal" + t.UniquenessKey()
|
||||
}
|
||||
|
||||
func (b *Binder) PushRef(ret *TypeReference) {
|
||||
b.References = append(b.References, ret)
|
||||
}
|
||||
|
||||
func isMap(t types.Type) bool {
|
||||
if t == nil {
|
||||
return true
|
||||
}
|
||||
_, ok := t.(*types.Map)
|
||||
return ok
|
||||
}
|
||||
|
||||
func isIntf(t types.Type) bool {
|
||||
if t == nil {
|
||||
return true
|
||||
}
|
||||
_, ok := t.(*types.Interface)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (b *Binder) TypeReference(schemaType *ast.Type, bindTarget types.Type) (ret *TypeReference, err error) {
|
||||
var pkgName, typeName string
|
||||
def := b.schema.Types[schemaType.Name()]
|
||||
defer func() {
|
||||
if err == nil && ret != nil {
|
||||
b.PushRef(ret)
|
||||
}
|
||||
}()
|
||||
|
||||
if len(b.cfg.Models[schemaType.Name()].Model) == 0 {
|
||||
return nil, fmt.Errorf("%s was not found", schemaType.Name())
|
||||
}
|
||||
|
||||
for _, model := range b.cfg.Models[schemaType.Name()].Model {
|
||||
if model == "map[string]interface{}" {
|
||||
if !isMap(bindTarget) {
|
||||
continue
|
||||
}
|
||||
return &TypeReference{
|
||||
Definition: def,
|
||||
GQL: schemaType,
|
||||
GO: MapType,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if model == "interface{}" {
|
||||
if !isIntf(bindTarget) {
|
||||
continue
|
||||
}
|
||||
return &TypeReference{
|
||||
Definition: def,
|
||||
GQL: schemaType,
|
||||
GO: InterfaceType,
|
||||
}, nil
|
||||
}
|
||||
|
||||
pkgName, typeName = code.PkgAndType(model)
|
||||
if pkgName == "" {
|
||||
return nil, fmt.Errorf("missing package name for %s", schemaType.Name())
|
||||
}
|
||||
|
||||
ref := &TypeReference{
|
||||
Definition: def,
|
||||
GQL: schemaType,
|
||||
}
|
||||
|
||||
obj, err := b.FindObject(pkgName, typeName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if fun, isFunc := obj.(*types.Func); isFunc {
|
||||
ref.GO = fun.Type().(*types.Signature).Params().At(0).Type()
|
||||
ref.Marshaler = fun
|
||||
ref.Unmarshaler = types.NewFunc(0, fun.Pkg(), "Unmarshal"+typeName, nil)
|
||||
} else if hasMethod(obj.Type(), "MarshalGQL") && hasMethod(obj.Type(), "UnmarshalGQL") {
|
||||
ref.GO = obj.Type()
|
||||
ref.IsMarshaler = true
|
||||
} else if underlying := basicUnderlying(obj.Type()); def.IsLeafType() && underlying != nil && underlying.Kind() == types.String {
|
||||
// Special case for named types wrapping strings. Used by default enum implementations.
|
||||
|
||||
ref.GO = obj.Type()
|
||||
ref.CastType = underlying
|
||||
|
||||
underlyingRef, err := b.TypeReference(&ast.Type{NamedType: "String"}, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ref.Marshaler = underlyingRef.Marshaler
|
||||
ref.Unmarshaler = underlyingRef.Unmarshaler
|
||||
} else {
|
||||
ref.GO = obj.Type()
|
||||
}
|
||||
|
||||
ref.GO = b.CopyModifiersFromAst(schemaType, ref.GO)
|
||||
|
||||
if bindTarget != nil {
|
||||
if err = code.CompatibleTypes(ref.GO, bindTarget); err != nil {
|
||||
continue
|
||||
}
|
||||
ref.GO = bindTarget
|
||||
}
|
||||
|
||||
return ref, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("%s has type compatible with %s", schemaType.Name(), bindTarget.String())
|
||||
}
|
||||
|
||||
func (b *Binder) CopyModifiersFromAst(t *ast.Type, base types.Type) types.Type {
|
||||
if t.Elem != nil {
|
||||
child := b.CopyModifiersFromAst(t.Elem, base)
|
||||
if _, isStruct := child.Underlying().(*types.Struct); isStruct {
|
||||
child = types.NewPointer(child)
|
||||
}
|
||||
return types.NewSlice(child)
|
||||
}
|
||||
|
||||
var isInterface bool
|
||||
if named, ok := base.(*types.Named); ok {
|
||||
_, isInterface = named.Underlying().(*types.Interface)
|
||||
}
|
||||
|
||||
if !isInterface && !t.NonNull {
|
||||
return types.NewPointer(base)
|
||||
}
|
||||
|
||||
return base
|
||||
}
|
||||
|
||||
func hasMethod(it types.Type, name string) bool {
|
||||
if ptr, isPtr := it.(*types.Pointer); isPtr {
|
||||
it = ptr.Elem()
|
||||
}
|
||||
namedType, ok := it.(*types.Named)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 0; i < namedType.NumMethods(); i++ {
|
||||
if namedType.Method(i).Name() == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func basicUnderlying(it types.Type) *types.Basic {
|
||||
if ptr, isPtr := it.(*types.Pointer); isPtr {
|
||||
it = ptr.Elem()
|
||||
}
|
||||
namedType, ok := it.(*types.Named)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
if basic, ok := namedType.Underlying().(*types.Basic); ok {
|
||||
return basic
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
490
vendor/github.com/99designs/gqlgen/codegen/config/config.go
generated
vendored
490
vendor/github.com/99designs/gqlgen/codegen/config/config.go
generated
vendored
@ -1,490 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/types"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
|
||||
"github.com/99designs/gqlgen/internal/code"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/vektah/gqlparser"
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
SchemaFilename StringList `yaml:"schema,omitempty"`
|
||||
Exec PackageConfig `yaml:"exec"`
|
||||
Model PackageConfig `yaml:"model"`
|
||||
Resolver PackageConfig `yaml:"resolver,omitempty"`
|
||||
AutoBind []string `yaml:"autobind"`
|
||||
Models TypeMap `yaml:"models,omitempty"`
|
||||
StructTag string `yaml:"struct_tag,omitempty"`
|
||||
Directives map[string]DirectiveConfig `yaml:"directives,omitempty"`
|
||||
}
|
||||
|
||||
var cfgFilenames = []string{".gqlgen.yml", "gqlgen.yml", "gqlgen.yaml"}
|
||||
|
||||
// DefaultConfig creates a copy of the default config
|
||||
func DefaultConfig() *Config {
|
||||
return &Config{
|
||||
SchemaFilename: StringList{"schema.graphql"},
|
||||
Model: PackageConfig{Filename: "models_gen.go"},
|
||||
Exec: PackageConfig{Filename: "generated.go"},
|
||||
Directives: map[string]DirectiveConfig{},
|
||||
}
|
||||
}
|
||||
|
||||
// LoadConfigFromDefaultLocations looks for a config file in the current directory, and all parent directories
|
||||
// walking up the tree. The closest config file will be returned.
|
||||
func LoadConfigFromDefaultLocations() (*Config, error) {
|
||||
cfgFile, err := findCfg()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = os.Chdir(filepath.Dir(cfgFile))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to enter config dir")
|
||||
}
|
||||
return LoadConfig(cfgFile)
|
||||
}
|
||||
|
||||
var path2regex = strings.NewReplacer(
|
||||
`.`, `\.`,
|
||||
`*`, `.+`,
|
||||
`\`, `[\\/]`,
|
||||
`/`, `[\\/]`,
|
||||
)
|
||||
|
||||
// LoadConfig reads the gqlgen.yml config file
|
||||
func LoadConfig(filename string) (*Config, error) {
|
||||
config := DefaultConfig()
|
||||
|
||||
b, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to read config")
|
||||
}
|
||||
|
||||
if err := yaml.UnmarshalStrict(b, config); err != nil {
|
||||
return nil, errors.Wrap(err, "unable to parse config")
|
||||
}
|
||||
|
||||
defaultDirectives := map[string]DirectiveConfig{
|
||||
"skip": {SkipRuntime: true},
|
||||
"include": {SkipRuntime: true},
|
||||
"deprecated": {SkipRuntime: true},
|
||||
}
|
||||
|
||||
for key, value := range defaultDirectives {
|
||||
if _, defined := config.Directives[key]; !defined {
|
||||
config.Directives[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
preGlobbing := config.SchemaFilename
|
||||
config.SchemaFilename = StringList{}
|
||||
for _, f := range preGlobbing {
|
||||
var matches []string
|
||||
|
||||
// for ** we want to override default globbing patterns and walk all
|
||||
// subdirectories to match schema files.
|
||||
if strings.Contains(f, "**") {
|
||||
pathParts := strings.SplitN(f, "**", 2)
|
||||
rest := strings.TrimPrefix(strings.TrimPrefix(pathParts[1], `\`), `/`)
|
||||
// turn the rest of the glob into a regex, anchored only at the end because ** allows
|
||||
// for any number of dirs in between and walk will let us match against the full path name
|
||||
globRe := regexp.MustCompile(path2regex.Replace(rest) + `$`)
|
||||
|
||||
if err := filepath.Walk(pathParts[0], func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if globRe.MatchString(strings.TrimPrefix(path, pathParts[0])) {
|
||||
matches = append(matches, path)
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to walk schema at root %s", pathParts[0])
|
||||
}
|
||||
} else {
|
||||
matches, err = filepath.Glob(f)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to glob schema filename %s", f)
|
||||
}
|
||||
}
|
||||
|
||||
for _, m := range matches {
|
||||
if config.SchemaFilename.Has(m) {
|
||||
continue
|
||||
}
|
||||
config.SchemaFilename = append(config.SchemaFilename, m)
|
||||
}
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
type PackageConfig struct {
|
||||
Filename string `yaml:"filename,omitempty"`
|
||||
Package string `yaml:"package,omitempty"`
|
||||
Type string `yaml:"type,omitempty"`
|
||||
}
|
||||
|
||||
type TypeMapEntry struct {
|
||||
Model StringList `yaml:"model"`
|
||||
Fields map[string]TypeMapField `yaml:"fields,omitempty"`
|
||||
}
|
||||
|
||||
type TypeMapField struct {
|
||||
Resolver bool `yaml:"resolver"`
|
||||
FieldName string `yaml:"fieldName"`
|
||||
}
|
||||
|
||||
type StringList []string
|
||||
|
||||
func (a *StringList) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
var single string
|
||||
err := unmarshal(&single)
|
||||
if err == nil {
|
||||
*a = []string{single}
|
||||
return nil
|
||||
}
|
||||
|
||||
var multi []string
|
||||
err = unmarshal(&multi)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*a = multi
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a StringList) Has(file string) bool {
|
||||
for _, existing := range a {
|
||||
if existing == file {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *PackageConfig) normalize() error {
|
||||
if c.Filename == "" {
|
||||
return errors.New("Filename is required")
|
||||
}
|
||||
c.Filename = abs(c.Filename)
|
||||
// If Package is not set, first attempt to load the package at the output dir. If that fails
|
||||
// fallback to just the base dir name of the output filename.
|
||||
if c.Package == "" {
|
||||
c.Package = code.NameForDir(c.Dir())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *PackageConfig) ImportPath() string {
|
||||
return code.ImportPathForDir(c.Dir())
|
||||
}
|
||||
|
||||
func (c *PackageConfig) Dir() string {
|
||||
return filepath.Dir(c.Filename)
|
||||
}
|
||||
|
||||
func (c *PackageConfig) Check() error {
|
||||
if strings.ContainsAny(c.Package, "./\\") {
|
||||
return fmt.Errorf("package should be the output package name only, do not include the output filename")
|
||||
}
|
||||
if c.Filename != "" && !strings.HasSuffix(c.Filename, ".go") {
|
||||
return fmt.Errorf("filename should be path to a go source file")
|
||||
}
|
||||
|
||||
return c.normalize()
|
||||
}
|
||||
|
||||
func (c *PackageConfig) Pkg() *types.Package {
|
||||
return types.NewPackage(c.ImportPath(), c.Dir())
|
||||
}
|
||||
|
||||
func (c *PackageConfig) IsDefined() bool {
|
||||
return c.Filename != ""
|
||||
}
|
||||
|
||||
func (c *Config) Check() error {
|
||||
if err := c.Models.Check(); err != nil {
|
||||
return errors.Wrap(err, "config.models")
|
||||
}
|
||||
if err := c.Exec.Check(); err != nil {
|
||||
return errors.Wrap(err, "config.exec")
|
||||
}
|
||||
if err := c.Model.Check(); err != nil {
|
||||
return errors.Wrap(err, "config.model")
|
||||
}
|
||||
if c.Resolver.IsDefined() {
|
||||
if err := c.Resolver.Check(); err != nil {
|
||||
return errors.Wrap(err, "config.resolver")
|
||||
}
|
||||
}
|
||||
|
||||
// check packages names against conflict, if present in the same dir
|
||||
// and check filenames for uniqueness
|
||||
packageConfigList := []PackageConfig{
|
||||
c.Model,
|
||||
c.Exec,
|
||||
c.Resolver,
|
||||
}
|
||||
filesMap := make(map[string]bool)
|
||||
pkgConfigsByDir := make(map[string]PackageConfig)
|
||||
for _, current := range packageConfigList {
|
||||
_, fileFound := filesMap[current.Filename]
|
||||
if fileFound {
|
||||
return fmt.Errorf("filename %s defined more than once", current.Filename)
|
||||
}
|
||||
filesMap[current.Filename] = true
|
||||
previous, inSameDir := pkgConfigsByDir[current.Dir()]
|
||||
if inSameDir && current.Package != previous.Package {
|
||||
return fmt.Errorf("filenames %s and %s are in the same directory but have different package definitions", stripPath(current.Filename), stripPath(previous.Filename))
|
||||
}
|
||||
pkgConfigsByDir[current.Dir()] = current
|
||||
}
|
||||
|
||||
return c.normalize()
|
||||
}
|
||||
|
||||
func stripPath(path string) string {
|
||||
return filepath.Base(path)
|
||||
}
|
||||
|
||||
type TypeMap map[string]TypeMapEntry
|
||||
|
||||
func (tm TypeMap) Exists(typeName string) bool {
|
||||
_, ok := tm[typeName]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (tm TypeMap) UserDefined(typeName string) bool {
|
||||
m, ok := tm[typeName]
|
||||
return ok && len(m.Model) > 0
|
||||
}
|
||||
|
||||
func (tm TypeMap) Check() error {
|
||||
for typeName, entry := range tm {
|
||||
for _, model := range entry.Model {
|
||||
if strings.LastIndex(model, ".") < strings.LastIndex(model, "/") {
|
||||
return fmt.Errorf("model %s: invalid type specifier \"%s\" - you need to specify a struct to map to", typeName, entry.Model)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tm TypeMap) ReferencedPackages() []string {
|
||||
var pkgs []string
|
||||
|
||||
for _, typ := range tm {
|
||||
for _, model := range typ.Model {
|
||||
if model == "map[string]interface{}" || model == "interface{}" {
|
||||
continue
|
||||
}
|
||||
pkg, _ := code.PkgAndType(model)
|
||||
if pkg == "" || inStrSlice(pkgs, pkg) {
|
||||
continue
|
||||
}
|
||||
pkgs = append(pkgs, code.QualifyPackagePath(pkg))
|
||||
}
|
||||
}
|
||||
|
||||
sort.Slice(pkgs, func(i, j int) bool {
|
||||
return pkgs[i] > pkgs[j]
|
||||
})
|
||||
return pkgs
|
||||
}
|
||||
|
||||
func (tm TypeMap) Add(name string, goType string) {
|
||||
modelCfg := tm[name]
|
||||
modelCfg.Model = append(modelCfg.Model, goType)
|
||||
tm[name] = modelCfg
|
||||
}
|
||||
|
||||
type DirectiveConfig struct {
|
||||
SkipRuntime bool `yaml:"skip_runtime"`
|
||||
}
|
||||
|
||||
func inStrSlice(haystack []string, needle string) bool {
|
||||
for _, v := range haystack {
|
||||
if needle == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// findCfg searches for the config file in this directory and all parents up the tree
|
||||
// looking for the closest match
|
||||
func findCfg() (string, error) {
|
||||
dir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "unable to get working dir to findCfg")
|
||||
}
|
||||
|
||||
cfg := findCfgInDir(dir)
|
||||
|
||||
for cfg == "" && dir != filepath.Dir(dir) {
|
||||
dir = filepath.Dir(dir)
|
||||
cfg = findCfgInDir(dir)
|
||||
}
|
||||
|
||||
if cfg == "" {
|
||||
return "", os.ErrNotExist
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func findCfgInDir(dir string) string {
|
||||
for _, cfgName := range cfgFilenames {
|
||||
path := filepath.Join(dir, cfgName)
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
return path
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *Config) normalize() error {
|
||||
if err := c.Model.normalize(); err != nil {
|
||||
return errors.Wrap(err, "model")
|
||||
}
|
||||
|
||||
if err := c.Exec.normalize(); err != nil {
|
||||
return errors.Wrap(err, "exec")
|
||||
}
|
||||
|
||||
if c.Resolver.IsDefined() {
|
||||
if err := c.Resolver.normalize(); err != nil {
|
||||
return errors.Wrap(err, "resolver")
|
||||
}
|
||||
}
|
||||
|
||||
if c.Models == nil {
|
||||
c.Models = TypeMap{}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Config) Autobind(s *ast.Schema) error {
|
||||
if len(c.AutoBind) == 0 {
|
||||
return nil
|
||||
}
|
||||
ps, err := packages.Load(&packages.Config{Mode: packages.LoadTypes}, c.AutoBind...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, t := range s.Types {
|
||||
if c.Models.UserDefined(t.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, p := range ps {
|
||||
if t := p.Types.Scope().Lookup(t.Name); t != nil {
|
||||
c.Models.Add(t.Name(), t.Pkg().Path()+"."+t.Name())
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Config) InjectBuiltins(s *ast.Schema) {
|
||||
builtins := TypeMap{
|
||||
"__Directive": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.Directive"}},
|
||||
"__DirectiveLocation": {Model: StringList{"github.com/99designs/gqlgen/graphql.String"}},
|
||||
"__Type": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.Type"}},
|
||||
"__TypeKind": {Model: StringList{"github.com/99designs/gqlgen/graphql.String"}},
|
||||
"__Field": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.Field"}},
|
||||
"__EnumValue": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.EnumValue"}},
|
||||
"__InputValue": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.InputValue"}},
|
||||
"__Schema": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.Schema"}},
|
||||
"Float": {Model: StringList{"github.com/99designs/gqlgen/graphql.Float"}},
|
||||
"String": {Model: StringList{"github.com/99designs/gqlgen/graphql.String"}},
|
||||
"Boolean": {Model: StringList{"github.com/99designs/gqlgen/graphql.Boolean"}},
|
||||
"Int": {Model: StringList{
|
||||
"github.com/99designs/gqlgen/graphql.Int",
|
||||
"github.com/99designs/gqlgen/graphql.Int32",
|
||||
"github.com/99designs/gqlgen/graphql.Int64",
|
||||
}},
|
||||
"ID": {
|
||||
Model: StringList{
|
||||
"github.com/99designs/gqlgen/graphql.ID",
|
||||
"github.com/99designs/gqlgen/graphql.IntID",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for typeName, entry := range builtins {
|
||||
if !c.Models.Exists(typeName) {
|
||||
c.Models[typeName] = entry
|
||||
}
|
||||
}
|
||||
|
||||
// These are additional types that are injected if defined in the schema as scalars.
|
||||
extraBuiltins := TypeMap{
|
||||
"Time": {Model: StringList{"github.com/99designs/gqlgen/graphql.Time"}},
|
||||
"Map": {Model: StringList{"github.com/99designs/gqlgen/graphql.Map"}},
|
||||
"Upload": {Model: StringList{"github.com/99designs/gqlgen/graphql.Upload"}},
|
||||
"Any": {Model: StringList{"github.com/99designs/gqlgen/graphql.Any"}},
|
||||
}
|
||||
|
||||
for typeName, entry := range extraBuiltins {
|
||||
if t, ok := s.Types[typeName]; !c.Models.Exists(typeName) && ok && t.Kind == ast.Scalar {
|
||||
c.Models[typeName] = entry
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Config) LoadSchema() (*ast.Schema, map[string]string, error) {
|
||||
schemaStrings := map[string]string{}
|
||||
|
||||
sources := make([]*ast.Source, len(c.SchemaFilename))
|
||||
|
||||
for i, filename := range c.SchemaFilename {
|
||||
filename = filepath.ToSlash(filename)
|
||||
var err error
|
||||
var schemaRaw []byte
|
||||
schemaRaw, err = ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "unable to open schema: "+err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
schemaStrings[filename] = string(schemaRaw)
|
||||
sources[i] = &ast.Source{Name: filename, Input: schemaStrings[filename]}
|
||||
}
|
||||
|
||||
schema, err := gqlparser.LoadSchema(sources...)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return schema, schemaStrings, nil
|
||||
}
|
||||
|
||||
func abs(path string) string {
|
||||
absPath, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return filepath.ToSlash(absPath)
|
||||
}
|
170
vendor/github.com/99designs/gqlgen/codegen/data.go
generated
vendored
170
vendor/github.com/99designs/gqlgen/codegen/data.go
generated
vendored
@ -1,170 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/99designs/gqlgen/codegen/config"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
)
|
||||
|
||||
// Data is a unified model of the code to be generated. Plugins may modify this structure to do things like implement
|
||||
// resolvers or directives automatically (eg grpc, validation)
|
||||
type Data struct {
|
||||
Config *config.Config
|
||||
Schema *ast.Schema
|
||||
SchemaStr map[string]string
|
||||
Directives DirectiveList
|
||||
Objects Objects
|
||||
Inputs Objects
|
||||
Interfaces map[string]*Interface
|
||||
ReferencedTypes map[string]*config.TypeReference
|
||||
ComplexityRoots map[string]*Object
|
||||
|
||||
QueryRoot *Object
|
||||
MutationRoot *Object
|
||||
SubscriptionRoot *Object
|
||||
}
|
||||
|
||||
type builder struct {
|
||||
Config *config.Config
|
||||
Schema *ast.Schema
|
||||
SchemaStr map[string]string
|
||||
Binder *config.Binder
|
||||
Directives map[string]*Directive
|
||||
}
|
||||
|
||||
func BuildData(cfg *config.Config) (*Data, error) {
|
||||
b := builder{
|
||||
Config: cfg,
|
||||
}
|
||||
|
||||
var err error
|
||||
b.Schema, b.SchemaStr, err = cfg.LoadSchema()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = cfg.Check()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = cfg.Autobind(b.Schema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg.InjectBuiltins(b.Schema)
|
||||
|
||||
b.Binder, err = b.Config.NewBinder(b.Schema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b.Directives, err = b.buildDirectives()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dataDirectives := make(map[string]*Directive)
|
||||
for name, d := range b.Directives {
|
||||
if !d.Builtin {
|
||||
dataDirectives[name] = d
|
||||
}
|
||||
}
|
||||
|
||||
s := Data{
|
||||
Config: cfg,
|
||||
Directives: dataDirectives,
|
||||
Schema: b.Schema,
|
||||
SchemaStr: b.SchemaStr,
|
||||
Interfaces: map[string]*Interface{},
|
||||
}
|
||||
|
||||
for _, schemaType := range b.Schema.Types {
|
||||
switch schemaType.Kind {
|
||||
case ast.Object:
|
||||
obj, err := b.buildObject(schemaType)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to build object definition")
|
||||
}
|
||||
|
||||
s.Objects = append(s.Objects, obj)
|
||||
case ast.InputObject:
|
||||
input, err := b.buildObject(schemaType)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to build input definition")
|
||||
}
|
||||
|
||||
s.Inputs = append(s.Inputs, input)
|
||||
|
||||
case ast.Union, ast.Interface:
|
||||
s.Interfaces[schemaType.Name] = b.buildInterface(schemaType)
|
||||
}
|
||||
}
|
||||
|
||||
if s.Schema.Query != nil {
|
||||
s.QueryRoot = s.Objects.ByName(s.Schema.Query.Name)
|
||||
} else {
|
||||
return nil, fmt.Errorf("query entry point missing")
|
||||
}
|
||||
|
||||
if s.Schema.Mutation != nil {
|
||||
s.MutationRoot = s.Objects.ByName(s.Schema.Mutation.Name)
|
||||
}
|
||||
|
||||
if s.Schema.Subscription != nil {
|
||||
s.SubscriptionRoot = s.Objects.ByName(s.Schema.Subscription.Name)
|
||||
}
|
||||
|
||||
if err := b.injectIntrospectionRoots(&s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.ReferencedTypes = b.buildTypes()
|
||||
|
||||
sort.Slice(s.Objects, func(i, j int) bool {
|
||||
return s.Objects[i].Definition.Name < s.Objects[j].Definition.Name
|
||||
})
|
||||
|
||||
sort.Slice(s.Inputs, func(i, j int) bool {
|
||||
return s.Inputs[i].Definition.Name < s.Inputs[j].Definition.Name
|
||||
})
|
||||
|
||||
return &s, nil
|
||||
}
|
||||
|
||||
func (b *builder) injectIntrospectionRoots(s *Data) error {
|
||||
obj := s.Objects.ByName(b.Schema.Query.Name)
|
||||
if obj == nil {
|
||||
return fmt.Errorf("root query type must be defined")
|
||||
}
|
||||
|
||||
__type, err := b.buildField(obj, &ast.FieldDefinition{
|
||||
Name: "__type",
|
||||
Type: ast.NamedType("__Type", nil),
|
||||
Arguments: []*ast.ArgumentDefinition{
|
||||
{
|
||||
Name: "name",
|
||||
Type: ast.NonNullNamedType("String", nil),
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
__schema, err := b.buildField(obj, &ast.FieldDefinition{
|
||||
Name: "__schema",
|
||||
Type: ast.NamedType("__Schema", nil),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
obj.Fields = append(obj.Fields, __type, __schema)
|
||||
|
||||
return nil
|
||||
}
|
175
vendor/github.com/99designs/gqlgen/codegen/directive.go
generated
vendored
175
vendor/github.com/99designs/gqlgen/codegen/directive.go
generated
vendored
@ -1,175 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/99designs/gqlgen/codegen/templates"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
)
|
||||
|
||||
type DirectiveList map[string]*Directive
|
||||
|
||||
//LocationDirectives filter directives by location
|
||||
func (dl DirectiveList) LocationDirectives(location string) DirectiveList {
|
||||
return locationDirectives(dl, ast.DirectiveLocation(location))
|
||||
}
|
||||
|
||||
type Directive struct {
|
||||
*ast.DirectiveDefinition
|
||||
Name string
|
||||
Args []*FieldArgument
|
||||
Builtin bool
|
||||
}
|
||||
|
||||
//IsLocation check location directive
|
||||
func (d *Directive) IsLocation(location ...ast.DirectiveLocation) bool {
|
||||
for _, l := range d.Locations {
|
||||
for _, a := range location {
|
||||
if l == a {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func locationDirectives(directives DirectiveList, location ...ast.DirectiveLocation) map[string]*Directive {
|
||||
mDirectives := make(map[string]*Directive)
|
||||
for name, d := range directives {
|
||||
if d.IsLocation(location...) {
|
||||
mDirectives[name] = d
|
||||
}
|
||||
}
|
||||
return mDirectives
|
||||
}
|
||||
|
||||
func (b *builder) buildDirectives() (map[string]*Directive, error) {
|
||||
directives := make(map[string]*Directive, len(b.Schema.Directives))
|
||||
|
||||
for name, dir := range b.Schema.Directives {
|
||||
if _, ok := directives[name]; ok {
|
||||
return nil, errors.Errorf("directive with name %s already exists", name)
|
||||
}
|
||||
|
||||
var args []*FieldArgument
|
||||
for _, arg := range dir.Arguments {
|
||||
tr, err := b.Binder.TypeReference(arg.Type, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newArg := &FieldArgument{
|
||||
ArgumentDefinition: arg,
|
||||
TypeReference: tr,
|
||||
VarName: templates.ToGoPrivate(arg.Name),
|
||||
}
|
||||
|
||||
if arg.DefaultValue != nil {
|
||||
var err error
|
||||
newArg.Default, err = arg.DefaultValue.Value(nil)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("default value for directive argument %s(%s) is not valid: %s", dir.Name, arg.Name, err.Error())
|
||||
}
|
||||
}
|
||||
args = append(args, newArg)
|
||||
}
|
||||
|
||||
directives[name] = &Directive{
|
||||
DirectiveDefinition: dir,
|
||||
Name: name,
|
||||
Args: args,
|
||||
Builtin: b.Config.Directives[name].SkipRuntime,
|
||||
}
|
||||
}
|
||||
|
||||
return directives, nil
|
||||
}
|
||||
|
||||
func (b *builder) getDirectives(list ast.DirectiveList) ([]*Directive, error) {
|
||||
dirs := make([]*Directive, len(list))
|
||||
for i, d := range list {
|
||||
argValues := make(map[string]interface{}, len(d.Arguments))
|
||||
for _, da := range d.Arguments {
|
||||
val, err := da.Value.Value(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
argValues[da.Name] = val
|
||||
}
|
||||
def, ok := b.Directives[d.Name]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("directive %s not found", d.Name)
|
||||
}
|
||||
|
||||
var args []*FieldArgument
|
||||
for _, a := range def.Args {
|
||||
value := a.Default
|
||||
if argValue, ok := argValues[a.Name]; ok {
|
||||
value = argValue
|
||||
}
|
||||
args = append(args, &FieldArgument{
|
||||
ArgumentDefinition: a.ArgumentDefinition,
|
||||
Value: value,
|
||||
VarName: a.VarName,
|
||||
TypeReference: a.TypeReference,
|
||||
})
|
||||
}
|
||||
dirs[i] = &Directive{
|
||||
Name: d.Name,
|
||||
Args: args,
|
||||
DirectiveDefinition: list[i].Definition,
|
||||
Builtin: b.Config.Directives[d.Name].SkipRuntime,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return dirs, nil
|
||||
}
|
||||
|
||||
func (d *Directive) ArgsFunc() string {
|
||||
if len(d.Args) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
return "dir_" + d.Name + "_args"
|
||||
}
|
||||
|
||||
func (d *Directive) CallArgs() string {
|
||||
args := []string{"ctx", "obj", "n"}
|
||||
|
||||
for _, arg := range d.Args {
|
||||
args = append(args, "args["+strconv.Quote(arg.Name)+"].("+templates.CurrentImports.LookupType(arg.TypeReference.GO)+")")
|
||||
}
|
||||
|
||||
return strings.Join(args, ", ")
|
||||
}
|
||||
|
||||
func (d *Directive) ResolveArgs(obj string, next int) string {
|
||||
args := []string{"ctx", obj, fmt.Sprintf("directive%d", next)}
|
||||
|
||||
for _, arg := range d.Args {
|
||||
dArg := arg.VarName
|
||||
if arg.Value == nil && arg.Default == nil {
|
||||
dArg = "nil"
|
||||
}
|
||||
|
||||
args = append(args, dArg)
|
||||
}
|
||||
|
||||
return strings.Join(args, ", ")
|
||||
}
|
||||
|
||||
func (d *Directive) Declaration() string {
|
||||
res := ucFirst(d.Name) + " func(ctx context.Context, obj interface{}, next graphql.Resolver"
|
||||
|
||||
for _, arg := range d.Args {
|
||||
res += fmt.Sprintf(", %s %s", arg.Name, templates.CurrentImports.LookupType(arg.TypeReference.GO))
|
||||
}
|
||||
|
||||
res += ") (res interface{}, err error)"
|
||||
return res
|
||||
}
|
137
vendor/github.com/99designs/gqlgen/codegen/directives.gotpl
generated
vendored
137
vendor/github.com/99designs/gqlgen/codegen/directives.gotpl
generated
vendored
@ -1,137 +0,0 @@
|
||||
{{ define "implDirectives" }}{{ $in := .DirectiveObjName }}
|
||||
{{- range $i, $directive := .ImplDirectives -}}
|
||||
directive{{add $i 1}} := func(ctx context.Context) (interface{}, error) {
|
||||
{{- range $arg := $directive.Args }}
|
||||
{{- if notNil "Value" $arg }}
|
||||
{{ $arg.VarName }}, err := ec.{{ $arg.TypeReference.UnmarshalFunc }}(ctx, {{ $arg.Value | dump }})
|
||||
if err != nil{
|
||||
return nil, err
|
||||
}
|
||||
{{- else if notNil "Default" $arg }}
|
||||
{{ $arg.VarName }}, err := ec.{{ $arg.TypeReference.UnmarshalFunc }}(ctx, {{ $arg.Default | dump }})
|
||||
if err != nil{
|
||||
return nil, err
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
return ec.directives.{{$directive.Name|ucFirst}}({{$directive.ResolveArgs $in $i }})
|
||||
}
|
||||
{{- end -}}
|
||||
{{ end }}
|
||||
|
||||
{{define "queryDirectives"}}
|
||||
for _, d := range obj.Directives {
|
||||
switch d.Name {
|
||||
{{- range $directive := . }}
|
||||
case "{{$directive.Name}}":
|
||||
{{- if $directive.Args }}
|
||||
rawArgs := d.ArgumentMap(ec.Variables)
|
||||
args, err := ec.{{ $directive.ArgsFunc }}(ctx,rawArgs)
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
{{- end }}
|
||||
n := next
|
||||
next = func(ctx context.Context) (interface{}, error) {
|
||||
return ec.directives.{{$directive.Name|ucFirst}}({{$directive.CallArgs}})
|
||||
}
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
tmp, err := next(ctx)
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if data, ok := tmp.(graphql.Marshaler); ok {
|
||||
return data
|
||||
}
|
||||
ec.Errorf(ctx, `unexpected type %T from directive, should be graphql.Marshaler`, tmp)
|
||||
return graphql.Null
|
||||
{{end}}
|
||||
|
||||
{{ if .Directives.LocationDirectives "QUERY" }}
|
||||
func (ec *executionContext) _queryMiddleware(ctx context.Context, obj *ast.OperationDefinition, next func(ctx context.Context) (interface{}, error)) graphql.Marshaler {
|
||||
{{ template "queryDirectives" .Directives.LocationDirectives "QUERY" }}
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
{{ if .Directives.LocationDirectives "MUTATION" }}
|
||||
func (ec *executionContext) _mutationMiddleware(ctx context.Context, obj *ast.OperationDefinition, next func(ctx context.Context) (interface{}, error)) graphql.Marshaler {
|
||||
{{ template "queryDirectives" .Directives.LocationDirectives "MUTATION" }}
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
{{ if .Directives.LocationDirectives "SUBSCRIPTION" }}
|
||||
func (ec *executionContext) _subscriptionMiddleware(ctx context.Context, obj *ast.OperationDefinition, next func(ctx context.Context) (interface{}, error)) func() graphql.Marshaler {
|
||||
for _, d := range obj.Directives {
|
||||
switch d.Name {
|
||||
{{- range $directive := .Directives.LocationDirectives "SUBSCRIPTION" }}
|
||||
case "{{$directive.Name}}":
|
||||
{{- if $directive.Args }}
|
||||
rawArgs := d.ArgumentMap(ec.Variables)
|
||||
args, err := ec.{{ $directive.ArgsFunc }}(ctx,rawArgs)
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return func() graphql.Marshaler {
|
||||
return graphql.Null
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
n := next
|
||||
next = func(ctx context.Context) (interface{}, error) {
|
||||
return ec.directives.{{$directive.Name|ucFirst}}({{$directive.CallArgs}})
|
||||
}
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
tmp, err := next(ctx)
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return func() graphql.Marshaler {
|
||||
return graphql.Null
|
||||
}
|
||||
}
|
||||
if data, ok := tmp.(func() graphql.Marshaler); ok {
|
||||
return data
|
||||
}
|
||||
ec.Errorf(ctx, `unexpected type %T from directive, should be graphql.Marshaler`, tmp)
|
||||
return func() graphql.Marshaler {
|
||||
return graphql.Null
|
||||
}
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
{{ if .Directives.LocationDirectives "FIELD" }}
|
||||
func (ec *executionContext) _fieldMiddleware(ctx context.Context, obj interface{}, next graphql.Resolver) interface{} {
|
||||
{{- if .Directives.LocationDirectives "FIELD" }}
|
||||
rctx := graphql.GetResolverContext(ctx)
|
||||
for _, d := range rctx.Field.Directives {
|
||||
switch d.Name {
|
||||
{{- range $directive := .Directives.LocationDirectives "FIELD" }}
|
||||
case "{{$directive.Name}}":
|
||||
{{- if $directive.Args }}
|
||||
rawArgs := d.ArgumentMap(ec.Variables)
|
||||
args, err := ec.{{ $directive.ArgsFunc }}(ctx,rawArgs)
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return nil
|
||||
}
|
||||
{{- end }}
|
||||
n := next
|
||||
next = func(ctx context.Context) (interface{}, error) {
|
||||
return ec.directives.{{$directive.Name|ucFirst}}({{$directive.CallArgs}})
|
||||
}
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
res, err := ec.ResolverMiddleware(ctx, next)
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return nil
|
||||
}
|
||||
return res
|
||||
}
|
||||
{{ end }}
|
413
vendor/github.com/99designs/gqlgen/codegen/field.go
generated
vendored
413
vendor/github.com/99designs/gqlgen/codegen/field.go
generated
vendored
@ -1,413 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/types"
|
||||
"log"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/99designs/gqlgen/codegen/config"
|
||||
"github.com/99designs/gqlgen/codegen/templates"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
)
|
||||
|
||||
type Field struct {
|
||||
*ast.FieldDefinition
|
||||
|
||||
TypeReference *config.TypeReference
|
||||
GoFieldType GoFieldType // The field type in go, if any
|
||||
GoReceiverName string // The name of method & var receiver in go, if any
|
||||
GoFieldName string // The name of the method or var in go, if any
|
||||
IsResolver bool // Does this field need a resolver
|
||||
Args []*FieldArgument // A list of arguments to be passed to this field
|
||||
MethodHasContext bool // If this is bound to a go method, does the method also take a context
|
||||
NoErr bool // If this is bound to a go method, does that method have an error as the second argument
|
||||
Object *Object // A link back to the parent object
|
||||
Default interface{} // The default value
|
||||
Directives []*Directive
|
||||
}
|
||||
|
||||
func (b *builder) buildField(obj *Object, field *ast.FieldDefinition) (*Field, error) {
|
||||
dirs, err := b.getDirectives(field.Directives)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f := Field{
|
||||
FieldDefinition: field,
|
||||
Object: obj,
|
||||
Directives: dirs,
|
||||
GoFieldName: templates.ToGo(field.Name),
|
||||
GoFieldType: GoFieldVariable,
|
||||
GoReceiverName: "obj",
|
||||
}
|
||||
|
||||
if field.DefaultValue != nil {
|
||||
var err error
|
||||
f.Default, err = field.DefaultValue.Value(nil)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("default value %s is not valid: %s", field.Name, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
for _, arg := range field.Arguments {
|
||||
newArg, err := b.buildArg(obj, arg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.Args = append(f.Args, newArg)
|
||||
}
|
||||
|
||||
if err = b.bindField(obj, &f); err != nil {
|
||||
f.IsResolver = true
|
||||
log.Println(err.Error())
|
||||
}
|
||||
|
||||
if f.IsResolver && !f.TypeReference.IsPtr() && f.TypeReference.IsStruct() {
|
||||
f.TypeReference = b.Binder.PointerTo(f.TypeReference)
|
||||
}
|
||||
|
||||
return &f, nil
|
||||
}
|
||||
|
||||
func (b *builder) bindField(obj *Object, f *Field) error {
|
||||
defer func() {
|
||||
if f.TypeReference == nil {
|
||||
tr, err := b.Binder.TypeReference(f.Type, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
f.TypeReference = tr
|
||||
}
|
||||
}()
|
||||
|
||||
switch {
|
||||
case f.Name == "__schema":
|
||||
f.GoFieldType = GoFieldMethod
|
||||
f.GoReceiverName = "ec"
|
||||
f.GoFieldName = "introspectSchema"
|
||||
return nil
|
||||
case f.Name == "__type":
|
||||
f.GoFieldType = GoFieldMethod
|
||||
f.GoReceiverName = "ec"
|
||||
f.GoFieldName = "introspectType"
|
||||
return nil
|
||||
case obj.Root:
|
||||
f.IsResolver = true
|
||||
return nil
|
||||
case b.Config.Models[obj.Name].Fields[f.Name].Resolver:
|
||||
f.IsResolver = true
|
||||
return nil
|
||||
case obj.Type == config.MapType:
|
||||
f.GoFieldType = GoFieldMap
|
||||
return nil
|
||||
case b.Config.Models[obj.Name].Fields[f.Name].FieldName != "":
|
||||
f.GoFieldName = b.Config.Models[obj.Name].Fields[f.Name].FieldName
|
||||
}
|
||||
|
||||
target, err := b.findBindTarget(obj.Type.(*types.Named), f.GoFieldName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pos := b.Binder.ObjectPosition(target)
|
||||
|
||||
switch target := target.(type) {
|
||||
case nil:
|
||||
objPos := b.Binder.TypePosition(obj.Type)
|
||||
return fmt.Errorf(
|
||||
"%s:%d adding resolver method for %s.%s, nothing matched",
|
||||
objPos.Filename,
|
||||
objPos.Line,
|
||||
obj.Name,
|
||||
f.Name,
|
||||
)
|
||||
|
||||
case *types.Func:
|
||||
sig := target.Type().(*types.Signature)
|
||||
if sig.Results().Len() == 1 {
|
||||
f.NoErr = true
|
||||
} else if sig.Results().Len() != 2 {
|
||||
return fmt.Errorf("method has wrong number of args")
|
||||
}
|
||||
params := sig.Params()
|
||||
// If the first argument is the context, remove it from the comparison and set
|
||||
// the MethodHasContext flag so that the context will be passed to this model's method
|
||||
if params.Len() > 0 && params.At(0).Type().String() == "context.Context" {
|
||||
f.MethodHasContext = true
|
||||
vars := make([]*types.Var, params.Len()-1)
|
||||
for i := 1; i < params.Len(); i++ {
|
||||
vars[i-1] = params.At(i)
|
||||
}
|
||||
params = types.NewTuple(vars...)
|
||||
}
|
||||
|
||||
if err = b.bindArgs(f, params); err != nil {
|
||||
return errors.Wrapf(err, "%s:%d", pos.Filename, pos.Line)
|
||||
}
|
||||
|
||||
result := sig.Results().At(0)
|
||||
tr, err := b.Binder.TypeReference(f.Type, result.Type())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// success, args and return type match. Bind to method
|
||||
f.GoFieldType = GoFieldMethod
|
||||
f.GoReceiverName = "obj"
|
||||
f.GoFieldName = target.Name()
|
||||
f.TypeReference = tr
|
||||
|
||||
return nil
|
||||
|
||||
case *types.Var:
|
||||
tr, err := b.Binder.TypeReference(f.Type, target.Type())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// success, bind to var
|
||||
f.GoFieldType = GoFieldVariable
|
||||
f.GoReceiverName = "obj"
|
||||
f.GoFieldName = target.Name()
|
||||
f.TypeReference = tr
|
||||
|
||||
return nil
|
||||
default:
|
||||
panic(fmt.Errorf("unknown bind target %T for %s", target, f.Name))
|
||||
}
|
||||
}
|
||||
|
||||
// findField attempts to match the name to a struct field with the following
|
||||
// priorites:
|
||||
// 1. Any method with a matching name
|
||||
// 2. Any Fields with a struct tag (see config.StructTag)
|
||||
// 3. Any fields with a matching name
|
||||
// 4. Same logic again for embedded fields
|
||||
func (b *builder) findBindTarget(named *types.Named, name string) (types.Object, error) {
|
||||
for i := 0; i < named.NumMethods(); i++ {
|
||||
method := named.Method(i)
|
||||
if !method.Exported() {
|
||||
continue
|
||||
}
|
||||
|
||||
if !strings.EqualFold(method.Name(), name) {
|
||||
continue
|
||||
}
|
||||
|
||||
return method, nil
|
||||
}
|
||||
|
||||
strukt, ok := named.Underlying().(*types.Struct)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("not a struct")
|
||||
}
|
||||
return b.findBindStructTarget(strukt, name)
|
||||
}
|
||||
|
||||
func (b *builder) findBindStructTarget(strukt *types.Struct, name string) (types.Object, error) {
|
||||
// struct tags have the highest priority
|
||||
if b.Config.StructTag != "" {
|
||||
var foundField *types.Var
|
||||
for i := 0; i < strukt.NumFields(); i++ {
|
||||
field := strukt.Field(i)
|
||||
if !field.Exported() {
|
||||
continue
|
||||
}
|
||||
tags := reflect.StructTag(strukt.Tag(i))
|
||||
if val, ok := tags.Lookup(b.Config.StructTag); ok && equalFieldName(val, name) {
|
||||
if foundField != nil {
|
||||
return nil, errors.Errorf("tag %s is ambigious; multiple fields have the same tag value of %s", b.Config.StructTag, val)
|
||||
}
|
||||
|
||||
foundField = field
|
||||
}
|
||||
}
|
||||
if foundField != nil {
|
||||
return foundField, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Then matching field names
|
||||
for i := 0; i < strukt.NumFields(); i++ {
|
||||
field := strukt.Field(i)
|
||||
if !field.Exported() {
|
||||
continue
|
||||
}
|
||||
if equalFieldName(field.Name(), name) { // aqui!
|
||||
return field, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Then look in embedded structs
|
||||
for i := 0; i < strukt.NumFields(); i++ {
|
||||
field := strukt.Field(i)
|
||||
if !field.Exported() {
|
||||
continue
|
||||
}
|
||||
|
||||
if !field.Anonymous() {
|
||||
continue
|
||||
}
|
||||
|
||||
fieldType := field.Type()
|
||||
if ptr, ok := fieldType.(*types.Pointer); ok {
|
||||
fieldType = ptr.Elem()
|
||||
}
|
||||
|
||||
switch fieldType := fieldType.(type) {
|
||||
case *types.Named:
|
||||
f, err := b.findBindTarget(fieldType, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if f != nil {
|
||||
return f, nil
|
||||
}
|
||||
case *types.Struct:
|
||||
f, err := b.findBindStructTarget(fieldType, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if f != nil {
|
||||
return f, nil
|
||||
}
|
||||
default:
|
||||
panic(fmt.Errorf("unknown embedded field type %T", field.Type()))
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (f *Field) HasDirectives() bool {
|
||||
return len(f.ImplDirectives()) > 0
|
||||
}
|
||||
|
||||
func (f *Field) DirectiveObjName() string {
|
||||
if f.Object.Root {
|
||||
return "nil"
|
||||
}
|
||||
return f.GoReceiverName
|
||||
}
|
||||
|
||||
func (f *Field) ImplDirectives() []*Directive {
|
||||
var d []*Directive
|
||||
loc := ast.LocationFieldDefinition
|
||||
if f.Object.IsInputType() {
|
||||
loc = ast.LocationInputFieldDefinition
|
||||
}
|
||||
for i := range f.Directives {
|
||||
if !f.Directives[i].Builtin && f.Directives[i].IsLocation(loc) {
|
||||
d = append(d, f.Directives[i])
|
||||
}
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
func (f *Field) IsReserved() bool {
|
||||
return strings.HasPrefix(f.Name, "__")
|
||||
}
|
||||
|
||||
func (f *Field) IsMethod() bool {
|
||||
return f.GoFieldType == GoFieldMethod
|
||||
}
|
||||
|
||||
func (f *Field) IsVariable() bool {
|
||||
return f.GoFieldType == GoFieldVariable
|
||||
}
|
||||
|
||||
func (f *Field) IsMap() bool {
|
||||
return f.GoFieldType == GoFieldMap
|
||||
}
|
||||
|
||||
func (f *Field) IsConcurrent() bool {
|
||||
if f.Object.DisableConcurrency {
|
||||
return false
|
||||
}
|
||||
return f.MethodHasContext || f.IsResolver
|
||||
}
|
||||
|
||||
func (f *Field) GoNameUnexported() string {
|
||||
return templates.ToGoPrivate(f.Name)
|
||||
}
|
||||
|
||||
func (f *Field) ShortInvocation() string {
|
||||
return fmt.Sprintf("%s().%s(%s)", f.Object.Definition.Name, f.GoFieldName, f.CallArgs())
|
||||
}
|
||||
|
||||
func (f *Field) ArgsFunc() string {
|
||||
if len(f.Args) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
return "field_" + f.Object.Definition.Name + "_" + f.Name + "_args"
|
||||
}
|
||||
|
||||
func (f *Field) ResolverType() string {
|
||||
if !f.IsResolver {
|
||||
return ""
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s().%s(%s)", f.Object.Definition.Name, f.GoFieldName, f.CallArgs())
|
||||
}
|
||||
|
||||
func (f *Field) ShortResolverDeclaration() string {
|
||||
res := "(ctx context.Context"
|
||||
|
||||
if !f.Object.Root {
|
||||
res += fmt.Sprintf(", obj *%s", templates.CurrentImports.LookupType(f.Object.Type))
|
||||
}
|
||||
for _, arg := range f.Args {
|
||||
res += fmt.Sprintf(", %s %s", arg.VarName, templates.CurrentImports.LookupType(arg.TypeReference.GO))
|
||||
}
|
||||
|
||||
result := templates.CurrentImports.LookupType(f.TypeReference.GO)
|
||||
if f.Object.Stream {
|
||||
result = "<-chan " + result
|
||||
}
|
||||
|
||||
res += fmt.Sprintf(") (%s, error)", result)
|
||||
return res
|
||||
}
|
||||
|
||||
func (f *Field) ComplexitySignature() string {
|
||||
res := fmt.Sprintf("func(childComplexity int")
|
||||
for _, arg := range f.Args {
|
||||
res += fmt.Sprintf(", %s %s", arg.VarName, templates.CurrentImports.LookupType(arg.TypeReference.GO))
|
||||
}
|
||||
res += ") int"
|
||||
return res
|
||||
}
|
||||
|
||||
func (f *Field) ComplexityArgs() string {
|
||||
args := make([]string, len(f.Args))
|
||||
for i, arg := range f.Args {
|
||||
args[i] = "args[" + strconv.Quote(arg.Name) + "].(" + templates.CurrentImports.LookupType(arg.TypeReference.GO) + ")"
|
||||
}
|
||||
|
||||
return strings.Join(args, ", ")
|
||||
}
|
||||
|
||||
func (f *Field) CallArgs() string {
|
||||
args := make([]string, 0, len(f.Args)+2)
|
||||
|
||||
if f.IsResolver {
|
||||
args = append(args, "rctx")
|
||||
|
||||
if !f.Object.Root {
|
||||
args = append(args, "obj")
|
||||
}
|
||||
} else if f.MethodHasContext {
|
||||
args = append(args, "ctx")
|
||||
}
|
||||
|
||||
for _, arg := range f.Args {
|
||||
args = append(args, "args["+strconv.Quote(arg.Name)+"].("+templates.CurrentImports.LookupType(arg.TypeReference.GO)+")")
|
||||
}
|
||||
|
||||
return strings.Join(args, ", ")
|
||||
}
|
145
vendor/github.com/99designs/gqlgen/codegen/field.gotpl
generated
vendored
145
vendor/github.com/99designs/gqlgen/codegen/field.gotpl
generated
vendored
@ -1,145 +0,0 @@
|
||||
{{- range $object := .Objects }}{{- range $field := $object.Fields }}
|
||||
|
||||
{{- if $object.Stream }}
|
||||
func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Context, field graphql.CollectedField) func() graphql.Marshaler {
|
||||
ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
|
||||
Field: field,
|
||||
Args: nil,
|
||||
})
|
||||
{{- if $field.Args }}
|
||||
rawArgs := field.ArgumentMap(ec.Variables)
|
||||
args, err := ec.{{ $field.ArgsFunc }}(ctx,rawArgs)
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return nil
|
||||
}
|
||||
{{- end }}
|
||||
// FIXME: subscriptions are missing request middleware stack https://github.com/99designs/gqlgen/issues/259
|
||||
// and Tracer stack
|
||||
rctx := ctx
|
||||
results, err := ec.resolvers.{{ $field.ShortInvocation }}
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return nil
|
||||
}
|
||||
return func() graphql.Marshaler {
|
||||
res, ok := <-results
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return graphql.WriterFunc(func(w io.Writer) {
|
||||
w.Write([]byte{'{'})
|
||||
graphql.MarshalString(field.Alias).MarshalGQL(w)
|
||||
w.Write([]byte{':'})
|
||||
ec.{{ $field.TypeReference.MarshalFunc }}(ctx, field.Selections, res).MarshalGQL(w)
|
||||
w.Write([]byte{'}'})
|
||||
})
|
||||
}
|
||||
}
|
||||
{{ else }}
|
||||
func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Context, field graphql.CollectedField{{ if not $object.Root }}, obj {{$object.Reference | ref}}{{end}}) (ret graphql.Marshaler) {
|
||||
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||
defer func () {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
ec.Tracer.EndFieldExecution(ctx)
|
||||
}()
|
||||
rctx := &graphql.ResolverContext{
|
||||
Object: {{$object.Name|quote}},
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: {{or $field.IsMethod $field.IsResolver}},
|
||||
}
|
||||
ctx = graphql.WithResolverContext(ctx, rctx)
|
||||
{{- if $field.Args }}
|
||||
rawArgs := field.ArgumentMap(ec.Variables)
|
||||
args, err := ec.{{ $field.ArgsFunc }}(ctx,rawArgs)
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
rctx.Args = args
|
||||
{{- end }}
|
||||
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
|
||||
{{- if $.Directives.LocationDirectives "FIELD" }}
|
||||
resTmp := ec._fieldMiddleware(ctx, {{if $object.Root}}nil{{else}}obj{{end}}, func(rctx context.Context) (interface{}, error) {
|
||||
{{ template "field" $field }}
|
||||
})
|
||||
{{ else }}
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
{{ template "field" $field }}
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
{{- end }}
|
||||
if resTmp == nil {
|
||||
{{- if $field.TypeReference.GQL.NonNull }}
|
||||
if !ec.HasError(rctx) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
{{- end }}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.({{$field.TypeReference.GO | ref}})
|
||||
rctx.Result = res
|
||||
ctx = ec.Tracer.StartFieldChildExecution(ctx)
|
||||
return ec.{{ $field.TypeReference.MarshalFunc }}(ctx, field.Selections, res)
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
{{- end }}{{- end}}
|
||||
|
||||
{{ define "field" }}
|
||||
{{- if .HasDirectives -}}
|
||||
directive0 := func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
{{ template "fieldDefinition" . }}
|
||||
}
|
||||
{{ template "implDirectives" . }}
|
||||
tmp, err := directive{{.ImplDirectives|len}}(rctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if data, ok := tmp.({{ .TypeReference.GO | ref }}) ; ok {
|
||||
return data, nil
|
||||
}
|
||||
{{- if .TypeReference.IsNilable -}}
|
||||
else if tmp == nil {
|
||||
return nil, nil
|
||||
}
|
||||
{{- end }}
|
||||
return nil, fmt.Errorf(`unexpected type %T from directive, should be {{ .TypeReference.GO }}`, tmp)
|
||||
{{- else -}}
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
{{ template "fieldDefinition" . }}
|
||||
{{- end -}}
|
||||
{{ end }}
|
||||
|
||||
{{ define "fieldDefinition" }}
|
||||
{{- if .IsResolver -}}
|
||||
return ec.resolvers.{{ .ShortInvocation }}
|
||||
{{- else if .IsMap -}}
|
||||
switch v := {{.GoReceiverName}}[{{.Name|quote}}].(type) {
|
||||
case {{.TypeReference.GO | ref}}:
|
||||
return v, nil
|
||||
case {{.TypeReference.Elem.GO | ref}}:
|
||||
return &v, nil
|
||||
case nil:
|
||||
return ({{.TypeReference.GO | ref}})(nil), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected type %T for field %s", v, {{ .Name | quote}})
|
||||
}
|
||||
{{- else if .IsMethod -}}
|
||||
{{- if .NoErr -}}
|
||||
return {{.GoReceiverName}}.{{.GoFieldName}}({{ .CallArgs }}), nil
|
||||
{{- else -}}
|
||||
return {{.GoReceiverName}}.{{.GoFieldName}}({{ .CallArgs }})
|
||||
{{- end -}}
|
||||
{{- else if .IsVariable -}}
|
||||
return {{.GoReceiverName}}.{{.GoFieldName}}, nil
|
||||
{{- end }}
|
||||
{{- end }}
|
15
vendor/github.com/99designs/gqlgen/codegen/generate.go
generated
vendored
15
vendor/github.com/99designs/gqlgen/codegen/generate.go
generated
vendored
@ -1,15 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"github.com/99designs/gqlgen/codegen/templates"
|
||||
)
|
||||
|
||||
func GenerateCode(data *Data) error {
|
||||
return templates.Render(templates.Options{
|
||||
PackageName: data.Config.Exec.Package,
|
||||
Filename: data.Config.Exec.Filename,
|
||||
Data: data,
|
||||
RegionTags: true,
|
||||
GeneratedHeader: true,
|
||||
})
|
||||
}
|
235
vendor/github.com/99designs/gqlgen/codegen/generated!.gotpl
generated
vendored
235
vendor/github.com/99designs/gqlgen/codegen/generated!.gotpl
generated
vendored
@ -1,235 +0,0 @@
|
||||
{{ reserveImport "context" }}
|
||||
{{ reserveImport "fmt" }}
|
||||
{{ reserveImport "io" }}
|
||||
{{ reserveImport "strconv" }}
|
||||
{{ reserveImport "time" }}
|
||||
{{ reserveImport "sync" }}
|
||||
{{ reserveImport "sync/atomic" }}
|
||||
{{ reserveImport "errors" }}
|
||||
{{ reserveImport "bytes" }}
|
||||
|
||||
{{ reserveImport "github.com/vektah/gqlparser" }}
|
||||
{{ reserveImport "github.com/vektah/gqlparser/ast" }}
|
||||
{{ reserveImport "github.com/99designs/gqlgen/graphql" }}
|
||||
{{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }}
|
||||
|
||||
|
||||
// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface.
|
||||
func NewExecutableSchema(cfg Config) graphql.ExecutableSchema {
|
||||
return &executableSchema{
|
||||
resolvers: cfg.Resolvers,
|
||||
directives: cfg.Directives,
|
||||
complexity: cfg.Complexity,
|
||||
}
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Resolvers ResolverRoot
|
||||
Directives DirectiveRoot
|
||||
Complexity ComplexityRoot
|
||||
}
|
||||
|
||||
type ResolverRoot interface {
|
||||
{{- range $object := .Objects -}}
|
||||
{{ if $object.HasResolvers -}}
|
||||
{{$object.Name}}() {{$object.Name}}Resolver
|
||||
{{ end }}
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
type DirectiveRoot struct {
|
||||
{{ range $directive := .Directives }}
|
||||
{{ $directive.Declaration }}
|
||||
{{ end }}
|
||||
}
|
||||
|
||||
type ComplexityRoot struct {
|
||||
{{ range $object := .Objects }}
|
||||
{{ if not $object.IsReserved -}}
|
||||
{{ $object.Name|go }} struct {
|
||||
{{ range $_, $fields := $object.UniqueFields }}
|
||||
{{- $field := index $fields 0 -}}
|
||||
{{ if not $field.IsReserved -}}
|
||||
{{ $field.GoFieldName }} {{ $field.ComplexitySignature }}
|
||||
{{ end }}
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
}
|
||||
|
||||
{{ range $object := .Objects -}}
|
||||
{{ if $object.HasResolvers }}
|
||||
type {{$object.Name}}Resolver interface {
|
||||
{{ range $field := $object.Fields -}}
|
||||
{{- if $field.IsResolver }}
|
||||
{{- $field.GoFieldName}}{{ $field.ShortResolverDeclaration }}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
type executableSchema struct {
|
||||
resolvers ResolverRoot
|
||||
directives DirectiveRoot
|
||||
complexity ComplexityRoot
|
||||
}
|
||||
|
||||
func (e *executableSchema) Schema() *ast.Schema {
|
||||
return parsedSchema
|
||||
}
|
||||
|
||||
func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) {
|
||||
ec := executionContext{nil, e}
|
||||
_ = ec
|
||||
switch typeName + "." + field {
|
||||
{{ range $object := .Objects }}
|
||||
{{ if not $object.IsReserved }}
|
||||
{{ range $_, $fields := $object.UniqueFields }}
|
||||
{{- $len := len $fields }}
|
||||
{{- range $i, $field := $fields }}
|
||||
{{- $last := eq (add $i 1) $len }}
|
||||
{{- if not $field.IsReserved }}
|
||||
{{- if eq $i 0 }}case {{ end }}"{{$object.Name}}.{{$field.Name}}"{{ if not $last }},{{ else }}:
|
||||
if e.complexity.{{$object.Name|go}}.{{$field.GoFieldName}} == nil {
|
||||
break
|
||||
}
|
||||
{{ if $field.Args }}
|
||||
args, err := ec.{{ $field.ArgsFunc }}(context.TODO(),rawArgs)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
{{ end }}
|
||||
return e.complexity.{{$object.Name|go}}.{{$field.GoFieldName}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{ end }}), true
|
||||
{{ end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func (e *executableSchema) Query(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {
|
||||
{{- if .QueryRoot }}
|
||||
ec := executionContext{graphql.GetRequestContext(ctx), e}
|
||||
|
||||
buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {
|
||||
{{ if .Directives.LocationDirectives "QUERY" -}}
|
||||
data := ec._queryMiddleware(ctx, op, func(ctx context.Context) (interface{}, error){
|
||||
return ec._{{.QueryRoot.Name}}(ctx, op.SelectionSet), nil
|
||||
})
|
||||
{{- else -}}
|
||||
data := ec._{{.QueryRoot.Name}}(ctx, op.SelectionSet)
|
||||
{{- end }}
|
||||
var buf bytes.Buffer
|
||||
data.MarshalGQL(&buf)
|
||||
return buf.Bytes()
|
||||
})
|
||||
|
||||
return &graphql.Response{
|
||||
Data: buf,
|
||||
Errors: ec.Errors,
|
||||
Extensions: ec.Extensions,
|
||||
}
|
||||
{{- else }}
|
||||
return graphql.ErrorResponse(ctx, "queries are not supported")
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
func (e *executableSchema) Mutation(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {
|
||||
{{- if .MutationRoot }}
|
||||
ec := executionContext{graphql.GetRequestContext(ctx), e}
|
||||
|
||||
buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {
|
||||
{{ if .Directives.LocationDirectives "MUTATION" -}}
|
||||
data := ec._mutationMiddleware(ctx, op, func(ctx context.Context) (interface{}, error){
|
||||
return ec._{{.MutationRoot.Name}}(ctx, op.SelectionSet), nil
|
||||
})
|
||||
{{- else -}}
|
||||
data := ec._{{.MutationRoot.Name}}(ctx, op.SelectionSet)
|
||||
{{- end }}
|
||||
var buf bytes.Buffer
|
||||
data.MarshalGQL(&buf)
|
||||
return buf.Bytes()
|
||||
})
|
||||
|
||||
return &graphql.Response{
|
||||
Data: buf,
|
||||
Errors: ec.Errors,
|
||||
Extensions: ec.Extensions,
|
||||
}
|
||||
{{- else }}
|
||||
return graphql.ErrorResponse(ctx, "mutations are not supported")
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
func (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDefinition) func() *graphql.Response {
|
||||
{{- if .SubscriptionRoot }}
|
||||
ec := executionContext{graphql.GetRequestContext(ctx), e}
|
||||
|
||||
{{ if .Directives.LocationDirectives "SUBSCRIPTION" -}}
|
||||
next := ec._subscriptionMiddleware(ctx, op, func(ctx context.Context) (interface{}, error){
|
||||
return ec._{{.SubscriptionRoot.Name}}(ctx, op.SelectionSet),nil
|
||||
})
|
||||
{{- else -}}
|
||||
next := ec._{{.SubscriptionRoot.Name}}(ctx, op.SelectionSet)
|
||||
{{- end }}
|
||||
if ec.Errors != nil {
|
||||
return graphql.OneShot(&graphql.Response{Data: []byte("null"), Errors: ec.Errors})
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
return func() *graphql.Response {
|
||||
buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {
|
||||
buf.Reset()
|
||||
data := next()
|
||||
|
||||
if data == nil {
|
||||
return nil
|
||||
}
|
||||
data.MarshalGQL(&buf)
|
||||
return buf.Bytes()
|
||||
})
|
||||
|
||||
if buf == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &graphql.Response{
|
||||
Data: buf,
|
||||
Errors: ec.Errors,
|
||||
Extensions: ec.Extensions,
|
||||
}
|
||||
}
|
||||
{{- else }}
|
||||
return graphql.OneShot(graphql.ErrorResponse(ctx, "subscriptions are not supported"))
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
type executionContext struct {
|
||||
*graphql.RequestContext
|
||||
*executableSchema
|
||||
}
|
||||
|
||||
func (ec *executionContext) introspectSchema() (*introspection.Schema, error) {
|
||||
if ec.DisableIntrospection {
|
||||
return nil, errors.New("introspection disabled")
|
||||
}
|
||||
return introspection.WrapSchema(parsedSchema), nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) introspectType(name string) (*introspection.Type, error) {
|
||||
if ec.DisableIntrospection {
|
||||
return nil, errors.New("introspection disabled")
|
||||
}
|
||||
return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil
|
||||
}
|
||||
|
||||
var parsedSchema = gqlparser.MustLoadSchema(
|
||||
{{- range $filename, $schema := .SchemaStr }}
|
||||
&ast.Source{Name: {{$filename|quote}}, Input: {{$schema|rawQuote}}},
|
||||
{{- end }}
|
||||
)
|
48
vendor/github.com/99designs/gqlgen/codegen/input.gotpl
generated
vendored
48
vendor/github.com/99designs/gqlgen/codegen/input.gotpl
generated
vendored
@ -1,48 +0,0 @@
|
||||
{{- range $input := .Inputs }}
|
||||
{{- if not .HasUnmarshal }}
|
||||
func (ec *executionContext) unmarshalInput{{ .Name }}(ctx context.Context, obj interface{}) ({{.Type | ref}}, error) {
|
||||
var it {{.Type | ref}}
|
||||
var asMap = obj.(map[string]interface{})
|
||||
{{ range $field := .Fields}}
|
||||
{{- if $field.Default}}
|
||||
if _, present := asMap[{{$field.Name|quote}}] ; !present {
|
||||
asMap[{{$field.Name|quote}}] = {{ $field.Default | dump }}
|
||||
}
|
||||
{{- end}}
|
||||
{{- end }}
|
||||
|
||||
for k, v := range asMap {
|
||||
switch k {
|
||||
{{- range $field := .Fields }}
|
||||
case {{$field.Name|quote}}:
|
||||
var err error
|
||||
{{- if $field.ImplDirectives }}
|
||||
directive0 := func(ctx context.Context) (interface{}, error) { return ec.{{ $field.TypeReference.UnmarshalFunc }}(ctx, v) }
|
||||
{{ template "implDirectives" $field }}
|
||||
tmp, err := directive{{$field.ImplDirectives|len}}(ctx)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
if data, ok := tmp.({{ $field.TypeReference.GO | ref }}) ; ok {
|
||||
it.{{$field.GoFieldName}} = data
|
||||
{{- if $field.TypeReference.IsNilable }}
|
||||
} else if tmp == nil {
|
||||
it.{{$field.GoFieldName}} = nil
|
||||
{{- end }}
|
||||
} else {
|
||||
return it, fmt.Errorf(`unexpected type %T from directive, should be {{ $field.TypeReference.GO }}`, tmp)
|
||||
}
|
||||
{{- else }}
|
||||
it.{{$field.GoFieldName}}, err = ec.{{ $field.TypeReference.UnmarshalFunc }}(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
|
||||
return it, nil
|
||||
}
|
||||
{{- end }}
|
||||
{{ end }}
|
63
vendor/github.com/99designs/gqlgen/codegen/interface.go
generated
vendored
63
vendor/github.com/99designs/gqlgen/codegen/interface.go
generated
vendored
@ -1,63 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"go/types"
|
||||
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
)
|
||||
|
||||
type Interface struct {
|
||||
*ast.Definition
|
||||
Type types.Type
|
||||
Implementors []InterfaceImplementor
|
||||
InTypemap bool
|
||||
}
|
||||
|
||||
type InterfaceImplementor struct {
|
||||
*ast.Definition
|
||||
|
||||
Interface *Interface
|
||||
Type types.Type
|
||||
}
|
||||
|
||||
func (b *builder) buildInterface(typ *ast.Definition) *Interface {
|
||||
obj, err := b.Binder.DefaultUserObject(typ.Name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
i := &Interface{
|
||||
Definition: typ,
|
||||
Type: obj,
|
||||
InTypemap: b.Config.Models.UserDefined(typ.Name),
|
||||
}
|
||||
|
||||
for _, implementor := range b.Schema.GetPossibleTypes(typ) {
|
||||
obj, err := b.Binder.DefaultUserObject(implementor.Name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
i.Implementors = append(i.Implementors, InterfaceImplementor{
|
||||
Definition: implementor,
|
||||
Type: obj,
|
||||
Interface: i,
|
||||
})
|
||||
}
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
func (i *InterfaceImplementor) ValueReceiver() bool {
|
||||
interfaceType, err := findGoInterface(i.Interface.Type)
|
||||
if interfaceType == nil || err != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
implementorType, err := findGoNamedType(i.Type)
|
||||
if implementorType == nil || err != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
return types.Implements(implementorType, interfaceType)
|
||||
}
|
20
vendor/github.com/99designs/gqlgen/codegen/interface.gotpl
generated
vendored
20
vendor/github.com/99designs/gqlgen/codegen/interface.gotpl
generated
vendored
@ -1,20 +0,0 @@
|
||||
{{- range $interface := .Interfaces }}
|
||||
|
||||
func (ec *executionContext) _{{$interface.Name}}(ctx context.Context, sel ast.SelectionSet, obj *{{$interface.Type | ref}}) graphql.Marshaler {
|
||||
switch obj := (*obj).(type) {
|
||||
case nil:
|
||||
return graphql.Null
|
||||
{{- range $implementor := $interface.Implementors }}
|
||||
{{- if $implementor.ValueReceiver }}
|
||||
case {{$implementor.Type | ref}}:
|
||||
return ec._{{$implementor.Name}}(ctx, sel, &obj)
|
||||
{{- end}}
|
||||
case *{{$implementor.Type | ref}}:
|
||||
return ec._{{$implementor.Name}}(ctx, sel, obj)
|
||||
{{- end }}
|
||||
default:
|
||||
panic(fmt.Errorf("unexpected type %T", obj))
|
||||
}
|
||||
}
|
||||
|
||||
{{- end }}
|
171
vendor/github.com/99designs/gqlgen/codegen/object.go
generated
vendored
171
vendor/github.com/99designs/gqlgen/codegen/object.go
generated
vendored
@ -1,171 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"go/types"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/99designs/gqlgen/codegen/config"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
)
|
||||
|
||||
type GoFieldType int
|
||||
|
||||
const (
|
||||
GoFieldUndefined GoFieldType = iota
|
||||
GoFieldMethod
|
||||
GoFieldVariable
|
||||
GoFieldMap
|
||||
)
|
||||
|
||||
type Object struct {
|
||||
*ast.Definition
|
||||
|
||||
Type types.Type
|
||||
ResolverInterface types.Type
|
||||
Root bool
|
||||
Fields []*Field
|
||||
Implements []*ast.Definition
|
||||
DisableConcurrency bool
|
||||
Stream bool
|
||||
Directives []*Directive
|
||||
}
|
||||
|
||||
func (b *builder) buildObject(typ *ast.Definition) (*Object, error) {
|
||||
dirs, err := b.getDirectives(typ.Directives)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, typ.Name)
|
||||
}
|
||||
|
||||
obj := &Object{
|
||||
Definition: typ,
|
||||
Root: b.Schema.Query == typ || b.Schema.Mutation == typ || b.Schema.Subscription == typ,
|
||||
DisableConcurrency: typ == b.Schema.Mutation,
|
||||
Stream: typ == b.Schema.Subscription,
|
||||
Directives: dirs,
|
||||
ResolverInterface: types.NewNamed(
|
||||
types.NewTypeName(0, b.Config.Exec.Pkg(), typ.Name+"Resolver", nil),
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
}
|
||||
|
||||
if !obj.Root {
|
||||
goObject, err := b.Binder.DefaultUserObject(typ.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
obj.Type = goObject
|
||||
}
|
||||
|
||||
for _, intf := range b.Schema.GetImplements(typ) {
|
||||
obj.Implements = append(obj.Implements, b.Schema.Types[intf.Name])
|
||||
}
|
||||
|
||||
for _, field := range typ.Fields {
|
||||
if strings.HasPrefix(field.Name, "__") {
|
||||
continue
|
||||
}
|
||||
|
||||
var f *Field
|
||||
f, err = b.buildField(obj, field)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
obj.Fields = append(obj.Fields, f)
|
||||
}
|
||||
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
func (o *Object) Reference() types.Type {
|
||||
switch o.Type.(type) {
|
||||
case *types.Pointer, *types.Slice, *types.Map:
|
||||
return o.Type
|
||||
}
|
||||
|
||||
return types.NewPointer(o.Type)
|
||||
}
|
||||
|
||||
type Objects []*Object
|
||||
|
||||
func (o *Object) Implementors() string {
|
||||
satisfiedBy := strconv.Quote(o.Name)
|
||||
for _, s := range o.Implements {
|
||||
satisfiedBy += ", " + strconv.Quote(s.Name)
|
||||
}
|
||||
return "[]string{" + satisfiedBy + "}"
|
||||
}
|
||||
|
||||
func (o *Object) HasResolvers() bool {
|
||||
for _, f := range o.Fields {
|
||||
if f.IsResolver {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (o *Object) HasUnmarshal() bool {
|
||||
if o.Type == config.MapType {
|
||||
return true
|
||||
}
|
||||
for i := 0; i < o.Type.(*types.Named).NumMethods(); i++ {
|
||||
if o.Type.(*types.Named).Method(i).Name() == "UnmarshalGQL" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (o *Object) HasDirectives() bool {
|
||||
if len(o.Directives) > 0 {
|
||||
return true
|
||||
}
|
||||
for _, f := range o.Fields {
|
||||
if f.HasDirectives() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (o *Object) IsConcurrent() bool {
|
||||
for _, f := range o.Fields {
|
||||
if f.IsConcurrent() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (o *Object) IsReserved() bool {
|
||||
return strings.HasPrefix(o.Definition.Name, "__")
|
||||
}
|
||||
|
||||
func (o *Object) Description() string {
|
||||
return o.Definition.Description
|
||||
}
|
||||
|
||||
func (os Objects) ByName(name string) *Object {
|
||||
for i, o := range os {
|
||||
if strings.EqualFold(o.Definition.Name, name) {
|
||||
return os[i]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ucFirst(s string) string {
|
||||
if s == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
r := []rune(s)
|
||||
r[0] = unicode.ToUpper(r[0])
|
||||
return string(r)
|
||||
}
|
85
vendor/github.com/99designs/gqlgen/codegen/object.gotpl
generated
vendored
85
vendor/github.com/99designs/gqlgen/codegen/object.gotpl
generated
vendored
@ -1,85 +0,0 @@
|
||||
{{- range $object := .Objects }}
|
||||
|
||||
var {{ $object.Name|lcFirst}}Implementors = {{$object.Implementors}}
|
||||
|
||||
{{- if .Stream }}
|
||||
func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.SelectionSet) func() graphql.Marshaler {
|
||||
fields := graphql.CollectFields(ec.RequestContext, sel, {{$object.Name|lcFirst}}Implementors)
|
||||
ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
|
||||
Object: {{$object.Name|quote}},
|
||||
})
|
||||
if len(fields) != 1 {
|
||||
ec.Errorf(ctx, "must subscribe to exactly one stream")
|
||||
return nil
|
||||
}
|
||||
|
||||
switch fields[0].Name {
|
||||
{{- range $field := $object.Fields }}
|
||||
case "{{$field.Name}}":
|
||||
return ec._{{$object.Name}}_{{$field.Name}}(ctx, fields[0])
|
||||
{{- end }}
|
||||
default:
|
||||
panic("unknown field " + strconv.Quote(fields[0].Name))
|
||||
}
|
||||
}
|
||||
{{- else }}
|
||||
func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.SelectionSet{{ if not $object.Root }},obj {{$object.Reference | ref }}{{ end }}) graphql.Marshaler {
|
||||
fields := graphql.CollectFields(ec.RequestContext, sel, {{$object.Name|lcFirst}}Implementors)
|
||||
{{if $object.Root}}
|
||||
ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
|
||||
Object: {{$object.Name|quote}},
|
||||
})
|
||||
{{end}}
|
||||
|
||||
out := graphql.NewFieldSet(fields)
|
||||
var invalids uint32
|
||||
for i, field := range fields {
|
||||
switch field.Name {
|
||||
case "__typename":
|
||||
out.Values[i] = graphql.MarshalString({{$object.Name|quote}})
|
||||
{{- range $field := $object.Fields }}
|
||||
case "{{$field.Name}}":
|
||||
{{- if $field.IsConcurrent }}
|
||||
field := field
|
||||
out.Concurrently(i, func() (res graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
}
|
||||
}()
|
||||
res = ec._{{$object.Name}}_{{$field.Name}}(ctx, field{{if not $object.Root}}, obj{{end}})
|
||||
{{- if $field.TypeReference.GQL.NonNull }}
|
||||
if res == graphql.Null {
|
||||
{{- if $object.IsConcurrent }}
|
||||
atomic.AddUint32(&invalids, 1)
|
||||
{{- else }}
|
||||
invalids++
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}
|
||||
return res
|
||||
})
|
||||
{{- else }}
|
||||
out.Values[i] = ec._{{$object.Name}}_{{$field.Name}}(ctx, field{{if not $object.Root}}, obj{{end}})
|
||||
{{- if $field.TypeReference.GQL.NonNull }}
|
||||
if out.Values[i] == graphql.Null {
|
||||
{{- if $object.IsConcurrent }}
|
||||
atomic.AddUint32(&invalids, 1)
|
||||
{{- else }}
|
||||
invalids++
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
default:
|
||||
panic("unknown field " + strconv.Quote(field.Name))
|
||||
}
|
||||
}
|
||||
out.Dispatch()
|
||||
if invalids > 0 { return graphql.Null }
|
||||
return out
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
{{- end }}
|
138
vendor/github.com/99designs/gqlgen/codegen/templates/import.go
generated
vendored
138
vendor/github.com/99designs/gqlgen/codegen/templates/import.go
generated
vendored
@ -1,138 +0,0 @@
|
||||
package templates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/types"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/99designs/gqlgen/internal/code"
|
||||
)
|
||||
|
||||
type Import struct {
|
||||
Name string
|
||||
Path string
|
||||
Alias string
|
||||
}
|
||||
|
||||
type Imports struct {
|
||||
imports []*Import
|
||||
destDir string
|
||||
}
|
||||
|
||||
func (i *Import) String() string {
|
||||
if strings.HasSuffix(i.Path, i.Alias) {
|
||||
return strconv.Quote(i.Path)
|
||||
}
|
||||
|
||||
return i.Alias + " " + strconv.Quote(i.Path)
|
||||
}
|
||||
|
||||
func (s *Imports) String() string {
|
||||
res := ""
|
||||
for i, imp := range s.imports {
|
||||
if i != 0 {
|
||||
res += "\n"
|
||||
}
|
||||
res += imp.String()
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (s *Imports) Reserve(path string, aliases ...string) (string, error) {
|
||||
if path == "" {
|
||||
panic("empty ambient import")
|
||||
}
|
||||
|
||||
// if we are referencing our own package we dont need an import
|
||||
if code.ImportPathForDir(s.destDir) == path {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
name := code.NameForPackage(path)
|
||||
var alias string
|
||||
if len(aliases) != 1 {
|
||||
alias = name
|
||||
} else {
|
||||
alias = aliases[0]
|
||||
}
|
||||
|
||||
if existing := s.findByPath(path); existing != nil {
|
||||
if existing.Alias == alias {
|
||||
return "", nil
|
||||
}
|
||||
return "", fmt.Errorf("ambient import already exists")
|
||||
}
|
||||
|
||||
if alias := s.findByAlias(alias); alias != nil {
|
||||
return "", fmt.Errorf("ambient import collides on an alias")
|
||||
}
|
||||
|
||||
s.imports = append(s.imports, &Import{
|
||||
Name: name,
|
||||
Path: path,
|
||||
Alias: alias,
|
||||
})
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (s *Imports) Lookup(path string) string {
|
||||
if path == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
path = code.NormalizeVendor(path)
|
||||
|
||||
// if we are referencing our own package we dont need an import
|
||||
if code.ImportPathForDir(s.destDir) == path {
|
||||
return ""
|
||||
}
|
||||
|
||||
if existing := s.findByPath(path); existing != nil {
|
||||
return existing.Alias
|
||||
}
|
||||
|
||||
imp := &Import{
|
||||
Name: code.NameForPackage(path),
|
||||
Path: path,
|
||||
}
|
||||
s.imports = append(s.imports, imp)
|
||||
|
||||
alias := imp.Name
|
||||
i := 1
|
||||
for s.findByAlias(alias) != nil {
|
||||
alias = imp.Name + strconv.Itoa(i)
|
||||
i++
|
||||
if i > 10 {
|
||||
panic(fmt.Errorf("too many collisions, last attempt was %s", alias))
|
||||
}
|
||||
}
|
||||
imp.Alias = alias
|
||||
|
||||
return imp.Alias
|
||||
}
|
||||
|
||||
func (s *Imports) LookupType(t types.Type) string {
|
||||
return types.TypeString(t, func(i *types.Package) string {
|
||||
return s.Lookup(i.Path())
|
||||
})
|
||||
}
|
||||
|
||||
func (s Imports) findByPath(importPath string) *Import {
|
||||
for _, imp := range s.imports {
|
||||
if imp.Path == importPath {
|
||||
return imp
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s Imports) findByAlias(alias string) *Import {
|
||||
for _, imp := range s.imports {
|
||||
if imp.Alias == alias {
|
||||
return imp
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
572
vendor/github.com/99designs/gqlgen/codegen/templates/templates.go
generated
vendored
572
vendor/github.com/99designs/gqlgen/codegen/templates/templates.go
generated
vendored
@ -1,572 +0,0 @@
|
||||
package templates
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/types"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
"unicode"
|
||||
|
||||
"github.com/99designs/gqlgen/internal/imports"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// CurrentImports keeps track of all the import declarations that are needed during the execution of a plugin.
|
||||
// this is done with a global because subtemplates currently get called in functions. Lets aim to remove this eventually.
|
||||
var CurrentImports *Imports
|
||||
|
||||
// Options specify various parameters to rendering a template.
|
||||
type Options struct {
|
||||
// PackageName is a helper that specifies the package header declaration.
|
||||
// In other words, when you write the template you don't need to specify `package X`
|
||||
// at the top of the file. By providing PackageName in the Options, the Render
|
||||
// function will do that for you.
|
||||
PackageName string
|
||||
// Template is a string of the entire template that
|
||||
// will be parsed and rendered. If it's empty,
|
||||
// the plugin processor will look for .gotpl files
|
||||
// in the same directory of where you wrote the plugin.
|
||||
Template string
|
||||
// Filename is the name of the file that will be
|
||||
// written to the system disk once the template is rendered.
|
||||
Filename string
|
||||
RegionTags bool
|
||||
GeneratedHeader bool
|
||||
// Data will be passed to the template execution.
|
||||
Data interface{}
|
||||
Funcs template.FuncMap
|
||||
}
|
||||
|
||||
// Render renders a gql plugin template from the given Options. Render is an
|
||||
// abstraction of the text/template package that makes it easier to write gqlgen
|
||||
// plugins. If Options.Template is empty, the Render function will look for `.gotpl`
|
||||
// files inside the directory where you wrote the plugin.
|
||||
func Render(cfg Options) error {
|
||||
if CurrentImports != nil {
|
||||
panic(fmt.Errorf("recursive or concurrent call to RenderToFile detected"))
|
||||
}
|
||||
CurrentImports = &Imports{destDir: filepath.Dir(cfg.Filename)}
|
||||
|
||||
// load path relative to calling source file
|
||||
_, callerFile, _, _ := runtime.Caller(1)
|
||||
rootDir := filepath.Dir(callerFile)
|
||||
|
||||
funcs := Funcs()
|
||||
for n, f := range cfg.Funcs {
|
||||
funcs[n] = f
|
||||
}
|
||||
t := template.New("").Funcs(funcs)
|
||||
|
||||
var roots []string
|
||||
if cfg.Template != "" {
|
||||
var err error
|
||||
t, err = t.New("template.gotpl").Parse(cfg.Template)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error with provided template")
|
||||
}
|
||||
roots = append(roots, "template.gotpl")
|
||||
} else {
|
||||
// load all the templates in the directory
|
||||
err := filepath.Walk(rootDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name := filepath.ToSlash(strings.TrimPrefix(path, rootDir+string(os.PathSeparator)))
|
||||
if !strings.HasSuffix(info.Name(), ".gotpl") {
|
||||
return nil
|
||||
}
|
||||
b, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t, err = t.New(name).Parse(string(b))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, cfg.Filename)
|
||||
}
|
||||
|
||||
roots = append(roots, name)
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "locating templates")
|
||||
}
|
||||
}
|
||||
|
||||
// then execute all the important looking ones in order, adding them to the same file
|
||||
sort.Slice(roots, func(i, j int) bool {
|
||||
// important files go first
|
||||
if strings.HasSuffix(roots[i], "!.gotpl") {
|
||||
return true
|
||||
}
|
||||
if strings.HasSuffix(roots[j], "!.gotpl") {
|
||||
return false
|
||||
}
|
||||
return roots[i] < roots[j]
|
||||
})
|
||||
var buf bytes.Buffer
|
||||
for _, root := range roots {
|
||||
if cfg.RegionTags {
|
||||
buf.WriteString("\n// region " + center(70, "*", " "+root+" ") + "\n")
|
||||
}
|
||||
err := t.Lookup(root).Execute(&buf, cfg.Data)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, root)
|
||||
}
|
||||
if cfg.RegionTags {
|
||||
buf.WriteString("\n// endregion " + center(70, "*", " "+root+" ") + "\n")
|
||||
}
|
||||
}
|
||||
|
||||
var result bytes.Buffer
|
||||
if cfg.GeneratedHeader {
|
||||
result.WriteString("// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\n")
|
||||
}
|
||||
result.WriteString("package ")
|
||||
result.WriteString(cfg.PackageName)
|
||||
result.WriteString("\n\n")
|
||||
result.WriteString("import (\n")
|
||||
result.WriteString(CurrentImports.String())
|
||||
result.WriteString(")\n")
|
||||
_, err := buf.WriteTo(&result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
CurrentImports = nil
|
||||
|
||||
return write(cfg.Filename, result.Bytes())
|
||||
}
|
||||
|
||||
func center(width int, pad string, s string) string {
|
||||
if len(s)+2 > width {
|
||||
return s
|
||||
}
|
||||
lpad := (width - len(s)) / 2
|
||||
rpad := width - (lpad + len(s))
|
||||
return strings.Repeat(pad, lpad) + s + strings.Repeat(pad, rpad)
|
||||
}
|
||||
|
||||
func Funcs() template.FuncMap {
|
||||
return template.FuncMap{
|
||||
"ucFirst": ucFirst,
|
||||
"lcFirst": lcFirst,
|
||||
"quote": strconv.Quote,
|
||||
"rawQuote": rawQuote,
|
||||
"dump": Dump,
|
||||
"ref": ref,
|
||||
"ts": TypeIdentifier,
|
||||
"call": Call,
|
||||
"prefixLines": prefixLines,
|
||||
"notNil": notNil,
|
||||
"reserveImport": CurrentImports.Reserve,
|
||||
"lookupImport": CurrentImports.Lookup,
|
||||
"go": ToGo,
|
||||
"goPrivate": ToGoPrivate,
|
||||
"add": func(a, b int) int {
|
||||
return a + b
|
||||
},
|
||||
"render": func(filename string, tpldata interface{}) (*bytes.Buffer, error) {
|
||||
return render(resolveName(filename, 0), tpldata)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func ucFirst(s string) string {
|
||||
if s == "" {
|
||||
return ""
|
||||
}
|
||||
r := []rune(s)
|
||||
r[0] = unicode.ToUpper(r[0])
|
||||
return string(r)
|
||||
}
|
||||
|
||||
func lcFirst(s string) string {
|
||||
if s == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
r := []rune(s)
|
||||
r[0] = unicode.ToLower(r[0])
|
||||
return string(r)
|
||||
}
|
||||
|
||||
func isDelimiter(c rune) bool {
|
||||
return c == '-' || c == '_' || unicode.IsSpace(c)
|
||||
}
|
||||
|
||||
func ref(p types.Type) string {
|
||||
return CurrentImports.LookupType(p)
|
||||
}
|
||||
|
||||
var pkgReplacer = strings.NewReplacer(
|
||||
"/", "ᚋ",
|
||||
".", "ᚗ",
|
||||
"-", "ᚑ",
|
||||
)
|
||||
|
||||
func TypeIdentifier(t types.Type) string {
|
||||
res := ""
|
||||
for {
|
||||
switch it := t.(type) {
|
||||
case *types.Pointer:
|
||||
t.Underlying()
|
||||
res += "ᚖ"
|
||||
t = it.Elem()
|
||||
case *types.Slice:
|
||||
res += "ᚕ"
|
||||
t = it.Elem()
|
||||
case *types.Named:
|
||||
res += pkgReplacer.Replace(it.Obj().Pkg().Path())
|
||||
res += "ᚐ"
|
||||
res += it.Obj().Name()
|
||||
return res
|
||||
case *types.Basic:
|
||||
res += it.Name()
|
||||
return res
|
||||
case *types.Map:
|
||||
res += "map"
|
||||
return res
|
||||
case *types.Interface:
|
||||
res += "interface"
|
||||
return res
|
||||
default:
|
||||
panic(fmt.Errorf("unexpected type %T", it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Call(p *types.Func) string {
|
||||
pkg := CurrentImports.Lookup(p.Pkg().Path())
|
||||
|
||||
if pkg != "" {
|
||||
pkg += "."
|
||||
}
|
||||
|
||||
if p.Type() != nil {
|
||||
// make sure the returned type is listed in our imports.
|
||||
ref(p.Type().(*types.Signature).Results().At(0).Type())
|
||||
}
|
||||
|
||||
return pkg + p.Name()
|
||||
}
|
||||
|
||||
func ToGo(name string) string {
|
||||
runes := make([]rune, 0, len(name))
|
||||
|
||||
wordWalker(name, func(info *wordInfo) {
|
||||
word := info.Word
|
||||
if info.MatchCommonInitial {
|
||||
word = strings.ToUpper(word)
|
||||
} else if !info.HasCommonInitial {
|
||||
if strings.ToUpper(word) == word || strings.ToLower(word) == word {
|
||||
// FOO or foo → Foo
|
||||
// FOo → FOo
|
||||
word = ucFirst(strings.ToLower(word))
|
||||
}
|
||||
}
|
||||
runes = append(runes, []rune(word)...)
|
||||
})
|
||||
|
||||
return string(runes)
|
||||
}
|
||||
|
||||
func ToGoPrivate(name string) string {
|
||||
runes := make([]rune, 0, len(name))
|
||||
|
||||
first := true
|
||||
wordWalker(name, func(info *wordInfo) {
|
||||
word := info.Word
|
||||
switch {
|
||||
case first:
|
||||
if strings.ToUpper(word) == word || strings.ToLower(word) == word {
|
||||
// ID → id, CAMEL → camel
|
||||
word = strings.ToLower(info.Word)
|
||||
} else {
|
||||
// ITicket → iTicket
|
||||
word = lcFirst(info.Word)
|
||||
}
|
||||
first = false
|
||||
case info.MatchCommonInitial:
|
||||
word = strings.ToUpper(word)
|
||||
case !info.HasCommonInitial:
|
||||
word = ucFirst(strings.ToLower(word))
|
||||
}
|
||||
runes = append(runes, []rune(word)...)
|
||||
})
|
||||
|
||||
return sanitizeKeywords(string(runes))
|
||||
}
|
||||
|
||||
type wordInfo struct {
|
||||
Word string
|
||||
MatchCommonInitial bool
|
||||
HasCommonInitial bool
|
||||
}
|
||||
|
||||
// This function is based on the following code.
|
||||
// https://github.com/golang/lint/blob/06c8688daad7faa9da5a0c2f163a3d14aac986ca/lint.go#L679
|
||||
func wordWalker(str string, f func(*wordInfo)) {
|
||||
runes := []rune(str)
|
||||
w, i := 0, 0 // index of start of word, scan
|
||||
hasCommonInitial := false
|
||||
for i+1 <= len(runes) {
|
||||
eow := false // whether we hit the end of a word
|
||||
switch {
|
||||
case i+1 == len(runes):
|
||||
eow = true
|
||||
case isDelimiter(runes[i+1]):
|
||||
// underscore; shift the remainder forward over any run of underscores
|
||||
eow = true
|
||||
n := 1
|
||||
for i+n+1 < len(runes) && isDelimiter(runes[i+n+1]) {
|
||||
n++
|
||||
}
|
||||
|
||||
// Leave at most one underscore if the underscore is between two digits
|
||||
if i+n+1 < len(runes) && unicode.IsDigit(runes[i]) && unicode.IsDigit(runes[i+n+1]) {
|
||||
n--
|
||||
}
|
||||
|
||||
copy(runes[i+1:], runes[i+n+1:])
|
||||
runes = runes[:len(runes)-n]
|
||||
case unicode.IsLower(runes[i]) && !unicode.IsLower(runes[i+1]):
|
||||
// lower->non-lower
|
||||
eow = true
|
||||
}
|
||||
i++
|
||||
|
||||
// [w,i) is a word.
|
||||
word := string(runes[w:i])
|
||||
if !eow && commonInitialisms[word] && !unicode.IsLower(runes[i]) {
|
||||
// through
|
||||
// split IDFoo → ID, Foo
|
||||
// but URLs → URLs
|
||||
} else if !eow {
|
||||
if commonInitialisms[word] {
|
||||
hasCommonInitial = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
matchCommonInitial := false
|
||||
if commonInitialisms[strings.ToUpper(word)] {
|
||||
hasCommonInitial = true
|
||||
matchCommonInitial = true
|
||||
}
|
||||
|
||||
f(&wordInfo{
|
||||
Word: word,
|
||||
MatchCommonInitial: matchCommonInitial,
|
||||
HasCommonInitial: hasCommonInitial,
|
||||
})
|
||||
hasCommonInitial = false
|
||||
w = i
|
||||
}
|
||||
}
|
||||
|
||||
var keywords = []string{
|
||||
"break",
|
||||
"default",
|
||||
"func",
|
||||
"interface",
|
||||
"select",
|
||||
"case",
|
||||
"defer",
|
||||
"go",
|
||||
"map",
|
||||
"struct",
|
||||
"chan",
|
||||
"else",
|
||||
"goto",
|
||||
"package",
|
||||
"switch",
|
||||
"const",
|
||||
"fallthrough",
|
||||
"if",
|
||||
"range",
|
||||
"type",
|
||||
"continue",
|
||||
"for",
|
||||
"import",
|
||||
"return",
|
||||
"var",
|
||||
"_",
|
||||
}
|
||||
|
||||
// sanitizeKeywords prevents collisions with go keywords for arguments to resolver functions
|
||||
func sanitizeKeywords(name string) string {
|
||||
for _, k := range keywords {
|
||||
if name == k {
|
||||
return name + "Arg"
|
||||
}
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
// commonInitialisms is a set of common initialisms.
|
||||
// Only add entries that are highly unlikely to be non-initialisms.
|
||||
// For instance, "ID" is fine (Freudian code is rare), but "AND" is not.
|
||||
var commonInitialisms = map[string]bool{
|
||||
"ACL": true,
|
||||
"API": true,
|
||||
"ASCII": true,
|
||||
"CPU": true,
|
||||
"CSS": true,
|
||||
"DNS": true,
|
||||
"EOF": true,
|
||||
"GUID": true,
|
||||
"HTML": true,
|
||||
"HTTP": true,
|
||||
"HTTPS": true,
|
||||
"ID": true,
|
||||
"IP": true,
|
||||
"JSON": true,
|
||||
"LHS": true,
|
||||
"QPS": true,
|
||||
"RAM": true,
|
||||
"RHS": true,
|
||||
"RPC": true,
|
||||
"SLA": true,
|
||||
"SMTP": true,
|
||||
"SQL": true,
|
||||
"SSH": true,
|
||||
"TCP": true,
|
||||
"TLS": true,
|
||||
"TTL": true,
|
||||
"UDP": true,
|
||||
"UI": true,
|
||||
"UID": true,
|
||||
"UUID": true,
|
||||
"URI": true,
|
||||
"URL": true,
|
||||
"UTF8": true,
|
||||
"VM": true,
|
||||
"XML": true,
|
||||
"XMPP": true,
|
||||
"XSRF": true,
|
||||
"XSS": true,
|
||||
}
|
||||
|
||||
func rawQuote(s string) string {
|
||||
return "`" + strings.Replace(s, "`", "`+\"`\"+`", -1) + "`"
|
||||
}
|
||||
|
||||
func notNil(field string, data interface{}) bool {
|
||||
v := reflect.ValueOf(data)
|
||||
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
if v.Kind() != reflect.Struct {
|
||||
return false
|
||||
}
|
||||
val := v.FieldByName(field)
|
||||
|
||||
return val.IsValid() && !val.IsNil()
|
||||
}
|
||||
|
||||
func Dump(val interface{}) string {
|
||||
switch val := val.(type) {
|
||||
case int:
|
||||
return strconv.Itoa(val)
|
||||
case int64:
|
||||
return fmt.Sprintf("%d", val)
|
||||
case float64:
|
||||
return fmt.Sprintf("%f", val)
|
||||
case string:
|
||||
return strconv.Quote(val)
|
||||
case bool:
|
||||
return strconv.FormatBool(val)
|
||||
case nil:
|
||||
return "nil"
|
||||
case []interface{}:
|
||||
var parts []string
|
||||
for _, part := range val {
|
||||
parts = append(parts, Dump(part))
|
||||
}
|
||||
return "[]interface{}{" + strings.Join(parts, ",") + "}"
|
||||
case map[string]interface{}:
|
||||
buf := bytes.Buffer{}
|
||||
buf.WriteString("map[string]interface{}{")
|
||||
var keys []string
|
||||
for key := range val {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
for _, key := range keys {
|
||||
data := val[key]
|
||||
|
||||
buf.WriteString(strconv.Quote(key))
|
||||
buf.WriteString(":")
|
||||
buf.WriteString(Dump(data))
|
||||
buf.WriteString(",")
|
||||
}
|
||||
buf.WriteString("}")
|
||||
return buf.String()
|
||||
default:
|
||||
panic(fmt.Errorf("unsupported type %T", val))
|
||||
}
|
||||
}
|
||||
|
||||
func prefixLines(prefix, s string) string {
|
||||
return prefix + strings.Replace(s, "\n", "\n"+prefix, -1)
|
||||
}
|
||||
|
||||
func resolveName(name string, skip int) string {
|
||||
if name[0] == '.' {
|
||||
// load path relative to calling source file
|
||||
_, callerFile, _, _ := runtime.Caller(skip + 1)
|
||||
return filepath.Join(filepath.Dir(callerFile), name[1:])
|
||||
}
|
||||
|
||||
// load path relative to this directory
|
||||
_, callerFile, _, _ := runtime.Caller(0)
|
||||
return filepath.Join(filepath.Dir(callerFile), name)
|
||||
}
|
||||
|
||||
func render(filename string, tpldata interface{}) (*bytes.Buffer, error) {
|
||||
t := template.New("").Funcs(Funcs())
|
||||
|
||||
b, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
t, err = t.New(filepath.Base(filename)).Parse(string(b))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
return buf, t.Execute(buf, tpldata)
|
||||
}
|
||||
|
||||
func write(filename string, b []byte) error {
|
||||
err := os.MkdirAll(filepath.Dir(filename), 0755)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create directory")
|
||||
}
|
||||
|
||||
formatted, err := imports.Prune(filename, b)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "gofmt failed on %s: %s\n", filepath.Base(filename), err.Error())
|
||||
formatted = b
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(filename, formatted, 0644)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to write %s", filename)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
18
vendor/github.com/99designs/gqlgen/codegen/type.go
generated
vendored
18
vendor/github.com/99designs/gqlgen/codegen/type.go
generated
vendored
@ -1,18 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"github.com/99designs/gqlgen/codegen/config"
|
||||
)
|
||||
|
||||
func (b *builder) buildTypes() map[string]*config.TypeReference {
|
||||
ret := map[string]*config.TypeReference{}
|
||||
|
||||
for _, ref := range b.Binder.References {
|
||||
for ref != nil {
|
||||
ret[ref.UniquenessKey()] = ref
|
||||
|
||||
ref = ref.Elem()
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
130
vendor/github.com/99designs/gqlgen/codegen/type.gotpl
generated
vendored
130
vendor/github.com/99designs/gqlgen/codegen/type.gotpl
generated
vendored
@ -1,130 +0,0 @@
|
||||
{{- range $type := .ReferencedTypes }}
|
||||
{{ with $type.UnmarshalFunc }}
|
||||
func (ec *executionContext) {{ . }}(ctx context.Context, v interface{}) ({{ $type.GO | ref }}, error) {
|
||||
{{- if $type.IsNilable }}
|
||||
if v == nil { return nil, nil }
|
||||
{{- end }}
|
||||
{{- if $type.IsPtr }}
|
||||
res, err := ec.{{ $type.Elem.UnmarshalFunc }}(ctx, v)
|
||||
return &res, err
|
||||
{{- else if $type.IsSlice }}
|
||||
var vSlice []interface{}
|
||||
if v != nil {
|
||||
if tmp1, ok := v.([]interface{}); ok {
|
||||
vSlice = tmp1
|
||||
} else {
|
||||
vSlice = []interface{}{ v }
|
||||
}
|
||||
}
|
||||
var err error
|
||||
res := make([]{{$type.GO.Elem | ref}}, len(vSlice))
|
||||
for i := range vSlice {
|
||||
res[i], err = ec.{{ $type.Elem.UnmarshalFunc }}(ctx, vSlice[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
{{- else }}
|
||||
{{- if $type.Unmarshaler }}
|
||||
{{- if $type.CastType }}
|
||||
tmp, err := {{ $type.Unmarshaler | call }}(v)
|
||||
return {{ $type.GO | ref }}(tmp), err
|
||||
{{- else}}
|
||||
return {{ $type.Unmarshaler | call }}(v)
|
||||
{{- end }}
|
||||
{{- else if eq ($type.GO | ref) "map[string]interface{}" }}
|
||||
return v.(map[string]interface{}), nil
|
||||
{{- else if $type.IsMarshaler -}}
|
||||
var res {{ $type.GO | ref }}
|
||||
return res, res.UnmarshalGQL(v)
|
||||
{{- else }}
|
||||
return ec.unmarshalInput{{ $type.GQL.Name }}(ctx, v)
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
{{ with $type.MarshalFunc }}
|
||||
func (ec *executionContext) {{ . }}(ctx context.Context, sel ast.SelectionSet, v {{ $type.GO | ref }}) graphql.Marshaler {
|
||||
{{- if $type.IsNilable }}
|
||||
if v == nil {
|
||||
{{- if $type.GQL.NonNull }}
|
||||
if !ec.HasError(graphql.GetResolverContext(ctx)) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
{{- end }}
|
||||
return graphql.Null
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
{{- if $type.IsSlice }}
|
||||
{{- if not $type.GQL.NonNull }}
|
||||
if v == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
{{- end }}
|
||||
ret := make(graphql.Array, len(v))
|
||||
{{- if not $type.IsScalar }}
|
||||
var wg sync.WaitGroup
|
||||
isLen1 := len(v) == 1
|
||||
if !isLen1 {
|
||||
wg.Add(len(v))
|
||||
}
|
||||
{{- end }}
|
||||
for i := range v {
|
||||
{{- if not $type.IsScalar }}
|
||||
i := i
|
||||
rctx := &graphql.ResolverContext{
|
||||
Index: &i,
|
||||
Result: &v[i],
|
||||
}
|
||||
ctx := graphql.WithResolverContext(ctx, rctx)
|
||||
f := func(i int) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = nil
|
||||
}
|
||||
}()
|
||||
if !isLen1 {
|
||||
defer wg.Done()
|
||||
}
|
||||
ret[i] = ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, v[i])
|
||||
}
|
||||
if isLen1 {
|
||||
f(i)
|
||||
} else {
|
||||
go f(i)
|
||||
}
|
||||
{{ else }}
|
||||
ret[i] = ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, v[i])
|
||||
{{- end}}
|
||||
}
|
||||
{{ if not $type.IsScalar }} wg.Wait() {{ end }}
|
||||
return ret
|
||||
{{- else }}
|
||||
|
||||
{{- if $type.IsMarshaler }}
|
||||
return v
|
||||
{{- else if $type.Marshaler }}
|
||||
{{- if $type.IsPtr }}
|
||||
return ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, *v)
|
||||
{{- else if $type.GQL.NonNull }}
|
||||
res := {{ $type.Marshaler | call }}({{- if $type.CastType }}{{ $type.CastType | ref }}(v){{else}}v{{- end }})
|
||||
if res == graphql.Null {
|
||||
if !ec.HasError(graphql.GetResolverContext(ctx)) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
}
|
||||
return res
|
||||
{{- else }}
|
||||
return {{ $type.Marshaler | call }}({{- if $type.CastType }}{{ $type.CastType | ref }}(v){{else}}v{{- end }})
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
return ec._{{$type.Definition.Name}}(ctx, sel, {{ if not $type.IsNilable}}&{{end}} v)
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
47
vendor/github.com/99designs/gqlgen/codegen/util.go
generated
vendored
47
vendor/github.com/99designs/gqlgen/codegen/util.go
generated
vendored
@ -1,47 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"go/types"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func findGoNamedType(def types.Type) (*types.Named, error) {
|
||||
if def == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
namedType, ok := def.(*types.Named)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("expected %s to be a named type, instead found %T\n", def.String(), def)
|
||||
}
|
||||
|
||||
return namedType, nil
|
||||
}
|
||||
|
||||
func findGoInterface(def types.Type) (*types.Interface, error) {
|
||||
if def == nil {
|
||||
return nil, nil
|
||||
}
|
||||
namedType, err := findGoNamedType(def)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if namedType == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
underlying, ok := namedType.Underlying().(*types.Interface)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("expected %s to be a named interface, instead found %s", def.String(), namedType.String())
|
||||
}
|
||||
|
||||
return underlying, nil
|
||||
}
|
||||
|
||||
func equalFieldName(source, target string) bool {
|
||||
source = strings.Replace(source, "_", "", -1)
|
||||
target = strings.Replace(target, "_", "", -1)
|
||||
return strings.EqualFold(source, target)
|
||||
}
|
104
vendor/github.com/99designs/gqlgen/complexity/complexity.go
generated
vendored
104
vendor/github.com/99designs/gqlgen/complexity/complexity.go
generated
vendored
@ -1,104 +0,0 @@
|
||||
package complexity
|
||||
|
||||
import (
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
)
|
||||
|
||||
func Calculate(es graphql.ExecutableSchema, op *ast.OperationDefinition, vars map[string]interface{}) int {
|
||||
walker := complexityWalker{
|
||||
es: es,
|
||||
schema: es.Schema(),
|
||||
vars: vars,
|
||||
}
|
||||
return walker.selectionSetComplexity(op.SelectionSet)
|
||||
}
|
||||
|
||||
type complexityWalker struct {
|
||||
es graphql.ExecutableSchema
|
||||
schema *ast.Schema
|
||||
vars map[string]interface{}
|
||||
}
|
||||
|
||||
func (cw complexityWalker) selectionSetComplexity(selectionSet ast.SelectionSet) int {
|
||||
var complexity int
|
||||
for _, selection := range selectionSet {
|
||||
switch s := selection.(type) {
|
||||
case *ast.Field:
|
||||
fieldDefinition := cw.schema.Types[s.Definition.Type.Name()]
|
||||
var childComplexity int
|
||||
switch fieldDefinition.Kind {
|
||||
case ast.Object, ast.Interface, ast.Union:
|
||||
childComplexity = cw.selectionSetComplexity(s.SelectionSet)
|
||||
}
|
||||
|
||||
args := s.ArgumentMap(cw.vars)
|
||||
var fieldComplexity int
|
||||
if s.ObjectDefinition.Kind == ast.Interface {
|
||||
fieldComplexity = cw.interfaceFieldComplexity(s.ObjectDefinition, s.Name, childComplexity, args)
|
||||
} else {
|
||||
fieldComplexity = cw.fieldComplexity(s.ObjectDefinition.Name, s.Name, childComplexity, args)
|
||||
}
|
||||
complexity = safeAdd(complexity, fieldComplexity)
|
||||
|
||||
case *ast.FragmentSpread:
|
||||
complexity = safeAdd(complexity, cw.selectionSetComplexity(s.Definition.SelectionSet))
|
||||
|
||||
case *ast.InlineFragment:
|
||||
complexity = safeAdd(complexity, cw.selectionSetComplexity(s.SelectionSet))
|
||||
}
|
||||
}
|
||||
return complexity
|
||||
}
|
||||
|
||||
func (cw complexityWalker) interfaceFieldComplexity(def *ast.Definition, field string, childComplexity int, args map[string]interface{}) int {
|
||||
// Interfaces don't have their own separate field costs, so they have to assume the worst case.
|
||||
// We iterate over all implementors and choose the most expensive one.
|
||||
maxComplexity := 0
|
||||
implementors := cw.schema.GetPossibleTypes(def)
|
||||
for _, t := range implementors {
|
||||
fieldComplexity := cw.fieldComplexity(t.Name, field, childComplexity, args)
|
||||
if fieldComplexity > maxComplexity {
|
||||
maxComplexity = fieldComplexity
|
||||
}
|
||||
}
|
||||
return maxComplexity
|
||||
}
|
||||
|
||||
func (cw complexityWalker) fieldComplexity(object, field string, childComplexity int, args map[string]interface{}) int {
|
||||
if customComplexity, ok := cw.es.Complexity(object, field, childComplexity, args); ok && customComplexity >= childComplexity {
|
||||
return customComplexity
|
||||
}
|
||||
// default complexity calculation
|
||||
return safeAdd(1, childComplexity)
|
||||
}
|
||||
|
||||
const maxInt = int(^uint(0) >> 1)
|
||||
|
||||
// safeAdd is a saturating add of a and b that ignores negative operands.
|
||||
// If a + b would overflow through normal Go addition,
|
||||
// it returns the maximum integer value instead.
|
||||
//
|
||||
// Adding complexities with this function prevents attackers from intentionally
|
||||
// overflowing the complexity calculation to allow overly-complex queries.
|
||||
//
|
||||
// It also helps mitigate the impact of custom complexities that accidentally
|
||||
// return negative values.
|
||||
func safeAdd(a, b int) int {
|
||||
// Ignore negative operands.
|
||||
if a < 0 {
|
||||
if b < 0 {
|
||||
return 1
|
||||
}
|
||||
return b
|
||||
} else if b < 0 {
|
||||
return a
|
||||
}
|
||||
|
||||
c := a + b
|
||||
if c < a {
|
||||
// Set c to maximum integer instead of overflowing.
|
||||
c = maxInt
|
||||
}
|
||||
return c
|
||||
}
|
1
vendor/github.com/99designs/gqlgen/docs/content/_introduction.md
generated
vendored
1
vendor/github.com/99designs/gqlgen/docs/content/_introduction.md
generated
vendored
@ -1 +0,0 @@
|
||||
../../README.md
|
19
vendor/github.com/99designs/gqlgen/graphql/any.go
generated
vendored
19
vendor/github.com/99designs/gqlgen/graphql/any.go
generated
vendored
@ -1,19 +0,0 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
func MarshalAny(v interface{}) Marshaler {
|
||||
return WriterFunc(func(w io.Writer) {
|
||||
err := json.NewEncoder(w).Encode(v)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func UnmarshalAny(v interface{}) (interface{}, error) {
|
||||
return v, nil
|
||||
}
|
30
vendor/github.com/99designs/gqlgen/graphql/bool.go
generated
vendored
30
vendor/github.com/99designs/gqlgen/graphql/bool.go
generated
vendored
@ -1,30 +0,0 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func MarshalBoolean(b bool) Marshaler {
|
||||
return WriterFunc(func(w io.Writer) {
|
||||
if b {
|
||||
w.Write(trueLit)
|
||||
} else {
|
||||
w.Write(falseLit)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func UnmarshalBoolean(v interface{}) (bool, error) {
|
||||
switch v := v.(type) {
|
||||
case string:
|
||||
return strings.ToLower(v) == "true", nil
|
||||
case int:
|
||||
return v != 0, nil
|
||||
case bool:
|
||||
return v, nil
|
||||
default:
|
||||
return false, fmt.Errorf("%T is not a bool", v)
|
||||
}
|
||||
}
|
274
vendor/github.com/99designs/gqlgen/graphql/context.go
generated
vendored
274
vendor/github.com/99designs/gqlgen/graphql/context.go
generated
vendored
@ -1,274 +0,0 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
"github.com/vektah/gqlparser/gqlerror"
|
||||
)
|
||||
|
||||
type Resolver func(ctx context.Context) (res interface{}, err error)
|
||||
type FieldMiddleware func(ctx context.Context, next Resolver) (res interface{}, err error)
|
||||
type RequestMiddleware func(ctx context.Context, next func(ctx context.Context) []byte) []byte
|
||||
type ComplexityLimitFunc func(ctx context.Context) int
|
||||
|
||||
type RequestContext struct {
|
||||
RawQuery string
|
||||
Variables map[string]interface{}
|
||||
Doc *ast.QueryDocument
|
||||
|
||||
ComplexityLimit int
|
||||
OperationComplexity int
|
||||
DisableIntrospection bool
|
||||
|
||||
// ErrorPresenter will be used to generate the error
|
||||
// message from errors given to Error().
|
||||
ErrorPresenter ErrorPresenterFunc
|
||||
Recover RecoverFunc
|
||||
ResolverMiddleware FieldMiddleware
|
||||
DirectiveMiddleware FieldMiddleware
|
||||
RequestMiddleware RequestMiddleware
|
||||
Tracer Tracer
|
||||
|
||||
errorsMu sync.Mutex
|
||||
Errors gqlerror.List
|
||||
extensionsMu sync.Mutex
|
||||
Extensions map[string]interface{}
|
||||
}
|
||||
|
||||
func DefaultResolverMiddleware(ctx context.Context, next Resolver) (res interface{}, err error) {
|
||||
return next(ctx)
|
||||
}
|
||||
|
||||
func DefaultDirectiveMiddleware(ctx context.Context, next Resolver) (res interface{}, err error) {
|
||||
return next(ctx)
|
||||
}
|
||||
|
||||
func DefaultRequestMiddleware(ctx context.Context, next func(ctx context.Context) []byte) []byte {
|
||||
return next(ctx)
|
||||
}
|
||||
|
||||
func NewRequestContext(doc *ast.QueryDocument, query string, variables map[string]interface{}) *RequestContext {
|
||||
return &RequestContext{
|
||||
Doc: doc,
|
||||
RawQuery: query,
|
||||
Variables: variables,
|
||||
ResolverMiddleware: DefaultResolverMiddleware,
|
||||
DirectiveMiddleware: DefaultDirectiveMiddleware,
|
||||
RequestMiddleware: DefaultRequestMiddleware,
|
||||
Recover: DefaultRecover,
|
||||
ErrorPresenter: DefaultErrorPresenter,
|
||||
Tracer: &NopTracer{},
|
||||
}
|
||||
}
|
||||
|
||||
type key string
|
||||
|
||||
const (
|
||||
request key = "request_context"
|
||||
resolver key = "resolver_context"
|
||||
)
|
||||
|
||||
func GetRequestContext(ctx context.Context) *RequestContext {
|
||||
if val, ok := ctx.Value(request).(*RequestContext); ok {
|
||||
return val
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func WithRequestContext(ctx context.Context, rc *RequestContext) context.Context {
|
||||
return context.WithValue(ctx, request, rc)
|
||||
}
|
||||
|
||||
type ResolverContext struct {
|
||||
Parent *ResolverContext
|
||||
// The name of the type this field belongs to
|
||||
Object string
|
||||
// These are the args after processing, they can be mutated in middleware to change what the resolver will get.
|
||||
Args map[string]interface{}
|
||||
// The raw field
|
||||
Field CollectedField
|
||||
// The index of array in path.
|
||||
Index *int
|
||||
// The result object of resolver
|
||||
Result interface{}
|
||||
// IsMethod indicates if the resolver is a method
|
||||
IsMethod bool
|
||||
}
|
||||
|
||||
func (r *ResolverContext) Path() []interface{} {
|
||||
var path []interface{}
|
||||
for it := r; it != nil; it = it.Parent {
|
||||
if it.Index != nil {
|
||||
path = append(path, *it.Index)
|
||||
} else if it.Field.Field != nil {
|
||||
path = append(path, it.Field.Alias)
|
||||
}
|
||||
}
|
||||
|
||||
// because we are walking up the chain, all the elements are backwards, do an inplace flip.
|
||||
for i := len(path)/2 - 1; i >= 0; i-- {
|
||||
opp := len(path) - 1 - i
|
||||
path[i], path[opp] = path[opp], path[i]
|
||||
}
|
||||
|
||||
return path
|
||||
}
|
||||
|
||||
func GetResolverContext(ctx context.Context) *ResolverContext {
|
||||
if val, ok := ctx.Value(resolver).(*ResolverContext); ok {
|
||||
return val
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func WithResolverContext(ctx context.Context, rc *ResolverContext) context.Context {
|
||||
rc.Parent = GetResolverContext(ctx)
|
||||
return context.WithValue(ctx, resolver, rc)
|
||||
}
|
||||
|
||||
// This is just a convenient wrapper method for CollectFields
|
||||
func CollectFieldsCtx(ctx context.Context, satisfies []string) []CollectedField {
|
||||
resctx := GetResolverContext(ctx)
|
||||
return CollectFields(GetRequestContext(ctx), resctx.Field.Selections, satisfies)
|
||||
}
|
||||
|
||||
// CollectAllFields returns a slice of all GraphQL field names that were selected for the current resolver context.
|
||||
// The slice will contain the unique set of all field names requested regardless of fragment type conditions.
|
||||
func CollectAllFields(ctx context.Context) []string {
|
||||
resctx := GetResolverContext(ctx)
|
||||
collected := CollectFields(GetRequestContext(ctx), resctx.Field.Selections, nil)
|
||||
uniq := make([]string, 0, len(collected))
|
||||
Next:
|
||||
for _, f := range collected {
|
||||
for _, name := range uniq {
|
||||
if name == f.Name {
|
||||
continue Next
|
||||
}
|
||||
}
|
||||
uniq = append(uniq, f.Name)
|
||||
}
|
||||
return uniq
|
||||
}
|
||||
|
||||
// Errorf sends an error string to the client, passing it through the formatter.
|
||||
func (c *RequestContext) Errorf(ctx context.Context, format string, args ...interface{}) {
|
||||
c.errorsMu.Lock()
|
||||
defer c.errorsMu.Unlock()
|
||||
|
||||
c.Errors = append(c.Errors, c.ErrorPresenter(ctx, fmt.Errorf(format, args...)))
|
||||
}
|
||||
|
||||
// Error sends an error to the client, passing it through the formatter.
|
||||
func (c *RequestContext) Error(ctx context.Context, err error) {
|
||||
c.errorsMu.Lock()
|
||||
defer c.errorsMu.Unlock()
|
||||
|
||||
c.Errors = append(c.Errors, c.ErrorPresenter(ctx, err))
|
||||
}
|
||||
|
||||
// HasError returns true if the current field has already errored
|
||||
func (c *RequestContext) HasError(rctx *ResolverContext) bool {
|
||||
c.errorsMu.Lock()
|
||||
defer c.errorsMu.Unlock()
|
||||
path := rctx.Path()
|
||||
|
||||
for _, err := range c.Errors {
|
||||
if equalPath(err.Path, path) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// GetErrors returns a list of errors that occurred in the current field
|
||||
func (c *RequestContext) GetErrors(rctx *ResolverContext) gqlerror.List {
|
||||
c.errorsMu.Lock()
|
||||
defer c.errorsMu.Unlock()
|
||||
path := rctx.Path()
|
||||
|
||||
var errs gqlerror.List
|
||||
for _, err := range c.Errors {
|
||||
if equalPath(err.Path, path) {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
func equalPath(a []interface{}, b []interface{}) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 0; i < len(a); i++ {
|
||||
if a[i] != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// AddError is a convenience method for adding an error to the current response
|
||||
func AddError(ctx context.Context, err error) {
|
||||
GetRequestContext(ctx).Error(ctx, err)
|
||||
}
|
||||
|
||||
// AddErrorf is a convenience method for adding an error to the current response
|
||||
func AddErrorf(ctx context.Context, format string, args ...interface{}) {
|
||||
GetRequestContext(ctx).Errorf(ctx, format, args...)
|
||||
}
|
||||
|
||||
// RegisterExtension registers an extension, returns error if extension has already been registered
|
||||
func (c *RequestContext) RegisterExtension(key string, value interface{}) error {
|
||||
c.extensionsMu.Lock()
|
||||
defer c.extensionsMu.Unlock()
|
||||
|
||||
if c.Extensions == nil {
|
||||
c.Extensions = make(map[string]interface{})
|
||||
}
|
||||
|
||||
if _, ok := c.Extensions[key]; ok {
|
||||
return fmt.Errorf("extension already registered for key %s", key)
|
||||
}
|
||||
|
||||
c.Extensions[key] = value
|
||||
return nil
|
||||
}
|
||||
|
||||
// ChainFieldMiddleware add chain by FieldMiddleware
|
||||
func ChainFieldMiddleware(handleFunc ...FieldMiddleware) FieldMiddleware {
|
||||
n := len(handleFunc)
|
||||
|
||||
if n > 1 {
|
||||
lastI := n - 1
|
||||
return func(ctx context.Context, next Resolver) (interface{}, error) {
|
||||
var (
|
||||
chainHandler Resolver
|
||||
curI int
|
||||
)
|
||||
chainHandler = func(currentCtx context.Context) (interface{}, error) {
|
||||
if curI == lastI {
|
||||
return next(currentCtx)
|
||||
}
|
||||
curI++
|
||||
res, err := handleFunc[curI](currentCtx, chainHandler)
|
||||
curI--
|
||||
return res, err
|
||||
|
||||
}
|
||||
return handleFunc[0](ctx, chainHandler)
|
||||
}
|
||||
}
|
||||
|
||||
if n == 1 {
|
||||
return handleFunc[0]
|
||||
}
|
||||
|
||||
return func(ctx context.Context, next Resolver) (interface{}, error) {
|
||||
return next(ctx)
|
||||
}
|
||||
}
|
33
vendor/github.com/99designs/gqlgen/graphql/error.go
generated
vendored
33
vendor/github.com/99designs/gqlgen/graphql/error.go
generated
vendored
@ -1,33 +0,0 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/vektah/gqlparser/gqlerror"
|
||||
)
|
||||
|
||||
type ErrorPresenterFunc func(context.Context, error) *gqlerror.Error
|
||||
|
||||
type ExtendedError interface {
|
||||
Extensions() map[string]interface{}
|
||||
}
|
||||
|
||||
func DefaultErrorPresenter(ctx context.Context, err error) *gqlerror.Error {
|
||||
if gqlerr, ok := err.(*gqlerror.Error); ok {
|
||||
if gqlerr.Path == nil {
|
||||
gqlerr.Path = GetResolverContext(ctx).Path()
|
||||
}
|
||||
return gqlerr
|
||||
}
|
||||
|
||||
var extensions map[string]interface{}
|
||||
if ee, ok := err.(ExtendedError); ok {
|
||||
extensions = ee.Extensions()
|
||||
}
|
||||
|
||||
return &gqlerror.Error{
|
||||
Message: err.Error(),
|
||||
Path: GetResolverContext(ctx).Path(),
|
||||
Extensions: extensions,
|
||||
}
|
||||
}
|
144
vendor/github.com/99designs/gqlgen/graphql/exec.go
generated
vendored
144
vendor/github.com/99designs/gqlgen/graphql/exec.go
generated
vendored
@ -1,144 +0,0 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
)
|
||||
|
||||
type ExecutableSchema interface {
|
||||
Schema() *ast.Schema
|
||||
|
||||
Complexity(typeName, fieldName string, childComplexity int, args map[string]interface{}) (int, bool)
|
||||
Query(ctx context.Context, op *ast.OperationDefinition) *Response
|
||||
Mutation(ctx context.Context, op *ast.OperationDefinition) *Response
|
||||
Subscription(ctx context.Context, op *ast.OperationDefinition) func() *Response
|
||||
}
|
||||
|
||||
// CollectFields returns the set of fields from an ast.SelectionSet where all collected fields satisfy at least one of the GraphQL types
|
||||
// passed through satisfies. Providing an empty or nil slice for satisfies will return collect all fields regardless of fragment
|
||||
// type conditions.
|
||||
func CollectFields(reqCtx *RequestContext, selSet ast.SelectionSet, satisfies []string) []CollectedField {
|
||||
return collectFields(reqCtx, selSet, satisfies, map[string]bool{})
|
||||
}
|
||||
|
||||
func collectFields(reqCtx *RequestContext, selSet ast.SelectionSet, satisfies []string, visited map[string]bool) []CollectedField {
|
||||
groupedFields := make([]CollectedField, 0, len(selSet))
|
||||
|
||||
for _, sel := range selSet {
|
||||
switch sel := sel.(type) {
|
||||
case *ast.Field:
|
||||
if !shouldIncludeNode(sel.Directives, reqCtx.Variables) {
|
||||
continue
|
||||
}
|
||||
f := getOrCreateAndAppendField(&groupedFields, sel.Alias, func() CollectedField {
|
||||
return CollectedField{Field: sel}
|
||||
})
|
||||
|
||||
f.Selections = append(f.Selections, sel.SelectionSet...)
|
||||
case *ast.InlineFragment:
|
||||
if !shouldIncludeNode(sel.Directives, reqCtx.Variables) {
|
||||
continue
|
||||
}
|
||||
if len(satisfies) > 0 && !instanceOf(sel.TypeCondition, satisfies) {
|
||||
continue
|
||||
}
|
||||
for _, childField := range collectFields(reqCtx, sel.SelectionSet, satisfies, visited) {
|
||||
f := getOrCreateAndAppendField(&groupedFields, childField.Name, func() CollectedField { return childField })
|
||||
f.Selections = append(f.Selections, childField.Selections...)
|
||||
}
|
||||
|
||||
case *ast.FragmentSpread:
|
||||
if !shouldIncludeNode(sel.Directives, reqCtx.Variables) {
|
||||
continue
|
||||
}
|
||||
fragmentName := sel.Name
|
||||
if _, seen := visited[fragmentName]; seen {
|
||||
continue
|
||||
}
|
||||
visited[fragmentName] = true
|
||||
|
||||
fragment := reqCtx.Doc.Fragments.ForName(fragmentName)
|
||||
if fragment == nil {
|
||||
// should never happen, validator has already run
|
||||
panic(fmt.Errorf("missing fragment %s", fragmentName))
|
||||
}
|
||||
|
||||
if len(satisfies) > 0 && !instanceOf(fragment.TypeCondition, satisfies) {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, childField := range collectFields(reqCtx, fragment.SelectionSet, satisfies, visited) {
|
||||
f := getOrCreateAndAppendField(&groupedFields, childField.Name, func() CollectedField { return childField })
|
||||
f.Selections = append(f.Selections, childField.Selections...)
|
||||
}
|
||||
default:
|
||||
panic(fmt.Errorf("unsupported %T", sel))
|
||||
}
|
||||
}
|
||||
|
||||
return groupedFields
|
||||
}
|
||||
|
||||
type CollectedField struct {
|
||||
*ast.Field
|
||||
|
||||
Selections ast.SelectionSet
|
||||
}
|
||||
|
||||
func instanceOf(val string, satisfies []string) bool {
|
||||
for _, s := range satisfies {
|
||||
if val == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getOrCreateAndAppendField(c *[]CollectedField, name string, creator func() CollectedField) *CollectedField {
|
||||
for i, cf := range *c {
|
||||
if cf.Alias == name {
|
||||
return &(*c)[i]
|
||||
}
|
||||
}
|
||||
|
||||
f := creator()
|
||||
|
||||
*c = append(*c, f)
|
||||
return &(*c)[len(*c)-1]
|
||||
}
|
||||
|
||||
func shouldIncludeNode(directives ast.DirectiveList, variables map[string]interface{}) bool {
|
||||
if len(directives) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
skip, include := false, true
|
||||
|
||||
if d := directives.ForName("skip"); d != nil {
|
||||
skip = resolveIfArgument(d, variables)
|
||||
}
|
||||
|
||||
if d := directives.ForName("include"); d != nil {
|
||||
include = resolveIfArgument(d, variables)
|
||||
}
|
||||
|
||||
return !skip && include
|
||||
}
|
||||
|
||||
func resolveIfArgument(d *ast.Directive, variables map[string]interface{}) bool {
|
||||
arg := d.Arguments.ForName("if")
|
||||
if arg == nil {
|
||||
panic(fmt.Sprintf("%s: argument 'if' not defined", d.Name))
|
||||
}
|
||||
value, err := arg.Value.Value(variables)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ret, ok := value.(bool)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("%s: argument 'if' is not a boolean", d.Name))
|
||||
}
|
||||
return ret
|
||||
}
|
63
vendor/github.com/99designs/gqlgen/graphql/fieldset.go
generated
vendored
63
vendor/github.com/99designs/gqlgen/graphql/fieldset.go
generated
vendored
@ -1,63 +0,0 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"io"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type FieldSet struct {
|
||||
fields []CollectedField
|
||||
Values []Marshaler
|
||||
delayed []delayedResult
|
||||
}
|
||||
|
||||
type delayedResult struct {
|
||||
i int
|
||||
f func() Marshaler
|
||||
}
|
||||
|
||||
func NewFieldSet(fields []CollectedField) *FieldSet {
|
||||
return &FieldSet{
|
||||
fields: fields,
|
||||
Values: make([]Marshaler, len(fields)),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *FieldSet) Concurrently(i int, f func() Marshaler) {
|
||||
m.delayed = append(m.delayed, delayedResult{i: i, f: f})
|
||||
}
|
||||
|
||||
func (m *FieldSet) Dispatch() {
|
||||
if len(m.delayed) == 1 {
|
||||
// only one concurrent task, no need to spawn a goroutine or deal create waitgroups
|
||||
d := m.delayed[0]
|
||||
m.Values[d.i] = d.f()
|
||||
} else if len(m.delayed) > 1 {
|
||||
// more than one concurrent task, use the main goroutine to do one, only spawn goroutines for the others
|
||||
|
||||
var wg sync.WaitGroup
|
||||
for _, d := range m.delayed[1:] {
|
||||
wg.Add(1)
|
||||
go func(d delayedResult) {
|
||||
m.Values[d.i] = d.f()
|
||||
wg.Done()
|
||||
}(d)
|
||||
}
|
||||
|
||||
m.Values[m.delayed[0].i] = m.delayed[0].f()
|
||||
wg.Wait()
|
||||
}
|
||||
}
|
||||
|
||||
func (m *FieldSet) MarshalGQL(writer io.Writer) {
|
||||
writer.Write(openBrace)
|
||||
for i, field := range m.fields {
|
||||
if i != 0 {
|
||||
writer.Write(comma)
|
||||
}
|
||||
writeQuotedString(writer, field.Alias)
|
||||
writer.Write(colon)
|
||||
m.Values[i].MarshalGQL(writer)
|
||||
}
|
||||
writer.Write(closeBrace)
|
||||
}
|
31
vendor/github.com/99designs/gqlgen/graphql/float.go
generated
vendored
31
vendor/github.com/99designs/gqlgen/graphql/float.go
generated
vendored
@ -1,31 +0,0 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func MarshalFloat(f float64) Marshaler {
|
||||
return WriterFunc(func(w io.Writer) {
|
||||
io.WriteString(w, fmt.Sprintf("%g", f))
|
||||
})
|
||||
}
|
||||
|
||||
func UnmarshalFloat(v interface{}) (float64, error) {
|
||||
switch v := v.(type) {
|
||||
case string:
|
||||
return strconv.ParseFloat(v, 64)
|
||||
case int:
|
||||
return float64(v), nil
|
||||
case int64:
|
||||
return float64(v), nil
|
||||
case float64:
|
||||
return v, nil
|
||||
case json.Number:
|
||||
return strconv.ParseFloat(string(v), 64)
|
||||
default:
|
||||
return 0, fmt.Errorf("%T is not an float", v)
|
||||
}
|
||||
}
|
57
vendor/github.com/99designs/gqlgen/graphql/id.go
generated
vendored
57
vendor/github.com/99designs/gqlgen/graphql/id.go
generated
vendored
@ -1,57 +0,0 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func MarshalID(s string) Marshaler {
|
||||
return WriterFunc(func(w io.Writer) {
|
||||
io.WriteString(w, strconv.Quote(s))
|
||||
})
|
||||
}
|
||||
func UnmarshalID(v interface{}) (string, error) {
|
||||
switch v := v.(type) {
|
||||
case string:
|
||||
return v, nil
|
||||
case json.Number:
|
||||
return string(v), nil
|
||||
case int:
|
||||
return strconv.Itoa(v), nil
|
||||
case float64:
|
||||
return fmt.Sprintf("%f", v), nil
|
||||
case bool:
|
||||
if v {
|
||||
return "true", nil
|
||||
} else {
|
||||
return "false", nil
|
||||
}
|
||||
case nil:
|
||||
return "null", nil
|
||||
default:
|
||||
return "", fmt.Errorf("%T is not a string", v)
|
||||
}
|
||||
}
|
||||
|
||||
func MarshalIntID(i int) Marshaler {
|
||||
return WriterFunc(func(w io.Writer) {
|
||||
writeQuotedString(w, strconv.Itoa(i))
|
||||
})
|
||||
}
|
||||
|
||||
func UnmarshalIntID(v interface{}) (int, error) {
|
||||
switch v := v.(type) {
|
||||
case string:
|
||||
return strconv.Atoi(v)
|
||||
case int:
|
||||
return v, nil
|
||||
case int64:
|
||||
return int(v), nil
|
||||
case json.Number:
|
||||
return strconv.Atoi(string(v))
|
||||
default:
|
||||
return 0, fmt.Errorf("%T is not an int", v)
|
||||
}
|
||||
}
|
79
vendor/github.com/99designs/gqlgen/graphql/int.go
generated
vendored
79
vendor/github.com/99designs/gqlgen/graphql/int.go
generated
vendored
@ -1,79 +0,0 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func MarshalInt(i int) Marshaler {
|
||||
return WriterFunc(func(w io.Writer) {
|
||||
io.WriteString(w, strconv.Itoa(i))
|
||||
})
|
||||
}
|
||||
|
||||
func UnmarshalInt(v interface{}) (int, error) {
|
||||
switch v := v.(type) {
|
||||
case string:
|
||||
return strconv.Atoi(v)
|
||||
case int:
|
||||
return v, nil
|
||||
case int64:
|
||||
return int(v), nil
|
||||
case json.Number:
|
||||
return strconv.Atoi(string(v))
|
||||
default:
|
||||
return 0, fmt.Errorf("%T is not an int", v)
|
||||
}
|
||||
}
|
||||
|
||||
func MarshalInt64(i int64) Marshaler {
|
||||
return WriterFunc(func(w io.Writer) {
|
||||
io.WriteString(w, strconv.FormatInt(i, 10))
|
||||
})
|
||||
}
|
||||
|
||||
func UnmarshalInt64(v interface{}) (int64, error) {
|
||||
switch v := v.(type) {
|
||||
case string:
|
||||
return strconv.ParseInt(v, 10, 64)
|
||||
case int:
|
||||
return int64(v), nil
|
||||
case int64:
|
||||
return v, nil
|
||||
case json.Number:
|
||||
return strconv.ParseInt(string(v), 10, 64)
|
||||
default:
|
||||
return 0, fmt.Errorf("%T is not an int", v)
|
||||
}
|
||||
}
|
||||
|
||||
func MarshalInt32(i int32) Marshaler {
|
||||
return WriterFunc(func(w io.Writer) {
|
||||
io.WriteString(w, strconv.FormatInt(int64(i), 10))
|
||||
})
|
||||
}
|
||||
|
||||
func UnmarshalInt32(v interface{}) (int32, error) {
|
||||
switch v := v.(type) {
|
||||
case string:
|
||||
iv, err := strconv.ParseInt(v, 10, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int32(iv), nil
|
||||
case int:
|
||||
return int32(v), nil
|
||||
case int64:
|
||||
return int32(v), nil
|
||||
case json.Number:
|
||||
iv, err := strconv.ParseInt(string(v), 10, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int32(iv), nil
|
||||
default:
|
||||
return 0, fmt.Errorf("%T is not an int", v)
|
||||
}
|
||||
}
|
72
vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go
generated
vendored
72
vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go
generated
vendored
@ -1,72 +0,0 @@
|
||||
// introspection implements the spec defined in https://github.com/facebook/graphql/blob/master/spec/Section%204%20--%20Introspection.md#schema-introspection
|
||||
package introspection
|
||||
|
||||
import "github.com/vektah/gqlparser/ast"
|
||||
|
||||
type (
|
||||
Directive struct {
|
||||
Name string
|
||||
Description string
|
||||
Locations []string
|
||||
Args []InputValue
|
||||
}
|
||||
|
||||
EnumValue struct {
|
||||
Name string
|
||||
Description string
|
||||
deprecation *ast.Directive
|
||||
}
|
||||
|
||||
Field struct {
|
||||
Name string
|
||||
Description string
|
||||
Type *Type
|
||||
Args []InputValue
|
||||
deprecation *ast.Directive
|
||||
}
|
||||
|
||||
InputValue struct {
|
||||
Name string
|
||||
Description string
|
||||
DefaultValue *string
|
||||
Type *Type
|
||||
}
|
||||
)
|
||||
|
||||
func WrapSchema(schema *ast.Schema) *Schema {
|
||||
return &Schema{schema: schema}
|
||||
}
|
||||
|
||||
func (f *EnumValue) IsDeprecated() bool {
|
||||
return f.deprecation != nil
|
||||
}
|
||||
|
||||
func (f *EnumValue) DeprecationReason() *string {
|
||||
if f.deprecation == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
reason := f.deprecation.Arguments.ForName("reason")
|
||||
if reason == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &reason.Value.Raw
|
||||
}
|
||||
|
||||
func (f *Field) IsDeprecated() bool {
|
||||
return f.deprecation != nil
|
||||
}
|
||||
|
||||
func (f *Field) DeprecationReason() *string {
|
||||
if f.deprecation == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
reason := f.deprecation.Arguments.ForName("reason")
|
||||
if reason == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &reason.Value.Raw
|
||||
}
|
104
vendor/github.com/99designs/gqlgen/graphql/introspection/query.go
generated
vendored
104
vendor/github.com/99designs/gqlgen/graphql/introspection/query.go
generated
vendored
@ -1,104 +0,0 @@
|
||||
package introspection
|
||||
|
||||
// Query is the query generated by graphiql to determine type information
|
||||
const Query = `
|
||||
query IntrospectionQuery {
|
||||
__schema {
|
||||
queryType {
|
||||
name
|
||||
}
|
||||
mutationType {
|
||||
name
|
||||
}
|
||||
subscriptionType {
|
||||
name
|
||||
}
|
||||
types {
|
||||
...FullType
|
||||
}
|
||||
directives {
|
||||
name
|
||||
description
|
||||
locations
|
||||
args {
|
||||
...InputValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment FullType on __Type {
|
||||
kind
|
||||
name
|
||||
description
|
||||
fields(includeDeprecated: true) {
|
||||
name
|
||||
description
|
||||
args {
|
||||
...InputValue
|
||||
}
|
||||
type {
|
||||
...TypeRef
|
||||
}
|
||||
isDeprecated
|
||||
deprecationReason
|
||||
}
|
||||
inputFields {
|
||||
...InputValue
|
||||
}
|
||||
interfaces {
|
||||
...TypeRef
|
||||
}
|
||||
enumValues(includeDeprecated: true) {
|
||||
name
|
||||
description
|
||||
isDeprecated
|
||||
deprecationReason
|
||||
}
|
||||
possibleTypes {
|
||||
...TypeRef
|
||||
}
|
||||
}
|
||||
|
||||
fragment InputValue on __InputValue {
|
||||
name
|
||||
description
|
||||
type {
|
||||
...TypeRef
|
||||
}
|
||||
defaultValue
|
||||
}
|
||||
|
||||
fragment TypeRef on __Type {
|
||||
kind
|
||||
name
|
||||
ofType {
|
||||
kind
|
||||
name
|
||||
ofType {
|
||||
kind
|
||||
name
|
||||
ofType {
|
||||
kind
|
||||
name
|
||||
ofType {
|
||||
kind
|
||||
name
|
||||
ofType {
|
||||
kind
|
||||
name
|
||||
ofType {
|
||||
kind
|
||||
name
|
||||
ofType {
|
||||
kind
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
68
vendor/github.com/99designs/gqlgen/graphql/introspection/schema.go
generated
vendored
68
vendor/github.com/99designs/gqlgen/graphql/introspection/schema.go
generated
vendored
@ -1,68 +0,0 @@
|
||||
package introspection
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
)
|
||||
|
||||
type Schema struct {
|
||||
schema *ast.Schema
|
||||
}
|
||||
|
||||
func (s *Schema) Types() []Type {
|
||||
types := make([]Type, 0, len(s.schema.Types))
|
||||
for _, typ := range s.schema.Types {
|
||||
if strings.HasPrefix(typ.Name, "__") {
|
||||
continue
|
||||
}
|
||||
types = append(types, *WrapTypeFromDef(s.schema, typ))
|
||||
}
|
||||
return types
|
||||
}
|
||||
|
||||
func (s *Schema) QueryType() *Type {
|
||||
return WrapTypeFromDef(s.schema, s.schema.Query)
|
||||
}
|
||||
|
||||
func (s *Schema) MutationType() *Type {
|
||||
return WrapTypeFromDef(s.schema, s.schema.Mutation)
|
||||
}
|
||||
|
||||
func (s *Schema) SubscriptionType() *Type {
|
||||
return WrapTypeFromDef(s.schema, s.schema.Subscription)
|
||||
}
|
||||
|
||||
func (s *Schema) Directives() []Directive {
|
||||
res := make([]Directive, 0, len(s.schema.Directives))
|
||||
|
||||
for _, d := range s.schema.Directives {
|
||||
res = append(res, s.directiveFromDef(d))
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func (s *Schema) directiveFromDef(d *ast.DirectiveDefinition) Directive {
|
||||
locs := make([]string, len(d.Locations))
|
||||
for i, loc := range d.Locations {
|
||||
locs[i] = string(loc)
|
||||
}
|
||||
|
||||
args := make([]InputValue, len(d.Arguments))
|
||||
for i, arg := range d.Arguments {
|
||||
args[i] = InputValue{
|
||||
Name: arg.Name,
|
||||
Description: arg.Description,
|
||||
DefaultValue: defaultValue(arg.DefaultValue),
|
||||
Type: WrapTypeFromType(s.schema, arg.Type),
|
||||
}
|
||||
}
|
||||
|
||||
return Directive{
|
||||
Name: d.Name,
|
||||
Description: d.Description,
|
||||
Locations: locs,
|
||||
Args: args,
|
||||
}
|
||||
}
|
176
vendor/github.com/99designs/gqlgen/graphql/introspection/type.go
generated
vendored
176
vendor/github.com/99designs/gqlgen/graphql/introspection/type.go
generated
vendored
@ -1,176 +0,0 @@
|
||||
package introspection
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
)
|
||||
|
||||
type Type struct {
|
||||
schema *ast.Schema
|
||||
def *ast.Definition
|
||||
typ *ast.Type
|
||||
}
|
||||
|
||||
func WrapTypeFromDef(s *ast.Schema, def *ast.Definition) *Type {
|
||||
if def == nil {
|
||||
return nil
|
||||
}
|
||||
return &Type{schema: s, def: def}
|
||||
}
|
||||
|
||||
func WrapTypeFromType(s *ast.Schema, typ *ast.Type) *Type {
|
||||
if typ == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !typ.NonNull && typ.NamedType != "" {
|
||||
return &Type{schema: s, def: s.Types[typ.NamedType]}
|
||||
}
|
||||
return &Type{schema: s, typ: typ}
|
||||
}
|
||||
|
||||
func (t *Type) Kind() string {
|
||||
if t.typ != nil {
|
||||
if t.typ.NonNull {
|
||||
return "NON_NULL"
|
||||
}
|
||||
|
||||
if t.typ.Elem != nil {
|
||||
return "LIST"
|
||||
}
|
||||
} else {
|
||||
return string(t.def.Kind)
|
||||
}
|
||||
|
||||
panic("UNKNOWN")
|
||||
}
|
||||
|
||||
func (t *Type) Name() *string {
|
||||
if t.def == nil {
|
||||
return nil
|
||||
}
|
||||
return &t.def.Name
|
||||
}
|
||||
|
||||
func (t *Type) Description() string {
|
||||
if t.def == nil {
|
||||
return ""
|
||||
}
|
||||
return t.def.Description
|
||||
}
|
||||
|
||||
func (t *Type) Fields(includeDeprecated bool) []Field {
|
||||
if t.def == nil || (t.def.Kind != ast.Object && t.def.Kind != ast.Interface) {
|
||||
return []Field{}
|
||||
}
|
||||
fields := []Field{}
|
||||
for _, f := range t.def.Fields {
|
||||
if strings.HasPrefix(f.Name, "__") {
|
||||
continue
|
||||
}
|
||||
|
||||
if !includeDeprecated && f.Directives.ForName("deprecated") != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var args []InputValue
|
||||
for _, arg := range f.Arguments {
|
||||
args = append(args, InputValue{
|
||||
Type: WrapTypeFromType(t.schema, arg.Type),
|
||||
Name: arg.Name,
|
||||
Description: arg.Description,
|
||||
DefaultValue: defaultValue(arg.DefaultValue),
|
||||
})
|
||||
}
|
||||
|
||||
fields = append(fields, Field{
|
||||
Name: f.Name,
|
||||
Description: f.Description,
|
||||
Args: args,
|
||||
Type: WrapTypeFromType(t.schema, f.Type),
|
||||
deprecation: f.Directives.ForName("deprecated"),
|
||||
})
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
func (t *Type) InputFields() []InputValue {
|
||||
if t.def == nil || t.def.Kind != ast.InputObject {
|
||||
return []InputValue{}
|
||||
}
|
||||
|
||||
res := []InputValue{}
|
||||
for _, f := range t.def.Fields {
|
||||
res = append(res, InputValue{
|
||||
Name: f.Name,
|
||||
Description: f.Description,
|
||||
Type: WrapTypeFromType(t.schema, f.Type),
|
||||
DefaultValue: defaultValue(f.DefaultValue),
|
||||
})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func defaultValue(value *ast.Value) *string {
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
val := value.String()
|
||||
return &val
|
||||
}
|
||||
|
||||
func (t *Type) Interfaces() []Type {
|
||||
if t.def == nil || t.def.Kind != ast.Object {
|
||||
return []Type{}
|
||||
}
|
||||
|
||||
res := []Type{}
|
||||
for _, intf := range t.def.Interfaces {
|
||||
res = append(res, *WrapTypeFromDef(t.schema, t.schema.Types[intf]))
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func (t *Type) PossibleTypes() []Type {
|
||||
if t.def == nil || (t.def.Kind != ast.Interface && t.def.Kind != ast.Union) {
|
||||
return []Type{}
|
||||
}
|
||||
|
||||
res := []Type{}
|
||||
for _, pt := range t.schema.GetPossibleTypes(t.def) {
|
||||
res = append(res, *WrapTypeFromDef(t.schema, pt))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (t *Type) EnumValues(includeDeprecated bool) []EnumValue {
|
||||
if t.def == nil || t.def.Kind != ast.Enum {
|
||||
return []EnumValue{}
|
||||
}
|
||||
|
||||
res := []EnumValue{}
|
||||
for _, val := range t.def.EnumValues {
|
||||
res = append(res, EnumValue{
|
||||
Name: val.Name,
|
||||
Description: val.Description,
|
||||
deprecation: val.Directives.ForName("deprecated"),
|
||||
})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (t *Type) OfType() *Type {
|
||||
if t.typ == nil {
|
||||
return nil
|
||||
}
|
||||
if t.typ.NonNull {
|
||||
// fake non null nodes
|
||||
cpy := *t.typ
|
||||
cpy.NonNull = false
|
||||
|
||||
return WrapTypeFromType(t.schema, &cpy)
|
||||
}
|
||||
return WrapTypeFromType(t.schema, t.typ.Elem)
|
||||
}
|
52
vendor/github.com/99designs/gqlgen/graphql/jsonw.go
generated
vendored
52
vendor/github.com/99designs/gqlgen/graphql/jsonw.go
generated
vendored
@ -1,52 +0,0 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
var nullLit = []byte(`null`)
|
||||
var trueLit = []byte(`true`)
|
||||
var falseLit = []byte(`false`)
|
||||
var openBrace = []byte(`{`)
|
||||
var closeBrace = []byte(`}`)
|
||||
var openBracket = []byte(`[`)
|
||||
var closeBracket = []byte(`]`)
|
||||
var colon = []byte(`:`)
|
||||
var comma = []byte(`,`)
|
||||
|
||||
var Null = &lit{nullLit}
|
||||
var True = &lit{trueLit}
|
||||
var False = &lit{falseLit}
|
||||
|
||||
type Marshaler interface {
|
||||
MarshalGQL(w io.Writer)
|
||||
}
|
||||
|
||||
type Unmarshaler interface {
|
||||
UnmarshalGQL(v interface{}) error
|
||||
}
|
||||
|
||||
type WriterFunc func(writer io.Writer)
|
||||
|
||||
func (f WriterFunc) MarshalGQL(w io.Writer) {
|
||||
f(w)
|
||||
}
|
||||
|
||||
type Array []Marshaler
|
||||
|
||||
func (a Array) MarshalGQL(writer io.Writer) {
|
||||
writer.Write(openBracket)
|
||||
for i, val := range a {
|
||||
if i != 0 {
|
||||
writer.Write(comma)
|
||||
}
|
||||
val.MarshalGQL(writer)
|
||||
}
|
||||
writer.Write(closeBracket)
|
||||
}
|
||||
|
||||
type lit struct{ b []byte }
|
||||
|
||||
func (l lit) MarshalGQL(w io.Writer) {
|
||||
w.Write(l.b)
|
||||
}
|
24
vendor/github.com/99designs/gqlgen/graphql/map.go
generated
vendored
24
vendor/github.com/99designs/gqlgen/graphql/map.go
generated
vendored
@ -1,24 +0,0 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
func MarshalMap(val map[string]interface{}) Marshaler {
|
||||
return WriterFunc(func(w io.Writer) {
|
||||
err := json.NewEncoder(w).Encode(val)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func UnmarshalMap(v interface{}) (map[string]interface{}, error) {
|
||||
if m, ok := v.(map[string]interface{}); ok {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("%T is not a map", v)
|
||||
}
|
14
vendor/github.com/99designs/gqlgen/graphql/oneshot.go
generated
vendored
14
vendor/github.com/99designs/gqlgen/graphql/oneshot.go
generated
vendored
@ -1,14 +0,0 @@
|
||||
package graphql
|
||||
|
||||
func OneShot(resp *Response) func() *Response {
|
||||
var oneshot bool
|
||||
|
||||
return func() *Response {
|
||||
if oneshot {
|
||||
return nil
|
||||
}
|
||||
oneshot = true
|
||||
|
||||
return resp
|
||||
}
|
||||
}
|
19
vendor/github.com/99designs/gqlgen/graphql/recovery.go
generated
vendored
19
vendor/github.com/99designs/gqlgen/graphql/recovery.go
generated
vendored
@ -1,19 +0,0 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
type RecoverFunc func(ctx context.Context, err interface{}) (userMessage error)
|
||||
|
||||
func DefaultRecover(ctx context.Context, err interface{}) error {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
fmt.Fprintln(os.Stderr)
|
||||
debug.PrintStack()
|
||||
|
||||
return errors.New("internal system error")
|
||||
}
|
24
vendor/github.com/99designs/gqlgen/graphql/response.go
generated
vendored
24
vendor/github.com/99designs/gqlgen/graphql/response.go
generated
vendored
@ -1,24 +0,0 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/vektah/gqlparser/gqlerror"
|
||||
)
|
||||
|
||||
// Errors are intentionally serialized first based on the advice in
|
||||
// https://github.com/facebook/graphql/commit/7b40390d48680b15cb93e02d46ac5eb249689876#diff-757cea6edf0288677a9eea4cfc801d87R107
|
||||
// and https://github.com/facebook/graphql/pull/384
|
||||
type Response struct {
|
||||
Errors gqlerror.List `json:"errors,omitempty"`
|
||||
Data json.RawMessage `json:"data"`
|
||||
Extensions map[string]interface{} `json:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
func ErrorResponse(ctx context.Context, messagef string, args ...interface{}) *Response {
|
||||
return &Response{
|
||||
Errors: gqlerror.List{{Message: fmt.Sprintf(messagef, args...)}},
|
||||
}
|
||||
}
|
7
vendor/github.com/99designs/gqlgen/graphql/root.go
generated
vendored
7
vendor/github.com/99designs/gqlgen/graphql/root.go
generated
vendored
@ -1,7 +0,0 @@
|
||||
package graphql
|
||||
|
||||
type Query struct{}
|
||||
|
||||
type Mutation struct{}
|
||||
|
||||
type Subscription struct{}
|
68
vendor/github.com/99designs/gqlgen/graphql/string.go
generated
vendored
68
vendor/github.com/99designs/gqlgen/graphql/string.go
generated
vendored
@ -1,68 +0,0 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const encodeHex = "0123456789ABCDEF"
|
||||
|
||||
func MarshalString(s string) Marshaler {
|
||||
return WriterFunc(func(w io.Writer) {
|
||||
writeQuotedString(w, s)
|
||||
})
|
||||
}
|
||||
|
||||
func writeQuotedString(w io.Writer, s string) {
|
||||
start := 0
|
||||
io.WriteString(w, `"`)
|
||||
|
||||
for i, c := range s {
|
||||
if c < 0x20 || c == '\\' || c == '"' {
|
||||
io.WriteString(w, s[start:i])
|
||||
|
||||
switch c {
|
||||
case '\t':
|
||||
io.WriteString(w, `\t`)
|
||||
case '\r':
|
||||
io.WriteString(w, `\r`)
|
||||
case '\n':
|
||||
io.WriteString(w, `\n`)
|
||||
case '\\':
|
||||
io.WriteString(w, `\\`)
|
||||
case '"':
|
||||
io.WriteString(w, `\"`)
|
||||
default:
|
||||
io.WriteString(w, `\u00`)
|
||||
w.Write([]byte{encodeHex[c>>4], encodeHex[c&0xf]})
|
||||
}
|
||||
|
||||
start = i + 1
|
||||
}
|
||||
}
|
||||
|
||||
io.WriteString(w, s[start:])
|
||||
io.WriteString(w, `"`)
|
||||
}
|
||||
|
||||
func UnmarshalString(v interface{}) (string, error) {
|
||||
switch v := v.(type) {
|
||||
case string:
|
||||
return v, nil
|
||||
case int:
|
||||
return strconv.Itoa(v), nil
|
||||
case float64:
|
||||
return fmt.Sprintf("%f", v), nil
|
||||
case bool:
|
||||
if v {
|
||||
return "true", nil
|
||||
} else {
|
||||
return "false", nil
|
||||
}
|
||||
case nil:
|
||||
return "null", nil
|
||||
default:
|
||||
return "", fmt.Errorf("%T is not a string", v)
|
||||
}
|
||||
}
|
25
vendor/github.com/99designs/gqlgen/graphql/time.go
generated
vendored
25
vendor/github.com/99designs/gqlgen/graphql/time.go
generated
vendored
@ -1,25 +0,0 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func MarshalTime(t time.Time) Marshaler {
|
||||
if t.IsZero() {
|
||||
return Null
|
||||
}
|
||||
|
||||
return WriterFunc(func(w io.Writer) {
|
||||
io.WriteString(w, strconv.Quote(t.Format(time.RFC3339)))
|
||||
})
|
||||
}
|
||||
|
||||
func UnmarshalTime(v interface{}) (time.Time, error) {
|
||||
if tmpStr, ok := v.(string); ok {
|
||||
return time.Parse(time.RFC3339, tmpStr)
|
||||
}
|
||||
return time.Time{}, errors.New("time should be RFC3339 formatted string")
|
||||
}
|
58
vendor/github.com/99designs/gqlgen/graphql/tracer.go
generated
vendored
58
vendor/github.com/99designs/gqlgen/graphql/tracer.go
generated
vendored
@ -1,58 +0,0 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
var _ Tracer = (*NopTracer)(nil)
|
||||
|
||||
type Tracer interface {
|
||||
StartOperationParsing(ctx context.Context) context.Context
|
||||
EndOperationParsing(ctx context.Context)
|
||||
StartOperationValidation(ctx context.Context) context.Context
|
||||
EndOperationValidation(ctx context.Context)
|
||||
StartOperationExecution(ctx context.Context) context.Context
|
||||
StartFieldExecution(ctx context.Context, field CollectedField) context.Context
|
||||
StartFieldResolverExecution(ctx context.Context, rc *ResolverContext) context.Context
|
||||
StartFieldChildExecution(ctx context.Context) context.Context
|
||||
EndFieldExecution(ctx context.Context)
|
||||
EndOperationExecution(ctx context.Context)
|
||||
}
|
||||
|
||||
type NopTracer struct{}
|
||||
|
||||
func (NopTracer) StartOperationParsing(ctx context.Context) context.Context {
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (NopTracer) EndOperationParsing(ctx context.Context) {
|
||||
}
|
||||
|
||||
func (NopTracer) StartOperationValidation(ctx context.Context) context.Context {
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (NopTracer) EndOperationValidation(ctx context.Context) {
|
||||
}
|
||||
|
||||
func (NopTracer) StartOperationExecution(ctx context.Context) context.Context {
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (NopTracer) StartFieldExecution(ctx context.Context, field CollectedField) context.Context {
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (NopTracer) StartFieldResolverExecution(ctx context.Context, rc *ResolverContext) context.Context {
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (NopTracer) StartFieldChildExecution(ctx context.Context) context.Context {
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (NopTracer) EndFieldExecution(ctx context.Context) {
|
||||
}
|
||||
|
||||
func (NopTracer) EndOperationExecution(ctx context.Context) {
|
||||
}
|
26
vendor/github.com/99designs/gqlgen/graphql/upload.go
generated
vendored
26
vendor/github.com/99designs/gqlgen/graphql/upload.go
generated
vendored
@ -1,26 +0,0 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
type Upload struct {
|
||||
File io.Reader
|
||||
Filename string
|
||||
Size int64
|
||||
}
|
||||
|
||||
func MarshalUpload(f Upload) Marshaler {
|
||||
return WriterFunc(func(w io.Writer) {
|
||||
io.Copy(w, f.File)
|
||||
})
|
||||
}
|
||||
|
||||
func UnmarshalUpload(v interface{}) (Upload, error) {
|
||||
upload, ok := v.(Upload)
|
||||
if !ok {
|
||||
return Upload{}, fmt.Errorf("%T is not an Upload", v)
|
||||
}
|
||||
return upload, nil
|
||||
}
|
3
vendor/github.com/99designs/gqlgen/graphql/version.go
generated
vendored
3
vendor/github.com/99designs/gqlgen/graphql/version.go
generated
vendored
@ -1,3 +0,0 @@
|
||||
package graphql
|
||||
|
||||
const Version = "v0.9.2"
|
57
vendor/github.com/99designs/gqlgen/handler/context.go
generated
vendored
57
vendor/github.com/99designs/gqlgen/handler/context.go
generated
vendored
@ -1,57 +0,0 @@
|
||||
package handler
|
||||
|
||||
import "context"
|
||||
|
||||
type key string
|
||||
|
||||
const (
|
||||
initpayload key = "ws_initpayload_context"
|
||||
)
|
||||
|
||||
// InitPayload is a structure that is parsed from the websocket init message payload. TO use
|
||||
// request headers for non-websocket, instead wrap the graphql handler in a middleware.
|
||||
type InitPayload map[string]interface{}
|
||||
|
||||
// GetString safely gets a string value from the payload. It returns an empty string if the
|
||||
// payload is nil or the value isn't set.
|
||||
func (payload InitPayload) GetString(key string) string {
|
||||
if payload == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
if value, ok := payload[key]; ok {
|
||||
res, _ := value.(string)
|
||||
return res
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// Authorization is a short hand for getting the Authorization header from the
|
||||
// payload.
|
||||
func (payload InitPayload) Authorization() string {
|
||||
if value := payload.GetString("Authorization"); value != "" {
|
||||
return value
|
||||
}
|
||||
|
||||
if value := payload.GetString("authorization"); value != "" {
|
||||
return value
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func withInitPayload(ctx context.Context, payload InitPayload) context.Context {
|
||||
return context.WithValue(ctx, initpayload, payload)
|
||||
}
|
||||
|
||||
// GetInitPayload gets a map of the data sent with the connection_init message, which is used by
|
||||
// graphql clients as a stand-in for HTTP headers.
|
||||
func GetInitPayload(ctx context.Context) InitPayload {
|
||||
payload, ok := ctx.Value(initpayload).(InitPayload)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return payload
|
||||
}
|
802
vendor/github.com/99designs/gqlgen/handler/graphql.go
generated
vendored
802
vendor/github.com/99designs/gqlgen/handler/graphql.go
generated
vendored
@ -1,802 +0,0 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/99designs/gqlgen/complexity"
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
"github.com/gorilla/websocket"
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
"github.com/vektah/gqlparser/gqlerror"
|
||||
"github.com/vektah/gqlparser/parser"
|
||||
"github.com/vektah/gqlparser/validator"
|
||||
)
|
||||
|
||||
type params struct {
|
||||
Query string `json:"query"`
|
||||
OperationName string `json:"operationName"`
|
||||
Variables map[string]interface{} `json:"variables"`
|
||||
Extensions *extensions `json:"extensions"`
|
||||
}
|
||||
|
||||
type extensions struct {
|
||||
PersistedQuery *persistedQuery `json:"persistedQuery"`
|
||||
}
|
||||
|
||||
type persistedQuery struct {
|
||||
Sha256 string `json:"sha256Hash"`
|
||||
Version int64 `json:"version"`
|
||||
}
|
||||
|
||||
const (
|
||||
errPersistedQueryNotSupported = "PersistedQueryNotSupported"
|
||||
errPersistedQueryNotFound = "PersistedQueryNotFound"
|
||||
)
|
||||
|
||||
type PersistedQueryCache interface {
|
||||
Add(ctx context.Context, hash string, query string)
|
||||
Get(ctx context.Context, hash string) (string, bool)
|
||||
}
|
||||
|
||||
type websocketInitFunc func(ctx context.Context, initPayload InitPayload) error
|
||||
|
||||
type Config struct {
|
||||
cacheSize int
|
||||
upgrader websocket.Upgrader
|
||||
recover graphql.RecoverFunc
|
||||
errorPresenter graphql.ErrorPresenterFunc
|
||||
resolverHook graphql.FieldMiddleware
|
||||
requestHook graphql.RequestMiddleware
|
||||
tracer graphql.Tracer
|
||||
complexityLimit int
|
||||
complexityLimitFunc graphql.ComplexityLimitFunc
|
||||
websocketInitFunc websocketInitFunc
|
||||
disableIntrospection bool
|
||||
connectionKeepAlivePingInterval time.Duration
|
||||
uploadMaxMemory int64
|
||||
uploadMaxSize int64
|
||||
apqCache PersistedQueryCache
|
||||
}
|
||||
|
||||
func (c *Config) newRequestContext(es graphql.ExecutableSchema, doc *ast.QueryDocument, op *ast.OperationDefinition, query string, variables map[string]interface{}) *graphql.RequestContext {
|
||||
reqCtx := graphql.NewRequestContext(doc, query, variables)
|
||||
reqCtx.DisableIntrospection = c.disableIntrospection
|
||||
|
||||
if hook := c.recover; hook != nil {
|
||||
reqCtx.Recover = hook
|
||||
}
|
||||
|
||||
if hook := c.errorPresenter; hook != nil {
|
||||
reqCtx.ErrorPresenter = hook
|
||||
}
|
||||
|
||||
if hook := c.resolverHook; hook != nil {
|
||||
reqCtx.ResolverMiddleware = hook
|
||||
}
|
||||
|
||||
if hook := c.requestHook; hook != nil {
|
||||
reqCtx.RequestMiddleware = hook
|
||||
}
|
||||
|
||||
if hook := c.tracer; hook != nil {
|
||||
reqCtx.Tracer = hook
|
||||
}
|
||||
|
||||
if c.complexityLimit > 0 || c.complexityLimitFunc != nil {
|
||||
reqCtx.ComplexityLimit = c.complexityLimit
|
||||
operationComplexity := complexity.Calculate(es, op, variables)
|
||||
reqCtx.OperationComplexity = operationComplexity
|
||||
}
|
||||
|
||||
return reqCtx
|
||||
}
|
||||
|
||||
type Option func(cfg *Config)
|
||||
|
||||
func WebsocketUpgrader(upgrader websocket.Upgrader) Option {
|
||||
return func(cfg *Config) {
|
||||
cfg.upgrader = upgrader
|
||||
}
|
||||
}
|
||||
|
||||
func RecoverFunc(recover graphql.RecoverFunc) Option {
|
||||
return func(cfg *Config) {
|
||||
cfg.recover = recover
|
||||
}
|
||||
}
|
||||
|
||||
// ErrorPresenter transforms errors found while resolving into errors that will be returned to the user. It provides
|
||||
// a good place to add any extra fields, like error.type, that might be desired by your frontend. Check the default
|
||||
// implementation in graphql.DefaultErrorPresenter for an example.
|
||||
func ErrorPresenter(f graphql.ErrorPresenterFunc) Option {
|
||||
return func(cfg *Config) {
|
||||
cfg.errorPresenter = f
|
||||
}
|
||||
}
|
||||
|
||||
// IntrospectionEnabled = false will forbid clients from calling introspection endpoints. Can be useful in prod when you dont
|
||||
// want clients introspecting the full schema.
|
||||
func IntrospectionEnabled(enabled bool) Option {
|
||||
return func(cfg *Config) {
|
||||
cfg.disableIntrospection = !enabled
|
||||
}
|
||||
}
|
||||
|
||||
// ComplexityLimit sets a maximum query complexity that is allowed to be executed.
|
||||
// If a query is submitted that exceeds the limit, a 422 status code will be returned.
|
||||
func ComplexityLimit(limit int) Option {
|
||||
return func(cfg *Config) {
|
||||
cfg.complexityLimit = limit
|
||||
}
|
||||
}
|
||||
|
||||
// ComplexityLimitFunc allows you to define a function to dynamically set the maximum query complexity that is allowed
|
||||
// to be executed.
|
||||
// If a query is submitted that exceeds the limit, a 422 status code will be returned.
|
||||
func ComplexityLimitFunc(complexityLimitFunc graphql.ComplexityLimitFunc) Option {
|
||||
return func(cfg *Config) {
|
||||
cfg.complexityLimitFunc = complexityLimitFunc
|
||||
}
|
||||
}
|
||||
|
||||
// ResolverMiddleware allows you to define a function that will be called around every resolver,
|
||||
// useful for logging.
|
||||
func ResolverMiddleware(middleware graphql.FieldMiddleware) Option {
|
||||
return func(cfg *Config) {
|
||||
if cfg.resolverHook == nil {
|
||||
cfg.resolverHook = middleware
|
||||
return
|
||||
}
|
||||
|
||||
lastResolve := cfg.resolverHook
|
||||
cfg.resolverHook = func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) {
|
||||
return lastResolve(ctx, func(ctx context.Context) (res interface{}, err error) {
|
||||
return middleware(ctx, next)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RequestMiddleware allows you to define a function that will be called around the root request,
|
||||
// after the query has been parsed. This is useful for logging
|
||||
func RequestMiddleware(middleware graphql.RequestMiddleware) Option {
|
||||
return func(cfg *Config) {
|
||||
if cfg.requestHook == nil {
|
||||
cfg.requestHook = middleware
|
||||
return
|
||||
}
|
||||
|
||||
lastResolve := cfg.requestHook
|
||||
cfg.requestHook = func(ctx context.Context, next func(ctx context.Context) []byte) []byte {
|
||||
return lastResolve(ctx, func(ctx context.Context) []byte {
|
||||
return middleware(ctx, next)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tracer allows you to add a request/resolver tracer that will be called around the root request,
|
||||
// calling resolver. This is useful for tracing
|
||||
func Tracer(tracer graphql.Tracer) Option {
|
||||
return func(cfg *Config) {
|
||||
if cfg.tracer == nil {
|
||||
cfg.tracer = tracer
|
||||
|
||||
} else {
|
||||
lastResolve := cfg.tracer
|
||||
cfg.tracer = &tracerWrapper{
|
||||
tracer1: lastResolve,
|
||||
tracer2: tracer,
|
||||
}
|
||||
}
|
||||
|
||||
opt := RequestMiddleware(func(ctx context.Context, next func(ctx context.Context) []byte) []byte {
|
||||
ctx = tracer.StartOperationExecution(ctx)
|
||||
resp := next(ctx)
|
||||
tracer.EndOperationExecution(ctx)
|
||||
|
||||
return resp
|
||||
})
|
||||
opt(cfg)
|
||||
}
|
||||
}
|
||||
|
||||
type tracerWrapper struct {
|
||||
tracer1 graphql.Tracer
|
||||
tracer2 graphql.Tracer
|
||||
}
|
||||
|
||||
func (tw *tracerWrapper) StartOperationParsing(ctx context.Context) context.Context {
|
||||
ctx = tw.tracer1.StartOperationParsing(ctx)
|
||||
ctx = tw.tracer2.StartOperationParsing(ctx)
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (tw *tracerWrapper) EndOperationParsing(ctx context.Context) {
|
||||
tw.tracer2.EndOperationParsing(ctx)
|
||||
tw.tracer1.EndOperationParsing(ctx)
|
||||
}
|
||||
|
||||
func (tw *tracerWrapper) StartOperationValidation(ctx context.Context) context.Context {
|
||||
ctx = tw.tracer1.StartOperationValidation(ctx)
|
||||
ctx = tw.tracer2.StartOperationValidation(ctx)
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (tw *tracerWrapper) EndOperationValidation(ctx context.Context) {
|
||||
tw.tracer2.EndOperationValidation(ctx)
|
||||
tw.tracer1.EndOperationValidation(ctx)
|
||||
}
|
||||
|
||||
func (tw *tracerWrapper) StartOperationExecution(ctx context.Context) context.Context {
|
||||
ctx = tw.tracer1.StartOperationExecution(ctx)
|
||||
ctx = tw.tracer2.StartOperationExecution(ctx)
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (tw *tracerWrapper) StartFieldExecution(ctx context.Context, field graphql.CollectedField) context.Context {
|
||||
ctx = tw.tracer1.StartFieldExecution(ctx, field)
|
||||
ctx = tw.tracer2.StartFieldExecution(ctx, field)
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (tw *tracerWrapper) StartFieldResolverExecution(ctx context.Context, rc *graphql.ResolverContext) context.Context {
|
||||
ctx = tw.tracer1.StartFieldResolverExecution(ctx, rc)
|
||||
ctx = tw.tracer2.StartFieldResolverExecution(ctx, rc)
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (tw *tracerWrapper) StartFieldChildExecution(ctx context.Context) context.Context {
|
||||
ctx = tw.tracer1.StartFieldChildExecution(ctx)
|
||||
ctx = tw.tracer2.StartFieldChildExecution(ctx)
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (tw *tracerWrapper) EndFieldExecution(ctx context.Context) {
|
||||
tw.tracer2.EndFieldExecution(ctx)
|
||||
tw.tracer1.EndFieldExecution(ctx)
|
||||
}
|
||||
|
||||
func (tw *tracerWrapper) EndOperationExecution(ctx context.Context) {
|
||||
tw.tracer2.EndOperationExecution(ctx)
|
||||
tw.tracer1.EndOperationExecution(ctx)
|
||||
}
|
||||
|
||||
// WebsocketInitFunc is called when the server receives connection init message from the client.
|
||||
// This can be used to check initial payload to see whether to accept the websocket connection.
|
||||
func WebsocketInitFunc(websocketInitFunc func(ctx context.Context, initPayload InitPayload) error) Option {
|
||||
return func(cfg *Config) {
|
||||
cfg.websocketInitFunc = websocketInitFunc
|
||||
}
|
||||
}
|
||||
|
||||
// CacheSize sets the maximum size of the query cache.
|
||||
// If size is less than or equal to 0, the cache is disabled.
|
||||
func CacheSize(size int) Option {
|
||||
return func(cfg *Config) {
|
||||
cfg.cacheSize = size
|
||||
}
|
||||
}
|
||||
|
||||
// UploadMaxSize sets the maximum number of bytes used to parse a request body
|
||||
// as multipart/form-data.
|
||||
func UploadMaxSize(size int64) Option {
|
||||
return func(cfg *Config) {
|
||||
cfg.uploadMaxSize = size
|
||||
}
|
||||
}
|
||||
|
||||
// UploadMaxMemory sets the maximum number of bytes used to parse a request body
|
||||
// as multipart/form-data in memory, with the remainder stored on disk in
|
||||
// temporary files.
|
||||
func UploadMaxMemory(size int64) Option {
|
||||
return func(cfg *Config) {
|
||||
cfg.uploadMaxMemory = size
|
||||
}
|
||||
}
|
||||
|
||||
// WebsocketKeepAliveDuration allows you to reconfigure the keepalive behavior.
|
||||
// By default, keepalive is enabled with a DefaultConnectionKeepAlivePingInterval
|
||||
// duration. Set handler.connectionKeepAlivePingInterval = 0 to disable keepalive
|
||||
// altogether.
|
||||
func WebsocketKeepAliveDuration(duration time.Duration) Option {
|
||||
return func(cfg *Config) {
|
||||
cfg.connectionKeepAlivePingInterval = duration
|
||||
}
|
||||
}
|
||||
|
||||
// Add cache that will hold queries for automatic persisted queries (APQ)
|
||||
func EnablePersistedQueryCache(cache PersistedQueryCache) Option {
|
||||
return func(cfg *Config) {
|
||||
cfg.apqCache = cache
|
||||
}
|
||||
}
|
||||
|
||||
const DefaultCacheSize = 1000
|
||||
const DefaultConnectionKeepAlivePingInterval = 25 * time.Second
|
||||
|
||||
// DefaultUploadMaxMemory is the maximum number of bytes used to parse a request body
|
||||
// as multipart/form-data in memory, with the remainder stored on disk in
|
||||
// temporary files.
|
||||
const DefaultUploadMaxMemory = 32 << 20
|
||||
|
||||
// DefaultUploadMaxSize is maximum number of bytes used to parse a request body
|
||||
// as multipart/form-data.
|
||||
const DefaultUploadMaxSize = 32 << 20
|
||||
|
||||
func GraphQL(exec graphql.ExecutableSchema, options ...Option) http.HandlerFunc {
|
||||
cfg := &Config{
|
||||
cacheSize: DefaultCacheSize,
|
||||
uploadMaxMemory: DefaultUploadMaxMemory,
|
||||
uploadMaxSize: DefaultUploadMaxSize,
|
||||
connectionKeepAlivePingInterval: DefaultConnectionKeepAlivePingInterval,
|
||||
upgrader: websocket.Upgrader{
|
||||
ReadBufferSize: 1024,
|
||||
WriteBufferSize: 1024,
|
||||
},
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
option(cfg)
|
||||
}
|
||||
|
||||
var cache *lru.Cache
|
||||
if cfg.cacheSize > 0 {
|
||||
var err error
|
||||
cache, err = lru.New(cfg.cacheSize)
|
||||
if err != nil {
|
||||
// An error is only returned for non-positive cache size
|
||||
// and we already checked for that.
|
||||
panic("unexpected error creating cache: " + err.Error())
|
||||
}
|
||||
}
|
||||
if cfg.tracer == nil {
|
||||
cfg.tracer = &graphql.NopTracer{}
|
||||
}
|
||||
|
||||
handler := &graphqlHandler{
|
||||
cfg: cfg,
|
||||
cache: cache,
|
||||
exec: exec,
|
||||
}
|
||||
|
||||
return handler.ServeHTTP
|
||||
}
|
||||
|
||||
var _ http.Handler = (*graphqlHandler)(nil)
|
||||
|
||||
type graphqlHandler struct {
|
||||
cfg *Config
|
||||
cache *lru.Cache
|
||||
exec graphql.ExecutableSchema
|
||||
}
|
||||
|
||||
func computeQueryHash(query string) string {
|
||||
b := sha256.Sum256([]byte(query))
|
||||
return hex.EncodeToString(b[:])
|
||||
}
|
||||
|
||||
func (gh *graphqlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == http.MethodOptions {
|
||||
w.Header().Set("Allow", "OPTIONS, GET, POST")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
return
|
||||
}
|
||||
|
||||
if strings.Contains(r.Header.Get("Upgrade"), "websocket") {
|
||||
connectWs(gh.exec, w, r, gh.cfg, gh.cache)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
var reqParams params
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
reqParams.Query = r.URL.Query().Get("query")
|
||||
reqParams.OperationName = r.URL.Query().Get("operationName")
|
||||
|
||||
if variables := r.URL.Query().Get("variables"); variables != "" {
|
||||
if err := jsonDecode(strings.NewReader(variables), &reqParams.Variables); err != nil {
|
||||
sendErrorf(w, http.StatusBadRequest, "variables could not be decoded")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if extensions := r.URL.Query().Get("extensions"); extensions != "" {
|
||||
if err := jsonDecode(strings.NewReader(extensions), &reqParams.Extensions); err != nil {
|
||||
sendErrorf(w, http.StatusBadRequest, "extensions could not be decoded")
|
||||
return
|
||||
}
|
||||
}
|
||||
case http.MethodPost:
|
||||
mediaType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
sendErrorf(w, http.StatusBadRequest, "error parsing request Content-Type")
|
||||
return
|
||||
}
|
||||
|
||||
switch mediaType {
|
||||
case "application/json":
|
||||
if err := jsonDecode(r.Body, &reqParams); err != nil {
|
||||
sendErrorf(w, http.StatusBadRequest, "json body could not be decoded: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
case "multipart/form-data":
|
||||
var closers []io.Closer
|
||||
var tmpFiles []string
|
||||
defer func() {
|
||||
for i := len(closers) - 1; 0 <= i; i-- {
|
||||
_ = closers[i].Close()
|
||||
}
|
||||
for _, tmpFile := range tmpFiles {
|
||||
_ = os.Remove(tmpFile)
|
||||
}
|
||||
}()
|
||||
if err := processMultipart(w, r, &reqParams, &closers, &tmpFiles, gh.cfg.uploadMaxSize, gh.cfg.uploadMaxMemory); err != nil {
|
||||
sendErrorf(w, http.StatusBadRequest, "multipart body could not be decoded: "+err.Error())
|
||||
return
|
||||
}
|
||||
default:
|
||||
sendErrorf(w, http.StatusBadRequest, "unsupported Content-Type: "+mediaType)
|
||||
return
|
||||
}
|
||||
default:
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
ctx := r.Context()
|
||||
|
||||
var queryHash string
|
||||
apqRegister := false
|
||||
apq := reqParams.Extensions != nil && reqParams.Extensions.PersistedQuery != nil
|
||||
if apq {
|
||||
// client has enabled apq
|
||||
queryHash = reqParams.Extensions.PersistedQuery.Sha256
|
||||
if gh.cfg.apqCache == nil {
|
||||
// server has disabled apq
|
||||
sendErrorf(w, http.StatusOK, errPersistedQueryNotSupported)
|
||||
return
|
||||
}
|
||||
if reqParams.Extensions.PersistedQuery.Version != 1 {
|
||||
sendErrorf(w, http.StatusOK, "Unsupported persisted query version")
|
||||
return
|
||||
}
|
||||
if reqParams.Query == "" {
|
||||
// client sent optimistic query hash without query string
|
||||
query, ok := gh.cfg.apqCache.Get(ctx, queryHash)
|
||||
if !ok {
|
||||
sendErrorf(w, http.StatusOK, errPersistedQueryNotFound)
|
||||
return
|
||||
}
|
||||
reqParams.Query = query
|
||||
} else {
|
||||
if computeQueryHash(reqParams.Query) != queryHash {
|
||||
sendErrorf(w, http.StatusOK, "provided sha does not match query")
|
||||
return
|
||||
}
|
||||
apqRegister = true
|
||||
}
|
||||
} else if reqParams.Query == "" {
|
||||
sendErrorf(w, http.StatusUnprocessableEntity, "Must provide query string")
|
||||
return
|
||||
}
|
||||
|
||||
var doc *ast.QueryDocument
|
||||
var cacheHit bool
|
||||
if gh.cache != nil {
|
||||
val, ok := gh.cache.Get(reqParams.Query)
|
||||
if ok {
|
||||
doc = val.(*ast.QueryDocument)
|
||||
cacheHit = true
|
||||
}
|
||||
}
|
||||
|
||||
ctx, doc, gqlErr := gh.parseOperation(ctx, &parseOperationArgs{
|
||||
Query: reqParams.Query,
|
||||
CachedDoc: doc,
|
||||
})
|
||||
if gqlErr != nil {
|
||||
sendError(w, http.StatusUnprocessableEntity, gqlErr)
|
||||
return
|
||||
}
|
||||
|
||||
ctx, op, vars, listErr := gh.validateOperation(ctx, &validateOperationArgs{
|
||||
Doc: doc,
|
||||
OperationName: reqParams.OperationName,
|
||||
CacheHit: cacheHit,
|
||||
R: r,
|
||||
Variables: reqParams.Variables,
|
||||
})
|
||||
if len(listErr) != 0 {
|
||||
sendError(w, http.StatusUnprocessableEntity, listErr...)
|
||||
return
|
||||
}
|
||||
|
||||
if gh.cache != nil && !cacheHit {
|
||||
gh.cache.Add(reqParams.Query, doc)
|
||||
}
|
||||
|
||||
reqCtx := gh.cfg.newRequestContext(gh.exec, doc, op, reqParams.Query, vars)
|
||||
ctx = graphql.WithRequestContext(ctx, reqCtx)
|
||||
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
userErr := reqCtx.Recover(ctx, err)
|
||||
sendErrorf(w, http.StatusUnprocessableEntity, userErr.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
if gh.cfg.complexityLimitFunc != nil {
|
||||
reqCtx.ComplexityLimit = gh.cfg.complexityLimitFunc(ctx)
|
||||
}
|
||||
|
||||
if reqCtx.ComplexityLimit > 0 && reqCtx.OperationComplexity > reqCtx.ComplexityLimit {
|
||||
sendErrorf(w, http.StatusUnprocessableEntity, "operation has complexity %d, which exceeds the limit of %d", reqCtx.OperationComplexity, reqCtx.ComplexityLimit)
|
||||
return
|
||||
}
|
||||
|
||||
if apqRegister && gh.cfg.apqCache != nil {
|
||||
// Add to persisted query cache
|
||||
gh.cfg.apqCache.Add(ctx, queryHash, reqParams.Query)
|
||||
}
|
||||
|
||||
switch op.Operation {
|
||||
case ast.Query:
|
||||
b, err := json.Marshal(gh.exec.Query(ctx, op))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Write(b)
|
||||
case ast.Mutation:
|
||||
b, err := json.Marshal(gh.exec.Mutation(ctx, op))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Write(b)
|
||||
default:
|
||||
sendErrorf(w, http.StatusBadRequest, "unsupported operation type")
|
||||
}
|
||||
}
|
||||
|
||||
type parseOperationArgs struct {
|
||||
Query string
|
||||
CachedDoc *ast.QueryDocument
|
||||
}
|
||||
|
||||
func (gh *graphqlHandler) parseOperation(ctx context.Context, args *parseOperationArgs) (context.Context, *ast.QueryDocument, *gqlerror.Error) {
|
||||
ctx = gh.cfg.tracer.StartOperationParsing(ctx)
|
||||
defer func() { gh.cfg.tracer.EndOperationParsing(ctx) }()
|
||||
|
||||
if args.CachedDoc != nil {
|
||||
return ctx, args.CachedDoc, nil
|
||||
}
|
||||
|
||||
doc, gqlErr := parser.ParseQuery(&ast.Source{Input: args.Query})
|
||||
if gqlErr != nil {
|
||||
return ctx, nil, gqlErr
|
||||
}
|
||||
|
||||
return ctx, doc, nil
|
||||
}
|
||||
|
||||
type validateOperationArgs struct {
|
||||
Doc *ast.QueryDocument
|
||||
OperationName string
|
||||
CacheHit bool
|
||||
R *http.Request
|
||||
Variables map[string]interface{}
|
||||
}
|
||||
|
||||
func (gh *graphqlHandler) validateOperation(ctx context.Context, args *validateOperationArgs) (context.Context, *ast.OperationDefinition, map[string]interface{}, gqlerror.List) {
|
||||
ctx = gh.cfg.tracer.StartOperationValidation(ctx)
|
||||
defer func() { gh.cfg.tracer.EndOperationValidation(ctx) }()
|
||||
|
||||
if !args.CacheHit {
|
||||
listErr := validator.Validate(gh.exec.Schema(), args.Doc)
|
||||
if len(listErr) != 0 {
|
||||
return ctx, nil, nil, listErr
|
||||
}
|
||||
}
|
||||
|
||||
op := args.Doc.Operations.ForName(args.OperationName)
|
||||
if op == nil {
|
||||
return ctx, nil, nil, gqlerror.List{gqlerror.Errorf("operation %s not found", args.OperationName)}
|
||||
}
|
||||
|
||||
if op.Operation != ast.Query && args.R.Method == http.MethodGet {
|
||||
return ctx, nil, nil, gqlerror.List{gqlerror.Errorf("GET requests only allow query operations")}
|
||||
}
|
||||
|
||||
vars, err := validator.VariableValues(gh.exec.Schema(), op, args.Variables)
|
||||
if err != nil {
|
||||
return ctx, nil, nil, gqlerror.List{err}
|
||||
}
|
||||
|
||||
return ctx, op, vars, nil
|
||||
}
|
||||
|
||||
func jsonDecode(r io.Reader, val interface{}) error {
|
||||
dec := json.NewDecoder(r)
|
||||
dec.UseNumber()
|
||||
return dec.Decode(val)
|
||||
}
|
||||
|
||||
func sendError(w http.ResponseWriter, code int, errors ...*gqlerror.Error) {
|
||||
w.WriteHeader(code)
|
||||
b, err := json.Marshal(&graphql.Response{Errors: errors})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Write(b)
|
||||
}
|
||||
|
||||
func sendErrorf(w http.ResponseWriter, code int, format string, args ...interface{}) {
|
||||
sendError(w, code, &gqlerror.Error{Message: fmt.Sprintf(format, args...)})
|
||||
}
|
||||
|
||||
type bytesReader struct {
|
||||
s *[]byte
|
||||
i int64 // current reading index
|
||||
prevRune int // index of previous rune; or < 0
|
||||
}
|
||||
|
||||
func (r *bytesReader) Read(b []byte) (n int, err error) {
|
||||
if r.s == nil {
|
||||
return 0, errors.New("byte slice pointer is nil")
|
||||
}
|
||||
if r.i >= int64(len(*r.s)) {
|
||||
return 0, io.EOF
|
||||
}
|
||||
r.prevRune = -1
|
||||
n = copy(b, (*r.s)[r.i:])
|
||||
r.i += int64(n)
|
||||
return
|
||||
}
|
||||
|
||||
func processMultipart(w http.ResponseWriter, r *http.Request, request *params, closers *[]io.Closer, tmpFiles *[]string, uploadMaxSize, uploadMaxMemory int64) error {
|
||||
var err error
|
||||
if r.ContentLength > uploadMaxSize {
|
||||
return errors.New("failed to parse multipart form, request body too large")
|
||||
}
|
||||
r.Body = http.MaxBytesReader(w, r.Body, uploadMaxSize)
|
||||
if err = r.ParseMultipartForm(uploadMaxMemory); err != nil {
|
||||
if strings.Contains(err.Error(), "request body too large") {
|
||||
return errors.New("failed to parse multipart form, request body too large")
|
||||
}
|
||||
return errors.New("failed to parse multipart form")
|
||||
}
|
||||
*closers = append(*closers, r.Body)
|
||||
|
||||
if err = jsonDecode(strings.NewReader(r.Form.Get("operations")), &request); err != nil {
|
||||
return errors.New("operations form field could not be decoded")
|
||||
}
|
||||
|
||||
var uploadsMap = map[string][]string{}
|
||||
if err = json.Unmarshal([]byte(r.Form.Get("map")), &uploadsMap); err != nil {
|
||||
return errors.New("map form field could not be decoded")
|
||||
}
|
||||
|
||||
var upload graphql.Upload
|
||||
for key, paths := range uploadsMap {
|
||||
if len(paths) == 0 {
|
||||
return fmt.Errorf("invalid empty operations paths list for key %s", key)
|
||||
}
|
||||
file, header, err := r.FormFile(key)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get key %s from form", key)
|
||||
}
|
||||
*closers = append(*closers, file)
|
||||
|
||||
if len(paths) == 1 {
|
||||
upload = graphql.Upload{
|
||||
File: file,
|
||||
Size: header.Size,
|
||||
Filename: header.Filename,
|
||||
}
|
||||
err = addUploadToOperations(request, upload, key, paths[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if r.ContentLength < uploadMaxMemory {
|
||||
fileBytes, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read file for key %s", key)
|
||||
}
|
||||
for _, path := range paths {
|
||||
upload = graphql.Upload{
|
||||
File: &bytesReader{s: &fileBytes, i: 0, prevRune: -1},
|
||||
Size: header.Size,
|
||||
Filename: header.Filename,
|
||||
}
|
||||
err = addUploadToOperations(request, upload, key, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tmpFile, err := ioutil.TempFile(os.TempDir(), "gqlgen-")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create temp file for key %s", key)
|
||||
}
|
||||
tmpName := tmpFile.Name()
|
||||
*tmpFiles = append(*tmpFiles, tmpName)
|
||||
_, err = io.Copy(tmpFile, file)
|
||||
if err != nil {
|
||||
if err := tmpFile.Close(); err != nil {
|
||||
return fmt.Errorf("failed to copy to temp file and close temp file for key %s", key)
|
||||
}
|
||||
return fmt.Errorf("failed to copy to temp file for key %s", key)
|
||||
}
|
||||
if err := tmpFile.Close(); err != nil {
|
||||
return fmt.Errorf("failed to close temp file for key %s", key)
|
||||
}
|
||||
for _, path := range paths {
|
||||
pathTmpFile, err := os.Open(tmpName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open temp file for key %s", key)
|
||||
}
|
||||
*closers = append(*closers, pathTmpFile)
|
||||
upload = graphql.Upload{
|
||||
File: pathTmpFile,
|
||||
Size: header.Size,
|
||||
Filename: header.Filename,
|
||||
}
|
||||
err = addUploadToOperations(request, upload, key, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func addUploadToOperations(request *params, upload graphql.Upload, key, path string) error {
|
||||
if !strings.HasPrefix(path, "variables.") {
|
||||
return fmt.Errorf("invalid operations paths for key %s", key)
|
||||
}
|
||||
|
||||
var ptr interface{} = request.Variables
|
||||
parts := strings.Split(path, ".")
|
||||
|
||||
// skip the first part (variables) because we started there
|
||||
for i, p := range parts[1:] {
|
||||
last := i == len(parts)-2
|
||||
if ptr == nil {
|
||||
return fmt.Errorf("path is missing \"variables.\" prefix, key: %s, path: %s", key, path)
|
||||
}
|
||||
if index, parseNbrErr := strconv.Atoi(p); parseNbrErr == nil {
|
||||
if last {
|
||||
ptr.([]interface{})[index] = upload
|
||||
} else {
|
||||
ptr = ptr.([]interface{})[index]
|
||||
}
|
||||
} else {
|
||||
if last {
|
||||
ptr.(map[string]interface{})[p] = upload
|
||||
} else {
|
||||
ptr = ptr.(map[string]interface{})[p]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
57
vendor/github.com/99designs/gqlgen/handler/mock.go
generated
vendored
57
vendor/github.com/99designs/gqlgen/handler/mock.go
generated
vendored
@ -1,57 +0,0 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
"github.com/vektah/gqlparser"
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
)
|
||||
|
||||
type executableSchemaMock struct {
|
||||
MutationFunc func(ctx context.Context, op *ast.OperationDefinition) *graphql.Response
|
||||
}
|
||||
|
||||
var _ graphql.ExecutableSchema = &executableSchemaMock{}
|
||||
|
||||
func (e *executableSchemaMock) Schema() *ast.Schema {
|
||||
return gqlparser.MustLoadSchema(&ast.Source{Input: `
|
||||
schema { query: Query, mutation: Mutation }
|
||||
type Query {
|
||||
empty: String!
|
||||
}
|
||||
scalar Upload
|
||||
type File {
|
||||
id: Int!
|
||||
}
|
||||
input UploadFile {
|
||||
id: Int!
|
||||
file: Upload!
|
||||
}
|
||||
type Mutation {
|
||||
singleUpload(file: Upload!): File!
|
||||
singleUploadWithPayload(req: UploadFile!): File!
|
||||
multipleUpload(files: [Upload!]!): [File!]!
|
||||
multipleUploadWithPayload(req: [UploadFile!]!): [File!]!
|
||||
}
|
||||
`})
|
||||
}
|
||||
|
||||
func (e *executableSchemaMock) Complexity(typeName, field string, childComplexity int, args map[string]interface{}) (int, bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func (e *executableSchemaMock) Query(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {
|
||||
return graphql.ErrorResponse(ctx, "queries are not supported")
|
||||
}
|
||||
|
||||
func (e *executableSchemaMock) Mutation(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {
|
||||
return e.MutationFunc(ctx, op)
|
||||
}
|
||||
|
||||
func (e *executableSchemaMock) Subscription(ctx context.Context, op *ast.OperationDefinition) func() *graphql.Response {
|
||||
return func() *graphql.Response {
|
||||
<-ctx.Done()
|
||||
return nil
|
||||
}
|
||||
}
|
61
vendor/github.com/99designs/gqlgen/handler/playground.go
generated
vendored
61
vendor/github.com/99designs/gqlgen/handler/playground.go
generated
vendored
@ -1,61 +0,0 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=utf-8/>
|
||||
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
|
||||
<link rel="shortcut icon" href="https://graphcool-playground.netlify.com/favicon.png">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/graphql-playground-react@{{ .version }}/build/static/css/index.css"
|
||||
integrity="{{ .cssSRI }}" crossorigin="anonymous"/>
|
||||
<link rel="shortcut icon" href="https://cdn.jsdelivr.net/npm/graphql-playground-react@{{ .version }}/build/favicon.png"
|
||||
integrity="{{ .faviconSRI }}" crossorigin="anonymous"/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/graphql-playground-react@{{ .version }}/build/static/js/middleware.js"
|
||||
integrity="{{ .jsSRI }}" crossorigin="anonymous"></script>
|
||||
<title>{{.title}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<style type="text/css">
|
||||
html { font-family: "Open Sans", sans-serif; overflow: hidden; }
|
||||
body { margin: 0; background: #172a3a; }
|
||||
</style>
|
||||
<div id="root"/>
|
||||
<script type="text/javascript">
|
||||
window.addEventListener('load', function (event) {
|
||||
const root = document.getElementById('root');
|
||||
root.classList.add('playgroundIn');
|
||||
const wsProto = location.protocol == 'https:' ? 'wss:' : 'ws:'
|
||||
GraphQLPlayground.init(root, {
|
||||
endpoint: location.protocol + '//' + location.host + '{{.endpoint}}',
|
||||
subscriptionsEndpoint: wsProto + '//' + location.host + '{{.endpoint }}',
|
||||
settings: {
|
||||
'request.credentials': 'same-origin'
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`))
|
||||
|
||||
func Playground(title string, endpoint string) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Add("Content-Type", "text/html")
|
||||
err := page.Execute(w, map[string]string{
|
||||
"title": title,
|
||||
"endpoint": endpoint,
|
||||
"version": "1.7.20",
|
||||
"cssSRI": "sha256-cS9Vc2OBt9eUf4sykRWukeFYaInL29+myBmFDSa7F/U=",
|
||||
"faviconSRI": "sha256-GhTyE+McTU79R4+pRO6ih+4TfsTOrpPwD8ReKFzb3PM=",
|
||||
"jsSRI": "sha256-4QG1Uza2GgGdlBL3RCBCGtGeZB6bDbsw8OltCMGeJsA=",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
51
vendor/github.com/99designs/gqlgen/handler/stub.go
generated
vendored
51
vendor/github.com/99designs/gqlgen/handler/stub.go
generated
vendored
@ -1,51 +0,0 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
"github.com/vektah/gqlparser"
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
)
|
||||
|
||||
type executableSchemaStub struct {
|
||||
NextResp chan struct{}
|
||||
}
|
||||
|
||||
var _ graphql.ExecutableSchema = &executableSchemaStub{}
|
||||
|
||||
func (e *executableSchemaStub) Schema() *ast.Schema {
|
||||
return gqlparser.MustLoadSchema(&ast.Source{Input: `
|
||||
schema { query: Query }
|
||||
type Query {
|
||||
me: User!
|
||||
user(id: Int): User!
|
||||
}
|
||||
type User { name: String! }
|
||||
`})
|
||||
}
|
||||
|
||||
func (e *executableSchemaStub) Complexity(typeName, field string, childComplexity int, args map[string]interface{}) (int, bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func (e *executableSchemaStub) Query(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {
|
||||
return &graphql.Response{Data: []byte(`{"name":"test"}`)}
|
||||
}
|
||||
|
||||
func (e *executableSchemaStub) Mutation(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {
|
||||
return graphql.ErrorResponse(ctx, "mutations are not supported")
|
||||
}
|
||||
|
||||
func (e *executableSchemaStub) Subscription(ctx context.Context, op *ast.OperationDefinition) func() *graphql.Response {
|
||||
return func() *graphql.Response {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
case <-e.NextResp:
|
||||
return &graphql.Response{
|
||||
Data: []byte(`{"name":"test"}`),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
323
vendor/github.com/99designs/gqlgen/handler/websocket.go
generated
vendored
323
vendor/github.com/99designs/gqlgen/handler/websocket.go
generated
vendored
@ -1,323 +0,0 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
"github.com/gorilla/websocket"
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
"github.com/vektah/gqlparser"
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
"github.com/vektah/gqlparser/gqlerror"
|
||||
"github.com/vektah/gqlparser/validator"
|
||||
)
|
||||
|
||||
const (
|
||||
connectionInitMsg = "connection_init" // Client -> Server
|
||||
connectionTerminateMsg = "connection_terminate" // Client -> Server
|
||||
startMsg = "start" // Client -> Server
|
||||
stopMsg = "stop" // Client -> Server
|
||||
connectionAckMsg = "connection_ack" // Server -> Client
|
||||
connectionErrorMsg = "connection_error" // Server -> Client
|
||||
dataMsg = "data" // Server -> Client
|
||||
errorMsg = "error" // Server -> Client
|
||||
completeMsg = "complete" // Server -> Client
|
||||
connectionKeepAliveMsg = "ka" // Server -> Client
|
||||
)
|
||||
|
||||
type operationMessage struct {
|
||||
Payload json.RawMessage `json:"payload,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type wsConnection struct {
|
||||
ctx context.Context
|
||||
conn *websocket.Conn
|
||||
exec graphql.ExecutableSchema
|
||||
active map[string]context.CancelFunc
|
||||
mu sync.Mutex
|
||||
cfg *Config
|
||||
cache *lru.Cache
|
||||
keepAliveTicker *time.Ticker
|
||||
|
||||
initPayload InitPayload
|
||||
}
|
||||
|
||||
func connectWs(exec graphql.ExecutableSchema, w http.ResponseWriter, r *http.Request, cfg *Config, cache *lru.Cache) {
|
||||
ws, err := cfg.upgrader.Upgrade(w, r, http.Header{
|
||||
"Sec-Websocket-Protocol": []string{"graphql-ws"},
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("unable to upgrade %T to websocket %s: ", w, err.Error())
|
||||
sendErrorf(w, http.StatusBadRequest, "unable to upgrade")
|
||||
return
|
||||
}
|
||||
|
||||
conn := wsConnection{
|
||||
active: map[string]context.CancelFunc{},
|
||||
exec: exec,
|
||||
conn: ws,
|
||||
ctx: r.Context(),
|
||||
cfg: cfg,
|
||||
cache: cache,
|
||||
}
|
||||
|
||||
if !conn.init() {
|
||||
return
|
||||
}
|
||||
|
||||
conn.run()
|
||||
}
|
||||
|
||||
func (c *wsConnection) init() bool {
|
||||
message := c.readOp()
|
||||
if message == nil {
|
||||
c.close(websocket.CloseProtocolError, "decoding error")
|
||||
return false
|
||||
}
|
||||
|
||||
switch message.Type {
|
||||
case connectionInitMsg:
|
||||
if len(message.Payload) > 0 {
|
||||
c.initPayload = make(InitPayload)
|
||||
err := json.Unmarshal(message.Payload, &c.initPayload)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if c.cfg.websocketInitFunc != nil {
|
||||
if err := c.cfg.websocketInitFunc(c.ctx, c.initPayload); err != nil {
|
||||
c.sendConnectionError(err.Error())
|
||||
c.close(websocket.CloseNormalClosure, "terminated")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
c.write(&operationMessage{Type: connectionAckMsg})
|
||||
c.write(&operationMessage{Type: connectionKeepAliveMsg})
|
||||
case connectionTerminateMsg:
|
||||
c.close(websocket.CloseNormalClosure, "terminated")
|
||||
return false
|
||||
default:
|
||||
c.sendConnectionError("unexpected message %s", message.Type)
|
||||
c.close(websocket.CloseProtocolError, "unexpected message")
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *wsConnection) write(msg *operationMessage) {
|
||||
c.mu.Lock()
|
||||
c.conn.WriteJSON(msg)
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
func (c *wsConnection) run() {
|
||||
// We create a cancellation that will shutdown the keep-alive when we leave
|
||||
// this function.
|
||||
ctx, cancel := context.WithCancel(c.ctx)
|
||||
defer cancel()
|
||||
|
||||
// Create a timer that will fire every interval to keep the connection alive.
|
||||
if c.cfg.connectionKeepAlivePingInterval != 0 {
|
||||
c.mu.Lock()
|
||||
c.keepAliveTicker = time.NewTicker(c.cfg.connectionKeepAlivePingInterval)
|
||||
c.mu.Unlock()
|
||||
|
||||
go c.keepAlive(ctx)
|
||||
}
|
||||
|
||||
for {
|
||||
message := c.readOp()
|
||||
if message == nil {
|
||||
return
|
||||
}
|
||||
|
||||
switch message.Type {
|
||||
case startMsg:
|
||||
if !c.subscribe(message) {
|
||||
return
|
||||
}
|
||||
case stopMsg:
|
||||
c.mu.Lock()
|
||||
closer := c.active[message.ID]
|
||||
c.mu.Unlock()
|
||||
if closer == nil {
|
||||
c.sendError(message.ID, gqlerror.Errorf("%s is not running, cannot stop", message.ID))
|
||||
continue
|
||||
}
|
||||
|
||||
closer()
|
||||
case connectionTerminateMsg:
|
||||
c.close(websocket.CloseNormalClosure, "terminated")
|
||||
return
|
||||
default:
|
||||
c.sendConnectionError("unexpected message %s", message.Type)
|
||||
c.close(websocket.CloseProtocolError, "unexpected message")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *wsConnection) keepAlive(ctx context.Context) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
c.keepAliveTicker.Stop()
|
||||
return
|
||||
case <-c.keepAliveTicker.C:
|
||||
c.write(&operationMessage{Type: connectionKeepAliveMsg})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *wsConnection) subscribe(message *operationMessage) bool {
|
||||
var reqParams params
|
||||
if err := jsonDecode(bytes.NewReader(message.Payload), &reqParams); err != nil {
|
||||
c.sendConnectionError("invalid json")
|
||||
return false
|
||||
}
|
||||
|
||||
var (
|
||||
doc *ast.QueryDocument
|
||||
cacheHit bool
|
||||
)
|
||||
if c.cache != nil {
|
||||
val, ok := c.cache.Get(reqParams.Query)
|
||||
if ok {
|
||||
doc = val.(*ast.QueryDocument)
|
||||
cacheHit = true
|
||||
}
|
||||
}
|
||||
if !cacheHit {
|
||||
var qErr gqlerror.List
|
||||
doc, qErr = gqlparser.LoadQuery(c.exec.Schema(), reqParams.Query)
|
||||
if qErr != nil {
|
||||
c.sendError(message.ID, qErr...)
|
||||
return true
|
||||
}
|
||||
if c.cache != nil {
|
||||
c.cache.Add(reqParams.Query, doc)
|
||||
}
|
||||
}
|
||||
|
||||
op := doc.Operations.ForName(reqParams.OperationName)
|
||||
if op == nil {
|
||||
c.sendError(message.ID, gqlerror.Errorf("operation %s not found", reqParams.OperationName))
|
||||
return true
|
||||
}
|
||||
|
||||
vars, err := validator.VariableValues(c.exec.Schema(), op, reqParams.Variables)
|
||||
if err != nil {
|
||||
c.sendError(message.ID, err)
|
||||
return true
|
||||
}
|
||||
reqCtx := c.cfg.newRequestContext(c.exec, doc, op, reqParams.Query, vars)
|
||||
ctx := graphql.WithRequestContext(c.ctx, reqCtx)
|
||||
|
||||
if c.initPayload != nil {
|
||||
ctx = withInitPayload(ctx, c.initPayload)
|
||||
}
|
||||
|
||||
if op.Operation != ast.Subscription {
|
||||
var result *graphql.Response
|
||||
if op.Operation == ast.Query {
|
||||
result = c.exec.Query(ctx, op)
|
||||
} else {
|
||||
result = c.exec.Mutation(ctx, op)
|
||||
}
|
||||
|
||||
c.sendData(message.ID, result)
|
||||
c.write(&operationMessage{ID: message.ID, Type: completeMsg})
|
||||
return true
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
c.mu.Lock()
|
||||
c.active[message.ID] = cancel
|
||||
c.mu.Unlock()
|
||||
go func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
userErr := reqCtx.Recover(ctx, r)
|
||||
c.sendError(message.ID, &gqlerror.Error{Message: userErr.Error()})
|
||||
}
|
||||
}()
|
||||
next := c.exec.Subscription(ctx, op)
|
||||
for result := next(); result != nil; result = next() {
|
||||
c.sendData(message.ID, result)
|
||||
}
|
||||
|
||||
c.write(&operationMessage{ID: message.ID, Type: completeMsg})
|
||||
|
||||
c.mu.Lock()
|
||||
delete(c.active, message.ID)
|
||||
c.mu.Unlock()
|
||||
cancel()
|
||||
}()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *wsConnection) sendData(id string, response *graphql.Response) {
|
||||
b, err := json.Marshal(response)
|
||||
if err != nil {
|
||||
c.sendError(id, gqlerror.Errorf("unable to encode json response: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.write(&operationMessage{Type: dataMsg, ID: id, Payload: b})
|
||||
}
|
||||
|
||||
func (c *wsConnection) sendError(id string, errors ...*gqlerror.Error) {
|
||||
errs := make([]error, len(errors))
|
||||
for i, err := range errors {
|
||||
errs[i] = err
|
||||
}
|
||||
b, err := json.Marshal(errs)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
c.write(&operationMessage{Type: errorMsg, ID: id, Payload: b})
|
||||
}
|
||||
|
||||
func (c *wsConnection) sendConnectionError(format string, args ...interface{}) {
|
||||
b, err := json.Marshal(&gqlerror.Error{Message: fmt.Sprintf(format, args...)})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
c.write(&operationMessage{Type: connectionErrorMsg, Payload: b})
|
||||
}
|
||||
|
||||
func (c *wsConnection) readOp() *operationMessage {
|
||||
_, r, err := c.conn.NextReader()
|
||||
if err != nil {
|
||||
c.sendConnectionError("invalid json")
|
||||
return nil
|
||||
}
|
||||
message := operationMessage{}
|
||||
if err := jsonDecode(r, &message); err != nil {
|
||||
c.sendConnectionError("invalid json")
|
||||
return nil
|
||||
}
|
||||
|
||||
return &message
|
||||
}
|
||||
|
||||
func (c *wsConnection) close(closeCode int, message string) {
|
||||
c.mu.Lock()
|
||||
_ = c.conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(closeCode, message))
|
||||
c.mu.Unlock()
|
||||
_ = c.conn.Close()
|
||||
}
|
163
vendor/github.com/99designs/gqlgen/internal/code/compare.go
generated
vendored
163
vendor/github.com/99designs/gqlgen/internal/code/compare.go
generated
vendored
@ -1,163 +0,0 @@
|
||||
package code
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/types"
|
||||
)
|
||||
|
||||
// CompatibleTypes isnt a strict comparison, it allows for pointer differences
|
||||
func CompatibleTypes(expected types.Type, actual types.Type) error {
|
||||
//fmt.Println("Comparing ", expected.String(), actual.String())
|
||||
|
||||
// Special case to deal with pointer mismatches
|
||||
{
|
||||
expectedPtr, expectedIsPtr := expected.(*types.Pointer)
|
||||
actualPtr, actualIsPtr := actual.(*types.Pointer)
|
||||
|
||||
if expectedIsPtr && actualIsPtr {
|
||||
return CompatibleTypes(expectedPtr.Elem(), actualPtr.Elem())
|
||||
}
|
||||
if expectedIsPtr && !actualIsPtr {
|
||||
return CompatibleTypes(expectedPtr.Elem(), actual)
|
||||
}
|
||||
if !expectedIsPtr && actualIsPtr {
|
||||
return CompatibleTypes(expected, actualPtr.Elem())
|
||||
}
|
||||
}
|
||||
|
||||
switch expected := expected.(type) {
|
||||
case *types.Slice:
|
||||
if actual, ok := actual.(*types.Slice); ok {
|
||||
return CompatibleTypes(expected.Elem(), actual.Elem())
|
||||
}
|
||||
|
||||
case *types.Array:
|
||||
if actual, ok := actual.(*types.Array); ok {
|
||||
if expected.Len() != actual.Len() {
|
||||
return fmt.Errorf("array length differs")
|
||||
}
|
||||
|
||||
return CompatibleTypes(expected.Elem(), actual.Elem())
|
||||
}
|
||||
|
||||
case *types.Basic:
|
||||
if actual, ok := actual.(*types.Basic); ok {
|
||||
if actual.Kind() != expected.Kind() {
|
||||
return fmt.Errorf("basic kind differs, %s != %s", expected.Name(), actual.Name())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
case *types.Struct:
|
||||
if actual, ok := actual.(*types.Struct); ok {
|
||||
if expected.NumFields() != actual.NumFields() {
|
||||
return fmt.Errorf("number of struct fields differ")
|
||||
}
|
||||
|
||||
for i := 0; i < expected.NumFields(); i++ {
|
||||
if expected.Field(i).Name() != actual.Field(i).Name() {
|
||||
return fmt.Errorf("struct field %d name differs, %s != %s", i, expected.Field(i).Name(), actual.Field(i).Name())
|
||||
}
|
||||
if err := CompatibleTypes(expected.Field(i).Type(), actual.Field(i).Type()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
case *types.Tuple:
|
||||
if actual, ok := actual.(*types.Tuple); ok {
|
||||
if expected.Len() != actual.Len() {
|
||||
return fmt.Errorf("tuple length differs, %d != %d", expected.Len(), actual.Len())
|
||||
}
|
||||
|
||||
for i := 0; i < expected.Len(); i++ {
|
||||
if err := CompatibleTypes(expected.At(i).Type(), actual.At(i).Type()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
case *types.Signature:
|
||||
if actual, ok := actual.(*types.Signature); ok {
|
||||
if err := CompatibleTypes(expected.Params(), actual.Params()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := CompatibleTypes(expected.Results(), actual.Results()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
case *types.Interface:
|
||||
if actual, ok := actual.(*types.Interface); ok {
|
||||
if expected.NumMethods() != actual.NumMethods() {
|
||||
return fmt.Errorf("interface method count differs, %d != %d", expected.NumMethods(), actual.NumMethods())
|
||||
}
|
||||
|
||||
for i := 0; i < expected.NumMethods(); i++ {
|
||||
if expected.Method(i).Name() != actual.Method(i).Name() {
|
||||
return fmt.Errorf("interface method %d name differs, %s != %s", i, expected.Method(i).Name(), actual.Method(i).Name())
|
||||
}
|
||||
if err := CompatibleTypes(expected.Method(i).Type(), actual.Method(i).Type()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
case *types.Map:
|
||||
if actual, ok := actual.(*types.Map); ok {
|
||||
if err := CompatibleTypes(expected.Key(), actual.Key()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := CompatibleTypes(expected.Elem(), actual.Elem()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
case *types.Chan:
|
||||
if actual, ok := actual.(*types.Chan); ok {
|
||||
return CompatibleTypes(expected.Elem(), actual.Elem())
|
||||
}
|
||||
|
||||
case *types.Named:
|
||||
if actual, ok := actual.(*types.Named); ok {
|
||||
if NormalizeVendor(expected.Obj().Pkg().Path()) != NormalizeVendor(actual.Obj().Pkg().Path()) {
|
||||
return fmt.Errorf(
|
||||
"package name of named type differs, %s != %s",
|
||||
NormalizeVendor(expected.Obj().Pkg().Path()),
|
||||
NormalizeVendor(actual.Obj().Pkg().Path()),
|
||||
)
|
||||
}
|
||||
|
||||
if expected.Obj().Name() != actual.Obj().Name() {
|
||||
return fmt.Errorf(
|
||||
"named type name differs, %s != %s",
|
||||
NormalizeVendor(expected.Obj().Name()),
|
||||
NormalizeVendor(actual.Obj().Name()),
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Before models are generated all missing references will be Invalid Basic references.
|
||||
// lets assume these are valid too.
|
||||
if actual, ok := actual.(*types.Basic); ok && actual.Kind() == types.Invalid {
|
||||
return nil
|
||||
}
|
||||
|
||||
default:
|
||||
return fmt.Errorf("missing support for %T", expected)
|
||||
}
|
||||
|
||||
return fmt.Errorf("type mismatch %T != %T", expected, actual)
|
||||
}
|
115
vendor/github.com/99designs/gqlgen/internal/code/imports.go
generated
vendored
115
vendor/github.com/99designs/gqlgen/internal/code/imports.go
generated
vendored
@ -1,115 +0,0 @@
|
||||
package code
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"go/build"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
var nameForPackageCache = sync.Map{}
|
||||
|
||||
var gopaths []string
|
||||
|
||||
func init() {
|
||||
gopaths = filepath.SplitList(build.Default.GOPATH)
|
||||
for i, p := range gopaths {
|
||||
gopaths[i] = filepath.ToSlash(filepath.Join(p, "src"))
|
||||
}
|
||||
}
|
||||
|
||||
// NameForDir manually looks for package stanzas in files located in the given directory. This can be
|
||||
// much faster than having to consult go list, because we already know exactly where to look.
|
||||
func NameForDir(dir string) string {
|
||||
dir, err := filepath.Abs(dir)
|
||||
if err != nil {
|
||||
return SanitizePackageName(filepath.Base(dir))
|
||||
}
|
||||
files, err := ioutil.ReadDir(dir)
|
||||
if err != nil {
|
||||
return SanitizePackageName(filepath.Base(dir))
|
||||
}
|
||||
fset := token.NewFileSet()
|
||||
for _, file := range files {
|
||||
if !strings.HasSuffix(strings.ToLower(file.Name()), ".go") {
|
||||
continue
|
||||
}
|
||||
|
||||
filename := filepath.Join(dir, file.Name())
|
||||
if src, err := parser.ParseFile(fset, filename, nil, parser.PackageClauseOnly); err == nil {
|
||||
return src.Name.Name
|
||||
}
|
||||
}
|
||||
|
||||
return SanitizePackageName(filepath.Base(dir))
|
||||
}
|
||||
|
||||
// ImportPathForDir takes a path and returns a golang import path for the package
|
||||
func ImportPathForDir(dir string) (res string) {
|
||||
dir, err := filepath.Abs(dir)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
dir = filepath.ToSlash(dir)
|
||||
|
||||
modDir := dir
|
||||
assumedPart := ""
|
||||
for {
|
||||
f, err := ioutil.ReadFile(filepath.Join(modDir, "go.mod"))
|
||||
if err == nil {
|
||||
// found it, stop searching
|
||||
return string(modregex.FindSubmatch(f)[1]) + assumedPart
|
||||
}
|
||||
|
||||
assumedPart = "/" + filepath.Base(modDir) + assumedPart
|
||||
parentDir, err := filepath.Abs(filepath.Join(modDir, ".."))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if parentDir == modDir {
|
||||
// Walked all the way to the root and didnt find anything :'(
|
||||
break
|
||||
}
|
||||
modDir = parentDir
|
||||
}
|
||||
|
||||
for _, gopath := range gopaths {
|
||||
if len(gopath) < len(dir) && strings.EqualFold(gopath, dir[0:len(gopath)]) {
|
||||
return dir[len(gopath)+1:]
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
var modregex = regexp.MustCompile("module (.*)\n")
|
||||
|
||||
// NameForPackage returns the package name for a given import path. This can be really slow.
|
||||
func NameForPackage(importPath string) string {
|
||||
if importPath == "" {
|
||||
panic(errors.New("import path can not be empty"))
|
||||
}
|
||||
if v, ok := nameForPackageCache.Load(importPath); ok {
|
||||
return v.(string)
|
||||
}
|
||||
importPath = QualifyPackagePath(importPath)
|
||||
p, _ := packages.Load(&packages.Config{
|
||||
Mode: packages.NeedName,
|
||||
}, importPath)
|
||||
|
||||
if len(p) != 1 || p[0].Name == "" {
|
||||
return SanitizePackageName(filepath.Base(importPath))
|
||||
}
|
||||
|
||||
nameForPackageCache.Store(importPath, p[0].Name)
|
||||
|
||||
return p[0].Name
|
||||
}
|
56
vendor/github.com/99designs/gqlgen/internal/code/util.go
generated
vendored
56
vendor/github.com/99designs/gqlgen/internal/code/util.go
generated
vendored
@ -1,56 +0,0 @@
|
||||
package code
|
||||
|
||||
import (
|
||||
"go/build"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// take a string in the form github.com/package/blah.Type and split it into package and type
|
||||
func PkgAndType(name string) (string, string) {
|
||||
parts := strings.Split(name, ".")
|
||||
if len(parts) == 1 {
|
||||
return "", name
|
||||
}
|
||||
|
||||
return strings.Join(parts[:len(parts)-1], "."), parts[len(parts)-1]
|
||||
}
|
||||
|
||||
var modsRegex = regexp.MustCompile(`^(\*|\[\])*`)
|
||||
|
||||
// NormalizeVendor takes a qualified package path and turns it into normal one.
|
||||
// eg .
|
||||
// github.com/foo/vendor/github.com/99designs/gqlgen/graphql becomes
|
||||
// github.com/99designs/gqlgen/graphql
|
||||
func NormalizeVendor(pkg string) string {
|
||||
modifiers := modsRegex.FindAllString(pkg, 1)[0]
|
||||
pkg = strings.TrimPrefix(pkg, modifiers)
|
||||
parts := strings.Split(pkg, "/vendor/")
|
||||
return modifiers + parts[len(parts)-1]
|
||||
}
|
||||
|
||||
// QualifyPackagePath takes an import and fully qualifies it with a vendor dir, if one is required.
|
||||
// eg .
|
||||
// github.com/99designs/gqlgen/graphql becomes
|
||||
// github.com/foo/vendor/github.com/99designs/gqlgen/graphql
|
||||
//
|
||||
// x/tools/packages only supports 'qualified package paths' so this will need to be done prior to calling it
|
||||
// See https://github.com/golang/go/issues/30289
|
||||
func QualifyPackagePath(importPath string) string {
|
||||
wd, _ := os.Getwd()
|
||||
|
||||
pkg, err := build.Import(importPath, wd, 0)
|
||||
if err != nil {
|
||||
return importPath
|
||||
}
|
||||
|
||||
return pkg.ImportPath
|
||||
}
|
||||
|
||||
var invalidPackageNameChar = regexp.MustCompile(`[^\w]`)
|
||||
|
||||
func SanitizePackageName(pkg string) string {
|
||||
return invalidPackageNameChar.ReplaceAllLiteralString(filepath.Base(pkg), "_")
|
||||
}
|
100
vendor/github.com/99designs/gqlgen/internal/imports/prune.go
generated
vendored
100
vendor/github.com/99designs/gqlgen/internal/imports/prune.go
generated
vendored
@ -1,100 +0,0 @@
|
||||
// Wrapper around x/tools/imports that only removes imports, never adds new ones.
|
||||
|
||||
package imports
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/printer"
|
||||
"go/token"
|
||||
"strings"
|
||||
|
||||
"github.com/99designs/gqlgen/internal/code"
|
||||
|
||||
"golang.org/x/tools/go/ast/astutil"
|
||||
"golang.org/x/tools/imports"
|
||||
)
|
||||
|
||||
type visitFn func(node ast.Node)
|
||||
|
||||
func (fn visitFn) Visit(node ast.Node) ast.Visitor {
|
||||
fn(node)
|
||||
return fn
|
||||
}
|
||||
|
||||
// Prune removes any unused imports
|
||||
func Prune(filename string, src []byte) ([]byte, error) {
|
||||
fset := token.NewFileSet()
|
||||
|
||||
file, err := parser.ParseFile(fset, filename, src, parser.ParseComments|parser.AllErrors)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
unused := getUnusedImports(file)
|
||||
for ipath, name := range unused {
|
||||
astutil.DeleteNamedImport(fset, file, name, ipath)
|
||||
}
|
||||
printConfig := &printer.Config{Mode: printer.TabIndent, Tabwidth: 8}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := printConfig.Fprint(&buf, fset, file); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return imports.Process(filename, buf.Bytes(), &imports.Options{FormatOnly: true, Comments: true, TabIndent: true, TabWidth: 8})
|
||||
}
|
||||
|
||||
func getUnusedImports(file ast.Node) map[string]string {
|
||||
imported := map[string]*ast.ImportSpec{}
|
||||
used := map[string]bool{}
|
||||
|
||||
ast.Walk(visitFn(func(node ast.Node) {
|
||||
if node == nil {
|
||||
return
|
||||
}
|
||||
switch v := node.(type) {
|
||||
case *ast.ImportSpec:
|
||||
if v.Name != nil {
|
||||
imported[v.Name.Name] = v
|
||||
break
|
||||
}
|
||||
ipath := strings.Trim(v.Path.Value, `"`)
|
||||
if ipath == "C" {
|
||||
break
|
||||
}
|
||||
|
||||
local := code.NameForPackage(ipath)
|
||||
|
||||
imported[local] = v
|
||||
case *ast.SelectorExpr:
|
||||
xident, ok := v.X.(*ast.Ident)
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
if xident.Obj != nil {
|
||||
// if the parser can resolve it, it's not a package ref
|
||||
break
|
||||
}
|
||||
used[xident.Name] = true
|
||||
}
|
||||
}), file)
|
||||
|
||||
for pkg := range used {
|
||||
delete(imported, pkg)
|
||||
}
|
||||
|
||||
unusedImport := map[string]string{}
|
||||
for pkg, is := range imported {
|
||||
if !used[pkg] && pkg != "_" && pkg != "." {
|
||||
name := ""
|
||||
if is.Name != nil {
|
||||
name = is.Name.Name
|
||||
}
|
||||
unusedImport[strings.Trim(is.Path.Value, `"`)] = name
|
||||
}
|
||||
}
|
||||
|
||||
return unusedImport
|
||||
}
|
237
vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go
generated
vendored
237
vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go
generated
vendored
@ -1,237 +0,0 @@
|
||||
package modelgen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/types"
|
||||
"sort"
|
||||
|
||||
"github.com/99designs/gqlgen/codegen/config"
|
||||
"github.com/99designs/gqlgen/codegen/templates"
|
||||
"github.com/99designs/gqlgen/internal/code"
|
||||
"github.com/99designs/gqlgen/plugin"
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
)
|
||||
|
||||
type ModelBuild struct {
|
||||
PackageName string
|
||||
Interfaces []*Interface
|
||||
Models []*Object
|
||||
Enums []*Enum
|
||||
Scalars []string
|
||||
}
|
||||
|
||||
type Interface struct {
|
||||
Description string
|
||||
Name string
|
||||
}
|
||||
|
||||
type Object struct {
|
||||
Description string
|
||||
Name string
|
||||
Fields []*Field
|
||||
Implements []string
|
||||
}
|
||||
|
||||
type Field struct {
|
||||
Description string
|
||||
Name string
|
||||
Type types.Type
|
||||
Tag string
|
||||
}
|
||||
|
||||
type Enum struct {
|
||||
Description string
|
||||
Name string
|
||||
Values []*EnumValue
|
||||
}
|
||||
|
||||
type EnumValue struct {
|
||||
Description string
|
||||
Name string
|
||||
}
|
||||
|
||||
func New() plugin.Plugin {
|
||||
return &Plugin{}
|
||||
}
|
||||
|
||||
type Plugin struct{}
|
||||
|
||||
var _ plugin.ConfigMutator = &Plugin{}
|
||||
|
||||
func (m *Plugin) Name() string {
|
||||
return "modelgen"
|
||||
}
|
||||
|
||||
func (m *Plugin) MutateConfig(cfg *config.Config) error {
|
||||
if err := cfg.Check(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
schema, _, err := cfg.LoadSchema()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = cfg.Autobind(schema)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.InjectBuiltins(schema)
|
||||
|
||||
binder, err := cfg.NewBinder(schema)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := &ModelBuild{
|
||||
PackageName: cfg.Model.Package,
|
||||
}
|
||||
|
||||
for _, schemaType := range schema.Types {
|
||||
if cfg.Models.UserDefined(schemaType.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
switch schemaType.Kind {
|
||||
case ast.Interface, ast.Union:
|
||||
it := &Interface{
|
||||
Description: schemaType.Description,
|
||||
Name: schemaType.Name,
|
||||
}
|
||||
|
||||
b.Interfaces = append(b.Interfaces, it)
|
||||
case ast.Object, ast.InputObject:
|
||||
if schemaType == schema.Query || schemaType == schema.Mutation || schemaType == schema.Subscription {
|
||||
continue
|
||||
}
|
||||
it := &Object{
|
||||
Description: schemaType.Description,
|
||||
Name: schemaType.Name,
|
||||
}
|
||||
|
||||
for _, implementor := range schema.GetImplements(schemaType) {
|
||||
it.Implements = append(it.Implements, implementor.Name)
|
||||
}
|
||||
|
||||
for _, field := range schemaType.Fields {
|
||||
var typ types.Type
|
||||
fieldDef := schema.Types[field.Type.Name()]
|
||||
|
||||
if cfg.Models.UserDefined(field.Type.Name()) {
|
||||
pkg, typeName := code.PkgAndType(cfg.Models[field.Type.Name()].Model[0])
|
||||
typ, err = binder.FindType(pkg, typeName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
switch fieldDef.Kind {
|
||||
case ast.Scalar:
|
||||
// no user defined model, referencing a default scalar
|
||||
typ = types.NewNamed(
|
||||
types.NewTypeName(0, cfg.Model.Pkg(), "string", nil),
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
case ast.Interface, ast.Union:
|
||||
// no user defined model, referencing a generated interface type
|
||||
typ = types.NewNamed(
|
||||
types.NewTypeName(0, cfg.Model.Pkg(), templates.ToGo(field.Type.Name()), nil),
|
||||
types.NewInterfaceType([]*types.Func{}, []types.Type{}),
|
||||
nil,
|
||||
)
|
||||
|
||||
case ast.Enum:
|
||||
// no user defined model, must reference a generated enum
|
||||
typ = types.NewNamed(
|
||||
types.NewTypeName(0, cfg.Model.Pkg(), templates.ToGo(field.Type.Name()), nil),
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
case ast.Object, ast.InputObject:
|
||||
// no user defined model, must reference a generated struct
|
||||
typ = types.NewNamed(
|
||||
types.NewTypeName(0, cfg.Model.Pkg(), templates.ToGo(field.Type.Name()), nil),
|
||||
types.NewStruct(nil, nil),
|
||||
nil,
|
||||
)
|
||||
|
||||
default:
|
||||
panic(fmt.Errorf("unknown ast type %s", fieldDef.Kind))
|
||||
}
|
||||
}
|
||||
|
||||
name := field.Name
|
||||
if nameOveride := cfg.Models[schemaType.Name].Fields[field.Name].FieldName; nameOveride != "" {
|
||||
name = nameOveride
|
||||
}
|
||||
|
||||
typ = binder.CopyModifiersFromAst(field.Type, typ)
|
||||
|
||||
if isStruct(typ) && (fieldDef.Kind == ast.Object || fieldDef.Kind == ast.InputObject) {
|
||||
typ = types.NewPointer(typ)
|
||||
}
|
||||
|
||||
it.Fields = append(it.Fields, &Field{
|
||||
Name: name,
|
||||
Type: typ,
|
||||
Description: field.Description,
|
||||
Tag: `json:"` + field.Name + `"`,
|
||||
})
|
||||
}
|
||||
|
||||
b.Models = append(b.Models, it)
|
||||
case ast.Enum:
|
||||
it := &Enum{
|
||||
Name: schemaType.Name,
|
||||
Description: schemaType.Description,
|
||||
}
|
||||
|
||||
for _, v := range schemaType.EnumValues {
|
||||
it.Values = append(it.Values, &EnumValue{
|
||||
Name: v.Name,
|
||||
Description: v.Description,
|
||||
})
|
||||
}
|
||||
|
||||
b.Enums = append(b.Enums, it)
|
||||
case ast.Scalar:
|
||||
b.Scalars = append(b.Scalars, schemaType.Name)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Slice(b.Enums, func(i, j int) bool { return b.Enums[i].Name < b.Enums[j].Name })
|
||||
sort.Slice(b.Models, func(i, j int) bool { return b.Models[i].Name < b.Models[j].Name })
|
||||
sort.Slice(b.Interfaces, func(i, j int) bool { return b.Interfaces[i].Name < b.Interfaces[j].Name })
|
||||
|
||||
for _, it := range b.Enums {
|
||||
cfg.Models.Add(it.Name, cfg.Model.ImportPath()+"."+templates.ToGo(it.Name))
|
||||
}
|
||||
for _, it := range b.Models {
|
||||
cfg.Models.Add(it.Name, cfg.Model.ImportPath()+"."+templates.ToGo(it.Name))
|
||||
}
|
||||
for _, it := range b.Interfaces {
|
||||
cfg.Models.Add(it.Name, cfg.Model.ImportPath()+"."+templates.ToGo(it.Name))
|
||||
}
|
||||
for _, it := range b.Scalars {
|
||||
cfg.Models.Add(it, "github.com/99designs/gqlgen/graphql.String")
|
||||
}
|
||||
|
||||
if len(b.Models) == 0 && len(b.Enums) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return templates.Render(templates.Options{
|
||||
PackageName: cfg.Model.Package,
|
||||
Filename: cfg.Model.Filename,
|
||||
Data: b,
|
||||
GeneratedHeader: true,
|
||||
})
|
||||
}
|
||||
|
||||
func isStruct(t types.Type) bool {
|
||||
_, is := t.Underlying().(*types.Struct)
|
||||
return is
|
||||
}
|
85
vendor/github.com/99designs/gqlgen/plugin/modelgen/models.gotpl
generated
vendored
85
vendor/github.com/99designs/gqlgen/plugin/modelgen/models.gotpl
generated
vendored
@ -1,85 +0,0 @@
|
||||
{{ reserveImport "context" }}
|
||||
{{ reserveImport "fmt" }}
|
||||
{{ reserveImport "io" }}
|
||||
{{ reserveImport "strconv" }}
|
||||
{{ reserveImport "time" }}
|
||||
{{ reserveImport "sync" }}
|
||||
{{ reserveImport "errors" }}
|
||||
{{ reserveImport "bytes" }}
|
||||
|
||||
{{ reserveImport "github.com/vektah/gqlparser" }}
|
||||
{{ reserveImport "github.com/vektah/gqlparser/ast" }}
|
||||
{{ reserveImport "github.com/99designs/gqlgen/graphql" }}
|
||||
{{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }}
|
||||
|
||||
{{- range $model := .Interfaces }}
|
||||
{{ with .Description }} {{.|prefixLines "// "}} {{ end }}
|
||||
type {{.Name|go }} interface {
|
||||
Is{{.Name|go }}()
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
{{ range $model := .Models }}
|
||||
{{with .Description }} {{.|prefixLines "// "}} {{end}}
|
||||
type {{ .Name|go }} struct {
|
||||
{{- range $field := .Fields }}
|
||||
{{- with .Description }}
|
||||
{{.|prefixLines "// "}}
|
||||
{{- end}}
|
||||
{{ $field.Name|go }} {{$field.Type | ref}} `{{$field.Tag}}`
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
{{- range $iface := .Implements }}
|
||||
func ({{ $model.Name|go }}) Is{{ $iface|go }}() {}
|
||||
{{- end }}
|
||||
{{- end}}
|
||||
|
||||
{{ range $enum := .Enums }}
|
||||
{{ with .Description }} {{.|prefixLines "// "}} {{end}}
|
||||
type {{.Name|go }} string
|
||||
const (
|
||||
{{- range $value := .Values}}
|
||||
{{- with .Description}}
|
||||
{{.|prefixLines "// "}}
|
||||
{{- end}}
|
||||
{{ $enum.Name|go }}{{ .Name|go }} {{$enum.Name|go }} = {{.Name|quote}}
|
||||
{{- end }}
|
||||
)
|
||||
|
||||
var All{{.Name|go }} = []{{ .Name|go }}{
|
||||
{{- range $value := .Values}}
|
||||
{{$enum.Name|go }}{{ .Name|go }},
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
func (e {{.Name|go }}) IsValid() bool {
|
||||
switch e {
|
||||
case {{ range $index, $element := .Values}}{{if $index}},{{end}}{{ $enum.Name|go }}{{ $element.Name|go }}{{end}}:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (e {{.Name|go }}) String() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
func (e *{{.Name|go }}) UnmarshalGQL(v interface{}) error {
|
||||
str, ok := v.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("enums must be strings")
|
||||
}
|
||||
|
||||
*e = {{ .Name|go }}(str)
|
||||
if !e.IsValid() {
|
||||
return fmt.Errorf("%s is not a valid {{ .Name }}", str)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e {{.Name|go }}) MarshalGQL(w io.Writer) {
|
||||
fmt.Fprint(w, strconv.Quote(e.String()))
|
||||
}
|
||||
|
||||
{{- end }}
|
20
vendor/github.com/99designs/gqlgen/plugin/plugin.go
generated
vendored
20
vendor/github.com/99designs/gqlgen/plugin/plugin.go
generated
vendored
@ -1,20 +0,0 @@
|
||||
// plugin package interfaces are EXPERIMENTAL.
|
||||
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"github.com/99designs/gqlgen/codegen"
|
||||
"github.com/99designs/gqlgen/codegen/config"
|
||||
)
|
||||
|
||||
type Plugin interface {
|
||||
Name() string
|
||||
}
|
||||
|
||||
type ConfigMutator interface {
|
||||
MutateConfig(cfg *config.Config) error
|
||||
}
|
||||
|
||||
type CodeGenerator interface {
|
||||
GenerateCode(cfg *codegen.Data) error
|
||||
}
|
54
vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go
generated
vendored
54
vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go
generated
vendored
@ -1,54 +0,0 @@
|
||||
package resolvergen
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/99designs/gqlgen/codegen"
|
||||
"github.com/99designs/gqlgen/codegen/templates"
|
||||
"github.com/99designs/gqlgen/plugin"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func New() plugin.Plugin {
|
||||
return &Plugin{}
|
||||
}
|
||||
|
||||
type Plugin struct{}
|
||||
|
||||
var _ plugin.CodeGenerator = &Plugin{}
|
||||
|
||||
func (m *Plugin) Name() string {
|
||||
// TODO: typo, should be resolvergen
|
||||
return "resovlergen"
|
||||
}
|
||||
func (m *Plugin) GenerateCode(data *codegen.Data) error {
|
||||
if !data.Config.Resolver.IsDefined() {
|
||||
return nil
|
||||
}
|
||||
|
||||
resolverBuild := &ResolverBuild{
|
||||
Data: data,
|
||||
PackageName: data.Config.Resolver.Package,
|
||||
ResolverType: data.Config.Resolver.Type,
|
||||
}
|
||||
filename := data.Config.Resolver.Filename
|
||||
|
||||
if _, err := os.Stat(filename); os.IsNotExist(errors.Cause(err)) {
|
||||
return templates.Render(templates.Options{
|
||||
PackageName: data.Config.Resolver.Package,
|
||||
Filename: data.Config.Resolver.Filename,
|
||||
Data: resolverBuild,
|
||||
})
|
||||
}
|
||||
|
||||
log.Printf("Skipped resolver: %s already exists\n", filename)
|
||||
return nil
|
||||
}
|
||||
|
||||
type ResolverBuild struct {
|
||||
*codegen.Data
|
||||
|
||||
PackageName string
|
||||
ResolverType string
|
||||
}
|
40
vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.gotpl
generated
vendored
40
vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.gotpl
generated
vendored
@ -1,40 +0,0 @@
|
||||
// THIS CODE IS A STARTING POINT ONLY. IT WILL NOT BE UPDATED WITH SCHEMA CHANGES.
|
||||
|
||||
{{ reserveImport "context" }}
|
||||
{{ reserveImport "fmt" }}
|
||||
{{ reserveImport "io" }}
|
||||
{{ reserveImport "strconv" }}
|
||||
{{ reserveImport "time" }}
|
||||
{{ reserveImport "sync" }}
|
||||
{{ reserveImport "errors" }}
|
||||
{{ reserveImport "bytes" }}
|
||||
|
||||
{{ reserveImport "github.com/99designs/gqlgen/handler" }}
|
||||
{{ reserveImport "github.com/vektah/gqlparser" }}
|
||||
{{ reserveImport "github.com/vektah/gqlparser/ast" }}
|
||||
{{ reserveImport "github.com/99designs/gqlgen/graphql" }}
|
||||
{{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }}
|
||||
|
||||
type {{.ResolverType}} struct {}
|
||||
|
||||
{{ range $object := .Objects -}}
|
||||
{{- if $object.HasResolvers -}}
|
||||
func (r *{{$.ResolverType}}) {{$object.Name}}() {{ $object.ResolverInterface | ref }} {
|
||||
return &{{lcFirst $object.Name}}{{ucFirst $.ResolverType}}{r}
|
||||
}
|
||||
{{ end -}}
|
||||
{{ end }}
|
||||
|
||||
{{ range $object := .Objects -}}
|
||||
{{- if $object.HasResolvers -}}
|
||||
type {{lcFirst $object.Name}}{{ucFirst $.ResolverType}} struct { *{{$.ResolverType}} }
|
||||
|
||||
{{ range $field := $object.Fields -}}
|
||||
{{- if $field.IsResolver -}}
|
||||
func (r *{{lcFirst $object.Name}}{{ucFirst $.ResolverType}}) {{$field.GoFieldName}}{{ $field.ShortResolverDeclaration }} {
|
||||
panic("not implemented")
|
||||
}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ end }}
|
93
vendor/github.com/99designs/gqlgen/plugin/schemaconfig/schemaconfig.go
generated
vendored
93
vendor/github.com/99designs/gqlgen/plugin/schemaconfig/schemaconfig.go
generated
vendored
@ -1,93 +0,0 @@
|
||||
package schemaconfig
|
||||
|
||||
import (
|
||||
"github.com/99designs/gqlgen/codegen/config"
|
||||
"github.com/99designs/gqlgen/plugin"
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
)
|
||||
|
||||
func New() plugin.Plugin {
|
||||
return &Plugin{}
|
||||
}
|
||||
|
||||
type Plugin struct{}
|
||||
|
||||
var _ plugin.ConfigMutator = &Plugin{}
|
||||
|
||||
func (m *Plugin) Name() string {
|
||||
return "schemaconfig"
|
||||
}
|
||||
|
||||
func (m *Plugin) MutateConfig(cfg *config.Config) error {
|
||||
if err := cfg.Check(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
schema, _, err := cfg.LoadSchema()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.Directives["goModel"] = config.DirectiveConfig{
|
||||
SkipRuntime: true,
|
||||
}
|
||||
|
||||
cfg.Directives["goField"] = config.DirectiveConfig{
|
||||
SkipRuntime: true,
|
||||
}
|
||||
|
||||
for _, schemaType := range schema.Types {
|
||||
if schemaType == schema.Query || schemaType == schema.Mutation || schemaType == schema.Subscription {
|
||||
continue
|
||||
}
|
||||
|
||||
if bd := schemaType.Directives.ForName("goModel"); bd != nil {
|
||||
if ma := bd.Arguments.ForName("model"); ma != nil {
|
||||
if mv, err := ma.Value.Value(nil); err == nil {
|
||||
cfg.Models.Add(schemaType.Name, mv.(string))
|
||||
}
|
||||
}
|
||||
if ma := bd.Arguments.ForName("models"); ma != nil {
|
||||
if mvs, err := ma.Value.Value(nil); err == nil {
|
||||
for _, mv := range mvs.([]interface{}) {
|
||||
cfg.Models.Add(schemaType.Name, mv.(string))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if schemaType.Kind == ast.Object || schemaType.Kind == ast.InputObject {
|
||||
for _, field := range schemaType.Fields {
|
||||
if fd := field.Directives.ForName("goField"); fd != nil {
|
||||
forceResolver := cfg.Models[schemaType.Name].Fields[field.Name].Resolver
|
||||
fieldName := cfg.Models[schemaType.Name].Fields[field.Name].FieldName
|
||||
|
||||
if ra := fd.Arguments.ForName("forceResolver"); ra != nil {
|
||||
if fr, err := ra.Value.Value(nil); err == nil {
|
||||
forceResolver = fr.(bool)
|
||||
}
|
||||
}
|
||||
|
||||
if na := fd.Arguments.ForName("name"); na != nil {
|
||||
if fr, err := na.Value.Value(nil); err == nil {
|
||||
fieldName = fr.(string)
|
||||
}
|
||||
}
|
||||
|
||||
if cfg.Models[schemaType.Name].Fields == nil {
|
||||
cfg.Models[schemaType.Name] = config.TypeMapEntry{
|
||||
Model: cfg.Models[schemaType.Name].Model,
|
||||
Fields: map[string]config.TypeMapField{},
|
||||
}
|
||||
}
|
||||
|
||||
cfg.Models[schemaType.Name].Fields[field.Name] = config.TypeMapField{
|
||||
FieldName: fieldName,
|
||||
Resolver: forceResolver,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
1
vendor/github.com/MichaelMure/go-term-text/.gitignore
generated
vendored
1
vendor/github.com/MichaelMure/go-term-text/.gitignore
generated
vendored
@ -1 +0,0 @@
|
||||
.idea/
|
16
vendor/github.com/MichaelMure/go-term-text/.travis.yml
generated
vendored
16
vendor/github.com/MichaelMure/go-term-text/.travis.yml
generated
vendored
@ -1,16 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
- 1.13.x
|
||||
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
|
||||
script:
|
||||
- go build
|
||||
- go test -v -bench=. -race -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
21
vendor/github.com/MichaelMure/go-term-text/LICENSE
generated
vendored
21
vendor/github.com/MichaelMure/go-term-text/LICENSE
generated
vendored
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Michael Muré
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
74
vendor/github.com/MichaelMure/go-term-text/Readme.md
generated
vendored
74
vendor/github.com/MichaelMure/go-term-text/Readme.md
generated
vendored
@ -1,74 +0,0 @@
|
||||
# go-term-text
|
||||
|
||||
[![Build Status](https://travis-ci.org/MichaelMure/go-term-text.svg?branch=master)](https://travis-ci.org/MichaelMure/go-term-text)
|
||||
[![GoDoc](https://godoc.org/github.com/MichaelMure/go-term-text?status.svg)](https://godoc.org/github.com/MichaelMure/go-term-text)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/MichaelMure/go-term-text)](https://goreportcard.com/report/github.com/MichaelMure/go-term-text)
|
||||
[![codecov](https://codecov.io/gh/MichaelMure/go-term-text/branch/master/graph/badge.svg)](https://codecov.io/gh/MichaelMure/go-term-text)
|
||||
[![GitHub license](https://img.shields.io/github/license/MichaelMure/go-term-text.svg)](https://github.com/MichaelMure/go-term-text/blob/master/LICENSE)
|
||||
[![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/the-git-bug/Lobby)
|
||||
|
||||
`go-term-text` is a go package implementing a collection of algorithms to help format and manipulate text for the terminal.
|
||||
|
||||
In particular, `go-term-text`:
|
||||
- support wide characters (chinese, japanese ...) and emoji
|
||||
- handle properly ANSI escape sequences
|
||||
|
||||
Included algorithms cover:
|
||||
- wrapping with padding and indentation
|
||||
- padding
|
||||
- text length
|
||||
- trimming
|
||||
- alignment
|
||||
- escape sequence extraction and reapplication
|
||||
- escape sequence snapshot and simplification
|
||||
- truncation
|
||||
|
||||
## Example
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/MichaelMure/go-term-text"
|
||||
)
|
||||
|
||||
func main() {
|
||||
input := "The \x1b[1mLorem ipsum\x1b[0m text is typically composed of " +
|
||||
"pseudo-Latin words. It is commonly used as \x1b[3mplaceholder\x1b[0m" +
|
||||
" text to examine or demonstrate the \x1b[9mvisual effects\x1b[0m of " +
|
||||
"various graphic design. 一只 A Quick \x1b[31m敏捷的狐 Fox " +
|
||||
"狸跳过了\x1b[0mDog一只懒狗。"
|
||||
|
||||
output, n := text.Wrap(input, 60,
|
||||
text.WrapIndent("\x1b[34m<-indent-> \x1b[0m"),
|
||||
text.WrapPad("\x1b[33m<-pad-> \x1b[0m"),
|
||||
)
|
||||
|
||||
fmt.Printf("output has %d lines\n\n", n)
|
||||
|
||||
fmt.Println("|" + strings.Repeat("-", 58) + "|")
|
||||
fmt.Println(output)
|
||||
fmt.Println("|" + strings.Repeat("-", 58) + "|")
|
||||
}
|
||||
```
|
||||
|
||||
This will print:
|
||||
|
||||
![example output](/img/example.png)
|
||||
|
||||
For more details, have a look at the [GoDoc](https://godoc.org/github.com/MichaelMure/go-term-text).
|
||||
|
||||
## Origin
|
||||
|
||||
This package has been extracted from the [git-bug](https://github.com/MichaelMure/git-bug) project. As such, its aim is to support this project and not to provide an all-in-one solution. Contributions as welcome though.
|
||||
|
||||
## Contribute
|
||||
|
||||
PRs accepted.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
67
vendor/github.com/MichaelMure/go-term-text/align.go
generated
vendored
67
vendor/github.com/MichaelMure/go-term-text/align.go
generated
vendored
@ -1,67 +0,0 @@
|
||||
package text
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Alignment int
|
||||
|
||||
const (
|
||||
NoAlign Alignment = iota
|
||||
AlignLeft
|
||||
AlignCenter
|
||||
AlignRight
|
||||
)
|
||||
|
||||
// LineAlign align the given line as asked and apply the needed padding to match the given
|
||||
// lineWidth, while ignoring the terminal escape sequences.
|
||||
// If the given lineWidth is too small to fit the given line, it's returned without
|
||||
// padding, overflowing lineWidth.
|
||||
func LineAlign(line string, lineWidth int, align Alignment) string {
|
||||
switch align {
|
||||
case NoAlign:
|
||||
return line
|
||||
case AlignLeft:
|
||||
return LineAlignLeft(line, lineWidth)
|
||||
case AlignCenter:
|
||||
return LineAlignCenter(line, lineWidth)
|
||||
case AlignRight:
|
||||
return LineAlignRight(line, lineWidth)
|
||||
}
|
||||
panic("unknown alignment")
|
||||
}
|
||||
|
||||
// LineAlignLeft align the given line on the left while ignoring the terminal escape sequences.
|
||||
// If the given lineWidth is too small to fit the given line, it's returned without
|
||||
// padding, overflowing lineWidth.
|
||||
func LineAlignLeft(line string, lineWidth int) string {
|
||||
return TrimSpace(line)
|
||||
}
|
||||
|
||||
// LineAlignCenter align the given line on the center and apply the needed left
|
||||
// padding, while ignoring the terminal escape sequences.
|
||||
// If the given lineWidth is too small to fit the given line, it's returned without
|
||||
// padding, overflowing lineWidth.
|
||||
func LineAlignCenter(line string, lineWidth int) string {
|
||||
trimmed := TrimSpace(line)
|
||||
totalPadLen := lineWidth - Len(trimmed)
|
||||
if totalPadLen < 0 {
|
||||
totalPadLen = 0
|
||||
}
|
||||
pad := strings.Repeat(" ", totalPadLen/2)
|
||||
return pad + trimmed
|
||||
}
|
||||
|
||||
// LineAlignRight align the given line on the right and apply the needed left
|
||||
// padding to match the given lineWidth, while ignoring the terminal escape sequences.
|
||||
// If the given lineWidth is too small to fit the given line, it's returned without
|
||||
// padding, overflowing lineWidth.
|
||||
func LineAlignRight(line string, lineWidth int) string {
|
||||
trimmed := TrimSpace(line)
|
||||
padLen := lineWidth - Len(trimmed)
|
||||
if padLen < 0 {
|
||||
padLen = 0
|
||||
}
|
||||
pad := strings.Repeat(" ", padLen)
|
||||
return pad + trimmed
|
||||
}
|
265
vendor/github.com/MichaelMure/go-term-text/escape_state.go
generated
vendored
265
vendor/github.com/MichaelMure/go-term-text/escape_state.go
generated
vendored
@ -1,265 +0,0 @@
|
||||
package text
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const Escape = '\x1b'
|
||||
|
||||
type EscapeState struct {
|
||||
Bold bool
|
||||
Dim bool
|
||||
Italic bool
|
||||
Underlined bool
|
||||
Blink bool
|
||||
Reverse bool
|
||||
Hidden bool
|
||||
CrossedOut bool
|
||||
|
||||
FgColor Color
|
||||
BgColor Color
|
||||
}
|
||||
|
||||
type Color interface {
|
||||
Codes() []string
|
||||
}
|
||||
|
||||
func (es *EscapeState) Witness(s string) {
|
||||
inEscape := false
|
||||
var start int
|
||||
|
||||
runes := []rune(s)
|
||||
|
||||
for i, r := range runes {
|
||||
if r == Escape {
|
||||
inEscape = true
|
||||
start = i
|
||||
continue
|
||||
}
|
||||
if inEscape {
|
||||
if r == 'm' {
|
||||
inEscape = false
|
||||
es.witnessCode(string(runes[start+1 : i]))
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (es *EscapeState) witnessCode(s string) {
|
||||
if s == "" {
|
||||
return
|
||||
}
|
||||
if s == "[" {
|
||||
es.reset()
|
||||
return
|
||||
}
|
||||
if len(s) < 2 {
|
||||
return
|
||||
}
|
||||
if s[0] != '[' {
|
||||
return
|
||||
}
|
||||
|
||||
s = s[1:]
|
||||
split := strings.Split(s, ";")
|
||||
|
||||
dequeue := func() {
|
||||
split = split[1:]
|
||||
}
|
||||
|
||||
color := func(ground int) Color {
|
||||
if len(split) < 1 {
|
||||
// the whole sequence is broken, ignoring the rest
|
||||
return nil
|
||||
}
|
||||
|
||||
subCode := split[0]
|
||||
dequeue()
|
||||
|
||||
switch subCode {
|
||||
case "2":
|
||||
if len(split) < 3 {
|
||||
return nil
|
||||
}
|
||||
r, err := strconv.Atoi(split[0])
|
||||
dequeue()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
g, err := strconv.Atoi(split[0])
|
||||
dequeue()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
b, err := strconv.Atoi(split[0])
|
||||
dequeue()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return &ColorRGB{ground: ground, R: r, G: g, B: b}
|
||||
|
||||
case "5":
|
||||
if len(split) < 1 {
|
||||
return nil
|
||||
}
|
||||
index, err := strconv.Atoi(split[0])
|
||||
dequeue()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return &Color256{ground: ground, Index: index}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
for len(split) > 0 {
|
||||
code, err := strconv.Atoi(split[0])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
dequeue()
|
||||
|
||||
switch {
|
||||
case code == 0:
|
||||
es.reset()
|
||||
|
||||
case code == 1:
|
||||
es.Bold = true
|
||||
case code == 2:
|
||||
es.Dim = true
|
||||
case code == 3:
|
||||
es.Italic = true
|
||||
case code == 4:
|
||||
es.Underlined = true
|
||||
case code == 5:
|
||||
es.Blink = true
|
||||
// case code == 6:
|
||||
case code == 7:
|
||||
es.Reverse = true
|
||||
case code == 8:
|
||||
es.Hidden = true
|
||||
case code == 9:
|
||||
es.CrossedOut = true
|
||||
|
||||
case code == 21:
|
||||
es.Bold = false
|
||||
case code == 22:
|
||||
es.Dim = false
|
||||
case code == 23:
|
||||
es.Italic = false
|
||||
case code == 24:
|
||||
es.Underlined = false
|
||||
case code == 25:
|
||||
es.Blink = false
|
||||
// case code == 26:
|
||||
case code == 27:
|
||||
es.Reverse = false
|
||||
case code == 28:
|
||||
es.Hidden = false
|
||||
case code == 29:
|
||||
es.CrossedOut = false
|
||||
|
||||
case (code >= 30 && code <= 37) || code == 39 || (code >= 90 && code <= 97):
|
||||
es.FgColor = ColorIndex(code)
|
||||
|
||||
case (code >= 40 && code <= 47) || code == 49 || (code >= 100 && code <= 107):
|
||||
es.BgColor = ColorIndex(code)
|
||||
|
||||
case code == 38:
|
||||
es.FgColor = color(code)
|
||||
if es.FgColor == nil {
|
||||
return
|
||||
}
|
||||
|
||||
case code == 48:
|
||||
es.BgColor = color(code)
|
||||
if es.BgColor == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (es *EscapeState) reset() {
|
||||
*es = EscapeState{}
|
||||
}
|
||||
|
||||
func (es *EscapeState) String() string {
|
||||
var codes []string
|
||||
|
||||
if es.Bold {
|
||||
codes = append(codes, strconv.Itoa(1))
|
||||
}
|
||||
if es.Dim {
|
||||
codes = append(codes, strconv.Itoa(2))
|
||||
}
|
||||
if es.Italic {
|
||||
codes = append(codes, strconv.Itoa(3))
|
||||
}
|
||||
if es.Underlined {
|
||||
codes = append(codes, strconv.Itoa(4))
|
||||
}
|
||||
if es.Blink {
|
||||
codes = append(codes, strconv.Itoa(5))
|
||||
}
|
||||
if es.Reverse {
|
||||
codes = append(codes, strconv.Itoa(7))
|
||||
}
|
||||
if es.Hidden {
|
||||
codes = append(codes, strconv.Itoa(8))
|
||||
}
|
||||
if es.CrossedOut {
|
||||
codes = append(codes, strconv.Itoa(9))
|
||||
}
|
||||
|
||||
if es.FgColor != nil {
|
||||
codes = append(codes, es.FgColor.Codes()...)
|
||||
}
|
||||
if es.BgColor != nil {
|
||||
codes = append(codes, es.BgColor.Codes()...)
|
||||
}
|
||||
|
||||
if len(codes) == 0 {
|
||||
return "\x1b[0m"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("\x1b[%sm", strings.Join(codes, ";"))
|
||||
}
|
||||
|
||||
type ColorIndex int
|
||||
|
||||
func (cInd ColorIndex) Codes() []string {
|
||||
return []string{strconv.Itoa(int(cInd))}
|
||||
}
|
||||
|
||||
type Color256 struct {
|
||||
ground int
|
||||
Index int
|
||||
}
|
||||
|
||||
func (c256 Color256) Codes() []string {
|
||||
return []string{
|
||||
strconv.Itoa(c256.ground),
|
||||
"5",
|
||||
strconv.Itoa(c256.Index),
|
||||
}
|
||||
}
|
||||
|
||||
type ColorRGB struct {
|
||||
ground int
|
||||
R, G, B int
|
||||
}
|
||||
|
||||
func (cRGB ColorRGB) Codes() []string {
|
||||
return []string{
|
||||
strconv.Itoa(cRGB.ground),
|
||||
"2",
|
||||
strconv.Itoa(cRGB.R),
|
||||
strconv.Itoa(cRGB.G),
|
||||
strconv.Itoa(cRGB.B),
|
||||
}
|
||||
}
|
95
vendor/github.com/MichaelMure/go-term-text/escapes.go
generated
vendored
95
vendor/github.com/MichaelMure/go-term-text/escapes.go
generated
vendored
@ -1,95 +0,0 @@
|
||||
package text
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// EscapeItem hold the description of terminal escapes in a line.
|
||||
// 'item' is the actual escape command
|
||||
// 'pos' is the index in the rune array where the 'item' shall be inserted back.
|
||||
// For example, the escape item in "F\x1b33mox" is {"\x1b33m", 1}.
|
||||
type EscapeItem struct {
|
||||
Item string
|
||||
Pos int
|
||||
}
|
||||
|
||||
// ExtractTermEscapes extract terminal escapes out of a line and returns a new
|
||||
// line without terminal escapes and a slice of escape items. The terminal escapes
|
||||
// can be inserted back into the new line at rune index 'item.pos' to recover the
|
||||
// original line.
|
||||
//
|
||||
// Required: The line shall not contain "\n"
|
||||
func ExtractTermEscapes(line string) (string, []EscapeItem) {
|
||||
var termEscapes []EscapeItem
|
||||
var line1 strings.Builder
|
||||
|
||||
pos := 0
|
||||
item := ""
|
||||
occupiedRuneCount := 0
|
||||
inEscape := false
|
||||
for i, r := range []rune(line) {
|
||||
if r == '\x1b' {
|
||||
pos = i
|
||||
item = string(r)
|
||||
inEscape = true
|
||||
continue
|
||||
}
|
||||
if inEscape {
|
||||
item += string(r)
|
||||
if r == 'm' {
|
||||
termEscapes = append(termEscapes, EscapeItem{item, pos - occupiedRuneCount})
|
||||
occupiedRuneCount += utf8.RuneCountInString(item)
|
||||
inEscape = false
|
||||
}
|
||||
continue
|
||||
}
|
||||
line1.WriteRune(r)
|
||||
}
|
||||
|
||||
return line1.String(), termEscapes
|
||||
}
|
||||
|
||||
// ApplyTermEscapes apply the extracted terminal escapes to the edited line.
|
||||
// Escape sequences need to be ordered by their position.
|
||||
// If the position is < 0, the escape is applied at the beginning of the line.
|
||||
// If the position is > len(line), the escape is applied at the end of the line.
|
||||
func ApplyTermEscapes(line string, escapes []EscapeItem) string {
|
||||
if len(escapes) == 0 {
|
||||
return line
|
||||
}
|
||||
|
||||
var out strings.Builder
|
||||
|
||||
currPos := 0
|
||||
currItem := 0
|
||||
for _, r := range line {
|
||||
for currItem < len(escapes) && currPos >= escapes[currItem].Pos {
|
||||
out.WriteString(escapes[currItem].Item)
|
||||
currItem++
|
||||
}
|
||||
out.WriteRune(r)
|
||||
currPos++
|
||||
}
|
||||
|
||||
// Don't forget the trailing escapes, if any.
|
||||
for currItem < len(escapes) {
|
||||
out.WriteString(escapes[currItem].Item)
|
||||
currItem++
|
||||
}
|
||||
|
||||
return out.String()
|
||||
}
|
||||
|
||||
// OffsetEscapes is a utility function to offset the position of a
|
||||
// collection of EscapeItem.
|
||||
func OffsetEscapes(escapes []EscapeItem, offset int) []EscapeItem {
|
||||
result := make([]EscapeItem, len(escapes))
|
||||
for i, e := range escapes {
|
||||
result[i] = EscapeItem{
|
||||
Item: e.Item,
|
||||
Pos: e.Pos + offset,
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
8
vendor/github.com/MichaelMure/go-term-text/go.mod
generated
vendored
8
vendor/github.com/MichaelMure/go-term-text/go.mod
generated
vendored
@ -1,8 +0,0 @@
|
||||
module github.com/MichaelMure/go-term-text
|
||||
|
||||
go 1.11
|
||||
|
||||
require (
|
||||
github.com/mattn/go-runewidth v0.0.6
|
||||
github.com/stretchr/testify v1.3.0
|
||||
)
|
9
vendor/github.com/MichaelMure/go-term-text/go.sum
generated
vendored
9
vendor/github.com/MichaelMure/go-term-text/go.sum
generated
vendored
@ -1,9 +0,0 @@
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/mattn/go-runewidth v0.0.6 h1:V2iyH+aX9C5fsYCpK60U8BYIvmhqxuOL3JZcqc1NB7k=
|
||||
github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
50
vendor/github.com/MichaelMure/go-term-text/left_pad.go
generated
vendored
50
vendor/github.com/MichaelMure/go-term-text/left_pad.go
generated
vendored
@ -1,50 +0,0 @@
|
||||
package text
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
|
||||
"github.com/mattn/go-runewidth"
|
||||
)
|
||||
|
||||
// LeftPadMaxLine pads a line on the left by a specified amount and pads the
|
||||
// string on the right to fill the maxLength.
|
||||
// If the given string is too long, it is truncated with an ellipsis.
|
||||
// Handle properly terminal color escape code
|
||||
func LeftPadMaxLine(line string, length, leftPad int) string {
|
||||
cleaned, escapes := ExtractTermEscapes(line)
|
||||
|
||||
scrWidth := runewidth.StringWidth(cleaned)
|
||||
// truncate and ellipse if needed
|
||||
if scrWidth+leftPad > length {
|
||||
cleaned = runewidth.Truncate(cleaned, length-leftPad, "…")
|
||||
} else if scrWidth+leftPad < length {
|
||||
cleaned = runewidth.FillRight(cleaned, length-leftPad)
|
||||
}
|
||||
|
||||
rightPart := ApplyTermEscapes(cleaned, escapes)
|
||||
pad := strings.Repeat(" ", leftPad)
|
||||
|
||||
return pad + rightPart
|
||||
}
|
||||
|
||||
// LeftPad left pad each line of the given text
|
||||
func LeftPadLines(text string, leftPad int) string {
|
||||
var result bytes.Buffer
|
||||
|
||||
pad := strings.Repeat(" ", leftPad)
|
||||
|
||||
lines := strings.Split(text, "\n")
|
||||
|
||||
for i, line := range lines {
|
||||
result.WriteString(pad)
|
||||
result.WriteString(line)
|
||||
|
||||
// no additional line break at the end
|
||||
if i < len(lines)-1 {
|
||||
result.WriteString("\n")
|
||||
}
|
||||
}
|
||||
|
||||
return result.String()
|
||||
}
|
45
vendor/github.com/MichaelMure/go-term-text/len.go
generated
vendored
45
vendor/github.com/MichaelMure/go-term-text/len.go
generated
vendored
@ -1,45 +0,0 @@
|
||||
package text
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/mattn/go-runewidth"
|
||||
)
|
||||
|
||||
// Len return the length of a string in a terminal, while ignoring the terminal
|
||||
// escape sequences.
|
||||
func Len(text string) int {
|
||||
length := 0
|
||||
escape := false
|
||||
|
||||
for _, char := range text {
|
||||
if char == '\x1b' {
|
||||
escape = true
|
||||
}
|
||||
if !escape {
|
||||
length += runewidth.RuneWidth(char)
|
||||
}
|
||||
if char == 'm' {
|
||||
escape = false
|
||||
}
|
||||
}
|
||||
|
||||
return length
|
||||
}
|
||||
|
||||
// MaxLineLen return the length in a terminal of the longest line, while
|
||||
// ignoring the terminal escape sequences.
|
||||
func MaxLineLen(text string) int {
|
||||
lines := strings.Split(text, "\n")
|
||||
|
||||
max := 0
|
||||
|
||||
for _, line := range lines {
|
||||
length := Len(line)
|
||||
if length > max {
|
||||
max = length
|
||||
}
|
||||
}
|
||||
|
||||
return max
|
||||
}
|
28
vendor/github.com/MichaelMure/go-term-text/trim.go
generated
vendored
28
vendor/github.com/MichaelMure/go-term-text/trim.go
generated
vendored
@ -1,28 +0,0 @@
|
||||
package text
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// TrimSpace remove the leading and trailing whitespace while ignoring the
|
||||
// terminal escape sequences.
|
||||
// Returns the number of trimmed space on both side.
|
||||
func TrimSpace(line string) string {
|
||||
cleaned, escapes := ExtractTermEscapes(line)
|
||||
|
||||
// trim left while counting
|
||||
left := 0
|
||||
trimmed := strings.TrimLeftFunc(cleaned, func(r rune) bool {
|
||||
if unicode.IsSpace(r) {
|
||||
left++
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
trimmed = strings.TrimRightFunc(trimmed, unicode.IsSpace)
|
||||
|
||||
escapes = OffsetEscapes(escapes, -left)
|
||||
return ApplyTermEscapes(trimmed, escapes)
|
||||
}
|
24
vendor/github.com/MichaelMure/go-term-text/truncate.go
generated
vendored
24
vendor/github.com/MichaelMure/go-term-text/truncate.go
generated
vendored
@ -1,24 +0,0 @@
|
||||
package text
|
||||
|
||||
import "github.com/mattn/go-runewidth"
|
||||
|
||||
// TruncateMax truncate a line if its length is greater
|
||||
// than the given length. Otherwise, the line is returned
|
||||
// as is. If truncating occur, an ellipsis is inserted at
|
||||
// the end.
|
||||
// Handle properly terminal color escape code
|
||||
func TruncateMax(line string, length int) string {
|
||||
if length <= 0 {
|
||||
return "…"
|
||||
}
|
||||
|
||||
l := Len(line)
|
||||
if l <= length || l == 0 {
|
||||
return line
|
||||
}
|
||||
|
||||
cleaned, escapes := ExtractTermEscapes(line)
|
||||
truncated := runewidth.Truncate(cleaned, length-1, "")
|
||||
|
||||
return ApplyTermEscapes(truncated, escapes) + "…"
|
||||
}
|
407
vendor/github.com/MichaelMure/go-term-text/wrap.go
generated
vendored
407
vendor/github.com/MichaelMure/go-term-text/wrap.go
generated
vendored
@ -1,407 +0,0 @@
|
||||
package text
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/mattn/go-runewidth"
|
||||
)
|
||||
|
||||
// Force runewidth not to treat ambiguous runes as wide chars, so that things
|
||||
// like unicode ellipsis/up/down/left/right glyphs can have correct runewidth
|
||||
// and can be displayed correctly in terminals.
|
||||
func init() {
|
||||
runewidth.DefaultCondition.EastAsianWidth = false
|
||||
}
|
||||
|
||||
type wrapOpts struct {
|
||||
indent string
|
||||
pad string
|
||||
align Alignment
|
||||
}
|
||||
|
||||
// WrapOption is a functional option for the Wrap() function
|
||||
type WrapOption func(opts *wrapOpts)
|
||||
|
||||
// WrapPad configure the padding with a string for Wrap()
|
||||
func WrapPad(pad string) WrapOption {
|
||||
return func(opts *wrapOpts) {
|
||||
opts.pad = pad
|
||||
}
|
||||
}
|
||||
|
||||
// WrapPadded configure the padding with a number of space characters for Wrap()
|
||||
func WrapPadded(padLen int) WrapOption {
|
||||
return func(opts *wrapOpts) {
|
||||
opts.pad = strings.Repeat(" ", padLen)
|
||||
}
|
||||
}
|
||||
|
||||
// WrapPad configure the indentation on the first line for Wrap()
|
||||
func WrapIndent(indent string) WrapOption {
|
||||
return func(opts *wrapOpts) {
|
||||
opts.indent = indent
|
||||
}
|
||||
}
|
||||
|
||||
// WrapAlign configure the text alignment for Wrap()
|
||||
func WrapAlign(align Alignment) WrapOption {
|
||||
return func(opts *wrapOpts) {
|
||||
opts.align = align
|
||||
}
|
||||
}
|
||||
|
||||
// allWrapOpts compile the set of WrapOption into a final wrapOpts
|
||||
// from the default values.
|
||||
func allWrapOpts(opts []WrapOption) *wrapOpts {
|
||||
wrapOpts := &wrapOpts{
|
||||
indent: "",
|
||||
pad: "",
|
||||
align: NoAlign,
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(wrapOpts)
|
||||
}
|
||||
if wrapOpts.indent == "" {
|
||||
wrapOpts.indent = wrapOpts.pad
|
||||
}
|
||||
return wrapOpts
|
||||
}
|
||||
|
||||
// Wrap a text for a given line size.
|
||||
// Handle properly terminal color escape code
|
||||
// Options are accepted to configure things like indent, padding or alignment.
|
||||
// Return the wrapped text and the number of lines
|
||||
func Wrap(text string, lineWidth int, opts ...WrapOption) (string, int) {
|
||||
wrapOpts := allWrapOpts(opts)
|
||||
|
||||
if lineWidth <= 0 {
|
||||
return "", 1
|
||||
}
|
||||
|
||||
var lines []string
|
||||
nbLine := 0
|
||||
|
||||
if len(wrapOpts.indent) >= lineWidth {
|
||||
// fallback rendering
|
||||
lines = append(lines, strings.Repeat("⭬", lineWidth))
|
||||
nbLine++
|
||||
wrapOpts.indent = wrapOpts.pad
|
||||
}
|
||||
if len(wrapOpts.pad) >= lineWidth {
|
||||
// fallback rendering
|
||||
line := strings.Repeat("⭬", lineWidth)
|
||||
return strings.Repeat(line+"\n", 5), 5
|
||||
}
|
||||
|
||||
// Start with the indent
|
||||
padStr := wrapOpts.indent
|
||||
padLen := Len(wrapOpts.indent)
|
||||
|
||||
// tabs are formatted as 4 spaces
|
||||
text = strings.Replace(text, "\t", " ", -1)
|
||||
|
||||
// NOTE: text is first segmented into lines so that softwrapLine can handle.
|
||||
for i, line := range strings.Split(text, "\n") {
|
||||
// on the second line, use the padding instead
|
||||
if i == 1 {
|
||||
padStr = wrapOpts.pad
|
||||
padLen = Len(wrapOpts.pad)
|
||||
}
|
||||
|
||||
if line == "" || strings.TrimSpace(line) == "" {
|
||||
// nothing in the line, we just add the non-empty part of the padding
|
||||
lines = append(lines, strings.TrimRight(padStr, " "))
|
||||
nbLine++
|
||||
continue
|
||||
}
|
||||
|
||||
wrapped := softwrapLine(line, lineWidth-padLen)
|
||||
split := strings.Split(wrapped, "\n")
|
||||
|
||||
if i == 0 && len(split) > 1 {
|
||||
// the very first line got wrapped
|
||||
// that means we need to switch to the normal padding
|
||||
// use the first wrapped line, ignore everything else and
|
||||
// wrap the remaining of the line with the normal padding.
|
||||
|
||||
content := LineAlign(strings.TrimRight(split[0], " "), lineWidth-padLen, wrapOpts.align)
|
||||
lines = append(lines, padStr+content)
|
||||
nbLine++
|
||||
line = strings.TrimPrefix(line, split[0])
|
||||
line = strings.TrimLeft(line, " ")
|
||||
|
||||
padStr = wrapOpts.pad
|
||||
padLen = Len(wrapOpts.pad)
|
||||
wrapped = softwrapLine(line, lineWidth-padLen)
|
||||
split = strings.Split(wrapped, "\n")
|
||||
}
|
||||
|
||||
for j, seg := range split {
|
||||
if j == 0 {
|
||||
// keep the left padding of the wrapped line
|
||||
content := LineAlign(strings.TrimRight(seg, " "), lineWidth-padLen, wrapOpts.align)
|
||||
lines = append(lines, padStr+content)
|
||||
} else {
|
||||
content := LineAlign(strings.TrimSpace(seg), lineWidth-padLen, wrapOpts.align)
|
||||
lines = append(lines, padStr+content)
|
||||
}
|
||||
nbLine++
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(lines, "\n"), nbLine
|
||||
}
|
||||
|
||||
// WrapLeftPadded wrap a text for a given line size with a left padding.
|
||||
// Handle properly terminal color escape code
|
||||
func WrapLeftPadded(text string, lineWidth int, leftPad int) (string, int) {
|
||||
return Wrap(text, lineWidth, WrapPadded(leftPad))
|
||||
}
|
||||
|
||||
// WrapWithPad wrap a text for a given line size with a custom left padding
|
||||
// Handle properly terminal color escape code
|
||||
func WrapWithPad(text string, lineWidth int, pad string) (string, int) {
|
||||
return Wrap(text, lineWidth, WrapPad(pad))
|
||||
}
|
||||
|
||||
// WrapWithPad wrap a text for a given line size with a custom left padding
|
||||
// This function also align the result depending on the requested alignment.
|
||||
// Handle properly terminal color escape code
|
||||
func WrapWithPadAlign(text string, lineWidth int, pad string, align Alignment) (string, int) {
|
||||
return Wrap(text, lineWidth, WrapPad(pad), WrapAlign(align))
|
||||
}
|
||||
|
||||
// WrapWithPadIndent wrap a text for a given line size with a custom left padding
|
||||
// and a first line indent. The padding is not effective on the first line, indent
|
||||
// is used instead, which allow to implement indents and outdents.
|
||||
// Handle properly terminal color escape code
|
||||
func WrapWithPadIndent(text string, lineWidth int, indent string, pad string) (string, int) {
|
||||
return Wrap(text, lineWidth, WrapIndent(indent), WrapPad(pad))
|
||||
}
|
||||
|
||||
// WrapWithPadIndentAlign wrap a text for a given line size with a custom left padding
|
||||
// and a first line indent. The padding is not effective on the first line, indent
|
||||
// is used instead, which allow to implement indents and outdents.
|
||||
// This function also align the result depending on the requested alignment.
|
||||
// Handle properly terminal color escape code
|
||||
func WrapWithPadIndentAlign(text string, lineWidth int, indent string, pad string, align Alignment) (string, int) {
|
||||
return Wrap(text, lineWidth, WrapIndent(indent), WrapPad(pad), WrapAlign(align))
|
||||
}
|
||||
|
||||
// Break a line into several lines so that each line consumes at most
|
||||
// 'textWidth' cells. Lines break at groups of white spaces and multibyte
|
||||
// chars. Nothing is removed from the original text so that it behaves like a
|
||||
// softwrap.
|
||||
//
|
||||
// Required: The line shall not contain '\n'
|
||||
//
|
||||
// WRAPPING ALGORITHM: The line is broken into non-breakable chunks, then line
|
||||
// breaks ("\n") are inserted between these groups so that the total length
|
||||
// between breaks does not exceed the required width. Words that are longer than
|
||||
// the textWidth are broken into pieces no longer than textWidth.
|
||||
func softwrapLine(line string, textWidth int) string {
|
||||
escaped, escapes := ExtractTermEscapes(line)
|
||||
|
||||
chunks := segmentLine(escaped)
|
||||
// Reverse the chunk array so we can use it as a stack.
|
||||
for i, j := 0, len(chunks)-1; i < j; i, j = i+1, j-1 {
|
||||
chunks[i], chunks[j] = chunks[j], chunks[i]
|
||||
}
|
||||
|
||||
// for readability, minimal implementation of a stack:
|
||||
|
||||
pop := func() string {
|
||||
result := chunks[len(chunks)-1]
|
||||
chunks = chunks[:len(chunks)-1]
|
||||
return result
|
||||
}
|
||||
|
||||
push := func(chunk string) {
|
||||
chunks = append(chunks, chunk)
|
||||
}
|
||||
|
||||
peek := func() string {
|
||||
return chunks[len(chunks)-1]
|
||||
}
|
||||
|
||||
empty := func() bool {
|
||||
return len(chunks) == 0
|
||||
}
|
||||
|
||||
var out strings.Builder
|
||||
|
||||
// helper to write in the output while interleaving the escape
|
||||
// sequence at the correct places.
|
||||
// note: the final algorithm will add additional line break in the original
|
||||
// text. Those line break are *not* fed to this helper so the positions don't
|
||||
// need to be offset, which make the whole thing much easier.
|
||||
currPos := 0
|
||||
currItem := 0
|
||||
outputString := func(s string) {
|
||||
for _, r := range s {
|
||||
for currItem < len(escapes) && currPos == escapes[currItem].Pos {
|
||||
out.WriteString(escapes[currItem].Item)
|
||||
currItem++
|
||||
}
|
||||
out.WriteRune(r)
|
||||
currPos++
|
||||
}
|
||||
}
|
||||
|
||||
width := 0
|
||||
|
||||
for !empty() {
|
||||
wl := Len(peek())
|
||||
|
||||
if width+wl <= textWidth {
|
||||
// the chunk fit in the available space
|
||||
outputString(pop())
|
||||
width += wl
|
||||
if width == textWidth && !empty() {
|
||||
// only add line break when there is more chunk to come
|
||||
out.WriteRune('\n')
|
||||
width = 0
|
||||
}
|
||||
} else if wl > textWidth {
|
||||
// words too long for a full line are split to fill the remaining space.
|
||||
// But if the long words is the first non-space word in the middle of the
|
||||
// line, preceding spaces shall not be counted in word splitting.
|
||||
splitWidth := textWidth - width
|
||||
if strings.HasSuffix(out.String(), "\n"+strings.Repeat(" ", width)) {
|
||||
splitWidth += width
|
||||
}
|
||||
left, right := splitWord(pop(), splitWidth)
|
||||
// remainder is pushed back to the stack for next round
|
||||
push(right)
|
||||
outputString(left)
|
||||
out.WriteRune('\n')
|
||||
width = 0
|
||||
} else {
|
||||
// normal line overflow, we add a line break and try again
|
||||
out.WriteRune('\n')
|
||||
width = 0
|
||||
}
|
||||
}
|
||||
|
||||
// Don't forget the trailing escapes, if any.
|
||||
for currItem < len(escapes) && currPos >= escapes[currItem].Pos {
|
||||
out.WriteString(escapes[currItem].Item)
|
||||
currItem++
|
||||
}
|
||||
|
||||
return out.String()
|
||||
}
|
||||
|
||||
// Segment a line into chunks, where each chunk consists of chars with the same
|
||||
// type and is not breakable.
|
||||
func segmentLine(s string) []string {
|
||||
var chunks []string
|
||||
|
||||
var word string
|
||||
wordType := none
|
||||
flushWord := func() {
|
||||
chunks = append(chunks, word)
|
||||
word = ""
|
||||
wordType = none
|
||||
}
|
||||
|
||||
for _, r := range s {
|
||||
// A WIDE_CHAR itself constitutes a chunk.
|
||||
thisType := runeType(r)
|
||||
if thisType == wideChar {
|
||||
if wordType != none {
|
||||
flushWord()
|
||||
}
|
||||
chunks = append(chunks, string(r))
|
||||
continue
|
||||
}
|
||||
// Other type of chunks starts with a char of that type, and ends with a
|
||||
// char with different type or end of string.
|
||||
if thisType != wordType {
|
||||
if wordType != none {
|
||||
flushWord()
|
||||
}
|
||||
word = string(r)
|
||||
wordType = thisType
|
||||
} else {
|
||||
word += string(r)
|
||||
}
|
||||
}
|
||||
if word != "" {
|
||||
flushWord()
|
||||
}
|
||||
|
||||
return chunks
|
||||
}
|
||||
|
||||
type RuneType int
|
||||
|
||||
// Rune categories
|
||||
//
|
||||
// These categories are so defined that each category forms a non-breakable
|
||||
// chunk. It IS NOT the same as unicode code point categories.
|
||||
const (
|
||||
none RuneType = iota
|
||||
wideChar
|
||||
invisible
|
||||
shortUnicode
|
||||
space
|
||||
visibleAscii
|
||||
)
|
||||
|
||||
// Determine the category of a rune.
|
||||
func runeType(r rune) RuneType {
|
||||
rw := runewidth.RuneWidth(r)
|
||||
if rw > 1 {
|
||||
return wideChar
|
||||
} else if rw == 0 {
|
||||
return invisible
|
||||
} else if r > 127 {
|
||||
return shortUnicode
|
||||
} else if r == ' ' {
|
||||
return space
|
||||
} else {
|
||||
return visibleAscii
|
||||
}
|
||||
}
|
||||
|
||||
// splitWord split a word at the given length, while ignoring the terminal escape sequences
|
||||
func splitWord(word string, length int) (string, string) {
|
||||
runes := []rune(word)
|
||||
var result []rune
|
||||
added := 0
|
||||
escape := false
|
||||
|
||||
if length == 0 {
|
||||
return "", word
|
||||
}
|
||||
|
||||
for _, r := range runes {
|
||||
if r == '\x1b' {
|
||||
escape = true
|
||||
}
|
||||
|
||||
width := runewidth.RuneWidth(r)
|
||||
if width+added > length {
|
||||
// wide character made the length overflow
|
||||
break
|
||||
}
|
||||
|
||||
result = append(result, r)
|
||||
|
||||
if !escape {
|
||||
added += width
|
||||
if added >= length {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if r == 'm' {
|
||||
escape = false
|
||||
}
|
||||
}
|
||||
|
||||
leftover := runes[len(result):]
|
||||
|
||||
return string(result), string(leftover)
|
||||
}
|
5
vendor/github.com/agnivade/levenshtein/.gitignore
generated
vendored
5
vendor/github.com/agnivade/levenshtein/.gitignore
generated
vendored
@ -1,5 +0,0 @@
|
||||
coverage.txt
|
||||
fuzz/fuzz-fuzz.zip
|
||||
fuzz/corpus/corpus/*
|
||||
fuzz/corpus/suppressions/*
|
||||
fuzz/corpus/crashes/*
|
7
vendor/github.com/agnivade/levenshtein/.travis.yml
generated
vendored
7
vendor/github.com/agnivade/levenshtein/.travis.yml
generated
vendored
@ -1,7 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- tip
|
21
vendor/github.com/agnivade/levenshtein/License.txt
generated
vendored
21
vendor/github.com/agnivade/levenshtein/License.txt
generated
vendored
@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Agniva De Sarker
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
13
vendor/github.com/agnivade/levenshtein/Makefile
generated
vendored
13
vendor/github.com/agnivade/levenshtein/Makefile
generated
vendored
@ -1,13 +0,0 @@
|
||||
all: test install
|
||||
|
||||
install:
|
||||
go install
|
||||
|
||||
lint:
|
||||
gofmt -l -s -w . && go tool vet -all . && golint
|
||||
|
||||
test:
|
||||
go test -race -v -coverprofile=coverage.txt -covermode=atomic
|
||||
|
||||
bench:
|
||||
go test -run=XXX -bench=. -benchmem
|
57
vendor/github.com/agnivade/levenshtein/README.md
generated
vendored
57
vendor/github.com/agnivade/levenshtein/README.md
generated
vendored
@ -1,57 +0,0 @@
|
||||
levenshtein [![Build Status](https://travis-ci.org/agnivade/levenshtein.svg?branch=master)](https://travis-ci.org/agnivade/levenshtein) [![Go Report Card](https://goreportcard.com/badge/github.com/agnivade/levenshtein)](https://goreportcard.com/report/github.com/agnivade/levenshtein) [![GoDoc](https://godoc.org/github.com/agnivade/levenshtein?status.svg)](https://godoc.org/github.com/agnivade/levenshtein)
|
||||
===========
|
||||
|
||||
[Go](http://golang.org) package to calculate the [Levenshtein Distance](http://en.wikipedia.org/wiki/Levenshtein_distance)
|
||||
|
||||
The library is fully capable of working with non-ascii strings. But the strings are not normalized. That is left as a user-dependant use case. Please normalize the strings before passing it to the library if you have such a requirement.
|
||||
- https://blog.golang.org/normalization
|
||||
|
||||
Install
|
||||
-------
|
||||
|
||||
go get github.com/agnivade/levenshtein
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/agnivade/levenshtein"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s1 := "kitten"
|
||||
s2 := "sitting"
|
||||
distance := levenshtein.ComputeDistance(s1, s2)
|
||||
fmt.Printf("The distance between %s and %s is %d.\n", s1, s2, distance)
|
||||
// Output:
|
||||
// The distance between kitten and sitting is 3.
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Benchmarks
|
||||
----------
|
||||
|
||||
```
|
||||
name time/op
|
||||
Simple/ASCII-4 537ns ± 2%
|
||||
Simple/French-4 956ns ± 0%
|
||||
Simple/Nordic-4 1.95µs ± 1%
|
||||
Simple/Tibetan-4 1.53µs ± 2%
|
||||
|
||||
name alloc/op
|
||||
Simple/ASCII-4 96.0B ± 0%
|
||||
Simple/French-4 128B ± 0%
|
||||
Simple/Nordic-4 192B ± 0%
|
||||
Simple/Tibetan-4 144B ± 0%
|
||||
|
||||
name allocs/op
|
||||
Simple/ASCII-4 1.00 ± 0%
|
||||
Simple/French-4 1.00 ± 0%
|
||||
Simple/Nordic-4 1.00 ± 0%
|
||||
Simple/Tibetan-4 1.00 ± 0%
|
||||
```
|
1
vendor/github.com/agnivade/levenshtein/go.mod
generated
vendored
1
vendor/github.com/agnivade/levenshtein/go.mod
generated
vendored
@ -1 +0,0 @@
|
||||
module github.com/agnivade/levenshtein
|
71
vendor/github.com/agnivade/levenshtein/levenshtein.go
generated
vendored
71
vendor/github.com/agnivade/levenshtein/levenshtein.go
generated
vendored
@ -1,71 +0,0 @@
|
||||
// Package levenshtein is a Go implementation to calculate Levenshtein Distance.
|
||||
//
|
||||
// Implementation taken from
|
||||
// https://gist.github.com/andrei-m/982927#gistcomment-1931258
|
||||
package levenshtein
|
||||
|
||||
// ComputeDistance computes the levenshtein distance between the two
|
||||
// strings passed as an argument. The return value is the levenshtein distance
|
||||
//
|
||||
// Works on runes (Unicode code points) but does not normalize
|
||||
// the input strings. See https://blog.golang.org/normalization
|
||||
// and the golang.org/x/text/unicode/norm pacage.
|
||||
func ComputeDistance(a, b string) int {
|
||||
if a == b {
|
||||
return 0
|
||||
}
|
||||
|
||||
// We need to convert to []rune if the strings are non-ascii.
|
||||
// This could be avoided by using utf8.RuneCountInString
|
||||
// and then doing some juggling with rune indices.
|
||||
// The primary challenge is keeping track of the previous rune.
|
||||
// With a range loop, its not that easy. And with a for-loop
|
||||
// we need to keep track of the inter-rune width using utf8.DecodeRuneInString
|
||||
s1 := []rune(a)
|
||||
s2 := []rune(b)
|
||||
|
||||
// swap to save some memory O(min(a,b)) instead of O(a)
|
||||
if len(s1) > len(s2) {
|
||||
s1, s2 = s2, s1
|
||||
}
|
||||
lenS1 := len(s1)
|
||||
lenS2 := len(s2)
|
||||
|
||||
// init the row
|
||||
x := make([]int, lenS1+1)
|
||||
for i := 0; i <= lenS1; i++ {
|
||||
x[i] = i
|
||||
}
|
||||
|
||||
// fill in the rest
|
||||
for i := 1; i <= lenS2; i++ {
|
||||
prev := i
|
||||
var current int
|
||||
|
||||
for j := 1; j <= lenS1; j++ {
|
||||
|
||||
if s2[i-1] == s1[j-1] {
|
||||
current = x[j-1] // match
|
||||
} else {
|
||||
current = min(x[j-1]+1, prev+1, x[j]+1)
|
||||
}
|
||||
x[j-1] = prev
|
||||
prev = current
|
||||
}
|
||||
x[lenS1] = prev
|
||||
}
|
||||
return x[lenS1]
|
||||
}
|
||||
|
||||
func min(a, b, c int) int {
|
||||
if a < b {
|
||||
if a < c {
|
||||
return a
|
||||
}
|
||||
} else {
|
||||
if b < c {
|
||||
return b
|
||||
}
|
||||
}
|
||||
return c
|
||||
}
|
14
vendor/github.com/araddon/dateparse/.travis.yml
generated
vendored
14
vendor/github.com/araddon/dateparse/.travis.yml
generated
vendored
@ -1,14 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
|
||||
before_install:
|
||||
- go get -t -v ./...
|
||||
|
||||
script:
|
||||
- go test -race -coverprofile=coverage.txt -covermode=atomic
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user