diff --git a/go.mod b/go.mod
index 233fa36..8ef6d0e 100644
--- a/go.mod
+++ b/go.mod
@@ -17,7 +17,7 @@ require (
github.com/spf13/viper v1.11.0
github.com/stretchr/testify v1.7.1
github.com/swaggo/echo-swagger v1.3.0
- github.com/swaggo/swag v1.8.1
+ github.com/swaggo/swag v1.8.10
github.com/theflyingcodr/govalidator v0.1.3
github.com/theflyingcodr/lathos v0.0.6
github.com/theflyingcodr/sockets v0.0.12-beta
@@ -65,7 +65,7 @@ require (
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
- golang.org/x/tools v0.1.9 // indirect
+ golang.org/x/tools v0.1.12 // indirect
google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/ini.v1 v1.66.4 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
diff --git a/go.sum b/go.sum
index c48fee6..3101463 100644
--- a/go.sum
+++ b/go.sum
@@ -17,14 +17,30 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
+cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
+cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
+cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
+cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=
+cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=
+cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=
+cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
+cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
+cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
+cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
+cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
+cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
+cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
+cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=
+cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
+cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
@@ -38,35 +54,63 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
+github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
+github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
-github.com/agiledragon/gomonkey/v2 v2.3.1 h1:k+UnUY0EMNYUFUAQVETGY9uUTxjMdnUkP0ARyJS1zzs=
+github.com/Shopify/sarama v1.30.0/go.mod h1:zujlQQx1kzHsh4jfV1USnptCQrHAEZ2Hk8fTKCulPVs=
+github.com/Shopify/toxiproxy/v2 v2.1.6-0.20210914104332-15ea381dcdae/go.mod h1:/cvHQkZ1fst0EmZnA5dFtiQdWCNCFYzb+uE2vqVgvx0=
github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY=
+github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
+github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/appleboy/gofight/v2 v2.1.2 h1:VOy3jow4vIK8BRQJoC/I9muxyYlJ2yb9ht2hZoS3rf4=
+github.com/appleboy/gofight/v2 v2.1.2/go.mod h1:frW+U1QZEdDgixycTj4CygQ48yLTUhplt43+Wczp3rw=
+github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
+github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
+github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
+github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
+github.com/bitcoinsv/bsvd v0.0.0-20190609155523-4c29707f7173/go.mod h1:BZ1UcC9+tmcDEcdVXgpt13hMczwJxWzpAn68wNs7zRA=
+github.com/bitcoinsv/bsvutil v0.0.0-20181216182056-1d77cf353ea9/go.mod h1:p44KuNKUH5BC8uX4ONEODaHUR4+ibC8todEAOGQEJAM=
+github.com/casbin/casbin/v2 v2.51.1/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
+github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
+github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
@@ -74,12 +118,27 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
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/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
+github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
+github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
+github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
+github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
+github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
+github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
+github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
+github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
+github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@@ -105,14 +164,18 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
@@ -120,6 +183,8 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
+github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
+github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -135,8 +200,11 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -147,13 +215,18 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
+github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
@@ -164,26 +237,74 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
+github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
+github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
+github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
+github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
+github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
+github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0=
+github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
+github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
+github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
+github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
+github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
+github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
+github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
+github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
+github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
+github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
+github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
+github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
+github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
+github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
+github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
+github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
+github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
+github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
+github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
+github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
+github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
+github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
+github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc=
+github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
@@ -192,12 +313,17 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
+github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
+github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -210,8 +336,10 @@ github.com/labstack/echo/v4 v4.7.2/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20L
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
+github.com/libsv/go-bc v0.1.9/go.mod h1:55OsjWtvaIEXy4w02icUi2lIdThuwqkAiSeF4GPU5tw=
github.com/libsv/go-bc v0.1.10 h1:pe3CriFVcHauoQSk8rJeC3/7BOgTqfp33LBb0M4SSi8=
github.com/libsv/go-bc v0.1.10/go.mod h1:55OsjWtvaIEXy4w02icUi2lIdThuwqkAiSeF4GPU5tw=
+github.com/libsv/go-bk v0.1.5/go.mod h1:xbDkeFFpP0uyFaPLnP6TwaLpAsHaslZ0LftTdWlB6HI=
github.com/libsv/go-bk v0.1.6 h1:c9CiT5+64HRDbzxPl1v/oiFmbvWZTuUYqywCf+MBs/c=
github.com/libsv/go-bk v0.1.6/go.mod h1:khJboDoH18FPUaZlzRFKzlVN84d4YfdmlDtdX4LAjQA=
github.com/libsv/go-bt/v2 v2.1.0-beta.2 h1:oq6BQQtNeZiG/esfoY/7RyYF+dDj996xqNfvoQfH6n4=
@@ -227,18 +355,31 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
+github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
+github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
+github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
+github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
+github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
+github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
+github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -250,16 +391,29 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE=
+github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
+github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
+github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
+github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
+github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
+github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
+github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
+github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
+github.com/openzipkin/zipkin-go v0.4.0/go.mod h1:4c3sLeE8xjNqehmF5RpAFLPLJxXscc0R4l6Zg0P1tTQ=
github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U=
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
+github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM=
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml/v2 v2.0.0-beta.8 h1:dy81yyLYJDwMTifq24Oi/IslOslRrDSb3jwDggjz3Z0=
github.com/pelletier/go-toml/v2 v2.0.0-beta.8/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
+github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -267,10 +421,14 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
+github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
+github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
+github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34=
github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
@@ -280,6 +438,7 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
@@ -287,22 +446,31 @@ github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
+github.com/rabbitmq/amqp091-go v1.1.0/go.mod h1:ogQDLSOACsLPsIq0NpbtiifNZi2YOz0VTJ0kHRghqbM=
+github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc=
github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
+github.com/sagikazarmark/crypt v0.5.0/go.mod h1:l+nzl7KWh51rpzp2h7t4MZWyiEWdhNpOAnclKvg+mdA=
+github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
+github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
@@ -330,14 +498,17 @@ github.com/swaggo/echo-swagger v1.3.0/go.mod h1:snY6MlGK+pQAfJNEfX5qaOzt/QuM/WIN
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2 h1:+iNTcqQJy0OZ5jk6a5NLib47eqXK8uYcPX+O4+cBpEM=
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w=
github.com/swaggo/swag v1.7.9/go.mod h1:gZ+TJ2w/Ve1RwQsA2IRoSOTidHz6DX+PIG8GWvbnoLU=
-github.com/swaggo/swag v1.8.1 h1:JuARzFX1Z1njbCGz+ZytBR15TFJwF2Q7fu8puJHhQYI=
-github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ=
+github.com/swaggo/swag v1.8.10 h1:eExW4bFa52WOjqRzRD58bgWsWfdFJso50lpbeTcmTfo=
+github.com/swaggo/swag v1.8.10/go.mod h1:ezQVUUhly8dludpVk+/PuwJWvLLanB13ygV5Pr9enSk=
github.com/theflyingcodr/govalidator v0.1.3 h1:eU8P2xZrU2s1FjbtoVW6yDgXG+g2xDM9p3eNPLFKmSk=
github.com/theflyingcodr/govalidator v0.1.3/go.mod h1:E6v0mkRcAVMTa7pC8VkUOtoE8WQ9zQ4/fOwrvtwhOM0=
github.com/theflyingcodr/lathos v0.0.6 h1:xIHMZTinurvodmFOgvSGD+OrDhSj42+Xz+FOXYwEr18=
github.com/theflyingcodr/lathos v0.0.6/go.mod h1:68tGFEbAqAzydWDb1KEJZPQY57l3hH32GXO11Hf1zGQ=
github.com/theflyingcodr/sockets v0.0.12-beta h1:5x6+7rQtVN0bEhaWdRm10MMvYdp0DPbHe5sB40DlVBk=
github.com/theflyingcodr/sockets v0.0.12-beta/go.mod h1:lEfw9IoVkWJsuvi5ja5QuusFjfVvpocaJl0RP7iFLRY=
+github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
+github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
+github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
@@ -345,32 +516,56 @@ github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPU
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
+github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
+github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
+github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+go.etcd.io/etcd/api/v3 v3.5.2/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
+go.etcd.io/etcd/client/pkg/v3 v3.5.2/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
+go.etcd.io/etcd/client/v2 v2.305.2/go.mod h1:2D7ZejHVMIfog1221iLSYlQRzrtECw3kz4I4VAQm3qI=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
+go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
+go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
+go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
+go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
+golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
@@ -380,6 +575,7 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
+golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -393,6 +589,7 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
@@ -404,10 +601,12 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -420,6 +619,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -430,22 +630,34 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
+golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
+golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
+golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
+golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220728030405-41545e8bf201 h1:bvOltf3SADAfG05iRml8lAB3qjoEX5RCyN4K6G5v3N0=
golang.org/x/net v0.0.0-20220728030405-41545e8bf201/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -457,8 +669,17 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
+golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
+golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -470,8 +691,12 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -484,13 +709,21 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -509,22 +742,47 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -535,16 +793,20 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ=
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@@ -557,6 +819,7 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -581,6 +844,7 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
@@ -588,17 +852,29 @@ golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82u
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
-golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8=
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
+golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U=
+golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
+gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
+gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
+gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
@@ -618,6 +894,23 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
+google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
+google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
+google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
+google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
+google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
+google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=
+google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=
+google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
+google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
+google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
+google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=
+google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
+google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=
+google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=
+google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=
+google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=
+google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -648,6 +941,7 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
@@ -660,7 +954,42 @@ google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
+google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
+google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
+google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
+google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
+google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
+google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
+google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
+google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
+google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
+google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
+google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
+google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
+google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
+google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
+google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
+google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@@ -674,9 +1003,24 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
+google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
+google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
+google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
+google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
+google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
+google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
+google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
+google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
+google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
+google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
+google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -689,6 +1033,7 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
@@ -697,14 +1042,19 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4=
gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
@@ -720,5 +1070,6 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
diff --git a/vendor/github.com/swaggo/swag/.goreleaser.yml b/vendor/github.com/swaggo/swag/.goreleaser.yml
index 6ce3665..5efb7a1 100644
--- a/vendor/github.com/swaggo/swag/.goreleaser.yml
+++ b/vendor/github.com/swaggo/swag/.goreleaser.yml
@@ -7,9 +7,8 @@ build:
- amd64
- arm64
- 386
- ignore:
- - goos: darwin
- goarch: arm64
+ env:
+ - CGO_ENABLED=0
archives:
-
replacements:
diff --git a/vendor/github.com/swaggo/swag/Dockerfile b/vendor/github.com/swaggo/swag/Dockerfile
index 65746bd..170d0c6 100644
--- a/vendor/github.com/swaggo/swag/Dockerfile
+++ b/vendor/github.com/swaggo/swag/Dockerfile
@@ -1,7 +1,7 @@
# Dockerfile References: https://docs.docker.com/engine/reference/builder/
# Start from the latest golang base image
-FROM golang:1.17-alpine as builder
+FROM golang:1.18.3-alpine as builder
# Set the Current Working Directory inside the container
WORKDIR /app
diff --git a/vendor/github.com/swaggo/swag/Makefile b/vendor/github.com/swaggo/swag/Makefile
index fa679d8..d1a9817 100644
--- a/vendor/github.com/swaggo/swag/Makefile
+++ b/vendor/github.com/swaggo/swag/Makefile
@@ -13,7 +13,7 @@ GOPATH:=$(shell $(GOCMD) env GOPATH)
u := $(if $(update),-u)
BINARY_NAME:=swag
-PACKAGES:=$(shell $(GOLIST) github.com/swaggo/swag github.com/swaggo/swag/cmd/swag github.com/swaggo/swag/gen)
+PACKAGES:=$(shell $(GOLIST) github.com/swaggo/swag github.com/swaggo/swag/cmd/swag github.com/swaggo/swag/gen github.com/swaggo/swag/format)
GOFILES:=$(shell find . -name "*.go" -type f)
export GO111MODULE := on
@@ -63,9 +63,9 @@ deps:
$(GOGET) golang.org/x/tools/go/loader
.PHONY: devel-deps
-devel-deps:
+devel-deps:
GO111MODULE=off $(GOGET) -v -u \
- golang.org/x/lint/golint
+ golang.org/x/lint/golint
.PHONY: lint
lint: devel-deps
@@ -91,4 +91,4 @@ fmt-check:
.PHONY: view-covered
view-covered:
$(GOTEST) -coverprofile=cover.out $(TARGET)
- $(GOCMD) tool cover -html=cover.out
\ No newline at end of file
+ $(GOCMD) tool cover -html=cover.out
diff --git a/vendor/github.com/swaggo/swag/README.md b/vendor/github.com/swaggo/swag/README.md
index 8774db7..fb4a490 100644
--- a/vendor/github.com/swaggo/swag/README.md
+++ b/vendor/github.com/swaggo/swag/README.md
@@ -9,7 +9,7 @@
[](https://goreportcard.com/report/github.com/swaggo/swag)
[](https://codebeat.co/projects/github-com-swaggo-swag-master)
[](https://godoc.org/github.com/swaggo/swag)
-[](#backers)
+[](#backers)
[](#sponsors) [](https://app.fossa.io/projects/git%2Bgithub.com%2Fswaggo%2Fswag?ref=badge_shield)
[](https://github.com/swaggo/swag/releases)
@@ -29,8 +29,9 @@ Swag converts Go annotations to Swagger Documentation 2.0. We've created a varie
- [Examples](#examples)
- [Descriptions over multiple lines](#descriptions-over-multiple-lines)
- [User defined structure with an array type](#user-defined-structure-with-an-array-type)
+ - [Function scoped struct declaration](#function-scoped-struct-declaration)
- [Model composition in response](#model-composition-in-response)
- - [Add a headers in response](#add-a-headers-in-response)
+ - [Add a headers in response](#add-a-headers-in-response)
- [Use multiple path params](#use-multiple-path-params)
- [Example value of struct](#example-value-of-struct)
- [SchemaExample of body](#schemaexample-of-body)
@@ -51,12 +52,9 @@ Swag converts Go annotations to Swagger Documentation 2.0. We've created a varie
2. Download swag by using:
```sh
-$ go get -u github.com/swaggo/swag/cmd/swag
-
-# 1.16 or newer
$ go install github.com/swaggo/swag/cmd/swag@latest
```
-To build from source you need [Go](https://golang.org/dl/) (1.15 or newer).
+To build from source you need [Go](https://golang.org/dl/) (1.16 or newer).
Or download a pre-compiled binary from the [release page](https://github.com/swaggo/swag/releases).
@@ -87,6 +85,7 @@ USAGE:
swag init [command options] [arguments...]
OPTIONS:
+ --quiet, -q Make the logger quiet. (default: false)
--generalInfo value, -g value Go file path in which 'swagger general API Info' is written (default: "main.go")
--dir value, -d value Directories you want to parse,comma separated and general-info file must be in the first one (default: "./")
--exclude value Exclude directories and files when searching, comma separated
@@ -100,8 +99,11 @@ OPTIONS:
--parseInternal Parse go files in internal packages, disabled by default (default: false)
--generatedTime Generate timestamp at the top of docs.go, disabled by default (default: false)
--parseDepth value Dependency parse depth (default: 100)
+ --requiredByDefault Set validation required for all fields by default (default: false)
--instanceName value This parameter can be used to name different swagger document instances. It is optional.
--overridesFile value File to read global type overrides from. (default: ".swaggo")
+ --parseGoList Parse dependency via 'go list' (default: true)
+ --tags value, -t value A comma-separated list of tags to filter the APIs for which the documentation is generated.Special case if the tag is prefixed with the '!' character then the APIs with that tag will be excluded
--help, -h show help (default: false)
```
@@ -127,9 +129,12 @@ OPTIONS:
- [echo](http://github.com/swaggo/echo-swagger)
- [buffalo](https://github.com/swaggo/buffalo-swagger)
- [net/http](https://github.com/swaggo/http-swagger)
+- [gorilla/mux](https://github.com/swaggo/http-swagger)
+- [go-chi/chi](https://github.com/swaggo/http-swagger)
- [flamingo](https://github.com/i-love-flamingo/swagger)
-- [fiber](https://github.com/arsmn/fiber-swagger)
+- [fiber](https://github.com/gofiber/swagger)
- [atreugo](https://github.com/Nerzal/atreugo-swagger)
+- [hertz](https://github.com/hertz-contrib/swagger)
## How to use it with Gin
@@ -193,7 +198,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/swaggo/files"
"github.com/swaggo/gin-swagger"
-
+
"./docs" // docs is generated by Swag CLI, you have to import it.
)
@@ -212,7 +217,7 @@ func main() {
docs.SwaggerInfo.Host = "petstore.swagger.io"
docs.SwaggerInfo.BasePath = "/v2"
docs.SwaggerInfo.Schemes = []string{"http", "https"}
-
+
r := gin.New()
// use ginSwagger middleware to serve the API docs
@@ -298,10 +303,10 @@ $ swag init
## The swag formatter
-The Swag Comments can be automatically formatted, just like 'go fmt'.
+The Swag Comments can be automatically formatted, just like 'go fmt'.
Find the result of formatting [here](https://github.com/swaggo/swag/tree/master/example/celler).
-Usage:
+Usage:
```shell
swag fmt
```
@@ -311,6 +316,28 @@ Exclude folder:
swag fmt -d ./ --exclude ./internal
```
+When using `swag fmt`, you need to ensure that you have a doc comment for the function to ensure correct formatting.
+This is due to `swag fmt` indenting swag comments with tabs, which is only allowed *after* a standard doc comment.
+
+For example, use
+
+```go
+// ListAccounts lists all existing accounts
+//
+// @Summary List accounts
+// @Description get accounts
+// @Tags accounts
+// @Accept json
+// @Produce json
+// @Param q query string false "name search by q" Format(email)
+// @Success 200 {array} model.Account
+// @Failure 400 {object} httputil.HTTPError
+// @Failure 404 {object} httputil.HTTPError
+// @Failure 500 {object} httputil.HTTPError
+// @Router /accounts [get]
+func (c *Controller) ListAccounts(ctx *gin.Context) {
+```
+
## Implementation Status
[Swagger 2.0 document](https://swagger.io/docs/specification/2-0/basic-structure/)
@@ -444,21 +471,21 @@ Besides that, `swag` also accepts aliases for some MIME Types as follows:
| annotation | description | parameters | example |
|------------|-------------|------------|---------|
| securitydefinitions.basic | [Basic](https://swagger.io/docs/specification/2-0/authentication/basic-authentication/) auth. | | // @securityDefinitions.basic BasicAuth |
-| securitydefinitions.apikey | [API key](https://swagger.io/docs/specification/2-0/authentication/api-keys/) auth. | in, name | // @securityDefinitions.apikey ApiKeyAuth |
-| securitydefinitions.oauth2.application | [OAuth2 application](https://swagger.io/docs/specification/authentication/oauth2/) auth. | tokenUrl, scope | // @securitydefinitions.oauth2.application OAuth2Application |
-| securitydefinitions.oauth2.implicit | [OAuth2 implicit](https://swagger.io/docs/specification/authentication/oauth2/) auth. | authorizationUrl, scope | // @securitydefinitions.oauth2.implicit OAuth2Implicit |
-| securitydefinitions.oauth2.password | [OAuth2 password](https://swagger.io/docs/specification/authentication/oauth2/) auth. | tokenUrl, scope | // @securitydefinitions.oauth2.password OAuth2Password |
-| securitydefinitions.oauth2.accessCode | [OAuth2 access code](https://swagger.io/docs/specification/authentication/oauth2/) auth. | tokenUrl, authorizationUrl, scope | // @securitydefinitions.oauth2.accessCode OAuth2AccessCode |
-
-
-| parameters annotation | example |
-|-----------------------|----------------------------------------------------------|
-| in | // @in header |
-| name | // @name Authorization |
-| tokenUrl | // @tokenUrl https://example.com/oauth/token |
-| authorizationurl | // @authorizationurl https://example.com/oauth/authorize |
-| scope.hoge | // @scope.write Grants write access |
-
+| securitydefinitions.apikey | [API key](https://swagger.io/docs/specification/2-0/authentication/api-keys/) auth. | in, name, description | // @securityDefinitions.apikey ApiKeyAuth |
+| securitydefinitions.oauth2.application | [OAuth2 application](https://swagger.io/docs/specification/authentication/oauth2/) auth. | tokenUrl, scope, description | // @securitydefinitions.oauth2.application OAuth2Application |
+| securitydefinitions.oauth2.implicit | [OAuth2 implicit](https://swagger.io/docs/specification/authentication/oauth2/) auth. | authorizationUrl, scope, description | // @securitydefinitions.oauth2.implicit OAuth2Implicit |
+| securitydefinitions.oauth2.password | [OAuth2 password](https://swagger.io/docs/specification/authentication/oauth2/) auth. | tokenUrl, scope, description | // @securitydefinitions.oauth2.password OAuth2Password |
+| securitydefinitions.oauth2.accessCode | [OAuth2 access code](https://swagger.io/docs/specification/authentication/oauth2/) auth. | tokenUrl, authorizationUrl, scope, description | // @securitydefinitions.oauth2.accessCode OAuth2AccessCode |
+
+
+| parameters annotation | example |
+|---------------------------------|-------------------------------------------------------------------------|
+| in | // @in header |
+| name | // @name Authorization |
+| tokenUrl | // @tokenUrl https://example.com/oauth/token |
+| authorizationurl | // @authorizationurl https://example.com/oauth/authorize |
+| scope.hoge | // @scope.write Grants write access |
+| description | // @description OAuth protects our entity endpoints |
## Attribute
@@ -469,6 +496,7 @@ Besides that, `swag` also accepts aliases for some MIME Types as follows:
// @Param string query string false "string valid" minlength(5) maxlength(10)
// @Param int query int false "int valid" minimum(1) maximum(10)
// @Param default query string false "string default" default(A)
+// @Param example query string false "string example" example(string)
// @Param collection query []string false "string collection" collectionFormat(multi)
// @Param extensions query []string false "string collection" extensions(x-example=test,x-nullable)
```
@@ -477,7 +505,7 @@ It also works for the struct fields:
```go
type Foo struct {
- Bar string `minLength:"4" maxLength:"16"`
+ Bar string `minLength:"4" maxLength:"16" example:"random string"`
Baz int `minimum:"10" maximum:"20" default:"15"`
Qux []string `enums:"foo,bar,baz"`
}
@@ -487,7 +515,7 @@ type Foo struct {
Field Name | Type | Description
---|:---:|---
-validate | `string` | Determines the validation for the parameter. Possible values are: `required`.
+validate | `string` | Determines the validation for the parameter. Possible values are: `required,optional`.
default | * | Declares the value of the parameter that the server will use if none is provided, for example a "count" to control the number of results per page might default to 100 if not supplied by the client in the request. (Note: "default" has no meaning for required parameters.) See https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-6.2. Unlike JSON Schema this value MUST conform to the defined [`type`](#parameterType) for this parameter.
maximum | `number` | See https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.1.2.
minimum | `number` | See https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.1.3.
@@ -497,6 +525,7 @@ Field Name | Type | Description
enums | [\*] | See https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.5.1.
format | `string` | The extending format for the previously mentioned [`type`](#parameterType). See [Data Type Formats](https://swagger.io/specification/v2/#dataTypeFormat) for further details.
collectionFormat | `string` |Determines the format of the array if type array is used. Possible values are:
- `csv` - comma separated values `foo,bar`.
- `ssv` - space separated values `foo bar`.
- `tsv` - tab separated values `foo\tbar`.
- `pipes` - pipe separated values
foo|bar. - `multi` - corresponds to multiple parameter instances instead of multiple values for a single instance `foo=bar&foo=baz`. This is valid only for parameters [`in`](#parameterIn) "query" or "formData".
Default value is `csv`.
+example | * | Declares the example for the parameter value
extensions | `string` | Add extension to parameters.
### Future
@@ -512,7 +541,7 @@ Field Name | Type | Description
### Descriptions over multiple lines
-You can add descriptions spanning multiple lines in either the general api description or routes definitions like so:
+You can add descriptions spanning multiple lines in either the general api description or routes definitions like so:
```go
// @description This is the first line
@@ -535,6 +564,30 @@ type Account struct {
}
```
+
+### Function scoped struct declaration
+
+You can declare your request response structs inside a function body.
+You must have to follow the naming convention `.. `.
+
+```go
+package main
+
+// @Param request body main.MyHandler.request true "query params"
+// @Success 200 {object} main.MyHandler.response
+// @Router /test [post]
+func MyHandler() {
+ type request struct {
+ RequestField string
+ }
+
+ type response struct {
+ ResponseField string
+ }
+}
+```
+
+
### Model composition in response
```go
// JSONResult's data field will be overridden by the specific type proto.Order
@@ -561,7 +614,7 @@ type Order struct { //in `proto` package
@success 200 {object} jsonresult.JSONResult{data=[]string} "desc"
```
-- overriding multiple fields. field will be added if not exists
+- overriding multiple fields. field will be added if not exists
```go
@success 200 {object} jsonresult.JSONResult{data1=string,data2=[]string,data3=proto.Order,data4=[]proto.Order} "desc"
```
@@ -751,7 +804,7 @@ Rendered:
"id": "integer"
}
```
-
+
### Use swaggerignore tag to exclude a field
diff --git a/vendor/github.com/swaggo/swag/README_zh-CN.md b/vendor/github.com/swaggo/swag/README_zh-CN.md
index 75dbbce..173f865 100644
--- a/vendor/github.com/swaggo/swag/README_zh-CN.md
+++ b/vendor/github.com/swaggo/swag/README_zh-CN.md
@@ -47,13 +47,10 @@ Swag将Go的注释转换为Swagger2.0文档。我们为流行的 [Go Web Framewo
2. 使用如下命令下载swag:
```bash
-$ go get -u github.com/swaggo/swag/cmd/swag
-
-# 1.16 及以上版本
$ go install github.com/swaggo/swag/cmd/swag@latest
```
-从源码开始构建的话,需要有Go环境(1.15及以上版本)。
+从源码开始构建的话,需要有Go环境(1.16及以上版本)。
或者从github的release页面下载预编译好的二进制文件。
@@ -63,7 +60,7 @@ $ go install github.com/swaggo/swag/cmd/swag@latest
swag init
```
-确保导入了生成的`docs/docs.go`文件,这样特定的配置文件才会被初始化。如果通用API指数没有写在`main.go`中,可以使用`-g`标识符来告知swag。
+确保导入了生成的`docs/docs.go`文件,这样特定的配置文件才会被初始化。如果通用API注释没有写在`main.go`中,可以使用`-g`标识符来告知swag。
```bash
swag init -g http/api.go
@@ -123,6 +120,13 @@ OPTIONS:
- [echo](http://github.com/swaggo/echo-swagger)
- [buffalo](https://github.com/swaggo/buffalo-swagger)
- [net/http](https://github.com/swaggo/http-swagger)
+- [net/http](https://github.com/swaggo/http-swagger)
+- [gorilla/mux](https://github.com/swaggo/http-swagger)
+- [go-chi/chi](https://github.com/swaggo/http-swagger)
+- [flamingo](https://github.com/i-love-flamingo/swagger)
+- [fiber](https://github.com/gofiber/swagger)
+- [atreugo](https://github.com/Nerzal/atreugo-swagger)
+- [hertz](https://github.com/hertz-contrib/swagger)
## 如何与Gin集成
diff --git a/vendor/github.com/swaggo/swag/const.go b/vendor/github.com/swaggo/swag/const.go
new file mode 100644
index 0000000..1353b6d
--- /dev/null
+++ b/vendor/github.com/swaggo/swag/const.go
@@ -0,0 +1,566 @@
+package swag
+
+import (
+ "go/ast"
+ "go/token"
+ "reflect"
+ "strconv"
+ "strings"
+)
+
+// ConstVariable a model to record a const variable
+type ConstVariable struct {
+ Name *ast.Ident
+ Type ast.Expr
+ Value interface{}
+ Comment *ast.CommentGroup
+ File *ast.File
+ Pkg *PackageDefinitions
+}
+
+var escapedChars = map[uint8]uint8{
+ 'n': '\n',
+ 'r': '\r',
+ 't': '\t',
+ 'v': '\v',
+ '\\': '\\',
+ '"': '"',
+}
+
+// EvaluateEscapedChar parse escaped character
+func EvaluateEscapedChar(text string) rune {
+ if len(text) == 1 {
+ return rune(text[0])
+ }
+
+ if len(text) == 2 && text[0] == '\\' {
+ return rune(escapedChars[text[1]])
+ }
+
+ if len(text) == 6 && text[0:2] == "\\u" {
+ n, err := strconv.ParseInt(text[2:], 16, 32)
+ if err == nil {
+ return rune(n)
+ }
+ }
+
+ return 0
+}
+
+// EvaluateEscapedString parse escaped characters in string
+func EvaluateEscapedString(text string) string {
+ if !strings.ContainsRune(text, '\\') {
+ return text
+ }
+ result := make([]byte, 0, len(text))
+ for i := 0; i < len(text); i++ {
+ if text[i] == '\\' {
+ i++
+ if text[i] == 'u' {
+ i++
+ char, err := strconv.ParseInt(text[i:i+4], 16, 32)
+ if err == nil {
+ result = AppendUtf8Rune(result, rune(char))
+ }
+ i += 3
+ } else if c, ok := escapedChars[text[i]]; ok {
+ result = append(result, c)
+ }
+ } else {
+ result = append(result, text[i])
+ }
+ }
+ return string(result)
+}
+
+// EvaluateDataConversion evaluate the type a explicit type conversion
+func EvaluateDataConversion(x interface{}, typeName string) interface{} {
+ switch value := x.(type) {
+ case int:
+ switch typeName {
+ case "int":
+ return int(value)
+ case "byte":
+ return byte(value)
+ case "int8":
+ return int8(value)
+ case "int16":
+ return int16(value)
+ case "int32":
+ return int32(value)
+ case "int64":
+ return int64(value)
+ case "uint":
+ return uint(value)
+ case "uint8":
+ return uint8(value)
+ case "uint16":
+ return uint16(value)
+ case "uint32":
+ return uint32(value)
+ case "uint64":
+ return uint64(value)
+ case "rune":
+ return rune(value)
+ }
+ case uint:
+ switch typeName {
+ case "int":
+ return int(value)
+ case "byte":
+ return byte(value)
+ case "int8":
+ return int8(value)
+ case "int16":
+ return int16(value)
+ case "int32":
+ return int32(value)
+ case "int64":
+ return int64(value)
+ case "uint":
+ return uint(value)
+ case "uint8":
+ return uint8(value)
+ case "uint16":
+ return uint16(value)
+ case "uint32":
+ return uint32(value)
+ case "uint64":
+ return uint64(value)
+ case "rune":
+ return rune(value)
+ }
+ case int8:
+ switch typeName {
+ case "int":
+ return int(value)
+ case "byte":
+ return byte(value)
+ case "int8":
+ return int8(value)
+ case "int16":
+ return int16(value)
+ case "int32":
+ return int32(value)
+ case "int64":
+ return int64(value)
+ case "uint":
+ return uint(value)
+ case "uint8":
+ return uint8(value)
+ case "uint16":
+ return uint16(value)
+ case "uint32":
+ return uint32(value)
+ case "uint64":
+ return uint64(value)
+ case "rune":
+ return rune(value)
+ }
+ case uint8:
+ switch typeName {
+ case "int":
+ return int(value)
+ case "byte":
+ return byte(value)
+ case "int8":
+ return int8(value)
+ case "int16":
+ return int16(value)
+ case "int32":
+ return int32(value)
+ case "int64":
+ return int64(value)
+ case "uint":
+ return uint(value)
+ case "uint8":
+ return uint8(value)
+ case "uint16":
+ return uint16(value)
+ case "uint32":
+ return uint32(value)
+ case "uint64":
+ return uint64(value)
+ case "rune":
+ return rune(value)
+ }
+ case int16:
+ switch typeName {
+ case "int":
+ return int(value)
+ case "byte":
+ return byte(value)
+ case "int8":
+ return int8(value)
+ case "int16":
+ return int16(value)
+ case "int32":
+ return int32(value)
+ case "int64":
+ return int64(value)
+ case "uint":
+ return uint(value)
+ case "uint8":
+ return uint8(value)
+ case "uint16":
+ return uint16(value)
+ case "uint32":
+ return uint32(value)
+ case "uint64":
+ return uint64(value)
+ case "rune":
+ return rune(value)
+ }
+ case uint16:
+ switch typeName {
+ case "int":
+ return int(value)
+ case "byte":
+ return byte(value)
+ case "int8":
+ return int8(value)
+ case "int16":
+ return int16(value)
+ case "int32":
+ return int32(value)
+ case "int64":
+ return int64(value)
+ case "uint":
+ return uint(value)
+ case "uint8":
+ return uint8(value)
+ case "uint16":
+ return uint16(value)
+ case "uint32":
+ return uint32(value)
+ case "uint64":
+ return uint64(value)
+ case "rune":
+ return rune(value)
+ }
+ case int32:
+ switch typeName {
+ case "int":
+ return int(value)
+ case "byte":
+ return byte(value)
+ case "int8":
+ return int8(value)
+ case "int16":
+ return int16(value)
+ case "int32":
+ return int32(value)
+ case "int64":
+ return int64(value)
+ case "uint":
+ return uint(value)
+ case "uint8":
+ return uint8(value)
+ case "uint16":
+ return uint16(value)
+ case "uint32":
+ return uint32(value)
+ case "uint64":
+ return uint64(value)
+ case "rune":
+ return rune(value)
+ case "string":
+ return string(value)
+ }
+ case uint32:
+ switch typeName {
+ case "int":
+ return int(value)
+ case "byte":
+ return byte(value)
+ case "int8":
+ return int8(value)
+ case "int16":
+ return int16(value)
+ case "int32":
+ return int32(value)
+ case "int64":
+ return int64(value)
+ case "uint":
+ return uint(value)
+ case "uint8":
+ return uint8(value)
+ case "uint16":
+ return uint16(value)
+ case "uint32":
+ return uint32(value)
+ case "uint64":
+ return uint64(value)
+ case "rune":
+ return rune(value)
+ }
+ case int64:
+ switch typeName {
+ case "int":
+ return int(value)
+ case "byte":
+ return byte(value)
+ case "int8":
+ return int8(value)
+ case "int16":
+ return int16(value)
+ case "int32":
+ return int32(value)
+ case "int64":
+ return int64(value)
+ case "uint":
+ return uint(value)
+ case "uint8":
+ return uint8(value)
+ case "uint16":
+ return uint16(value)
+ case "uint32":
+ return uint32(value)
+ case "uint64":
+ return uint64(value)
+ case "rune":
+ return rune(value)
+ }
+ case uint64:
+ switch typeName {
+ case "int":
+ return int(value)
+ case "byte":
+ return byte(value)
+ case "int8":
+ return int8(value)
+ case "int16":
+ return int16(value)
+ case "int32":
+ return int32(value)
+ case "int64":
+ return int64(value)
+ case "uint":
+ return uint(value)
+ case "uint8":
+ return uint8(value)
+ case "uint16":
+ return uint16(value)
+ case "uint32":
+ return uint32(value)
+ case "uint64":
+ return uint64(value)
+ case "rune":
+ return rune(value)
+ }
+ case string:
+ switch typeName {
+ case "string":
+ return value
+ }
+ }
+ return nil
+}
+
+// EvaluateUnary evaluate the type and value of a unary expression
+func EvaluateUnary(x interface{}, operator token.Token, xtype ast.Expr) (interface{}, ast.Expr) {
+ switch operator {
+ case token.SUB:
+ switch value := x.(type) {
+ case int:
+ return -value, xtype
+ case int8:
+ return -value, xtype
+ case int16:
+ return -value, xtype
+ case int32:
+ return -value, xtype
+ case int64:
+ return -value, xtype
+ }
+ case token.XOR:
+ switch value := x.(type) {
+ case int:
+ return ^value, xtype
+ case int8:
+ return ^value, xtype
+ case int16:
+ return ^value, xtype
+ case int32:
+ return ^value, xtype
+ case int64:
+ return ^value, xtype
+ case uint:
+ return ^value, xtype
+ case uint8:
+ return ^value, xtype
+ case uint16:
+ return ^value, xtype
+ case uint32:
+ return ^value, xtype
+ case uint64:
+ return ^value, xtype
+ }
+ }
+ return nil, nil
+}
+
+// EvaluateBinary evaluate the type and value of a binary expression
+func EvaluateBinary(x, y interface{}, operator token.Token, xtype, ytype ast.Expr) (interface{}, ast.Expr) {
+ if operator == token.SHR || operator == token.SHL {
+ var rightOperand uint64
+ yValue := CanIntegerValue{reflect.ValueOf(y)}
+ if yValue.CanUint() {
+ rightOperand = yValue.Uint()
+ } else if yValue.CanInt() {
+ rightOperand = uint64(yValue.Int())
+ }
+
+ switch operator {
+ case token.SHL:
+ switch xValue := x.(type) {
+ case int:
+ return xValue << rightOperand, xtype
+ case int8:
+ return xValue << rightOperand, xtype
+ case int16:
+ return xValue << rightOperand, xtype
+ case int32:
+ return xValue << rightOperand, xtype
+ case int64:
+ return xValue << rightOperand, xtype
+ case uint:
+ return xValue << rightOperand, xtype
+ case uint8:
+ return xValue << rightOperand, xtype
+ case uint16:
+ return xValue << rightOperand, xtype
+ case uint32:
+ return xValue << rightOperand, xtype
+ case uint64:
+ return xValue << rightOperand, xtype
+ }
+ case token.SHR:
+ switch xValue := x.(type) {
+ case int:
+ return xValue >> rightOperand, xtype
+ case int8:
+ return xValue >> rightOperand, xtype
+ case int16:
+ return xValue >> rightOperand, xtype
+ case int32:
+ return xValue >> rightOperand, xtype
+ case int64:
+ return xValue >> rightOperand, xtype
+ case uint:
+ return xValue >> rightOperand, xtype
+ case uint8:
+ return xValue >> rightOperand, xtype
+ case uint16:
+ return xValue >> rightOperand, xtype
+ case uint32:
+ return xValue >> rightOperand, xtype
+ case uint64:
+ return xValue >> rightOperand, xtype
+ }
+ }
+ return nil, nil
+ }
+
+ evalType := xtype
+ if evalType == nil {
+ evalType = ytype
+ }
+
+ xValue := CanIntegerValue{reflect.ValueOf(x)}
+ yValue := CanIntegerValue{reflect.ValueOf(y)}
+ if xValue.Kind() == reflect.String && yValue.Kind() == reflect.String {
+ return xValue.String() + yValue.String(), evalType
+ }
+
+ var targetValue reflect.Value
+ if xValue.Kind() != reflect.Int {
+ targetValue = reflect.New(xValue.Type()).Elem()
+ } else {
+ targetValue = reflect.New(yValue.Type()).Elem()
+ }
+
+ switch operator {
+ case token.ADD:
+ if xValue.CanInt() && yValue.CanInt() {
+ targetValue.SetInt(xValue.Int() + yValue.Int())
+ } else if xValue.CanUint() && yValue.CanUint() {
+ targetValue.SetUint(xValue.Uint() + yValue.Uint())
+ } else if xValue.CanInt() && yValue.CanUint() {
+ targetValue.SetUint(uint64(xValue.Int()) + yValue.Uint())
+ } else if xValue.CanUint() && yValue.CanInt() {
+ targetValue.SetUint(xValue.Uint() + uint64(yValue.Int()))
+ }
+ case token.SUB:
+ if xValue.CanInt() && yValue.CanInt() {
+ targetValue.SetInt(xValue.Int() - yValue.Int())
+ } else if xValue.CanUint() && yValue.CanUint() {
+ targetValue.SetUint(xValue.Uint() - yValue.Uint())
+ } else if xValue.CanInt() && yValue.CanUint() {
+ targetValue.SetUint(uint64(xValue.Int()) - yValue.Uint())
+ } else if xValue.CanUint() && yValue.CanInt() {
+ targetValue.SetUint(xValue.Uint() - uint64(yValue.Int()))
+ }
+ case token.MUL:
+ if xValue.CanInt() && yValue.CanInt() {
+ targetValue.SetInt(xValue.Int() * yValue.Int())
+ } else if xValue.CanUint() && yValue.CanUint() {
+ targetValue.SetUint(xValue.Uint() * yValue.Uint())
+ } else if xValue.CanInt() && yValue.CanUint() {
+ targetValue.SetUint(uint64(xValue.Int()) * yValue.Uint())
+ } else if xValue.CanUint() && yValue.CanInt() {
+ targetValue.SetUint(xValue.Uint() * uint64(yValue.Int()))
+ }
+ case token.QUO:
+ if xValue.CanInt() && yValue.CanInt() {
+ targetValue.SetInt(xValue.Int() / yValue.Int())
+ } else if xValue.CanUint() && yValue.CanUint() {
+ targetValue.SetUint(xValue.Uint() / yValue.Uint())
+ } else if xValue.CanInt() && yValue.CanUint() {
+ targetValue.SetUint(uint64(xValue.Int()) / yValue.Uint())
+ } else if xValue.CanUint() && yValue.CanInt() {
+ targetValue.SetUint(xValue.Uint() / uint64(yValue.Int()))
+ }
+ case token.REM:
+ if xValue.CanInt() && yValue.CanInt() {
+ targetValue.SetInt(xValue.Int() % yValue.Int())
+ } else if xValue.CanUint() && yValue.CanUint() {
+ targetValue.SetUint(xValue.Uint() % yValue.Uint())
+ } else if xValue.CanInt() && yValue.CanUint() {
+ targetValue.SetUint(uint64(xValue.Int()) % yValue.Uint())
+ } else if xValue.CanUint() && yValue.CanInt() {
+ targetValue.SetUint(xValue.Uint() % uint64(yValue.Int()))
+ }
+ case token.AND:
+ if xValue.CanInt() && yValue.CanInt() {
+ targetValue.SetInt(xValue.Int() & yValue.Int())
+ } else if xValue.CanUint() && yValue.CanUint() {
+ targetValue.SetUint(xValue.Uint() & yValue.Uint())
+ } else if xValue.CanInt() && yValue.CanUint() {
+ targetValue.SetUint(uint64(xValue.Int()) & yValue.Uint())
+ } else if xValue.CanUint() && yValue.CanInt() {
+ targetValue.SetUint(xValue.Uint() & uint64(yValue.Int()))
+ }
+ case token.OR:
+ if xValue.CanInt() && yValue.CanInt() {
+ targetValue.SetInt(xValue.Int() | yValue.Int())
+ } else if xValue.CanUint() && yValue.CanUint() {
+ targetValue.SetUint(xValue.Uint() | yValue.Uint())
+ } else if xValue.CanInt() && yValue.CanUint() {
+ targetValue.SetUint(uint64(xValue.Int()) | yValue.Uint())
+ } else if xValue.CanUint() && yValue.CanInt() {
+ targetValue.SetUint(xValue.Uint() | uint64(yValue.Int()))
+ }
+ case token.XOR:
+ if xValue.CanInt() && yValue.CanInt() {
+ targetValue.SetInt(xValue.Int() ^ yValue.Int())
+ } else if xValue.CanUint() && yValue.CanUint() {
+ targetValue.SetUint(xValue.Uint() ^ yValue.Uint())
+ } else if xValue.CanInt() && yValue.CanUint() {
+ targetValue.SetUint(uint64(xValue.Int()) ^ yValue.Uint())
+ } else if xValue.CanUint() && yValue.CanInt() {
+ targetValue.SetUint(xValue.Uint() ^ uint64(yValue.Int()))
+ }
+ }
+ return targetValue.Interface(), evalType
+}
diff --git a/vendor/github.com/swaggo/swag/enums.go b/vendor/github.com/swaggo/swag/enums.go
new file mode 100644
index 0000000..38658f2
--- /dev/null
+++ b/vendor/github.com/swaggo/swag/enums.go
@@ -0,0 +1,13 @@
+package swag
+
+const (
+ enumVarNamesExtension = "x-enum-varnames"
+ enumCommentsExtension = "x-enum-comments"
+)
+
+// EnumValue a model to record an enum consts variable
+type EnumValue struct {
+ key string
+ Value interface{}
+ Comment string
+}
diff --git a/vendor/github.com/swaggo/swag/field_parser.go b/vendor/github.com/swaggo/swag/field_parser.go
index b5cf262..beee28a 100644
--- a/vendor/github.com/swaggo/swag/field_parser.go
+++ b/vendor/github.com/swaggo/swag/field_parser.go
@@ -13,7 +13,14 @@ import (
"github.com/go-openapi/spec"
)
-var _ FieldParser = &tagBaseFieldParser{}
+var _ FieldParser = &tagBaseFieldParser{p: nil, field: nil, tag: ""}
+
+const (
+ requiredLabel = "required"
+ optionalLabel = "optional"
+ swaggerTypeTag = "swaggertype"
+ swaggerIgnoreTag = "swaggerignore"
+)
type tagBaseFieldParser struct {
p *Parser
@@ -22,52 +29,57 @@ type tagBaseFieldParser struct {
}
func newTagBaseFieldParser(p *Parser, field *ast.Field) FieldParser {
- ps := &tagBaseFieldParser{
+ fieldParser := tagBaseFieldParser{
p: p,
field: field,
+ tag: "",
}
- if ps.field.Tag != nil {
- ps.tag = reflect.StructTag(strings.Replace(field.Tag.Value, "`", "", -1))
+ if fieldParser.field.Tag != nil {
+ fieldParser.tag = reflect.StructTag(strings.ReplaceAll(field.Tag.Value, "`", ""))
}
- return ps
+ return &fieldParser
}
-func (ps *tagBaseFieldParser) ShouldSkip() (bool, error) {
+func (ps *tagBaseFieldParser) ShouldSkip() bool {
// Skip non-exported fields.
- if !ast.IsExported(ps.field.Names[0].Name) {
- return true, nil
+ if ps.field.Names != nil && !ast.IsExported(ps.field.Names[0].Name) {
+ return true
}
if ps.field.Tag == nil {
- return false, nil
+ return false
}
- ignoreTag := ps.tag.Get("swaggerignore")
+ ignoreTag := ps.tag.Get(swaggerIgnoreTag)
if strings.EqualFold(ignoreTag, "true") {
- return true, nil
+ return true
}
// json:"tag,hoge"
- name := strings.TrimSpace(strings.Split(ps.tag.Get("json"), ",")[0])
+ name := strings.TrimSpace(strings.Split(ps.tag.Get(jsonTag), ",")[0])
if name == "-" {
- return true, nil
+ return true
}
- return false, nil
+ return false
}
func (ps *tagBaseFieldParser) FieldName() (string, error) {
var name string
if ps.field.Tag != nil {
// json:"tag,hoge"
- name = strings.TrimSpace(strings.Split(ps.tag.Get("json"), ",")[0])
+ name = strings.TrimSpace(strings.Split(ps.tag.Get(jsonTag), ",")[0])
if name != "" {
return name, nil
}
}
+ if ps.field.Names == nil {
+ return "", nil
+ }
+
switch ps.p.PropNamingStrategy {
case SnakeCase:
return toSnakeCase(ps.field.Names[0].Name), nil
@@ -79,34 +91,40 @@ func (ps *tagBaseFieldParser) FieldName() (string, error) {
}
func toSnakeCase(in string) string {
- runes := []rune(in)
- length := len(runes)
-
- var out []rune
- for i := 0; i < length; i++ {
- if i > 0 && unicode.IsUpper(runes[i]) &&
- ((i+1 < length && unicode.IsLower(runes[i+1])) || unicode.IsLower(runes[i-1])) {
+ var (
+ runes = []rune(in)
+ length = len(runes)
+ out []rune
+ )
+
+ for idx := 0; idx < length; idx++ {
+ if idx > 0 && unicode.IsUpper(runes[idx]) &&
+ ((idx+1 < length && unicode.IsLower(runes[idx+1])) || unicode.IsLower(runes[idx-1])) {
out = append(out, '_')
}
- out = append(out, unicode.ToLower(runes[i]))
+
+ out = append(out, unicode.ToLower(runes[idx]))
}
return string(out)
}
func toLowerCamelCase(in string) string {
- runes := []rune(in)
+ var flag bool
- var out []rune
- flag := false
+ out := make([]rune, len(in))
+
+ runes := []rune(in)
for i, curr := range runes {
if (i == 0 && unicode.IsUpper(curr)) || (flag && unicode.IsUpper(curr)) {
- out = append(out, unicode.ToLower(curr))
+ out[i] = unicode.ToLower(curr)
flag = true
- } else {
- out = append(out, curr)
- flag = false
+
+ continue
}
+
+ out[i] = curr
+ flag = false
}
return string(out)
@@ -117,7 +135,7 @@ func (ps *tagBaseFieldParser) CustomSchema() (*spec.Schema, error) {
return nil, nil
}
- typeTag := ps.tag.Get("swaggertype")
+ typeTag := ps.tag.Get(swaggerTypeTag)
if typeTag != "" {
return BuildCustomSchema(strings.Split(typeTag, ","))
}
@@ -126,7 +144,6 @@ func (ps *tagBaseFieldParser) CustomSchema() (*spec.Schema, error) {
}
type structField struct {
- desc string
schemaType string
arrayType string
formatType string
@@ -138,11 +155,8 @@ type structField struct {
maxItems *int64
minItems *int64
exampleValue interface{}
- defaultValue interface{}
- extensions map[string]interface{}
enums []interface{}
enumVarNames []interface{}
- readOnly bool
unique bool
}
@@ -155,198 +169,179 @@ func splitNotWrapped(s string, sep rune) []string {
'{': '}',
}
- result := make([]string, 0)
- current := ""
- var openCount = 0
- var openChar rune
+ var (
+ result = make([]string, 0)
+ current = strings.Builder{}
+ openCount = 0
+ openChar rune
+ )
+
for _, char := range s {
- if openChar == 0 && openCloseMap[char] != 0 {
+ switch {
+ case openChar == 0 && openCloseMap[char] != 0:
openChar = char
+
openCount++
- current += string(char)
- } else if char == openChar {
+
+ current.WriteRune(char)
+ case char == openChar:
openCount++
- current = current + string(char)
- } else if openCount > 0 && char == openCloseMap[openChar] {
+
+ current.WriteRune(char)
+ case openCount > 0 && char == openCloseMap[openChar]:
openCount--
- current += string(char)
- } else if openCount == 0 && char == sep {
- result = append(result, current)
+
+ current.WriteRune(char)
+ case openCount == 0 && char == sep:
+ result = append(result, current.String())
+
openChar = 0
- current = ""
- } else {
- current += string(char)
+
+ current = strings.Builder{}
+ default:
+ current.WriteRune(char)
}
}
- if current != "" {
- result = append(result, current)
+ if current.String() != "" {
+ result = append(result, current.String())
}
return result
}
+// ComplementSchema complement schema with field properties
func (ps *tagBaseFieldParser) ComplementSchema(schema *spec.Schema) error {
types := ps.p.GetSchemaTypePath(schema, 2)
if len(types) == 0 {
return fmt.Errorf("invalid type for field: %s", ps.field.Names[0])
}
+ if IsRefSchema(schema) {
+ var newSchema = spec.Schema{}
+ err := ps.complementSchema(&newSchema, types)
+ if err != nil {
+ return err
+ }
+ if !reflect.ValueOf(newSchema).IsZero() {
+ *schema = *(newSchema.WithAllOf(*schema))
+ }
+ return nil
+ }
+
+ return ps.complementSchema(schema, types)
+}
+
+// complementSchema complement schema with field properties
+func (ps *tagBaseFieldParser) complementSchema(schema *spec.Schema, types []string) error {
if ps.field.Tag == nil {
if ps.field.Doc != nil {
schema.Description = strings.TrimSpace(ps.field.Doc.Text())
}
+
if schema.Description == "" && ps.field.Comment != nil {
schema.Description = strings.TrimSpace(ps.field.Comment.Text())
}
+
return nil
}
- structField := &structField{
+ field := &structField{
schemaType: types[0],
formatType: ps.tag.Get(formatTag),
- readOnly: ps.tag.Get(readOnlyTag) == "true",
}
if len(types) > 1 && (types[0] == ARRAY || types[0] == OBJECT) {
- structField.arrayType = types[1]
+ field.arrayType = types[1]
}
- if ps.field.Doc != nil {
- structField.desc = strings.TrimSpace(ps.field.Doc.Text())
- }
- if structField.desc == "" && ps.field.Comment != nil {
- structField.desc = strings.TrimSpace(ps.field.Comment.Text())
- }
-
- jsonTag := ps.tag.Get(jsonTag)
- // json:"name,string" or json:",string"
+ jsonTagValue := ps.tag.Get(jsonTag)
- exampleTag, ok := ps.tag.Lookup(exampleTag)
- if ok {
- structField.exampleValue = exampleTag
- if !strings.Contains(jsonTag, ",string") {
- example, err := defineTypeOfExample(structField.schemaType, structField.arrayType, exampleTag)
- if err != nil {
- return err
- }
- structField.exampleValue = example
- }
+ bindingTagValue := ps.tag.Get(bindingTag)
+ if bindingTagValue != "" {
+ parseValidTags(bindingTagValue, field)
}
- bindingTag := ps.tag.Get(bindingTag)
- if bindingTag != "" {
- ps.parseValidTags(bindingTag, structField)
+ validateTagValue := ps.tag.Get(validateTag)
+ if validateTagValue != "" {
+ parseValidTags(validateTagValue, field)
}
- validateTag := ps.tag.Get(validateTag)
- if validateTag != "" {
- ps.parseValidTags(validateTag, structField)
- }
-
- extensionsTag := ps.tag.Get(extensionsTag)
- if extensionsTag != "" {
- structField.extensions = map[string]interface{}{}
- for _, val := range splitNotWrapped(extensionsTag, ',') {
- parts := strings.SplitN(val, "=", 2)
- if len(parts) == 2 {
- structField.extensions[parts[0]] = parts[1]
- } else {
- if len(parts[0]) > 0 && string(parts[0][0]) == "!" {
- structField.extensions[parts[0][1:]] = false
- } else {
- structField.extensions[parts[0]] = true
- }
- }
- }
- }
-
- enumsTag := ps.tag.Get(enumsTag)
- if enumsTag != "" {
- enumType := structField.schemaType
- if structField.schemaType == ARRAY {
- enumType = structField.arrayType
- }
-
- structField.enums = nil
- for _, e := range strings.Split(enumsTag, ",") {
- value, err := defineType(enumType, e)
- if err != nil {
- return err
- }
- structField.enums = append(structField.enums, value)
- }
- }
- varnamesTag := ps.tag.Get("x-enum-varnames")
- if varnamesTag != "" {
- if structField.extensions == nil {
- structField.extensions = map[string]interface{}{}
- }
- varNames := strings.Split(varnamesTag, ",")
- if len(varNames) != len(structField.enums) {
- return fmt.Errorf("invalid count of x-enum-varnames. expected %d, got %d", len(structField.enums), len(varNames))
- }
- structField.enumVarNames = nil
- for _, v := range varNames {
- structField.enumVarNames = append(structField.enumVarNames, v)
- }
- structField.extensions["x-enum-varnames"] = structField.enumVarNames
- }
- defaultTag := ps.tag.Get(defaultTag)
- if defaultTag != "" {
- value, err := defineType(structField.schemaType, defaultTag)
+ enumsTagValue := ps.tag.Get(enumsTag)
+ if enumsTagValue != "" {
+ err := parseEnumTags(enumsTagValue, field)
if err != nil {
return err
}
- structField.defaultValue = value
}
- if IsNumericType(structField.schemaType) || IsNumericType(structField.arrayType) {
+ if IsNumericType(field.schemaType) || IsNumericType(field.arrayType) {
maximum, err := getFloatTag(ps.tag, maximumTag)
if err != nil {
return err
}
+
if maximum != nil {
- structField.maximum = maximum
+ field.maximum = maximum
}
minimum, err := getFloatTag(ps.tag, minimumTag)
if err != nil {
return err
}
+
if minimum != nil {
- structField.minimum = minimum
+ field.minimum = minimum
}
multipleOf, err := getFloatTag(ps.tag, multipleOfTag)
if err != nil {
return err
}
+
if multipleOf != nil {
- structField.multipleOf = multipleOf
+ field.multipleOf = multipleOf
}
}
- if structField.schemaType == STRING || structField.arrayType == STRING {
- maxLength, err := getIntTag(ps.tag, "maxLength")
+ if field.schemaType == STRING || field.arrayType == STRING {
+ maxLength, err := getIntTag(ps.tag, maxLengthTag)
if err != nil {
return err
}
+
if maxLength != nil {
- structField.maxLength = maxLength
+ field.maxLength = maxLength
}
- minLength, err := getIntTag(ps.tag, "minLength")
+ minLength, err := getIntTag(ps.tag, minLengthTag)
if err != nil {
return err
}
+
if minLength != nil {
- structField.minLength = minLength
+ field.minLength = minLength
+ }
+ }
+
+ // json:"name,string" or json:",string"
+ exampleTagValue, ok := ps.tag.Lookup(exampleTag)
+ if ok {
+ field.exampleValue = exampleTagValue
+
+ if !strings.Contains(jsonTagValue, ",string") {
+ example, err := defineTypeOfExample(field.schemaType, field.arrayType, exampleTagValue)
+ if err != nil {
+ return err
+ }
+
+ field.exampleValue = example
}
}
// perform this after setting everything else (min, max, etc...)
- if strings.Contains(jsonTag, ",string") { // @encoding/json: "It applies only to fields of string, floating point, integer, or boolean types."
+ if strings.Contains(jsonTagValue, ",string") {
+ // @encoding/json: "It applies only to fields of string, floating point, integer, or boolean types."
defaultValues := map[string]string{
// Zero Values as string
STRING: "",
@@ -355,51 +350,98 @@ func (ps *tagBaseFieldParser) ComplementSchema(schema *spec.Schema) error {
NUMBER: "0",
}
- defaultValue, ok := defaultValues[structField.schemaType]
+ defaultValue, ok := defaultValues[field.schemaType]
if ok {
- structField.schemaType = STRING
+ field.schemaType = STRING
+ *schema = *PrimitiveSchema(field.schemaType)
- if structField.exampleValue == nil {
+ if field.exampleValue == nil {
// if exampleValue is not defined by the user,
// we will force an example with a correct value
// (eg: int->"0", bool:"false")
- structField.exampleValue = defaultValue
+ field.exampleValue = defaultValue
}
}
}
- if structField.schemaType == STRING && types[0] != STRING {
- *schema = *PrimitiveSchema(structField.schemaType)
+ if ps.field.Doc != nil {
+ schema.Description = strings.TrimSpace(ps.field.Doc.Text())
}
- schema.Description = structField.desc
- schema.ReadOnly = structField.readOnly
- if !reflect.ValueOf(schema.Ref).IsZero() && schema.ReadOnly {
- schema.AllOf = []spec.Schema{*spec.RefSchema(schema.Ref.String())}
- schema.Ref = spec.Ref{} // clear out existing ref
+ if schema.Description == "" && ps.field.Comment != nil {
+ schema.Description = strings.TrimSpace(ps.field.Comment.Text())
}
- schema.Default = structField.defaultValue
- schema.Example = structField.exampleValue
- if structField.schemaType != ARRAY {
- schema.Format = structField.formatType
+
+ schema.ReadOnly = ps.tag.Get(readOnlyTag) == "true"
+
+ defaultTagValue := ps.tag.Get(defaultTag)
+ if defaultTagValue != "" {
+ value, err := defineType(field.schemaType, defaultTagValue)
+ if err != nil {
+ return err
+ }
+
+ schema.Default = value
+ }
+
+ schema.Example = field.exampleValue
+
+ if field.schemaType != ARRAY {
+ schema.Format = field.formatType
+ }
+
+ extensionsTagValue := ps.tag.Get(extensionsTag)
+ if extensionsTagValue != "" {
+ schema.Extensions = setExtensionParam(extensionsTagValue)
+ }
+
+ varNamesTag := ps.tag.Get("x-enum-varnames")
+ if varNamesTag != "" {
+ varNames := strings.Split(varNamesTag, ",")
+ if len(varNames) != len(field.enums) {
+ return fmt.Errorf("invalid count of x-enum-varnames. expected %d, got %d", len(field.enums), len(varNames))
+ }
+
+ field.enumVarNames = nil
+
+ for _, v := range varNames {
+ field.enumVarNames = append(field.enumVarNames, v)
+ }
+
+ if field.schemaType == ARRAY {
+ // Add the var names in the items schema
+ if schema.Items.Schema.Extensions == nil {
+ schema.Items.Schema.Extensions = map[string]interface{}{}
+ }
+ schema.Items.Schema.Extensions[enumVarNamesExtension] = field.enumVarNames
+ } else {
+ // Add to top level schema
+ if schema.Extensions == nil {
+ schema.Extensions = map[string]interface{}{}
+ }
+ schema.Extensions[enumVarNamesExtension] = field.enumVarNames
+ }
}
- schema.Extensions = structField.extensions
+
eleSchema := schema
- if structField.schemaType == ARRAY {
+
+ if field.schemaType == ARRAY {
// For Array only
- schema.MaxItems = structField.maxItems
- schema.MinItems = structField.minItems
- schema.UniqueItems = structField.unique
+ schema.MaxItems = field.maxItems
+ schema.MinItems = field.minItems
+ schema.UniqueItems = field.unique
eleSchema = schema.Items.Schema
- eleSchema.Format = structField.formatType
- }
- eleSchema.Maximum = structField.maximum
- eleSchema.Minimum = structField.minimum
- eleSchema.MultipleOf = structField.multipleOf
- eleSchema.MaxLength = structField.maxLength
- eleSchema.MinLength = structField.minLength
- eleSchema.Enum = structField.enums
+ eleSchema.Format = field.formatType
+ }
+
+ eleSchema.Maximum = field.maximum
+ eleSchema.Minimum = field.minimum
+ eleSchema.MultipleOf = field.multipleOf
+ eleSchema.MaxLength = field.maxLength
+ eleSchema.MinLength = field.minLength
+ eleSchema.Enum = field.enums
+
return nil
}
@@ -439,8 +481,11 @@ func (ps *tagBaseFieldParser) IsRequired() (bool, error) {
bindingTag := ps.tag.Get(bindingTag)
if bindingTag != "" {
for _, val := range strings.Split(bindingTag, ",") {
- if val == "required" {
+ switch val {
+ case requiredLabel:
return true, nil
+ case optionalLabel:
+ return false, nil
}
}
}
@@ -448,36 +493,36 @@ func (ps *tagBaseFieldParser) IsRequired() (bool, error) {
validateTag := ps.tag.Get(validateTag)
if validateTag != "" {
for _, val := range strings.Split(validateTag, ",") {
- if val == "required" {
+ switch val {
+ case requiredLabel:
return true, nil
+ case optionalLabel:
+ return false, nil
}
}
}
- return false, nil
+ return ps.p.RequiredByDefault, nil
}
-func (ps *tagBaseFieldParser) parseValidTags(validTag string, sf *structField) {
+func parseValidTags(validTag string, sf *structField) {
// `validate:"required,max=10,min=1"`
// ps. required checked by IsRequired().
for _, val := range strings.Split(validTag, ",") {
var (
- valKey string
valValue string
+ keyVal = strings.Split(val, "=")
)
- kv := strings.Split(val, "=")
- switch len(kv) {
+
+ switch len(keyVal) {
case 1:
- valKey = kv[0]
case 2:
- valKey = kv[0]
- valValue = kv[1]
+ valValue = strings.ReplaceAll(strings.ReplaceAll(keyVal[1], utf8HexComma, ","), utf8Pipe, "|")
default:
continue
}
- valValue = strings.Replace(strings.Replace(valValue, utf8HexComma, ",", -1), utf8Pipe, "|", -1)
- switch valKey {
+ switch keyVal[0] {
case "max", "lte":
sf.setMax(valValue)
case "min", "gte":
@@ -497,6 +542,26 @@ func (ps *tagBaseFieldParser) parseValidTags(validTag string, sf *structField) {
}
}
+func parseEnumTags(enumTag string, field *structField) error {
+ enumType := field.schemaType
+ if field.schemaType == ARRAY {
+ enumType = field.arrayType
+ }
+
+ field.enums = nil
+
+ for _, e := range strings.Split(enumTag, ",") {
+ value, err := defineType(enumType, e)
+ if err != nil {
+ return err
+ }
+
+ field.enums = append(field.enums, value)
+ }
+
+ return nil
+}
+
func (sf *structField) setOneOf(valValue string) {
if len(sf.enums) != 0 {
return
@@ -513,6 +578,7 @@ func (sf *structField) setOneOf(valValue string) {
if err != nil {
continue
}
+
sf.enums = append(sf.enums, value)
}
}
@@ -522,6 +588,7 @@ func (sf *structField) setMin(valValue string) {
if err != nil {
return
}
+
switch sf.schemaType {
case INTEGER, NUMBER:
sf.minimum = &value
@@ -539,6 +606,7 @@ func (sf *structField) setMax(valValue string) {
if err != nil {
return
}
+
switch sf.schemaType {
case INTEGER, NUMBER:
sf.maximum = &value
@@ -558,25 +626,30 @@ const (
// These code copy from
// https://github.com/go-playground/validator/blob/d4271985b44b735c6f76abc7a06532ee997f9476/baked_in.go#L207
-// ---
+// ---.
var oneofValsCache = map[string][]string{}
var oneofValsCacheRWLock = sync.RWMutex{}
var splitParamsRegex = regexp.MustCompile(`'[^']*'|\S+`)
-func parseOneOfParam2(s string) []string {
+func parseOneOfParam2(param string) []string {
oneofValsCacheRWLock.RLock()
- values, ok := oneofValsCache[s]
+ values, ok := oneofValsCache[param]
oneofValsCacheRWLock.RUnlock()
+
if !ok {
oneofValsCacheRWLock.Lock()
- values = splitParamsRegex.FindAllString(s, -1)
+ values = splitParamsRegex.FindAllString(param, -1)
+
for i := 0; i < len(values); i++ {
- values[i] = strings.Replace(values[i], "'", "", -1)
+ values[i] = strings.ReplaceAll(values[i], "'", "")
}
- oneofValsCache[s] = values
+
+ oneofValsCache[param] = values
+
oneofValsCacheRWLock.Unlock()
}
+
return values
}
-// ---
+// ---.
diff --git a/vendor/github.com/swaggo/swag/formater.go b/vendor/github.com/swaggo/swag/formater.go
deleted file mode 100644
index 1c903f4..0000000
--- a/vendor/github.com/swaggo/swag/formater.go
+++ /dev/null
@@ -1,326 +0,0 @@
-package swag
-
-import (
- "bytes"
- "crypto/md5"
- "fmt"
- "go/ast"
- goparser "go/parser"
- "go/token"
- "io"
- "io/ioutil"
- "log"
- "os"
- "path/filepath"
- "regexp"
- "runtime"
- "strings"
- "text/tabwriter"
-)
-
-const splitTag = "&*"
-
-// Formater implements a formater for Go source files.
-type Formater struct {
- // debugging output goes here
- debug Debugger
-
- // excludes excludes dirs and files in SearchDir
- excludes map[string]struct{}
-
- mainFile string
-}
-
-// NewFormater create a new formater instance.
-func NewFormater() *Formater {
- formater := &Formater{
- debug: log.New(os.Stdout, "", log.LstdFlags),
- excludes: make(map[string]struct{}),
- }
- return formater
-}
-
-// FormatAPI format the swag comment.
-func (f *Formater) FormatAPI(searchDir, excludeDir, mainFile string) error {
- searchDirs := strings.Split(searchDir, ",")
- for _, searchDir := range searchDirs {
- if _, err := os.Stat(searchDir); os.IsNotExist(err) {
- return fmt.Errorf("dir: %s does not exist", searchDir)
- }
- }
- for _, fi := range strings.Split(excludeDir, ",") {
- fi = strings.TrimSpace(fi)
- if fi != "" {
- fi = filepath.Clean(fi)
- f.excludes[fi] = struct{}{}
- }
- }
-
- // parse main.go
- absMainAPIFilePath, err := filepath.Abs(filepath.Join(searchDirs[0], mainFile))
- if err != nil {
- return err
- }
- err = f.FormatMain(absMainAPIFilePath)
- if err != nil {
- return err
- }
- f.mainFile = mainFile
-
- err = f.formatMultiSearchDir(searchDirs)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func (f *Formater) formatMultiSearchDir(searchDirs []string) error {
- for _, searchDir := range searchDirs {
- f.debug.Printf("Format API Info, search dir:%s", searchDir)
-
- err := filepath.Walk(searchDir, f.visit)
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-func (f *Formater) visit(path string, fileInfo os.FileInfo, err error) error {
- if err := walkWith(f.excludes, false)(path, fileInfo); err != nil {
- return err
- } else if fileInfo.IsDir() {
- // skip if file is folder
- return nil
- }
-
- if strings.HasSuffix(strings.ToLower(path), "_test.go") || filepath.Ext(path) != ".go" {
- // skip if file not has suffix "*.go"
- return nil
- }
- if strings.HasSuffix(strings.ToLower(path), f.mainFile) {
- // skip main file
- return nil
- }
-
- err = f.FormatFile(path)
- if err != nil {
- return fmt.Errorf("ParseFile error:%+v", err)
- }
- return nil
-}
-
-// FormatMain format the main.go comment.
-func (f *Formater) FormatMain(mainFilepath string) error {
- fileSet := token.NewFileSet()
- astFile, err := goparser.ParseFile(fileSet, mainFilepath, nil, goparser.ParseComments)
- if err != nil {
- return fmt.Errorf("cannot format file, err: %w path : %s ", err, mainFilepath)
- }
- var (
- formatedComments = bytes.Buffer{}
- // CommentCache
- oldCommentsMap = make(map[string]string)
- )
-
- if astFile.Comments != nil {
- for _, comment := range astFile.Comments {
- formatFuncDoc(comment.List, &formatedComments, oldCommentsMap)
- }
- }
-
- return writeFormatedComments(mainFilepath, formatedComments, oldCommentsMap)
-}
-
-// FormatFile format the swag comment in go function.
-func (f *Formater) FormatFile(filepath string) error {
- fileSet := token.NewFileSet()
- astFile, err := goparser.ParseFile(fileSet, filepath, nil, goparser.ParseComments)
- if err != nil {
- return fmt.Errorf("cannot format file, err: %w path : %s ", err, filepath)
- }
-
- var (
- formatedComments = bytes.Buffer{}
- // CommentCache
- oldCommentsMap = make(map[string]string)
- )
-
- for _, astDescription := range astFile.Decls {
- astDeclaration, ok := astDescription.(*ast.FuncDecl)
- if ok && astDeclaration.Doc != nil && astDeclaration.Doc.List != nil {
- formatFuncDoc(astDeclaration.Doc.List, &formatedComments, oldCommentsMap)
- }
- }
-
- return writeFormatedComments(filepath, formatedComments, oldCommentsMap)
-}
-
-func writeFormatedComments(filepath string, formatedComments bytes.Buffer, oldCommentsMap map[string]string) error {
- // Replace the file
- // Read the file
- srcBytes, err := ioutil.ReadFile(filepath)
- if err != nil {
- return fmt.Errorf("cannot open file, err: %w path : %s ", err, filepath)
- }
- replaceSrc := string(srcBytes)
- newComments := strings.Split(formatedComments.String(), "\n")
- for _, e := range newComments {
- commentSplit := strings.Split(e, splitTag)
- if len(commentSplit) == 2 {
- commentHash, commentContent := commentSplit[0], commentSplit[1]
-
- if !isBlankComment(commentContent) {
- replaceSrc = strings.Replace(replaceSrc, oldCommentsMap[commentHash], commentContent, 1)
- }
- }
- }
- return writeBack(filepath, []byte(replaceSrc), srcBytes)
-}
-
-func formatFuncDoc(commentList []*ast.Comment, formatedComments io.Writer, oldCommentsMap map[string]string) {
- tabw := tabwriter.NewWriter(formatedComments, 0, 0, 2, ' ', 0)
-
- for _, comment := range commentList {
- commentLine := comment.Text
- if isSwagComment(commentLine) || isBlankComment(commentLine) {
- cmd5 := fmt.Sprintf("%x", md5.Sum([]byte(commentLine)))
-
- // Find the separator and replace to \t
- c := separatorFinder(commentLine, '\t')
- oldCommentsMap[cmd5] = commentLine
-
- // md5 + splitTag + srcCommentLine
- // eg. xxx&*@Description get struct array
- _, _ = fmt.Fprintln(tabw, cmd5+splitTag+c)
- }
- }
- // format by tabwriter
- _ = tabw.Flush()
-}
-
-// Check of @Param @Success @Failure @Response @Header
-var specialTagForSplit = map[string]byte{
- paramAttr: 1,
- successAttr: 1,
- failureAttr: 1,
- responseAttr: 1,
- headerAttr: 1,
-}
-
-var skipChar = map[byte]byte{
- '"': 1,
- '(': 1,
- '{': 1,
- '[': 1,
-}
-
-var skipCharEnd = map[byte]byte{
- '"': 1,
- ')': 1,
- '}': 1,
- ']': 1,
-}
-
-func separatorFinder(comment string, rp byte) string {
- commentBytes := []byte(comment)
- commentLine := strings.TrimSpace(strings.TrimLeft(comment, "/"))
- if len(commentLine) == 0 {
- return ""
- }
- attribute := strings.Fields(commentLine)[0]
- attrLen := strings.Index(comment, attribute) + len(attribute)
- attribute = strings.ToLower(attribute)
- var i = attrLen
-
- if _, ok := specialTagForSplit[attribute]; ok {
- var skipFlag bool
- for ; i < len(commentBytes); i++ {
- if !skipFlag && commentBytes[i] == ' ' {
- j := i
- for j < len(commentBytes) && commentBytes[j] == ' ' {
- j++
- }
- commentBytes = replaceRange(commentBytes, i, j, rp)
- }
- if _, ok := skipChar[commentBytes[i]]; ok && !skipFlag {
- skipFlag = true
- } else if _, ok := skipCharEnd[commentBytes[i]]; ok && skipFlag {
- skipFlag = false
- }
- }
- } else {
- for i < len(commentBytes) && commentBytes[i] == ' ' {
- i++
- }
- if i >= len(commentBytes) {
- return comment
- }
- commentBytes = replaceRange(commentBytes, attrLen, i, rp)
- }
- return string(commentBytes)
-}
-
-func replaceRange(s []byte, start, end int, new byte) []byte {
- if start > end || end < 1 {
- return s
- }
- if end > len(s) {
- end = len(s)
- }
- s = append(s[:start], s[end-1:]...)
- s[start] = new
- return s
-}
-
-var swagCommentExpression = regexp.MustCompile("@[A-z]+")
-
-func isSwagComment(comment string) bool {
- return swagCommentExpression.MatchString(strings.ToLower(comment))
-}
-
-func isBlankComment(comment string) bool {
- lc := strings.TrimSpace(comment)
- return len(lc) == 0
-}
-
-// writeBack write to file
-func writeBack(filepath string, src, old []byte) error {
- // make a temporary backup before overwriting original
- bakname, err := backupFile(filepath+".", old, 0644)
- if err != nil {
- return err
- }
- err = ioutil.WriteFile(filepath, src, 0644)
- if err != nil {
- _ = os.Rename(bakname, filepath)
- return err
- }
- _ = os.Remove(bakname)
- return nil
-}
-
-const chmodSupported = runtime.GOOS != "windows"
-
-// backupFile writes data to a new file named filename with permissions perm,
-// with edits[j].begin
+ })
+
+ for _, edit := range edits {
+ prefix := contents[:edit.begin]
+ suffix := contents[edit.end:]
+ contents = append(prefix, append(edit.replacement, suffix...)...)
+ }
+
+ return contents
+}
+
+// formatFuncDoc reformats the comment lines in commentList, and appends any
+// changes to the edit list.
+func formatFuncDoc(fileSet *token.FileSet, commentList []*ast.Comment, edits *edits) {
+ // Building the edit list to format a comment block is a two-step process.
+ // First, we iterate over each comment line looking for Swag attributes. In
+ // each one we find, we replace alignment whitespace with a tab character,
+ // then write the result into a tab writer.
+
+ linesToComments := make(map[int]int, len(commentList))
+
+ buffer := &bytes.Buffer{}
+ w := tabwriter.NewWriter(buffer, 1, 4, 1, '\t', 0)
+
+ for commentIndex, comment := range commentList {
+ text := comment.Text
+ if attr, body, found := swagComment(text); found {
+ formatted := "//\t" + attr
+ if body != "" {
+ formatted += "\t" + splitComment2(attr, body)
+ }
+ _, _ = fmt.Fprintln(w, formatted)
+ linesToComments[len(linesToComments)] = commentIndex
+ }
+ }
+
+ // Once we've loaded all of the comment lines to be aligned into the tab
+ // writer, flushing it causes the aligned text to be written out to the
+ // backing buffer.
+ _ = w.Flush()
+
+ // Now the second step: we iterate over the aligned comment lines that were
+ // written into the backing buffer, pair each one up to its original
+ // comment line, and use the combination to describe the edit that needs to
+ // be made to the original input.
+ formattedComments := bytes.Split(buffer.Bytes(), []byte("\n"))
+ for lineIndex, commentIndex := range linesToComments {
+ comment := commentList[commentIndex]
+ *edits = append(*edits, edit{
+ begin: fileSet.Position(comment.Pos()).Offset,
+ end: fileSet.Position(comment.End()).Offset,
+ replacement: formattedComments[lineIndex],
+ })
+ }
+}
+
+func splitComment2(attr, body string) string {
+ if specialTagForSplit[strings.ToLower(attr)] {
+ for i := 0; i < len(body); i++ {
+ if skipEnd, ok := skipChar[body[i]]; ok {
+ skipStart, n := body[i], 1
+ for i++; i < len(body); i++ {
+ if skipStart != skipEnd && body[i] == skipStart {
+ n++
+ } else if body[i] == skipEnd {
+ n--
+ if n == 0 {
+ break
+ }
+ }
+ }
+ } else if body[i] == ' ' || body[i] == '\t' {
+ j := i
+ for ; j < len(body) && (body[j] == ' ' || body[j] == '\t'); j++ {
+ }
+ body = replaceRange(body, i, j, "\t")
+ }
+ }
+ }
+ return body
+}
+
+func replaceRange(s string, start, end int, new string) string {
+ return s[:start] + new + s[end:]
+}
+
+var swagCommentLineExpression = regexp.MustCompile(`^\/\/\s+(@[\S.]+)\s*(.*)`)
+
+func swagComment(comment string) (string, string, bool) {
+ matches := swagCommentLineExpression.FindStringSubmatch(comment)
+ if matches == nil {
+ return "", "", false
+ }
+ return matches[1], matches[2], true
+}
diff --git a/vendor/github.com/swaggo/swag/generics.go b/vendor/github.com/swaggo/swag/generics.go
new file mode 100644
index 0000000..276c1f3
--- /dev/null
+++ b/vendor/github.com/swaggo/swag/generics.go
@@ -0,0 +1,348 @@
+//go:build go1.18
+// +build go1.18
+
+package swag
+
+import (
+ "errors"
+ "fmt"
+ "go/ast"
+ "strings"
+ "unicode"
+
+ "github.com/go-openapi/spec"
+)
+
+type genericTypeSpec struct {
+ ArrayDepth int
+ TypeSpec *TypeSpecDef
+ Name string
+}
+
+func (t *genericTypeSpec) TypeName() string {
+ if t.TypeSpec != nil {
+ return t.TypeSpec.TypeName()
+ }
+ return t.Name
+}
+
+func (pkgDefs *PackagesDefinitions) parametrizeGenericType(file *ast.File, original *TypeSpecDef, fullGenericForm string) *TypeSpecDef {
+ if original == nil || original.TypeSpec.TypeParams == nil || len(original.TypeSpec.TypeParams.List) == 0 {
+ return original
+ }
+
+ name, genericParams := splitGenericsTypeName(fullGenericForm)
+ if genericParams == nil {
+ return nil
+ }
+
+ genericParamTypeDefs := map[string]*genericTypeSpec{}
+ if len(genericParams) != len(original.TypeSpec.TypeParams.List) {
+ return nil
+ }
+
+ for i, genericParam := range genericParams {
+ arrayDepth := 0
+ for {
+ if len(genericParam) <= 2 || genericParam[:2] != "[]" {
+ break
+ }
+ genericParam = genericParam[2:]
+ arrayDepth++
+ }
+
+ typeDef := pkgDefs.FindTypeSpec(genericParam, file)
+ if typeDef != nil {
+ genericParam = typeDef.TypeName()
+ if _, ok := pkgDefs.uniqueDefinitions[genericParam]; !ok {
+ pkgDefs.uniqueDefinitions[genericParam] = typeDef
+ }
+ }
+
+ genericParamTypeDefs[original.TypeSpec.TypeParams.List[i].Names[0].Name] = &genericTypeSpec{
+ ArrayDepth: arrayDepth,
+ TypeSpec: typeDef,
+ Name: genericParam,
+ }
+ }
+
+ name = fmt.Sprintf("%s%s-", string(IgnoreNameOverridePrefix), original.TypeName())
+ var nameParts []string
+ for _, def := range original.TypeSpec.TypeParams.List {
+ if specDef, ok := genericParamTypeDefs[def.Names[0].Name]; ok {
+ var prefix = ""
+ if specDef.ArrayDepth == 1 {
+ prefix = "array_"
+ } else if specDef.ArrayDepth > 1 {
+ prefix = fmt.Sprintf("array%d_", specDef.ArrayDepth)
+ }
+ nameParts = append(nameParts, prefix+specDef.TypeName())
+ }
+ }
+
+ name += strings.Replace(strings.Join(nameParts, "-"), ".", "_", -1)
+
+ if typeSpec, ok := pkgDefs.uniqueDefinitions[name]; ok {
+ return typeSpec
+ }
+
+ parametrizedTypeSpec := &TypeSpecDef{
+ File: original.File,
+ PkgPath: original.PkgPath,
+ TypeSpec: &ast.TypeSpec{
+ Name: &ast.Ident{
+ Name: name,
+ NamePos: original.TypeSpec.Name.NamePos,
+ Obj: original.TypeSpec.Name.Obj,
+ },
+ Doc: original.TypeSpec.Doc,
+ Assign: original.TypeSpec.Assign,
+ },
+ }
+ pkgDefs.uniqueDefinitions[name] = parametrizedTypeSpec
+
+ parametrizedTypeSpec.TypeSpec.Type = pkgDefs.resolveGenericType(original.File, original.TypeSpec.Type, genericParamTypeDefs)
+
+ return parametrizedTypeSpec
+}
+
+// splitGenericsTypeName splits a generic struct name in his parts
+func splitGenericsTypeName(fullGenericForm string) (string, []string) {
+ //remove all spaces character
+ fullGenericForm = strings.Map(func(r rune) rune {
+ if unicode.IsSpace(r) {
+ return -1
+ }
+ return r
+ }, fullGenericForm)
+
+ // split only at the first '[' and remove the last ']'
+ if fullGenericForm[len(fullGenericForm)-1] != ']' {
+ return "", nil
+ }
+
+ genericParams := strings.SplitN(fullGenericForm[:len(fullGenericForm)-1], "[", 2)
+ if len(genericParams) == 1 {
+ return "", nil
+ }
+
+ // generic type name
+ genericTypeName := genericParams[0]
+
+ depth := 0
+ genericParams = strings.FieldsFunc(genericParams[1], func(r rune) bool {
+ if r == '[' {
+ depth++
+ } else if r == ']' {
+ depth--
+ } else if r == ',' && depth == 0 {
+ return true
+ }
+ return false
+ })
+ if depth != 0 {
+ return "", nil
+ }
+
+ return genericTypeName, genericParams
+}
+
+func (pkgDefs *PackagesDefinitions) getParametrizedType(genTypeSpec *genericTypeSpec) ast.Expr {
+ if genTypeSpec.TypeSpec != nil && strings.Contains(genTypeSpec.Name, ".") {
+ parts := strings.SplitN(genTypeSpec.Name, ".", 2)
+ return &ast.SelectorExpr{
+ X: &ast.Ident{Name: parts[0]},
+ Sel: &ast.Ident{Name: parts[1]},
+ }
+ }
+
+ //a primitive type name or a type name in current package
+ return &ast.Ident{Name: genTypeSpec.Name}
+}
+
+func (pkgDefs *PackagesDefinitions) resolveGenericType(file *ast.File, expr ast.Expr, genericParamTypeDefs map[string]*genericTypeSpec) ast.Expr {
+ switch astExpr := expr.(type) {
+ case *ast.Ident:
+ if genTypeSpec, ok := genericParamTypeDefs[astExpr.Name]; ok {
+ retType := pkgDefs.getParametrizedType(genTypeSpec)
+ for i := 0; i < genTypeSpec.ArrayDepth; i++ {
+ retType = &ast.ArrayType{Elt: retType}
+ }
+ return retType
+ }
+ case *ast.ArrayType:
+ return &ast.ArrayType{
+ Elt: pkgDefs.resolveGenericType(file, astExpr.Elt, genericParamTypeDefs),
+ Len: astExpr.Len,
+ Lbrack: astExpr.Lbrack,
+ }
+ case *ast.StarExpr:
+ return &ast.StarExpr{
+ Star: astExpr.Star,
+ X: pkgDefs.resolveGenericType(file, astExpr.X, genericParamTypeDefs),
+ }
+ case *ast.IndexExpr, *ast.IndexListExpr:
+ fullGenericName, _ := getGenericFieldType(file, expr, genericParamTypeDefs)
+ typeDef := pkgDefs.FindTypeSpec(fullGenericName, file)
+ if typeDef != nil {
+ return typeDef.TypeSpec.Name
+ }
+ case *ast.StructType:
+ newStructTypeDef := &ast.StructType{
+ Struct: astExpr.Struct,
+ Incomplete: astExpr.Incomplete,
+ Fields: &ast.FieldList{
+ Opening: astExpr.Fields.Opening,
+ Closing: astExpr.Fields.Closing,
+ },
+ }
+
+ for _, field := range astExpr.Fields.List {
+ newField := &ast.Field{
+ Type: field.Type,
+ Doc: field.Doc,
+ Names: field.Names,
+ Tag: field.Tag,
+ Comment: field.Comment,
+ }
+
+ newField.Type = pkgDefs.resolveGenericType(file, field.Type, genericParamTypeDefs)
+
+ newStructTypeDef.Fields.List = append(newStructTypeDef.Fields.List, newField)
+ }
+ return newStructTypeDef
+ }
+ return expr
+}
+
+func getExtendedGenericFieldType(file *ast.File, field ast.Expr, genericParamTypeDefs map[string]*genericTypeSpec) (string, error) {
+ switch fieldType := field.(type) {
+ case *ast.ArrayType:
+ fieldName, err := getExtendedGenericFieldType(file, fieldType.Elt, genericParamTypeDefs)
+ return "[]" + fieldName, err
+ case *ast.StarExpr:
+ return getExtendedGenericFieldType(file, fieldType.X, genericParamTypeDefs)
+ case *ast.Ident:
+ if genericParamTypeDefs != nil {
+ if typeSpec, ok := genericParamTypeDefs[fieldType.Name]; ok {
+ return typeSpec.Name, nil
+ }
+ }
+ if fieldType.Obj == nil {
+ return fieldType.Name, nil
+ }
+
+ tSpec := &TypeSpecDef{
+ File: file,
+ TypeSpec: fieldType.Obj.Decl.(*ast.TypeSpec),
+ PkgPath: file.Name.Name,
+ }
+ return tSpec.TypeName(), nil
+ default:
+ return getFieldType(file, field, genericParamTypeDefs)
+ }
+}
+
+func getGenericFieldType(file *ast.File, field ast.Expr, genericParamTypeDefs map[string]*genericTypeSpec) (string, error) {
+ var fullName string
+ var baseName string
+ var err error
+ switch fieldType := field.(type) {
+ case *ast.IndexListExpr:
+ baseName, err = getGenericTypeName(file, fieldType.X)
+ if err != nil {
+ return "", err
+ }
+ fullName = baseName + "["
+
+ for _, index := range fieldType.Indices {
+ fieldName, err := getExtendedGenericFieldType(file, index, genericParamTypeDefs)
+ if err != nil {
+ return "", err
+ }
+
+ fullName += fieldName + ","
+ }
+
+ fullName = strings.TrimRight(fullName, ",") + "]"
+ case *ast.IndexExpr:
+ baseName, err = getGenericTypeName(file, fieldType.X)
+ if err != nil {
+ return "", err
+ }
+
+ indexName, err := getExtendedGenericFieldType(file, fieldType.Index, genericParamTypeDefs)
+ if err != nil {
+ return "", err
+ }
+
+ fullName = fmt.Sprintf("%s[%s]", baseName, indexName)
+ }
+
+ if fullName == "" {
+ return "", fmt.Errorf("unknown field type %#v", field)
+ }
+
+ var packageName string
+ if !strings.Contains(baseName, ".") {
+ if file.Name == nil {
+ return "", errors.New("file name is nil")
+ }
+ packageName, _ = getFieldType(file, file.Name, genericParamTypeDefs)
+ }
+
+ return strings.TrimLeft(fmt.Sprintf("%s.%s", packageName, fullName), "."), nil
+}
+
+func getGenericTypeName(file *ast.File, field ast.Expr) (string, error) {
+ switch fieldType := field.(type) {
+ case *ast.Ident:
+ if fieldType.Obj == nil {
+ return fieldType.Name, nil
+ }
+
+ tSpec := &TypeSpecDef{
+ File: file,
+ TypeSpec: fieldType.Obj.Decl.(*ast.TypeSpec),
+ PkgPath: file.Name.Name,
+ }
+ return tSpec.TypeName(), nil
+ case *ast.ArrayType:
+ tSpec := &TypeSpecDef{
+ File: file,
+ TypeSpec: fieldType.Elt.(*ast.Ident).Obj.Decl.(*ast.TypeSpec),
+ PkgPath: file.Name.Name,
+ }
+ return tSpec.TypeName(), nil
+ case *ast.SelectorExpr:
+ return fmt.Sprintf("%s.%s", fieldType.X.(*ast.Ident).Name, fieldType.Sel.Name), nil
+ }
+ return "", fmt.Errorf("unknown type %#v", field)
+}
+
+func (parser *Parser) parseGenericTypeExpr(file *ast.File, typeExpr ast.Expr) (*spec.Schema, error) {
+ switch expr := typeExpr.(type) {
+ // suppress debug messages for these types
+ case *ast.InterfaceType:
+ case *ast.StructType:
+ case *ast.Ident:
+ case *ast.StarExpr:
+ case *ast.SelectorExpr:
+ case *ast.ArrayType:
+ case *ast.MapType:
+ case *ast.FuncType:
+ case *ast.IndexExpr:
+ name, err := getExtendedGenericFieldType(file, expr, nil)
+ if err == nil {
+ if schema, err := parser.getTypeSchema(name, file, false); err == nil {
+ return schema, nil
+ }
+ }
+
+ parser.debug.Printf("Type definition of type '%T' is not supported yet. Using 'object' instead. (%s)\n", typeExpr, err)
+ default:
+ parser.debug.Printf("Type definition of type '%T' is not supported yet. Using 'object' instead.\n", typeExpr)
+ }
+
+ return PrimitiveSchema(OBJECT), nil
+}
diff --git a/vendor/github.com/swaggo/swag/generics_other.go b/vendor/github.com/swaggo/swag/generics_other.go
new file mode 100644
index 0000000..5fd9e82
--- /dev/null
+++ b/vendor/github.com/swaggo/swag/generics_other.go
@@ -0,0 +1,42 @@
+//go:build !go1.18
+// +build !go1.18
+
+package swag
+
+import (
+ "fmt"
+ "github.com/go-openapi/spec"
+ "go/ast"
+)
+
+type genericTypeSpec struct {
+ ArrayDepth int
+ TypeSpec *TypeSpecDef
+ Name string
+}
+
+func (pkgDefs *PackagesDefinitions) parametrizeGenericType(file *ast.File, original *TypeSpecDef, fullGenericForm string) *TypeSpecDef {
+ return original
+}
+
+func getGenericFieldType(file *ast.File, field ast.Expr, genericParamTypeDefs map[string]*genericTypeSpec) (string, error) {
+ return "", fmt.Errorf("unknown field type %#v", field)
+}
+
+func (parser *Parser) parseGenericTypeExpr(file *ast.File, typeExpr ast.Expr) (*spec.Schema, error) {
+ switch typeExpr.(type) {
+ // suppress debug messages for these types
+ case *ast.InterfaceType:
+ case *ast.StructType:
+ case *ast.Ident:
+ case *ast.StarExpr:
+ case *ast.SelectorExpr:
+ case *ast.ArrayType:
+ case *ast.MapType:
+ case *ast.FuncType:
+ default:
+ parser.debug.Printf("Type definition of type '%T' is not supported yet. Using 'object' instead.\n", typeExpr)
+ }
+
+ return PrimitiveSchema(OBJECT), nil
+}
diff --git a/vendor/github.com/swaggo/swag/golist.go b/vendor/github.com/swaggo/swag/golist.go
new file mode 100644
index 0000000..ca916a8
--- /dev/null
+++ b/vendor/github.com/swaggo/swag/golist.go
@@ -0,0 +1,74 @@
+package swag
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "fmt"
+ "go/build"
+ "os/exec"
+ "path/filepath"
+)
+
+func listPackages(ctx context.Context, dir string, env []string, args ...string) (pkgs []*build.Package, finalErr error) {
+ cmd := exec.CommandContext(ctx, "go", append([]string{"list", "-json", "-e"}, args...)...)
+ cmd.Env = env
+ cmd.Dir = dir
+
+ stdout, err := cmd.StdoutPipe()
+ if err != nil {
+ return nil, err
+ }
+ var stderrBuf bytes.Buffer
+ cmd.Stderr = &stderrBuf
+ defer func() {
+ if stderrBuf.Len() > 0 {
+ finalErr = fmt.Errorf("%v\n%s", finalErr, stderrBuf.Bytes())
+ }
+ }()
+
+ err = cmd.Start()
+ if err != nil {
+ return nil, err
+ }
+ dec := json.NewDecoder(stdout)
+ for dec.More() {
+ var pkg build.Package
+ err = dec.Decode(&pkg)
+ if err != nil {
+ return nil, err
+ }
+ pkgs = append(pkgs, &pkg)
+ }
+ err = cmd.Wait()
+ if err != nil {
+ return nil, err
+ }
+ return pkgs, nil
+}
+
+func (parser *Parser) getAllGoFileInfoFromDepsByList(pkg *build.Package) error {
+ ignoreInternal := pkg.Goroot && !parser.ParseInternal
+ if ignoreInternal { // ignored internal
+ return nil
+ }
+
+ srcDir := pkg.Dir
+ var err error
+ for i := range pkg.GoFiles {
+ err = parser.parseFile(pkg.ImportPath, filepath.Join(srcDir, pkg.GoFiles[i]), nil, ParseModels)
+ if err != nil {
+ return err
+ }
+ }
+
+ // parse .go source files that import "C"
+ for i := range pkg.CgoFiles {
+ err = parser.parseFile(pkg.ImportPath, filepath.Join(srcDir, pkg.CgoFiles[i]), nil, ParseModels)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/swaggo/swag/operation.go b/vendor/github.com/swaggo/swag/operation.go
index 66d7ca5..8cadc62 100644
--- a/vendor/github.com/swaggo/swag/operation.go
+++ b/vendor/github.com/swaggo/swag/operation.go
@@ -6,7 +6,6 @@ import (
"go/ast"
goparser "go/parser"
"go/token"
- "io/ioutil"
"net/http"
"os"
"path/filepath"
@@ -62,8 +61,23 @@ func NewOperation(parser *Parser, options ...func(*Operation)) *Operation {
RouterProperties: []RouteProperties{},
Operation: spec.Operation{
OperationProps: spec.OperationProps{
+ ID: "",
+ Description: "",
+ Summary: "",
+ Security: nil,
+ ExternalDocs: nil,
+ Deprecated: false,
+ Tags: []string{},
+ Consumes: []string{},
+ Produces: []string{},
+ Schemes: []string{},
+ Parameters: []spec.Parameter{},
Responses: &spec.Responses{
+ VendorExtensible: spec.VendorExtensible{
+ Extensions: spec.Extensions{},
+ },
ResponsesProps: spec.ResponsesProps{
+ Default: nil,
StatusCodeResponses: make(map[int]spec.Response),
},
},
@@ -72,6 +86,7 @@ func NewOperation(parser *Parser, options ...func(*Operation)) *Operation {
Extensions: spec.Extensions{},
},
},
+ codeExampleFilesDir: "",
}
for _, option := range options {
@@ -94,11 +109,14 @@ func (operation *Operation) ParseComment(comment string, astFile *ast.File) erro
if len(commentLine) == 0 {
return nil
}
- attribute := strings.Fields(commentLine)[0]
- lineRemainder := strings.TrimSpace(commentLine[len(attribute):])
- lowerAttribute := strings.ToLower(attribute)
- var err error
+ fields := FieldsByAnySpace(commentLine, 2)
+ attribute := fields[0]
+ lowerAttribute := strings.ToLower(attribute)
+ var lineRemainder string
+ if len(fields) > 1 {
+ lineRemainder = fields[1]
+ }
switch lowerAttribute {
case descriptionAttr:
operation.ParseDescriptionComment(lineRemainder)
@@ -107,6 +125,7 @@ func (operation *Operation) ParseComment(comment string, astFile *ast.File) erro
if err != nil {
return err
}
+
operation.ParseDescriptionComment(string(commentInfo))
case summaryAttr:
operation.Summary = lineRemainder
@@ -115,28 +134,28 @@ func (operation *Operation) ParseComment(comment string, astFile *ast.File) erro
case tagsAttr:
operation.ParseTagsComment(lineRemainder)
case acceptAttr:
- err = operation.ParseAcceptComment(lineRemainder)
+ return operation.ParseAcceptComment(lineRemainder)
case produceAttr:
- err = operation.ParseProduceComment(lineRemainder)
+ return operation.ParseProduceComment(lineRemainder)
case paramAttr:
- err = operation.ParseParamComment(lineRemainder, astFile)
+ return operation.ParseParamComment(lineRemainder, astFile)
case successAttr, failureAttr, responseAttr:
- err = operation.ParseResponseComment(lineRemainder, astFile)
+ return operation.ParseResponseComment(lineRemainder, astFile)
case headerAttr:
- err = operation.ParseResponseHeaderComment(lineRemainder, astFile)
+ return operation.ParseResponseHeaderComment(lineRemainder, astFile)
case routerAttr:
- err = operation.ParseRouterComment(lineRemainder)
+ return operation.ParseRouterComment(lineRemainder)
case securityAttr:
- err = operation.ParseSecurityComment(lineRemainder)
+ return operation.ParseSecurityComment(lineRemainder)
case deprecatedAttr:
operation.Deprecate()
case xCodeSamplesAttr:
- err = operation.ParseCodeSample(attribute, commentLine, lineRemainder)
+ return operation.ParseCodeSample(attribute, commentLine, lineRemainder)
default:
- err = operation.ParseMetadata(attribute, lowerAttribute, lineRemainder)
+ return operation.ParseMetadata(attribute, lowerAttribute, lineRemainder)
}
- return err
+ return nil
}
// ParseCodeSample godoc.
@@ -148,6 +167,7 @@ func (operation *Operation) ParseCodeSample(attribute, _, lineRemainder string)
}
var valueJSON interface{}
+
err = json.Unmarshal(data, &valueJSON)
if err != nil {
return fmt.Errorf("annotation %s need a valid json value", attribute)
@@ -170,6 +190,7 @@ func (operation *Operation) ParseDescriptionComment(lineRemainder string) {
return
}
+
operation.Description += "\n" + lineRemainder
}
@@ -182,6 +203,7 @@ func (operation *Operation) ParseMetadata(attribute, lowerAttribute, lineRemaind
}
var valueJSON interface{}
+
err := json.Unmarshal([]byte(lineRemainder), &valueJSON)
if err != nil {
return fmt.Errorf("annotation %s need a valid json value", attribute)
@@ -194,7 +216,7 @@ func (operation *Operation) ParseMetadata(attribute, lowerAttribute, lineRemaind
return nil
}
-var paramPattern = regexp.MustCompile(`(\S+)[\s]+([\w]+)[\s]+([\S.]+)[\s]+([\w]+)[\s]+"([^"]+)"`)
+var paramPattern = regexp.MustCompile(`(\S+)\s+(\w+)\s+([\S. ]+?)\s+(\w+)\s+"([^"]+)"`)
func findInSlice(arr []string, target string) bool {
for _, str := range arr {
@@ -206,38 +228,25 @@ func findInSlice(arr []string, target string) bool {
return false
}
-func (operation *Operation) parseArrayParam(param *spec.Parameter, paramType, refType, objectType string) error {
- if !IsPrimitiveType(refType) {
- return fmt.Errorf("%s is not supported array type for %s", refType, paramType)
- }
- param.SimpleSchema.Type = objectType
- if operation.parser != nil {
- param.CollectionFormat = TransToValidCollectionFormat(operation.parser.collectionFormatInQuery)
- }
- param.SimpleSchema.Items = &spec.Items{
- SimpleSchema: spec.SimpleSchema{
- Type: refType,
- },
- }
-
- return nil
-}
-
// ParseParamComment parses params return []string of param properties
// E.g. @Param queryText formData string true "The email for login"
-// [param name] [paramType] [data type] [is mandatory?] [Comment]
+//
+// [param name] [paramType] [data type] [is mandatory?] [Comment]
+//
// E.g. @Param some_id path int true "Some ID".
func (operation *Operation) ParseParamComment(commentLine string, astFile *ast.File) error {
matches := paramPattern.FindStringSubmatch(commentLine)
if len(matches) != 6 {
return fmt.Errorf("missing required param comment parameters \"%s\"", commentLine)
}
+
name := matches[1]
paramType := matches[2]
refType := TransToValidSchemeType(matches[3])
// Detect refType
objectType := OBJECT
+
if strings.HasPrefix(refType, "[]") {
objectType = ARRAY
refType = strings.TrimPrefix(refType, "[]")
@@ -247,19 +256,30 @@ func (operation *Operation) ParseParamComment(commentLine string, astFile *ast.F
objectType = PRIMITIVE
}
+ var enums []interface{}
+ if !IsPrimitiveType(refType) {
+ schema, _ := operation.parser.getTypeSchema(refType, astFile, false)
+ if schema != nil && len(schema.Type) == 1 && schema.Enum != nil {
+ if objectType == OBJECT {
+ objectType = PRIMITIVE
+ }
+ refType = TransToValidSchemeType(schema.Type[0])
+ enums = schema.Enum
+ }
+ }
+
requiredText := strings.ToLower(matches[4])
- required := requiredText == "true" || requiredText == "required"
+ required := requiredText == "true" || requiredText == requiredLabel
description := matches[5]
- param := createParameter(paramType, description, name, refType, required)
+ param := createParameter(paramType, description, name, objectType, refType, required, enums, operation.parser.collectionFormatInQuery)
switch paramType {
case "path", "header":
switch objectType {
case ARRAY:
- err := operation.parseArrayParam(¶m, paramType, refType, objectType)
- if err != nil {
- return err
+ if !IsPrimitiveType(refType) {
+ return fmt.Errorf("%s is not supported array type for %s", refType, paramType)
}
case OBJECT:
return fmt.Errorf("%s is not supported type for %s", refType, paramType)
@@ -267,48 +287,43 @@ func (operation *Operation) ParseParamComment(commentLine string, astFile *ast.F
case "query", "formData":
switch objectType {
case ARRAY:
- err := operation.parseArrayParam(¶m, paramType, refType, objectType)
- if err != nil {
- return err
+ if !IsPrimitiveType(refType) && !(refType == "file" && paramType == "formData") {
+ return fmt.Errorf("%s is not supported array type for %s", refType, paramType)
}
+ case PRIMITIVE:
+ break
case OBJECT:
schema, err := operation.parser.getTypeSchema(refType, astFile, false)
if err != nil {
return err
}
+
if len(schema.Properties) == 0 {
return nil
}
items := schema.Properties.ToOrderedSchemaItems()
+
for _, item := range items {
- name := item.Name
- prop := item.Schema
+ name, prop := item.Name, item.Schema
if len(prop.Type) == 0 {
continue
}
+
switch {
- case prop.Type[0] == ARRAY &&
- prop.Items.Schema != nil &&
- len(prop.Items.Schema.Type) > 0 &&
- IsSimplePrimitiveType(prop.Items.Schema.Type[0]):
- param = createParameter(paramType, prop.Description, name, prop.Type[0], findInSlice(schema.Required, name))
- param.SimpleSchema.Type = prop.Type[0]
- if operation.parser != nil && operation.parser.collectionFormatInQuery != "" && param.CollectionFormat == "" {
- param.CollectionFormat = TransToValidCollectionFormat(operation.parser.collectionFormatInQuery)
- }
- param.SimpleSchema.Items = &spec.Items{
- SimpleSchema: spec.SimpleSchema{
- Type: prop.Items.Schema.Type[0],
- },
- }
+ case prop.Type[0] == ARRAY && prop.Items.Schema != nil &&
+ len(prop.Items.Schema.Type) > 0 && IsSimplePrimitiveType(prop.Items.Schema.Type[0]):
+
+ param = createParameter(paramType, prop.Description, name, prop.Type[0], prop.Items.Schema.Type[0], findInSlice(schema.Required, name), enums, operation.parser.collectionFormatInQuery)
+
case IsSimplePrimitiveType(prop.Type[0]):
- param = createParameter(paramType, prop.Description, name, prop.Type[0], findInSlice(schema.Required, name))
+ param = createParameter(paramType, prop.Description, name, PRIMITIVE, prop.Type[0], findInSlice(schema.Required, name), enums, operation.parser.collectionFormatInQuery)
default:
operation.parser.debug.Printf("skip field [%s] in %s is not supported type for %s", name, refType, paramType)
continue
}
+
param.Nullable = prop.Nullable
param.Format = prop.Format
param.Default = prop.Default
@@ -335,20 +350,22 @@ func (operation *Operation) ParseParamComment(commentLine string, astFile *ast.F
if objectType == PRIMITIVE {
param.Schema = PrimitiveSchema(refType)
} else {
- schema, err := operation.parseAPIObjectSchema(objectType, refType, astFile)
+ schema, err := operation.parseAPIObjectSchema(commentLine, objectType, refType, astFile)
if err != nil {
return err
}
+
param.Schema = schema
}
default:
return fmt.Errorf("%s is not supported paramType", paramType)
}
- err := operation.parseAndExtractionParamAttribute(commentLine, objectType, refType, ¶m)
+ err := operation.parseParamAttribute(commentLine, objectType, refType, ¶m)
if err != nil {
return err
}
+
operation.Operation.Parameters = append(operation.Operation.Parameters, param)
return nil
@@ -365,8 +382,8 @@ const (
validateTag = "validate"
minimumTag = "minimum"
maximumTag = "maximum"
- minLengthTag = "minlength"
- maxLengthTag = "maxlength"
+ minLengthTag = "minLength"
+ maxLengthTag = "maxLength"
multipleOfTag = "multipleOf"
readOnlyTag = "readonly"
extensionsTag = "extensions"
@@ -398,22 +415,24 @@ var regexAttributes = map[string]*regexp.Regexp{
schemaExampleTag: regexp.MustCompile(`(?i)\s+schemaExample\(.*\)`),
}
-func (operation *Operation) parseAndExtractionParamAttribute(commentLine, objectType, schemaType string, param *spec.Parameter) error {
+func (operation *Operation) parseParamAttribute(comment, objectType, schemaType string, param *spec.Parameter) error {
schemaType = TransToValidSchemeType(schemaType)
+
for attrKey, re := range regexAttributes {
- attr, err := findAttr(re, commentLine)
+ attr, err := findAttr(re, comment)
if err != nil {
continue
}
+
switch attrKey {
case enumsTag:
err = setEnumParam(param, attr, objectType, schemaType)
case minimumTag, maximumTag:
- err = setNumberParam(param, attrKey, schemaType, attr, commentLine)
+ err = setNumberParam(param, attrKey, schemaType, attr, comment)
case defaultTag:
err = setDefault(param, schemaType, attr)
case minLengthTag, maxLengthTag:
- err = setStringParam(param, attrKey, schemaType, attr, commentLine)
+ err = setStringParam(param, attrKey, schemaType, attr, comment)
case formatTag:
param.Format = attr
case exampleTag:
@@ -421,10 +440,11 @@ func (operation *Operation) parseAndExtractionParamAttribute(commentLine, object
case schemaExampleTag:
err = setSchemaExample(param, schemaType, attr)
case extensionsTag:
- _ = setExtensionParam(param, attr)
+ param.Extensions = setExtensionParam(attr)
case collectionFormatTag:
- err = setCollectionFormatParam(param, attrKey, objectType, attr, commentLine)
+ err = setCollectionFormatParam(param, attrKey, objectType, attr, comment)
}
+
if err != nil {
return err
}
@@ -435,8 +455,8 @@ func (operation *Operation) parseAndExtractionParamAttribute(commentLine, object
func findAttr(re *regexp.Regexp, commentLine string) (string, error) {
attr := re.FindString(commentLine)
- l := strings.Index(attr, "(")
- r := strings.Index(attr, ")")
+
+ l, r := strings.Index(attr, "("), strings.Index(attr, ")")
if l == -1 || r == -1 {
return "", fmt.Errorf("can not find regex=%s, comment=%s", re.String(), commentLine)
}
@@ -471,12 +491,14 @@ func setNumberParam(param *spec.Parameter, name, schemaType, attr, commentLine s
if err != nil {
return fmt.Errorf("maximum is allow only a number. comment=%s got=%s", commentLine, attr)
}
+
switch name {
case minimumTag:
param.Minimum = &n
case maximumTag:
param.Maximum = &n
}
+
return nil
default:
return fmt.Errorf("%s is attribute to set to a number. comment=%s got=%s", name, commentLine, schemaType)
@@ -503,23 +525,33 @@ func setEnumParam(param *spec.Parameter, attr, objectType, schemaType string) er
return nil
}
-func setExtensionParam(param *spec.Parameter, attr string) error {
- param.Extensions = map[string]interface{}{}
+func setExtensionParam(attr string) spec.Extensions {
+ extensions := spec.Extensions{}
+
for _, val := range splitNotWrapped(attr, ',') {
parts := strings.SplitN(val, "=", 2)
if len(parts) == 2 {
- param.Extensions.Add(parts[0], parts[1])
+ extensions.Add(parts[0], parts[1])
+
+ continue
+ }
+
+ if len(parts[0]) > 0 && string(parts[0][0]) == "!" {
+ extensions.Add(parts[0][1:], false)
continue
}
- param.Extensions.Add(parts[0], true)
+
+ extensions.Add(parts[0], true)
}
- return nil
+
+ return extensions
}
func setCollectionFormatParam(param *spec.Parameter, name, schemaType, attr, commentLine string) error {
if schemaType == ARRAY {
param.CollectionFormat = TransToValidCollectionFormat(attr)
+
return nil
}
@@ -531,13 +563,12 @@ func setDefault(param *spec.Parameter, schemaType string, value string) error {
if err != nil {
return nil // Don't set a default value if it's not valid
}
+
param.Default = val
+
return nil
}
-// controlCharReplacer replaces \r \n \t in example string values
-var controlCharReplacer = strings.NewReplacer(`\r`, "\r", `\n`, "\n", `\t`, "\t")
-
func setSchemaExample(param *spec.Parameter, schemaType string, value string) error {
val, err := defineType(schemaType, value)
if err != nil {
@@ -550,7 +581,8 @@ func setSchemaExample(param *spec.Parameter, schemaType string, value string) er
switch v := val.(type) {
case string:
- param.Schema.Example = controlCharReplacer.Replace(v)
+ // replaces \r \n \t in example string values.
+ param.Schema.Example = strings.NewReplacer(`\r`, "\r", `\n`, "\n", `\t`, "\t").Replace(v)
default:
param.Schema.Example = val
}
@@ -563,13 +595,16 @@ func setExample(param *spec.Parameter, schemaType string, value string) error {
if err != nil {
return nil // Don't set a example value if it's not valid
}
+
param.Example = val
+
return nil
}
// defineType enum value define the type (object and array unsupported).
func defineType(schemaType string, value string) (v interface{}, err error) {
schemaType = TransToValidSchemeType(schemaType)
+
switch schemaType {
case STRING:
return value, nil
@@ -597,8 +632,7 @@ func defineType(schemaType string, value string) (v interface{}, err error) {
// ParseTagsComment parses comment for given `tag` comment string.
func (operation *Operation) ParseTagsComment(commentLine string) {
- tags := strings.Split(commentLine, ",")
- for _, tag := range tags {
+ for _, tag := range strings.Split(commentLine, ",") {
operation.Tags = append(operation.Tags, strings.TrimSpace(tag))
}
}
@@ -617,13 +651,13 @@ func (operation *Operation) ParseProduceComment(commentLine string) error {
// `produce` (`Content-Type:` response header) or
// `accept` (`Accept:` request header).
func parseMimeTypeList(mimeTypeList string, typeList *[]string, format string) error {
- mimeTypes := strings.Split(mimeTypeList, ",")
- for _, typeName := range mimeTypes {
+ for _, typeName := range strings.Split(mimeTypeList, ",") {
if mimeTypePattern.MatchString(typeName) {
*typeList = append(*typeList, typeName)
continue
}
+
aliasMimeType, ok := mimeTypeAliases[typeName]
if !ok {
return fmt.Errorf(format, typeName)
@@ -643,6 +677,7 @@ func (operation *Operation) ParseRouterComment(commentLine string) error {
if len(matches) != 3 {
return fmt.Errorf("can not parse router comment \"%s\"", commentLine)
}
+
signature := RouteProperties{
Path: matches[1],
HTTPMethod: strings.ToUpper(matches[2]),
@@ -659,35 +694,41 @@ func (operation *Operation) ParseRouterComment(commentLine string) error {
// ParseSecurityComment parses comment for given `security` comment string.
func (operation *Operation) ParseSecurityComment(commentLine string) error {
- //var securityMap map[string][]string = map[string][]string{}
+ var (
+ securityMap = make(map[string][]string)
+ securitySource = commentLine[strings.Index(commentLine, "@Security")+1:]
+ )
- var securityMap = make(map[string][]string)
- securitySource := commentLine[strings.Index(commentLine, "@Security")+1:]
for _, securityOption := range strings.Split(securitySource, "||") {
securityOption = strings.TrimSpace(securityOption)
- l := strings.Index(securityOption, "[")
- r := strings.Index(securityOption, "]")
- if !(l == -1 && r == -1) {
- scopes := securityOption[l+1 : r]
- var s []string
+
+ left, right := strings.Index(securityOption, "["), strings.Index(securityOption, "]")
+
+ if !(left == -1 && right == -1) {
+ scopes := securityOption[left+1 : right]
+
+ var options []string
+
for _, scope := range strings.Split(scopes, ",") {
- s = append(s, strings.TrimSpace(scope))
+ options = append(options, strings.TrimSpace(scope))
}
- securityKey := securityOption[0:l]
- securityMap[securityKey] = append(securityMap[securityKey], s...)
+ securityKey := securityOption[0:left]
+ securityMap[securityKey] = append(securityMap[securityKey], options...)
} else {
securityKey := strings.TrimSpace(securityOption)
securityMap[securityKey] = []string{}
}
}
+
operation.Security = append(operation.Security, securityMap)
+
return nil
}
// findTypeDef attempts to find the *ast.TypeSpec for a specific type given the
// type's name and the package's import path.
-// TODO: improve finding external pkg
+// TODO: improve finding external pkg.
func findTypeDef(importPath, typeName string) (*ast.TypeSpec, error) {
cwd, err := os.Getwd()
if err != nil {
@@ -723,7 +764,6 @@ func findTypeDef(importPath, typeName string) (*ast.TypeSpec, error) {
}
// TODO: possibly cache pkgInfo since it's an expensive operation
-
for i := range pkgInfo.Files {
for _, astDeclaration := range pkgInfo.Files[i].Decls {
generalDeclaration, ok := astDeclaration.(*ast.GenDecl)
@@ -743,18 +783,22 @@ func findTypeDef(importPath, typeName string) (*ast.TypeSpec, error) {
return nil, fmt.Errorf("type spec not found")
}
-var responsePattern = regexp.MustCompile(`^([\w,]+)[\s]+([\w{}]+)[\s]+([\w\-.\\{}=,\[\]]+)[^"]*(.*)?`)
+var responsePattern = regexp.MustCompile(`^([\w,]+)\s+([\w{}]+)\s+([\w\-.\\{}=,\[\s\]]+)\s*(".*)?`)
// ResponseType{data1=Type1,data2=Type2}.
var combinedPattern = regexp.MustCompile(`^([\w\-./\[\]]+){(.*)}$`)
func (operation *Operation) parseObjectSchema(refType string, astFile *ast.File) (*spec.Schema, error) {
+ return parseObjectSchema(operation.parser, refType, astFile)
+}
+
+func parseObjectSchema(parser *Parser, refType string, astFile *ast.File) (*spec.Schema, error) {
switch {
case refType == NIL:
return nil, nil
- case refType == "interface{}":
+ case refType == INTERFACE:
return PrimitiveSchema(OBJECT), nil
- case refType == "any":
+ case refType == ANY:
return PrimitiveSchema(OBJECT), nil
case IsGolangPrimitiveType(refType):
refType = TransToValidSchemeType(refType)
@@ -763,7 +807,7 @@ func (operation *Operation) parseObjectSchema(refType string, astFile *ast.File)
case IsPrimitiveType(refType):
return PrimitiveSchema(refType), nil
case strings.HasPrefix(refType, "[]"):
- schema, err := operation.parseObjectSchema(refType[2:], astFile)
+ schema, err := parseObjectSchema(parser, refType[2:], astFile)
if err != nil {
return nil, err
}
@@ -775,21 +819,23 @@ func (operation *Operation) parseObjectSchema(refType string, astFile *ast.File)
if idx < 0 {
return nil, fmt.Errorf("invalid type: %s", refType)
}
+
refType = refType[idx+1:]
- if refType == "interface{}" || refType == "any" {
+ if refType == INTERFACE || refType == ANY {
return spec.MapProperty(nil), nil
}
- schema, err := operation.parseObjectSchema(refType, astFile)
+
+ schema, err := parseObjectSchema(parser, refType, astFile)
if err != nil {
return nil, err
}
return spec.MapProperty(schema), nil
case strings.Contains(refType, "{"):
- return operation.parseCombinedObjectSchema(refType, astFile)
+ return parseCombinedObjectSchema(parser, refType, astFile)
default:
- if operation.parser != nil { // checking refType has existing in 'TypeDefinitions'
- schema, err := operation.parser.getTypeSchema(refType, astFile, true)
+ if parser != nil { // checking refType has existing in 'TypeDefinitions'
+ schema, err := parser.getTypeSchema(refType, astFile, true)
if err != nil {
return nil, err
}
@@ -801,45 +847,46 @@ func (operation *Operation) parseObjectSchema(refType string, astFile *ast.File)
}
}
-func (operation *Operation) parseCombinedObjectSchema(refType string, astFile *ast.File) (*spec.Schema, error) {
+func parseFields(s string) []string {
+ nestLevel := 0
+
+ return strings.FieldsFunc(s, func(char rune) bool {
+ if char == '{' {
+ nestLevel++
+
+ return false
+ } else if char == '}' {
+ nestLevel--
+
+ return false
+ }
+
+ return char == ',' && nestLevel == 0
+ })
+}
+
+func parseCombinedObjectSchema(parser *Parser, refType string, astFile *ast.File) (*spec.Schema, error) {
matches := combinedPattern.FindStringSubmatch(refType)
if len(matches) != 3 {
return nil, fmt.Errorf("invalid type: %s", refType)
}
- refType = matches[1]
- schema, err := operation.parseObjectSchema(refType, astFile)
+
+ schema, err := parseObjectSchema(parser, matches[1], astFile)
if err != nil {
return nil, err
}
- parseFields := func(s string) []string {
- n := 0
-
- return strings.FieldsFunc(s, func(r rune) bool {
- if r == '{' {
- n++
+ fields, props := parseFields(matches[2]), map[string]spec.Schema{}
- return false
- } else if r == '}' {
- n--
-
- return false
- }
-
- return r == ',' && n == 0
- })
- }
-
- fields := parseFields(matches[2])
- props := map[string]spec.Schema{}
for _, field := range fields {
- matches := strings.SplitN(field, "=", 2)
- if len(matches) == 2 {
- schema, err := operation.parseObjectSchema(matches[1], astFile)
+ keyVal := strings.SplitN(field, "=", 2)
+ if len(keyVal) == 2 {
+ schema, err := parseObjectSchema(parser, keyVal[1], astFile)
if err != nil {
return nil, err
}
- props[matches[0]] = *schema
+
+ props[keyVal[0]] = *schema
}
}
@@ -855,12 +902,22 @@ func (operation *Operation) parseCombinedObjectSchema(refType string, astFile *a
}), nil
}
-func (operation *Operation) parseAPIObjectSchema(schemaType, refType string, astFile *ast.File) (*spec.Schema, error) {
+func (operation *Operation) parseAPIObjectSchema(commentLine, schemaType, refType string, astFile *ast.File) (*spec.Schema, error) {
+ if strings.HasSuffix(refType, ",") && strings.Contains(refType, "[") {
+ // regexp may have broken generic syntax. find closing bracket and add it back
+ allMatchesLenOffset := strings.Index(commentLine, refType) + len(refType)
+ lostPartEndIdx := strings.Index(commentLine[allMatchesLenOffset:], "]")
+ if lostPartEndIdx >= 0 {
+ refType += commentLine[allMatchesLenOffset : allMatchesLenOffset+lostPartEndIdx+1]
+ }
+ }
+
switch schemaType {
case OBJECT:
if !strings.HasPrefix(refType, "[]") {
return operation.parseObjectSchema(refType, astFile)
}
+
refType = refType[2:]
fallthrough
@@ -889,7 +946,8 @@ func (operation *Operation) ParseResponseComment(commentLine string, astFile *as
}
description := strings.Trim(matches[4], "\"")
- schema, err := operation.parseAPIObjectSchema(strings.Trim(matches[2], "{}"), matches[3], astFile)
+
+ schema, err := operation.parseAPIObjectSchema(commentLine, strings.Trim(matches[2], "{}"), strings.TrimSpace(matches[3]), astFile)
if err != nil {
return err
}
@@ -900,6 +958,7 @@ func (operation *Operation) ParseResponseComment(commentLine string, astFile *as
continue
}
+
code, err := strconv.Atoi(codeStr)
if err != nil {
return fmt.Errorf("can not parse response comment \"%s\"", commentLine)
@@ -924,6 +983,23 @@ func newHeaderSpec(schemaType, description string) spec.Header {
HeaderProps: spec.HeaderProps{
Description: description,
},
+ VendorExtensible: spec.VendorExtensible{
+ Extensions: nil,
+ },
+ CommonValidations: spec.CommonValidations{
+ Maximum: nil,
+ ExclusiveMaximum: false,
+ Minimum: nil,
+ ExclusiveMinimum: false,
+ MaxLength: nil,
+ MinLength: nil,
+ Pattern: "",
+ MaxItems: nil,
+ MinItems: nil,
+ UniqueItems: false,
+ MultipleOf: nil,
+ Enum: nil,
+ },
}
}
@@ -936,7 +1012,7 @@ func (operation *Operation) ParseResponseHeaderComment(commentLine string, _ *as
header := newHeaderSpec(strings.Trim(matches[2], "{}"), strings.Trim(matches[4], "\""))
- headerKey := matches[3]
+ headerKey := strings.TrimSpace(matches[3])
if strings.EqualFold(matches[1], "all") {
if operation.Responses.Default != nil {
@@ -966,6 +1042,7 @@ func (operation *Operation) ParseResponseHeaderComment(commentLine string, _ *as
if err != nil {
return fmt.Errorf("can not parse response comment \"%s\"", commentLine)
}
+
if operation.Responses.StatusCodeResponses != nil {
response, responseExist := operation.Responses.StatusCodeResponses[code]
if responseExist {
@@ -979,7 +1056,7 @@ func (operation *Operation) ParseResponseHeaderComment(commentLine string, _ *as
return nil
}
-var emptyResponsePattern = regexp.MustCompile(`([\w,]+)[\s]+"(.*)"`)
+var emptyResponsePattern = regexp.MustCompile(`([\w,]+)\s+"(.*)"`)
// ParseEmptyResponseComment parse only comment out status code and description,eg: @Success 200 "it's ok".
func (operation *Operation) ParseEmptyResponseComment(commentLine string) error {
@@ -989,6 +1066,7 @@ func (operation *Operation) ParseEmptyResponseComment(commentLine string) error
}
description := strings.Trim(matches[2], "\"")
+
for _, codeStr := range strings.Split(matches[1], ",") {
if strings.EqualFold(codeStr, defaultTag) {
operation.DefaultResponse().WithDescription(description)
@@ -1015,12 +1093,13 @@ func (operation *Operation) ParseEmptyResponseOnly(commentLine string) error {
continue
}
+
code, err := strconv.Atoi(codeStr)
if err != nil {
return fmt.Errorf("can not parse response comment \"%s\"", commentLine)
}
- operation.AddResponse(code, spec.NewResponse())
+ operation.AddResponse(code, spec.NewResponse().WithDescription(http.StatusText(code)))
}
return nil
@@ -1031,7 +1110,8 @@ func (operation *Operation) DefaultResponse() *spec.Response {
if operation.Responses.Default == nil {
operation.Responses.Default = &spec.Response{
ResponseProps: spec.ResponseProps{
- Headers: make(map[string]spec.Header),
+ Description: "",
+ Headers: make(map[string]spec.Header),
},
}
}
@@ -1044,11 +1124,12 @@ func (operation *Operation) AddResponse(code int, response *spec.Response) {
if response.Headers == nil {
response.Headers = make(map[string]spec.Header)
}
+
operation.Responses.StatusCodeResponses[code] = *response
}
// createParameter returns swagger spec.Parameter for given paramType, description, paramName, schemaType, required.
-func createParameter(paramType, description, paramName, schemaType string, required bool) spec.Parameter {
+func createParameter(paramType, description, paramName, objectType, schemaType string, required bool, enums []interface{}, collectionFormat string) spec.Parameter {
// //five possible parameter types. query, path, body, header, form
result := spec.Parameter{
ParamProps: spec.ParamProps{
@@ -1060,33 +1141,40 @@ func createParameter(paramType, description, paramName, schemaType string, requi
}
if paramType == "body" {
- result.ParamProps.Schema = &spec.Schema{
- SchemaProps: spec.SchemaProps{
- Type: []string{schemaType},
- },
- }
-
return result
}
- result.SimpleSchema = spec.SimpleSchema{
- Type: schemaType,
+ switch objectType {
+ case ARRAY:
+ result.Type = objectType
+ result.CollectionFormat = collectionFormat
+ result.Items = &spec.Items{
+ CommonValidations: spec.CommonValidations{
+ Enum: enums,
+ },
+ SimpleSchema: spec.SimpleSchema{
+ Type: schemaType,
+ },
+ }
+ case PRIMITIVE, OBJECT:
+ result.Type = schemaType
+ result.Enum = enums
}
-
return result
}
func getCodeExampleForSummary(summaryName string, dirPath string) ([]byte, error) {
- filesInfos, err := ioutil.ReadDir(dirPath)
+ dirEntries, err := os.ReadDir(dirPath)
if err != nil {
return nil, err
}
- for _, fileInfo := range filesInfos {
- if fileInfo.IsDir() {
+ for _, entry := range dirEntries {
+ if entry.IsDir() {
continue
}
- fileName := fileInfo.Name()
+
+ fileName := entry.Name()
if !strings.Contains(fileName, ".json") {
continue
@@ -1094,7 +1182,8 @@ func getCodeExampleForSummary(summaryName string, dirPath string) ([]byte, error
if strings.Contains(fileName, summaryName) {
fullPath := filepath.Join(dirPath, fileName)
- commentInfo, err := ioutil.ReadFile(fullPath)
+
+ commentInfo, err := os.ReadFile(fullPath)
if err != nil {
return nil, fmt.Errorf("Failed to read code example file %s error: %s ", fullPath, err)
}
diff --git a/vendor/github.com/swaggo/swag/package.go b/vendor/github.com/swaggo/swag/package.go
new file mode 100644
index 0000000..08f8b92
--- /dev/null
+++ b/vendor/github.com/swaggo/swag/package.go
@@ -0,0 +1,183 @@
+package swag
+
+import (
+ "go/ast"
+ "go/token"
+ "reflect"
+ "strconv"
+)
+
+// PackageDefinitions files and definition in a package.
+type PackageDefinitions struct {
+ // files in this package, map key is file's relative path starting package path
+ Files map[string]*ast.File
+
+ // definitions in this package, map key is typeName
+ TypeDefinitions map[string]*TypeSpecDef
+
+ // const variables in this package, map key is the name
+ ConstTable map[string]*ConstVariable
+
+ // const variables in order in this package
+ OrderedConst []*ConstVariable
+
+ // package name
+ Name string
+
+ // package path
+ Path string
+}
+
+// ConstVariableGlobalEvaluator an interface used to evaluate enums across packages
+type ConstVariableGlobalEvaluator interface {
+ EvaluateConstValue(pkg *PackageDefinitions, cv *ConstVariable, recursiveStack map[string]struct{}) (interface{}, ast.Expr)
+ EvaluateConstValueByName(file *ast.File, pkgPath, constVariableName string, recursiveStack map[string]struct{}) (interface{}, ast.Expr)
+ FindTypeSpec(typeName string, file *ast.File) *TypeSpecDef
+}
+
+// NewPackageDefinitions new a PackageDefinitions object
+func NewPackageDefinitions(name, pkgPath string) *PackageDefinitions {
+ return &PackageDefinitions{
+ Name: name,
+ Path: pkgPath,
+ Files: make(map[string]*ast.File),
+ TypeDefinitions: make(map[string]*TypeSpecDef),
+ ConstTable: make(map[string]*ConstVariable),
+ }
+}
+
+// AddFile add a file
+func (pkg *PackageDefinitions) AddFile(pkgPath string, file *ast.File) *PackageDefinitions {
+ pkg.Files[pkgPath] = file
+ return pkg
+}
+
+// AddTypeSpec add a type spec.
+func (pkg *PackageDefinitions) AddTypeSpec(name string, typeSpec *TypeSpecDef) *PackageDefinitions {
+ pkg.TypeDefinitions[name] = typeSpec
+ return pkg
+}
+
+// AddConst add a const variable.
+func (pkg *PackageDefinitions) AddConst(astFile *ast.File, valueSpec *ast.ValueSpec) *PackageDefinitions {
+ for i := 0; i < len(valueSpec.Names) && i < len(valueSpec.Values); i++ {
+ variable := &ConstVariable{
+ Name: valueSpec.Names[i],
+ Type: valueSpec.Type,
+ Value: valueSpec.Values[i],
+ Comment: valueSpec.Comment,
+ File: astFile,
+ }
+ pkg.ConstTable[valueSpec.Names[i].Name] = variable
+ pkg.OrderedConst = append(pkg.OrderedConst, variable)
+ }
+ return pkg
+}
+
+func (pkg *PackageDefinitions) evaluateConstValue(file *ast.File, iota int, expr ast.Expr, globalEvaluator ConstVariableGlobalEvaluator, recursiveStack map[string]struct{}) (interface{}, ast.Expr) {
+ switch valueExpr := expr.(type) {
+ case *ast.Ident:
+ if valueExpr.Name == "iota" {
+ return iota, nil
+ }
+ if pkg.ConstTable != nil {
+ if cv, ok := pkg.ConstTable[valueExpr.Name]; ok {
+ return globalEvaluator.EvaluateConstValue(pkg, cv, recursiveStack)
+ }
+ }
+ case *ast.SelectorExpr:
+ pkgIdent, ok := valueExpr.X.(*ast.Ident)
+ if !ok {
+ return nil, nil
+ }
+ return globalEvaluator.EvaluateConstValueByName(file, pkgIdent.Name, valueExpr.Sel.Name, recursiveStack)
+ case *ast.BasicLit:
+ switch valueExpr.Kind {
+ case token.INT:
+ // hexadecimal
+ if len(valueExpr.Value) > 2 && valueExpr.Value[0] == '0' && valueExpr.Value[1] == 'x' {
+ if x, err := strconv.ParseInt(valueExpr.Value[2:], 16, 64); err == nil {
+ return int(x), nil
+ } else if x, err := strconv.ParseUint(valueExpr.Value[2:], 16, 64); err == nil {
+ return x, nil
+ } else {
+ panic(err)
+ }
+ }
+
+ //octet
+ if len(valueExpr.Value) > 1 && valueExpr.Value[0] == '0' {
+ if x, err := strconv.ParseInt(valueExpr.Value[1:], 8, 64); err == nil {
+ return int(x), nil
+ } else if x, err := strconv.ParseUint(valueExpr.Value[1:], 8, 64); err == nil {
+ return x, nil
+ } else {
+ panic(err)
+ }
+ }
+
+ //a basic literal integer is int type in default, or must have an explicit converting type in front
+ if x, err := strconv.ParseInt(valueExpr.Value, 10, 64); err == nil {
+ return int(x), nil
+ } else if x, err := strconv.ParseUint(valueExpr.Value, 10, 64); err == nil {
+ return x, nil
+ } else {
+ panic(err)
+ }
+ case token.STRING:
+ if valueExpr.Value[0] == '`' {
+ return valueExpr.Value[1 : len(valueExpr.Value)-1], nil
+ }
+ return EvaluateEscapedString(valueExpr.Value[1 : len(valueExpr.Value)-1]), nil
+ case token.CHAR:
+ return EvaluateEscapedChar(valueExpr.Value[1 : len(valueExpr.Value)-1]), nil
+ }
+ case *ast.UnaryExpr:
+ x, evalType := pkg.evaluateConstValue(file, iota, valueExpr.X, globalEvaluator, recursiveStack)
+ if x == nil {
+ return x, evalType
+ }
+ return EvaluateUnary(x, valueExpr.Op, evalType)
+ case *ast.BinaryExpr:
+ x, evalTypex := pkg.evaluateConstValue(file, iota, valueExpr.X, globalEvaluator, recursiveStack)
+ y, evalTypey := pkg.evaluateConstValue(file, iota, valueExpr.Y, globalEvaluator, recursiveStack)
+ if x == nil || y == nil {
+ return nil, nil
+ }
+ return EvaluateBinary(x, y, valueExpr.Op, evalTypex, evalTypey)
+ case *ast.ParenExpr:
+ return pkg.evaluateConstValue(file, iota, valueExpr.X, globalEvaluator, recursiveStack)
+ case *ast.CallExpr:
+ //data conversion
+ if len(valueExpr.Args) != 1 {
+ return nil, nil
+ }
+ arg := valueExpr.Args[0]
+ if ident, ok := valueExpr.Fun.(*ast.Ident); ok {
+ name := ident.Name
+ if name == "uintptr" {
+ name = "uint"
+ }
+ if IsGolangPrimitiveType(name) {
+ value, _ := pkg.evaluateConstValue(file, iota, arg, globalEvaluator, recursiveStack)
+ value = EvaluateDataConversion(value, name)
+ return value, nil
+ } else if name == "len" {
+ value, _ := pkg.evaluateConstValue(file, iota, arg, globalEvaluator, recursiveStack)
+ return reflect.ValueOf(value).Len(), nil
+ }
+ typeDef := globalEvaluator.FindTypeSpec(name, file)
+ if typeDef == nil {
+ return nil, nil
+ }
+ return arg, valueExpr.Fun
+ } else if selector, ok := valueExpr.Fun.(*ast.SelectorExpr); ok {
+ typeDef := globalEvaluator.FindTypeSpec(fullTypeName(selector.X.(*ast.Ident).Name, selector.Sel.Name), file)
+ if typeDef == nil {
+ return nil, nil
+ }
+ return arg, typeDef.TypeSpec.Type
+ }
+ }
+ return nil, nil
+}
diff --git a/vendor/github.com/swaggo/swag/packages.go b/vendor/github.com/swaggo/swag/packages.go
index c454f06..2c5693f 100644
--- a/vendor/github.com/swaggo/swag/packages.go
+++ b/vendor/github.com/swaggo/swag/packages.go
@@ -1,11 +1,13 @@
package swag
import (
+ "fmt"
"go/ast"
goparser "go/parser"
"go/token"
"os"
"path/filepath"
+ "runtime"
"sort"
"strings"
@@ -17,6 +19,8 @@ type PackagesDefinitions struct {
files map[*ast.File]*AstFileInfo
packages map[string]*PackageDefinitions
uniqueDefinitions map[string]*TypeSpecDef
+ parseDependency bool
+ debug Debugger
}
// NewPackagesDefinitions create object PackagesDefinitions.
@@ -28,14 +32,25 @@ func NewPackagesDefinitions() *PackagesDefinitions {
}
}
-// CollectAstFile collect ast.file.
-func (pkgs *PackagesDefinitions) CollectAstFile(packageDir, path string, astFile *ast.File) error {
- if pkgs.files == nil {
- pkgs.files = make(map[*ast.File]*AstFileInfo)
+// ParseFile parse a source file.
+func (pkgDefs *PackagesDefinitions) ParseFile(packageDir, path string, src interface{}, flag ParseFlag) error {
+ // positions are relative to FileSet
+ fileSet := token.NewFileSet()
+ astFile, err := goparser.ParseFile(fileSet, path, src, goparser.ParseComments)
+ if err != nil {
+ return fmt.Errorf("failed to parse file %s, error:%+v", path, err)
+ }
+ return pkgDefs.collectAstFile(fileSet, packageDir, path, astFile, flag)
+}
+
+// collectAstFile collect ast.file.
+func (pkgDefs *PackagesDefinitions) collectAstFile(fileSet *token.FileSet, packageDir, path string, astFile *ast.File, flag ParseFlag) error {
+ if pkgDefs.files == nil {
+ pkgDefs.files = make(map[*ast.File]*AstFileInfo)
}
- if pkgs.packages == nil {
- pkgs.packages = make(map[string]*PackageDefinitions)
+ if pkgDefs.packages == nil {
+ pkgDefs.packages = make(map[string]*PackageDefinitions)
}
// return without storing the file if we lack a packageDir
@@ -48,35 +63,39 @@ func (pkgs *PackagesDefinitions) CollectAstFile(packageDir, path string, astFile
return err
}
- pd, ok := pkgs.packages[packageDir]
+ dependency, ok := pkgDefs.packages[packageDir]
if ok {
// return without storing the file if it already exists
- _, exists := pd.Files[path]
+ _, exists := dependency.Files[path]
if exists {
return nil
}
- pd.Files[path] = astFile
+
+ dependency.Files[path] = astFile
} else {
- pkgs.packages[packageDir] = &PackageDefinitions{
- Name: astFile.Name.Name,
- Files: map[string]*ast.File{path: astFile},
- TypeDefinitions: make(map[string]*TypeSpecDef),
- }
+ pkgDefs.packages[packageDir] = NewPackageDefinitions(astFile.Name.Name, packageDir).AddFile(path, astFile)
}
- pkgs.files[astFile] = &AstFileInfo{
+ pkgDefs.files[astFile] = &AstFileInfo{
+ FileSet: fileSet,
File: astFile,
Path: path,
PackagePath: packageDir,
+ ParseFlag: flag,
}
return nil
}
// RangeFiles for range the collection of ast.File in alphabetic order.
-func rangeFiles(files map[*ast.File]*AstFileInfo, handle func(filename string, file *ast.File) error) error {
- sortedFiles := make([]*AstFileInfo, 0, len(files))
- for _, info := range files {
+func (pkgDefs *PackagesDefinitions) RangeFiles(handle func(info *AstFileInfo) error) error {
+ sortedFiles := make([]*AstFileInfo, 0, len(pkgDefs.files))
+ for _, info := range pkgDefs.files {
+ // ignore package path prefix with 'vendor' or $GOROOT,
+ // because the router info of api will not be included these files.
+ if strings.HasPrefix(info.PackagePath, "vendor") || strings.HasPrefix(info.Path, runtime.GOROOT()) {
+ continue
+ }
sortedFiles = append(sortedFiles, info)
}
@@ -85,7 +104,7 @@ func rangeFiles(files map[*ast.File]*AstFileInfo, handle func(filename string, f
})
for _, info := range sortedFiles {
- err := handle(info.Path, info.File)
+ err := handle(info)
if err != nil {
return err
}
@@ -96,17 +115,25 @@ func rangeFiles(files map[*ast.File]*AstFileInfo, handle func(filename string, f
// ParseTypes parse types
// @Return parsed definitions.
-func (pkgs *PackagesDefinitions) ParseTypes() (map[*TypeSpecDef]*Schema, error) {
+func (pkgDefs *PackagesDefinitions) ParseTypes() (map[*TypeSpecDef]*Schema, error) {
parsedSchemas := make(map[*TypeSpecDef]*Schema)
- for astFile, info := range pkgs.files {
- pkgs.parseTypesFromFile(astFile, info.PackagePath, parsedSchemas)
+ for astFile, info := range pkgDefs.files {
+ pkgDefs.parseTypesFromFile(astFile, info.PackagePath, parsedSchemas)
+ pkgDefs.parseFunctionScopedTypesFromFile(astFile, info.PackagePath, parsedSchemas)
}
+ pkgDefs.removeAllNotUniqueTypes()
+ pkgDefs.evaluateAllConstVariables()
+ pkgDefs.collectConstEnums(parsedSchemas)
return parsedSchemas, nil
}
-func (pkgs *PackagesDefinitions) parseTypesFromFile(astFile *ast.File, packagePath string, parsedSchemas map[*TypeSpecDef]*Schema) {
+func (pkgDefs *PackagesDefinitions) parseTypesFromFile(astFile *ast.File, packagePath string, parsedSchemas map[*TypeSpecDef]*Schema) {
for _, astDeclaration := range astFile.Decls {
- if generalDeclaration, ok := astDeclaration.(*ast.GenDecl); ok && generalDeclaration.Tok == token.TYPE {
+ generalDeclaration, ok := astDeclaration.(*ast.GenDecl)
+ if !ok {
+ continue
+ }
+ if generalDeclaration.Tok == token.TYPE {
for _, astSpec := range generalDeclaration.Specs {
if typeSpec, ok := astSpec.(*ast.TypeSpec); ok {
typeSpecDef := &TypeSpecDef{
@@ -123,29 +150,100 @@ func (pkgs *PackagesDefinitions) parseTypesFromFile(astFile *ast.File, packagePa
}
}
- if pkgs.uniqueDefinitions == nil {
- pkgs.uniqueDefinitions = make(map[string]*TypeSpecDef)
+ if pkgDefs.uniqueDefinitions == nil {
+ pkgDefs.uniqueDefinitions = make(map[string]*TypeSpecDef)
}
- fullName := typeSpecDef.FullName()
- anotherTypeDef, ok := pkgs.uniqueDefinitions[fullName]
+ fullName := typeSpecDef.TypeName()
+
+ anotherTypeDef, ok := pkgDefs.uniqueDefinitions[fullName]
if ok {
- if typeSpecDef.PkgPath == anotherTypeDef.PkgPath {
- continue
- } else {
- delete(pkgs.uniqueDefinitions, fullName)
+ if anotherTypeDef == nil {
+ typeSpecDef.NotUnique = true
+ fullName = typeSpecDef.TypeName()
+ pkgDefs.uniqueDefinitions[fullName] = typeSpecDef
+ } else if typeSpecDef.PkgPath != anotherTypeDef.PkgPath {
+ pkgDefs.uniqueDefinitions[fullName] = nil
+ anotherTypeDef.NotUnique = true
+ pkgDefs.uniqueDefinitions[anotherTypeDef.TypeName()] = anotherTypeDef
+ typeSpecDef.NotUnique = true
+ fullName = typeSpecDef.TypeName()
+ pkgDefs.uniqueDefinitions[fullName] = typeSpecDef
}
} else {
- pkgs.uniqueDefinitions[fullName] = typeSpecDef
+ pkgDefs.uniqueDefinitions[fullName] = typeSpecDef
}
- if pkgs.packages[typeSpecDef.PkgPath] == nil {
- pkgs.packages[typeSpecDef.PkgPath] = &PackageDefinitions{
- Name: astFile.Name.Name,
- TypeDefinitions: map[string]*TypeSpecDef{typeSpecDef.Name(): typeSpecDef},
+ if pkgDefs.packages[typeSpecDef.PkgPath] == nil {
+ pkgDefs.packages[typeSpecDef.PkgPath] = NewPackageDefinitions(astFile.Name.Name, typeSpecDef.PkgPath).AddTypeSpec(typeSpecDef.Name(), typeSpecDef)
+ } else if _, ok = pkgDefs.packages[typeSpecDef.PkgPath].TypeDefinitions[typeSpecDef.Name()]; !ok {
+ pkgDefs.packages[typeSpecDef.PkgPath].AddTypeSpec(typeSpecDef.Name(), typeSpecDef)
+ }
+ }
+ }
+ } else if generalDeclaration.Tok == token.CONST {
+ // collect consts
+ pkgDefs.collectConstVariables(astFile, packagePath, generalDeclaration)
+ }
+ }
+}
+
+func (pkgDefs *PackagesDefinitions) parseFunctionScopedTypesFromFile(astFile *ast.File, packagePath string, parsedSchemas map[*TypeSpecDef]*Schema) {
+ for _, astDeclaration := range astFile.Decls {
+ funcDeclaration, ok := astDeclaration.(*ast.FuncDecl)
+ if ok && funcDeclaration.Body != nil {
+ for _, stmt := range funcDeclaration.Body.List {
+ if declStmt, ok := (stmt).(*ast.DeclStmt); ok {
+ if genDecl, ok := (declStmt.Decl).(*ast.GenDecl); ok && genDecl.Tok == token.TYPE {
+ for _, astSpec := range genDecl.Specs {
+ if typeSpec, ok := astSpec.(*ast.TypeSpec); ok {
+ typeSpecDef := &TypeSpecDef{
+ PkgPath: packagePath,
+ File: astFile,
+ TypeSpec: typeSpec,
+ ParentSpec: astDeclaration,
+ }
+
+ if idt, ok := typeSpec.Type.(*ast.Ident); ok && IsGolangPrimitiveType(idt.Name) && parsedSchemas != nil {
+ parsedSchemas[typeSpecDef] = &Schema{
+ PkgPath: typeSpecDef.PkgPath,
+ Name: astFile.Name.Name,
+ Schema: PrimitiveSchema(TransToValidSchemeType(idt.Name)),
+ }
+ }
+
+ if pkgDefs.uniqueDefinitions == nil {
+ pkgDefs.uniqueDefinitions = make(map[string]*TypeSpecDef)
+ }
+
+ fullName := typeSpecDef.TypeName()
+
+ anotherTypeDef, ok := pkgDefs.uniqueDefinitions[fullName]
+ if ok {
+ if anotherTypeDef == nil {
+ typeSpecDef.NotUnique = true
+ fullName = typeSpecDef.TypeName()
+ pkgDefs.uniqueDefinitions[fullName] = typeSpecDef
+ } else if typeSpecDef.PkgPath != anotherTypeDef.PkgPath {
+ pkgDefs.uniqueDefinitions[fullName] = nil
+ anotherTypeDef.NotUnique = true
+ pkgDefs.uniqueDefinitions[anotherTypeDef.TypeName()] = anotherTypeDef
+ typeSpecDef.NotUnique = true
+ fullName = typeSpecDef.TypeName()
+ pkgDefs.uniqueDefinitions[fullName] = typeSpecDef
+ }
+ } else {
+ pkgDefs.uniqueDefinitions[fullName] = typeSpecDef
+ }
+
+ if pkgDefs.packages[typeSpecDef.PkgPath] == nil {
+ pkgDefs.packages[typeSpecDef.PkgPath] = NewPackageDefinitions(astFile.Name.Name, typeSpecDef.PkgPath).AddTypeSpec(fullName, typeSpecDef)
+ } else if _, ok = pkgDefs.packages[typeSpecDef.PkgPath].TypeDefinitions[fullName]; !ok {
+ pkgDefs.packages[typeSpecDef.PkgPath].AddTypeSpec(fullName, typeSpecDef)
+ }
+ }
}
- } else if _, ok = pkgs.packages[typeSpecDef.PkgPath].TypeDefinitions[typeSpecDef.Name()]; !ok {
- pkgs.packages[typeSpecDef.PkgPath].TypeDefinitions[typeSpecDef.Name()] = typeSpecDef
+
}
}
}
@@ -153,11 +251,152 @@ func (pkgs *PackagesDefinitions) parseTypesFromFile(astFile *ast.File, packagePa
}
}
-func (pkgs *PackagesDefinitions) findTypeSpec(pkgPath string, typeName string) *TypeSpecDef {
- if pkgs.packages == nil {
+func (pkgDefs *PackagesDefinitions) collectConstVariables(astFile *ast.File, packagePath string, generalDeclaration *ast.GenDecl) {
+ pkg, ok := pkgDefs.packages[packagePath]
+ if !ok {
+ pkg = NewPackageDefinitions(astFile.Name.Name, packagePath)
+ pkgDefs.packages[packagePath] = pkg
+ }
+
+ var lastValueSpec *ast.ValueSpec
+ for _, astSpec := range generalDeclaration.Specs {
+ valueSpec, ok := astSpec.(*ast.ValueSpec)
+ if !ok {
+ continue
+ }
+ if len(valueSpec.Names) == 1 && len(valueSpec.Values) == 1 {
+ lastValueSpec = valueSpec
+ } else if len(valueSpec.Names) == 1 && len(valueSpec.Values) == 0 && valueSpec.Type == nil && lastValueSpec != nil {
+ valueSpec.Type = lastValueSpec.Type
+ valueSpec.Values = lastValueSpec.Values
+ }
+ pkg.AddConst(astFile, valueSpec)
+ }
+}
+
+func (pkgDefs *PackagesDefinitions) evaluateAllConstVariables() {
+ for _, pkg := range pkgDefs.packages {
+ for _, constVar := range pkg.OrderedConst {
+ pkgDefs.EvaluateConstValue(pkg, constVar, nil)
+ }
+ }
+}
+
+// EvaluateConstValue evaluate a const variable.
+func (pkgDefs *PackagesDefinitions) EvaluateConstValue(pkg *PackageDefinitions, cv *ConstVariable, recursiveStack map[string]struct{}) (interface{}, ast.Expr) {
+ if expr, ok := cv.Value.(ast.Expr); ok {
+ defer func() {
+ if err := recover(); err != nil {
+ if fi, ok := pkgDefs.files[cv.File]; ok {
+ pos := fi.FileSet.Position(cv.Name.NamePos)
+ pkgDefs.debug.Printf("warning: failed to evaluate const %s at %s:%d:%d, %v", cv.Name.Name, fi.Path, pos.Line, pos.Column, err)
+ }
+ }
+ }()
+ if recursiveStack == nil {
+ recursiveStack = make(map[string]struct{})
+ }
+ fullConstName := fullTypeName(pkg.Path, cv.Name.Name)
+ if _, ok = recursiveStack[fullConstName]; ok {
+ return nil, nil
+ }
+ recursiveStack[fullConstName] = struct{}{}
+
+ value, evalType := pkg.evaluateConstValue(cv.File, cv.Name.Obj.Data.(int), expr, pkgDefs, recursiveStack)
+ if cv.Type == nil && evalType != nil {
+ cv.Type = evalType
+ }
+ if value != nil {
+ cv.Value = value
+ }
+ return value, cv.Type
+ }
+ return cv.Value, cv.Type
+}
+
+// EvaluateConstValueByName evaluate a const variable by name.
+func (pkgDefs *PackagesDefinitions) EvaluateConstValueByName(file *ast.File, pkgName, constVariableName string, recursiveStack map[string]struct{}) (interface{}, ast.Expr) {
+ matchedPkgPaths, externalPkgPaths := pkgDefs.findPackagePathFromImports(pkgName, file)
+ for _, pkgPath := range matchedPkgPaths {
+ if pkg, ok := pkgDefs.packages[pkgPath]; ok {
+ if cv, ok := pkg.ConstTable[constVariableName]; ok {
+ return pkgDefs.EvaluateConstValue(pkg, cv, recursiveStack)
+ }
+ }
+ }
+ if pkgDefs.parseDependency {
+ for _, pkgPath := range externalPkgPaths {
+ if err := pkgDefs.loadExternalPackage(pkgPath); err == nil {
+ if pkg, ok := pkgDefs.packages[pkgPath]; ok {
+ if cv, ok := pkg.ConstTable[constVariableName]; ok {
+ return pkgDefs.EvaluateConstValue(pkg, cv, recursiveStack)
+ }
+ }
+ }
+ }
+ }
+ return nil, nil
+}
+
+func (pkgDefs *PackagesDefinitions) collectConstEnums(parsedSchemas map[*TypeSpecDef]*Schema) {
+ for _, pkg := range pkgDefs.packages {
+ for _, constVar := range pkg.OrderedConst {
+ if constVar.Type == nil {
+ continue
+ }
+ ident, ok := constVar.Type.(*ast.Ident)
+ if !ok || IsGolangPrimitiveType(ident.Name) {
+ continue
+ }
+ typeDef, ok := pkg.TypeDefinitions[ident.Name]
+ if !ok {
+ continue
+ }
+
+ //delete it from parsed schemas, and will parse it again
+ if _, ok := parsedSchemas[typeDef]; ok {
+ delete(parsedSchemas, typeDef)
+ }
+
+ if typeDef.Enums == nil {
+ typeDef.Enums = make([]EnumValue, 0)
+ }
+
+ name := constVar.Name.Name
+ if _, ok := constVar.Value.(ast.Expr); ok {
+ continue
+ }
+
+ enumValue := EnumValue{
+ key: name,
+ Value: constVar.Value,
+ }
+ if constVar.Comment != nil && len(constVar.Comment.List) > 0 {
+ enumValue.Comment = constVar.Comment.List[0].Text
+ enumValue.Comment = strings.TrimPrefix(enumValue.Comment, "//")
+ enumValue.Comment = strings.TrimPrefix(enumValue.Comment, "/*")
+ enumValue.Comment = strings.TrimSuffix(enumValue.Comment, "*/")
+ enumValue.Comment = strings.TrimSpace(enumValue.Comment)
+ }
+ typeDef.Enums = append(typeDef.Enums, enumValue)
+ }
+ }
+}
+
+func (pkgDefs *PackagesDefinitions) removeAllNotUniqueTypes() {
+ for key, ud := range pkgDefs.uniqueDefinitions {
+ if ud == nil {
+ delete(pkgDefs.uniqueDefinitions, key)
+ }
+ }
+}
+
+func (pkgDefs *PackagesDefinitions) findTypeSpec(pkgPath string, typeName string) *TypeSpecDef {
+ if pkgDefs.packages == nil {
return nil
}
- pd, found := pkgs.packages[pkgPath]
+
+ pd, found := pkgDefs.packages[pkgPath]
if found {
typeSpec, ok := pd.TypeDefinitions[typeName]
if ok {
@@ -168,7 +407,7 @@ func (pkgs *PackagesDefinitions) findTypeSpec(pkgPath string, typeName string) *
return nil
}
-func (pkgs *PackagesDefinitions) loadExternalPackage(importPath string) error {
+func (pkgDefs *PackagesDefinitions) loadExternalPackage(importPath string) error {
cwd, err := os.Getwd()
if err != nil {
return err
@@ -189,7 +428,7 @@ func (pkgs *PackagesDefinitions) loadExternalPackage(importPath string) error {
for _, info := range loaderProgram.AllPackages {
pkgPath := strings.TrimPrefix(info.Pkg.Path(), "vendor/")
for _, astFile := range info.Files {
- pkgs.parseTypesFromFile(astFile, pkgPath, nil)
+ pkgDefs.parseTypesFromFile(astFile, pkgPath, nil)
}
}
@@ -199,19 +438,16 @@ func (pkgs *PackagesDefinitions) loadExternalPackage(importPath string) error {
// findPackagePathFromImports finds out the package path of a package via ranging imports of an ast.File
// @pkg the name of the target package
// @file current ast.File in which to search imports
-// @fuzzy search for the package path that the last part matches the @pkg if true
-// @return the package path of a package of @pkg.
-func (pkgs *PackagesDefinitions) findPackagePathFromImports(pkg string, file *ast.File, fuzzy bool) string {
+// @return the package paths of a package of @pkg.
+func (pkgDefs *PackagesDefinitions) findPackagePathFromImports(pkg string, file *ast.File) (matchedPkgPaths, externalPkgPaths []string) {
if file == nil {
- return ""
+ return
}
if strings.ContainsRune(pkg, '.') {
pkg = strings.Split(pkg, ".")[0]
}
- hasAnonymousPkg := false
-
matchLastPathPart := func(pkgPath string) bool {
paths := strings.Split(pkgPath, "/")
return paths[len(paths)-1] == pkg
@@ -219,118 +455,119 @@ func (pkgs *PackagesDefinitions) findPackagePathFromImports(pkg string, file *as
// prior to match named package
for _, imp := range file.Imports {
+ path := strings.Trim(imp.Path.Value, `"`)
if imp.Name != nil {
if imp.Name.Name == pkg {
- return strings.Trim(imp.Path.Value, `"`)
- }
- if imp.Name.Name == "_" {
- hasAnonymousPkg = true
+ // if name match, break loop and return
+ _, ok := pkgDefs.packages[path]
+ if ok {
+ matchedPkgPaths = []string{path}
+ externalPkgPaths = nil
+ } else {
+ externalPkgPaths = []string{path}
+ matchedPkgPaths = nil
+ }
+ break
+ } else if imp.Name.Name == "_" && len(pkg) > 0 {
+ //for unused types
+ pd, ok := pkgDefs.packages[path]
+ if ok {
+ if pd.Name == pkg {
+ matchedPkgPaths = append(matchedPkgPaths, path)
+ }
+ } else if matchLastPathPart(path) {
+ externalPkgPaths = append(externalPkgPaths, path)
+ }
+ } else if imp.Name.Name == "." && len(pkg) == 0 {
+ _, ok := pkgDefs.packages[path]
+ if ok {
+ matchedPkgPaths = append(matchedPkgPaths, path)
+ } else if len(pkg) == 0 || matchLastPathPart(path) {
+ externalPkgPaths = append(externalPkgPaths, path)
+ }
}
-
- continue
- }
- if pkgs.packages != nil {
- path := strings.Trim(imp.Path.Value, `"`)
- if fuzzy {
- if matchLastPathPart(path) {
- return path
+ } else if pkgDefs.packages != nil && len(pkg) > 0 {
+ pd, ok := pkgDefs.packages[path]
+ if ok {
+ if pd.Name == pkg {
+ matchedPkgPaths = append(matchedPkgPaths, path)
}
- } else if pd, ok := pkgs.packages[path]; ok && pd.Name == pkg {
- return path
+ } else if matchLastPathPart(path) {
+ externalPkgPaths = append(externalPkgPaths, path)
}
}
}
- // match unnamed package
- if hasAnonymousPkg && pkgs.packages != nil {
- for _, imp := range file.Imports {
- if imp.Name == nil {
- continue
- }
- if imp.Name.Name == "_" {
- path := strings.Trim(imp.Path.Value, `"`)
- if fuzzy {
- if matchLastPathPart(path) {
- return path
- }
- } else if pd, ok := pkgs.packages[path]; ok && pd.Name == pkg {
- return path
+ if len(pkg) == 0 || file.Name.Name == pkg {
+ matchedPkgPaths = append(matchedPkgPaths, pkgDefs.files[file].PackagePath)
+ }
+
+ return
+}
+
+func (pkgDefs *PackagesDefinitions) findTypeSpecFromPackagePaths(matchedPkgPaths, externalPkgPaths []string, name string) (typeDef *TypeSpecDef) {
+ for _, pkgPath := range matchedPkgPaths {
+ typeDef = pkgDefs.findTypeSpec(pkgPath, name)
+ if typeDef != nil {
+ return typeDef
+ }
+ }
+
+ if pkgDefs.parseDependency {
+ for _, pkgPath := range externalPkgPaths {
+ if err := pkgDefs.loadExternalPackage(pkgPath); err == nil {
+ typeDef = pkgDefs.findTypeSpec(pkgPath, name)
+ if typeDef != nil {
+ return typeDef
}
}
}
}
- return ""
+ return typeDef
}
// FindTypeSpec finds out TypeSpecDef of a type by typeName
// @typeName the name of the target type, if it starts with a package name, find its own package path from imports on top of @file
// @file the ast.file in which @typeName is used
// @pkgPath the package path of @file.
-func (pkgs *PackagesDefinitions) FindTypeSpec(typeName string, file *ast.File, parseDependency bool) *TypeSpecDef {
+func (pkgDefs *PackagesDefinitions) FindTypeSpec(typeName string, file *ast.File) *TypeSpecDef {
if IsGolangPrimitiveType(typeName) {
return nil
}
+
if file == nil { // for test
- return pkgs.uniqueDefinitions[typeName]
+ return pkgDefs.uniqueDefinitions[typeName]
}
- parts := strings.Split(typeName, ".")
+ parts := strings.Split(strings.Split(typeName, "[")[0], ".")
if len(parts) > 1 {
- isAliasPkgName := func(file *ast.File, pkgName string) bool {
- if file != nil && file.Imports != nil {
- for _, pkg := range file.Imports {
- if pkg.Name != nil && pkg.Name.Name == pkgName {
- return true
- }
- }
- }
-
- return false
- }
-
- if !isAliasPkgName(file, parts[0]) {
- typeDef, ok := pkgs.uniqueDefinitions[typeName]
- if ok {
- return typeDef
- }
- }
- pkgPath := pkgs.findPackagePathFromImports(parts[0], file, false)
- if len(pkgPath) == 0 {
- // check if the current package
- if parts[0] == file.Name.Name {
- pkgPath = pkgs.files[file].PackagePath
- } else if parseDependency {
- // take it as an external package, needs to be loaded
- if pkgPath = pkgs.findPackagePathFromImports(parts[0], file, true); len(pkgPath) > 0 {
- if err := pkgs.loadExternalPackage(pkgPath); err != nil {
- return nil
- }
- }
- }
+ typeDef, ok := pkgDefs.uniqueDefinitions[typeName]
+ if ok {
+ return typeDef
}
- return pkgs.findTypeSpec(pkgPath, parts[1])
+ pkgPaths, externalPkgPaths := pkgDefs.findPackagePathFromImports(parts[0], file)
+ typeDef = pkgDefs.findTypeSpecFromPackagePaths(pkgPaths, externalPkgPaths, parts[1])
+ return pkgDefs.parametrizeGenericType(file, typeDef, typeName)
}
- typeDef, ok := pkgs.uniqueDefinitions[fullTypeName(file.Name.Name, typeName)]
+ typeDef, ok := pkgDefs.uniqueDefinitions[fullTypeName(file.Name.Name, typeName)]
if ok {
return typeDef
}
- typeDef = pkgs.findTypeSpec(pkgs.files[file].PackagePath, typeName)
- if typeDef != nil {
+ //in case that comment //@name renamed the type with a name without a dot
+ typeDef, ok = pkgDefs.uniqueDefinitions[typeName]
+ if ok {
return typeDef
}
- for _, imp := range file.Imports {
- if imp.Name != nil && imp.Name.Name == "." {
- typeDef := pkgs.findTypeSpec(strings.Trim(imp.Path.Value, `"`), typeName)
- if typeDef != nil {
- return typeDef
- }
- }
+ name := parts[0]
+ typeDef, ok = pkgDefs.uniqueDefinitions[fullTypeName(file.Name.Name, name)]
+ if !ok {
+ pkgPaths, externalPkgPaths := pkgDefs.findPackagePathFromImports("", file)
+ typeDef = pkgDefs.findTypeSpecFromPackagePaths(pkgPaths, externalPkgPaths, name)
}
-
- return nil
+ return pkgDefs.parametrizeGenericType(file, typeDef, typeName)
}
diff --git a/vendor/github.com/swaggo/swag/parser.go b/vendor/github.com/swaggo/swag/parser.go
index 387151a..190f713 100644
--- a/vendor/github.com/swaggo/swag/parser.go
+++ b/vendor/github.com/swaggo/swag/parser.go
@@ -1,6 +1,7 @@
package swag
import (
+ "context"
"encoding/json"
"errors"
"fmt"
@@ -8,10 +9,8 @@ import (
"go/build"
goparser "go/parser"
"go/token"
- "io/ioutil"
"log"
"net/http"
- "net/url"
"os"
"os/exec"
"path/filepath"
@@ -48,13 +47,39 @@ const (
deprecatedAttr = "@deprecated"
securityAttr = "@security"
titleAttr = "@title"
+ conNameAttr = "@contact.name"
+ conURLAttr = "@contact.url"
+ conEmailAttr = "@contact.email"
+ licNameAttr = "@license.name"
+ licURLAttr = "@license.url"
versionAttr = "@version"
descriptionAttr = "@description"
descriptionMarkdownAttr = "@description.markdown"
+ secBasicAttr = "@securitydefinitions.basic"
+ secAPIKeyAttr = "@securitydefinitions.apikey"
+ secApplicationAttr = "@securitydefinitions.oauth2.application"
+ secImplicitAttr = "@securitydefinitions.oauth2.implicit"
+ secPasswordAttr = "@securitydefinitions.oauth2.password"
+ secAccessCodeAttr = "@securitydefinitions.oauth2.accesscode"
+ tosAttr = "@termsofservice"
xCodeSamplesAttr = "@x-codesamples"
scopeAttrPrefix = "@scope."
)
+// ParseFlag determine what to parse
+type ParseFlag int
+
+const (
+ // ParseNone parse nothing
+ ParseNone ParseFlag = 0x00
+ // ParseOperations parse operations
+ ParseOperations = 0x01
+ // ParseModels parse models
+ ParseModels = 0x02
+ // ParseAll parse operations and models
+ ParseAll = ParseOperations | ParseModels
+)
+
var (
// ErrRecursiveParseStruct recursively parsing struct.
ErrRecursiveParseStruct = errors.New("recursively parsing struct")
@@ -65,7 +90,7 @@ var (
// ErrFailedConvertPrimitiveType Failed to convert for swag to interpretable type.
ErrFailedConvertPrimitiveType = errors.New("swag property: failed convert primitive type")
- // ErrSkippedField .swaggo specifies field should be skipped
+ // ErrSkippedField .swaggo specifies field should be skipped.
ErrSkippedField = errors.New("field is skipped by global overrides")
)
@@ -93,15 +118,6 @@ type Parser struct {
// outputSchemas store schemas which will be export to swagger
outputSchemas map[*TypeSpecDef]*Schema
- // existSchemaNames store names of models for conflict determination
- existSchemaNames map[string]*Schema
-
- // toBeRenamedSchemas names of models to be renamed
- toBeRenamedSchemas map[string]string
-
- // toBeRenamedSchemas URLs of ref models to be renamed
- toBeRenamedRefURLs []*url.URL
-
// PropNamingStrategy naming strategy
PropNamingStrategy string
@@ -117,6 +133,9 @@ type Parser struct {
// Strict whether swag should error or warn when it detects cases which are most likely user errors
Strict bool
+ // RequiredByDefault set validation required for all fields by default
+ RequiredByDefault bool
+
// structStack stores full names of the structures that were already parsed or are being parsed now
structStack []*TypeSpecDef
@@ -132,6 +151,9 @@ type Parser struct {
// excludes excludes dirs and files in SearchDir
excludes map[string]struct{}
+ // tells parser to include only specific extension
+ parseExtension string
+
// debugging output goes here
debug Debugger
@@ -140,14 +162,20 @@ type Parser struct {
// Overrides allows global replacements of types. A blank replacement will be skipped.
Overrides map[string]string
+
+ // parseGoList whether swag use go list to parse dependency
+ parseGoList bool
+
+ // tags to filter the APIs after
+ tags map[string]struct{}
}
-// FieldParserFactory create FieldParser
+// FieldParserFactory create FieldParser.
type FieldParserFactory func(ps *Parser, field *ast.Field) FieldParser
-// FieldParser parse struct field
+// FieldParser parse struct field.
type FieldParser interface {
- ShouldSkip() (bool, error)
+ ShouldSkip() bool
FieldName() (string, error)
CustomSchema() (*spec.Schema, error)
ComplementSchema(schema *spec.Schema) error
@@ -161,8 +189,6 @@ type Debugger interface {
// New creates a new Parser with default properties.
func New(options ...func(*Parser)) *Parser {
- // parser.swagger.SecurityDefinitions =
-
parser := &Parser{
swagger: &spec.Swagger{
SwaggerProps: spec.SwaggerProps{
@@ -177,18 +203,23 @@ func New(options ...func(*Parser)) *Parser {
},
Paths: &spec.Paths{
Paths: make(map[string]spec.PathItem),
+ VendorExtensible: spec.VendorExtensible{
+ Extensions: nil,
+ },
},
Definitions: make(map[string]spec.Schema),
SecurityDefinitions: make(map[string]*spec.SecurityScheme),
},
+ VendorExtensible: spec.VendorExtensible{
+ Extensions: nil,
+ },
},
packages: NewPackagesDefinitions(),
debug: log.New(os.Stdout, "", log.LstdFlags),
parsedSchemas: make(map[*TypeSpecDef]*Schema),
outputSchemas: make(map[*TypeSpecDef]*Schema),
- existSchemaNames: make(map[string]*Schema),
- toBeRenamedSchemas: make(map[string]string),
excludes: make(map[string]struct{}),
+ tags: make(map[string]struct{}),
fieldParserFactory: newTagBaseFieldParser,
Overrides: make(map[string]string),
}
@@ -197,9 +228,21 @@ func New(options ...func(*Parser)) *Parser {
option(parser)
}
+ parser.packages.debug = parser.debug
+
return parser
}
+// SetParseDependency sets whether to parse the dependent packages.
+func SetParseDependency(parseDependency bool) func(*Parser) {
+ return func(p *Parser) {
+ p.ParseDependency = parseDependency
+ if p.packages != nil {
+ p.packages.parseDependency = parseDependency
+ }
+ }
+}
+
// SetMarkdownFileDirectory sets the directory to search for markdown files.
func SetMarkdownFileDirectory(directoryPath string) func(*Parser) {
return func(p *Parser) {
@@ -227,6 +270,25 @@ func SetExcludedDirsAndFiles(excludes string) func(*Parser) {
}
}
+// SetTags sets the tags to be included
+func SetTags(include string) func(*Parser) {
+ return func(p *Parser) {
+ for _, f := range strings.Split(include, ",") {
+ f = strings.TrimSpace(f)
+ if f != "" {
+ p.tags[f] = struct{}{}
+ }
+ }
+ }
+}
+
+// SetParseExtension parses only those operations which match given extension
+func SetParseExtension(parseExtension string) func(*Parser) {
+ return func(p *Parser) {
+ p.parseExtension = parseExtension
+ }
+}
+
// SetStrict sets whether swag should error or warn when it detects cases which are most likely user errors.
func SetStrict(strict bool) func(*Parser) {
return func(p *Parser) {
@@ -237,7 +299,9 @@ func SetStrict(strict bool) func(*Parser) {
// SetDebugger allows the use of user-defined implementations.
func SetDebugger(logger Debugger) func(parser *Parser) {
return func(p *Parser) {
- p.debug = logger
+ if logger != nil {
+ p.debug = logger
+ }
}
}
@@ -257,6 +321,13 @@ func SetOverrides(overrides map[string]string) func(parser *Parser) {
}
}
+// ParseUsingGoList sets whether swag use go list to parse dependency
+func ParseUsingGoList(enabled bool) func(parser *Parser) {
+ return func(p *Parser) {
+ p.parseGoList = enabled
+ }
+}
+
// ParseAPI parses general api info for given searchDir and mainAPIFile.
func (parser *Parser) ParseAPI(searchDir string, mainAPIFile string, parseDepth int) error {
return parser.ParseAPIMultiSearchDir([]string{searchDir}, mainAPIFile, parseDepth)
@@ -283,26 +354,41 @@ func (parser *Parser) ParseAPIMultiSearchDir(searchDirs []string, mainAPIFile st
return err
}
+ // Use 'go list' command instead of depth.Resolve()
if parser.ParseDependency {
- var t depth.Tree
- t.ResolveInternal = true
- t.MaxDepth = parseDepth
-
- pkgName, err := getPkgName(filepath.Dir(absMainAPIFilePath))
- if err != nil {
- return err
- }
+ if parser.parseGoList {
+ pkgs, err := listPackages(context.Background(), filepath.Dir(absMainAPIFilePath), nil, "-deps")
+ if err != nil {
+ return fmt.Errorf("pkg %s cannot find all dependencies, %s", filepath.Dir(absMainAPIFilePath), err)
+ }
- err = t.Resolve(pkgName)
- if err != nil {
- return fmt.Errorf("pkg %s cannot find all dependencies, %s", pkgName, err)
- }
+ length := len(pkgs)
+ for i := 0; i < length; i++ {
+ err := parser.getAllGoFileInfoFromDepsByList(pkgs[i])
+ if err != nil {
+ return err
+ }
+ }
+ } else {
+ var t depth.Tree
+ t.ResolveInternal = true
+ t.MaxDepth = parseDepth
- for i := 0; i < len(t.Root.Deps); i++ {
- err := parser.getAllGoFileInfoFromDeps(&t.Root.Deps[i])
+ pkgName, err := getPkgName(filepath.Dir(absMainAPIFilePath))
if err != nil {
return err
}
+
+ err = t.Resolve(pkgName)
+ if err != nil {
+ return fmt.Errorf("pkg %s cannot find all dependencies, %s", pkgName, err)
+ }
+ for i := 0; i < len(t.Root.Deps); i++ {
+ err := parser.getAllGoFileInfoFromDeps(&t.Root.Deps[i])
+ if err != nil {
+ return err
+ }
+ }
}
}
@@ -316,20 +402,20 @@ func (parser *Parser) ParseAPIMultiSearchDir(searchDirs []string, mainAPIFile st
return err
}
- err = rangeFiles(parser.packages.files, parser.ParseRouterAPIInfo)
+ err = parser.packages.RangeFiles(parser.ParseRouterAPIInfo)
if err != nil {
return err
}
- parser.renameRefSchemas()
-
return parser.checkOperationIDUniqueness()
}
func getPkgName(searchDir string) (string, error) {
cmd := exec.Command("go", "list", "-f={{.ImportPath}}")
cmd.Dir = searchDir
+
var stdout, stderr strings.Builder
+
cmd.Stdout = &stdout
cmd.Stderr = &stderr
@@ -342,20 +428,14 @@ func getPkgName(searchDir string) (string, error) {
if outStr[0] == '_' { // will shown like _/{GOPATH}/src/{YOUR_PACKAGE} when NOT enable GO MODULE.
outStr = strings.TrimPrefix(outStr, "_"+build.Default.GOPATH+"/src/")
}
+
f := strings.Split(outStr, "\n")
+
outStr = f[0]
return outStr, nil
}
-func initIfEmpty(license *spec.License) *spec.License {
- if license == nil {
- return new(spec.License)
- }
-
- return license
-}
-
// ParseGeneralAPIInfo parses general api info for given mainAPIFile path.
func (parser *Parser) ParseGeneralAPIInfo(mainAPIFile string) error {
fileTree, err := goparser.ParseFile(token.NewFileSet(), mainAPIFile, nil, goparser.ParseComments)
@@ -370,7 +450,8 @@ func (parser *Parser) ParseGeneralAPIInfo(mainAPIFile string) error {
if !isGeneralAPIComment(comments) {
continue
}
- err := parseGeneralAPIInfo(parser, comments)
+
+ err = parseGeneralAPIInfo(parser, comments)
if err != nil {
return err
}
@@ -383,49 +464,44 @@ func parseGeneralAPIInfo(parser *Parser, comments []string) error {
previousAttribute := ""
// parsing classic meta data model
- for i, commentLine := range comments {
- attribute := strings.Split(commentLine, " ")[0]
- value := strings.TrimSpace(commentLine[len(attribute):])
- multilineBlock := false
- if previousAttribute == attribute {
- multilineBlock = true
- }
- switch strings.ToLower(attribute) {
- case versionAttr:
- parser.swagger.Info.Version = value
- case titleAttr:
- parser.swagger.Info.Title = value
+ for line := 0; line < len(comments); line++ {
+ commentLine := comments[line]
+ commentLine = strings.TrimSpace(commentLine)
+ if len(commentLine) == 0 {
+ continue
+ }
+ fields := FieldsByAnySpace(commentLine, 2)
+
+ attribute := fields[0]
+ var value string
+ if len(fields) > 1 {
+ value = fields[1]
+ }
+
+ switch attr := strings.ToLower(attribute); attr {
+ case versionAttr, titleAttr, tosAttr, licNameAttr, licURLAttr, conNameAttr, conURLAttr, conEmailAttr:
+ setSwaggerInfo(parser.swagger, attr, value)
case descriptionAttr:
- if multilineBlock {
+ if previousAttribute == attribute {
parser.swagger.Info.Description += "\n" + value
continue
}
- parser.swagger.Info.Description = value
- case "@description.markdown":
+
+ setSwaggerInfo(parser.swagger, attr, value)
+ case descriptionMarkdownAttr:
commentInfo, err := getMarkdownForTag("api", parser.markdownFileDir)
if err != nil {
return err
}
- parser.swagger.Info.Description = string(commentInfo)
- case "@termsofservice":
- parser.swagger.Info.TermsOfService = value
- case "@contact.name":
- parser.swagger.Info.Contact.Name = value
- case "@contact.email":
- parser.swagger.Info.Contact.Email = value
- case "@contact.url":
- parser.swagger.Info.Contact.URL = value
- case "@license.name":
- parser.swagger.Info.License = initIfEmpty(parser.swagger.Info.License)
- parser.swagger.Info.License.Name = value
- case "@license.url":
- parser.swagger.Info.License = initIfEmpty(parser.swagger.Info.License)
- parser.swagger.Info.License.URL = value
+
+ setSwaggerInfo(parser.swagger, descriptionAttr, string(commentInfo))
+
case "@host":
parser.swagger.Host = value
case "@basepath":
parser.swagger.BasePath = value
+
case acceptAttr:
err := parser.ParseAcceptComment(value)
if err != nil {
@@ -437,7 +513,7 @@ func parseGeneralAPIInfo(parser *Parser, comments []string) error {
return err
}
case "@schemes":
- parser.swagger.Schemes = getSchemes(commentLine)
+ parser.swagger.Schemes = strings.Split(value, " ")
case "@tag.name":
parser.swagger.Tags = append(parser.swagger.Tags, spec.Tag{
TagProps: spec.TagProps{
@@ -450,85 +526,67 @@ func parseGeneralAPIInfo(parser *Parser, comments []string) error {
replaceLastTag(parser.swagger.Tags, tag)
case "@tag.description.markdown":
tag := parser.swagger.Tags[len(parser.swagger.Tags)-1]
+
commentInfo, err := getMarkdownForTag(tag.TagProps.Name, parser.markdownFileDir)
if err != nil {
return err
}
+
tag.TagProps.Description = string(commentInfo)
replaceLastTag(parser.swagger.Tags, tag)
case "@tag.docs.url":
tag := parser.swagger.Tags[len(parser.swagger.Tags)-1]
tag.TagProps.ExternalDocs = &spec.ExternalDocumentation{
- URL: value,
+ URL: value,
+ Description: "",
}
+
replaceLastTag(parser.swagger.Tags, tag)
case "@tag.docs.description":
tag := parser.swagger.Tags[len(parser.swagger.Tags)-1]
if tag.TagProps.ExternalDocs == nil {
return fmt.Errorf("%s needs to come after a @tags.docs.url", attribute)
}
+
tag.TagProps.ExternalDocs.Description = value
replaceLastTag(parser.swagger.Tags, tag)
- case "@securitydefinitions.basic":
- parser.swagger.SecurityDefinitions[value] = spec.BasicAuth()
- case "@securitydefinitions.apikey":
- attrMap, _, _, err := parseSecAttr(attribute, []string{"@in", "@name"}, comments[i+1:])
- if err != nil {
- return err
- }
- parser.swagger.SecurityDefinitions[value] = spec.APIKeyAuth(attrMap["@name"], attrMap["@in"])
- case "@securitydefinitions.oauth2.application":
- attrMap, scopes, extensions, err := parseSecAttr(attribute, []string{"@tokenurl"}, comments[i+1:])
- if err != nil {
- return err
- }
- parser.swagger.SecurityDefinitions[value] = secOAuth2Application(attrMap["@tokenurl"], scopes, extensions)
- case "@securitydefinitions.oauth2.implicit":
- attrs, scopes, ext, err := parseSecAttr(attribute, []string{"@authorizationurl"}, comments[i+1:])
- if err != nil {
- return err
- }
- parser.swagger.SecurityDefinitions[value] = secOAuth2Implicit(attrs["@authorizationurl"], scopes, ext)
- case "@securitydefinitions.oauth2.password":
- attrs, scopes, ext, err := parseSecAttr(attribute, []string{"@tokenurl"}, comments[i+1:])
- if err != nil {
- return err
- }
- parser.swagger.SecurityDefinitions[value] = secOAuth2Password(attrs["@tokenurl"], scopes, ext)
- case "@securitydefinitions.oauth2.accesscode":
- attrs, scopes, ext, err := parseSecAttr(attribute, []string{"@tokenurl", "@authorizationurl"}, comments[i+1:])
+
+ case secBasicAttr, secAPIKeyAttr, secApplicationAttr, secImplicitAttr, secPasswordAttr, secAccessCodeAttr:
+ scheme, err := parseSecAttributes(attribute, comments, &line)
if err != nil {
return err
}
- parser.swagger.SecurityDefinitions[value] = secOAuth2AccessToken(attrs["@authorizationurl"], attrs["@tokenurl"], scopes, ext)
+
+ parser.swagger.SecurityDefinitions[value] = scheme
+
case "@query.collection.format":
- parser.collectionFormatInQuery = value
+ parser.collectionFormatInQuery = TransToValidCollectionFormat(value)
default:
- prefixExtension := "@x-"
- // Prefix extension + 1 char + 1 space + 1 char
- if len(attribute) > 5 && attribute[:len(prefixExtension)] == prefixExtension {
+ if strings.HasPrefix(attribute, "@x-") {
+ extensionName := attribute[1:]
+
extExistsInSecurityDef := false
// for each security definition
for _, v := range parser.swagger.SecurityDefinitions {
// check if extension exists
- _, extExistsInSecurityDef = v.VendorExtensible.Extensions.GetString(attribute[1:])
+ _, extExistsInSecurityDef = v.VendorExtensible.Extensions.GetString(extensionName)
// if it exists in at least one, then we stop iterating
if extExistsInSecurityDef {
break
}
}
+
// if it is present on security def, don't add it again
if extExistsInSecurityDef {
break
}
- var valueJSON interface{}
- split := strings.SplitAfter(commentLine, attribute+" ")
- if len(split) < 2 {
+ if len(value) == 0 {
return fmt.Errorf("annotation %s need a value", attribute)
}
- extensionName := "x-" + strings.SplitAfter(attribute, prefixExtension)[1]
- err := json.Unmarshal([]byte(split[1]), &valueJSON)
+
+ var valueJSON interface{}
+ err := json.Unmarshal([]byte(value), &valueJSON)
if err != nil {
return fmt.Errorf("annotation %s need a valid json value", attribute)
}
@@ -539,143 +597,202 @@ func parseGeneralAPIInfo(parser *Parser, comments []string) error {
if parser.swagger.Extensions == nil {
parser.swagger.Extensions = make(map[string]interface{})
}
+
parser.swagger.Extensions[attribute[1:]] = valueJSON
}
}
}
+
previousAttribute = attribute
}
return nil
}
-// ParseAcceptComment parses comment for given `accept` comment string.
-func (parser *Parser) ParseAcceptComment(commentLine string) error {
- return parseMimeTypeList(commentLine, &parser.swagger.Consumes, "%v accept type can't be accepted")
-}
-
-// ParseProduceComment parses comment for given `produce` comment string.
-func (parser *Parser) ParseProduceComment(commentLine string) error {
- return parseMimeTypeList(commentLine, &parser.swagger.Produces, "%v produce type can't be accepted")
+func setSwaggerInfo(swagger *spec.Swagger, attribute, value string) {
+ switch attribute {
+ case versionAttr:
+ swagger.Info.Version = value
+ case titleAttr:
+ swagger.Info.Title = value
+ case tosAttr:
+ swagger.Info.TermsOfService = value
+ case descriptionAttr:
+ swagger.Info.Description = value
+ case conNameAttr:
+ swagger.Info.Contact.Name = value
+ case conEmailAttr:
+ swagger.Info.Contact.Email = value
+ case conURLAttr:
+ swagger.Info.Contact.URL = value
+ case licNameAttr:
+ swagger.Info.License = initIfEmpty(swagger.Info.License)
+ swagger.Info.License.Name = value
+ case licURLAttr:
+ swagger.Info.License = initIfEmpty(swagger.Info.License)
+ swagger.Info.License.URL = value
+ }
}
-func isGeneralAPIComment(comments []string) bool {
- for _, commentLine := range comments {
- attribute := strings.ToLower(strings.Split(commentLine, " ")[0])
- switch attribute {
- // The @summary, @router, @success, @failure annotation belongs to Operation
- case summaryAttr, routerAttr, successAttr, failureAttr, responseAttr:
- return false
+func parseSecAttributes(context string, lines []string, index *int) (*spec.SecurityScheme, error) {
+ const (
+ in = "@in"
+ name = "@name"
+ descriptionAttr = "@description"
+ tokenURL = "@tokenurl"
+ authorizationURL = "@authorizationurl"
+ )
+
+ var search []string
+
+ attribute := strings.ToLower(FieldsByAnySpace(lines[*index], 2)[0])
+ switch attribute {
+ case secBasicAttr:
+ return spec.BasicAuth(), nil
+ case secAPIKeyAttr:
+ search = []string{in, name}
+ case secApplicationAttr, secPasswordAttr:
+ search = []string{tokenURL}
+ case secImplicitAttr:
+ search = []string{authorizationURL}
+ case secAccessCodeAttr:
+ search = []string{tokenURL, authorizationURL}
+ }
+
+ // For the first line we get the attributes in the context parameter, so we skip to the next one
+ *index++
+
+ attrMap, scopes := make(map[string]string), make(map[string]string)
+ extensions, description := make(map[string]interface{}), ""
+
+ for ; *index < len(lines); *index++ {
+ v := strings.TrimSpace(lines[*index])
+ if len(v) == 0 {
+ continue
}
- }
- return true
-}
+ fields := FieldsByAnySpace(v, 2)
+ securityAttr := strings.ToLower(fields[0])
+ var value string
+ if len(fields) > 1 {
+ value = fields[1]
+ }
-func parseSecAttr(context string, search []string, lines []string) (map[string]string, map[string]string, map[string]interface{}, error) {
- attrMap := map[string]string{}
- scopes := map[string]string{}
- extensions := map[string]interface{}{}
- for _, v := range lines {
- securityAttr := strings.ToLower(strings.Split(v, " ")[0])
for _, findterm := range search {
if securityAttr == findterm {
- attrMap[securityAttr] = strings.TrimSpace(v[len(securityAttr):])
+ attrMap[securityAttr] = value
- continue
+ break
}
}
+
isExists, err := isExistsScope(securityAttr)
if err != nil {
- return nil, nil, nil, err
+ return nil, err
}
+
if isExists {
scopes[securityAttr[len(scopeAttrPrefix):]] = v[len(securityAttr):]
}
+
if strings.HasPrefix(securityAttr, "@x-") {
// Add the custom attribute without the @
- extensions[securityAttr[1:]] = strings.TrimSpace(v[len(securityAttr):])
+ extensions[securityAttr[1:]] = value
}
+
+ // Not mandatory field
+ if securityAttr == descriptionAttr {
+ description = value
+ }
+
// next securityDefinitions
if strings.Index(securityAttr, "@securitydefinitions.") == 0 {
+ // Go back to the previous line and break
+ *index--
+
break
}
}
if len(attrMap) != len(search) {
- return nil, nil, nil, fmt.Errorf("%s is %v required", context, search)
+ return nil, fmt.Errorf("%s is %v required", context, search)
}
- return attrMap, scopes, extensions, nil
-}
+ var scheme *spec.SecurityScheme
-func secOAuth2Application(tokenURL string, scopes map[string]string,
- extensions map[string]interface{}) *spec.SecurityScheme {
- securityScheme := spec.OAuth2Application(tokenURL)
- securityScheme.VendorExtensible.Extensions = handleSecuritySchemaExtensions(extensions)
- for scope, description := range scopes {
- securityScheme.AddScope(scope, description)
+ switch attribute {
+ case secAPIKeyAttr:
+ scheme = spec.APIKeyAuth(attrMap[name], attrMap[in])
+ case secApplicationAttr:
+ scheme = spec.OAuth2Application(attrMap[tokenURL])
+ case secImplicitAttr:
+ scheme = spec.OAuth2Implicit(attrMap[authorizationURL])
+ case secPasswordAttr:
+ scheme = spec.OAuth2Password(attrMap[tokenURL])
+ case secAccessCodeAttr:
+ scheme = spec.OAuth2AccessToken(attrMap[authorizationURL], attrMap[tokenURL])
}
- return securityScheme
-}
+ scheme.Description = description
+
+ for extKey, extValue := range extensions {
+ scheme.AddExtension(extKey, extValue)
+ }
-func secOAuth2Implicit(authorizationURL string, scopes map[string]string,
- extensions map[string]interface{}) *spec.SecurityScheme {
- securityScheme := spec.OAuth2Implicit(authorizationURL)
- securityScheme.VendorExtensible.Extensions = handleSecuritySchemaExtensions(extensions)
- for scope, description := range scopes {
- securityScheme.AddScope(scope, description)
+ for scope, scopeDescription := range scopes {
+ scheme.AddScope(scope, scopeDescription)
}
- return securityScheme
+ return scheme, nil
}
-func secOAuth2Password(tokenURL string, scopes map[string]string,
- extensions map[string]interface{}) *spec.SecurityScheme {
- securityScheme := spec.OAuth2Password(tokenURL)
- securityScheme.VendorExtensible.Extensions = handleSecuritySchemaExtensions(extensions)
- for scope, description := range scopes {
- securityScheme.AddScope(scope, description)
+func initIfEmpty(license *spec.License) *spec.License {
+ if license == nil {
+ return new(spec.License)
}
- return securityScheme
+ return license
}
-func secOAuth2AccessToken(authorizationURL, tokenURL string,
- scopes map[string]string, extensions map[string]interface{}) *spec.SecurityScheme {
- securityScheme := spec.OAuth2AccessToken(authorizationURL, tokenURL)
- securityScheme.VendorExtensible.Extensions = handleSecuritySchemaExtensions(extensions)
- for scope, description := range scopes {
- securityScheme.AddScope(scope, description)
- }
+// ParseAcceptComment parses comment for given `accept` comment string.
+func (parser *Parser) ParseAcceptComment(commentLine string) error {
+ return parseMimeTypeList(commentLine, &parser.swagger.Consumes, "%v accept type can't be accepted")
+}
- return securityScheme
+// ParseProduceComment parses comment for given `produce` comment string.
+func (parser *Parser) ParseProduceComment(commentLine string) error {
+ return parseMimeTypeList(commentLine, &parser.swagger.Produces, "%v produce type can't be accepted")
}
-func handleSecuritySchemaExtensions(providedExtensions map[string]interface{}) spec.Extensions {
- var extensions spec.Extensions
- if len(providedExtensions) > 0 {
- extensions = make(map[string]interface{}, len(providedExtensions))
- for key, value := range providedExtensions {
- extensions[key] = value
+func isGeneralAPIComment(comments []string) bool {
+ for _, commentLine := range comments {
+ commentLine = strings.TrimSpace(commentLine)
+ if len(commentLine) == 0 {
+ continue
+ }
+ attribute := strings.ToLower(FieldsByAnySpace(commentLine, 2)[0])
+ switch attribute {
+ // The @summary, @router, @success, @failure annotation belongs to Operation
+ case summaryAttr, routerAttr, successAttr, failureAttr, responseAttr:
+ return false
}
}
- return extensions
+ return true
}
func getMarkdownForTag(tagName string, dirPath string) ([]byte, error) {
- filesInfos, err := ioutil.ReadDir(dirPath)
+ dirEntries, err := os.ReadDir(dirPath)
if err != nil {
return nil, err
}
- for _, fileInfo := range filesInfos {
- if fileInfo.IsDir() {
+ for _, entry := range dirEntries {
+ if entry.IsDir() {
continue
}
- fileName := fileInfo.Name()
+
+ fileName := entry.Name()
if !strings.Contains(fileName, ".md") {
continue
@@ -683,7 +800,8 @@ func getMarkdownForTag(tagName string, dirPath string) ([]byte, error) {
if strings.Contains(fileName, tagName) {
fullPath := filepath.Join(dirPath, fileName)
- commentInfo, err := ioutil.ReadFile(fullPath)
+
+ commentInfo, err := os.ReadFile(fullPath)
if err != nil {
return nil, fmt.Errorf("Failed to read markdown file %s error: %s ", fullPath, err)
}
@@ -708,50 +826,81 @@ func isExistsScope(scope string) (bool, error) {
return strings.Contains(scope, scopeAttrPrefix), nil
}
-// getSchemes parses swagger schemes for given commentLine.
-func getSchemes(commentLine string) []string {
- attribute := strings.ToLower(strings.Split(commentLine, " ")[0])
+func getTagsFromComment(comment string) (tags []string) {
+ commentLine := strings.TrimSpace(strings.TrimLeft(comment, "/"))
+ if len(commentLine) == 0 {
+ return nil
+ }
+
+ attribute := strings.Fields(commentLine)[0]
+ lineRemainder, lowerAttribute := strings.TrimSpace(commentLine[len(attribute):]), strings.ToLower(attribute)
+
+ if lowerAttribute == tagsAttr {
+ for _, tag := range strings.Split(lineRemainder, ",") {
+ tags = append(tags, strings.TrimSpace(tag))
+ }
+ }
+ return
- return strings.Split(strings.TrimSpace(commentLine[len(attribute):]), " ")
}
-// ParseRouterAPIInfo parses router api info for given astFile.
-func (parser *Parser) ParseRouterAPIInfo(fileName string, astFile *ast.File) error {
- for _, astDescription := range astFile.Decls {
- astDeclaration, ok := astDescription.(*ast.FuncDecl)
- if ok && astDeclaration.Doc != nil && astDeclaration.Doc.List != nil {
- // for per 'function' comment, create a new 'Operation' object
- operation := NewOperation(parser, SetCodeExampleFilesDirectory(parser.codeExampleFilesDir))
- for _, comment := range astDeclaration.Doc.List {
- err := operation.ParseComment(comment.Text, astFile)
- if err != nil {
- return fmt.Errorf("ParseComment error in file %s :%+v", fileName, err)
+func (parser *Parser) matchTags(comments []*ast.Comment) (match bool) {
+ if len(parser.tags) != 0 {
+ for _, comment := range comments {
+ for _, tag := range getTagsFromComment(comment.Text) {
+ if _, has := parser.tags["!"+tag]; has {
+ return false
+ }
+ if _, has := parser.tags[tag]; has {
+ match = true // keep iterating as it may contain a tag that is excluded
}
}
+ }
+ return
+ }
+ return true
+}
- for _, routeProperties := range operation.RouterProperties {
- var pathItem spec.PathItem
- var ok bool
+func matchExtension(extensionToMatch string, comments []*ast.Comment) (match bool) {
+ if len(extensionToMatch) != 0 {
+ for _, comment := range comments {
+ commentLine := strings.TrimSpace(strings.TrimLeft(comment.Text, "/"))
+ fields := FieldsByAnySpace(commentLine, 2)
+ if len(fields) > 0 {
+ lowerAttribute := strings.ToLower(fields[0])
- pathItem, ok = parser.swagger.Paths.Paths[routeProperties.Path]
- if !ok {
- pathItem = spec.PathItem{}
+ if lowerAttribute == fmt.Sprintf("@x-%s", strings.ToLower(extensionToMatch)) {
+ return true
}
+ }
+ }
+ return false
+ }
+ return true
+}
- op := refRouteMethodOp(&pathItem, routeProperties.HTTPMethod)
-
- // check if we already have a operation for this path and method
- if *op != nil {
- err := fmt.Errorf("route %s %s is declared multiple times", routeProperties.HTTPMethod, routeProperties.Path)
- if parser.Strict {
- return err
+// ParseRouterAPIInfo parses router api info for given astFile.
+func (parser *Parser) ParseRouterAPIInfo(fileInfo *AstFileInfo) error {
+ for _, astDescription := range fileInfo.File.Decls {
+ if (fileInfo.ParseFlag & ParseOperations) == ParseNone {
+ continue
+ }
+ astDeclaration, ok := astDescription.(*ast.FuncDecl)
+ if ok && astDeclaration.Doc != nil && astDeclaration.Doc.List != nil {
+ if parser.matchTags(astDeclaration.Doc.List) &&
+ matchExtension(parser.parseExtension, astDeclaration.Doc.List) {
+ // for per 'function' comment, create a new 'Operation' object
+ operation := NewOperation(parser, SetCodeExampleFilesDirectory(parser.codeExampleFilesDir))
+ for _, comment := range astDeclaration.Doc.List {
+ err := operation.ParseComment(comment.Text, fileInfo.File)
+ if err != nil {
+ return fmt.Errorf("ParseComment error in file %s :%+v", fileInfo.Path, err)
}
- parser.debug.Printf("warning: %s\n", err)
}
-
- *op = &operation.Operation
-
- parser.swagger.Paths.Paths[routeProperties.Path] = pathItem
+ err := processRouterOperation(parser, operation)
+ if err != nil {
+ return err
+ }
}
}
}
@@ -776,14 +925,48 @@ func refRouteMethodOp(item *spec.PathItem, method string) (op **spec.Operation)
case http.MethodOptions:
op = &item.Options
}
+
return
}
+func processRouterOperation(parser *Parser, operation *Operation) error {
+ for _, routeProperties := range operation.RouterProperties {
+ var (
+ pathItem spec.PathItem
+ ok bool
+ )
+
+ pathItem, ok = parser.swagger.Paths.Paths[routeProperties.Path]
+ if !ok {
+ pathItem = spec.PathItem{}
+ }
+
+ op := refRouteMethodOp(&pathItem, routeProperties.HTTPMethod)
+
+ // check if we already have an operation for this path and method
+ if *op != nil {
+ err := fmt.Errorf("route %s %s is declared multiple times", routeProperties.HTTPMethod, routeProperties.Path)
+ if parser.Strict {
+ return err
+ }
+
+ parser.debug.Printf("warning: %s\n", err)
+ }
+
+ *op = &operation.Operation
+
+ parser.swagger.Paths.Paths[routeProperties.Path] = pathItem
+ }
+
+ return nil
+}
+
func convertFromSpecificToPrimitive(typeName string) (string, error) {
name := typeName
if strings.ContainsRune(name, '.') {
name = strings.Split(name, ".")[1]
}
+
switch strings.ToUpper(name) {
case "TIME", "OBJECTID", "UUID":
return STRING, nil
@@ -795,6 +978,14 @@ func convertFromSpecificToPrimitive(typeName string) (string, error) {
}
func (parser *Parser) getTypeSchema(typeName string, file *ast.File, ref bool) (*spec.Schema, error) {
+ if override, ok := parser.Overrides[typeName]; ok {
+ parser.debug.Printf("Override detected for %s: using %s instead", typeName, override)
+ return parseObjectSchema(parser, override, file)
+ }
+
+ if IsInterfaceLike(typeName) {
+ return &spec.Schema{}, nil
+ }
if IsGolangPrimitiveType(typeName) {
return PrimitiveSchema(TransToValidSchemeType(typeName)), nil
}
@@ -804,7 +995,7 @@ func (parser *Parser) getTypeSchema(typeName string, file *ast.File, ref bool) (
return PrimitiveSchema(schemaType), nil
}
- typeSpecDef := parser.packages.FindTypeSpec(typeName, file, parser.ParseDependency)
+ typeSpecDef := parser.packages.FindTypeSpec(typeName, file)
if typeSpecDef == nil {
return nil, fmt.Errorf("cannot find type definition: %s", typeName)
}
@@ -812,6 +1003,7 @@ func (parser *Parser) getTypeSchema(typeName string, file *ast.File, ref bool) (
if override, ok := parser.Overrides[typeSpecDef.FullPath()]; ok {
if override == "" {
parser.debug.Printf("Override detected for %s: ignoring", typeSpecDef.FullPath())
+
return nil, ErrSkippedField
}
@@ -821,6 +1013,7 @@ func (parser *Parser) getTypeSchema(typeName string, file *ast.File, ref bool) (
if separator == -1 {
// treat as a swaggertype tag
parts := strings.Split(override, ",")
+
return BuildCustomSchema(parts)
}
@@ -830,71 +1023,31 @@ func (parser *Parser) getTypeSchema(typeName string, file *ast.File, ref bool) (
schema, ok := parser.parsedSchemas[typeSpecDef]
if !ok {
var err error
+
schema, err = parser.ParseDefinition(typeSpecDef)
if err != nil {
if err == ErrRecursiveParseStruct && ref {
return parser.getRefTypeSchema(typeSpecDef, schema), nil
}
-
return nil, err
}
}
- if ref && len(schema.Schema.Type) > 0 && schema.Schema.Type[0] == OBJECT {
- return parser.getRefTypeSchema(typeSpecDef, schema), nil
- }
-
- return schema.Schema, nil
-}
-
-func (parser *Parser) renameRefSchemas() {
- if len(parser.toBeRenamedSchemas) == 0 {
- return
- }
-
- // rename schemas in swagger.Definitions
- for name, pkgPath := range parser.toBeRenamedSchemas {
- if schema, ok := parser.swagger.Definitions[name]; ok {
- delete(parser.swagger.Definitions, name)
- name = parser.renameSchema(name, pkgPath)
- parser.swagger.Definitions[name] = schema
- }
- }
-
- // rename URLs if match
- for _, refURL := range parser.toBeRenamedRefURLs {
- parts := strings.Split(refURL.Fragment, "/")
- name := parts[len(parts)-1]
- if pkgPath, ok := parser.toBeRenamedSchemas[name]; ok {
- parts[len(parts)-1] = parser.renameSchema(name, pkgPath)
- refURL.Fragment = strings.Join(parts, "/")
+ if ref {
+ if IsComplexSchema(schema.Schema) {
+ return parser.getRefTypeSchema(typeSpecDef, schema), nil
}
+ // if it is a simple schema, just return a copy
+ newSchema := *schema.Schema
+ return &newSchema, nil
}
-}
-func (parser *Parser) renameSchema(name, pkgPath string) string {
- parts := strings.Split(name, ".")
- name = fullTypeName(pkgPath, parts[len(parts)-1])
- name = strings.ReplaceAll(name, "/", "_")
-
- return name
+ return schema.Schema, nil
}
func (parser *Parser) getRefTypeSchema(typeSpecDef *TypeSpecDef, schema *Schema) *spec.Schema {
_, ok := parser.outputSchemas[typeSpecDef]
if !ok {
- existSchema, ok := parser.existSchemaNames[schema.Name]
- if ok {
- // store the first one to be renamed after parsing over
- _, ok = parser.toBeRenamedSchemas[existSchema.Name]
- if !ok {
- parser.toBeRenamedSchemas[existSchema.Name] = existSchema.PkgPath
- }
- // rename not the first one
- schema.Name = parser.renameSchema(schema.Name, schema.PkgPath)
- } else {
- parser.existSchemaNames[schema.Name] = schema
- }
parser.swagger.Definitions[schema.Name] = spec.Schema{}
if schema.Schema != nil {
@@ -905,8 +1058,6 @@ func (parser *Parser) getRefTypeSchema(typeSpecDef *TypeSpecDef, schema *Schema)
}
refSchema := RefSchema(schema.Name)
- // store every URL
- parser.toBeRenamedRefURLs = append(parser.toBeRenamedRefURLs, refSchema.Ref.GetURL())
return refSchema
}
@@ -925,11 +1076,9 @@ func (parser *Parser) isInStructStack(typeSpecDef *TypeSpecDef) bool {
// given name and package, and populates swagger schema definitions registry
// with a schema for the given type
func (parser *Parser) ParseDefinition(typeSpecDef *TypeSpecDef) (*Schema, error) {
- typeName := typeSpecDef.FullName()
- refTypeName := TypeDocName(typeName, typeSpecDef.TypeSpec)
-
- schema, ok := parser.parsedSchemas[typeSpecDef]
- if ok {
+ typeName := typeSpecDef.TypeName()
+ schema, found := parser.parsedSchemas[typeSpecDef]
+ if found {
parser.debug.Printf("Skipping '%s', already parsed.", typeName)
return schema, nil
@@ -939,12 +1088,13 @@ func (parser *Parser) ParseDefinition(typeSpecDef *TypeSpecDef) (*Schema, error)
parser.debug.Printf("Skipping '%s', recursion detected.", typeName)
return &Schema{
- Name: refTypeName,
+ Name: typeName,
PkgPath: typeSpecDef.PkgPath,
Schema: PrimitiveSchema(OBJECT),
},
ErrRecursiveParseStruct
}
+
parser.structStack = append(parser.structStack, typeSpecDef)
parser.debug.Printf("Generating %s", typeName)
@@ -958,28 +1108,43 @@ func (parser *Parser) ParseDefinition(typeSpecDef *TypeSpecDef) (*Schema, error)
fillDefinitionDescription(definition, typeSpecDef.File, typeSpecDef)
}
- s := Schema{
- Name: refTypeName,
+ if len(typeSpecDef.Enums) > 0 {
+ var varnames []string
+ var enumComments = make(map[string]string)
+ for _, value := range typeSpecDef.Enums {
+ definition.Enum = append(definition.Enum, value.Value)
+ varnames = append(varnames, value.key)
+ if len(value.Comment) > 0 {
+ enumComments[value.key] = value.Comment
+ }
+ }
+ if definition.Extensions == nil {
+ definition.Extensions = make(spec.Extensions)
+ }
+ definition.Extensions[enumVarNamesExtension] = varnames
+ if len(enumComments) > 0 {
+ definition.Extensions[enumCommentsExtension] = enumComments
+ }
+ }
+
+ sch := Schema{
+ Name: typeName,
PkgPath: typeSpecDef.PkgPath,
Schema: definition,
}
- parser.parsedSchemas[typeSpecDef] = &s
+ parser.parsedSchemas[typeSpecDef] = &sch
// update an empty schema as a result of recursion
- s2, ok := parser.outputSchemas[typeSpecDef]
- if ok {
+ s2, found := parser.outputSchemas[typeSpecDef]
+ if found {
parser.swagger.Definitions[s2.Name] = *definition
}
- return &s, nil
+ return &sch, nil
}
-func fullTypeName(pkgName, typeName string) string {
- if pkgName != "" {
- return pkgName + "." + typeName
- }
-
- return typeName
+func fullTypeName(parts ...string) string {
+ return strings.Join(parts, ".")
}
// fillDefinitionDescription additionally fills fields in definition (spec.Schema)
@@ -1014,13 +1179,19 @@ func extractDeclarationDescription(commentGroups ...*ast.CommentGroup) string {
}
isHandlingDescription := false
+
for _, comment := range commentGroup.List {
commentText := strings.TrimSpace(strings.TrimLeft(comment.Text, "/"))
- attribute := strings.Split(commentText, " ")[0]
+ if len(commentText) == 0 {
+ continue
+ }
+ attribute := FieldsByAnySpace(commentText, 2)[0]
+
if strings.ToLower(attribute) != descriptionAttr {
if !isHandlingDescription {
continue
}
+
break
}
@@ -1079,17 +1250,15 @@ func (parser *Parser) parseTypeExpr(file *ast.File, typeExpr ast.Expr, ref bool)
case *ast.FuncType:
return nil, ErrFuncTypeField
- // ...
- default:
- parser.debug.Printf("Type definition of type '%T' is not supported yet. Using 'object' instead.\n", typeExpr)
+ // ...
}
- return PrimitiveSchema(OBJECT), nil
+ return parser.parseGenericTypeExpr(file, typeExpr)
}
func (parser *Parser) parseStruct(file *ast.File, fields *ast.FieldList) (*spec.Schema, error) {
- required := make([]string, 0)
- properties := make(map[string]spec.Schema)
+ required, properties := make([]string, 0), make(map[string]spec.Schema)
+
for _, field := range fields.List {
fieldProps, requiredFromAnon, err := parser.parseStructField(file, field)
if err != nil {
@@ -1099,10 +1268,13 @@ func (parser *Parser) parseStruct(file *ast.File, fields *ast.FieldList) (*spec.
return nil, err
}
+
if len(fieldProps) == 0 {
continue
}
+
required = append(required, requiredFromAnon...)
+
for k, v := range fieldProps {
properties[k] = v
}
@@ -1120,22 +1292,35 @@ func (parser *Parser) parseStruct(file *ast.File, fields *ast.FieldList) (*spec.
}
func (parser *Parser) parseStructField(file *ast.File, field *ast.Field) (map[string]spec.Schema, []string, error) {
- if field.Names == nil {
- if field.Tag != nil {
- skip, ok := reflect.StructTag(strings.ReplaceAll(field.Tag.Value, "`", "")).Lookup("swaggerignore")
- if ok && strings.EqualFold(skip, "true") {
- return nil, nil, nil
- }
+ if field.Tag != nil {
+ skip, ok := reflect.StructTag(strings.ReplaceAll(field.Tag.Value, "`", "")).Lookup("swaggerignore")
+ if ok && strings.EqualFold(skip, "true") {
+ return nil, nil, nil
}
+ }
- typeName, err := getFieldType(field.Type)
+ ps := parser.fieldParserFactory(parser, field)
+
+ if ps.ShouldSkip() {
+ return nil, nil, nil
+ }
+
+ fieldName, err := ps.FieldName()
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if fieldName == "" {
+ typeName, err := getFieldType(file, field.Type, nil)
if err != nil {
return nil, nil, err
}
+
schema, err := parser.getTypeSchema(typeName, file, false)
if err != nil {
return nil, nil, err
}
+
if len(schema.Type) > 0 && schema.Type[0] == OBJECT {
if len(schema.Properties) == 0 {
return nil, nil, nil
@@ -1148,32 +1333,18 @@ func (parser *Parser) parseStructField(file *ast.File, field *ast.Field) (map[st
return properties, schema.SchemaProps.Required, nil
}
-
// for alias type of non-struct types ,such as array,map, etc. ignore field tag.
return map[string]spec.Schema{typeName: *schema}, nil, nil
- }
-
- ps := parser.fieldParserFactory(parser, field)
-
- ok, err := ps.ShouldSkip()
- if err != nil {
- return nil, nil, err
- }
- if ok {
- return nil, nil, nil
- }
- fieldName, err := ps.FieldName()
- if err != nil {
- return nil, nil, err
}
schema, err := ps.CustomSchema()
if err != nil {
return nil, nil, err
}
+
if schema == nil {
- typeName, err := getFieldType(field.Type)
+ typeName, err := getFieldType(file, field.Type, nil)
if err == nil {
// named type
schema, err = parser.getTypeSchema(typeName, file, true)
@@ -1181,6 +1352,7 @@ func (parser *Parser) parseStructField(file *ast.File, field *ast.Field) (map[st
// unnamed type
schema, err = parser.parseTypeExpr(file, field.Type, false)
}
+
if err != nil {
return nil, nil, err
}
@@ -1192,10 +1364,12 @@ func (parser *Parser) parseStructField(file *ast.File, field *ast.Field) (map[st
}
var tagRequired []string
+
required, err := ps.IsRequired()
if err != nil {
return nil, nil, err
}
+
if required {
tagRequired = append(tagRequired, fieldName)
}
@@ -1203,27 +1377,26 @@ func (parser *Parser) parseStructField(file *ast.File, field *ast.Field) (map[st
return map[string]spec.Schema{fieldName: *schema}, tagRequired, nil
}
-func getFieldType(field ast.Expr) (string, error) {
+func getFieldType(file *ast.File, field ast.Expr, genericParamTypeDefs map[string]*genericTypeSpec) (string, error) {
switch fieldType := field.(type) {
case *ast.Ident:
return fieldType.Name, nil
case *ast.SelectorExpr:
- packageName, err := getFieldType(fieldType.X)
+ packageName, err := getFieldType(file, fieldType.X, genericParamTypeDefs)
if err != nil {
return "", err
}
return fullTypeName(packageName, fieldType.Sel.Name), nil
-
case *ast.StarExpr:
- fullName, err := getFieldType(fieldType.X)
+ fullName, err := getFieldType(file, fieldType.X, genericParamTypeDefs)
if err != nil {
return "", err
}
return fullName, nil
default:
- return "", fmt.Errorf("unknown field type %#v", field)
+ return getGenericFieldType(file, field, genericParamTypeDefs)
}
}
@@ -1232,6 +1405,7 @@ func (parser *Parser) GetSchemaTypePath(schema *spec.Schema, depth int) []string
if schema == nil || depth == 0 {
return nil
}
+
name := schema.Ref.String()
if name != "" {
if pos := strings.LastIndexByte(name, '/'); pos >= 0 {
@@ -1243,10 +1417,12 @@ func (parser *Parser) GetSchemaTypePath(schema *spec.Schema, depth int) []string
return nil
}
+
if len(schema.Type) > 0 {
switch schema.Type[0] {
case ARRAY:
depth--
+
s := []string{schema.Type[0]}
return append(s, parser.GetSchemaTypePath(schema.Items.Schema, depth)...)
@@ -1254,6 +1430,7 @@ func (parser *Parser) GetSchemaTypePath(schema *spec.Schema, depth int) []string
if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil {
// for map
depth--
+
s := []string{schema.Type[0]}
return append(s, parser.GetSchemaTypePath(schema.AdditionalProperties.Schema, depth)...)
@@ -1270,7 +1447,7 @@ func replaceLastTag(slice []spec.Tag, element spec.Tag) {
slice = append(slice[:len(slice)-1], element)
}
-// defineTypeOfExample example value define the type (object and array unsupported)
+// defineTypeOfExample example value define the type (object and array unsupported).
func defineTypeOfExample(schemaType, arrayType, exampleValue string) (interface{}, error) {
switch schemaType {
case STRING:
@@ -1304,6 +1481,7 @@ func defineTypeOfExample(schemaType, arrayType, exampleValue string) (interface{
if err != nil {
return nil, err
}
+
result = append(result, v)
}
@@ -1314,19 +1492,24 @@ func defineTypeOfExample(schemaType, arrayType, exampleValue string) (interface{
}
values := strings.Split(exampleValue, ",")
+
result := map[string]interface{}{}
+
for _, value := range values {
- mapData := strings.Split(value, ":")
+ mapData := strings.SplitN(value, ":", 2)
if len(mapData) == 2 {
v, err := defineTypeOfExample(arrayType, "", mapData[1])
if err != nil {
return nil, err
}
+
result[mapData[0]] = v
- } else {
- return nil, fmt.Errorf("example value %s should format: key:value", exampleValue)
+
+ continue
}
+
+ return nil, fmt.Errorf("example value %s should format: key:value", exampleValue)
}
return result, nil
@@ -1338,9 +1521,12 @@ func defineTypeOfExample(schemaType, arrayType, exampleValue string) (interface{
// GetAllGoFileInfo gets all Go source files information for given searchDir.
func (parser *Parser) getAllGoFileInfo(packageDir, searchDir string) error {
return filepath.Walk(searchDir, func(path string, f os.FileInfo, _ error) error {
- if err := parser.Skip(path, f); err != nil {
+ err := parser.Skip(path, f)
+ if err != nil {
return err
- } else if f.IsDir() {
+ }
+
+ if f.IsDir() {
return nil
}
@@ -1349,7 +1535,7 @@ func (parser *Parser) getAllGoFileInfo(packageDir, searchDir string) error {
return err
}
- return parser.parseFile(filepath.ToSlash(filepath.Dir(filepath.Clean(filepath.Join(packageDir, relPath)))), path, nil)
+ return parser.parseFile(filepath.ToSlash(filepath.Dir(filepath.Clean(filepath.Join(packageDir, relPath)))), path, nil, ParseAll)
})
}
@@ -1363,8 +1549,10 @@ func (parser *Parser) getAllGoFileInfoFromDeps(pkg *depth.Pkg) error {
if pkg.Raw == nil && pkg.Name == "C" {
return nil
}
+
srcDir := pkg.Raw.Dir
- files, err := ioutil.ReadDir(srcDir) // only parsing files in the dir(don't contain sub dir files)
+
+ files, err := os.ReadDir(srcDir) // only parsing files in the dir(don't contain sub dir files)
if err != nil {
return err
}
@@ -1375,7 +1563,7 @@ func (parser *Parser) getAllGoFileInfoFromDeps(pkg *depth.Pkg) error {
}
path := filepath.Join(srcDir, f.Name())
- if err := parser.parseFile(pkg.Name, path, nil); err != nil {
+ if err := parser.parseFile(pkg.Name, path, nil, ParseModels); err != nil {
return err
}
}
@@ -1389,23 +1577,12 @@ func (parser *Parser) getAllGoFileInfoFromDeps(pkg *depth.Pkg) error {
return nil
}
-func (parser *Parser) parseFile(packageDir, path string, src interface{}) error {
+func (parser *Parser) parseFile(packageDir, path string, src interface{}, flag ParseFlag) error {
if strings.HasSuffix(strings.ToLower(path), "_test.go") || filepath.Ext(path) != ".go" {
return nil
}
- // positions are relative to FileSet
- astFile, err := goparser.ParseFile(token.NewFileSet(), path, src, goparser.ParseComments)
- if err != nil {
- return fmt.Errorf("ParseFile error:%+v", err)
- }
-
- err = parser.packages.CollectAstFile(packageDir, path, astFile)
- if err != nil {
- return err
- }
-
- return nil
+ return parser.packages.ParseFile(packageDir, path, src, flag)
}
func (parser *Parser) checkOperationIDUniqueness() error {
@@ -1414,24 +1591,29 @@ func (parser *Parser) checkOperationIDUniqueness() error {
for path, item := range parser.swagger.Paths.Paths {
var method, id string
+
for method = range allMethod {
op := refRouteMethodOp(&item, method)
if *op != nil {
id = (**op).ID
+
break
}
}
+
if id == "" {
continue
}
current := fmt.Sprintf("%s %s", method, path)
+
previous, ok := operationsIds[id]
if ok {
return fmt.Errorf(
"duplicated @id annotation '%s' found in '%s', previously declared in: '%s'",
id, current, previous)
}
+
operationsIds[id] = current
}
@@ -1448,7 +1630,7 @@ func walkWith(excludes map[string]struct{}, parseVendor bool) func(path string,
if f.IsDir() {
if !parseVendor && f.Name() == "vendor" || // ignore "vendor"
f.Name() == "docs" || // exclude docs
- len(f.Name()) > 1 && f.Name()[0] == '.' { // exclude all hidden folder
+ len(f.Name()) > 1 && f.Name()[0] == '.' && f.Name() != ".." { // exclude all hidden folder
return filepath.SkipDir
}
diff --git a/vendor/github.com/swaggo/swag/schema.go b/vendor/github.com/swaggo/swag/schema.go
index 0e72f65..ba92ac6 100644
--- a/vendor/github.com/swaggo/swag/schema.go
+++ b/vendor/github.com/swaggo/swag/schema.go
@@ -3,8 +3,6 @@ package swag
import (
"errors"
"fmt"
- "go/ast"
- "strings"
"github.com/go-openapi/spec"
)
@@ -26,10 +24,17 @@ const (
STRING = "string"
// FUNC represent a function value.
FUNC = "func"
+ // ERROR represent a error value.
+ ERROR = "error"
+ // INTERFACE represent a interface value.
+ INTERFACE = "interface{}"
// ANY represent a any value.
ANY = "any"
// NIL represent a empty value.
NIL = "nil"
+
+ // IgnoreNameOverridePrefix Prepend to model to avoid renaming based on comment.
+ IgnoreNameOverridePrefix = '$'
)
// CheckSchemaType checks if typeName is not a name of primitive type.
@@ -61,6 +66,11 @@ func IsPrimitiveType(typeName string) bool {
return false
}
+// IsInterfaceLike determines whether the swagger type name is an go named interface type like error type.
+func IsInterfaceLike(typeName string) bool {
+ return typeName == ERROR || typeName == ANY
+}
+
// IsNumericType determines whether the swagger type name is a numeric type.
func IsNumericType(typeName string) bool {
return typeName == INTEGER || typeName == NUMBER
@@ -104,8 +114,7 @@ func IsGolangPrimitiveType(typeName string) bool {
"float32",
"float64",
"bool",
- "string",
- "any":
+ "string":
return true
}
@@ -122,23 +131,34 @@ func TransToValidCollectionFormat(format string) string {
return ""
}
-// TypeDocName get alias from comment '// @name ', otherwise the original type name to display in doc.
-func TypeDocName(pkgName string, spec *ast.TypeSpec) string {
- if spec != nil {
- if spec.Comment != nil {
- for _, comment := range spec.Comment.List {
- texts := strings.Split(strings.TrimSpace(strings.TrimLeft(comment.Text, "/")), " ")
- if len(texts) > 1 && strings.ToLower(texts[0]) == "@name" {
- return texts[1]
- }
- }
- }
- if spec.Name != nil {
- return fullTypeName(strings.Split(pkgName, ".")[0], spec.Name.Name)
+func ignoreNameOverride(name string) bool {
+ return len(name) != 0 && name[0] == IgnoreNameOverridePrefix
+}
+
+// IsComplexSchema whether a schema is complex and should be a ref schema
+func IsComplexSchema(schema *spec.Schema) bool {
+ // a enum type should be complex
+ if len(schema.Enum) > 0 {
+ return true
+ }
+
+ // a deep array type is complex, how to determine deep? here more than 2 ,for example: [][]object,[][][]int
+ if len(schema.Type) > 2 {
+ return true
+ }
+
+ //Object included, such as Object or []Object
+ for _, st := range schema.Type {
+ if st == OBJECT {
+ return true
}
}
+ return false
+}
- return pkgName
+// IsRefSchema whether a schema is a reference schema.
+func IsRefSchema(schema *spec.Schema) bool {
+ return schema.Ref.Ref.GetURL() != nil
}
// RefSchema build a reference schema.
@@ -168,6 +188,7 @@ func BuildCustomSchema(types []string) (*spec.Schema, error) {
if len(types) == 1 {
return nil, errors.New("need array item type after array")
}
+
schema, err := BuildCustomSchema(types[1:])
if err != nil {
return nil, err
@@ -178,6 +199,7 @@ func BuildCustomSchema(types []string) (*spec.Schema, error) {
if len(types) == 1 {
return PrimitiveSchema(types[0]), nil
}
+
schema, err := BuildCustomSchema(types[1:])
if err != nil {
return nil, err
diff --git a/vendor/github.com/swaggo/swag/spec.go b/vendor/github.com/swaggo/swag/spec.go
index 9e0ec1a..3a727c9 100644
--- a/vendor/github.com/swaggo/swag/spec.go
+++ b/vendor/github.com/swaggo/swag/spec.go
@@ -21,31 +21,33 @@ type Spec struct {
// ReadDoc parses SwaggerTemplate into swagger document.
func (i *Spec) ReadDoc() string {
- i.Description = strings.Replace(i.Description, "\n", "\\n", -1)
+ i.Description = strings.ReplaceAll(i.Description, "\n", "\\n")
- t, err := template.New("swagger_info").Funcs(template.FuncMap{
+ tpl, err := template.New("swagger_info").Funcs(template.FuncMap{
"marshal": func(v interface{}) string {
a, _ := json.Marshal(v)
+
return string(a)
},
"escape": func(v interface{}) string {
// escape tabs
- str := strings.Replace(v.(string), "\t", "\\t", -1)
+ var str = strings.ReplaceAll(v.(string), "\t", "\\t")
// replace " with \", and if that results in \\", replace that with \\\"
- str = strings.Replace(str, "\"", "\\\"", -1)
- return strings.Replace(str, "\\\\\"", "\\\\\\\"", -1)
+ str = strings.ReplaceAll(str, "\"", "\\\"")
+
+ return strings.ReplaceAll(str, "\\\\\"", "\\\\\\\"")
},
}).Parse(i.SwaggerTemplate)
if err != nil {
return i.SwaggerTemplate
}
- var tpl bytes.Buffer
- if err = t.Execute(&tpl, i); err != nil {
+ var doc bytes.Buffer
+ if err = tpl.Execute(&doc, i); err != nil {
return i.SwaggerTemplate
}
- return tpl.String()
+ return doc.String()
}
// InstanceName returns Spec instance name.
diff --git a/vendor/github.com/swaggo/swag/swagger.go b/vendor/github.com/swaggo/swag/swagger.go
index c00feb2..74c162c 100644
--- a/vendor/github.com/swaggo/swag/swagger.go
+++ b/vendor/github.com/swaggo/swag/swagger.go
@@ -23,6 +23,7 @@ type Swagger interface {
func Register(name string, swagger Swagger) {
swaggerMu.Lock()
defer swaggerMu.Unlock()
+
if swagger == nil {
panic("swagger is nil")
}
@@ -34,9 +35,19 @@ func Register(name string, swagger Swagger) {
if _, ok := swags[name]; ok {
panic("Register called twice for swag: " + name)
}
+
swags[name] = swagger
}
+// GetSwagger returns the swagger instance for given name.
+// If not found, returns nil.
+func GetSwagger(name string) Swagger {
+ swaggerMu.RLock()
+ defer swaggerMu.RUnlock()
+
+ return swags[name]
+}
+
// ReadDoc reads swagger document. An optional name parameter can be passed to read a specific document.
// The default name is "swagger".
func ReadDoc(optionalName ...string) (string, error) {
diff --git a/vendor/github.com/swaggo/swag/types.go b/vendor/github.com/swaggo/swag/types.go
index 82ddbbe..8e2f51d 100644
--- a/vendor/github.com/swaggo/swag/types.go
+++ b/vendor/github.com/swaggo/swag/types.go
@@ -2,6 +2,8 @@ package swag
import (
"go/ast"
+ "go/token"
+ "strings"
"github.com/go-openapi/spec"
)
@@ -21,8 +23,13 @@ type TypeSpecDef struct {
// the TypeSpec of this type definition
TypeSpec *ast.TypeSpec
+ Enums []EnumValue
+
// path of package starting from under ${GOPATH}/src or from module path in go.mod
- PkgPath string
+ PkgPath string
+ ParentSpec ast.Decl
+
+ NotUnique bool
}
// Name the name of the typeSpec.
@@ -34,18 +41,49 @@ func (t *TypeSpecDef) Name() string {
return ""
}
-// FullName full name of the typeSpec.
-func (t *TypeSpecDef) FullName() string {
- return fullTypeName(t.File.Name.Name, t.TypeSpec.Name.Name)
+// TypeName the type name of the typeSpec.
+func (t *TypeSpecDef) TypeName() string {
+ if ignoreNameOverride(t.TypeSpec.Name.Name) {
+ return t.TypeSpec.Name.Name[1:]
+ } else if t.TypeSpec.Comment != nil {
+ // get alias from comment '// @name '
+ for _, comment := range t.TypeSpec.Comment.List {
+ texts := strings.Split(strings.TrimSpace(strings.TrimLeft(comment.Text, "/")), " ")
+ if len(texts) > 1 && strings.ToLower(texts[0]) == "@name" {
+ return texts[1]
+ }
+ }
+ }
+
+ var names []string
+ if t.NotUnique {
+ pkgPath := strings.Map(func(r rune) rune {
+ if r == '\\' || r == '/' || r == '.' {
+ return '_'
+ }
+ return r
+ }, t.PkgPath)
+ names = append(names, pkgPath)
+ } else {
+ names = append(names, t.File.Name.Name)
+ }
+ if parentFun, ok := (t.ParentSpec).(*ast.FuncDecl); ok && parentFun != nil {
+ names = append(names, parentFun.Name.Name)
+ }
+ names = append(names, t.TypeSpec.Name.Name)
+ return fullTypeName(names...)
}
-// FullPath of the typeSpec.
+// FullPath return the full path of the typeSpec.
func (t *TypeSpecDef) FullPath() string {
return t.PkgPath + "." + t.Name()
}
// AstFileInfo information of an ast.File.
type AstFileInfo struct {
+ //FileSet the FileSet object which is used to parse this go source file
+ FileSet *token.FileSet
+
// File ast.File
File *ast.File
@@ -54,16 +92,7 @@ type AstFileInfo struct {
// PackagePath package import path of the ast.File
PackagePath string
-}
-
-// PackageDefinitions files and definition in a package.
-type PackageDefinitions struct {
- // files in this package, map key is file's relative path starting package path
- Files map[string]*ast.File
-
- // definitions in this package, map key is typeName
- TypeDefinitions map[string]*TypeSpecDef
- // package name
- Name string
+ // ParseFlag determine what to parse
+ ParseFlag ParseFlag
}
diff --git a/vendor/github.com/swaggo/swag/utils.go b/vendor/github.com/swaggo/swag/utils.go
new file mode 100644
index 0000000..df31ff2
--- /dev/null
+++ b/vendor/github.com/swaggo/swag/utils.go
@@ -0,0 +1,55 @@
+package swag
+
+import "unicode"
+
+// FieldsFunc split a string s by a func splitter into max n parts
+func FieldsFunc(s string, f func(rune2 rune) bool, n int) []string {
+ // A span is used to record a slice of s of the form s[start:end].
+ // The start index is inclusive and the end index is exclusive.
+ type span struct {
+ start int
+ end int
+ }
+ spans := make([]span, 0, 32)
+
+ // Find the field start and end indices.
+ // Doing this in a separate pass (rather than slicing the string s
+ // and collecting the result substrings right away) is significantly
+ // more efficient, possibly due to cache effects.
+ start := -1 // valid span start if >= 0
+ for end, rune := range s {
+ if f(rune) {
+ if start >= 0 {
+ spans = append(spans, span{start, end})
+ // Set start to a negative value.
+ // Note: using -1 here consistently and reproducibly
+ // slows down this code by a several percent on amd64.
+ start = ^start
+ }
+ } else {
+ if start < 0 {
+ start = end
+ if n > 0 && len(spans)+1 >= n {
+ break
+ }
+ }
+ }
+ }
+
+ // Last field might end at EOF.
+ if start >= 0 {
+ spans = append(spans, span{start, len(s)})
+ }
+
+ // Create strings from recorded field indices.
+ a := make([]string, len(spans))
+ for i, span := range spans {
+ a[i] = s[span.start:span.end]
+ }
+ return a
+}
+
+// FieldsByAnySpace split a string s by any space character into max n parts
+func FieldsByAnySpace(s string, n int) []string {
+ return FieldsFunc(s, unicode.IsSpace, n)
+}
diff --git a/vendor/github.com/swaggo/swag/utils_go18.go b/vendor/github.com/swaggo/swag/utils_go18.go
new file mode 100644
index 0000000..814f934
--- /dev/null
+++ b/vendor/github.com/swaggo/swag/utils_go18.go
@@ -0,0 +1,31 @@
+//go:build go1.18
+// +build go1.18
+
+package swag
+
+import (
+ "reflect"
+ "unicode/utf8"
+)
+
+// AppendUtf8Rune appends the UTF-8 encoding of r to the end of p and
+// returns the extended buffer. If the rune is out of range,
+// it appends the encoding of RuneError.
+func AppendUtf8Rune(p []byte, r rune) []byte {
+ return utf8.AppendRune(p, r)
+}
+
+// CanIntegerValue a wrapper of reflect.Value
+type CanIntegerValue struct {
+ reflect.Value
+}
+
+// CanInt reports whether Uint can be used without panicking.
+func (v CanIntegerValue) CanInt() bool {
+ return v.Value.CanInt()
+}
+
+// CanUint reports whether Uint can be used without panicking.
+func (v CanIntegerValue) CanUint() bool {
+ return v.Value.CanUint()
+}
diff --git a/vendor/github.com/swaggo/swag/utils_other.go b/vendor/github.com/swaggo/swag/utils_other.go
new file mode 100644
index 0000000..531c0df
--- /dev/null
+++ b/vendor/github.com/swaggo/swag/utils_other.go
@@ -0,0 +1,47 @@
+//go:build !go1.18
+// +build !go1.18
+
+package swag
+
+import (
+ "reflect"
+ "unicode/utf8"
+)
+
+// AppendUtf8Rune appends the UTF-8 encoding of r to the end of p and
+// returns the extended buffer. If the rune is out of range,
+// it appends the encoding of RuneError.
+func AppendUtf8Rune(p []byte, r rune) []byte {
+ length := utf8.RuneLen(rune(r))
+ if length > 0 {
+ utf8Slice := make([]byte, length)
+ utf8.EncodeRune(utf8Slice, rune(r))
+ p = append(p, utf8Slice...)
+ }
+ return p
+}
+
+// CanIntegerValue a wrapper of reflect.Value
+type CanIntegerValue struct {
+ reflect.Value
+}
+
+// CanInt reports whether Uint can be used without panicking.
+func (v CanIntegerValue) CanInt() bool {
+ switch v.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return true
+ default:
+ return false
+ }
+}
+
+// CanUint reports whether Uint can be used without panicking.
+func (v CanIntegerValue) CanUint() bool {
+ switch v.Kind() {
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return true
+ default:
+ return false
+ }
+}
diff --git a/vendor/github.com/swaggo/swag/version.go b/vendor/github.com/swaggo/swag/version.go
index 0955fab..c9ee5ac 100644
--- a/vendor/github.com/swaggo/swag/version.go
+++ b/vendor/github.com/swaggo/swag/version.go
@@ -1,4 +1,4 @@
package swag
// Version of swag.
-const Version = "v1.8.1"
+const Version = "v1.8.10"
diff --git a/vendor/golang.org/x/tools/AUTHORS b/vendor/golang.org/x/tools/AUTHORS
deleted file mode 100644
index 15167cd..0000000
--- a/vendor/golang.org/x/tools/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code refers to The Go Authors for copyright purposes.
-# The master list of authors is in the main Go distribution,
-# visible at http://tip.golang.org/AUTHORS.
diff --git a/vendor/golang.org/x/tools/CONTRIBUTORS b/vendor/golang.org/x/tools/CONTRIBUTORS
deleted file mode 100644
index 1c4577e..0000000
--- a/vendor/golang.org/x/tools/CONTRIBUTORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code was written by the Go contributors.
-# The master list of contributors is in the main Go distribution,
-# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go b/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go
index a5c6d6d..9fa5aa1 100644
--- a/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go
+++ b/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go
@@ -22,9 +22,9 @@ import (
// additional whitespace abutting a node to be enclosed by it.
// In this example:
//
-// z := x + y // add them
-// <-A->
-// <----B----->
+// z := x + y // add them
+// <-A->
+// <----B----->
//
// the ast.BinaryExpr(+) node is considered to enclose interval B
// even though its [Pos()..End()) is actually only interval A.
@@ -43,10 +43,10 @@ import (
// interior whitespace of path[0].
// In this example:
//
-// z := x + y // add them
-// <--C--> <---E-->
-// ^
-// D
+// z := x + y // add them
+// <--C--> <---E-->
+// ^
+// D
//
// intervals C, D and E are inexact. C is contained by the
// z-assignment statement, because it spans three of its children (:=,
@@ -54,12 +54,11 @@ import (
// interior whitespace of the assignment. E is considered interior
// whitespace of the BlockStmt containing the assignment.
//
-// Precondition: [start, end) both lie within the same file as root.
-// TODO(adonovan): return (nil, false) in this case and remove precond.
-// Requires FileSet; see loader.tokenFileContainsPos.
-//
-// Postcondition: path is never nil; it always contains at least 'root'.
-//
+// The resulting path is never empty; it always contains at least the
+// 'root' *ast.File. Ideally PathEnclosingInterval would reject
+// intervals that lie wholly or partially outside the range of the
+// file, but unfortunately ast.File records only the token.Pos of
+// the 'package' keyword, but not of the start of the file itself.
func PathEnclosingInterval(root *ast.File, start, end token.Pos) (path []ast.Node, exact bool) {
// fmt.Printf("EnclosingInterval %d %d\n", start, end) // debugging
@@ -135,6 +134,7 @@ func PathEnclosingInterval(root *ast.File, start, end token.Pos) (path []ast.Nod
return false // inexact: overlaps multiple children
}
+ // Ensure [start,end) is nondecreasing.
if start > end {
start, end = end, start
}
@@ -162,7 +162,6 @@ func PathEnclosingInterval(root *ast.File, start, end token.Pos) (path []ast.Nod
// tokenNode is a dummy implementation of ast.Node for a single token.
// They are used transiently by PathEnclosingInterval but never escape
// this package.
-//
type tokenNode struct {
pos token.Pos
end token.Pos
@@ -183,7 +182,6 @@ func tok(pos token.Pos, len int) ast.Node {
// childrenOf returns the direct non-nil children of ast.Node n.
// It may include fake ast.Node implementations for bare tokens.
// it is not safe to call (e.g.) ast.Walk on such nodes.
-//
func childrenOf(n ast.Node) []ast.Node {
var children []ast.Node
@@ -488,7 +486,6 @@ func (sl byPos) Swap(i, j int) {
// TODO(adonovan): in some cases (e.g. Field, FieldList, Ident,
// StarExpr) we could be much more specific given the path to the AST
// root. Perhaps we should do that.
-//
func NodeDescription(n ast.Node) string {
switch n := n.(type) {
case *ast.ArrayType:
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/imports.go b/vendor/golang.org/x/tools/go/ast/astutil/imports.go
index 2087cee..18d1adb 100644
--- a/vendor/golang.org/x/tools/go/ast/astutil/imports.go
+++ b/vendor/golang.org/x/tools/go/ast/astutil/imports.go
@@ -22,8 +22,11 @@ func AddImport(fset *token.FileSet, f *ast.File, path string) (added bool) {
// If name is not empty, it is used to rename the import.
//
// For example, calling
+//
// AddNamedImport(fset, f, "pathpkg", "path")
+//
// adds
+//
// import pathpkg "path"
func AddNamedImport(fset *token.FileSet, f *ast.File, name, path string) (added bool) {
if imports(f, name, path) {
@@ -270,8 +273,8 @@ func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (del
}
if j > 0 {
lastImpspec := gen.Specs[j-1].(*ast.ImportSpec)
- lastLine := fset.Position(lastImpspec.Path.ValuePos).Line
- line := fset.Position(impspec.Path.ValuePos).Line
+ lastLine := fset.PositionFor(lastImpspec.Path.ValuePos, false).Line
+ line := fset.PositionFor(impspec.Path.ValuePos, false).Line
// We deleted an entry but now there may be
// a blank line-sized hole where the import was.
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go b/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go
index 6d9ca23..f430b21 100644
--- a/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go
+++ b/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go
@@ -41,7 +41,6 @@ type ApplyFunc func(*Cursor) bool
// Children are traversed in the order in which they appear in the
// respective node's struct definition. A package's files are
// traversed in the filenames' alphabetical order.
-//
func Apply(root ast.Node, pre, post ApplyFunc) (result ast.Node) {
parent := &struct{ ast.Node }{root}
defer func() {
@@ -65,8 +64,8 @@ var abort = new(int) // singleton, to signal termination of Apply
// c.Parent(), and f is the field identifier with name c.Name(),
// the following invariants hold:
//
-// p.f == c.Node() if c.Index() < 0
-// p.f[c.Index()] == c.Node() if c.Index() >= 0
+// p.f == c.Node() if c.Index() < 0
+// p.f[c.Index()] == c.Node() if c.Index() >= 0
//
// The methods Replace, Delete, InsertBefore, and InsertAfter
// can be used to change the AST without disrupting Apply.
@@ -294,6 +293,9 @@ func (a *application) apply(parent ast.Node, name string, iter *iterator, n ast.
a.apply(n, "Fields", nil, n.Fields)
case *ast.FuncType:
+ if tparams := typeparams.ForFuncType(n); tparams != nil {
+ a.apply(n, "TypeParams", nil, tparams)
+ }
a.apply(n, "Params", nil, n.Params)
a.apply(n, "Results", nil, n.Results)
@@ -406,6 +408,9 @@ func (a *application) apply(parent ast.Node, name string, iter *iterator, n ast.
case *ast.TypeSpec:
a.apply(n, "Doc", nil, n.Doc)
a.apply(n, "Name", nil, n.Name)
+ if tparams := typeparams.ForTypeSpec(n); tparams != nil {
+ a.apply(n, "TypeParams", nil, tparams)
+ }
a.apply(n, "Type", nil, n.Type)
a.apply(n, "Comment", nil, n.Comment)
diff --git a/vendor/golang.org/x/tools/go/buildutil/allpackages.go b/vendor/golang.org/x/tools/go/buildutil/allpackages.go
index c0cb03e..dfb8cd6 100644
--- a/vendor/golang.org/x/tools/go/buildutil/allpackages.go
+++ b/vendor/golang.org/x/tools/go/buildutil/allpackages.go
@@ -28,7 +28,6 @@ import (
//
// All I/O is done via the build.Context file system interface,
// which must be concurrency-safe.
-//
func AllPackages(ctxt *build.Context) []string {
var list []string
ForEachPackage(ctxt, func(pkg string, _ error) {
@@ -48,7 +47,6 @@ func AllPackages(ctxt *build.Context) []string {
//
// All I/O is done via the build.Context file system interface,
// which must be concurrency-safe.
-//
func ForEachPackage(ctxt *build.Context, found func(importPath string, err error)) {
ch := make(chan item)
@@ -127,19 +125,18 @@ func allPackages(ctxt *build.Context, root string, ch chan<- item) {
// ExpandPatterns returns the set of packages matched by patterns,
// which may have the following forms:
//
-// golang.org/x/tools/cmd/guru # a single package
-// golang.org/x/tools/... # all packages beneath dir
-// ... # the entire workspace.
+// golang.org/x/tools/cmd/guru # a single package
+// golang.org/x/tools/... # all packages beneath dir
+// ... # the entire workspace.
//
// Order is significant: a pattern preceded by '-' removes matching
// packages from the set. For example, these patterns match all encoding
// packages except encoding/xml:
//
-// encoding/... -encoding/xml
+// encoding/... -encoding/xml
//
// A trailing slash in a pattern is ignored. (Path components of Go
// package names are separated by slash, not the platform's path separator.)
-//
func ExpandPatterns(ctxt *build.Context, patterns []string) map[string]bool {
// TODO(adonovan): support other features of 'go list':
// - "std"/"cmd"/"all" meta-packages
diff --git a/vendor/golang.org/x/tools/go/buildutil/fakecontext.go b/vendor/golang.org/x/tools/go/buildutil/fakecontext.go
index 5fc672f..15025f6 100644
--- a/vendor/golang.org/x/tools/go/buildutil/fakecontext.go
+++ b/vendor/golang.org/x/tools/go/buildutil/fakecontext.go
@@ -30,7 +30,6 @@ import (
// /go/src/ including, for instance, "math" and "math/big".
// ReadDir("/go/src/math/big") would return all the files in the
// "math/big" package.
-//
func FakeContext(pkgs map[string]map[string]string) *build.Context {
clean := func(filename string) string {
f := path.Clean(filepath.ToSlash(filename))
diff --git a/vendor/golang.org/x/tools/go/buildutil/overlay.go b/vendor/golang.org/x/tools/go/buildutil/overlay.go
index 8e23908..bdbfd93 100644
--- a/vendor/golang.org/x/tools/go/buildutil/overlay.go
+++ b/vendor/golang.org/x/tools/go/buildutil/overlay.go
@@ -60,8 +60,7 @@ func OverlayContext(orig *build.Context, overlay map[string][]byte) *build.Conte
// ParseOverlayArchive parses an archive containing Go files and their
// contents. The result is intended to be used with OverlayContext.
//
-//
-// Archive format
+// # Archive format
//
// The archive consists of a series of files. Each file consists of a
// name, a decimal file size and the file contents, separated by
diff --git a/vendor/golang.org/x/tools/go/buildutil/tags.go b/vendor/golang.org/x/tools/go/buildutil/tags.go
index 6da0ce4..7cf523b 100644
--- a/vendor/golang.org/x/tools/go/buildutil/tags.go
+++ b/vendor/golang.org/x/tools/go/buildutil/tags.go
@@ -20,7 +20,8 @@ const TagsFlagDoc = "a list of `build tags` to consider satisfied during the bui
// See $GOROOT/src/cmd/go/doc.go for description of 'go build -tags' flag.
//
// Example:
-// flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc)
+//
+// flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc)
type TagsFlag []string
func (v *TagsFlag) Set(s string) error {
diff --git a/vendor/golang.org/x/tools/go/buildutil/util.go b/vendor/golang.org/x/tools/go/buildutil/util.go
index fc923d7..d771b18 100644
--- a/vendor/golang.org/x/tools/go/buildutil/util.go
+++ b/vendor/golang.org/x/tools/go/buildutil/util.go
@@ -28,7 +28,6 @@ import (
// filename that will be attached to the ASTs.
//
// TODO(adonovan): call this from go/loader.parseFiles when the tree thaws.
-//
func ParseFile(fset *token.FileSet, ctxt *build.Context, displayPath func(string) string, dir string, file string, mode parser.Mode) (*ast.File, error) {
if !IsAbsPath(ctxt, file) {
file = JoinPath(ctxt, dir, file)
@@ -51,7 +50,6 @@ func ParseFile(fset *token.FileSet, ctxt *build.Context, displayPath func(string
//
// The '...Files []string' fields of the resulting build.Package are not
// populated (build.FindOnly mode).
-//
func ContainingPackage(ctxt *build.Context, dir, filename string) (*build.Package, error) {
if !IsAbsPath(ctxt, filename) {
filename = JoinPath(ctxt, dir, filename)
@@ -196,7 +194,6 @@ func SplitPathList(ctxt *build.Context, s string) []string {
// sameFile returns true if x and y have the same basename and denote
// the same file.
-//
func sameFile(x, y string) bool {
if path.Clean(x) == path.Clean(y) {
return true
diff --git a/vendor/golang.org/x/tools/go/internal/cgo/cgo.go b/vendor/golang.org/x/tools/go/internal/cgo/cgo.go
index d01fb04..3fce480 100644
--- a/vendor/golang.org/x/tools/go/internal/cgo/cgo.go
+++ b/vendor/golang.org/x/tools/go/internal/cgo/cgo.go
@@ -69,7 +69,6 @@ import (
// ProcessFiles invokes the cgo preprocessor on bp.CgoFiles, parses
// the output and returns the resulting ASTs.
-//
func ProcessFiles(bp *build.Package, fset *token.FileSet, DisplayPath func(path string) string, mode parser.Mode) ([]*ast.File, error) {
tmpdir, err := ioutil.TempDir("", strings.Replace(bp.ImportPath, "/", "_", -1)+"_C")
if err != nil {
diff --git a/vendor/golang.org/x/tools/go/loader/doc.go b/vendor/golang.org/x/tools/go/loader/doc.go
index c5aa31c..e35b1fd 100644
--- a/vendor/golang.org/x/tools/go/loader/doc.go
+++ b/vendor/golang.org/x/tools/go/loader/doc.go
@@ -20,36 +20,35 @@
// be called any number of times. Finally, these are followed by a
// call to Load() to actually load and type-check the program.
//
-// var conf loader.Config
+// var conf loader.Config
//
-// // Use the command-line arguments to specify
-// // a set of initial packages to load from source.
-// // See FromArgsUsage for help.
-// rest, err := conf.FromArgs(os.Args[1:], wantTests)
+// // Use the command-line arguments to specify
+// // a set of initial packages to load from source.
+// // See FromArgsUsage for help.
+// rest, err := conf.FromArgs(os.Args[1:], wantTests)
//
-// // Parse the specified files and create an ad hoc package with path "foo".
-// // All files must have the same 'package' declaration.
-// conf.CreateFromFilenames("foo", "foo.go", "bar.go")
+// // Parse the specified files and create an ad hoc package with path "foo".
+// // All files must have the same 'package' declaration.
+// conf.CreateFromFilenames("foo", "foo.go", "bar.go")
//
-// // Create an ad hoc package with path "foo" from
-// // the specified already-parsed files.
-// // All ASTs must have the same 'package' declaration.
-// conf.CreateFromFiles("foo", parsedFiles)
+// // Create an ad hoc package with path "foo" from
+// // the specified already-parsed files.
+// // All ASTs must have the same 'package' declaration.
+// conf.CreateFromFiles("foo", parsedFiles)
//
-// // Add "runtime" to the set of packages to be loaded.
-// conf.Import("runtime")
+// // Add "runtime" to the set of packages to be loaded.
+// conf.Import("runtime")
//
-// // Adds "fmt" and "fmt_test" to the set of packages
-// // to be loaded. "fmt" will include *_test.go files.
-// conf.ImportWithTests("fmt")
+// // Adds "fmt" and "fmt_test" to the set of packages
+// // to be loaded. "fmt" will include *_test.go files.
+// conf.ImportWithTests("fmt")
//
-// // Finally, load all the packages specified by the configuration.
-// prog, err := conf.Load()
+// // Finally, load all the packages specified by the configuration.
+// prog, err := conf.Load()
//
// See examples_test.go for examples of API usage.
//
-//
-// CONCEPTS AND TERMINOLOGY
+// # CONCEPTS AND TERMINOLOGY
//
// The WORKSPACE is the set of packages accessible to the loader. The
// workspace is defined by Config.Build, a *build.Context. The
@@ -92,7 +91,6 @@
// The INITIAL packages are those specified in the configuration. A
// DEPENDENCY is a package loaded to satisfy an import in an initial
// package or another dependency.
-//
package loader
// IMPLEMENTATION NOTES
diff --git a/vendor/golang.org/x/tools/go/loader/loader.go b/vendor/golang.org/x/tools/go/loader/loader.go
index 508a1fd..edf62c2 100644
--- a/vendor/golang.org/x/tools/go/loader/loader.go
+++ b/vendor/golang.org/x/tools/go/loader/loader.go
@@ -23,6 +23,7 @@ import (
"golang.org/x/tools/go/ast/astutil"
"golang.org/x/tools/go/internal/cgo"
+ "golang.org/x/tools/internal/typeparams"
)
var ignoreVendor build.ImportMode
@@ -178,7 +179,6 @@ type Program struct {
// for a single package.
//
// Not mutated once exposed via the API.
-//
type PackageInfo struct {
Pkg *types.Package
Importable bool // true if 'import "Pkg.Path()"' would resolve to this
@@ -216,7 +216,6 @@ func (conf *Config) fset() *token.FileSet {
// src specifies the parser input as a string, []byte, or io.Reader, and
// filename is its apparent name. If src is nil, the contents of
// filename are read from the file system.
-//
func (conf *Config) ParseFile(filename string, src interface{}) (*ast.File, error) {
// TODO(adonovan): use conf.build() etc like parseFiles does.
return parser.ParseFile(conf.fset(), filename, src, conf.ParserMode)
@@ -261,7 +260,6 @@ A '--' argument terminates the list of packages.
//
// Only superficial errors are reported at this stage; errors dependent
// on I/O are detected during Load.
-//
func (conf *Config) FromArgs(args []string, xtest bool) ([]string, error) {
var rest []string
for i, arg := range args {
@@ -299,14 +297,12 @@ func (conf *Config) FromArgs(args []string, xtest bool) ([]string, error) {
// CreateFromFilenames is a convenience function that adds
// a conf.CreatePkgs entry to create a package of the specified *.go
// files.
-//
func (conf *Config) CreateFromFilenames(path string, filenames ...string) {
conf.CreatePkgs = append(conf.CreatePkgs, PkgSpec{Path: path, Filenames: filenames})
}
// CreateFromFiles is a convenience function that adds a conf.CreatePkgs
// entry to create package of the specified path and parsed files.
-//
func (conf *Config) CreateFromFiles(path string, files ...*ast.File) {
conf.CreatePkgs = append(conf.CreatePkgs, PkgSpec{Path: path, Files: files})
}
@@ -320,12 +316,10 @@ func (conf *Config) CreateFromFiles(path string, files ...*ast.File) {
// In addition, if any *_test.go files contain a "package x_test"
// declaration, an additional package comprising just those files will
// be added to CreatePkgs.
-//
func (conf *Config) ImportWithTests(path string) { conf.addImport(path, true) }
// Import is a convenience function that adds path to ImportPkgs, the
// set of initial packages that will be imported from source.
-//
func (conf *Config) Import(path string) { conf.addImport(path, false) }
func (conf *Config) addImport(path string, tests bool) {
@@ -344,7 +338,6 @@ func (conf *Config) addImport(path string, tests bool) {
// exact is defined as for astutil.PathEnclosingInterval.
//
// The zero value is returned if not found.
-//
func (prog *Program) PathEnclosingInterval(start, end token.Pos) (pkg *PackageInfo, path []ast.Node, exact bool) {
for _, info := range prog.AllPackages {
for _, f := range info.Files {
@@ -367,7 +360,6 @@ func (prog *Program) PathEnclosingInterval(start, end token.Pos) (pkg *PackageIn
// InitialPackages returns a new slice containing the set of initial
// packages (Created + Imported) in unspecified order.
-//
func (prog *Program) InitialPackages() []*PackageInfo {
infos := make([]*PackageInfo, 0, len(prog.Created)+len(prog.Imported))
infos = append(infos, prog.Created...)
@@ -434,7 +426,6 @@ type findpkgValue struct {
// Upon completion, exactly one of info and err is non-nil:
// info on successful creation of a package, err otherwise.
// A successful package may still contain type errors.
-//
type importInfo struct {
path string // import path
info *PackageInfo // results of typechecking (including errors)
@@ -474,7 +465,6 @@ type importError struct {
// false, Load will fail if any package had an error.
//
// It is an error if no packages were loaded.
-//
func (conf *Config) Load() (*Program, error) {
// Create a simple default error handler for parse/type errors.
if conf.TypeChecker.Error == nil {
@@ -731,10 +721,10 @@ func (conf *Config) build() *build.Context {
// errors that were encountered.
//
// 'which' indicates which files to include:
-// 'g': include non-test *.go source files (GoFiles + processed CgoFiles)
-// 't': include in-package *_test.go source files (TestGoFiles)
-// 'x': include external *_test.go source files. (XTestGoFiles)
//
+// 'g': include non-test *.go source files (GoFiles + processed CgoFiles)
+// 't': include in-package *_test.go source files (TestGoFiles)
+// 'x': include external *_test.go source files. (XTestGoFiles)
func (conf *Config) parsePackageFiles(bp *build.Package, which rune) ([]*ast.File, []error) {
if bp.ImportPath == "unsafe" {
return nil, nil
@@ -775,7 +765,6 @@ func (conf *Config) parsePackageFiles(bp *build.Package, which rune) ([]*ast.Fil
// in the package's PackageInfo).
//
// Idempotent.
-//
func (imp *importer) doImport(from *PackageInfo, to string) (*types.Package, error) {
if to == "C" {
// This should be unreachable, but ad hoc packages are
@@ -867,7 +856,6 @@ func (imp *importer) findPackage(importPath, fromDir string, mode build.ImportMo
//
// fromDir is the directory containing the import declaration that
// caused these imports.
-//
func (imp *importer) importAll(fromPath, fromDir string, imports map[string]bool, mode build.ImportMode) (infos []*PackageInfo, errors []importError) {
if fromPath != "" {
// We're loading a set of imports.
@@ -950,7 +938,6 @@ func (imp *importer) findPath(from, to string) []string {
// caller must call awaitCompletion() before accessing its info field.
//
// startLoad is concurrency-safe and idempotent.
-//
func (imp *importer) startLoad(bp *build.Package) *importInfo {
path := bp.ImportPath
imp.importedMu.Lock()
@@ -994,7 +981,6 @@ func (imp *importer) load(bp *build.Package) *PackageInfo {
//
// cycleCheck determines whether the imports within files create
// dependency edges that should be checked for potential cycles.
-//
func (imp *importer) addFiles(info *PackageInfo, files []*ast.File, cycleCheck bool) {
// Ensure the dependencies are loaded, in parallel.
var fromPath string
@@ -1053,6 +1039,7 @@ func (imp *importer) newPackageInfo(path, dir string) *PackageInfo {
errorFunc: imp.conf.TypeChecker.Error,
dir: dir,
}
+ typeparams.InitInstanceInfo(&info.Info)
// Copy the types.Config so we can vary it across PackageInfos.
tc := imp.conf.TypeChecker
diff --git a/vendor/golang.org/x/tools/go/loader/util.go b/vendor/golang.org/x/tools/go/loader/util.go
index 7f38dd7..3a80aca 100644
--- a/vendor/golang.org/x/tools/go/loader/util.go
+++ b/vendor/golang.org/x/tools/go/loader/util.go
@@ -27,7 +27,6 @@ var ioLimit = make(chan bool, 10)
//
// I/O is done via ctxt, which may specify a virtual file system.
// displayPath is used to transform the filenames attached to the ASTs.
-//
func parseFiles(fset *token.FileSet, ctxt *build.Context, displayPath func(string) string, dir string, files []string, mode parser.Mode) ([]*ast.File, []error) {
if displayPath == nil {
displayPath = func(path string) string { return path }
diff --git a/vendor/golang.org/x/tools/internal/typeparams/common.go b/vendor/golang.org/x/tools/internal/typeparams/common.go
index 1222764..25a1426 100644
--- a/vendor/golang.org/x/tools/internal/typeparams/common.go
+++ b/vendor/golang.org/x/tools/internal/typeparams/common.go
@@ -16,11 +16,10 @@
// Additionally, this package contains common utilities for working with the
// new generic constructs, to supplement the standard library APIs. Notably,
// the StructuralTerms API computes a minimal representation of the structural
-// restrictions on a type parameter. In the future, this API may be available
-// from go/types.
+// restrictions on a type parameter.
//
-// See the example/README.md for a more detailed guide on how to update tools
-// to support generics.
+// An external version of these APIs is available in the
+// golang.org/x/exp/typeparams module.
package typeparams
import (
@@ -77,3 +76,104 @@ func IsTypeParam(t types.Type) bool {
_, ok := t.(*TypeParam)
return ok
}
+
+// OriginMethod returns the origin method associated with the method fn.
+// For methods on a non-generic receiver base type, this is just
+// fn. However, for methods with a generic receiver, OriginMethod returns the
+// corresponding method in the method set of the origin type.
+//
+// As a special case, if fn is not a method (has no receiver), OriginMethod
+// returns fn.
+func OriginMethod(fn *types.Func) *types.Func {
+ recv := fn.Type().(*types.Signature).Recv()
+ if recv == nil {
+
+ return fn
+ }
+ base := recv.Type()
+ p, isPtr := base.(*types.Pointer)
+ if isPtr {
+ base = p.Elem()
+ }
+ named, isNamed := base.(*types.Named)
+ if !isNamed {
+ // Receiver is a *types.Interface.
+ return fn
+ }
+ if ForNamed(named).Len() == 0 {
+ // Receiver base has no type parameters, so we can avoid the lookup below.
+ return fn
+ }
+ orig := NamedTypeOrigin(named)
+ gfn, _, _ := types.LookupFieldOrMethod(orig, true, fn.Pkg(), fn.Name())
+ return gfn.(*types.Func)
+}
+
+// GenericAssignableTo is a generalization of types.AssignableTo that
+// implements the following rule for uninstantiated generic types:
+//
+// If V and T are generic named types, then V is considered assignable to T if,
+// for every possible instantation of V[A_1, ..., A_N], the instantiation
+// T[A_1, ..., A_N] is valid and V[A_1, ..., A_N] implements T[A_1, ..., A_N].
+//
+// If T has structural constraints, they must be satisfied by V.
+//
+// For example, consider the following type declarations:
+//
+// type Interface[T any] interface {
+// Accept(T)
+// }
+//
+// type Container[T any] struct {
+// Element T
+// }
+//
+// func (c Container[T]) Accept(t T) { c.Element = t }
+//
+// In this case, GenericAssignableTo reports that instantiations of Container
+// are assignable to the corresponding instantiation of Interface.
+func GenericAssignableTo(ctxt *Context, V, T types.Type) bool {
+ // If V and T are not both named, or do not have matching non-empty type
+ // parameter lists, fall back on types.AssignableTo.
+
+ VN, Vnamed := V.(*types.Named)
+ TN, Tnamed := T.(*types.Named)
+ if !Vnamed || !Tnamed {
+ return types.AssignableTo(V, T)
+ }
+
+ vtparams := ForNamed(VN)
+ ttparams := ForNamed(TN)
+ if vtparams.Len() == 0 || vtparams.Len() != ttparams.Len() || NamedTypeArgs(VN).Len() != 0 || NamedTypeArgs(TN).Len() != 0 {
+ return types.AssignableTo(V, T)
+ }
+
+ // V and T have the same (non-zero) number of type params. Instantiate both
+ // with the type parameters of V. This must always succeed for V, and will
+ // succeed for T if and only if the type set of each type parameter of V is a
+ // subset of the type set of the corresponding type parameter of T, meaning
+ // that every instantiation of V corresponds to a valid instantiation of T.
+
+ // Minor optimization: ensure we share a context across the two
+ // instantiations below.
+ if ctxt == nil {
+ ctxt = NewContext()
+ }
+
+ var targs []types.Type
+ for i := 0; i < vtparams.Len(); i++ {
+ targs = append(targs, vtparams.At(i))
+ }
+
+ vinst, err := Instantiate(ctxt, V, targs, true)
+ if err != nil {
+ panic("type parameters should satisfy their own constraints")
+ }
+
+ tinst, err := Instantiate(ctxt, T, targs, true)
+ if err != nil {
+ return false
+ }
+
+ return types.AssignableTo(vinst, tinst)
+}
diff --git a/vendor/golang.org/x/tools/internal/typeparams/coretype.go b/vendor/golang.org/x/tools/internal/typeparams/coretype.go
new file mode 100644
index 0000000..993135e
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typeparams/coretype.go
@@ -0,0 +1,122 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typeparams
+
+import (
+ "go/types"
+)
+
+// CoreType returns the core type of T or nil if T does not have a core type.
+//
+// See https://go.dev/ref/spec#Core_types for the definition of a core type.
+func CoreType(T types.Type) types.Type {
+ U := T.Underlying()
+ if _, ok := U.(*types.Interface); !ok {
+ return U // for non-interface types,
+ }
+
+ terms, err := _NormalTerms(U)
+ if len(terms) == 0 || err != nil {
+ // len(terms) -> empty type set of interface.
+ // err != nil => U is invalid, exceeds complexity bounds, or has an empty type set.
+ return nil // no core type.
+ }
+
+ U = terms[0].Type().Underlying()
+ var identical int // i in [0,identical) => Identical(U, terms[i].Type().Underlying())
+ for identical = 1; identical < len(terms); identical++ {
+ if !types.Identical(U, terms[identical].Type().Underlying()) {
+ break
+ }
+ }
+
+ if identical == len(terms) {
+ // https://go.dev/ref/spec#Core_types
+ // "There is a single type U which is the underlying type of all types in the type set of T"
+ return U
+ }
+ ch, ok := U.(*types.Chan)
+ if !ok {
+ return nil // no core type as identical < len(terms) and U is not a channel.
+ }
+ // https://go.dev/ref/spec#Core_types
+ // "the type chan E if T contains only bidirectional channels, or the type chan<- E or
+ // <-chan E depending on the direction of the directional channels present."
+ for chans := identical; chans < len(terms); chans++ {
+ curr, ok := terms[chans].Type().Underlying().(*types.Chan)
+ if !ok {
+ return nil
+ }
+ if !types.Identical(ch.Elem(), curr.Elem()) {
+ return nil // channel elements are not identical.
+ }
+ if ch.Dir() == types.SendRecv {
+ // ch is bidirectional. We can safely always use curr's direction.
+ ch = curr
+ } else if curr.Dir() != types.SendRecv && ch.Dir() != curr.Dir() {
+ // ch and curr are not bidirectional and not the same direction.
+ return nil
+ }
+ }
+ return ch
+}
+
+// _NormalTerms returns a slice of terms representing the normalized structural
+// type restrictions of a type, if any.
+//
+// For all types other than *types.TypeParam, *types.Interface, and
+// *types.Union, this is just a single term with Tilde() == false and
+// Type() == typ. For *types.TypeParam, *types.Interface, and *types.Union, see
+// below.
+//
+// Structural type restrictions of a type parameter are created via
+// non-interface types embedded in its constraint interface (directly, or via a
+// chain of interface embeddings). For example, in the declaration type
+// T[P interface{~int; m()}] int the structural restriction of the type
+// parameter P is ~int.
+//
+// With interface embedding and unions, the specification of structural type
+// restrictions may be arbitrarily complex. For example, consider the
+// following:
+//
+// type A interface{ ~string|~[]byte }
+//
+// type B interface{ int|string }
+//
+// type C interface { ~string|~int }
+//
+// type T[P interface{ A|B; C }] int
+//
+// In this example, the structural type restriction of P is ~string|int: A|B
+// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int,
+// which when intersected with C (~string|~int) yields ~string|int.
+//
+// _NormalTerms computes these expansions and reductions, producing a
+// "normalized" form of the embeddings. A structural restriction is normalized
+// if it is a single union containing no interface terms, and is minimal in the
+// sense that removing any term changes the set of types satisfying the
+// constraint. It is left as a proof for the reader that, modulo sorting, there
+// is exactly one such normalized form.
+//
+// Because the minimal representation always takes this form, _NormalTerms
+// returns a slice of tilde terms corresponding to the terms of the union in
+// the normalized structural restriction. An error is returned if the type is
+// invalid, exceeds complexity bounds, or has an empty type set. In the latter
+// case, _NormalTerms returns ErrEmptyTypeSet.
+//
+// _NormalTerms makes no guarantees about the order of terms, except that it
+// is deterministic.
+func _NormalTerms(typ types.Type) ([]*Term, error) {
+ switch typ := typ.(type) {
+ case *TypeParam:
+ return StructuralTerms(typ)
+ case *Union:
+ return UnionTermSet(typ)
+ case *types.Interface:
+ return InterfaceTermSet(typ)
+ default:
+ return []*Term{NewTerm(false, typ)}, nil
+ }
+}
diff --git a/vendor/golang.org/x/tools/internal/typeparams/normalize.go b/vendor/golang.org/x/tools/internal/typeparams/normalize.go
index 090f142..9c631b6 100644
--- a/vendor/golang.org/x/tools/internal/typeparams/normalize.go
+++ b/vendor/golang.org/x/tools/internal/typeparams/normalize.go
@@ -24,20 +24,22 @@ var ErrEmptyTypeSet = errors.New("empty type set")
// Structural type restrictions of a type parameter are created via
// non-interface types embedded in its constraint interface (directly, or via a
// chain of interface embeddings). For example, in the declaration
-// type T[P interface{~int; m()}] int
+//
+// type T[P interface{~int; m()}] int
+//
// the structural restriction of the type parameter P is ~int.
//
// With interface embedding and unions, the specification of structural type
// restrictions may be arbitrarily complex. For example, consider the
// following:
//
-// type A interface{ ~string|~[]byte }
+// type A interface{ ~string|~[]byte }
//
-// type B interface{ int|string }
+// type B interface{ int|string }
//
-// type C interface { ~string|~int }
+// type C interface { ~string|~int }
//
-// type T[P interface{ A|B; C }] int
+// type T[P interface{ A|B; C }] int
//
// In this example, the structural type restriction of P is ~string|int: A|B
// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int,
diff --git a/vendor/golang.org/x/tools/internal/typeparams/termlist.go b/vendor/golang.org/x/tools/internal/typeparams/termlist.go
index 10857d5..933106a 100644
--- a/vendor/golang.org/x/tools/internal/typeparams/termlist.go
+++ b/vendor/golang.org/x/tools/internal/typeparams/termlist.go
@@ -97,15 +97,6 @@ func (xl termlist) norm() termlist {
return rl
}
-// If the type set represented by xl is specified by a single (non-𝓤) term,
-// structuralType returns that type. Otherwise it returns nil.
-func (xl termlist) structuralType() types.Type {
- if nl := xl.norm(); len(nl) == 1 {
- return nl[0].typ // if nl.isAll() then typ is nil, which is ok
- }
- return nil
-}
-
// union returns the union xl ∪ yl.
func (xl termlist) union(yl termlist) termlist {
return append(xl, yl...).norm()
diff --git a/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go b/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go
index 5fd3fc3..b478897 100644
--- a/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go
+++ b/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go
@@ -185,6 +185,11 @@ func GetInstances(info *types.Info) map[*ast.Ident]Instance { return nil }
// this Go version.
type Context struct{}
+// NewContext returns a placeholder Context instance.
+func NewContext() *Context {
+ return &Context{}
+}
+
// Instantiate is unsupported on this Go version, and panics.
func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) {
unsupported()
diff --git a/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go b/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go
index 7470aed..114a36b 100644
--- a/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go
+++ b/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go
@@ -140,6 +140,11 @@ func GetInstances(info *types.Info) map[*ast.Ident]Instance {
// Context is an alias for types.Context.
type Context = types.Context
+// NewContext calls types.NewContext.
+func NewContext() *Context {
+ return types.NewContext()
+}
+
// Instantiate calls types.Instantiate.
func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) {
return types.Instantiate(ctxt, typ, targs, validate)
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 9675a67..45b6271 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -189,7 +189,7 @@ github.com/swaggo/echo-swagger
# github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2
## explicit; go 1.15
github.com/swaggo/files
-# github.com/swaggo/swag v1.8.1
+# github.com/swaggo/swag v1.8.10
## explicit; go 1.18
github.com/swaggo/swag
# github.com/theflyingcodr/govalidator v0.1.3
@@ -241,8 +241,8 @@ golang.org/x/text/width
# golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9
## explicit
golang.org/x/time/rate
-# golang.org/x/tools v0.1.9
-## explicit; go 1.17
+# golang.org/x/tools v0.1.12
+## explicit; go 1.18
golang.org/x/tools/go/ast/astutil
golang.org/x/tools/go/buildutil
golang.org/x/tools/go/internal/cgo