mirror of
https://github.com/slimtoolkit/slim.git
synced 2025-06-03 04:00:23 +00:00
Bump github.com/getkin/kin-openapi from 0.76.0 to 0.131.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.76.0 to 0.131.0. - [Release notes](https://github.com/getkin/kin-openapi/releases) - [Commits](https://github.com/getkin/kin-openapi/compare/v0.76.0...v0.131.0) --- updated-dependencies: - dependency-name: github.com/getkin/kin-openapi dependency-version: 0.131.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
parent
79b63a80c1
commit
92169241a2
14
go.mod
14
go.mod
@ -1,6 +1,6 @@
|
||||
module github.com/slimtoolkit/slim
|
||||
|
||||
go 1.21
|
||||
go 1.22.5
|
||||
|
||||
require (
|
||||
github.com/armon/go-radix v1.0.0
|
||||
@ -15,7 +15,7 @@ require (
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/fatih/color v1.13.0
|
||||
github.com/fsouza/go-dockerclient v1.10.0
|
||||
github.com/getkin/kin-openapi v0.76.0
|
||||
github.com/getkin/kin-openapi v0.131.0
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/gocolly/colly/v2 v2.1.0
|
||||
github.com/google/go-containerregistry v0.19.0
|
||||
@ -59,9 +59,9 @@ require (
|
||||
github.com/go-errors/errors v1.4.2 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.1 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
@ -87,10 +87,14 @@ require (
|
||||
github.com/moby/sys/user v0.2.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect
|
||||
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/perimeterx/marshmallow v1.1.5 // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
@ -147,7 +151,7 @@ require (
|
||||
github.com/moby/patternmatcher v0.6.0 // indirect
|
||||
github.com/moby/sys/sequential v0.5.0 // indirect
|
||||
github.com/pkg/term v0.0.0-20200520122047-c3ffed290a03 // indirect
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/ulikunitz/xz v0.5.7 // indirect
|
||||
k8s.io/klog/v2 v2.90.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect
|
||||
|
42
go.sum
42
go.sum
@ -124,8 +124,8 @@ github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBd
|
||||
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/fsouza/go-dockerclient v1.10.0 h1:ppSBsbR60I1DFbV4Ag7LlHlHakHFRNLk9XakATW1yVQ=
|
||||
github.com/fsouza/go-dockerclient v1.10.0/go.mod h1:+iNzAW78AzClIBTZ6WFjkaMvOgz68GyCJ236b1opLTs=
|
||||
github.com/getkin/kin-openapi v0.76.0 h1:j77zg3Ec+k+r+GA3d8hBoXpAc6KX9TbBPrwQGBIy2sY=
|
||||
github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg=
|
||||
github.com/getkin/kin-openapi v0.131.0 h1:NO2UeHnFKRYhZ8wg6Nyh5Cq7dHk4suQQr72a4pMrDxE=
|
||||
github.com/getkin/kin-openapi v0.131.0/go.mod h1:3OlG51PCYNsPByuiMB0t4fjnNlIDnaEDsjiKUV8nL58=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
|
||||
@ -139,18 +139,20 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
|
||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||
github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8=
|
||||
github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
|
||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
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 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
|
||||
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/gocolly/colly v1.2.0/go.mod h1:Hof5T3ZswNVsOHYmba1u03W65HDWgpV5HifSuueE0EA=
|
||||
@ -246,16 +248,14 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB
|
||||
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/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
||||
@ -300,6 +300,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
@ -308,6 +310,10 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
||||
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY=
|
||||
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw=
|
||||
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c=
|
||||
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o=
|
||||
github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk=
|
||||
github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo=
|
||||
github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
|
||||
@ -317,6 +323,8 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
|
||||
github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s=
|
||||
github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@ -341,8 +349,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
|
||||
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
||||
@ -376,8 +384,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
@ -386,13 +395,15 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/temoto/robotstxt v1.1.1/go.mod h1:+1AmkuG3IYkh1kv0d2qEB9Le88ehNO0zwOr3ujewlOo=
|
||||
github.com/temoto/robotstxt v1.1.2 h1:W2pOjSJ6SWvldyEuiFXNxz3xZ8aiWX5LbfDiOFd7Fxg=
|
||||
github.com/temoto/robotstxt v1.1.2/go.mod h1:+1AmkuG3IYkh1kv0d2qEB9Le88ehNO0zwOr3ujewlOo=
|
||||
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||
github.com/ulikunitz/xz v0.5.7 h1:YvTNdFzX6+W5m9msiYg/zpkSURPPtOlzbqYjrFn7Yt4=
|
||||
github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
@ -600,7 +611,6 @@ google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHh
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
2
vendor/github.com/getkin/kin-openapi/jsoninfo/doc.go
generated
vendored
2
vendor/github.com/getkin/kin-openapi/jsoninfo/doc.go
generated
vendored
@ -1,2 +0,0 @@
|
||||
// Package jsoninfo provides information and functions for marshalling/unmarshalling JSON.
|
||||
package jsoninfo
|
121
vendor/github.com/getkin/kin-openapi/jsoninfo/field_info.go
generated
vendored
121
vendor/github.com/getkin/kin-openapi/jsoninfo/field_info.go
generated
vendored
@ -1,121 +0,0 @@
|
||||
package jsoninfo
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// FieldInfo contains information about JSON serialization of a field.
|
||||
type FieldInfo struct {
|
||||
MultipleFields bool // Whether multiple Go fields share this JSON name
|
||||
HasJSONTag bool
|
||||
TypeIsMarshaller bool
|
||||
TypeIsUnmarshaller bool
|
||||
JSONOmitEmpty bool
|
||||
JSONString bool
|
||||
Index []int
|
||||
Type reflect.Type
|
||||
JSONName string
|
||||
}
|
||||
|
||||
func AppendFields(fields []FieldInfo, parentIndex []int, t reflect.Type) []FieldInfo {
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
// For each field
|
||||
numField := t.NumField()
|
||||
iteration:
|
||||
for i := 0; i < numField; i++ {
|
||||
f := t.Field(i)
|
||||
index := make([]int, 0, len(parentIndex)+1)
|
||||
index = append(index, parentIndex...)
|
||||
index = append(index, i)
|
||||
|
||||
// See whether this is an embedded field
|
||||
if f.Anonymous {
|
||||
if f.Tag.Get("json") == "-" {
|
||||
continue
|
||||
}
|
||||
fields = AppendFields(fields, index, f.Type)
|
||||
continue iteration
|
||||
}
|
||||
|
||||
// Ignore certain types
|
||||
switch f.Type.Kind() {
|
||||
case reflect.Func, reflect.Chan:
|
||||
continue iteration
|
||||
}
|
||||
|
||||
// Is it a private (lowercase) field?
|
||||
firstRune, _ := utf8.DecodeRuneInString(f.Name)
|
||||
if unicode.IsLower(firstRune) {
|
||||
continue iteration
|
||||
}
|
||||
|
||||
// Declare a field
|
||||
field := FieldInfo{
|
||||
Index: index,
|
||||
Type: f.Type,
|
||||
JSONName: f.Name,
|
||||
}
|
||||
|
||||
// Read "json" tag
|
||||
jsonTag := f.Tag.Get("json")
|
||||
|
||||
// Read our custom "multijson" tag that
|
||||
// allows multiple fields with the same name.
|
||||
if v := f.Tag.Get("multijson"); v != "" {
|
||||
field.MultipleFields = true
|
||||
jsonTag = v
|
||||
}
|
||||
|
||||
// Handle "-"
|
||||
if jsonTag == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Parse the tag
|
||||
if jsonTag != "" {
|
||||
field.HasJSONTag = true
|
||||
for i, part := range strings.Split(jsonTag, ",") {
|
||||
if i == 0 {
|
||||
if part != "" {
|
||||
field.JSONName = part
|
||||
}
|
||||
} else {
|
||||
switch part {
|
||||
case "omitempty":
|
||||
field.JSONOmitEmpty = true
|
||||
case "string":
|
||||
field.JSONString = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_, field.TypeIsMarshaller = field.Type.MethodByName("MarshalJSON")
|
||||
_, field.TypeIsUnmarshaller = field.Type.MethodByName("UnmarshalJSON")
|
||||
|
||||
// Field is done
|
||||
fields = append(fields, field)
|
||||
}
|
||||
|
||||
return fields
|
||||
}
|
||||
|
||||
type sortableFieldInfos []FieldInfo
|
||||
|
||||
func (list sortableFieldInfos) Len() int {
|
||||
return len(list)
|
||||
}
|
||||
|
||||
func (list sortableFieldInfos) Less(i, j int) bool {
|
||||
return list[i].JSONName < list[j].JSONName
|
||||
}
|
||||
|
||||
func (list sortableFieldInfos) Swap(i, j int) {
|
||||
a, b := list[i], list[j]
|
||||
list[i], list[j] = b, a
|
||||
}
|
162
vendor/github.com/getkin/kin-openapi/jsoninfo/marshal.go
generated
vendored
162
vendor/github.com/getkin/kin-openapi/jsoninfo/marshal.go
generated
vendored
@ -1,162 +0,0 @@
|
||||
package jsoninfo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// MarshalStrictStruct function:
|
||||
// * Marshals struct fields, ignoring MarshalJSON() and fields without 'json' tag.
|
||||
// * Correctly handles StrictStruct semantics.
|
||||
func MarshalStrictStruct(value StrictStruct) ([]byte, error) {
|
||||
encoder := NewObjectEncoder()
|
||||
if err := value.EncodeWith(encoder, value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return encoder.Bytes()
|
||||
}
|
||||
|
||||
type ObjectEncoder struct {
|
||||
result map[string]json.RawMessage
|
||||
}
|
||||
|
||||
func NewObjectEncoder() *ObjectEncoder {
|
||||
return &ObjectEncoder{
|
||||
result: make(map[string]json.RawMessage, 8),
|
||||
}
|
||||
}
|
||||
|
||||
// Bytes returns the result of encoding.
|
||||
func (encoder *ObjectEncoder) Bytes() ([]byte, error) {
|
||||
return json.Marshal(encoder.result)
|
||||
}
|
||||
|
||||
// EncodeExtension adds a key/value to the current JSON object.
|
||||
func (encoder *ObjectEncoder) EncodeExtension(key string, value interface{}) error {
|
||||
data, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
encoder.result[key] = data
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncodeExtensionMap adds all properties to the result.
|
||||
func (encoder *ObjectEncoder) EncodeExtensionMap(value map[string]json.RawMessage) error {
|
||||
if value != nil {
|
||||
result := encoder.result
|
||||
for k, v := range value {
|
||||
result[k] = v
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (encoder *ObjectEncoder) EncodeStructFieldsAndExtensions(value interface{}) error {
|
||||
reflection := reflect.ValueOf(value)
|
||||
|
||||
// Follow "encoding/json" semantics
|
||||
if reflection.Kind() != reflect.Ptr {
|
||||
// Panic because this is a clear programming error
|
||||
panic(fmt.Errorf("value %s is not a pointer", reflection.Type().String()))
|
||||
}
|
||||
if reflection.IsNil() {
|
||||
// Panic because this is a clear programming error
|
||||
panic(fmt.Errorf("value %s is nil", reflection.Type().String()))
|
||||
}
|
||||
|
||||
// Take the element
|
||||
reflection = reflection.Elem()
|
||||
|
||||
// Obtain typeInfo
|
||||
typeInfo := GetTypeInfo(reflection.Type())
|
||||
|
||||
// Declare result
|
||||
result := encoder.result
|
||||
|
||||
// Supported fields
|
||||
iteration:
|
||||
for _, field := range typeInfo.Fields {
|
||||
// Fields without JSON tag are ignored
|
||||
if !field.HasJSONTag {
|
||||
continue
|
||||
}
|
||||
|
||||
// Marshal
|
||||
fieldValue := reflection.FieldByIndex(field.Index)
|
||||
if v, ok := fieldValue.Interface().(json.Marshaler); ok {
|
||||
if fieldValue.Kind() == reflect.Ptr && fieldValue.IsNil() {
|
||||
if field.JSONOmitEmpty {
|
||||
continue iteration
|
||||
}
|
||||
result[field.JSONName] = []byte("null")
|
||||
continue
|
||||
}
|
||||
fieldData, err := v.MarshalJSON()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result[field.JSONName] = fieldData
|
||||
continue
|
||||
}
|
||||
switch fieldValue.Kind() {
|
||||
case reflect.Ptr, reflect.Interface:
|
||||
if fieldValue.IsNil() {
|
||||
if field.JSONOmitEmpty {
|
||||
continue iteration
|
||||
}
|
||||
result[field.JSONName] = []byte("null")
|
||||
continue
|
||||
}
|
||||
case reflect.Struct:
|
||||
case reflect.Map:
|
||||
if field.JSONOmitEmpty && (fieldValue.IsNil() || fieldValue.Len() == 0) {
|
||||
continue iteration
|
||||
}
|
||||
case reflect.Slice:
|
||||
if field.JSONOmitEmpty && fieldValue.Len() == 0 {
|
||||
continue iteration
|
||||
}
|
||||
case reflect.Bool:
|
||||
x := fieldValue.Bool()
|
||||
if field.JSONOmitEmpty && !x {
|
||||
continue iteration
|
||||
}
|
||||
s := "false"
|
||||
if x {
|
||||
s = "true"
|
||||
}
|
||||
result[field.JSONName] = []byte(s)
|
||||
continue iteration
|
||||
case reflect.Int64, reflect.Int, reflect.Int32:
|
||||
if field.JSONOmitEmpty && fieldValue.Int() == 0 {
|
||||
continue iteration
|
||||
}
|
||||
case reflect.Uint64, reflect.Uint, reflect.Uint32:
|
||||
if field.JSONOmitEmpty && fieldValue.Uint() == 0 {
|
||||
continue iteration
|
||||
}
|
||||
case reflect.Float64:
|
||||
if field.JSONOmitEmpty && fieldValue.Float() == 0.0 {
|
||||
continue iteration
|
||||
}
|
||||
case reflect.String:
|
||||
if field.JSONOmitEmpty && len(fieldValue.String()) == 0 {
|
||||
continue iteration
|
||||
}
|
||||
default:
|
||||
panic(fmt.Errorf("field %q has unsupported type %s", field.JSONName, field.Type.String()))
|
||||
}
|
||||
|
||||
// No special treament is needed
|
||||
// Use plain old "encoding/json".Marshal
|
||||
fieldData, err := json.Marshal(fieldValue.Addr().Interface())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result[field.JSONName] = fieldData
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
30
vendor/github.com/getkin/kin-openapi/jsoninfo/marshal_ref.go
generated
vendored
30
vendor/github.com/getkin/kin-openapi/jsoninfo/marshal_ref.go
generated
vendored
@ -1,30 +0,0 @@
|
||||
package jsoninfo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
func MarshalRef(value string, otherwise interface{}) ([]byte, error) {
|
||||
if len(value) > 0 {
|
||||
return json.Marshal(&refProps{
|
||||
Ref: value,
|
||||
})
|
||||
}
|
||||
return json.Marshal(otherwise)
|
||||
}
|
||||
|
||||
func UnmarshalRef(data []byte, destRef *string, destOtherwise interface{}) error {
|
||||
refProps := &refProps{}
|
||||
if err := json.Unmarshal(data, refProps); err == nil {
|
||||
ref := refProps.Ref
|
||||
if len(ref) > 0 {
|
||||
*destRef = ref
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return json.Unmarshal(data, destOtherwise)
|
||||
}
|
||||
|
||||
type refProps struct {
|
||||
Ref string `json:"$ref,omitempty"`
|
||||
}
|
6
vendor/github.com/getkin/kin-openapi/jsoninfo/strict_struct.go
generated
vendored
6
vendor/github.com/getkin/kin-openapi/jsoninfo/strict_struct.go
generated
vendored
@ -1,6 +0,0 @@
|
||||
package jsoninfo
|
||||
|
||||
type StrictStruct interface {
|
||||
EncodeWith(encoder *ObjectEncoder, value interface{}) error
|
||||
DecodeWith(decoder *ObjectDecoder, value interface{}) error
|
||||
}
|
68
vendor/github.com/getkin/kin-openapi/jsoninfo/type_info.go
generated
vendored
68
vendor/github.com/getkin/kin-openapi/jsoninfo/type_info.go
generated
vendored
@ -1,68 +0,0 @@
|
||||
package jsoninfo
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
typeInfos = map[reflect.Type]*TypeInfo{}
|
||||
typeInfosMutex sync.RWMutex
|
||||
)
|
||||
|
||||
// TypeInfo contains information about JSON serialization of a type
|
||||
type TypeInfo struct {
|
||||
Type reflect.Type
|
||||
Fields []FieldInfo
|
||||
}
|
||||
|
||||
func GetTypeInfoForValue(value interface{}) *TypeInfo {
|
||||
return GetTypeInfo(reflect.TypeOf(value))
|
||||
}
|
||||
|
||||
// GetTypeInfo returns TypeInfo for the given type.
|
||||
func GetTypeInfo(t reflect.Type) *TypeInfo {
|
||||
for t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
typeInfosMutex.RLock()
|
||||
typeInfo, exists := typeInfos[t]
|
||||
typeInfosMutex.RUnlock()
|
||||
if exists {
|
||||
return typeInfo
|
||||
}
|
||||
if t.Kind() != reflect.Struct {
|
||||
typeInfo = &TypeInfo{
|
||||
Type: t,
|
||||
}
|
||||
} else {
|
||||
// Allocate
|
||||
typeInfo = &TypeInfo{
|
||||
Type: t,
|
||||
Fields: make([]FieldInfo, 0, 16),
|
||||
}
|
||||
|
||||
// Add fields
|
||||
typeInfo.Fields = AppendFields(nil, nil, t)
|
||||
|
||||
// Sort fields
|
||||
sort.Sort(sortableFieldInfos(typeInfo.Fields))
|
||||
}
|
||||
|
||||
// Publish
|
||||
typeInfosMutex.Lock()
|
||||
typeInfos[t] = typeInfo
|
||||
typeInfosMutex.Unlock()
|
||||
return typeInfo
|
||||
}
|
||||
|
||||
// FieldNames returns all field names
|
||||
func (typeInfo *TypeInfo) FieldNames() []string {
|
||||
fields := typeInfo.Fields
|
||||
names := make([]string, 0, len(fields))
|
||||
for _, field := range fields {
|
||||
names = append(names, field.JSONName)
|
||||
}
|
||||
return names
|
||||
}
|
121
vendor/github.com/getkin/kin-openapi/jsoninfo/unmarshal.go
generated
vendored
121
vendor/github.com/getkin/kin-openapi/jsoninfo/unmarshal.go
generated
vendored
@ -1,121 +0,0 @@
|
||||
package jsoninfo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// UnmarshalStrictStruct function:
|
||||
// * Unmarshals struct fields, ignoring UnmarshalJSON(...) and fields without 'json' tag.
|
||||
// * Correctly handles StrictStruct
|
||||
func UnmarshalStrictStruct(data []byte, value StrictStruct) error {
|
||||
decoder, err := NewObjectDecoder(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return value.DecodeWith(decoder, value)
|
||||
}
|
||||
|
||||
type ObjectDecoder struct {
|
||||
Data []byte
|
||||
remainingFields map[string]json.RawMessage
|
||||
}
|
||||
|
||||
func NewObjectDecoder(data []byte) (*ObjectDecoder, error) {
|
||||
var remainingFields map[string]json.RawMessage
|
||||
if err := json.Unmarshal(data, &remainingFields); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal extension properties: %v (%s)", err, data)
|
||||
}
|
||||
return &ObjectDecoder{
|
||||
Data: data,
|
||||
remainingFields: remainingFields,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DecodeExtensionMap returns all properties that were not decoded previously.
|
||||
func (decoder *ObjectDecoder) DecodeExtensionMap() map[string]json.RawMessage {
|
||||
return decoder.remainingFields
|
||||
}
|
||||
|
||||
func (decoder *ObjectDecoder) DecodeStructFieldsAndExtensions(value interface{}) error {
|
||||
reflection := reflect.ValueOf(value)
|
||||
if reflection.Kind() != reflect.Ptr {
|
||||
panic(fmt.Errorf("value %T is not a pointer", value))
|
||||
}
|
||||
if reflection.IsNil() {
|
||||
panic(fmt.Errorf("value %T is nil", value))
|
||||
}
|
||||
reflection = reflection.Elem()
|
||||
for (reflection.Kind() == reflect.Interface || reflection.Kind() == reflect.Ptr) && !reflection.IsNil() {
|
||||
reflection = reflection.Elem()
|
||||
}
|
||||
reflectionType := reflection.Type()
|
||||
if reflectionType.Kind() != reflect.Struct {
|
||||
panic(fmt.Errorf("value %T is not a struct", value))
|
||||
}
|
||||
typeInfo := GetTypeInfo(reflectionType)
|
||||
|
||||
// Supported fields
|
||||
fields := typeInfo.Fields
|
||||
remainingFields := decoder.remainingFields
|
||||
for fieldIndex, field := range fields {
|
||||
// Fields without JSON tag are ignored
|
||||
if !field.HasJSONTag {
|
||||
continue
|
||||
}
|
||||
|
||||
// Get data
|
||||
fieldData, exists := remainingFields[field.JSONName]
|
||||
if !exists {
|
||||
continue
|
||||
}
|
||||
|
||||
// Unmarshal
|
||||
if field.TypeIsUnmarshaller {
|
||||
fieldType := field.Type
|
||||
isPtr := false
|
||||
if fieldType.Kind() == reflect.Ptr {
|
||||
fieldType = fieldType.Elem()
|
||||
isPtr = true
|
||||
}
|
||||
fieldValue := reflect.New(fieldType)
|
||||
if err := fieldValue.Interface().(json.Unmarshaler).UnmarshalJSON(fieldData); err != nil {
|
||||
if field.MultipleFields {
|
||||
i := fieldIndex + 1
|
||||
if i < len(fields) && fields[i].JSONName == field.JSONName {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("failed to unmarshal property %q (%s): %v",
|
||||
field.JSONName, fieldValue.Type().String(), err)
|
||||
}
|
||||
if !isPtr {
|
||||
fieldValue = fieldValue.Elem()
|
||||
}
|
||||
reflection.FieldByIndex(field.Index).Set(fieldValue)
|
||||
|
||||
// Remove the field from remaining fields
|
||||
delete(remainingFields, field.JSONName)
|
||||
} else {
|
||||
fieldPtr := reflection.FieldByIndex(field.Index)
|
||||
if fieldPtr.Kind() != reflect.Ptr || fieldPtr.IsNil() {
|
||||
fieldPtr = fieldPtr.Addr()
|
||||
}
|
||||
if err := json.Unmarshal(fieldData, fieldPtr.Interface()); err != nil {
|
||||
if field.MultipleFields {
|
||||
i := fieldIndex + 1
|
||||
if i < len(fields) && fields[i].JSONName == field.JSONName {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("failed to unmarshal property %q (%s): %v",
|
||||
field.JSONName, fieldPtr.Type().String(), err)
|
||||
}
|
||||
|
||||
// Remove the field from remaining fields
|
||||
delete(remainingFields, field.JSONName)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
42
vendor/github.com/getkin/kin-openapi/jsoninfo/unsupported_properties_error.go
generated
vendored
42
vendor/github.com/getkin/kin-openapi/jsoninfo/unsupported_properties_error.go
generated
vendored
@ -1,42 +0,0 @@
|
||||
package jsoninfo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// UnsupportedPropertiesError is a helper for extensions that want to refuse
|
||||
// unsupported JSON object properties.
|
||||
//
|
||||
// It produces a helpful error message.
|
||||
type UnsupportedPropertiesError struct {
|
||||
Value interface{}
|
||||
UnsupportedProperties map[string]json.RawMessage
|
||||
}
|
||||
|
||||
func NewUnsupportedPropertiesError(v interface{}, m map[string]json.RawMessage) error {
|
||||
return &UnsupportedPropertiesError{
|
||||
Value: v,
|
||||
UnsupportedProperties: m,
|
||||
}
|
||||
}
|
||||
|
||||
func (err *UnsupportedPropertiesError) Error() string {
|
||||
m := err.UnsupportedProperties
|
||||
typeInfo := GetTypeInfoForValue(err.Value)
|
||||
if m == nil || typeInfo == nil {
|
||||
return fmt.Sprintf("invalid %T", *err)
|
||||
}
|
||||
keys := make([]string, 0, len(m))
|
||||
for k := range m {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
supported := typeInfo.FieldNames()
|
||||
if len(supported) == 0 {
|
||||
return fmt.Sprintf("type \"%T\" doesn't take any properties. Unsupported properties: %+v",
|
||||
err.Value, keys)
|
||||
}
|
||||
return fmt.Sprintf("unsupported properties: %+v (supported properties are: %+v)", keys, supported)
|
||||
}
|
15
vendor/github.com/getkin/kin-openapi/openapi2/header.go
generated
vendored
Normal file
15
vendor/github.com/getkin/kin-openapi/openapi2/header.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
package openapi2
|
||||
|
||||
type Header struct {
|
||||
Parameter
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of Header.
|
||||
func (header Header) MarshalJSON() ([]byte, error) {
|
||||
return header.Parameter.MarshalJSON()
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Header to a copy of data.
|
||||
func (header *Header) UnmarshalJSON(data []byte) error {
|
||||
return header.Parameter.UnmarshalJSON(data)
|
||||
}
|
15
vendor/github.com/getkin/kin-openapi/openapi2/helpers.go
generated
vendored
Normal file
15
vendor/github.com/getkin/kin-openapi/openapi2/helpers.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
package openapi2
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// copyURI makes a copy of the pointer.
|
||||
func copyURI(u *url.URL) *url.URL {
|
||||
if u == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
c := *u // shallow-copy
|
||||
return &c
|
||||
}
|
34
vendor/github.com/getkin/kin-openapi/openapi2/marsh.go
generated
vendored
Normal file
34
vendor/github.com/getkin/kin-openapi/openapi2/marsh.go
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
package openapi2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/oasdiff/yaml"
|
||||
)
|
||||
|
||||
func unmarshalError(jsonUnmarshalErr error) error {
|
||||
if before, after, found := strings.Cut(jsonUnmarshalErr.Error(), "Bis"); found && before != "" && after != "" {
|
||||
before = strings.ReplaceAll(before, " Go struct ", " ")
|
||||
return fmt.Errorf("%s%s", before, strings.ReplaceAll(after, "Bis", ""))
|
||||
}
|
||||
return jsonUnmarshalErr
|
||||
}
|
||||
|
||||
func unmarshal(data []byte, v any) error {
|
||||
var jsonErr, yamlErr error
|
||||
|
||||
// See https://github.com/getkin/kin-openapi/issues/680
|
||||
if jsonErr = json.Unmarshal(data, v); jsonErr == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalStrict(data, v) TODO: investigate how ymlv3 handles duplicate map keys
|
||||
if yamlErr = yaml.Unmarshal(data, v); yamlErr == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// If both unmarshaling attempts fail, return a new error that includes both errors
|
||||
return fmt.Errorf("failed to unmarshal data: json error: %v, yaml error: %v", jsonErr, yamlErr)
|
||||
}
|
344
vendor/github.com/getkin/kin-openapi/openapi2/openapi2.go
generated
vendored
344
vendor/github.com/getkin/kin-openapi/openapi2/openapi2.go
generated
vendored
@ -1,270 +1,120 @@
|
||||
package openapi2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
"github.com/getkin/kin-openapi/openapi3"
|
||||
)
|
||||
|
||||
// T is the root of an OpenAPI v2 document
|
||||
type T struct {
|
||||
openapi3.ExtensionProps
|
||||
Swagger string `json:"swagger" yaml:"swagger"`
|
||||
Info openapi3.Info `json:"info" yaml:"info"`
|
||||
ExternalDocs *openapi3.ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
|
||||
Schemes []string `json:"schemes,omitempty" yaml:"schemes,omitempty"`
|
||||
Consumes []string `json:"consumes,omitempty" yaml:"consumes,omitempty"`
|
||||
Host string `json:"host,omitempty" yaml:"host,omitempty"`
|
||||
BasePath string `json:"basePath,omitempty" yaml:"basePath,omitempty"`
|
||||
Paths map[string]*PathItem `json:"paths,omitempty" yaml:"paths,omitempty"`
|
||||
Definitions map[string]*openapi3.SchemaRef `json:"definitions,omitempty,noref" yaml:"definitions,omitempty,noref"`
|
||||
Parameters map[string]*Parameter `json:"parameters,omitempty,noref" yaml:"parameters,omitempty,noref"`
|
||||
Responses map[string]*Response `json:"responses,omitempty,noref" yaml:"responses,omitempty,noref"`
|
||||
SecurityDefinitions map[string]*SecurityScheme `json:"securityDefinitions,omitempty" yaml:"securityDefinitions,omitempty"`
|
||||
Security SecurityRequirements `json:"security,omitempty" yaml:"security,omitempty"`
|
||||
Tags openapi3.Tags `json:"tags,omitempty" yaml:"tags,omitempty"`
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
|
||||
Swagger string `json:"swagger" yaml:"swagger"` // required
|
||||
Info openapi3.Info `json:"info" yaml:"info"` // required
|
||||
ExternalDocs *openapi3.ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
|
||||
Schemes []string `json:"schemes,omitempty" yaml:"schemes,omitempty"`
|
||||
Consumes []string `json:"consumes,omitempty" yaml:"consumes,omitempty"`
|
||||
Produces []string `json:"produces,omitempty" yaml:"produces,omitempty"`
|
||||
Host string `json:"host,omitempty" yaml:"host,omitempty"`
|
||||
BasePath string `json:"basePath,omitempty" yaml:"basePath,omitempty"`
|
||||
Paths map[string]*PathItem `json:"paths,omitempty" yaml:"paths,omitempty"`
|
||||
Definitions map[string]*SchemaRef `json:"definitions,omitempty" yaml:"definitions,omitempty"`
|
||||
Parameters map[string]*Parameter `json:"parameters,omitempty" yaml:"parameters,omitempty"`
|
||||
Responses map[string]*Response `json:"responses,omitempty" yaml:"responses,omitempty"`
|
||||
SecurityDefinitions map[string]*SecurityScheme `json:"securityDefinitions,omitempty" yaml:"securityDefinitions,omitempty"`
|
||||
Security SecurityRequirements `json:"security,omitempty" yaml:"security,omitempty"`
|
||||
Tags openapi3.Tags `json:"tags,omitempty" yaml:"tags,omitempty"`
|
||||
}
|
||||
|
||||
func (doc *T) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(doc)
|
||||
// MarshalJSON returns the JSON encoding of T.
|
||||
func (doc T) MarshalJSON() ([]byte, error) {
|
||||
m := make(map[string]any, 15+len(doc.Extensions))
|
||||
for k, v := range doc.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
m["swagger"] = doc.Swagger
|
||||
m["info"] = doc.Info
|
||||
if x := doc.ExternalDocs; x != nil {
|
||||
m["externalDocs"] = x
|
||||
}
|
||||
if x := doc.Schemes; len(x) != 0 {
|
||||
m["schemes"] = x
|
||||
}
|
||||
if x := doc.Consumes; len(x) != 0 {
|
||||
m["consumes"] = x
|
||||
}
|
||||
if x := doc.Produces; len(x) != 0 {
|
||||
m["produces"] = x
|
||||
}
|
||||
if x := doc.Host; x != "" {
|
||||
m["host"] = x
|
||||
}
|
||||
if x := doc.BasePath; x != "" {
|
||||
m["basePath"] = x
|
||||
}
|
||||
if x := doc.Paths; len(x) != 0 {
|
||||
m["paths"] = x
|
||||
}
|
||||
if x := doc.Definitions; len(x) != 0 {
|
||||
m["definitions"] = x
|
||||
}
|
||||
if x := doc.Parameters; len(x) != 0 {
|
||||
m["parameters"] = x
|
||||
}
|
||||
if x := doc.Responses; len(x) != 0 {
|
||||
m["responses"] = x
|
||||
}
|
||||
if x := doc.SecurityDefinitions; len(x) != 0 {
|
||||
m["securityDefinitions"] = x
|
||||
}
|
||||
if x := doc.Security; len(x) != 0 {
|
||||
m["security"] = x
|
||||
}
|
||||
if x := doc.Tags; len(x) != 0 {
|
||||
m["tags"] = x
|
||||
}
|
||||
return json.Marshal(m)
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets T to a copy of data.
|
||||
func (doc *T) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, doc)
|
||||
type TBis T
|
||||
var x TBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, "swagger")
|
||||
delete(x.Extensions, "info")
|
||||
delete(x.Extensions, "externalDocs")
|
||||
delete(x.Extensions, "schemes")
|
||||
delete(x.Extensions, "consumes")
|
||||
delete(x.Extensions, "produces")
|
||||
delete(x.Extensions, "host")
|
||||
delete(x.Extensions, "basePath")
|
||||
delete(x.Extensions, "paths")
|
||||
delete(x.Extensions, "definitions")
|
||||
delete(x.Extensions, "parameters")
|
||||
delete(x.Extensions, "responses")
|
||||
delete(x.Extensions, "securityDefinitions")
|
||||
delete(x.Extensions, "security")
|
||||
delete(x.Extensions, "tags")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*doc = T(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (doc *T) AddOperation(path string, method string, operation *Operation) {
|
||||
paths := doc.Paths
|
||||
if paths == nil {
|
||||
paths = make(map[string]*PathItem, 8)
|
||||
doc.Paths = paths
|
||||
if doc.Paths == nil {
|
||||
doc.Paths = make(map[string]*PathItem)
|
||||
}
|
||||
pathItem := paths[path]
|
||||
pathItem := doc.Paths[path]
|
||||
if pathItem == nil {
|
||||
pathItem = &PathItem{}
|
||||
paths[path] = pathItem
|
||||
doc.Paths[path] = pathItem
|
||||
}
|
||||
pathItem.SetOperation(method, operation)
|
||||
}
|
||||
|
||||
type PathItem struct {
|
||||
openapi3.ExtensionProps
|
||||
Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
|
||||
Delete *Operation `json:"delete,omitempty" yaml:"delete,omitempty"`
|
||||
Get *Operation `json:"get,omitempty" yaml:"get,omitempty"`
|
||||
Head *Operation `json:"head,omitempty" yaml:"head,omitempty"`
|
||||
Options *Operation `json:"options,omitempty" yaml:"options,omitempty"`
|
||||
Patch *Operation `json:"patch,omitempty" yaml:"patch,omitempty"`
|
||||
Post *Operation `json:"post,omitempty" yaml:"post,omitempty"`
|
||||
Put *Operation `json:"put,omitempty" yaml:"put,omitempty"`
|
||||
Parameters Parameters `json:"parameters,omitempty" yaml:"parameters,omitempty"`
|
||||
}
|
||||
|
||||
func (pathItem *PathItem) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(pathItem)
|
||||
}
|
||||
|
||||
func (pathItem *PathItem) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, pathItem)
|
||||
}
|
||||
|
||||
func (pathItem *PathItem) Operations() map[string]*Operation {
|
||||
operations := make(map[string]*Operation, 8)
|
||||
if v := pathItem.Delete; v != nil {
|
||||
operations[http.MethodDelete] = v
|
||||
}
|
||||
if v := pathItem.Get; v != nil {
|
||||
operations[http.MethodGet] = v
|
||||
}
|
||||
if v := pathItem.Head; v != nil {
|
||||
operations[http.MethodHead] = v
|
||||
}
|
||||
if v := pathItem.Options; v != nil {
|
||||
operations[http.MethodOptions] = v
|
||||
}
|
||||
if v := pathItem.Patch; v != nil {
|
||||
operations[http.MethodPatch] = v
|
||||
}
|
||||
if v := pathItem.Post; v != nil {
|
||||
operations[http.MethodPost] = v
|
||||
}
|
||||
if v := pathItem.Put; v != nil {
|
||||
operations[http.MethodPut] = v
|
||||
}
|
||||
return operations
|
||||
}
|
||||
|
||||
func (pathItem *PathItem) GetOperation(method string) *Operation {
|
||||
switch method {
|
||||
case http.MethodDelete:
|
||||
return pathItem.Delete
|
||||
case http.MethodGet:
|
||||
return pathItem.Get
|
||||
case http.MethodHead:
|
||||
return pathItem.Head
|
||||
case http.MethodOptions:
|
||||
return pathItem.Options
|
||||
case http.MethodPatch:
|
||||
return pathItem.Patch
|
||||
case http.MethodPost:
|
||||
return pathItem.Post
|
||||
case http.MethodPut:
|
||||
return pathItem.Put
|
||||
default:
|
||||
panic(fmt.Errorf("unsupported HTTP method %q", method))
|
||||
}
|
||||
}
|
||||
|
||||
func (pathItem *PathItem) SetOperation(method string, operation *Operation) {
|
||||
switch method {
|
||||
case http.MethodDelete:
|
||||
pathItem.Delete = operation
|
||||
case http.MethodGet:
|
||||
pathItem.Get = operation
|
||||
case http.MethodHead:
|
||||
pathItem.Head = operation
|
||||
case http.MethodOptions:
|
||||
pathItem.Options = operation
|
||||
case http.MethodPatch:
|
||||
pathItem.Patch = operation
|
||||
case http.MethodPost:
|
||||
pathItem.Post = operation
|
||||
case http.MethodPut:
|
||||
pathItem.Put = operation
|
||||
default:
|
||||
panic(fmt.Errorf("unsupported HTTP method %q", method))
|
||||
}
|
||||
}
|
||||
|
||||
type Operation struct {
|
||||
openapi3.ExtensionProps
|
||||
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
ExternalDocs *openapi3.ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
|
||||
Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"`
|
||||
OperationID string `json:"operationId,omitempty" yaml:"operationId,omitempty"`
|
||||
Parameters Parameters `json:"parameters,omitempty" yaml:"parameters,omitempty"`
|
||||
Responses map[string]*Response `json:"responses" yaml:"responses"`
|
||||
Consumes []string `json:"consumes,omitempty" yaml:"consumes,omitempty"`
|
||||
Produces []string `json:"produces,omitempty" yaml:"produces,omitempty"`
|
||||
Security *SecurityRequirements `json:"security,omitempty" yaml:"security,omitempty"`
|
||||
}
|
||||
|
||||
func (operation *Operation) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(operation)
|
||||
}
|
||||
|
||||
func (operation *Operation) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, operation)
|
||||
}
|
||||
|
||||
type Parameters []*Parameter
|
||||
|
||||
var _ sort.Interface = Parameters{}
|
||||
|
||||
func (ps Parameters) Len() int { return len(ps) }
|
||||
func (ps Parameters) Swap(i, j int) { ps[i], ps[j] = ps[j], ps[i] }
|
||||
func (ps Parameters) Less(i, j int) bool {
|
||||
if ps[i].Name != ps[j].Name {
|
||||
return ps[i].Name < ps[j].Name
|
||||
}
|
||||
if ps[i].In != ps[j].In {
|
||||
return ps[i].In < ps[j].In
|
||||
}
|
||||
return ps[i].Ref < ps[j].Ref
|
||||
}
|
||||
|
||||
type Parameter struct {
|
||||
openapi3.ExtensionProps
|
||||
Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
|
||||
In string `json:"in,omitempty" yaml:"in,omitempty"`
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
CollectionFormat string `json:"collectionFormat,omitempty" yaml:"collectionFormat,omitempty"`
|
||||
Type string `json:"type,omitempty" yaml:"type,omitempty"`
|
||||
Format string `json:"format,omitempty" yaml:"format,omitempty"`
|
||||
Pattern string `json:"pattern,omitempty" yaml:"pattern,omitempty"`
|
||||
AllowEmptyValue bool `json:"allowEmptyValue,omitempty" yaml:"allowEmptyValue,omitempty"`
|
||||
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
|
||||
UniqueItems bool `json:"uniqueItems,omitempty" yaml:"uniqueItems,omitempty"`
|
||||
ExclusiveMin bool `json:"exclusiveMinimum,omitempty" yaml:"exclusiveMinimum,omitempty"`
|
||||
ExclusiveMax bool `json:"exclusiveMaximum,omitempty" yaml:"exclusiveMaximum,omitempty"`
|
||||
Schema *openapi3.SchemaRef `json:"schema,omitempty" yaml:"schema,omitempty"`
|
||||
Items *openapi3.SchemaRef `json:"items,omitempty" yaml:"items,omitempty"`
|
||||
Enum []interface{} `json:"enum,omitempty" yaml:"enum,omitempty"`
|
||||
MultipleOf *float64 `json:"multipleOf,omitempty" yaml:"multipleOf,omitempty"`
|
||||
Minimum *float64 `json:"minimum,omitempty" yaml:"minimum,omitempty"`
|
||||
Maximum *float64 `json:"maximum,omitempty" yaml:"maximum,omitempty"`
|
||||
MaxLength *uint64 `json:"maxLength,omitempty" yaml:"maxLength,omitempty"`
|
||||
MaxItems *uint64 `json:"maxItems,omitempty" yaml:"maxItems,omitempty"`
|
||||
MinLength uint64 `json:"minLength,omitempty" yaml:"minLength,omitempty"`
|
||||
MinItems uint64 `json:"minItems,omitempty" yaml:"minItems,omitempty"`
|
||||
Default interface{} `json:"default,omitempty" yaml:"default,omitempty"`
|
||||
}
|
||||
|
||||
func (parameter *Parameter) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(parameter)
|
||||
}
|
||||
|
||||
func (parameter *Parameter) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, parameter)
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
openapi3.ExtensionProps
|
||||
Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
Schema *openapi3.SchemaRef `json:"schema,omitempty" yaml:"schema,omitempty"`
|
||||
Headers map[string]*Header `json:"headers,omitempty" yaml:"headers,omitempty"`
|
||||
Examples map[string]interface{} `json:"examples,omitempty" yaml:"examples,omitempty"`
|
||||
}
|
||||
|
||||
func (response *Response) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(response)
|
||||
}
|
||||
|
||||
func (response *Response) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, response)
|
||||
}
|
||||
|
||||
type Header struct {
|
||||
openapi3.ExtensionProps
|
||||
Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
Type string `json:"type,omitempty" yaml:"type,omitempty"`
|
||||
}
|
||||
|
||||
func (header *Header) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(header)
|
||||
}
|
||||
|
||||
func (header *Header) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, header)
|
||||
}
|
||||
|
||||
type SecurityRequirements []map[string][]string
|
||||
|
||||
type SecurityScheme struct {
|
||||
openapi3.ExtensionProps
|
||||
Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
Type string `json:"type,omitempty" yaml:"type,omitempty"`
|
||||
In string `json:"in,omitempty" yaml:"in,omitempty"`
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
Flow string `json:"flow,omitempty" yaml:"flow,omitempty"`
|
||||
AuthorizationURL string `json:"authorizationUrl,omitempty" yaml:"authorizationUrl,omitempty"`
|
||||
TokenURL string `json:"tokenUrl,omitempty" yaml:"tokenUrl,omitempty"`
|
||||
Scopes map[string]string `json:"scopes,omitempty" yaml:"scopes,omitempty"`
|
||||
Tags openapi3.Tags `json:"tags,omitempty" yaml:"tags,omitempty"`
|
||||
}
|
||||
|
||||
func (securityScheme *SecurityScheme) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(securityScheme)
|
||||
}
|
||||
|
||||
func (securityScheme *SecurityScheme) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, securityScheme)
|
||||
}
|
||||
|
94
vendor/github.com/getkin/kin-openapi/openapi2/operation.go
generated
vendored
Normal file
94
vendor/github.com/getkin/kin-openapi/openapi2/operation.go
generated
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
package openapi2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/getkin/kin-openapi/openapi3"
|
||||
)
|
||||
|
||||
type Operation struct {
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
|
||||
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"`
|
||||
ExternalDocs *openapi3.ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
|
||||
Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"`
|
||||
OperationID string `json:"operationId,omitempty" yaml:"operationId,omitempty"`
|
||||
Parameters Parameters `json:"parameters,omitempty" yaml:"parameters,omitempty"`
|
||||
Responses map[string]*Response `json:"responses" yaml:"responses"`
|
||||
Consumes []string `json:"consumes,omitempty" yaml:"consumes,omitempty"`
|
||||
Produces []string `json:"produces,omitempty" yaml:"produces,omitempty"`
|
||||
Schemes []string `json:"schemes,omitempty" yaml:"schemes,omitempty"`
|
||||
Security *SecurityRequirements `json:"security,omitempty" yaml:"security,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of Operation.
|
||||
func (operation Operation) MarshalJSON() ([]byte, error) {
|
||||
m := make(map[string]any, 12+len(operation.Extensions))
|
||||
for k, v := range operation.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := operation.Summary; x != "" {
|
||||
m["summary"] = x
|
||||
}
|
||||
if x := operation.Description; x != "" {
|
||||
m["description"] = x
|
||||
}
|
||||
if x := operation.Deprecated; x {
|
||||
m["deprecated"] = x
|
||||
}
|
||||
if x := operation.ExternalDocs; x != nil {
|
||||
m["externalDocs"] = x
|
||||
}
|
||||
if x := operation.Tags; len(x) != 0 {
|
||||
m["tags"] = x
|
||||
}
|
||||
if x := operation.OperationID; x != "" {
|
||||
m["operationId"] = x
|
||||
}
|
||||
if x := operation.Parameters; len(x) != 0 {
|
||||
m["parameters"] = x
|
||||
}
|
||||
m["responses"] = operation.Responses
|
||||
if x := operation.Consumes; len(x) != 0 {
|
||||
m["consumes"] = x
|
||||
}
|
||||
if x := operation.Produces; len(x) != 0 {
|
||||
m["produces"] = x
|
||||
}
|
||||
if x := operation.Schemes; len(x) != 0 {
|
||||
m["schemes"] = x
|
||||
}
|
||||
if x := operation.Security; x != nil {
|
||||
m["security"] = x
|
||||
}
|
||||
return json.Marshal(m)
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Operation to a copy of data.
|
||||
func (operation *Operation) UnmarshalJSON(data []byte) error {
|
||||
type OperationBis Operation
|
||||
var x OperationBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, "summary")
|
||||
delete(x.Extensions, "description")
|
||||
delete(x.Extensions, "deprecated")
|
||||
delete(x.Extensions, "externalDocs")
|
||||
delete(x.Extensions, "tags")
|
||||
delete(x.Extensions, "operationId")
|
||||
delete(x.Extensions, "parameters")
|
||||
delete(x.Extensions, "responses")
|
||||
delete(x.Extensions, "consumes")
|
||||
delete(x.Extensions, "produces")
|
||||
delete(x.Extensions, "schemes")
|
||||
delete(x.Extensions, "security")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*operation = Operation(x)
|
||||
return nil
|
||||
}
|
180
vendor/github.com/getkin/kin-openapi/openapi2/parameter.go
generated
vendored
Normal file
180
vendor/github.com/getkin/kin-openapi/openapi2/parameter.go
generated
vendored
Normal file
@ -0,0 +1,180 @@
|
||||
package openapi2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"sort"
|
||||
|
||||
"github.com/getkin/kin-openapi/openapi3"
|
||||
)
|
||||
|
||||
type Parameters []*Parameter
|
||||
|
||||
var _ sort.Interface = Parameters{}
|
||||
|
||||
func (ps Parameters) Len() int { return len(ps) }
|
||||
func (ps Parameters) Swap(i, j int) { ps[i], ps[j] = ps[j], ps[i] }
|
||||
func (ps Parameters) Less(i, j int) bool {
|
||||
if ps[i].Name != ps[j].Name {
|
||||
return ps[i].Name < ps[j].Name
|
||||
}
|
||||
if ps[i].In != ps[j].In {
|
||||
return ps[i].In < ps[j].In
|
||||
}
|
||||
return ps[i].Ref < ps[j].Ref
|
||||
}
|
||||
|
||||
type Parameter struct {
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
|
||||
Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
|
||||
|
||||
In string `json:"in,omitempty" yaml:"in,omitempty"`
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
CollectionFormat string `json:"collectionFormat,omitempty" yaml:"collectionFormat,omitempty"`
|
||||
Type *openapi3.Types `json:"type,omitempty" yaml:"type,omitempty"`
|
||||
Format string `json:"format,omitempty" yaml:"format,omitempty"`
|
||||
Pattern string `json:"pattern,omitempty" yaml:"pattern,omitempty"`
|
||||
AllowEmptyValue bool `json:"allowEmptyValue,omitempty" yaml:"allowEmptyValue,omitempty"`
|
||||
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
|
||||
UniqueItems bool `json:"uniqueItems,omitempty" yaml:"uniqueItems,omitempty"`
|
||||
ExclusiveMin bool `json:"exclusiveMinimum,omitempty" yaml:"exclusiveMinimum,omitempty"`
|
||||
ExclusiveMax bool `json:"exclusiveMaximum,omitempty" yaml:"exclusiveMaximum,omitempty"`
|
||||
Schema *SchemaRef `json:"schema,omitempty" yaml:"schema,omitempty"`
|
||||
Items *SchemaRef `json:"items,omitempty" yaml:"items,omitempty"`
|
||||
Enum []any `json:"enum,omitempty" yaml:"enum,omitempty"`
|
||||
MultipleOf *float64 `json:"multipleOf,omitempty" yaml:"multipleOf,omitempty"`
|
||||
Minimum *float64 `json:"minimum,omitempty" yaml:"minimum,omitempty"`
|
||||
Maximum *float64 `json:"maximum,omitempty" yaml:"maximum,omitempty"`
|
||||
MaxLength *uint64 `json:"maxLength,omitempty" yaml:"maxLength,omitempty"`
|
||||
MaxItems *uint64 `json:"maxItems,omitempty" yaml:"maxItems,omitempty"`
|
||||
MinLength uint64 `json:"minLength,omitempty" yaml:"minLength,omitempty"`
|
||||
MinItems uint64 `json:"minItems,omitempty" yaml:"minItems,omitempty"`
|
||||
Default any `json:"default,omitempty" yaml:"default,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of Parameter.
|
||||
func (parameter Parameter) MarshalJSON() ([]byte, error) {
|
||||
if ref := parameter.Ref; ref != "" {
|
||||
return json.Marshal(openapi3.Ref{Ref: ref})
|
||||
}
|
||||
|
||||
m := make(map[string]any, 24+len(parameter.Extensions))
|
||||
for k, v := range parameter.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
|
||||
if x := parameter.In; x != "" {
|
||||
m["in"] = x
|
||||
}
|
||||
if x := parameter.Name; x != "" {
|
||||
m["name"] = x
|
||||
}
|
||||
if x := parameter.Description; x != "" {
|
||||
m["description"] = x
|
||||
}
|
||||
if x := parameter.CollectionFormat; x != "" {
|
||||
m["collectionFormat"] = x
|
||||
}
|
||||
if x := parameter.Type; x != nil {
|
||||
m["type"] = x
|
||||
}
|
||||
if x := parameter.Format; x != "" {
|
||||
m["format"] = x
|
||||
}
|
||||
if x := parameter.Pattern; x != "" {
|
||||
m["pattern"] = x
|
||||
}
|
||||
if x := parameter.AllowEmptyValue; x {
|
||||
m["allowEmptyValue"] = x
|
||||
}
|
||||
if x := parameter.Required; x {
|
||||
m["required"] = x
|
||||
}
|
||||
if x := parameter.UniqueItems; x {
|
||||
m["uniqueItems"] = x
|
||||
}
|
||||
if x := parameter.ExclusiveMin; x {
|
||||
m["exclusiveMinimum"] = x
|
||||
}
|
||||
if x := parameter.ExclusiveMax; x {
|
||||
m["exclusiveMaximum"] = x
|
||||
}
|
||||
if x := parameter.Schema; x != nil {
|
||||
m["schema"] = x
|
||||
}
|
||||
if x := parameter.Items; x != nil {
|
||||
m["items"] = x
|
||||
}
|
||||
if x := parameter.Enum; x != nil {
|
||||
m["enum"] = x
|
||||
}
|
||||
if x := parameter.MultipleOf; x != nil {
|
||||
m["multipleOf"] = x
|
||||
}
|
||||
if x := parameter.Minimum; x != nil {
|
||||
m["minimum"] = x
|
||||
}
|
||||
if x := parameter.Maximum; x != nil {
|
||||
m["maximum"] = x
|
||||
}
|
||||
if x := parameter.MaxLength; x != nil {
|
||||
m["maxLength"] = x
|
||||
}
|
||||
if x := parameter.MaxItems; x != nil {
|
||||
m["maxItems"] = x
|
||||
}
|
||||
if x := parameter.MinLength; x != 0 {
|
||||
m["minLength"] = x
|
||||
}
|
||||
if x := parameter.MinItems; x != 0 {
|
||||
m["minItems"] = x
|
||||
}
|
||||
if x := parameter.Default; x != nil {
|
||||
m["default"] = x
|
||||
}
|
||||
|
||||
return json.Marshal(m)
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Parameter to a copy of data.
|
||||
func (parameter *Parameter) UnmarshalJSON(data []byte) error {
|
||||
type ParameterBis Parameter
|
||||
var x ParameterBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, "$ref")
|
||||
|
||||
delete(x.Extensions, "in")
|
||||
delete(x.Extensions, "name")
|
||||
delete(x.Extensions, "description")
|
||||
delete(x.Extensions, "collectionFormat")
|
||||
delete(x.Extensions, "type")
|
||||
delete(x.Extensions, "format")
|
||||
delete(x.Extensions, "pattern")
|
||||
delete(x.Extensions, "allowEmptyValue")
|
||||
delete(x.Extensions, "required")
|
||||
delete(x.Extensions, "uniqueItems")
|
||||
delete(x.Extensions, "exclusiveMinimum")
|
||||
delete(x.Extensions, "exclusiveMaximum")
|
||||
delete(x.Extensions, "schema")
|
||||
delete(x.Extensions, "items")
|
||||
delete(x.Extensions, "enum")
|
||||
delete(x.Extensions, "multipleOf")
|
||||
delete(x.Extensions, "minimum")
|
||||
delete(x.Extensions, "maximum")
|
||||
delete(x.Extensions, "maxLength")
|
||||
delete(x.Extensions, "maxItems")
|
||||
delete(x.Extensions, "minLength")
|
||||
delete(x.Extensions, "minItems")
|
||||
delete(x.Extensions, "default")
|
||||
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
|
||||
*parameter = Parameter(x)
|
||||
return nil
|
||||
}
|
153
vendor/github.com/getkin/kin-openapi/openapi2/path_item.go
generated
vendored
Normal file
153
vendor/github.com/getkin/kin-openapi/openapi2/path_item.go
generated
vendored
Normal file
@ -0,0 +1,153 @@
|
||||
package openapi2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/getkin/kin-openapi/openapi3"
|
||||
)
|
||||
|
||||
type PathItem struct {
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
|
||||
Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
|
||||
|
||||
Delete *Operation `json:"delete,omitempty" yaml:"delete,omitempty"`
|
||||
Get *Operation `json:"get,omitempty" yaml:"get,omitempty"`
|
||||
Head *Operation `json:"head,omitempty" yaml:"head,omitempty"`
|
||||
Options *Operation `json:"options,omitempty" yaml:"options,omitempty"`
|
||||
Patch *Operation `json:"patch,omitempty" yaml:"patch,omitempty"`
|
||||
Post *Operation `json:"post,omitempty" yaml:"post,omitempty"`
|
||||
Put *Operation `json:"put,omitempty" yaml:"put,omitempty"`
|
||||
Parameters Parameters `json:"parameters,omitempty" yaml:"parameters,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of PathItem.
|
||||
func (pathItem PathItem) MarshalJSON() ([]byte, error) {
|
||||
if ref := pathItem.Ref; ref != "" {
|
||||
return json.Marshal(openapi3.Ref{Ref: ref})
|
||||
}
|
||||
|
||||
m := make(map[string]any, 8+len(pathItem.Extensions))
|
||||
for k, v := range pathItem.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := pathItem.Delete; x != nil {
|
||||
m["delete"] = x
|
||||
}
|
||||
if x := pathItem.Get; x != nil {
|
||||
m["get"] = x
|
||||
}
|
||||
if x := pathItem.Head; x != nil {
|
||||
m["head"] = x
|
||||
}
|
||||
if x := pathItem.Options; x != nil {
|
||||
m["options"] = x
|
||||
}
|
||||
if x := pathItem.Patch; x != nil {
|
||||
m["patch"] = x
|
||||
}
|
||||
if x := pathItem.Post; x != nil {
|
||||
m["post"] = x
|
||||
}
|
||||
if x := pathItem.Put; x != nil {
|
||||
m["put"] = x
|
||||
}
|
||||
if x := pathItem.Parameters; len(x) != 0 {
|
||||
m["parameters"] = x
|
||||
}
|
||||
return json.Marshal(m)
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets PathItem to a copy of data.
|
||||
func (pathItem *PathItem) UnmarshalJSON(data []byte) error {
|
||||
type PathItemBis PathItem
|
||||
var x PathItemBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, "$ref")
|
||||
delete(x.Extensions, "delete")
|
||||
delete(x.Extensions, "get")
|
||||
delete(x.Extensions, "head")
|
||||
delete(x.Extensions, "options")
|
||||
delete(x.Extensions, "patch")
|
||||
delete(x.Extensions, "post")
|
||||
delete(x.Extensions, "put")
|
||||
delete(x.Extensions, "parameters")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*pathItem = PathItem(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pathItem *PathItem) Operations() map[string]*Operation {
|
||||
operations := make(map[string]*Operation)
|
||||
if v := pathItem.Delete; v != nil {
|
||||
operations[http.MethodDelete] = v
|
||||
}
|
||||
if v := pathItem.Get; v != nil {
|
||||
operations[http.MethodGet] = v
|
||||
}
|
||||
if v := pathItem.Head; v != nil {
|
||||
operations[http.MethodHead] = v
|
||||
}
|
||||
if v := pathItem.Options; v != nil {
|
||||
operations[http.MethodOptions] = v
|
||||
}
|
||||
if v := pathItem.Patch; v != nil {
|
||||
operations[http.MethodPatch] = v
|
||||
}
|
||||
if v := pathItem.Post; v != nil {
|
||||
operations[http.MethodPost] = v
|
||||
}
|
||||
if v := pathItem.Put; v != nil {
|
||||
operations[http.MethodPut] = v
|
||||
}
|
||||
return operations
|
||||
}
|
||||
|
||||
func (pathItem *PathItem) GetOperation(method string) *Operation {
|
||||
switch method {
|
||||
case http.MethodDelete:
|
||||
return pathItem.Delete
|
||||
case http.MethodGet:
|
||||
return pathItem.Get
|
||||
case http.MethodHead:
|
||||
return pathItem.Head
|
||||
case http.MethodOptions:
|
||||
return pathItem.Options
|
||||
case http.MethodPatch:
|
||||
return pathItem.Patch
|
||||
case http.MethodPost:
|
||||
return pathItem.Post
|
||||
case http.MethodPut:
|
||||
return pathItem.Put
|
||||
default:
|
||||
panic(fmt.Errorf("unsupported HTTP method %q", method))
|
||||
}
|
||||
}
|
||||
|
||||
func (pathItem *PathItem) SetOperation(method string, operation *Operation) {
|
||||
switch method {
|
||||
case http.MethodDelete:
|
||||
pathItem.Delete = operation
|
||||
case http.MethodGet:
|
||||
pathItem.Get = operation
|
||||
case http.MethodHead:
|
||||
pathItem.Head = operation
|
||||
case http.MethodOptions:
|
||||
pathItem.Options = operation
|
||||
case http.MethodPatch:
|
||||
pathItem.Patch = operation
|
||||
case http.MethodPost:
|
||||
pathItem.Post = operation
|
||||
case http.MethodPut:
|
||||
pathItem.Put = operation
|
||||
default:
|
||||
panic(fmt.Errorf("unsupported HTTP method %q", method))
|
||||
}
|
||||
}
|
9
vendor/github.com/getkin/kin-openapi/openapi2/ref.go
generated
vendored
Normal file
9
vendor/github.com/getkin/kin-openapi/openapi2/ref.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
package openapi2
|
||||
|
||||
//go:generate go run refsgenerator.go
|
||||
|
||||
// Ref is specified by OpenAPI/Swagger 2.0 standard.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#reference-object
|
||||
type Ref struct {
|
||||
Ref string `json:"$ref" yaml:"$ref"`
|
||||
}
|
104
vendor/github.com/getkin/kin-openapi/openapi2/refs.go
generated
vendored
Normal file
104
vendor/github.com/getkin/kin-openapi/openapi2/refs.go
generated
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
package openapi2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/perimeterx/marshmallow"
|
||||
)
|
||||
|
||||
// SchemaRef represents either a Schema or a $ref to a Schema.
|
||||
// When serializing and both fields are set, Ref is preferred over Value.
|
||||
type SchemaRef struct {
|
||||
// Extensions only captures fields starting with 'x-' as no other fields
|
||||
// are allowed by the openapi spec.
|
||||
Extensions map[string]any
|
||||
|
||||
Ref string
|
||||
Value *Schema
|
||||
extra []string
|
||||
|
||||
refPath *url.URL
|
||||
}
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*SchemaRef)(nil)
|
||||
|
||||
func (x *SchemaRef) isEmpty() bool { return x == nil || x.Ref == "" && x.Value == nil }
|
||||
|
||||
// RefString returns the $ref value.
|
||||
func (x *SchemaRef) RefString() string { return x.Ref }
|
||||
|
||||
// CollectionName returns the JSON string used for a collection of these components.
|
||||
func (x *SchemaRef) CollectionName() string { return "schemas" }
|
||||
|
||||
// RefPath returns the path of the $ref relative to the root document.
|
||||
func (x *SchemaRef) RefPath() *url.URL { return copyURI(x.refPath) }
|
||||
|
||||
func (x *SchemaRef) setRefPath(u *url.URL) {
|
||||
// Once the refPath is set don't override. References can be loaded
|
||||
// multiple times not all with access to the correct path info.
|
||||
if x.refPath != nil {
|
||||
return
|
||||
}
|
||||
|
||||
x.refPath = copyURI(u)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of SchemaRef.
|
||||
func (x SchemaRef) MarshalYAML() (any, error) {
|
||||
if ref := x.Ref; ref != "" {
|
||||
return &Ref{Ref: ref}, nil
|
||||
}
|
||||
return x.Value.MarshalYAML()
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of SchemaRef.
|
||||
func (x SchemaRef) MarshalJSON() ([]byte, error) {
|
||||
y, err := x.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(y)
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets SchemaRef to a copy of data.
|
||||
func (x *SchemaRef) UnmarshalJSON(data []byte) error {
|
||||
var refOnly Ref
|
||||
if extra, err := marshmallow.Unmarshal(data, &refOnly, marshmallow.WithExcludeKnownFieldsFromMap(true)); err == nil && refOnly.Ref != "" {
|
||||
x.Ref = refOnly.Ref
|
||||
if len(extra) != 0 {
|
||||
x.extra = make([]string, 0, len(extra))
|
||||
for key := range extra {
|
||||
x.extra = append(x.extra, key)
|
||||
}
|
||||
sort.Strings(x.extra)
|
||||
for k := range extra {
|
||||
if !strings.HasPrefix(k, "x-") {
|
||||
delete(extra, k)
|
||||
}
|
||||
}
|
||||
if len(extra) != 0 {
|
||||
x.Extensions = extra
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal(data, &x.Value)
|
||||
}
|
||||
|
||||
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (x *SchemaRef) JSONLookup(token string) (any, error) {
|
||||
if token == "$ref" {
|
||||
return x.Ref, nil
|
||||
}
|
||||
|
||||
if v, ok := x.Extensions[token]; ok {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
ptr, _, err := jsonpointer.GetForToken(x.Value, token)
|
||||
return ptr, err
|
||||
}
|
63
vendor/github.com/getkin/kin-openapi/openapi2/response.go
generated
vendored
Normal file
63
vendor/github.com/getkin/kin-openapi/openapi2/response.go
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
package openapi2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/getkin/kin-openapi/openapi3"
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
|
||||
Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
|
||||
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
Schema *SchemaRef `json:"schema,omitempty" yaml:"schema,omitempty"`
|
||||
Headers map[string]*Header `json:"headers,omitempty" yaml:"headers,omitempty"`
|
||||
Examples map[string]any `json:"examples,omitempty" yaml:"examples,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of Response.
|
||||
func (response Response) MarshalJSON() ([]byte, error) {
|
||||
if ref := response.Ref; ref != "" {
|
||||
return json.Marshal(openapi3.Ref{Ref: ref})
|
||||
}
|
||||
|
||||
m := make(map[string]any, 4+len(response.Extensions))
|
||||
for k, v := range response.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := response.Description; x != "" {
|
||||
m["description"] = x
|
||||
}
|
||||
if x := response.Schema; x != nil {
|
||||
m["schema"] = x
|
||||
}
|
||||
if x := response.Headers; len(x) != 0 {
|
||||
m["headers"] = x
|
||||
}
|
||||
if x := response.Examples; len(x) != 0 {
|
||||
m["examples"] = x
|
||||
}
|
||||
return json.Marshal(m)
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Response to a copy of data.
|
||||
func (response *Response) UnmarshalJSON(data []byte) error {
|
||||
type ResponseBis Response
|
||||
var x ResponseBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, "$ref")
|
||||
delete(x.Extensions, "description")
|
||||
delete(x.Extensions, "schema")
|
||||
delete(x.Extensions, "headers")
|
||||
delete(x.Extensions, "examples")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*response = Response(x)
|
||||
return nil
|
||||
}
|
269
vendor/github.com/getkin/kin-openapi/openapi2/schema.go
generated
vendored
Normal file
269
vendor/github.com/getkin/kin-openapi/openapi2/schema.go
generated
vendored
Normal file
@ -0,0 +1,269 @@
|
||||
package openapi2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/getkin/kin-openapi/openapi3"
|
||||
)
|
||||
|
||||
type (
|
||||
Schemas map[string]*SchemaRef
|
||||
SchemaRefs []*SchemaRef
|
||||
)
|
||||
|
||||
// Schema is specified by OpenAPI/Swagger 2.0 standard.
|
||||
// See https://swagger.io/specification/v2/#schema-object
|
||||
type Schema struct {
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
|
||||
AllOf SchemaRefs `json:"allOf,omitempty" yaml:"allOf,omitempty"`
|
||||
Not *SchemaRef `json:"not,omitempty" yaml:"not,omitempty"`
|
||||
Type *openapi3.Types `json:"type,omitempty" yaml:"type,omitempty"`
|
||||
Title string `json:"title,omitempty" yaml:"title,omitempty"`
|
||||
Format string `json:"format,omitempty" yaml:"format,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
Enum []any `json:"enum,omitempty" yaml:"enum,omitempty"`
|
||||
Default any `json:"default,omitempty" yaml:"default,omitempty"`
|
||||
Example any `json:"example,omitempty" yaml:"example,omitempty"`
|
||||
ExternalDocs *openapi3.ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
|
||||
|
||||
// Array-related, here for struct compactness
|
||||
UniqueItems bool `json:"uniqueItems,omitempty" yaml:"uniqueItems,omitempty"`
|
||||
// Number-related, here for struct compactness
|
||||
ExclusiveMin bool `json:"exclusiveMinimum,omitempty" yaml:"exclusiveMinimum,omitempty"`
|
||||
ExclusiveMax bool `json:"exclusiveMaximum,omitempty" yaml:"exclusiveMaximum,omitempty"`
|
||||
// Properties
|
||||
ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"`
|
||||
WriteOnly bool `json:"writeOnly,omitempty" yaml:"writeOnly,omitempty"`
|
||||
AllowEmptyValue bool `json:"allowEmptyValue,omitempty" yaml:"allowEmptyValue,omitempty"`
|
||||
Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"`
|
||||
XML *openapi3.XML `json:"xml,omitempty" yaml:"xml,omitempty"`
|
||||
|
||||
// Number
|
||||
Min *float64 `json:"minimum,omitempty" yaml:"minimum,omitempty"`
|
||||
Max *float64 `json:"maximum,omitempty" yaml:"maximum,omitempty"`
|
||||
MultipleOf *float64 `json:"multipleOf,omitempty" yaml:"multipleOf,omitempty"`
|
||||
|
||||
// String
|
||||
MinLength uint64 `json:"minLength,omitempty" yaml:"minLength,omitempty"`
|
||||
MaxLength *uint64 `json:"maxLength,omitempty" yaml:"maxLength,omitempty"`
|
||||
Pattern string `json:"pattern,omitempty" yaml:"pattern,omitempty"`
|
||||
|
||||
// Array
|
||||
MinItems uint64 `json:"minItems,omitempty" yaml:"minItems,omitempty"`
|
||||
MaxItems *uint64 `json:"maxItems,omitempty" yaml:"maxItems,omitempty"`
|
||||
Items *SchemaRef `json:"items,omitempty" yaml:"items,omitempty"`
|
||||
|
||||
// Object
|
||||
Required []string `json:"required,omitempty" yaml:"required,omitempty"`
|
||||
Properties Schemas `json:"properties,omitempty" yaml:"properties,omitempty"`
|
||||
MinProps uint64 `json:"minProperties,omitempty" yaml:"minProperties,omitempty"`
|
||||
MaxProps *uint64 `json:"maxProperties,omitempty" yaml:"maxProperties,omitempty"`
|
||||
AdditionalProperties openapi3.AdditionalProperties `json:"additionalProperties,omitempty" yaml:"additionalProperties,omitempty"`
|
||||
Discriminator string `json:"discriminator,omitempty" yaml:"discriminator,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of Schema.
|
||||
func (schema Schema) MarshalJSON() ([]byte, error) {
|
||||
m, err := schema.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(m)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of Schema.
|
||||
func (schema Schema) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 36+len(schema.Extensions))
|
||||
for k, v := range schema.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
|
||||
if x := schema.AllOf; len(x) != 0 {
|
||||
m["allOf"] = x
|
||||
}
|
||||
if x := schema.Not; x != nil {
|
||||
m["not"] = x
|
||||
}
|
||||
if x := schema.Type; x != nil {
|
||||
m["type"] = x
|
||||
}
|
||||
if x := schema.Title; len(x) != 0 {
|
||||
m["title"] = x
|
||||
}
|
||||
if x := schema.Format; len(x) != 0 {
|
||||
m["format"] = x
|
||||
}
|
||||
if x := schema.Description; len(x) != 0 {
|
||||
m["description"] = x
|
||||
}
|
||||
if x := schema.Enum; len(x) != 0 {
|
||||
m["enum"] = x
|
||||
}
|
||||
if x := schema.Default; x != nil {
|
||||
m["default"] = x
|
||||
}
|
||||
if x := schema.Example; x != nil {
|
||||
m["example"] = x
|
||||
}
|
||||
if x := schema.ExternalDocs; x != nil {
|
||||
m["externalDocs"] = x
|
||||
}
|
||||
|
||||
// Array-related
|
||||
if x := schema.UniqueItems; x {
|
||||
m["uniqueItems"] = x
|
||||
}
|
||||
// Number-related
|
||||
if x := schema.ExclusiveMin; x {
|
||||
m["exclusiveMinimum"] = x
|
||||
}
|
||||
if x := schema.ExclusiveMax; x {
|
||||
m["exclusiveMaximum"] = x
|
||||
}
|
||||
if x := schema.ReadOnly; x {
|
||||
m["readOnly"] = x
|
||||
}
|
||||
if x := schema.WriteOnly; x {
|
||||
m["writeOnly"] = x
|
||||
}
|
||||
if x := schema.AllowEmptyValue; x {
|
||||
m["allowEmptyValue"] = x
|
||||
}
|
||||
if x := schema.Deprecated; x {
|
||||
m["deprecated"] = x
|
||||
}
|
||||
if x := schema.XML; x != nil {
|
||||
m["xml"] = x
|
||||
}
|
||||
|
||||
// Number
|
||||
if x := schema.Min; x != nil {
|
||||
m["minimum"] = x
|
||||
}
|
||||
if x := schema.Max; x != nil {
|
||||
m["maximum"] = x
|
||||
}
|
||||
if x := schema.MultipleOf; x != nil {
|
||||
m["multipleOf"] = x
|
||||
}
|
||||
|
||||
// String
|
||||
if x := schema.MinLength; x != 0 {
|
||||
m["minLength"] = x
|
||||
}
|
||||
if x := schema.MaxLength; x != nil {
|
||||
m["maxLength"] = x
|
||||
}
|
||||
if x := schema.Pattern; x != "" {
|
||||
m["pattern"] = x
|
||||
}
|
||||
|
||||
// Array
|
||||
if x := schema.MinItems; x != 0 {
|
||||
m["minItems"] = x
|
||||
}
|
||||
if x := schema.MaxItems; x != nil {
|
||||
m["maxItems"] = x
|
||||
}
|
||||
if x := schema.Items; x != nil {
|
||||
m["items"] = x
|
||||
}
|
||||
|
||||
// Object
|
||||
if x := schema.Required; len(x) != 0 {
|
||||
m["required"] = x
|
||||
}
|
||||
if x := schema.Properties; len(x) != 0 {
|
||||
m["properties"] = x
|
||||
}
|
||||
if x := schema.MinProps; x != 0 {
|
||||
m["minProperties"] = x
|
||||
}
|
||||
if x := schema.MaxProps; x != nil {
|
||||
m["maxProperties"] = x
|
||||
}
|
||||
if x := schema.AdditionalProperties; x.Has != nil || x.Schema != nil {
|
||||
m["additionalProperties"] = &x
|
||||
}
|
||||
if x := schema.Discriminator; x != "" {
|
||||
m["discriminator"] = x
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Schema to a copy of data.
|
||||
func (schema *Schema) UnmarshalJSON(data []byte) error {
|
||||
type SchemaBis Schema
|
||||
var x SchemaBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
|
||||
delete(x.Extensions, "oneOf")
|
||||
delete(x.Extensions, "anyOf")
|
||||
delete(x.Extensions, "allOf")
|
||||
delete(x.Extensions, "not")
|
||||
delete(x.Extensions, "type")
|
||||
delete(x.Extensions, "title")
|
||||
delete(x.Extensions, "format")
|
||||
delete(x.Extensions, "description")
|
||||
delete(x.Extensions, "enum")
|
||||
delete(x.Extensions, "default")
|
||||
delete(x.Extensions, "example")
|
||||
delete(x.Extensions, "externalDocs")
|
||||
|
||||
// Array-related
|
||||
delete(x.Extensions, "uniqueItems")
|
||||
// Number-related
|
||||
delete(x.Extensions, "exclusiveMinimum")
|
||||
delete(x.Extensions, "exclusiveMaximum")
|
||||
// Properties
|
||||
delete(x.Extensions, "nullable")
|
||||
delete(x.Extensions, "readOnly")
|
||||
delete(x.Extensions, "writeOnly")
|
||||
delete(x.Extensions, "allowEmptyValue")
|
||||
delete(x.Extensions, "deprecated")
|
||||
delete(x.Extensions, "xml")
|
||||
|
||||
// Number
|
||||
delete(x.Extensions, "minimum")
|
||||
delete(x.Extensions, "maximum")
|
||||
delete(x.Extensions, "multipleOf")
|
||||
|
||||
// String
|
||||
delete(x.Extensions, "minLength")
|
||||
delete(x.Extensions, "maxLength")
|
||||
delete(x.Extensions, "pattern")
|
||||
|
||||
// Array
|
||||
delete(x.Extensions, "minItems")
|
||||
delete(x.Extensions, "maxItems")
|
||||
delete(x.Extensions, "items")
|
||||
|
||||
// Object
|
||||
delete(x.Extensions, "required")
|
||||
delete(x.Extensions, "properties")
|
||||
delete(x.Extensions, "minProperties")
|
||||
delete(x.Extensions, "maxProperties")
|
||||
delete(x.Extensions, "additionalProperties")
|
||||
delete(x.Extensions, "discriminator")
|
||||
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
|
||||
*schema = Schema(x)
|
||||
|
||||
if schema.Format == "date" {
|
||||
// This is a fix for: https://github.com/getkin/kin-openapi/issues/697
|
||||
if eg, ok := schema.Example.(string); ok {
|
||||
schema.Example = strings.TrimSuffix(eg, "T00:00:00Z")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
90
vendor/github.com/getkin/kin-openapi/openapi2/security_scheme.go
generated
vendored
Normal file
90
vendor/github.com/getkin/kin-openapi/openapi2/security_scheme.go
generated
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
package openapi2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/getkin/kin-openapi/openapi3"
|
||||
)
|
||||
|
||||
type SecurityRequirements []map[string][]string
|
||||
|
||||
type SecurityScheme struct {
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
|
||||
Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
|
||||
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
Type string `json:"type,omitempty" yaml:"type,omitempty"`
|
||||
In string `json:"in,omitempty" yaml:"in,omitempty"`
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
Flow string `json:"flow,omitempty" yaml:"flow,omitempty"`
|
||||
AuthorizationURL string `json:"authorizationUrl,omitempty" yaml:"authorizationUrl,omitempty"`
|
||||
TokenURL string `json:"tokenUrl,omitempty" yaml:"tokenUrl,omitempty"`
|
||||
Scopes map[string]string `json:"scopes,omitempty" yaml:"scopes,omitempty"`
|
||||
Tags openapi3.Tags `json:"tags,omitempty" yaml:"tags,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of SecurityScheme.
|
||||
func (securityScheme SecurityScheme) MarshalJSON() ([]byte, error) {
|
||||
if ref := securityScheme.Ref; ref != "" {
|
||||
return json.Marshal(openapi3.Ref{Ref: ref})
|
||||
}
|
||||
|
||||
m := make(map[string]any, 10+len(securityScheme.Extensions))
|
||||
for k, v := range securityScheme.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := securityScheme.Description; x != "" {
|
||||
m["description"] = x
|
||||
}
|
||||
if x := securityScheme.Type; x != "" {
|
||||
m["type"] = x
|
||||
}
|
||||
if x := securityScheme.In; x != "" {
|
||||
m["in"] = x
|
||||
}
|
||||
if x := securityScheme.Name; x != "" {
|
||||
m["name"] = x
|
||||
}
|
||||
if x := securityScheme.Flow; x != "" {
|
||||
m["flow"] = x
|
||||
}
|
||||
if x := securityScheme.AuthorizationURL; x != "" {
|
||||
m["authorizationUrl"] = x
|
||||
}
|
||||
if x := securityScheme.TokenURL; x != "" {
|
||||
m["tokenUrl"] = x
|
||||
}
|
||||
if x := securityScheme.Scopes; len(x) != 0 {
|
||||
m["scopes"] = x
|
||||
}
|
||||
if x := securityScheme.Tags; len(x) != 0 {
|
||||
m["tags"] = x
|
||||
}
|
||||
return json.Marshal(m)
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets SecurityScheme to a copy of data.
|
||||
func (securityScheme *SecurityScheme) UnmarshalJSON(data []byte) error {
|
||||
type SecuritySchemeBis SecurityScheme
|
||||
var x SecuritySchemeBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, "$ref")
|
||||
delete(x.Extensions, "description")
|
||||
delete(x.Extensions, "type")
|
||||
delete(x.Extensions, "in")
|
||||
delete(x.Extensions, "name")
|
||||
delete(x.Extensions, "flow")
|
||||
delete(x.Extensions, "authorizationUrl")
|
||||
delete(x.Extensions, "tokenUrl")
|
||||
delete(x.Extensions, "scopes")
|
||||
delete(x.Extensions, "tags")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*securityScheme = SecurityScheme(x)
|
||||
return nil
|
||||
}
|
663
vendor/github.com/getkin/kin-openapi/openapi2conv/openapi2_conv.go
generated
vendored
663
vendor/github.com/getkin/kin-openapi/openapi2conv/openapi2_conv.go
generated
vendored
File diff suppressed because it is too large
Load Diff
67
vendor/github.com/getkin/kin-openapi/openapi3/callback.go
generated
vendored
67
vendor/github.com/getkin/kin-openapi/openapi3/callback.go
generated
vendored
@ -2,35 +2,60 @@ package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type Callbacks map[string]*CallbackRef
|
||||
// Callback is specified by OpenAPI/Swagger standard version 3.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#callback-object
|
||||
type Callback struct {
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*Callbacks)(nil)
|
||||
|
||||
func (c Callbacks) JSONLookup(token string) (interface{}, error) {
|
||||
ref, ok := c[token]
|
||||
if ref == nil || !ok {
|
||||
return nil, fmt.Errorf("object has no field %q", token)
|
||||
}
|
||||
|
||||
if ref.Ref != "" {
|
||||
return &Ref{Ref: ref.Ref}, nil
|
||||
}
|
||||
return ref.Value, nil
|
||||
m map[string]*PathItem
|
||||
}
|
||||
|
||||
// Callback is specified by OpenAPI/Swagger standard version 3.0.
|
||||
type Callback map[string]*PathItem
|
||||
// NewCallback builds a Callback object with path items in insertion order.
|
||||
func NewCallback(opts ...NewCallbackOption) *Callback {
|
||||
Callback := NewCallbackWithCapacity(len(opts))
|
||||
for _, opt := range opts {
|
||||
opt(Callback)
|
||||
}
|
||||
return Callback
|
||||
}
|
||||
|
||||
func (value Callback) Validate(ctx context.Context) error {
|
||||
for _, v := range value {
|
||||
// NewCallbackOption describes options to NewCallback func
|
||||
type NewCallbackOption func(*Callback)
|
||||
|
||||
// WithCallback adds Callback as an option to NewCallback
|
||||
func WithCallback(cb string, pathItem *PathItem) NewCallbackOption {
|
||||
return func(callback *Callback) {
|
||||
if p := pathItem; p != nil && cb != "" {
|
||||
callback.Set(cb, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate returns an error if Callback does not comply with the OpenAPI spec.
|
||||
func (callback *Callback) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
keys := make([]string, 0, callback.Len())
|
||||
for key := range callback.Map() {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, key := range keys {
|
||||
v := callback.Value(key)
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
return validateExtensions(ctx, callback.Extensions)
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Callbacks to a copy of data.
|
||||
func (callbacks *Callbacks) UnmarshalJSON(data []byte) (err error) {
|
||||
*callbacks, _, err = unmarshalStringMapP[CallbackRef](data)
|
||||
return
|
||||
}
|
||||
|
341
vendor/github.com/getkin/kin-openapi/openapi3/components.go
generated
vendored
341
vendor/github.com/getkin/kin-openapi/openapi3/components.go
generated
vendored
@ -2,20 +2,36 @@ package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"sort"
|
||||
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
)
|
||||
|
||||
// Components is specified by OpenAPI/Swagger standard version 3.0.
|
||||
type (
|
||||
Callbacks map[string]*CallbackRef
|
||||
Examples map[string]*ExampleRef
|
||||
Headers map[string]*HeaderRef
|
||||
Links map[string]*LinkRef
|
||||
ParametersMap map[string]*ParameterRef
|
||||
RequestBodies map[string]*RequestBodyRef
|
||||
ResponseBodies map[string]*ResponseRef
|
||||
Schemas map[string]*SchemaRef
|
||||
SecuritySchemes map[string]*SecuritySchemeRef
|
||||
)
|
||||
|
||||
// Components is specified by OpenAPI/Swagger standard version 3.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#components-object
|
||||
type Components struct {
|
||||
ExtensionProps
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
Schemas Schemas `json:"schemas,omitempty" yaml:"schemas,omitempty"`
|
||||
Parameters ParametersMap `json:"parameters,omitempty" yaml:"parameters,omitempty"`
|
||||
Headers Headers `json:"headers,omitempty" yaml:"headers,omitempty"`
|
||||
RequestBodies RequestBodies `json:"requestBodies,omitempty" yaml:"requestBodies,omitempty"`
|
||||
Responses Responses `json:"responses,omitempty" yaml:"responses,omitempty"`
|
||||
Responses ResponseBodies `json:"responses,omitempty" yaml:"responses,omitempty"`
|
||||
SecuritySchemes SecuritySchemes `json:"securitySchemes,omitempty" yaml:"securitySchemes,omitempty"`
|
||||
Examples Examples `json:"examples,omitempty" yaml:"examples,omitempty"`
|
||||
Links Links `json:"links,omitempty" yaml:"links,omitempty"`
|
||||
@ -26,82 +42,331 @@ func NewComponents() Components {
|
||||
return Components{}
|
||||
}
|
||||
|
||||
func (components *Components) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(components)
|
||||
// MarshalJSON returns the JSON encoding of Components.
|
||||
func (components Components) MarshalJSON() ([]byte, error) {
|
||||
x, err := components.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of Components.
|
||||
func (components Components) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 9+len(components.Extensions))
|
||||
for k, v := range components.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := components.Schemas; len(x) != 0 {
|
||||
m["schemas"] = x
|
||||
}
|
||||
if x := components.Parameters; len(x) != 0 {
|
||||
m["parameters"] = x
|
||||
}
|
||||
if x := components.Headers; len(x) != 0 {
|
||||
m["headers"] = x
|
||||
}
|
||||
if x := components.RequestBodies; len(x) != 0 {
|
||||
m["requestBodies"] = x
|
||||
}
|
||||
if x := components.Responses; len(x) != 0 {
|
||||
m["responses"] = x
|
||||
}
|
||||
if x := components.SecuritySchemes; len(x) != 0 {
|
||||
m["securitySchemes"] = x
|
||||
}
|
||||
if x := components.Examples; len(x) != 0 {
|
||||
m["examples"] = x
|
||||
}
|
||||
if x := components.Links; len(x) != 0 {
|
||||
m["links"] = x
|
||||
}
|
||||
if x := components.Callbacks; len(x) != 0 {
|
||||
m["callbacks"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Components to a copy of data.
|
||||
func (components *Components) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, components)
|
||||
type ComponentsBis Components
|
||||
var x ComponentsBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "schemas")
|
||||
delete(x.Extensions, "parameters")
|
||||
delete(x.Extensions, "headers")
|
||||
delete(x.Extensions, "requestBodies")
|
||||
delete(x.Extensions, "responses")
|
||||
delete(x.Extensions, "securitySchemes")
|
||||
delete(x.Extensions, "examples")
|
||||
delete(x.Extensions, "links")
|
||||
delete(x.Extensions, "callbacks")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*components = Components(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (components *Components) Validate(ctx context.Context) (err error) {
|
||||
for k, v := range components.Schemas {
|
||||
// Validate returns an error if Components does not comply with the OpenAPI spec.
|
||||
func (components *Components) Validate(ctx context.Context, opts ...ValidationOption) (err error) {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
schemas := make([]string, 0, len(components.Schemas))
|
||||
for name := range components.Schemas {
|
||||
schemas = append(schemas, name)
|
||||
}
|
||||
sort.Strings(schemas)
|
||||
for _, k := range schemas {
|
||||
v := components.Schemas[k]
|
||||
if err = ValidateIdentifier(k); err != nil {
|
||||
return
|
||||
return fmt.Errorf("schema %q: %w", k, err)
|
||||
}
|
||||
if err = v.Validate(ctx); err != nil {
|
||||
return
|
||||
return fmt.Errorf("schema %q: %w", k, err)
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range components.Parameters {
|
||||
parameters := make([]string, 0, len(components.Parameters))
|
||||
for name := range components.Parameters {
|
||||
parameters = append(parameters, name)
|
||||
}
|
||||
sort.Strings(parameters)
|
||||
for _, k := range parameters {
|
||||
v := components.Parameters[k]
|
||||
if err = ValidateIdentifier(k); err != nil {
|
||||
return
|
||||
return fmt.Errorf("parameter %q: %w", k, err)
|
||||
}
|
||||
if err = v.Validate(ctx); err != nil {
|
||||
return
|
||||
return fmt.Errorf("parameter %q: %w", k, err)
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range components.RequestBodies {
|
||||
requestBodies := make([]string, 0, len(components.RequestBodies))
|
||||
for name := range components.RequestBodies {
|
||||
requestBodies = append(requestBodies, name)
|
||||
}
|
||||
sort.Strings(requestBodies)
|
||||
for _, k := range requestBodies {
|
||||
v := components.RequestBodies[k]
|
||||
if err = ValidateIdentifier(k); err != nil {
|
||||
return
|
||||
return fmt.Errorf("request body %q: %w", k, err)
|
||||
}
|
||||
if err = v.Validate(ctx); err != nil {
|
||||
return
|
||||
return fmt.Errorf("request body %q: %w", k, err)
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range components.Responses {
|
||||
responses := make([]string, 0, len(components.Responses))
|
||||
for name := range components.Responses {
|
||||
responses = append(responses, name)
|
||||
}
|
||||
sort.Strings(responses)
|
||||
for _, k := range responses {
|
||||
if err = ValidateIdentifier(k); err != nil {
|
||||
return
|
||||
return fmt.Errorf("response %q: %w", k, err)
|
||||
}
|
||||
v := components.Responses[k]
|
||||
if err = v.Validate(ctx); err != nil {
|
||||
return
|
||||
return fmt.Errorf("response %q: %w", k, err)
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range components.Headers {
|
||||
headers := make([]string, 0, len(components.Headers))
|
||||
for name := range components.Headers {
|
||||
headers = append(headers, name)
|
||||
}
|
||||
sort.Strings(headers)
|
||||
for _, k := range headers {
|
||||
v := components.Headers[k]
|
||||
if err = ValidateIdentifier(k); err != nil {
|
||||
return
|
||||
return fmt.Errorf("header %q: %w", k, err)
|
||||
}
|
||||
if err = v.Validate(ctx); err != nil {
|
||||
return
|
||||
return fmt.Errorf("header %q: %w", k, err)
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range components.SecuritySchemes {
|
||||
securitySchemes := make([]string, 0, len(components.SecuritySchemes))
|
||||
for name := range components.SecuritySchemes {
|
||||
securitySchemes = append(securitySchemes, name)
|
||||
}
|
||||
sort.Strings(securitySchemes)
|
||||
for _, k := range securitySchemes {
|
||||
v := components.SecuritySchemes[k]
|
||||
if err = ValidateIdentifier(k); err != nil {
|
||||
return
|
||||
return fmt.Errorf("security scheme %q: %w", k, err)
|
||||
}
|
||||
if err = v.Validate(ctx); err != nil {
|
||||
return
|
||||
return fmt.Errorf("security scheme %q: %w", k, err)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
examples := make([]string, 0, len(components.Examples))
|
||||
for name := range components.Examples {
|
||||
examples = append(examples, name)
|
||||
}
|
||||
sort.Strings(examples)
|
||||
for _, k := range examples {
|
||||
v := components.Examples[k]
|
||||
if err = ValidateIdentifier(k); err != nil {
|
||||
return fmt.Errorf("example %q: %w", k, err)
|
||||
}
|
||||
if err = v.Validate(ctx); err != nil {
|
||||
return fmt.Errorf("example %q: %w", k, err)
|
||||
}
|
||||
}
|
||||
|
||||
links := make([]string, 0, len(components.Links))
|
||||
for name := range components.Links {
|
||||
links = append(links, name)
|
||||
}
|
||||
sort.Strings(links)
|
||||
for _, k := range links {
|
||||
v := components.Links[k]
|
||||
if err = ValidateIdentifier(k); err != nil {
|
||||
return fmt.Errorf("link %q: %w", k, err)
|
||||
}
|
||||
if err = v.Validate(ctx); err != nil {
|
||||
return fmt.Errorf("link %q: %w", k, err)
|
||||
}
|
||||
}
|
||||
|
||||
callbacks := make([]string, 0, len(components.Callbacks))
|
||||
for name := range components.Callbacks {
|
||||
callbacks = append(callbacks, name)
|
||||
}
|
||||
sort.Strings(callbacks)
|
||||
for _, k := range callbacks {
|
||||
v := components.Callbacks[k]
|
||||
if err = ValidateIdentifier(k); err != nil {
|
||||
return fmt.Errorf("callback %q: %w", k, err)
|
||||
}
|
||||
if err = v.Validate(ctx); err != nil {
|
||||
return fmt.Errorf("callback %q: %w", k, err)
|
||||
}
|
||||
}
|
||||
|
||||
return validateExtensions(ctx, components.Extensions)
|
||||
}
|
||||
|
||||
const identifierPattern = `^[a-zA-Z0-9._-]+$`
|
||||
var _ jsonpointer.JSONPointable = (*Schemas)(nil)
|
||||
|
||||
// IdentifierRegExp verifies whether Component object key matches 'identifierPattern' pattern, according to OapiAPI v3.x.0.
|
||||
// Hovever, to be able supporting legacy OpenAPI v2.x, there is a need to customize above pattern in orde not to fail
|
||||
// converted v2-v3 validation
|
||||
var IdentifierRegExp = regexp.MustCompile(identifierPattern)
|
||||
|
||||
func ValidateIdentifier(value string) error {
|
||||
if IdentifierRegExp.MatchString(value) {
|
||||
return nil
|
||||
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (m Schemas) JSONLookup(token string) (any, error) {
|
||||
if v, ok := m[token]; !ok || v == nil {
|
||||
return nil, fmt.Errorf("no schema %q", token)
|
||||
} else if ref := v.Ref; ref != "" {
|
||||
return &Ref{Ref: ref}, nil
|
||||
} else {
|
||||
return v.Value, nil
|
||||
}
|
||||
}
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*ParametersMap)(nil)
|
||||
|
||||
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (m ParametersMap) JSONLookup(token string) (any, error) {
|
||||
if v, ok := m[token]; !ok || v == nil {
|
||||
return nil, fmt.Errorf("no parameter %q", token)
|
||||
} else if ref := v.Ref; ref != "" {
|
||||
return &Ref{Ref: ref}, nil
|
||||
} else {
|
||||
return v.Value, nil
|
||||
}
|
||||
}
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*Headers)(nil)
|
||||
|
||||
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (m Headers) JSONLookup(token string) (any, error) {
|
||||
if v, ok := m[token]; !ok || v == nil {
|
||||
return nil, fmt.Errorf("no header %q", token)
|
||||
} else if ref := v.Ref; ref != "" {
|
||||
return &Ref{Ref: ref}, nil
|
||||
} else {
|
||||
return v.Value, nil
|
||||
}
|
||||
}
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*RequestBodyRef)(nil)
|
||||
|
||||
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (m RequestBodies) JSONLookup(token string) (any, error) {
|
||||
if v, ok := m[token]; !ok || v == nil {
|
||||
return nil, fmt.Errorf("no request body %q", token)
|
||||
} else if ref := v.Ref; ref != "" {
|
||||
return &Ref{Ref: ref}, nil
|
||||
} else {
|
||||
return v.Value, nil
|
||||
}
|
||||
}
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*ResponseRef)(nil)
|
||||
|
||||
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (m ResponseBodies) JSONLookup(token string) (any, error) {
|
||||
if v, ok := m[token]; !ok || v == nil {
|
||||
return nil, fmt.Errorf("no response body %q", token)
|
||||
} else if ref := v.Ref; ref != "" {
|
||||
return &Ref{Ref: ref}, nil
|
||||
} else {
|
||||
return v.Value, nil
|
||||
}
|
||||
}
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*SecuritySchemes)(nil)
|
||||
|
||||
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (m SecuritySchemes) JSONLookup(token string) (any, error) {
|
||||
if v, ok := m[token]; !ok || v == nil {
|
||||
return nil, fmt.Errorf("no security scheme body %q", token)
|
||||
} else if ref := v.Ref; ref != "" {
|
||||
return &Ref{Ref: ref}, nil
|
||||
} else {
|
||||
return v.Value, nil
|
||||
}
|
||||
}
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*Examples)(nil)
|
||||
|
||||
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (m Examples) JSONLookup(token string) (any, error) {
|
||||
if v, ok := m[token]; !ok || v == nil {
|
||||
return nil, fmt.Errorf("no example body %q", token)
|
||||
} else if ref := v.Ref; ref != "" {
|
||||
return &Ref{Ref: ref}, nil
|
||||
} else {
|
||||
return v.Value, nil
|
||||
}
|
||||
}
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*Links)(nil)
|
||||
|
||||
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (m Links) JSONLookup(token string) (any, error) {
|
||||
if v, ok := m[token]; !ok || v == nil {
|
||||
return nil, fmt.Errorf("no link body %q", token)
|
||||
} else if ref := v.Ref; ref != "" {
|
||||
return &Ref{Ref: ref}, nil
|
||||
} else {
|
||||
return v.Value, nil
|
||||
}
|
||||
}
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*Callbacks)(nil)
|
||||
|
||||
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (m Callbacks) JSONLookup(token string) (any, error) {
|
||||
if v, ok := m[token]; !ok || v == nil {
|
||||
return nil, fmt.Errorf("no callback body %q", token)
|
||||
} else if ref := v.Ref; ref != "" {
|
||||
return &Ref{Ref: ref}, nil
|
||||
} else {
|
||||
return v.Value, nil
|
||||
}
|
||||
return fmt.Errorf("identifier %q is not supported by OpenAPIv3 standard (regexp: %q)", value, identifierPattern)
|
||||
}
|
||||
|
71
vendor/github.com/getkin/kin-openapi/openapi3/contact.go
generated
vendored
Normal file
71
vendor/github.com/getkin/kin-openapi/openapi3/contact.go
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// Contact is specified by OpenAPI/Swagger standard version 3.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#contact-object
|
||||
type Contact struct {
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
URL string `json:"url,omitempty" yaml:"url,omitempty"`
|
||||
Email string `json:"email,omitempty" yaml:"email,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of Contact.
|
||||
func (contact Contact) MarshalJSON() ([]byte, error) {
|
||||
x, err := contact.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of Contact.
|
||||
func (contact Contact) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 3+len(contact.Extensions))
|
||||
for k, v := range contact.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := contact.Name; x != "" {
|
||||
m["name"] = x
|
||||
}
|
||||
if x := contact.URL; x != "" {
|
||||
m["url"] = x
|
||||
}
|
||||
if x := contact.Email; x != "" {
|
||||
m["email"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Contact to a copy of data.
|
||||
func (contact *Contact) UnmarshalJSON(data []byte) error {
|
||||
type ContactBis Contact
|
||||
var x ContactBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "name")
|
||||
delete(x.Extensions, "url")
|
||||
delete(x.Extensions, "email")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*contact = Contact(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate returns an error if Contact does not comply with the OpenAPI spec.
|
||||
func (contact *Contact) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
return validateExtensions(ctx, contact.Extensions)
|
||||
}
|
23
vendor/github.com/getkin/kin-openapi/openapi3/content.go
generated
vendored
23
vendor/github.com/getkin/kin-openapi/openapi3/content.go
generated
vendored
@ -2,6 +2,7 @@ package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -9,7 +10,7 @@ import (
|
||||
type Content map[string]*MediaType
|
||||
|
||||
func NewContent() Content {
|
||||
return make(map[string]*MediaType, 4)
|
||||
return make(map[string]*MediaType)
|
||||
}
|
||||
|
||||
func NewContentWithSchema(schema *Schema, consumes []string) Content {
|
||||
@ -104,12 +105,26 @@ func (content Content) Get(mime string) *MediaType {
|
||||
return content["*/*"]
|
||||
}
|
||||
|
||||
func (value Content) Validate(ctx context.Context) error {
|
||||
for _, v := range value {
|
||||
// Validate MediaType
|
||||
// Validate returns an error if Content does not comply with the OpenAPI spec.
|
||||
func (content Content) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
keys := make([]string, 0, len(content))
|
||||
for key := range content {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
v := content[k]
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Content to a copy of data.
|
||||
func (content *Content) UnmarshalJSON(data []byte) (err error) {
|
||||
*content, _, err = unmarshalStringMapP[MediaType](data)
|
||||
return
|
||||
}
|
||||
|
60
vendor/github.com/getkin/kin-openapi/openapi3/discriminator.go
generated
vendored
60
vendor/github.com/getkin/kin-openapi/openapi3/discriminator.go
generated
vendored
@ -2,25 +2,63 @@ package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// Discriminator is specified by OpenAPI/Swagger standard version 3.0.
|
||||
// Discriminator is specified by OpenAPI/Swagger standard version 3.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#discriminator-object
|
||||
type Discriminator struct {
|
||||
ExtensionProps
|
||||
PropertyName string `json:"propertyName" yaml:"propertyName"`
|
||||
Mapping map[string]string `json:"mapping,omitempty" yaml:"mapping,omitempty"`
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
PropertyName string `json:"propertyName" yaml:"propertyName"` // required
|
||||
Mapping StringMap `json:"mapping,omitempty" yaml:"mapping,omitempty"`
|
||||
}
|
||||
|
||||
func (value *Discriminator) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(value)
|
||||
// MarshalJSON returns the JSON encoding of Discriminator.
|
||||
func (discriminator Discriminator) MarshalJSON() ([]byte, error) {
|
||||
x, err := discriminator.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
func (value *Discriminator) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, value)
|
||||
// MarshalYAML returns the YAML encoding of Discriminator.
|
||||
func (discriminator Discriminator) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 2+len(discriminator.Extensions))
|
||||
for k, v := range discriminator.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
m["propertyName"] = discriminator.PropertyName
|
||||
if x := discriminator.Mapping; len(x) != 0 {
|
||||
m["mapping"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (value *Discriminator) Validate(ctx context.Context) error {
|
||||
// UnmarshalJSON sets Discriminator to a copy of data.
|
||||
func (discriminator *Discriminator) UnmarshalJSON(data []byte) error {
|
||||
type DiscriminatorBis Discriminator
|
||||
var x DiscriminatorBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "propertyName")
|
||||
delete(x.Extensions, "mapping")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*discriminator = Discriminator(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate returns an error if Discriminator does not comply with the OpenAPI spec.
|
||||
func (discriminator *Discriminator) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
return validateExtensions(ctx, discriminator.Extensions)
|
||||
}
|
||||
|
2
vendor/github.com/getkin/kin-openapi/openapi3/doc.go
generated
vendored
2
vendor/github.com/getkin/kin-openapi/openapi3/doc.go
generated
vendored
@ -1,4 +1,4 @@
|
||||
// Package openapi3 parses and writes OpenAPI 3 specification documents.
|
||||
//
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md
|
||||
package openapi3
|
||||
|
82
vendor/github.com/getkin/kin-openapi/openapi3/encoding.go
generated
vendored
82
vendor/github.com/getkin/kin-openapi/openapi3/encoding.go
generated
vendored
@ -2,14 +2,16 @@ package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Encoding is specified by OpenAPI/Swagger 3.0 standard.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#encoding-object
|
||||
type Encoding struct {
|
||||
ExtensionProps
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
ContentType string `json:"contentType,omitempty" yaml:"contentType,omitempty"`
|
||||
Headers Headers `json:"headers,omitempty" yaml:"headers,omitempty"`
|
||||
@ -38,12 +40,59 @@ func (encoding *Encoding) WithHeaderRef(name string, ref *HeaderRef) *Encoding {
|
||||
return encoding
|
||||
}
|
||||
|
||||
func (encoding *Encoding) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(encoding)
|
||||
// MarshalJSON returns the JSON encoding of Encoding.
|
||||
func (encoding Encoding) MarshalJSON() ([]byte, error) {
|
||||
x, err := encoding.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of Encoding.
|
||||
func (encoding Encoding) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 5+len(encoding.Extensions))
|
||||
for k, v := range encoding.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := encoding.ContentType; x != "" {
|
||||
m["contentType"] = x
|
||||
}
|
||||
if x := encoding.Headers; len(x) != 0 {
|
||||
m["headers"] = x
|
||||
}
|
||||
if x := encoding.Style; x != "" {
|
||||
m["style"] = x
|
||||
}
|
||||
if x := encoding.Explode; x != nil {
|
||||
m["explode"] = x
|
||||
}
|
||||
if x := encoding.AllowReserved; x {
|
||||
m["allowReserved"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Encoding to a copy of data.
|
||||
func (encoding *Encoding) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, encoding)
|
||||
type EncodingBis Encoding
|
||||
var x EncodingBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "contentType")
|
||||
delete(x.Extensions, "headers")
|
||||
delete(x.Extensions, "style")
|
||||
delete(x.Extensions, "explode")
|
||||
delete(x.Extensions, "allowReserved")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*encoding = Encoding(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SerializationMethod returns a serialization method of request body.
|
||||
@ -61,11 +110,21 @@ func (encoding *Encoding) SerializationMethod() *SerializationMethod {
|
||||
return sm
|
||||
}
|
||||
|
||||
func (value *Encoding) Validate(ctx context.Context) error {
|
||||
if value == nil {
|
||||
// Validate returns an error if Encoding does not comply with the OpenAPI spec.
|
||||
func (encoding *Encoding) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if encoding == nil {
|
||||
return nil
|
||||
}
|
||||
for k, v := range value.Headers {
|
||||
|
||||
headers := make([]string, 0, len(encoding.Headers))
|
||||
for k := range encoding.Headers {
|
||||
headers = append(headers, k)
|
||||
}
|
||||
sort.Strings(headers)
|
||||
for _, k := range headers {
|
||||
v := encoding.Headers[k]
|
||||
if err := ValidateIdentifier(k); err != nil {
|
||||
return nil
|
||||
}
|
||||
@ -75,7 +134,7 @@ func (value *Encoding) Validate(ctx context.Context) error {
|
||||
}
|
||||
|
||||
// Validate a media types's serialization method.
|
||||
sm := value.SerializationMethod()
|
||||
sm := encoding.SerializationMethod()
|
||||
switch {
|
||||
case sm.Style == SerializationForm && sm.Explode,
|
||||
sm.Style == SerializationForm && !sm.Explode,
|
||||
@ -84,10 +143,9 @@ func (value *Encoding) Validate(ctx context.Context) error {
|
||||
sm.Style == SerializationPipeDelimited && sm.Explode,
|
||||
sm.Style == SerializationPipeDelimited && !sm.Explode,
|
||||
sm.Style == SerializationDeepObject && sm.Explode:
|
||||
// it is a valid
|
||||
default:
|
||||
return fmt.Errorf("serialization method with style=%q and explode=%v is not supported by media type", sm.Style, sm.Explode)
|
||||
}
|
||||
|
||||
return nil
|
||||
return validateExtensions(ctx, encoding.Extensions)
|
||||
}
|
||||
|
28
vendor/github.com/getkin/kin-openapi/openapi3/errors.go
generated
vendored
28
vendor/github.com/getkin/kin-openapi/openapi3/errors.go
generated
vendored
@ -10,16 +10,22 @@ import (
|
||||
type MultiError []error
|
||||
|
||||
func (me MultiError) Error() string {
|
||||
return spliceErr(" | ", me)
|
||||
}
|
||||
|
||||
func spliceErr(sep string, errs []error) string {
|
||||
buff := &bytes.Buffer{}
|
||||
for _, e := range me {
|
||||
for i, e := range errs {
|
||||
buff.WriteString(e.Error())
|
||||
buff.WriteString(" | ")
|
||||
if i != len(errs)-1 {
|
||||
buff.WriteString(sep)
|
||||
}
|
||||
}
|
||||
return buff.String()
|
||||
}
|
||||
|
||||
//Is allows you to determine if a generic error is in fact a MultiError using `errors.Is()`
|
||||
//It will also return true if any of the contained errors match target
|
||||
// Is allows you to determine if a generic error is in fact a MultiError using `errors.Is()`
|
||||
// It will also return true if any of the contained errors match target
|
||||
func (me MultiError) Is(target error) bool {
|
||||
if _, ok := target.(MultiError); ok {
|
||||
return true
|
||||
@ -32,8 +38,8 @@ func (me MultiError) Is(target error) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
//As allows you to use `errors.As()` to set target to the first error within the multi error that matches the target type
|
||||
func (me MultiError) As(target interface{}) bool {
|
||||
// As allows you to use `errors.As()` to set target to the first error within the multi error that matches the target type
|
||||
func (me MultiError) As(target any) bool {
|
||||
for _, e := range me {
|
||||
if errors.As(e, target) {
|
||||
return true
|
||||
@ -41,3 +47,13 @@ func (me MultiError) As(target interface{}) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type multiErrorForOneOf MultiError
|
||||
|
||||
func (meo multiErrorForOneOf) Error() string {
|
||||
return spliceErr(" Or ", meo)
|
||||
}
|
||||
|
||||
func (meo multiErrorForOneOf) Unwrap() error {
|
||||
return MultiError(meo)
|
||||
}
|
||||
|
93
vendor/github.com/getkin/kin-openapi/openapi3/example.go
generated
vendored
Normal file
93
vendor/github.com/getkin/kin-openapi/openapi3/example.go
generated
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// Example is specified by OpenAPI/Swagger 3.0 standard.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#example-object
|
||||
type Example struct {
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
Value any `json:"value,omitempty" yaml:"value,omitempty"`
|
||||
ExternalValue string `json:"externalValue,omitempty" yaml:"externalValue,omitempty"`
|
||||
}
|
||||
|
||||
func NewExample(value any) *Example {
|
||||
return &Example{Value: value}
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of Example.
|
||||
func (example Example) MarshalJSON() ([]byte, error) {
|
||||
x, err := example.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of Example.
|
||||
func (example Example) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 4+len(example.Extensions))
|
||||
for k, v := range example.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := example.Summary; x != "" {
|
||||
m["summary"] = x
|
||||
}
|
||||
if x := example.Description; x != "" {
|
||||
m["description"] = x
|
||||
}
|
||||
if x := example.Value; x != nil {
|
||||
m["value"] = x
|
||||
}
|
||||
if x := example.ExternalValue; x != "" {
|
||||
m["externalValue"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Example to a copy of data.
|
||||
func (example *Example) UnmarshalJSON(data []byte) error {
|
||||
type ExampleBis Example
|
||||
var x ExampleBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "summary")
|
||||
delete(x.Extensions, "description")
|
||||
delete(x.Extensions, "value")
|
||||
delete(x.Extensions, "externalValue")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*example = Example(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate returns an error if Example does not comply with the OpenAPI spec.
|
||||
func (example *Example) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if example.Value != nil && example.ExternalValue != "" {
|
||||
return errors.New("value and externalValue are mutually exclusive")
|
||||
}
|
||||
if example.Value == nil && example.ExternalValue == "" {
|
||||
return errors.New("no value or externalValue field")
|
||||
}
|
||||
|
||||
return validateExtensions(ctx, example.Extensions)
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Examples to a copy of data.
|
||||
func (examples *Examples) UnmarshalJSON(data []byte) (err error) {
|
||||
*examples, _, err = unmarshalStringMapP[ExampleRef](data)
|
||||
return
|
||||
}
|
16
vendor/github.com/getkin/kin-openapi/openapi3/example_validation.go
generated
vendored
Normal file
16
vendor/github.com/getkin/kin-openapi/openapi3/example_validation.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
package openapi3
|
||||
|
||||
import "context"
|
||||
|
||||
func validateExampleValue(ctx context.Context, input any, schema *Schema) error {
|
||||
opts := make([]SchemaValidationOption, 0, 2)
|
||||
|
||||
if vo := getValidationOptions(ctx); vo.examplesValidationAsReq {
|
||||
opts = append(opts, VisitAsRequest())
|
||||
} else if vo.examplesValidationAsRes {
|
||||
opts = append(opts, VisitAsResponse())
|
||||
}
|
||||
opts = append(opts, MultiErrors())
|
||||
|
||||
return schema.VisitJSON(input, opts...)
|
||||
}
|
53
vendor/github.com/getkin/kin-openapi/openapi3/examples.go
generated
vendored
53
vendor/github.com/getkin/kin-openapi/openapi3/examples.go
generated
vendored
@ -1,53 +0,0 @@
|
||||
package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
)
|
||||
|
||||
type Examples map[string]*ExampleRef
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*Examples)(nil)
|
||||
|
||||
func (e Examples) JSONLookup(token string) (interface{}, error) {
|
||||
ref, ok := e[token]
|
||||
if ref == nil || !ok {
|
||||
return nil, fmt.Errorf("object has no field %q", token)
|
||||
}
|
||||
|
||||
if ref.Ref != "" {
|
||||
return &Ref{Ref: ref.Ref}, nil
|
||||
}
|
||||
return ref.Value, nil
|
||||
}
|
||||
|
||||
// Example is specified by OpenAPI/Swagger 3.0 standard.
|
||||
type Example struct {
|
||||
ExtensionProps
|
||||
|
||||
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
Value interface{} `json:"value,omitempty" yaml:"value,omitempty"`
|
||||
ExternalValue string `json:"externalValue,omitempty" yaml:"externalValue,omitempty"`
|
||||
}
|
||||
|
||||
func NewExample(value interface{}) *Example {
|
||||
return &Example{
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func (example *Example) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(example)
|
||||
}
|
||||
|
||||
func (example *Example) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, example)
|
||||
}
|
||||
|
||||
func (value *Example) Validate(ctx context.Context) error {
|
||||
return nil // TODO
|
||||
}
|
46
vendor/github.com/getkin/kin-openapi/openapi3/extension.go
generated
vendored
46
vendor/github.com/getkin/kin-openapi/openapi3/extension.go
generated
vendored
@ -1,38 +1,32 @@
|
||||
package openapi3
|
||||
|
||||
import (
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ExtensionProps provides support for OpenAPI extensions.
|
||||
// It reads/writes all properties that begin with "x-".
|
||||
type ExtensionProps struct {
|
||||
Extensions map[string]interface{} `json:"-" yaml:"-"`
|
||||
}
|
||||
func validateExtensions(ctx context.Context, extensions map[string]any) error { // FIXME: newtype + Validate(...)
|
||||
allowed := getValidationOptions(ctx).extraSiblingFieldsAllowed
|
||||
|
||||
// Assert that the type implements the interface
|
||||
var _ jsoninfo.StrictStruct = &ExtensionProps{}
|
||||
|
||||
// EncodeWith will be invoked by package "jsoninfo"
|
||||
func (props *ExtensionProps) EncodeWith(encoder *jsoninfo.ObjectEncoder, value interface{}) error {
|
||||
for k, v := range props.Extensions {
|
||||
if err := encoder.EncodeExtension(k, v); err != nil {
|
||||
return err
|
||||
var unknowns []string
|
||||
for k := range extensions {
|
||||
if strings.HasPrefix(k, "x-") {
|
||||
continue
|
||||
}
|
||||
if allowed != nil {
|
||||
if _, ok := allowed[k]; ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
unknowns = append(unknowns, k)
|
||||
}
|
||||
return encoder.EncodeStructFieldsAndExtensions(value)
|
||||
}
|
||||
|
||||
// DecodeWith will be invoked by package "jsoninfo"
|
||||
func (props *ExtensionProps) DecodeWith(decoder *jsoninfo.ObjectDecoder, value interface{}) error {
|
||||
if err := decoder.DecodeStructFieldsAndExtensions(value); err != nil {
|
||||
return err
|
||||
if len(unknowns) != 0 {
|
||||
sort.Strings(unknowns)
|
||||
return fmt.Errorf("extra sibling fields: %+v", unknowns)
|
||||
}
|
||||
source := decoder.DecodeExtensionMap()
|
||||
result := make(map[string]interface{}, len(source))
|
||||
for k, v := range source {
|
||||
result[k] = v
|
||||
}
|
||||
props.Extensions = result
|
||||
|
||||
return nil
|
||||
}
|
||||
|
70
vendor/github.com/getkin/kin-openapi/openapi3/external_docs.go
generated
vendored
70
vendor/github.com/getkin/kin-openapi/openapi3/external_docs.go
generated
vendored
@ -1,21 +1,75 @@
|
||||
package openapi3
|
||||
|
||||
import (
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// ExternalDocs is specified by OpenAPI/Swagger standard version 3.0.
|
||||
// ExternalDocs is specified by OpenAPI/Swagger standard version 3.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#external-documentation-object
|
||||
type ExternalDocs struct {
|
||||
ExtensionProps
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
Description string `json:"description,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
URL string `json:"url,omitempty" yaml:"url,omitempty"`
|
||||
}
|
||||
|
||||
func (e *ExternalDocs) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(e)
|
||||
// MarshalJSON returns the JSON encoding of ExternalDocs.
|
||||
func (e ExternalDocs) MarshalJSON() ([]byte, error) {
|
||||
x, err := e.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of ExternalDocs.
|
||||
func (e ExternalDocs) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 2+len(e.Extensions))
|
||||
for k, v := range e.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := e.Description; x != "" {
|
||||
m["description"] = x
|
||||
}
|
||||
if x := e.URL; x != "" {
|
||||
m["url"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets ExternalDocs to a copy of data.
|
||||
func (e *ExternalDocs) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, e)
|
||||
type ExternalDocsBis ExternalDocs
|
||||
var x ExternalDocsBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "description")
|
||||
delete(x.Extensions, "url")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*e = ExternalDocs(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate returns an error if ExternalDocs does not comply with the OpenAPI spec.
|
||||
func (e *ExternalDocs) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if e.URL == "" {
|
||||
return errors.New("url is required")
|
||||
}
|
||||
if _, err := url.Parse(e.URL); err != nil {
|
||||
return fmt.Errorf("url is incorrect: %w", err)
|
||||
}
|
||||
|
||||
return validateExtensions(ctx, e.Extensions)
|
||||
}
|
||||
|
120
vendor/github.com/getkin/kin-openapi/openapi3/header.go
generated
vendored
120
vendor/github.com/getkin/kin-openapi/openapi3/header.go
generated
vendored
@ -5,61 +5,63 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
)
|
||||
|
||||
type Headers map[string]*HeaderRef
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*Headers)(nil)
|
||||
|
||||
func (h Headers) JSONLookup(token string) (interface{}, error) {
|
||||
ref, ok := h[token]
|
||||
if ref == nil || !ok {
|
||||
return nil, fmt.Errorf("object has no field %q", token)
|
||||
}
|
||||
|
||||
if ref.Ref != "" {
|
||||
return &Ref{Ref: ref.Ref}, nil
|
||||
}
|
||||
return ref.Value, nil
|
||||
}
|
||||
|
||||
// Header is specified by OpenAPI/Swagger 3.0 standard.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#headerObject
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#header-object
|
||||
type Header struct {
|
||||
Parameter
|
||||
}
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*Header)(nil)
|
||||
|
||||
func (value *Header) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, value)
|
||||
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (header Header) JSONLookup(token string) (any, error) {
|
||||
return header.Parameter.JSONLookup(token)
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of Header.
|
||||
func (header Header) MarshalJSON() ([]byte, error) {
|
||||
return header.Parameter.MarshalJSON()
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Header to a copy of data.
|
||||
func (header *Header) UnmarshalJSON(data []byte) error {
|
||||
return header.Parameter.UnmarshalJSON(data)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the JSON encoding of Header.
|
||||
func (header Header) MarshalYAML() (any, error) {
|
||||
return header.Parameter, nil
|
||||
}
|
||||
|
||||
// SerializationMethod returns a header's serialization method.
|
||||
func (value *Header) SerializationMethod() (*SerializationMethod, error) {
|
||||
style := value.Style
|
||||
func (header *Header) SerializationMethod() (*SerializationMethod, error) {
|
||||
style := header.Style
|
||||
if style == "" {
|
||||
style = SerializationSimple
|
||||
}
|
||||
explode := false
|
||||
if value.Explode != nil {
|
||||
explode = *value.Explode
|
||||
if header.Explode != nil {
|
||||
explode = *header.Explode
|
||||
}
|
||||
return &SerializationMethod{Style: style, Explode: explode}, nil
|
||||
}
|
||||
|
||||
func (value *Header) Validate(ctx context.Context) error {
|
||||
if value.Name != "" {
|
||||
// Validate returns an error if Header does not comply with the OpenAPI spec.
|
||||
func (header *Header) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if header.Name != "" {
|
||||
return errors.New("header 'name' MUST NOT be specified, it is given in the corresponding headers map")
|
||||
}
|
||||
if value.In != "" {
|
||||
if header.In != "" {
|
||||
return errors.New("header 'in' MUST NOT be specified, it is implicitly in header")
|
||||
}
|
||||
|
||||
// Validate a parameter's serialization method.
|
||||
sm, err := value.SerializationMethod()
|
||||
sm, err := header.SerializationMethod()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -67,62 +69,34 @@ func (value *Header) Validate(ctx context.Context) error {
|
||||
sm.Style == SerializationSimple && !sm.Explode ||
|
||||
sm.Style == SerializationSimple && sm.Explode; !smSupported {
|
||||
e := fmt.Errorf("serialization method with style=%q and explode=%v is not supported by a header parameter", sm.Style, sm.Explode)
|
||||
return fmt.Errorf("header schema is invalid: %v", e)
|
||||
return fmt.Errorf("header schema is invalid: %w", e)
|
||||
}
|
||||
|
||||
if (value.Schema == nil) == (value.Content == nil) {
|
||||
e := fmt.Errorf("parameter must contain exactly one of content and schema: %v", value)
|
||||
return fmt.Errorf("header schema is invalid: %v", e)
|
||||
if (header.Schema == nil) == (len(header.Content) == 0) {
|
||||
e := fmt.Errorf("parameter must contain exactly one of content and schema: %v", header)
|
||||
return fmt.Errorf("header schema is invalid: %w", e)
|
||||
}
|
||||
if schema := value.Schema; schema != nil {
|
||||
if schema := header.Schema; schema != nil {
|
||||
if err := schema.Validate(ctx); err != nil {
|
||||
return fmt.Errorf("header schema is invalid: %v", err)
|
||||
return fmt.Errorf("header schema is invalid: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if content := value.Content; content != nil {
|
||||
if content := header.Content; content != nil {
|
||||
e := errors.New("parameter content must only contain one entry")
|
||||
if len(content) > 1 {
|
||||
return fmt.Errorf("header content is invalid: %w", e)
|
||||
}
|
||||
|
||||
if err := content.Validate(ctx); err != nil {
|
||||
return fmt.Errorf("header content is invalid: %v", err)
|
||||
return fmt.Errorf("header content is invalid: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (value Header) JSONLookup(token string) (interface{}, error) {
|
||||
switch token {
|
||||
case "schema":
|
||||
if value.Schema != nil {
|
||||
if value.Schema.Ref != "" {
|
||||
return &Ref{Ref: value.Schema.Ref}, nil
|
||||
}
|
||||
return value.Schema.Value, nil
|
||||
}
|
||||
case "name":
|
||||
return value.Name, nil
|
||||
case "in":
|
||||
return value.In, nil
|
||||
case "description":
|
||||
return value.Description, nil
|
||||
case "style":
|
||||
return value.Style, nil
|
||||
case "explode":
|
||||
return value.Explode, nil
|
||||
case "allowEmptyValue":
|
||||
return value.AllowEmptyValue, nil
|
||||
case "allowReserved":
|
||||
return value.AllowReserved, nil
|
||||
case "deprecated":
|
||||
return value.Deprecated, nil
|
||||
case "required":
|
||||
return value.Required, nil
|
||||
case "example":
|
||||
return value.Example, nil
|
||||
case "examples":
|
||||
return value.Examples, nil
|
||||
case "content":
|
||||
return value.Content, nil
|
||||
}
|
||||
|
||||
v, _, err := jsonpointer.GetForToken(value.ExtensionProps, token)
|
||||
return v, err
|
||||
// UnmarshalJSON sets Headers to a copy of data.
|
||||
func (headers *Headers) UnmarshalJSON(data []byte) (err error) {
|
||||
*headers, _, err = unmarshalStringMapP[HeaderRef](data)
|
||||
return
|
||||
}
|
||||
|
261
vendor/github.com/getkin/kin-openapi/openapi3/helpers.go
generated
vendored
Normal file
261
vendor/github.com/getkin/kin-openapi/openapi3/helpers.go
generated
vendored
Normal file
@ -0,0 +1,261 @@
|
||||
package openapi3
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
)
|
||||
|
||||
const identifierChars = `a-zA-Z0-9._-`
|
||||
|
||||
// IdentifierRegExp verifies whether Component object key matches contains just 'identifierChars', according to OpenAPI v3.x.
|
||||
// InvalidIdentifierCharRegExp matches all characters not contained in 'identifierChars'.
|
||||
// However, to be able supporting legacy OpenAPI v2.x, there is a need to customize above pattern in order not to fail
|
||||
// converted v2-v3 validation
|
||||
var (
|
||||
IdentifierRegExp = regexp.MustCompile(`^[` + identifierChars + `]+$`)
|
||||
InvalidIdentifierCharRegExp = regexp.MustCompile(`[^` + identifierChars + `]`)
|
||||
)
|
||||
|
||||
// ValidateIdentifier returns an error if the given component name does not match [IdentifierRegExp].
|
||||
func ValidateIdentifier(value string) error {
|
||||
if IdentifierRegExp.MatchString(value) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("identifier %q is not supported by OpenAPIv3 standard (charset: [%q])", value, identifierChars)
|
||||
}
|
||||
|
||||
// Float64Ptr is a helper for defining OpenAPI schemas.
|
||||
func Float64Ptr(value float64) *float64 {
|
||||
return &value
|
||||
}
|
||||
|
||||
// BoolPtr is a helper for defining OpenAPI schemas.
|
||||
func BoolPtr(value bool) *bool {
|
||||
return &value
|
||||
}
|
||||
|
||||
// Int64Ptr is a helper for defining OpenAPI schemas.
|
||||
func Int64Ptr(value int64) *int64 {
|
||||
return &value
|
||||
}
|
||||
|
||||
// Uint64Ptr is a helper for defining OpenAPI schemas.
|
||||
func Uint64Ptr(value uint64) *uint64 {
|
||||
return &value
|
||||
}
|
||||
|
||||
// componentNames returns the map keys in a sorted slice.
|
||||
func componentNames[E any](s map[string]E) []string {
|
||||
out := make([]string, 0, len(s))
|
||||
for i := range s {
|
||||
out = append(out, i)
|
||||
}
|
||||
sort.Strings(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// copyURI makes a copy of the pointer.
|
||||
func copyURI(u *url.URL) *url.URL {
|
||||
if u == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
c := *u // shallow-copy
|
||||
return &c
|
||||
}
|
||||
|
||||
type ComponentRef interface {
|
||||
RefString() string
|
||||
RefPath() *url.URL
|
||||
CollectionName() string
|
||||
}
|
||||
|
||||
// refersToSameDocument returns if the $ref refers to the same document.
|
||||
//
|
||||
// Documents in different directories will have distinct $ref values that resolve to
|
||||
// the same document.
|
||||
// For example, consider the 3 files:
|
||||
//
|
||||
// /records.yaml
|
||||
// /root.yaml $ref: records.yaml
|
||||
// /schema/other.yaml $ref: ../records.yaml
|
||||
//
|
||||
// The records.yaml reference in the 2 latter refers to the same document.
|
||||
func refersToSameDocument(o1 ComponentRef, o2 ComponentRef) bool {
|
||||
if o1 == nil || o2 == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
r1 := o1.RefPath()
|
||||
r2 := o2.RefPath()
|
||||
|
||||
if r1 == nil || r2 == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// refURL is relative to the working directory & base spec file.
|
||||
return referenceURIMatch(r1, r2)
|
||||
}
|
||||
|
||||
// referencesRootDocument returns if the $ref points to the root document of the OpenAPI spec.
|
||||
//
|
||||
// If the document has no location, perhaps loaded from data in memory, it always returns false.
|
||||
func referencesRootDocument(doc *T, ref ComponentRef) bool {
|
||||
if doc.url == nil || ref == nil || ref.RefPath() == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
refURL := *ref.RefPath()
|
||||
refURL.Fragment = ""
|
||||
|
||||
// Check referenced element was in the root document.
|
||||
return referenceURIMatch(doc.url, &refURL)
|
||||
}
|
||||
|
||||
func referenceURIMatch(u1 *url.URL, u2 *url.URL) bool {
|
||||
s1, s2 := *u1, *u2
|
||||
if s1.Scheme == "" {
|
||||
s1.Scheme = "file"
|
||||
}
|
||||
if s2.Scheme == "" {
|
||||
s2.Scheme = "file"
|
||||
}
|
||||
|
||||
return s1.String() == s2.String()
|
||||
}
|
||||
|
||||
// ReferencesComponentInRootDocument returns if the given component reference references
|
||||
// the same document or element as another component reference in the root document's
|
||||
// '#/components/<type>'. If it does, it returns the name of it in the form
|
||||
// '#/components/<type>/NameXXX'
|
||||
//
|
||||
// Of course given a component from the root document will always match itself.
|
||||
//
|
||||
// https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#reference-object
|
||||
// https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#relative-references-in-urls
|
||||
//
|
||||
// Example. Take the spec with directory structure:
|
||||
//
|
||||
// openapi.yaml
|
||||
// schemas/
|
||||
// ├─ record.yaml
|
||||
// ├─ records.yaml
|
||||
//
|
||||
// In openapi.yaml we have:
|
||||
//
|
||||
// components:
|
||||
// schemas:
|
||||
// Record:
|
||||
// $ref: schemas/record.yaml
|
||||
//
|
||||
// Case 1: records.yml references a component in the root document
|
||||
//
|
||||
// $ref: ../openapi.yaml#/components/schemas/Record
|
||||
//
|
||||
// This would return...
|
||||
//
|
||||
// #/components/schemas/Record
|
||||
//
|
||||
// Case 2: records.yml indirectly refers to the same schema
|
||||
// as a schema the root document's '#/components/schemas'.
|
||||
//
|
||||
// $ref: ./record.yaml
|
||||
//
|
||||
// This would also return...
|
||||
//
|
||||
// #/components/schemas/Record
|
||||
func ReferencesComponentInRootDocument(doc *T, ref ComponentRef) (string, bool) {
|
||||
if ref == nil || ref.RefString() == "" {
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Case 1:
|
||||
// Something like: ../another-folder/document.json#/myElement
|
||||
if isRemoteReference(ref.RefString()) && isRootComponentReference(ref.RefString(), ref.CollectionName()) {
|
||||
// Determine if it is *this* root doc.
|
||||
if referencesRootDocument(doc, ref) {
|
||||
_, name, _ := strings.Cut(ref.RefString(), path.Join("#/components/", ref.CollectionName()))
|
||||
|
||||
return path.Join("#/components/", ref.CollectionName(), name), true
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no schemas defined in the root document return early.
|
||||
if doc.Components == nil {
|
||||
return "", false
|
||||
}
|
||||
|
||||
collection, _, err := jsonpointer.GetForToken(doc.Components, ref.CollectionName())
|
||||
if err != nil {
|
||||
panic(err) // unreachable
|
||||
}
|
||||
|
||||
var components map[string]ComponentRef
|
||||
|
||||
componentRefType := reflect.TypeOf(new(ComponentRef)).Elem()
|
||||
if t := reflect.TypeOf(collection); t.Kind() == reflect.Map &&
|
||||
t.Key().Kind() == reflect.String &&
|
||||
t.Elem().AssignableTo(componentRefType) {
|
||||
v := reflect.ValueOf(collection)
|
||||
|
||||
components = make(map[string]ComponentRef, v.Len())
|
||||
for _, key := range v.MapKeys() {
|
||||
strct := v.MapIndex(key)
|
||||
// Type assertion safe, already checked via reflection above.
|
||||
components[key.Interface().(string)] = strct.Interface().(ComponentRef)
|
||||
}
|
||||
} else {
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Case 2:
|
||||
// Something like: ../openapi.yaml#/components/schemas/myElement
|
||||
for name, s := range components {
|
||||
// Must be a reference to a YAML file.
|
||||
if !isWholeDocumentReference(s.RefString()) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Is the schema a ref to the same resource.
|
||||
if !refersToSameDocument(s, ref) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Transform the remote ref to the equivalent schema in the root document.
|
||||
return path.Join("#/components/", ref.CollectionName(), name), true
|
||||
}
|
||||
|
||||
return "", false
|
||||
}
|
||||
|
||||
// isElementReference takes a $ref value and checks if it references a specific element.
|
||||
func isElementReference(ref string) bool {
|
||||
return ref != "" && !isWholeDocumentReference(ref)
|
||||
}
|
||||
|
||||
// isSchemaReference takes a $ref value and checks if it references a schema element.
|
||||
func isRootComponentReference(ref string, compType string) bool {
|
||||
return isElementReference(ref) && strings.Contains(ref, path.Join("#/components/", compType))
|
||||
}
|
||||
|
||||
// isWholeDocumentReference takes a $ref value and checks if it is whole document reference.
|
||||
func isWholeDocumentReference(ref string) bool {
|
||||
return ref != "" && !strings.ContainsAny(ref, "#")
|
||||
}
|
||||
|
||||
// isRemoteReference takes a $ref value and checks if it is remote reference.
|
||||
func isRemoteReference(ref string) bool {
|
||||
return ref != "" && !strings.HasPrefix(ref, "#") && !isURLReference(ref)
|
||||
}
|
||||
|
||||
// isURLReference takes a $ref value and checks if it is URL reference.
|
||||
func isURLReference(ref string) bool {
|
||||
return strings.HasPrefix(ref, "http://") || strings.HasPrefix(ref, "https://") || strings.HasPrefix(ref, "//")
|
||||
}
|
124
vendor/github.com/getkin/kin-openapi/openapi3/info.go
generated
vendored
124
vendor/github.com/getkin/kin-openapi/openapi3/info.go
generated
vendored
@ -2,14 +2,16 @@ package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
)
|
||||
|
||||
// Info is specified by OpenAPI/Swagger standard version 3.0.
|
||||
// Info is specified by OpenAPI/Swagger standard version 3.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#info-object
|
||||
type Info struct {
|
||||
ExtensionProps
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
Title string `json:"title" yaml:"title"` // Required
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
TermsOfService string `json:"termsOfService,omitempty" yaml:"termsOfService,omitempty"`
|
||||
@ -18,76 +20,86 @@ type Info struct {
|
||||
Version string `json:"version" yaml:"version"` // Required
|
||||
}
|
||||
|
||||
func (value *Info) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(value)
|
||||
// MarshalJSON returns the JSON encoding of Info.
|
||||
func (info Info) MarshalJSON() ([]byte, error) {
|
||||
x, err := info.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
func (value *Info) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, value)
|
||||
// MarshalYAML returns the YAML encoding of Info.
|
||||
func (info *Info) MarshalYAML() (any, error) {
|
||||
if info == nil {
|
||||
return nil, nil
|
||||
}
|
||||
m := make(map[string]any, 6+len(info.Extensions))
|
||||
for k, v := range info.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
m["title"] = info.Title
|
||||
if x := info.Description; x != "" {
|
||||
m["description"] = x
|
||||
}
|
||||
if x := info.TermsOfService; x != "" {
|
||||
m["termsOfService"] = x
|
||||
}
|
||||
if x := info.Contact; x != nil {
|
||||
m["contact"] = x
|
||||
}
|
||||
if x := info.License; x != nil {
|
||||
m["license"] = x
|
||||
}
|
||||
m["version"] = info.Version
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (value *Info) Validate(ctx context.Context) error {
|
||||
if contact := value.Contact; contact != nil {
|
||||
// UnmarshalJSON sets Info to a copy of data.
|
||||
func (info *Info) UnmarshalJSON(data []byte) error {
|
||||
type InfoBis Info
|
||||
var x InfoBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "title")
|
||||
delete(x.Extensions, "description")
|
||||
delete(x.Extensions, "termsOfService")
|
||||
delete(x.Extensions, "contact")
|
||||
delete(x.Extensions, "license")
|
||||
delete(x.Extensions, "version")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*info = Info(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate returns an error if Info does not comply with the OpenAPI spec.
|
||||
func (info *Info) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if contact := info.Contact; contact != nil {
|
||||
if err := contact.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if license := value.License; license != nil {
|
||||
if license := info.License; license != nil {
|
||||
if err := license.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if value.Version == "" {
|
||||
if info.Version == "" {
|
||||
return errors.New("value of version must be a non-empty string")
|
||||
}
|
||||
|
||||
if value.Title == "" {
|
||||
if info.Title == "" {
|
||||
return errors.New("value of title must be a non-empty string")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Contact is specified by OpenAPI/Swagger standard version 3.0.
|
||||
type Contact struct {
|
||||
ExtensionProps
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
URL string `json:"url,omitempty" yaml:"url,omitempty"`
|
||||
Email string `json:"email,omitempty" yaml:"email,omitempty"`
|
||||
}
|
||||
|
||||
func (value *Contact) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(value)
|
||||
}
|
||||
|
||||
func (value *Contact) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, value)
|
||||
}
|
||||
|
||||
func (value *Contact) Validate(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// License is specified by OpenAPI/Swagger standard version 3.0.
|
||||
type License struct {
|
||||
ExtensionProps
|
||||
Name string `json:"name" yaml:"name"` // Required
|
||||
URL string `json:"url,omitempty" yaml:"url,omitempty"`
|
||||
}
|
||||
|
||||
func (value *License) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(value)
|
||||
}
|
||||
|
||||
func (value *License) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, value)
|
||||
}
|
||||
|
||||
func (value *License) Validate(ctx context.Context) error {
|
||||
if value.Name == "" {
|
||||
return errors.New("value of license name must be a non-empty string")
|
||||
}
|
||||
return nil
|
||||
return validateExtensions(ctx, info.Extensions)
|
||||
}
|
||||
|
546
vendor/github.com/getkin/kin-openapi/openapi3/internalize_refs.go
generated
vendored
Normal file
546
vendor/github.com/getkin/kin-openapi/openapi3/internalize_refs.go
generated
vendored
Normal file
@ -0,0 +1,546 @@
|
||||
package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// RefNameResolver maps a component to an name that is used as it's internalized name.
|
||||
//
|
||||
// The function should avoid name collisions (i.e. be a injective mapping).
|
||||
// It must only contain characters valid for fixed field names: [IdentifierRegExp].
|
||||
type RefNameResolver func(*T, ComponentRef) string
|
||||
|
||||
// DefaultRefResolver is a default implementation of refNameResolver for the
|
||||
// InternalizeRefs function.
|
||||
//
|
||||
// The external reference is internalized to (hopefully) a unique name. If
|
||||
// the external reference matches (by path) to another reference in the root
|
||||
// document then the name of that component is used.
|
||||
//
|
||||
// The transformation involves:
|
||||
// - Cutting the "#/components/<type>" part.
|
||||
// - Cutting the file extensions (.yaml/.json) from documents.
|
||||
// - Trimming the common directory with the root spec.
|
||||
// - Replace invalid characters with with underscores.
|
||||
//
|
||||
// This is an injective mapping over a "reasonable" amount of the possible openapi
|
||||
// spec domain space but is not perfect. There might be edge cases.
|
||||
func DefaultRefNameResolver(doc *T, ref ComponentRef) string {
|
||||
if ref.RefString() == "" || ref.RefPath() == nil {
|
||||
panic("unable to resolve reference to name")
|
||||
}
|
||||
|
||||
name := ref.RefPath()
|
||||
|
||||
// If refering to a component in the root spec, no need to internalize just use
|
||||
// the existing component.
|
||||
// XXX(percivalalb): since this function call is iterating over components behind the
|
||||
// scenes during an internalization call it actually starts interating over
|
||||
// new & replaced internalized components. This might caused some edge cases,
|
||||
// haven't found one yet but this might need to actually be used on a frozen copy
|
||||
// of doc.
|
||||
if nameInRoot, found := ReferencesComponentInRootDocument(doc, ref); found {
|
||||
nameInRoot = strings.TrimPrefix(nameInRoot, "#")
|
||||
|
||||
rootCompURI := copyURI(doc.url)
|
||||
rootCompURI.Fragment = nameInRoot
|
||||
name = rootCompURI
|
||||
}
|
||||
|
||||
filePath, componentPath := name.Path, name.Fragment
|
||||
|
||||
// Cut out the "#/components/<type>" to make the names shorter.
|
||||
// XXX(percivalalb): This might cause collisions but is worth the brevity.
|
||||
if b, a, ok := strings.Cut(componentPath, path.Join("components", ref.CollectionName(), "")); ok {
|
||||
componentPath = path.Join(b, a)
|
||||
}
|
||||
|
||||
if filePath != "" {
|
||||
// If the path is the same as the root doc, just remove.
|
||||
if doc.url != nil && filePath == doc.url.Path {
|
||||
filePath = ""
|
||||
}
|
||||
|
||||
// Remove the path extentions to make this JSON/YAML agnostic.
|
||||
for ext := path.Ext(filePath); len(ext) > 0; ext = path.Ext(filePath) {
|
||||
filePath = strings.TrimSuffix(filePath, ext)
|
||||
}
|
||||
|
||||
// Trim the common prefix with the root doc path.
|
||||
if doc.url != nil {
|
||||
commonDir := path.Dir(doc.url.Path)
|
||||
for {
|
||||
if commonDir == "." { // no common prefix
|
||||
break
|
||||
}
|
||||
|
||||
if p, found := cutDirectories(filePath, commonDir); found {
|
||||
filePath = p
|
||||
break
|
||||
}
|
||||
|
||||
commonDir = path.Dir(commonDir)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var internalizedName string
|
||||
|
||||
// Trim .'s & slashes from start e.g. otherwise ./doc.yaml would end up as __doc
|
||||
if filePath != "" {
|
||||
internalizedName = strings.TrimLeft(filePath, "./")
|
||||
}
|
||||
|
||||
if componentPath != "" {
|
||||
if internalizedName != "" {
|
||||
internalizedName += "_"
|
||||
}
|
||||
|
||||
internalizedName += strings.TrimLeft(componentPath, "./")
|
||||
}
|
||||
|
||||
// Replace invalid characters in component fixed field names.
|
||||
internalizedName = InvalidIdentifierCharRegExp.ReplaceAllString(internalizedName, "_")
|
||||
|
||||
return internalizedName
|
||||
}
|
||||
|
||||
// cutDirectories removes the given directories from the start of the path if
|
||||
// the path is a child.
|
||||
func cutDirectories(p, dirs string) (string, bool) {
|
||||
if dirs == "" || p == "" {
|
||||
return p, false
|
||||
}
|
||||
|
||||
p = strings.TrimRight(p, "/")
|
||||
dirs = strings.TrimRight(dirs, "/")
|
||||
|
||||
var sb strings.Builder
|
||||
sb.Grow(len(ParameterInHeader))
|
||||
for _, segments := range strings.Split(p, "/") {
|
||||
sb.WriteString(segments)
|
||||
|
||||
if sb.String() == p {
|
||||
return strings.TrimPrefix(p, dirs), true
|
||||
}
|
||||
|
||||
sb.WriteRune('/')
|
||||
}
|
||||
|
||||
return p, false
|
||||
}
|
||||
|
||||
func isExternalRef(ref string, parentIsExternal bool) bool {
|
||||
return ref != "" && (!strings.HasPrefix(ref, "#/components/") || parentIsExternal)
|
||||
}
|
||||
|
||||
func (doc *T) addSchemaToSpec(s *SchemaRef, refNameResolver RefNameResolver, parentIsExternal bool) bool {
|
||||
if s == nil || !isExternalRef(s.Ref, parentIsExternal) {
|
||||
return false
|
||||
}
|
||||
|
||||
name := refNameResolver(doc, s)
|
||||
if doc.Components != nil {
|
||||
if _, ok := doc.Components.Schemas[name]; ok {
|
||||
s.Ref = "#/components/schemas/" + name
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if doc.Components == nil {
|
||||
doc.Components = &Components{}
|
||||
}
|
||||
if doc.Components.Schemas == nil {
|
||||
doc.Components.Schemas = make(Schemas)
|
||||
}
|
||||
doc.Components.Schemas[name] = s.Value.NewRef()
|
||||
s.Ref = "#/components/schemas/" + name
|
||||
return true
|
||||
}
|
||||
|
||||
func (doc *T) addParameterToSpec(p *ParameterRef, refNameResolver RefNameResolver, parentIsExternal bool) bool {
|
||||
if p == nil || !isExternalRef(p.Ref, parentIsExternal) {
|
||||
return false
|
||||
}
|
||||
name := refNameResolver(doc, p)
|
||||
if doc.Components != nil {
|
||||
if _, ok := doc.Components.Parameters[name]; ok {
|
||||
p.Ref = "#/components/parameters/" + name
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if doc.Components == nil {
|
||||
doc.Components = &Components{}
|
||||
}
|
||||
if doc.Components.Parameters == nil {
|
||||
doc.Components.Parameters = make(ParametersMap)
|
||||
}
|
||||
doc.Components.Parameters[name] = &ParameterRef{Value: p.Value}
|
||||
p.Ref = "#/components/parameters/" + name
|
||||
return true
|
||||
}
|
||||
|
||||
func (doc *T) addHeaderToSpec(h *HeaderRef, refNameResolver RefNameResolver, parentIsExternal bool) bool {
|
||||
if h == nil || !isExternalRef(h.Ref, parentIsExternal) {
|
||||
return false
|
||||
}
|
||||
name := refNameResolver(doc, h)
|
||||
if doc.Components != nil {
|
||||
if _, ok := doc.Components.Headers[name]; ok {
|
||||
h.Ref = "#/components/headers/" + name
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if doc.Components == nil {
|
||||
doc.Components = &Components{}
|
||||
}
|
||||
if doc.Components.Headers == nil {
|
||||
doc.Components.Headers = make(Headers)
|
||||
}
|
||||
doc.Components.Headers[name] = &HeaderRef{Value: h.Value}
|
||||
h.Ref = "#/components/headers/" + name
|
||||
return true
|
||||
}
|
||||
|
||||
func (doc *T) addRequestBodyToSpec(r *RequestBodyRef, refNameResolver RefNameResolver, parentIsExternal bool) bool {
|
||||
if r == nil || !isExternalRef(r.Ref, parentIsExternal) {
|
||||
return false
|
||||
}
|
||||
name := refNameResolver(doc, r)
|
||||
if doc.Components != nil {
|
||||
if _, ok := doc.Components.RequestBodies[name]; ok {
|
||||
r.Ref = "#/components/requestBodies/" + name
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if doc.Components == nil {
|
||||
doc.Components = &Components{}
|
||||
}
|
||||
if doc.Components.RequestBodies == nil {
|
||||
doc.Components.RequestBodies = make(RequestBodies)
|
||||
}
|
||||
doc.Components.RequestBodies[name] = &RequestBodyRef{Value: r.Value}
|
||||
r.Ref = "#/components/requestBodies/" + name
|
||||
return true
|
||||
}
|
||||
|
||||
func (doc *T) addResponseToSpec(r *ResponseRef, refNameResolver RefNameResolver, parentIsExternal bool) bool {
|
||||
if r == nil || !isExternalRef(r.Ref, parentIsExternal) {
|
||||
return false
|
||||
}
|
||||
name := refNameResolver(doc, r)
|
||||
if doc.Components != nil {
|
||||
if _, ok := doc.Components.Responses[name]; ok {
|
||||
r.Ref = "#/components/responses/" + name
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if doc.Components == nil {
|
||||
doc.Components = &Components{}
|
||||
}
|
||||
if doc.Components.Responses == nil {
|
||||
doc.Components.Responses = make(ResponseBodies)
|
||||
}
|
||||
doc.Components.Responses[name] = &ResponseRef{Value: r.Value}
|
||||
r.Ref = "#/components/responses/" + name
|
||||
return true
|
||||
}
|
||||
|
||||
func (doc *T) addSecuritySchemeToSpec(ss *SecuritySchemeRef, refNameResolver RefNameResolver, parentIsExternal bool) {
|
||||
if ss == nil || !isExternalRef(ss.Ref, parentIsExternal) {
|
||||
return
|
||||
}
|
||||
name := refNameResolver(doc, ss)
|
||||
if doc.Components != nil {
|
||||
if _, ok := doc.Components.SecuritySchemes[name]; ok {
|
||||
ss.Ref = "#/components/securitySchemes/" + name
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if doc.Components == nil {
|
||||
doc.Components = &Components{}
|
||||
}
|
||||
if doc.Components.SecuritySchemes == nil {
|
||||
doc.Components.SecuritySchemes = make(SecuritySchemes)
|
||||
}
|
||||
doc.Components.SecuritySchemes[name] = &SecuritySchemeRef{Value: ss.Value}
|
||||
ss.Ref = "#/components/securitySchemes/" + name
|
||||
|
||||
}
|
||||
|
||||
func (doc *T) addExampleToSpec(e *ExampleRef, refNameResolver RefNameResolver, parentIsExternal bool) {
|
||||
if e == nil || !isExternalRef(e.Ref, parentIsExternal) {
|
||||
return
|
||||
}
|
||||
name := refNameResolver(doc, e)
|
||||
if doc.Components != nil {
|
||||
if _, ok := doc.Components.Examples[name]; ok {
|
||||
e.Ref = "#/components/examples/" + name
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if doc.Components == nil {
|
||||
doc.Components = &Components{}
|
||||
}
|
||||
if doc.Components.Examples == nil {
|
||||
doc.Components.Examples = make(Examples)
|
||||
}
|
||||
doc.Components.Examples[name] = &ExampleRef{Value: e.Value}
|
||||
e.Ref = "#/components/examples/" + name
|
||||
|
||||
}
|
||||
|
||||
func (doc *T) addLinkToSpec(l *LinkRef, refNameResolver RefNameResolver, parentIsExternal bool) {
|
||||
if l == nil || !isExternalRef(l.Ref, parentIsExternal) {
|
||||
return
|
||||
}
|
||||
name := refNameResolver(doc, l)
|
||||
if doc.Components != nil {
|
||||
if _, ok := doc.Components.Links[name]; ok {
|
||||
l.Ref = "#/components/links/" + name
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if doc.Components == nil {
|
||||
doc.Components = &Components{}
|
||||
}
|
||||
if doc.Components.Links == nil {
|
||||
doc.Components.Links = make(Links)
|
||||
}
|
||||
doc.Components.Links[name] = &LinkRef{Value: l.Value}
|
||||
l.Ref = "#/components/links/" + name
|
||||
|
||||
}
|
||||
|
||||
func (doc *T) addCallbackToSpec(c *CallbackRef, refNameResolver RefNameResolver, parentIsExternal bool) bool {
|
||||
if c == nil || !isExternalRef(c.Ref, parentIsExternal) {
|
||||
return false
|
||||
}
|
||||
name := refNameResolver(doc, c)
|
||||
|
||||
if doc.Components == nil {
|
||||
doc.Components = &Components{}
|
||||
}
|
||||
if doc.Components.Callbacks == nil {
|
||||
doc.Components.Callbacks = make(Callbacks)
|
||||
}
|
||||
c.Ref = "#/components/callbacks/" + name
|
||||
doc.Components.Callbacks[name] = &CallbackRef{Value: c.Value}
|
||||
return true
|
||||
}
|
||||
|
||||
func (doc *T) derefSchema(s *Schema, refNameResolver RefNameResolver, parentIsExternal bool) {
|
||||
if s == nil || doc.isVisitedSchema(s) {
|
||||
return
|
||||
}
|
||||
|
||||
for _, list := range []SchemaRefs{s.AllOf, s.AnyOf, s.OneOf} {
|
||||
for _, s2 := range list {
|
||||
isExternal := doc.addSchemaToSpec(s2, refNameResolver, parentIsExternal)
|
||||
if s2 != nil {
|
||||
doc.derefSchema(s2.Value, refNameResolver, isExternal || parentIsExternal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range componentNames(s.Properties) {
|
||||
s2 := s.Properties[name]
|
||||
isExternal := doc.addSchemaToSpec(s2, refNameResolver, parentIsExternal)
|
||||
if s2 != nil {
|
||||
doc.derefSchema(s2.Value, refNameResolver, isExternal || parentIsExternal)
|
||||
}
|
||||
}
|
||||
for _, ref := range []*SchemaRef{s.Not, s.AdditionalProperties.Schema, s.Items} {
|
||||
isExternal := doc.addSchemaToSpec(ref, refNameResolver, parentIsExternal)
|
||||
if ref != nil {
|
||||
doc.derefSchema(ref.Value, refNameResolver, isExternal || parentIsExternal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (doc *T) derefHeaders(hs Headers, refNameResolver RefNameResolver, parentIsExternal bool) {
|
||||
for _, name := range componentNames(hs) {
|
||||
h := hs[name]
|
||||
isExternal := doc.addHeaderToSpec(h, refNameResolver, parentIsExternal)
|
||||
if doc.isVisitedHeader(h.Value) {
|
||||
continue
|
||||
}
|
||||
doc.derefParameter(h.Value.Parameter, refNameResolver, parentIsExternal || isExternal)
|
||||
}
|
||||
}
|
||||
|
||||
func (doc *T) derefExamples(es Examples, refNameResolver RefNameResolver, parentIsExternal bool) {
|
||||
for _, name := range componentNames(es) {
|
||||
e := es[name]
|
||||
doc.addExampleToSpec(e, refNameResolver, parentIsExternal)
|
||||
}
|
||||
}
|
||||
|
||||
func (doc *T) derefContent(c Content, refNameResolver RefNameResolver, parentIsExternal bool) {
|
||||
for _, name := range componentNames(c) {
|
||||
mediatype := c[name]
|
||||
isExternal := doc.addSchemaToSpec(mediatype.Schema, refNameResolver, parentIsExternal)
|
||||
if mediatype.Schema != nil {
|
||||
doc.derefSchema(mediatype.Schema.Value, refNameResolver, isExternal || parentIsExternal)
|
||||
}
|
||||
doc.derefExamples(mediatype.Examples, refNameResolver, parentIsExternal)
|
||||
for _, name := range componentNames(mediatype.Encoding) {
|
||||
e := mediatype.Encoding[name]
|
||||
doc.derefHeaders(e.Headers, refNameResolver, parentIsExternal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (doc *T) derefLinks(ls Links, refNameResolver RefNameResolver, parentIsExternal bool) {
|
||||
for _, name := range componentNames(ls) {
|
||||
l := ls[name]
|
||||
doc.addLinkToSpec(l, refNameResolver, parentIsExternal)
|
||||
}
|
||||
}
|
||||
|
||||
func (doc *T) derefResponse(r *ResponseRef, refNameResolver RefNameResolver, parentIsExternal bool) {
|
||||
isExternal := doc.addResponseToSpec(r, refNameResolver, parentIsExternal)
|
||||
if v := r.Value; v != nil {
|
||||
doc.derefHeaders(v.Headers, refNameResolver, isExternal || parentIsExternal)
|
||||
doc.derefContent(v.Content, refNameResolver, isExternal || parentIsExternal)
|
||||
doc.derefLinks(v.Links, refNameResolver, isExternal || parentIsExternal)
|
||||
}
|
||||
}
|
||||
|
||||
func (doc *T) derefResponses(rs *Responses, refNameResolver RefNameResolver, parentIsExternal bool) {
|
||||
doc.derefResponseBodies(rs.Map(), refNameResolver, parentIsExternal)
|
||||
}
|
||||
|
||||
func (doc *T) derefResponseBodies(es ResponseBodies, refNameResolver RefNameResolver, parentIsExternal bool) {
|
||||
for _, name := range componentNames(es) {
|
||||
e := es[name]
|
||||
doc.derefResponse(e, refNameResolver, parentIsExternal)
|
||||
}
|
||||
}
|
||||
|
||||
func (doc *T) derefParameter(p Parameter, refNameResolver RefNameResolver, parentIsExternal bool) {
|
||||
isExternal := doc.addSchemaToSpec(p.Schema, refNameResolver, parentIsExternal)
|
||||
doc.derefContent(p.Content, refNameResolver, parentIsExternal)
|
||||
if p.Schema != nil {
|
||||
doc.derefSchema(p.Schema.Value, refNameResolver, isExternal || parentIsExternal)
|
||||
}
|
||||
}
|
||||
|
||||
func (doc *T) derefRequestBody(r RequestBody, refNameResolver RefNameResolver, parentIsExternal bool) {
|
||||
doc.derefContent(r.Content, refNameResolver, parentIsExternal)
|
||||
}
|
||||
|
||||
func (doc *T) derefPaths(paths map[string]*PathItem, refNameResolver RefNameResolver, parentIsExternal bool) {
|
||||
for _, name := range componentNames(paths) {
|
||||
ops := paths[name]
|
||||
pathIsExternal := isExternalRef(ops.Ref, parentIsExternal)
|
||||
// inline full operations
|
||||
ops.Ref = ""
|
||||
|
||||
for _, param := range ops.Parameters {
|
||||
isExternal := doc.addParameterToSpec(param, refNameResolver, pathIsExternal)
|
||||
if param.Value != nil {
|
||||
doc.derefParameter(*param.Value, refNameResolver, pathIsExternal || isExternal)
|
||||
}
|
||||
}
|
||||
|
||||
opsWithMethod := ops.Operations()
|
||||
for _, name := range componentNames(opsWithMethod) {
|
||||
op := opsWithMethod[name]
|
||||
isExternal := doc.addRequestBodyToSpec(op.RequestBody, refNameResolver, pathIsExternal)
|
||||
if op.RequestBody != nil && op.RequestBody.Value != nil {
|
||||
doc.derefRequestBody(*op.RequestBody.Value, refNameResolver, pathIsExternal || isExternal)
|
||||
}
|
||||
for _, name := range componentNames(op.Callbacks) {
|
||||
cb := op.Callbacks[name]
|
||||
isExternal := doc.addCallbackToSpec(cb, refNameResolver, pathIsExternal)
|
||||
if cb.Value != nil {
|
||||
cbValue := (*cb.Value).Map()
|
||||
doc.derefPaths(cbValue, refNameResolver, pathIsExternal || isExternal)
|
||||
}
|
||||
}
|
||||
doc.derefResponses(op.Responses, refNameResolver, pathIsExternal)
|
||||
for _, param := range op.Parameters {
|
||||
isExternal := doc.addParameterToSpec(param, refNameResolver, pathIsExternal)
|
||||
if param.Value != nil {
|
||||
doc.derefParameter(*param.Value, refNameResolver, pathIsExternal || isExternal)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// InternalizeRefs removes all references to external files from the spec and moves them
|
||||
// to the components section.
|
||||
//
|
||||
// refNameResolver takes in references to returns a name to store the reference under locally.
|
||||
// It MUST return a unique name for each reference type.
|
||||
// A default implementation is provided that will suffice for most use cases. See the function
|
||||
// documentation for more details.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// doc.InternalizeRefs(context.Background(), nil)
|
||||
func (doc *T) InternalizeRefs(ctx context.Context, refNameResolver func(*T, ComponentRef) string) {
|
||||
doc.resetVisited()
|
||||
|
||||
if refNameResolver == nil {
|
||||
refNameResolver = DefaultRefNameResolver
|
||||
}
|
||||
|
||||
if components := doc.Components; components != nil {
|
||||
for _, name := range componentNames(components.Schemas) {
|
||||
schema := components.Schemas[name]
|
||||
isExternal := doc.addSchemaToSpec(schema, refNameResolver, false)
|
||||
if schema != nil {
|
||||
schema.Ref = "" // always dereference the top level
|
||||
doc.derefSchema(schema.Value, refNameResolver, isExternal)
|
||||
}
|
||||
}
|
||||
for _, name := range componentNames(components.Parameters) {
|
||||
p := components.Parameters[name]
|
||||
isExternal := doc.addParameterToSpec(p, refNameResolver, false)
|
||||
if p != nil && p.Value != nil {
|
||||
p.Ref = "" // always dereference the top level
|
||||
doc.derefParameter(*p.Value, refNameResolver, isExternal)
|
||||
}
|
||||
}
|
||||
doc.derefHeaders(components.Headers, refNameResolver, false)
|
||||
for _, name := range componentNames(components.RequestBodies) {
|
||||
req := components.RequestBodies[name]
|
||||
isExternal := doc.addRequestBodyToSpec(req, refNameResolver, false)
|
||||
if req != nil && req.Value != nil {
|
||||
req.Ref = "" // always dereference the top level
|
||||
doc.derefRequestBody(*req.Value, refNameResolver, isExternal)
|
||||
}
|
||||
}
|
||||
doc.derefResponseBodies(components.Responses, refNameResolver, false)
|
||||
for _, name := range componentNames(components.SecuritySchemes) {
|
||||
ss := components.SecuritySchemes[name]
|
||||
doc.addSecuritySchemeToSpec(ss, refNameResolver, false)
|
||||
}
|
||||
doc.derefExamples(components.Examples, refNameResolver, false)
|
||||
doc.derefLinks(components.Links, refNameResolver, false)
|
||||
|
||||
for _, name := range componentNames(components.Callbacks) {
|
||||
cb := components.Callbacks[name]
|
||||
isExternal := doc.addCallbackToSpec(cb, refNameResolver, false)
|
||||
if cb != nil && cb.Value != nil {
|
||||
cb.Ref = "" // always dereference the top level
|
||||
cbValue := (*cb.Value).Map()
|
||||
doc.derefPaths(cbValue, refNameResolver, isExternal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doc.derefPaths(doc.Paths.Map(), refNameResolver, false)
|
||||
}
|
68
vendor/github.com/getkin/kin-openapi/openapi3/license.go
generated
vendored
Normal file
68
vendor/github.com/getkin/kin-openapi/openapi3/license.go
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// License is specified by OpenAPI/Swagger standard version 3.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#license-object
|
||||
type License struct {
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
Name string `json:"name" yaml:"name"` // Required
|
||||
URL string `json:"url,omitempty" yaml:"url,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of License.
|
||||
func (license License) MarshalJSON() ([]byte, error) {
|
||||
x, err := license.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of License.
|
||||
func (license License) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 2+len(license.Extensions))
|
||||
for k, v := range license.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
m["name"] = license.Name
|
||||
if x := license.URL; x != "" {
|
||||
m["url"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets License to a copy of data.
|
||||
func (license *License) UnmarshalJSON(data []byte) error {
|
||||
type LicenseBis License
|
||||
var x LicenseBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "name")
|
||||
delete(x.Extensions, "url")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*license = License(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate returns an error if License does not comply with the OpenAPI spec.
|
||||
func (license *License) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if license.Name == "" {
|
||||
return errors.New("value of license name must be a non-empty string")
|
||||
}
|
||||
|
||||
return validateExtensions(ctx, license.Extensions)
|
||||
}
|
128
vendor/github.com/getkin/kin-openapi/openapi3/link.go
generated
vendored
128
vendor/github.com/getkin/kin-openapi/openapi3/link.go
generated
vendored
@ -2,54 +2,102 @@ package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
)
|
||||
|
||||
type Links map[string]*LinkRef
|
||||
|
||||
func (l Links) JSONLookup(token string) (interface{}, error) {
|
||||
ref, ok := l[token]
|
||||
if ok == false {
|
||||
return nil, fmt.Errorf("object has no field %q", token)
|
||||
}
|
||||
|
||||
if ref != nil && ref.Ref != "" {
|
||||
return &Ref{Ref: ref.Ref}, nil
|
||||
}
|
||||
return ref.Value, nil
|
||||
}
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*Links)(nil)
|
||||
|
||||
// Link is specified by OpenAPI/Swagger standard version 3.0.
|
||||
// Link is specified by OpenAPI/Swagger standard version 3.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#link-object
|
||||
type Link struct {
|
||||
ExtensionProps
|
||||
OperationID string `json:"operationId,omitempty" yaml:"operationId,omitempty"`
|
||||
OperationRef string `json:"operationRef,omitempty" yaml:"operationRef,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
Parameters map[string]interface{} `json:"parameters,omitempty" yaml:"parameters,omitempty"`
|
||||
Server *Server `json:"server,omitempty" yaml:"server,omitempty"`
|
||||
RequestBody interface{} `json:"requestBody,omitempty" yaml:"requestBody,omitempty"`
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
OperationRef string `json:"operationRef,omitempty" yaml:"operationRef,omitempty"`
|
||||
OperationID string `json:"operationId,omitempty" yaml:"operationId,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
Parameters map[string]any `json:"parameters,omitempty" yaml:"parameters,omitempty"`
|
||||
Server *Server `json:"server,omitempty" yaml:"server,omitempty"`
|
||||
RequestBody any `json:"requestBody,omitempty" yaml:"requestBody,omitempty"`
|
||||
}
|
||||
|
||||
func (value *Link) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(value)
|
||||
}
|
||||
|
||||
func (value *Link) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, value)
|
||||
}
|
||||
|
||||
func (value *Link) Validate(ctx context.Context) error {
|
||||
if value.OperationID == "" && value.OperationRef == "" {
|
||||
return errors.New("missing operationId or operationRef on link")
|
||||
// MarshalJSON returns the JSON encoding of Link.
|
||||
func (link Link) MarshalJSON() ([]byte, error) {
|
||||
x, err := link.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if value.OperationID != "" && value.OperationRef != "" {
|
||||
return fmt.Errorf("operationId %q and operationRef %q are mutually exclusive", value.OperationID, value.OperationRef)
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of Link.
|
||||
func (link Link) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 6+len(link.Extensions))
|
||||
for k, v := range link.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
|
||||
if x := link.OperationRef; x != "" {
|
||||
m["operationRef"] = x
|
||||
}
|
||||
if x := link.OperationID; x != "" {
|
||||
m["operationId"] = x
|
||||
}
|
||||
if x := link.Description; x != "" {
|
||||
m["description"] = x
|
||||
}
|
||||
if x := link.Parameters; len(x) != 0 {
|
||||
m["parameters"] = x
|
||||
}
|
||||
if x := link.Server; x != nil {
|
||||
m["server"] = x
|
||||
}
|
||||
if x := link.RequestBody; x != nil {
|
||||
m["requestBody"] = x
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Link to a copy of data.
|
||||
func (link *Link) UnmarshalJSON(data []byte) error {
|
||||
type LinkBis Link
|
||||
var x LinkBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "operationRef")
|
||||
delete(x.Extensions, "operationId")
|
||||
delete(x.Extensions, "description")
|
||||
delete(x.Extensions, "parameters")
|
||||
delete(x.Extensions, "server")
|
||||
delete(x.Extensions, "requestBody")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*link = Link(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate returns an error if Link does not comply with the OpenAPI spec.
|
||||
func (link *Link) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if link.OperationID == "" && link.OperationRef == "" {
|
||||
return errors.New("missing operationId or operationRef on link")
|
||||
}
|
||||
if link.OperationID != "" && link.OperationRef != "" {
|
||||
return fmt.Errorf("operationId %q and operationRef %q are mutually exclusive", link.OperationID, link.OperationRef)
|
||||
}
|
||||
|
||||
return validateExtensions(ctx, link.Extensions)
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Links to a copy of data.
|
||||
func (links *Links) UnmarshalJSON(data []byte) (err error) {
|
||||
*links, _, err = unmarshalStringMapP[LinkRef](data)
|
||||
return
|
||||
}
|
||||
|
965
vendor/github.com/getkin/kin-openapi/openapi3/loader.go
generated
vendored
965
vendor/github.com/getkin/kin-openapi/openapi3/loader.go
generated
vendored
File diff suppressed because it is too large
Load Diff
116
vendor/github.com/getkin/kin-openapi/openapi3/loader_uri_reader.go
generated
vendored
Normal file
116
vendor/github.com/getkin/kin-openapi/openapi3/loader_uri_reader.go
generated
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
package openapi3
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// ReadFromURIFunc defines a function which reads the contents of a resource
|
||||
// located at a URI.
|
||||
type ReadFromURIFunc func(loader *Loader, url *url.URL) ([]byte, error)
|
||||
|
||||
var uriMu = &sync.RWMutex{}
|
||||
|
||||
// ErrURINotSupported indicates the ReadFromURIFunc does not know how to handle a
|
||||
// given URI.
|
||||
var ErrURINotSupported = errors.New("unsupported URI")
|
||||
|
||||
// ReadFromURIs returns a ReadFromURIFunc which tries to read a URI using the
|
||||
// given reader functions, in the same order. If a reader function does not
|
||||
// support the URI and returns ErrURINotSupported, the next function is checked
|
||||
// until a match is found, or the URI is not supported by any.
|
||||
func ReadFromURIs(readers ...ReadFromURIFunc) ReadFromURIFunc {
|
||||
return func(loader *Loader, url *url.URL) ([]byte, error) {
|
||||
for i := range readers {
|
||||
buf, err := readers[i](loader, url)
|
||||
if err == ErrURINotSupported {
|
||||
continue
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf, nil
|
||||
}
|
||||
return nil, ErrURINotSupported
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultReadFromURI returns a caching ReadFromURIFunc which can read remote
|
||||
// HTTP URIs and local file URIs.
|
||||
var DefaultReadFromURI = URIMapCache(ReadFromURIs(ReadFromHTTP(http.DefaultClient), ReadFromFile))
|
||||
|
||||
// ReadFromHTTP returns a ReadFromURIFunc which uses the given http.Client to
|
||||
// read the contents from a remote HTTP URI. This client may be customized to
|
||||
// implement timeouts, RFC 7234 caching, etc.
|
||||
func ReadFromHTTP(cl *http.Client) ReadFromURIFunc {
|
||||
return func(loader *Loader, location *url.URL) ([]byte, error) {
|
||||
if location.Scheme == "" || location.Host == "" {
|
||||
return nil, ErrURINotSupported
|
||||
}
|
||||
req, err := http.NewRequest("GET", location.String(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := cl.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode > 399 {
|
||||
return nil, fmt.Errorf("error loading %q: request returned status code %d", location.String(), resp.StatusCode)
|
||||
}
|
||||
return io.ReadAll(resp.Body)
|
||||
}
|
||||
}
|
||||
|
||||
func is_file(location *url.URL) bool {
|
||||
return location.Path != "" &&
|
||||
location.Host == "" &&
|
||||
(location.Scheme == "" || location.Scheme == "file")
|
||||
}
|
||||
|
||||
// ReadFromFile is a ReadFromURIFunc which reads local file URIs.
|
||||
func ReadFromFile(loader *Loader, location *url.URL) ([]byte, error) {
|
||||
if !is_file(location) {
|
||||
return nil, ErrURINotSupported
|
||||
}
|
||||
return os.ReadFile(filepath.FromSlash(location.Path))
|
||||
}
|
||||
|
||||
// URIMapCache returns a ReadFromURIFunc that caches the contents read from URI
|
||||
// locations in a simple map. This cache implementation is suitable for
|
||||
// short-lived processes such as command-line tools which process OpenAPI
|
||||
// documents.
|
||||
func URIMapCache(reader ReadFromURIFunc) ReadFromURIFunc {
|
||||
cache := map[string][]byte{}
|
||||
return func(loader *Loader, location *url.URL) (buf []byte, err error) {
|
||||
if location.Scheme == "" || location.Scheme == "file" {
|
||||
if !filepath.IsAbs(location.Path) {
|
||||
// Do not cache relative file paths; this can cause trouble if
|
||||
// the current working directory changes when processing
|
||||
// multiple top-level documents.
|
||||
return reader(loader, location)
|
||||
}
|
||||
}
|
||||
uri := location.String()
|
||||
var ok bool
|
||||
uriMu.RLock()
|
||||
if buf, ok = cache[uri]; ok {
|
||||
uriMu.RUnlock()
|
||||
return
|
||||
}
|
||||
uriMu.RUnlock()
|
||||
if buf, err = reader(loader, location); err != nil {
|
||||
return
|
||||
}
|
||||
uriMu.Lock()
|
||||
defer uriMu.Unlock()
|
||||
cache[uri] = buf
|
||||
return
|
||||
}
|
||||
}
|
435
vendor/github.com/getkin/kin-openapi/openapi3/maplike.go
generated
vendored
Normal file
435
vendor/github.com/getkin/kin-openapi/openapi3/maplike.go
generated
vendored
Normal file
@ -0,0 +1,435 @@
|
||||
package openapi3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
)
|
||||
|
||||
// NewResponsesWithCapacity builds a responses object of the given capacity.
|
||||
func NewResponsesWithCapacity(cap int) *Responses {
|
||||
if cap == 0 {
|
||||
return &Responses{m: make(map[string]*ResponseRef)}
|
||||
}
|
||||
return &Responses{m: make(map[string]*ResponseRef, cap)}
|
||||
}
|
||||
|
||||
// Value returns the responses for key or nil
|
||||
func (responses *Responses) Value(key string) *ResponseRef {
|
||||
if responses.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
return responses.m[key]
|
||||
}
|
||||
|
||||
// Set adds or replaces key 'key' of 'responses' with 'value'.
|
||||
// Note: 'responses' MUST be non-nil
|
||||
func (responses *Responses) Set(key string, value *ResponseRef) {
|
||||
if responses.m == nil {
|
||||
responses.m = make(map[string]*ResponseRef)
|
||||
}
|
||||
responses.m[key] = value
|
||||
}
|
||||
|
||||
// Len returns the amount of keys in responses excluding responses.Extensions.
|
||||
func (responses *Responses) Len() int {
|
||||
if responses == nil || responses.m == nil {
|
||||
return 0
|
||||
}
|
||||
return len(responses.m)
|
||||
}
|
||||
|
||||
// Delete removes the entry associated with key 'key' from 'responses'.
|
||||
func (responses *Responses) Delete(key string) {
|
||||
if responses != nil && responses.m != nil {
|
||||
delete(responses.m, key)
|
||||
}
|
||||
}
|
||||
|
||||
// Map returns responses as a 'map'.
|
||||
// Note: iteration on Go maps is not ordered.
|
||||
func (responses *Responses) Map() (m map[string]*ResponseRef) {
|
||||
if responses == nil || len(responses.m) == 0 {
|
||||
return make(map[string]*ResponseRef)
|
||||
}
|
||||
m = make(map[string]*ResponseRef, len(responses.m))
|
||||
for k, v := range responses.m {
|
||||
m[k] = v
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*Responses)(nil)
|
||||
|
||||
// JSONLookup implements https://github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (responses Responses) JSONLookup(token string) (any, error) {
|
||||
if v := responses.Value(token); v == nil {
|
||||
vv, _, err := jsonpointer.GetForToken(responses.Extensions, token)
|
||||
return vv, err
|
||||
} else if ref := v.Ref; ref != "" {
|
||||
return &Ref{Ref: ref}, nil
|
||||
} else {
|
||||
var vv *Response = v.Value
|
||||
return vv, nil
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of Responses.
|
||||
func (responses *Responses) MarshalYAML() (any, error) {
|
||||
if responses == nil {
|
||||
return nil, nil
|
||||
}
|
||||
m := make(map[string]any, responses.Len()+len(responses.Extensions))
|
||||
for k, v := range responses.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
for k, v := range responses.Map() {
|
||||
m[k] = v
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of Responses.
|
||||
func (responses *Responses) MarshalJSON() ([]byte, error) {
|
||||
responsesYaml, err := responses.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(responsesYaml)
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Responses to a copy of data.
|
||||
func (responses *Responses) UnmarshalJSON(data []byte) (err error) {
|
||||
var m map[string]any
|
||||
if err = json.Unmarshal(data, &m); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ks := make([]string, 0, len(m))
|
||||
for k := range m {
|
||||
ks = append(ks, k)
|
||||
}
|
||||
sort.Strings(ks)
|
||||
|
||||
x := Responses{
|
||||
Extensions: make(map[string]any),
|
||||
m: make(map[string]*ResponseRef, len(m)),
|
||||
}
|
||||
|
||||
for _, k := range ks {
|
||||
v := m[k]
|
||||
if strings.HasPrefix(k, "x-") {
|
||||
x.Extensions[k] = v
|
||||
continue
|
||||
}
|
||||
|
||||
if k == originKey {
|
||||
var data []byte
|
||||
if data, err = json.Marshal(v); err != nil {
|
||||
return
|
||||
}
|
||||
if err = json.Unmarshal(data, &x.Origin); err != nil {
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
var data []byte
|
||||
if data, err = json.Marshal(v); err != nil {
|
||||
return
|
||||
}
|
||||
var vv ResponseRef
|
||||
if err = vv.UnmarshalJSON(data); err != nil {
|
||||
return
|
||||
}
|
||||
x.m[k] = &vv
|
||||
}
|
||||
*responses = x
|
||||
return
|
||||
}
|
||||
|
||||
// NewCallbackWithCapacity builds a callback object of the given capacity.
|
||||
func NewCallbackWithCapacity(cap int) *Callback {
|
||||
if cap == 0 {
|
||||
return &Callback{m: make(map[string]*PathItem)}
|
||||
}
|
||||
return &Callback{m: make(map[string]*PathItem, cap)}
|
||||
}
|
||||
|
||||
// Value returns the callback for key or nil
|
||||
func (callback *Callback) Value(key string) *PathItem {
|
||||
if callback.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
return callback.m[key]
|
||||
}
|
||||
|
||||
// Set adds or replaces key 'key' of 'callback' with 'value'.
|
||||
// Note: 'callback' MUST be non-nil
|
||||
func (callback *Callback) Set(key string, value *PathItem) {
|
||||
if callback.m == nil {
|
||||
callback.m = make(map[string]*PathItem)
|
||||
}
|
||||
callback.m[key] = value
|
||||
}
|
||||
|
||||
// Len returns the amount of keys in callback excluding callback.Extensions.
|
||||
func (callback *Callback) Len() int {
|
||||
if callback == nil || callback.m == nil {
|
||||
return 0
|
||||
}
|
||||
return len(callback.m)
|
||||
}
|
||||
|
||||
// Delete removes the entry associated with key 'key' from 'callback'.
|
||||
func (callback *Callback) Delete(key string) {
|
||||
if callback != nil && callback.m != nil {
|
||||
delete(callback.m, key)
|
||||
}
|
||||
}
|
||||
|
||||
// Map returns callback as a 'map'.
|
||||
// Note: iteration on Go maps is not ordered.
|
||||
func (callback *Callback) Map() (m map[string]*PathItem) {
|
||||
if callback == nil || len(callback.m) == 0 {
|
||||
return make(map[string]*PathItem)
|
||||
}
|
||||
m = make(map[string]*PathItem, len(callback.m))
|
||||
for k, v := range callback.m {
|
||||
m[k] = v
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*Callback)(nil)
|
||||
|
||||
// JSONLookup implements https://github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (callback Callback) JSONLookup(token string) (any, error) {
|
||||
if v := callback.Value(token); v == nil {
|
||||
vv, _, err := jsonpointer.GetForToken(callback.Extensions, token)
|
||||
return vv, err
|
||||
} else if ref := v.Ref; ref != "" {
|
||||
return &Ref{Ref: ref}, nil
|
||||
} else {
|
||||
var vv *PathItem = v
|
||||
return vv, nil
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of Callback.
|
||||
func (callback *Callback) MarshalYAML() (any, error) {
|
||||
if callback == nil {
|
||||
return nil, nil
|
||||
}
|
||||
m := make(map[string]any, callback.Len()+len(callback.Extensions))
|
||||
for k, v := range callback.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
for k, v := range callback.Map() {
|
||||
m[k] = v
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of Callback.
|
||||
func (callback *Callback) MarshalJSON() ([]byte, error) {
|
||||
callbackYaml, err := callback.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(callbackYaml)
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Callback to a copy of data.
|
||||
func (callback *Callback) UnmarshalJSON(data []byte) (err error) {
|
||||
var m map[string]any
|
||||
if err = json.Unmarshal(data, &m); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ks := make([]string, 0, len(m))
|
||||
for k := range m {
|
||||
ks = append(ks, k)
|
||||
}
|
||||
sort.Strings(ks)
|
||||
|
||||
x := Callback{
|
||||
Extensions: make(map[string]any),
|
||||
m: make(map[string]*PathItem, len(m)),
|
||||
}
|
||||
|
||||
for _, k := range ks {
|
||||
v := m[k]
|
||||
if strings.HasPrefix(k, "x-") {
|
||||
x.Extensions[k] = v
|
||||
continue
|
||||
}
|
||||
|
||||
if k == originKey {
|
||||
var data []byte
|
||||
if data, err = json.Marshal(v); err != nil {
|
||||
return
|
||||
}
|
||||
if err = json.Unmarshal(data, &x.Origin); err != nil {
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
var data []byte
|
||||
if data, err = json.Marshal(v); err != nil {
|
||||
return
|
||||
}
|
||||
var vv PathItem
|
||||
if err = vv.UnmarshalJSON(data); err != nil {
|
||||
return
|
||||
}
|
||||
x.m[k] = &vv
|
||||
}
|
||||
*callback = x
|
||||
return
|
||||
}
|
||||
|
||||
// NewPathsWithCapacity builds a paths object of the given capacity.
|
||||
func NewPathsWithCapacity(cap int) *Paths {
|
||||
if cap == 0 {
|
||||
return &Paths{m: make(map[string]*PathItem)}
|
||||
}
|
||||
return &Paths{m: make(map[string]*PathItem, cap)}
|
||||
}
|
||||
|
||||
// Value returns the paths for key or nil
|
||||
func (paths *Paths) Value(key string) *PathItem {
|
||||
if paths.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
return paths.m[key]
|
||||
}
|
||||
|
||||
// Set adds or replaces key 'key' of 'paths' with 'value'.
|
||||
// Note: 'paths' MUST be non-nil
|
||||
func (paths *Paths) Set(key string, value *PathItem) {
|
||||
if paths.m == nil {
|
||||
paths.m = make(map[string]*PathItem)
|
||||
}
|
||||
paths.m[key] = value
|
||||
}
|
||||
|
||||
// Len returns the amount of keys in paths excluding paths.Extensions.
|
||||
func (paths *Paths) Len() int {
|
||||
if paths == nil || paths.m == nil {
|
||||
return 0
|
||||
}
|
||||
return len(paths.m)
|
||||
}
|
||||
|
||||
// Delete removes the entry associated with key 'key' from 'paths'.
|
||||
func (paths *Paths) Delete(key string) {
|
||||
if paths != nil && paths.m != nil {
|
||||
delete(paths.m, key)
|
||||
}
|
||||
}
|
||||
|
||||
// Map returns paths as a 'map'.
|
||||
// Note: iteration on Go maps is not ordered.
|
||||
func (paths *Paths) Map() (m map[string]*PathItem) {
|
||||
if paths == nil || len(paths.m) == 0 {
|
||||
return make(map[string]*PathItem)
|
||||
}
|
||||
m = make(map[string]*PathItem, len(paths.m))
|
||||
for k, v := range paths.m {
|
||||
m[k] = v
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*Paths)(nil)
|
||||
|
||||
// JSONLookup implements https://github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (paths Paths) JSONLookup(token string) (any, error) {
|
||||
if v := paths.Value(token); v == nil {
|
||||
vv, _, err := jsonpointer.GetForToken(paths.Extensions, token)
|
||||
return vv, err
|
||||
} else if ref := v.Ref; ref != "" {
|
||||
return &Ref{Ref: ref}, nil
|
||||
} else {
|
||||
var vv *PathItem = v
|
||||
return vv, nil
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of Paths.
|
||||
func (paths *Paths) MarshalYAML() (any, error) {
|
||||
if paths == nil {
|
||||
return nil, nil
|
||||
}
|
||||
m := make(map[string]any, paths.Len()+len(paths.Extensions))
|
||||
for k, v := range paths.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
for k, v := range paths.Map() {
|
||||
m[k] = v
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of Paths.
|
||||
func (paths *Paths) MarshalJSON() ([]byte, error) {
|
||||
pathsYaml, err := paths.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(pathsYaml)
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Paths to a copy of data.
|
||||
func (paths *Paths) UnmarshalJSON(data []byte) (err error) {
|
||||
var m map[string]any
|
||||
if err = json.Unmarshal(data, &m); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ks := make([]string, 0, len(m))
|
||||
for k := range m {
|
||||
ks = append(ks, k)
|
||||
}
|
||||
sort.Strings(ks)
|
||||
|
||||
x := Paths{
|
||||
Extensions: make(map[string]any),
|
||||
m: make(map[string]*PathItem, len(m)),
|
||||
}
|
||||
|
||||
for _, k := range ks {
|
||||
v := m[k]
|
||||
if strings.HasPrefix(k, "x-") {
|
||||
x.Extensions[k] = v
|
||||
continue
|
||||
}
|
||||
|
||||
if k == originKey {
|
||||
var data []byte
|
||||
if data, err = json.Marshal(v); err != nil {
|
||||
return
|
||||
}
|
||||
if err = json.Unmarshal(data, &x.Origin); err != nil {
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
var data []byte
|
||||
if data, err = json.Marshal(v); err != nil {
|
||||
return
|
||||
}
|
||||
var vv PathItem
|
||||
if err = vv.UnmarshalJSON(data); err != nil {
|
||||
return
|
||||
}
|
||||
x.m[k] = &vv
|
||||
}
|
||||
*paths = x
|
||||
return
|
||||
}
|
34
vendor/github.com/getkin/kin-openapi/openapi3/marsh.go
generated
vendored
Normal file
34
vendor/github.com/getkin/kin-openapi/openapi3/marsh.go
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
package openapi3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/oasdiff/yaml"
|
||||
)
|
||||
|
||||
func unmarshalError(jsonUnmarshalErr error) error {
|
||||
if before, after, found := strings.Cut(jsonUnmarshalErr.Error(), "Bis"); found && before != "" && after != "" {
|
||||
before = strings.ReplaceAll(before, " Go struct ", " ")
|
||||
return fmt.Errorf("%s%s", before, strings.ReplaceAll(after, "Bis", ""))
|
||||
}
|
||||
return jsonUnmarshalErr
|
||||
}
|
||||
|
||||
func unmarshal(data []byte, v any, includeOrigin bool) error {
|
||||
var jsonErr, yamlErr error
|
||||
|
||||
// See https://github.com/getkin/kin-openapi/issues/680
|
||||
if jsonErr = json.Unmarshal(data, v); jsonErr == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalStrict(data, v) TODO: investigate how ymlv3 handles duplicate map keys
|
||||
if yamlErr = yaml.UnmarshalWithOrigin(data, v, includeOrigin); yamlErr == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// If both unmarshaling attempts fail, return a new error that includes both errors
|
||||
return fmt.Errorf("failed to unmarshal data: json error: %v, yaml error: %v", jsonErr, yamlErr)
|
||||
}
|
117
vendor/github.com/getkin/kin-openapi/openapi3/media_type.go
generated
vendored
117
vendor/github.com/getkin/kin-openapi/openapi3/media_type.go
generated
vendored
@ -2,17 +2,22 @@ package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
)
|
||||
|
||||
// MediaType is specified by OpenAPI/Swagger 3.0 standard.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#media-type-object
|
||||
type MediaType struct {
|
||||
ExtensionProps
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
Schema *SchemaRef `json:"schema,omitempty" yaml:"schema,omitempty"`
|
||||
Example interface{} `json:"example,omitempty" yaml:"example,omitempty"`
|
||||
Example any `json:"example,omitempty" yaml:"example,omitempty"`
|
||||
Examples Examples `json:"examples,omitempty" yaml:"examples,omitempty"`
|
||||
Encoding map[string]*Encoding `json:"encoding,omitempty" yaml:"encoding,omitempty"`
|
||||
}
|
||||
@ -37,7 +42,7 @@ func (mediaType *MediaType) WithSchemaRef(schema *SchemaRef) *MediaType {
|
||||
return mediaType
|
||||
}
|
||||
|
||||
func (mediaType *MediaType) WithExample(name string, value interface{}) *MediaType {
|
||||
func (mediaType *MediaType) WithExample(name string, value any) *MediaType {
|
||||
example := mediaType.Examples
|
||||
if example == nil {
|
||||
example = make(map[string]*ExampleRef)
|
||||
@ -59,27 +64,103 @@ func (mediaType *MediaType) WithEncoding(name string, enc *Encoding) *MediaType
|
||||
return mediaType
|
||||
}
|
||||
|
||||
func (mediaType *MediaType) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(mediaType)
|
||||
// MarshalJSON returns the JSON encoding of MediaType.
|
||||
func (mediaType MediaType) MarshalJSON() ([]byte, error) {
|
||||
x, err := mediaType.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of MediaType.
|
||||
func (mediaType MediaType) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 4+len(mediaType.Extensions))
|
||||
for k, v := range mediaType.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := mediaType.Schema; x != nil {
|
||||
m["schema"] = x
|
||||
}
|
||||
if x := mediaType.Example; x != nil {
|
||||
m["example"] = x
|
||||
}
|
||||
if x := mediaType.Examples; len(x) != 0 {
|
||||
m["examples"] = x
|
||||
}
|
||||
if x := mediaType.Encoding; len(x) != 0 {
|
||||
m["encoding"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets MediaType to a copy of data.
|
||||
func (mediaType *MediaType) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, mediaType)
|
||||
}
|
||||
|
||||
func (value *MediaType) Validate(ctx context.Context) error {
|
||||
if value == nil {
|
||||
return nil
|
||||
type MediaTypeBis MediaType
|
||||
var x MediaTypeBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
if schema := value.Schema; schema != nil {
|
||||
if err := schema.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "schema")
|
||||
delete(x.Extensions, "example")
|
||||
delete(x.Extensions, "examples")
|
||||
delete(x.Extensions, "encoding")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*mediaType = MediaType(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mediaType MediaType) JSONLookup(token string) (interface{}, error) {
|
||||
// Validate returns an error if MediaType does not comply with the OpenAPI spec.
|
||||
func (mediaType *MediaType) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if mediaType == nil {
|
||||
return nil
|
||||
}
|
||||
if schema := mediaType.Schema; schema != nil {
|
||||
if err := schema.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if mediaType.Example != nil && mediaType.Examples != nil {
|
||||
return errors.New("example and examples are mutually exclusive")
|
||||
}
|
||||
|
||||
if vo := getValidationOptions(ctx); !vo.examplesValidationDisabled {
|
||||
if example := mediaType.Example; example != nil {
|
||||
if err := validateExampleValue(ctx, example, schema.Value); err != nil {
|
||||
return fmt.Errorf("invalid example: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if examples := mediaType.Examples; examples != nil {
|
||||
names := make([]string, 0, len(examples))
|
||||
for name := range examples {
|
||||
names = append(names, name)
|
||||
}
|
||||
sort.Strings(names)
|
||||
for _, k := range names {
|
||||
v := examples[k]
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return fmt.Errorf("example %s: %w", k, err)
|
||||
}
|
||||
if err := validateExampleValue(ctx, v.Value.Value, schema.Value); err != nil {
|
||||
return fmt.Errorf("example %s: %w", k, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return validateExtensions(ctx, mediaType.Extensions)
|
||||
}
|
||||
|
||||
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (mediaType MediaType) JSONLookup(token string) (any, error) {
|
||||
switch token {
|
||||
case "schema":
|
||||
if mediaType.Schema != nil {
|
||||
@ -95,6 +176,6 @@ func (mediaType MediaType) JSONLookup(token string) (interface{}, error) {
|
||||
case "encoding":
|
||||
return mediaType.Encoding, nil
|
||||
}
|
||||
v, _, err := jsonpointer.GetForToken(mediaType.ExtensionProps, token)
|
||||
v, _, err := jsonpointer.GetForToken(mediaType.Extensions, token)
|
||||
return v, err
|
||||
}
|
||||
|
194
vendor/github.com/getkin/kin-openapi/openapi3/openapi3.go
generated
vendored
194
vendor/github.com/getkin/kin-openapi/openapi3/openapi3.go
generated
vendored
@ -2,43 +2,129 @@ package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
)
|
||||
|
||||
// T is the root of an OpenAPI v3 document
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#openapi-object
|
||||
type T struct {
|
||||
ExtensionProps
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
|
||||
OpenAPI string `json:"openapi" yaml:"openapi"` // Required
|
||||
Components Components `json:"components,omitempty" yaml:"components,omitempty"`
|
||||
Components *Components `json:"components,omitempty" yaml:"components,omitempty"`
|
||||
Info *Info `json:"info" yaml:"info"` // Required
|
||||
Paths Paths `json:"paths" yaml:"paths"` // Required
|
||||
Paths *Paths `json:"paths" yaml:"paths"` // Required
|
||||
Security SecurityRequirements `json:"security,omitempty" yaml:"security,omitempty"`
|
||||
Servers Servers `json:"servers,omitempty" yaml:"servers,omitempty"`
|
||||
Tags Tags `json:"tags,omitempty" yaml:"tags,omitempty"`
|
||||
ExternalDocs *ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
|
||||
|
||||
visited visitedComponent
|
||||
url *url.URL
|
||||
}
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*T)(nil)
|
||||
|
||||
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (doc *T) JSONLookup(token string) (any, error) {
|
||||
switch token {
|
||||
case "openapi":
|
||||
return doc.OpenAPI, nil
|
||||
case "components":
|
||||
return doc.Components, nil
|
||||
case "info":
|
||||
return doc.Info, nil
|
||||
case "paths":
|
||||
return doc.Paths, nil
|
||||
case "security":
|
||||
return doc.Security, nil
|
||||
case "servers":
|
||||
return doc.Servers, nil
|
||||
case "tags":
|
||||
return doc.Tags, nil
|
||||
case "externalDocs":
|
||||
return doc.ExternalDocs, nil
|
||||
}
|
||||
|
||||
v, _, err := jsonpointer.GetForToken(doc.Extensions, token)
|
||||
return v, err
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of T.
|
||||
func (doc *T) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(doc)
|
||||
x, err := doc.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of T.
|
||||
func (doc *T) MarshalYAML() (any, error) {
|
||||
if doc == nil {
|
||||
return nil, nil
|
||||
}
|
||||
m := make(map[string]any, 4+len(doc.Extensions))
|
||||
for k, v := range doc.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
m["openapi"] = doc.OpenAPI
|
||||
if x := doc.Components; x != nil {
|
||||
m["components"] = x
|
||||
}
|
||||
m["info"] = doc.Info
|
||||
m["paths"] = doc.Paths
|
||||
if x := doc.Security; len(x) != 0 {
|
||||
m["security"] = x
|
||||
}
|
||||
if x := doc.Servers; len(x) != 0 {
|
||||
m["servers"] = x
|
||||
}
|
||||
if x := doc.Tags; len(x) != 0 {
|
||||
m["tags"] = x
|
||||
}
|
||||
if x := doc.ExternalDocs; x != nil {
|
||||
m["externalDocs"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets T to a copy of data.
|
||||
func (doc *T) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, doc)
|
||||
type TBis T
|
||||
var x TBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, "openapi")
|
||||
delete(x.Extensions, "components")
|
||||
delete(x.Extensions, "info")
|
||||
delete(x.Extensions, "paths")
|
||||
delete(x.Extensions, "security")
|
||||
delete(x.Extensions, "servers")
|
||||
delete(x.Extensions, "tags")
|
||||
delete(x.Extensions, "externalDocs")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*doc = T(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (doc *T) AddOperation(path string, method string, operation *Operation) {
|
||||
paths := doc.Paths
|
||||
if paths == nil {
|
||||
paths = make(Paths)
|
||||
doc.Paths = paths
|
||||
if doc.Paths == nil {
|
||||
doc.Paths = NewPaths()
|
||||
}
|
||||
pathItem := paths[path]
|
||||
pathItem := doc.Paths.Value(path)
|
||||
if pathItem == nil {
|
||||
pathItem = &PathItem{}
|
||||
paths[path] = pathItem
|
||||
doc.Paths.Set(path, pathItem)
|
||||
}
|
||||
pathItem.SetOperation(method, operation)
|
||||
}
|
||||
@ -47,59 +133,73 @@ func (doc *T) AddServer(server *Server) {
|
||||
doc.Servers = append(doc.Servers, server)
|
||||
}
|
||||
|
||||
func (value *T) Validate(ctx context.Context) error {
|
||||
if value.OpenAPI == "" {
|
||||
func (doc *T) AddServers(servers ...*Server) {
|
||||
doc.Servers = append(doc.Servers, servers...)
|
||||
}
|
||||
|
||||
// Validate returns an error if T does not comply with the OpenAPI spec.
|
||||
// Validations Options can be provided to modify the validation behavior.
|
||||
func (doc *T) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if doc.OpenAPI == "" {
|
||||
return errors.New("value of openapi must be a non-empty string")
|
||||
}
|
||||
|
||||
// NOTE: only mention info/components/paths/... key in this func's errors.
|
||||
var wrap func(error) error
|
||||
|
||||
{
|
||||
wrap := func(e error) error { return fmt.Errorf("invalid components: %v", e) }
|
||||
if err := value.Components.Validate(ctx); err != nil {
|
||||
wrap = func(e error) error { return fmt.Errorf("invalid components: %w", e) }
|
||||
if v := doc.Components; v != nil {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
wrap := func(e error) error { return fmt.Errorf("invalid info: %v", e) }
|
||||
if v := value.Info; v != nil {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return wrap(err)
|
||||
}
|
||||
} else {
|
||||
return wrap(errors.New("must be an object"))
|
||||
wrap = func(e error) error { return fmt.Errorf("invalid info: %w", e) }
|
||||
if v := doc.Info; v != nil {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return wrap(err)
|
||||
}
|
||||
} else {
|
||||
return wrap(errors.New("must be an object"))
|
||||
}
|
||||
|
||||
wrap = func(e error) error { return fmt.Errorf("invalid paths: %w", e) }
|
||||
if v := doc.Paths; v != nil {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return wrap(err)
|
||||
}
|
||||
} else {
|
||||
return wrap(errors.New("must be an object"))
|
||||
}
|
||||
|
||||
wrap = func(e error) error { return fmt.Errorf("invalid security: %w", e) }
|
||||
if v := doc.Security; v != nil {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
wrap := func(e error) error { return fmt.Errorf("invalid paths: %v", e) }
|
||||
if v := value.Paths; v != nil {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return wrap(err)
|
||||
}
|
||||
} else {
|
||||
return wrap(errors.New("must be an object"))
|
||||
wrap = func(e error) error { return fmt.Errorf("invalid servers: %w", e) }
|
||||
if v := doc.Servers; v != nil {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
wrap := func(e error) error { return fmt.Errorf("invalid security: %v", e) }
|
||||
if v := value.Security; v != nil {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return wrap(err)
|
||||
}
|
||||
wrap = func(e error) error { return fmt.Errorf("invalid tags: %w", e) }
|
||||
if v := doc.Tags; v != nil {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
wrap := func(e error) error { return fmt.Errorf("invalid servers: %v", e) }
|
||||
if v := value.Servers; v != nil {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return wrap(err)
|
||||
}
|
||||
wrap = func(e error) error { return fmt.Errorf("invalid external docs: %w", e) }
|
||||
if v := doc.ExternalDocs; v != nil {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return validateExtensions(ctx, doc.Extensions)
|
||||
}
|
||||
|
130
vendor/github.com/getkin/kin-openapi/openapi3/operation.go
generated
vendored
130
vendor/github.com/getkin/kin-openapi/openapi3/operation.go
generated
vendored
@ -2,16 +2,19 @@ package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
)
|
||||
|
||||
// Operation represents "operation" specified by" OpenAPI/Swagger 3.0 standard.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object
|
||||
type Operation struct {
|
||||
ExtensionProps
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
// Optional tags for documentation.
|
||||
Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"`
|
||||
@ -32,7 +35,7 @@ type Operation struct {
|
||||
RequestBody *RequestBodyRef `json:"requestBody,omitempty" yaml:"requestBody,omitempty"`
|
||||
|
||||
// Responses.
|
||||
Responses Responses `json:"responses" yaml:"responses"` // Required
|
||||
Responses *Responses `json:"responses" yaml:"responses"` // Required
|
||||
|
||||
// Optional callbacks
|
||||
Callbacks Callbacks `json:"callbacks,omitempty" yaml:"callbacks,omitempty"`
|
||||
@ -54,15 +57,88 @@ func NewOperation() *Operation {
|
||||
return &Operation{}
|
||||
}
|
||||
|
||||
func (operation *Operation) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(operation)
|
||||
// MarshalJSON returns the JSON encoding of Operation.
|
||||
func (operation Operation) MarshalJSON() ([]byte, error) {
|
||||
x, err := operation.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of Operation.
|
||||
func (operation Operation) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 12+len(operation.Extensions))
|
||||
for k, v := range operation.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := operation.Tags; len(x) != 0 {
|
||||
m["tags"] = x
|
||||
}
|
||||
if x := operation.Summary; x != "" {
|
||||
m["summary"] = x
|
||||
}
|
||||
if x := operation.Description; x != "" {
|
||||
m["description"] = x
|
||||
}
|
||||
if x := operation.OperationID; x != "" {
|
||||
m["operationId"] = x
|
||||
}
|
||||
if x := operation.Parameters; len(x) != 0 {
|
||||
m["parameters"] = x
|
||||
}
|
||||
if x := operation.RequestBody; x != nil {
|
||||
m["requestBody"] = x
|
||||
}
|
||||
m["responses"] = operation.Responses
|
||||
if x := operation.Callbacks; len(x) != 0 {
|
||||
m["callbacks"] = x
|
||||
}
|
||||
if x := operation.Deprecated; x {
|
||||
m["deprecated"] = x
|
||||
}
|
||||
if x := operation.Security; x != nil {
|
||||
m["security"] = x
|
||||
}
|
||||
if x := operation.Servers; x != nil {
|
||||
m["servers"] = x
|
||||
}
|
||||
if x := operation.ExternalDocs; x != nil {
|
||||
m["externalDocs"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Operation to a copy of data.
|
||||
func (operation *Operation) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, operation)
|
||||
type OperationBis Operation
|
||||
var x OperationBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "tags")
|
||||
delete(x.Extensions, "summary")
|
||||
delete(x.Extensions, "description")
|
||||
delete(x.Extensions, "operationId")
|
||||
delete(x.Extensions, "parameters")
|
||||
delete(x.Extensions, "requestBody")
|
||||
delete(x.Extensions, "responses")
|
||||
delete(x.Extensions, "callbacks")
|
||||
delete(x.Extensions, "deprecated")
|
||||
delete(x.Extensions, "security")
|
||||
delete(x.Extensions, "servers")
|
||||
delete(x.Extensions, "externalDocs")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*operation = Operation(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (operation Operation) JSONLookup(token string) (interface{}, error) {
|
||||
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (operation Operation) JSONLookup(token string) (any, error) {
|
||||
switch token {
|
||||
case "requestBody":
|
||||
if operation.RequestBody != nil {
|
||||
@ -95,48 +171,54 @@ func (operation Operation) JSONLookup(token string) (interface{}, error) {
|
||||
return operation.ExternalDocs, nil
|
||||
}
|
||||
|
||||
v, _, err := jsonpointer.GetForToken(operation.ExtensionProps, token)
|
||||
v, _, err := jsonpointer.GetForToken(operation.Extensions, token)
|
||||
return v, err
|
||||
}
|
||||
|
||||
func (operation *Operation) AddParameter(p *Parameter) {
|
||||
operation.Parameters = append(operation.Parameters, &ParameterRef{
|
||||
Value: p,
|
||||
})
|
||||
operation.Parameters = append(operation.Parameters, &ParameterRef{Value: p})
|
||||
}
|
||||
|
||||
func (operation *Operation) AddResponse(status int, response *Response) {
|
||||
responses := operation.Responses
|
||||
if responses == nil {
|
||||
responses = NewResponses()
|
||||
operation.Responses = responses
|
||||
}
|
||||
code := "default"
|
||||
if status != 0 {
|
||||
if 0 < status && status < 1000 {
|
||||
code = strconv.FormatInt(int64(status), 10)
|
||||
}
|
||||
responses[code] = &ResponseRef{
|
||||
Value: response,
|
||||
if operation.Responses == nil {
|
||||
operation.Responses = NewResponses()
|
||||
}
|
||||
operation.Responses.Set(code, &ResponseRef{Value: response})
|
||||
}
|
||||
|
||||
func (value *Operation) Validate(ctx context.Context) error {
|
||||
if v := value.Parameters; v != nil {
|
||||
// Validate returns an error if Operation does not comply with the OpenAPI spec.
|
||||
func (operation *Operation) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if v := operation.Parameters; v != nil {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if v := value.RequestBody; v != nil {
|
||||
|
||||
if v := operation.RequestBody; v != nil {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if v := value.Responses; v != nil {
|
||||
|
||||
if v := operation.Responses; v != nil {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return errors.New("value of responses must be an object")
|
||||
}
|
||||
return nil
|
||||
|
||||
if v := operation.ExternalDocs; v != nil {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return fmt.Errorf("invalid external docs: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return validateExtensions(ctx, operation.Extensions)
|
||||
}
|
||||
|
17
vendor/github.com/getkin/kin-openapi/openapi3/origin.go
generated
vendored
Normal file
17
vendor/github.com/getkin/kin-openapi/openapi3/origin.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
package openapi3
|
||||
|
||||
const originKey = "__origin__"
|
||||
|
||||
// Origin contains the origin of a collection.
|
||||
// Key is the location of the collection itself.
|
||||
// Fields is a map of the location of each field in the collection.
|
||||
type Origin struct {
|
||||
Key *Location `json:"key,omitempty" yaml:"key,omitempty"`
|
||||
Fields map[string]Location `json:"fields,omitempty" yaml:"fields,omitempty"`
|
||||
}
|
||||
|
||||
// Location is a struct that contains the location of a field.
|
||||
type Location struct {
|
||||
Line int `json:"line,omitempty" yaml:"line,omitempty"`
|
||||
Column int `json:"column,omitempty" yaml:"column,omitempty"`
|
||||
}
|
341
vendor/github.com/getkin/kin-openapi/openapi3/parameter.go
generated
vendored
341
vendor/github.com/getkin/kin-openapi/openapi3/parameter.go
generated
vendored
@ -2,47 +2,31 @@ package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
)
|
||||
|
||||
type ParametersMap map[string]*ParameterRef
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*ParametersMap)(nil)
|
||||
|
||||
func (p ParametersMap) JSONLookup(token string) (interface{}, error) {
|
||||
ref, ok := p[token]
|
||||
if ref == nil || ok == false {
|
||||
return nil, fmt.Errorf("object has no field %q", token)
|
||||
}
|
||||
|
||||
if ref.Ref != "" {
|
||||
return &Ref{Ref: ref.Ref}, nil
|
||||
}
|
||||
return ref.Value, nil
|
||||
}
|
||||
|
||||
// Parameters is specified by OpenAPI/Swagger 3.0 standard.
|
||||
type Parameters []*ParameterRef
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*Parameters)(nil)
|
||||
|
||||
func (p Parameters) JSONLookup(token string) (interface{}, error) {
|
||||
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (p Parameters) JSONLookup(token string) (any, error) {
|
||||
index, err := strconv.Atoi(token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if index < 0 || index >= len(p) {
|
||||
return nil, fmt.Errorf("index %d out of bounds of array of length %d", index, len(p))
|
||||
}
|
||||
|
||||
ref := p[index]
|
||||
|
||||
if ref != nil && ref.Ref != "" {
|
||||
return &Ref{Ref: ref.Ref}, nil
|
||||
}
|
||||
@ -64,10 +48,13 @@ func (parameters Parameters) GetByInAndName(in string, name string) *Parameter {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (value Parameters) Validate(ctx context.Context) error {
|
||||
// Validate returns an error if Parameters does not comply with the OpenAPI spec.
|
||||
func (parameters Parameters) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
dupes := make(map[string]struct{})
|
||||
for _, item := range value {
|
||||
if v := item.Value; v != nil {
|
||||
for _, parameterRef := range parameters {
|
||||
if v := parameterRef.Value; v != nil {
|
||||
key := v.In + ":" + v.Name
|
||||
if _, ok := dupes[key]; ok {
|
||||
return fmt.Errorf("more than one %q parameter has name %q", v.In, v.Name)
|
||||
@ -75,7 +62,7 @@ func (value Parameters) Validate(ctx context.Context) error {
|
||||
dupes[key] = struct{}{}
|
||||
}
|
||||
|
||||
if err := item.Validate(ctx); err != nil {
|
||||
if err := parameterRef.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -83,22 +70,24 @@ func (value Parameters) Validate(ctx context.Context) error {
|
||||
}
|
||||
|
||||
// Parameter is specified by OpenAPI/Swagger 3.0 standard.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#parameterObject
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#parameter-object
|
||||
type Parameter struct {
|
||||
ExtensionProps
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
In string `json:"in,omitempty" yaml:"in,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
Style string `json:"style,omitempty" yaml:"style,omitempty"`
|
||||
Explode *bool `json:"explode,omitempty" yaml:"explode,omitempty"`
|
||||
AllowEmptyValue bool `json:"allowEmptyValue,omitempty" yaml:"allowEmptyValue,omitempty"`
|
||||
AllowReserved bool `json:"allowReserved,omitempty" yaml:"allowReserved,omitempty"`
|
||||
Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"`
|
||||
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
|
||||
Schema *SchemaRef `json:"schema,omitempty" yaml:"schema,omitempty"`
|
||||
Example interface{} `json:"example,omitempty" yaml:"example,omitempty"`
|
||||
Examples Examples `json:"examples,omitempty" yaml:"examples,omitempty"`
|
||||
Content Content `json:"content,omitempty" yaml:"content,omitempty"`
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
In string `json:"in,omitempty" yaml:"in,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
Style string `json:"style,omitempty" yaml:"style,omitempty"`
|
||||
Explode *bool `json:"explode,omitempty" yaml:"explode,omitempty"`
|
||||
AllowEmptyValue bool `json:"allowEmptyValue,omitempty" yaml:"allowEmptyValue,omitempty"`
|
||||
AllowReserved bool `json:"allowReserved,omitempty" yaml:"allowReserved,omitempty"`
|
||||
Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"`
|
||||
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
|
||||
Schema *SchemaRef `json:"schema,omitempty" yaml:"schema,omitempty"`
|
||||
Example any `json:"example,omitempty" yaml:"example,omitempty"`
|
||||
Examples Examples `json:"examples,omitempty" yaml:"examples,omitempty"`
|
||||
Content Content `json:"content,omitempty" yaml:"content,omitempty"`
|
||||
}
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*Parameter)(nil)
|
||||
@ -160,50 +149,133 @@ func (parameter *Parameter) WithSchema(value *Schema) *Parameter {
|
||||
return parameter
|
||||
}
|
||||
|
||||
func (parameter *Parameter) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(parameter)
|
||||
// MarshalJSON returns the JSON encoding of Parameter.
|
||||
func (parameter Parameter) MarshalJSON() ([]byte, error) {
|
||||
x, err := parameter.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
func (parameter *Parameter) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, parameter)
|
||||
}
|
||||
|
||||
func (value Parameter) JSONLookup(token string) (interface{}, error) {
|
||||
switch token {
|
||||
case "schema":
|
||||
if value.Schema != nil {
|
||||
if value.Schema.Ref != "" {
|
||||
return &Ref{Ref: value.Schema.Ref}, nil
|
||||
}
|
||||
return value.Schema.Value, nil
|
||||
}
|
||||
case "name":
|
||||
return value.Name, nil
|
||||
case "in":
|
||||
return value.In, nil
|
||||
case "description":
|
||||
return value.Description, nil
|
||||
case "style":
|
||||
return value.Style, nil
|
||||
case "explode":
|
||||
return value.Explode, nil
|
||||
case "allowEmptyValue":
|
||||
return value.AllowEmptyValue, nil
|
||||
case "allowReserved":
|
||||
return value.AllowReserved, nil
|
||||
case "deprecated":
|
||||
return value.Deprecated, nil
|
||||
case "required":
|
||||
return value.Required, nil
|
||||
case "example":
|
||||
return value.Example, nil
|
||||
case "examples":
|
||||
return value.Examples, nil
|
||||
case "content":
|
||||
return value.Content, nil
|
||||
// MarshalYAML returns the YAML encoding of Parameter.
|
||||
func (parameter Parameter) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 13+len(parameter.Extensions))
|
||||
for k, v := range parameter.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
|
||||
v, _, err := jsonpointer.GetForToken(value.ExtensionProps, token)
|
||||
if x := parameter.Name; x != "" {
|
||||
m["name"] = x
|
||||
}
|
||||
if x := parameter.In; x != "" {
|
||||
m["in"] = x
|
||||
}
|
||||
if x := parameter.Description; x != "" {
|
||||
m["description"] = x
|
||||
}
|
||||
if x := parameter.Style; x != "" {
|
||||
m["style"] = x
|
||||
}
|
||||
if x := parameter.Explode; x != nil {
|
||||
m["explode"] = x
|
||||
}
|
||||
if x := parameter.AllowEmptyValue; x {
|
||||
m["allowEmptyValue"] = x
|
||||
}
|
||||
if x := parameter.AllowReserved; x {
|
||||
m["allowReserved"] = x
|
||||
}
|
||||
if x := parameter.Deprecated; x {
|
||||
m["deprecated"] = x
|
||||
}
|
||||
if x := parameter.Required; x {
|
||||
m["required"] = x
|
||||
}
|
||||
if x := parameter.Schema; x != nil {
|
||||
m["schema"] = x
|
||||
}
|
||||
if x := parameter.Example; x != nil {
|
||||
m["example"] = x
|
||||
}
|
||||
if x := parameter.Examples; len(x) != 0 {
|
||||
m["examples"] = x
|
||||
}
|
||||
if x := parameter.Content; len(x) != 0 {
|
||||
m["content"] = x
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Parameter to a copy of data.
|
||||
func (parameter *Parameter) UnmarshalJSON(data []byte) error {
|
||||
type ParameterBis Parameter
|
||||
var x ParameterBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "name")
|
||||
delete(x.Extensions, "in")
|
||||
delete(x.Extensions, "description")
|
||||
delete(x.Extensions, "style")
|
||||
delete(x.Extensions, "explode")
|
||||
delete(x.Extensions, "allowEmptyValue")
|
||||
delete(x.Extensions, "allowReserved")
|
||||
delete(x.Extensions, "deprecated")
|
||||
delete(x.Extensions, "required")
|
||||
delete(x.Extensions, "schema")
|
||||
delete(x.Extensions, "example")
|
||||
delete(x.Extensions, "examples")
|
||||
delete(x.Extensions, "content")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
|
||||
*parameter = Parameter(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (parameter Parameter) JSONLookup(token string) (any, error) {
|
||||
switch token {
|
||||
case "schema":
|
||||
if parameter.Schema != nil {
|
||||
if parameter.Schema.Ref != "" {
|
||||
return &Ref{Ref: parameter.Schema.Ref}, nil
|
||||
}
|
||||
return parameter.Schema.Value, nil
|
||||
}
|
||||
case "name":
|
||||
return parameter.Name, nil
|
||||
case "in":
|
||||
return parameter.In, nil
|
||||
case "description":
|
||||
return parameter.Description, nil
|
||||
case "style":
|
||||
return parameter.Style, nil
|
||||
case "explode":
|
||||
return parameter.Explode, nil
|
||||
case "allowEmptyValue":
|
||||
return parameter.AllowEmptyValue, nil
|
||||
case "allowReserved":
|
||||
return parameter.AllowReserved, nil
|
||||
case "deprecated":
|
||||
return parameter.Deprecated, nil
|
||||
case "required":
|
||||
return parameter.Required, nil
|
||||
case "example":
|
||||
return parameter.Example, nil
|
||||
case "examples":
|
||||
return parameter.Examples, nil
|
||||
case "content":
|
||||
return parameter.Content, nil
|
||||
}
|
||||
|
||||
v, _, err := jsonpointer.GetForToken(parameter.Extensions, token)
|
||||
return v, err
|
||||
}
|
||||
|
||||
@ -237,11 +309,14 @@ func (parameter *Parameter) SerializationMethod() (*SerializationMethod, error)
|
||||
}
|
||||
}
|
||||
|
||||
func (value *Parameter) Validate(ctx context.Context) error {
|
||||
if value.Name == "" {
|
||||
// Validate returns an error if Parameter does not comply with the OpenAPI spec.
|
||||
func (parameter *Parameter) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if parameter.Name == "" {
|
||||
return errors.New("parameter name can't be blank")
|
||||
}
|
||||
in := value.In
|
||||
in := parameter.In
|
||||
switch in {
|
||||
case
|
||||
ParameterInPath,
|
||||
@ -249,57 +324,101 @@ func (value *Parameter) Validate(ctx context.Context) error {
|
||||
ParameterInHeader,
|
||||
ParameterInCookie:
|
||||
default:
|
||||
return fmt.Errorf("parameter can't have 'in' value %q", value.In)
|
||||
return fmt.Errorf("parameter can't have 'in' value %q", parameter.In)
|
||||
}
|
||||
|
||||
if in == ParameterInPath && !parameter.Required {
|
||||
return fmt.Errorf("path parameter %q must be required", parameter.Name)
|
||||
}
|
||||
|
||||
// Validate a parameter's serialization method.
|
||||
sm, err := value.SerializationMethod()
|
||||
sm, err := parameter.SerializationMethod()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var smSupported bool
|
||||
switch {
|
||||
case value.In == ParameterInPath && sm.Style == SerializationSimple && !sm.Explode,
|
||||
value.In == ParameterInPath && sm.Style == SerializationSimple && sm.Explode,
|
||||
value.In == ParameterInPath && sm.Style == SerializationLabel && !sm.Explode,
|
||||
value.In == ParameterInPath && sm.Style == SerializationLabel && sm.Explode,
|
||||
value.In == ParameterInPath && sm.Style == SerializationMatrix && !sm.Explode,
|
||||
value.In == ParameterInPath && sm.Style == SerializationMatrix && sm.Explode,
|
||||
case parameter.In == ParameterInPath && sm.Style == SerializationSimple && !sm.Explode,
|
||||
parameter.In == ParameterInPath && sm.Style == SerializationSimple && sm.Explode,
|
||||
parameter.In == ParameterInPath && sm.Style == SerializationLabel && !sm.Explode,
|
||||
parameter.In == ParameterInPath && sm.Style == SerializationLabel && sm.Explode,
|
||||
parameter.In == ParameterInPath && sm.Style == SerializationMatrix && !sm.Explode,
|
||||
parameter.In == ParameterInPath && sm.Style == SerializationMatrix && sm.Explode,
|
||||
|
||||
value.In == ParameterInQuery && sm.Style == SerializationForm && sm.Explode,
|
||||
value.In == ParameterInQuery && sm.Style == SerializationForm && !sm.Explode,
|
||||
value.In == ParameterInQuery && sm.Style == SerializationSpaceDelimited && sm.Explode,
|
||||
value.In == ParameterInQuery && sm.Style == SerializationSpaceDelimited && !sm.Explode,
|
||||
value.In == ParameterInQuery && sm.Style == SerializationPipeDelimited && sm.Explode,
|
||||
value.In == ParameterInQuery && sm.Style == SerializationPipeDelimited && !sm.Explode,
|
||||
value.In == ParameterInQuery && sm.Style == SerializationDeepObject && sm.Explode,
|
||||
parameter.In == ParameterInQuery && sm.Style == SerializationForm && sm.Explode,
|
||||
parameter.In == ParameterInQuery && sm.Style == SerializationForm && !sm.Explode,
|
||||
parameter.In == ParameterInQuery && sm.Style == SerializationSpaceDelimited && sm.Explode,
|
||||
parameter.In == ParameterInQuery && sm.Style == SerializationSpaceDelimited && !sm.Explode,
|
||||
parameter.In == ParameterInQuery && sm.Style == SerializationPipeDelimited && sm.Explode,
|
||||
parameter.In == ParameterInQuery && sm.Style == SerializationPipeDelimited && !sm.Explode,
|
||||
parameter.In == ParameterInQuery && sm.Style == SerializationDeepObject && sm.Explode,
|
||||
|
||||
value.In == ParameterInHeader && sm.Style == SerializationSimple && !sm.Explode,
|
||||
value.In == ParameterInHeader && sm.Style == SerializationSimple && sm.Explode,
|
||||
parameter.In == ParameterInHeader && sm.Style == SerializationSimple && !sm.Explode,
|
||||
parameter.In == ParameterInHeader && sm.Style == SerializationSimple && sm.Explode,
|
||||
|
||||
value.In == ParameterInCookie && sm.Style == SerializationForm && !sm.Explode,
|
||||
value.In == ParameterInCookie && sm.Style == SerializationForm && sm.Explode:
|
||||
parameter.In == ParameterInCookie && sm.Style == SerializationForm && !sm.Explode,
|
||||
parameter.In == ParameterInCookie && sm.Style == SerializationForm && sm.Explode:
|
||||
smSupported = true
|
||||
}
|
||||
if !smSupported {
|
||||
e := fmt.Errorf("serialization method with style=%q and explode=%v is not supported by a %s parameter", sm.Style, sm.Explode, in)
|
||||
return fmt.Errorf("parameter %q schema is invalid: %v", value.Name, e)
|
||||
return fmt.Errorf("parameter %q schema is invalid: %w", parameter.Name, e)
|
||||
}
|
||||
|
||||
if (value.Schema == nil) == (value.Content == nil) {
|
||||
if (parameter.Schema == nil) == (len(parameter.Content) == 0) {
|
||||
e := errors.New("parameter must contain exactly one of content and schema")
|
||||
return fmt.Errorf("parameter %q schema is invalid: %v", value.Name, e)
|
||||
return fmt.Errorf("parameter %q schema is invalid: %w", parameter.Name, e)
|
||||
}
|
||||
if schema := value.Schema; schema != nil {
|
||||
if err := schema.Validate(ctx); err != nil {
|
||||
return fmt.Errorf("parameter %q schema is invalid: %v", value.Name, err)
|
||||
|
||||
if content := parameter.Content; content != nil {
|
||||
e := errors.New("parameter content must only contain one entry")
|
||||
if len(content) > 1 {
|
||||
return fmt.Errorf("parameter %q content is invalid: %w", parameter.Name, e)
|
||||
}
|
||||
|
||||
if err := content.Validate(ctx); err != nil {
|
||||
return fmt.Errorf("parameter %q content is invalid: %w", parameter.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
if content := value.Content; content != nil {
|
||||
if err := content.Validate(ctx); err != nil {
|
||||
return fmt.Errorf("parameter %q content is invalid: %v", value.Name, err)
|
||||
if schema := parameter.Schema; schema != nil {
|
||||
if err := schema.Validate(ctx); err != nil {
|
||||
return fmt.Errorf("parameter %q schema is invalid: %w", parameter.Name, err)
|
||||
}
|
||||
if parameter.Example != nil && parameter.Examples != nil {
|
||||
return fmt.Errorf("parameter %q example and examples are mutually exclusive", parameter.Name)
|
||||
}
|
||||
|
||||
if vo := getValidationOptions(ctx); vo.examplesValidationDisabled {
|
||||
return nil
|
||||
}
|
||||
if example := parameter.Example; example != nil {
|
||||
if err := validateExampleValue(ctx, example, schema.Value); err != nil {
|
||||
return fmt.Errorf("invalid example: %w", err)
|
||||
}
|
||||
} else if examples := parameter.Examples; examples != nil {
|
||||
names := make([]string, 0, len(examples))
|
||||
for name := range examples {
|
||||
names = append(names, name)
|
||||
}
|
||||
sort.Strings(names)
|
||||
for _, k := range names {
|
||||
v := examples[k]
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return fmt.Errorf("%s: %w", k, err)
|
||||
}
|
||||
if err := validateExampleValue(ctx, v.Value.Value, schema.Value); err != nil {
|
||||
return fmt.Errorf("%s: %w", k, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
return validateExtensions(ctx, parameter.Extensions)
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets ParametersMap to a copy of data.
|
||||
func (parametersMap *ParametersMap) UnmarshalJSON(data []byte) (err error) {
|
||||
*parametersMap, _, err = unmarshalStringMapP[ParameterRef](data)
|
||||
return
|
||||
}
|
||||
|
144
vendor/github.com/getkin/kin-openapi/openapi3/path_item.go
generated
vendored
144
vendor/github.com/getkin/kin-openapi/openapi3/path_item.go
generated
vendored
@ -2,14 +2,18 @@ package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// PathItem is specified by OpenAPI/Swagger standard version 3.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#path-item-object
|
||||
type PathItem struct {
|
||||
ExtensionProps
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
Ref string `json:"$ref,omitempty" yaml:"$ref,omitempty"`
|
||||
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
@ -26,16 +30,99 @@ type PathItem struct {
|
||||
Parameters Parameters `json:"parameters,omitempty" yaml:"parameters,omitempty"`
|
||||
}
|
||||
|
||||
func (pathItem *PathItem) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(pathItem)
|
||||
// MarshalJSON returns the JSON encoding of PathItem.
|
||||
func (pathItem PathItem) MarshalJSON() ([]byte, error) {
|
||||
x, err := pathItem.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of PathItem.
|
||||
func (pathItem PathItem) MarshalYAML() (any, error) {
|
||||
if ref := pathItem.Ref; ref != "" {
|
||||
return Ref{Ref: ref}, nil
|
||||
}
|
||||
|
||||
m := make(map[string]any, 13+len(pathItem.Extensions))
|
||||
for k, v := range pathItem.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := pathItem.Summary; x != "" {
|
||||
m["summary"] = x
|
||||
}
|
||||
if x := pathItem.Description; x != "" {
|
||||
m["description"] = x
|
||||
}
|
||||
if x := pathItem.Connect; x != nil {
|
||||
m["connect"] = x
|
||||
}
|
||||
if x := pathItem.Delete; x != nil {
|
||||
m["delete"] = x
|
||||
}
|
||||
if x := pathItem.Get; x != nil {
|
||||
m["get"] = x
|
||||
}
|
||||
if x := pathItem.Head; x != nil {
|
||||
m["head"] = x
|
||||
}
|
||||
if x := pathItem.Options; x != nil {
|
||||
m["options"] = x
|
||||
}
|
||||
if x := pathItem.Patch; x != nil {
|
||||
m["patch"] = x
|
||||
}
|
||||
if x := pathItem.Post; x != nil {
|
||||
m["post"] = x
|
||||
}
|
||||
if x := pathItem.Put; x != nil {
|
||||
m["put"] = x
|
||||
}
|
||||
if x := pathItem.Trace; x != nil {
|
||||
m["trace"] = x
|
||||
}
|
||||
if x := pathItem.Servers; len(x) != 0 {
|
||||
m["servers"] = x
|
||||
}
|
||||
if x := pathItem.Parameters; len(x) != 0 {
|
||||
m["parameters"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets PathItem to a copy of data.
|
||||
func (pathItem *PathItem) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, pathItem)
|
||||
type PathItemBis PathItem
|
||||
var x PathItemBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "$ref")
|
||||
delete(x.Extensions, "summary")
|
||||
delete(x.Extensions, "description")
|
||||
delete(x.Extensions, "connect")
|
||||
delete(x.Extensions, "delete")
|
||||
delete(x.Extensions, "get")
|
||||
delete(x.Extensions, "head")
|
||||
delete(x.Extensions, "options")
|
||||
delete(x.Extensions, "patch")
|
||||
delete(x.Extensions, "post")
|
||||
delete(x.Extensions, "put")
|
||||
delete(x.Extensions, "trace")
|
||||
delete(x.Extensions, "servers")
|
||||
delete(x.Extensions, "parameters")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*pathItem = PathItem(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pathItem *PathItem) Operations() map[string]*Operation {
|
||||
operations := make(map[string]*Operation, 4)
|
||||
operations := make(map[string]*Operation)
|
||||
if v := pathItem.Connect; v != nil {
|
||||
operations[http.MethodConnect] = v
|
||||
}
|
||||
@ -116,11 +203,48 @@ func (pathItem *PathItem) SetOperation(method string, operation *Operation) {
|
||||
}
|
||||
}
|
||||
|
||||
func (value *PathItem) Validate(ctx context.Context) error {
|
||||
for _, operation := range value.Operations() {
|
||||
// Validate returns an error if PathItem does not comply with the OpenAPI spec.
|
||||
func (pathItem *PathItem) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
operations := pathItem.Operations()
|
||||
|
||||
methods := make([]string, 0, len(operations))
|
||||
for method := range operations {
|
||||
methods = append(methods, method)
|
||||
}
|
||||
sort.Strings(methods)
|
||||
for _, method := range methods {
|
||||
operation := operations[method]
|
||||
if err := operation.Validate(ctx); err != nil {
|
||||
return fmt.Errorf("invalid operation %s: %v", method, err)
|
||||
}
|
||||
}
|
||||
|
||||
if v := pathItem.Parameters; v != nil {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
return validateExtensions(ctx, pathItem.Extensions)
|
||||
}
|
||||
|
||||
// isEmpty's introduced in 546590b1
|
||||
func (pathItem *PathItem) isEmpty() bool {
|
||||
// NOTE: ignores pathItem.Extensions
|
||||
// NOTE: ignores pathItem.Ref
|
||||
return pathItem.Summary == "" &&
|
||||
pathItem.Description == "" &&
|
||||
pathItem.Connect == nil &&
|
||||
pathItem.Delete == nil &&
|
||||
pathItem.Get == nil &&
|
||||
pathItem.Head == nil &&
|
||||
pathItem.Options == nil &&
|
||||
pathItem.Patch == nil &&
|
||||
pathItem.Post == nil &&
|
||||
pathItem.Put == nil &&
|
||||
pathItem.Trace == nil &&
|
||||
len(pathItem.Servers) == 0 &&
|
||||
len(pathItem.Parameters) == 0
|
||||
}
|
||||
|
139
vendor/github.com/getkin/kin-openapi/openapi3/paths.go
generated
vendored
139
vendor/github.com/getkin/kin-openapi/openapi3/paths.go
generated
vendored
@ -3,22 +3,60 @@ package openapi3
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Paths is specified by OpenAPI/Swagger standard version 3.0.
|
||||
type Paths map[string]*PathItem
|
||||
// Paths is specified by OpenAPI/Swagger standard version 3.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#paths-object
|
||||
type Paths struct {
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
func (value Paths) Validate(ctx context.Context) error {
|
||||
normalizedPaths := make(map[string]string)
|
||||
for path, pathItem := range value {
|
||||
m map[string]*PathItem
|
||||
}
|
||||
|
||||
// NewPaths builds a paths object with path items in insertion order.
|
||||
func NewPaths(opts ...NewPathsOption) *Paths {
|
||||
paths := NewPathsWithCapacity(len(opts))
|
||||
for _, opt := range opts {
|
||||
opt(paths)
|
||||
}
|
||||
return paths
|
||||
}
|
||||
|
||||
// NewPathsOption describes options to NewPaths func
|
||||
type NewPathsOption func(*Paths)
|
||||
|
||||
// WithPath adds a named path item
|
||||
func WithPath(path string, pathItem *PathItem) NewPathsOption {
|
||||
return func(paths *Paths) {
|
||||
if p := pathItem; p != nil && path != "" {
|
||||
paths.Set(path, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate returns an error if Paths does not comply with the OpenAPI spec.
|
||||
func (paths *Paths) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
normalizedPaths := make(map[string]string, paths.Len())
|
||||
|
||||
keys := make([]string, 0, paths.Len())
|
||||
for key := range paths.Map() {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, path := range keys {
|
||||
pathItem := paths.Value(path)
|
||||
if path == "" || path[0] != '/' {
|
||||
return fmt.Errorf("path %q does not start with a forward slash (/)", path)
|
||||
}
|
||||
|
||||
if pathItem == nil {
|
||||
value[path] = &PathItem{}
|
||||
pathItem = value[path]
|
||||
pathItem = &PathItem{}
|
||||
paths.Set(path, pathItem)
|
||||
}
|
||||
|
||||
normalizedPath, _, varsInPath := normalizeTemplatedPath(path)
|
||||
@ -35,7 +73,14 @@ func (value Paths) Validate(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
for method, operation := range pathItem.Operations() {
|
||||
operations := pathItem.Operations()
|
||||
methods := make([]string, 0, len(operations))
|
||||
for method := range operations {
|
||||
methods = append(methods, method)
|
||||
}
|
||||
sort.Strings(methods)
|
||||
for _, method := range methods {
|
||||
operation := operations[method]
|
||||
var setParams []string
|
||||
for _, parameterRef := range operation.Parameters {
|
||||
if parameterRef != nil {
|
||||
@ -79,10 +124,46 @@ func (value Paths) Validate(ctx context.Context) error {
|
||||
}
|
||||
|
||||
if err := pathItem.Validate(ctx); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("invalid path %s: %v", path, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
if err := paths.validateUniqueOperationIDs(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return validateExtensions(ctx, paths.Extensions)
|
||||
}
|
||||
|
||||
// InMatchingOrder returns paths in the order they are matched against URLs.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#paths-object
|
||||
// When matching URLs, concrete (non-templated) paths would be matched
|
||||
// before their templated counterparts.
|
||||
func (paths *Paths) InMatchingOrder() []string {
|
||||
// NOTE: sorting by number of variables ASC then by descending lexicographical
|
||||
// order seems to be a good heuristic.
|
||||
if paths.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
vars := make(map[int][]string)
|
||||
max := 0
|
||||
for path := range paths.Map() {
|
||||
count := strings.Count(path, "}")
|
||||
vars[count] = append(vars[count], path)
|
||||
if count > max {
|
||||
max = count
|
||||
}
|
||||
}
|
||||
|
||||
ordered := make([]string, 0, paths.Len())
|
||||
for c := 0; c <= max; c++ {
|
||||
if ps, ok := vars[c]; ok {
|
||||
sort.Sort(sort.Reverse(sort.StringSlice(ps)))
|
||||
ordered = append(ordered, ps...)
|
||||
}
|
||||
}
|
||||
return ordered
|
||||
}
|
||||
|
||||
// Find returns a path that matches the key.
|
||||
@ -91,21 +172,21 @@ func (value Paths) Validate(ctx context.Context) error {
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// paths := openapi3.Paths {
|
||||
// "/person/{personName}": &openapi3.PathItem{},
|
||||
// }
|
||||
// pathItem := path.Find("/person/{name}")
|
||||
// paths := openapi3.Paths {
|
||||
// "/person/{personName}": &openapi3.PathItem{},
|
||||
// }
|
||||
// pathItem := path.Find("/person/{name}")
|
||||
//
|
||||
// would return the correct path item.
|
||||
func (paths Paths) Find(key string) *PathItem {
|
||||
func (paths *Paths) Find(key string) *PathItem {
|
||||
// Try directly access the map
|
||||
pathItem := paths[key]
|
||||
pathItem := paths.Value(key)
|
||||
if pathItem != nil {
|
||||
return pathItem
|
||||
}
|
||||
|
||||
normalizedPath, expected, _ := normalizeTemplatedPath(key)
|
||||
for path, pathItem := range paths {
|
||||
for path, pathItem := range paths.Map() {
|
||||
pathNormalized, got, _ := normalizeTemplatedPath(path)
|
||||
if got == expected && pathNormalized == normalizedPath {
|
||||
return pathItem
|
||||
@ -114,6 +195,30 @@ func (paths Paths) Find(key string) *PathItem {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (paths *Paths) validateUniqueOperationIDs() error {
|
||||
operationIDs := make(map[string]string)
|
||||
for urlPath, pathItem := range paths.Map() {
|
||||
if pathItem == nil {
|
||||
continue
|
||||
}
|
||||
for httpMethod, operation := range pathItem.Operations() {
|
||||
if operation == nil || operation.OperationID == "" {
|
||||
continue
|
||||
}
|
||||
endpoint := httpMethod + " " + urlPath
|
||||
if endpointDup, ok := operationIDs[operation.OperationID]; ok {
|
||||
if endpoint > endpointDup { // For make error message a bit more deterministic. May be useful for tests.
|
||||
endpoint, endpointDup = endpointDup, endpoint
|
||||
}
|
||||
return fmt.Errorf("operations %q and %q have the same operation id %q",
|
||||
endpoint, endpointDup, operation.OperationID)
|
||||
}
|
||||
operationIDs[operation.OperationID] = endpoint
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func normalizeTemplatedPath(path string) (string, uint, map[string]struct{}) {
|
||||
if strings.IndexByte(path, '{') < 0 {
|
||||
return path, 0, nil
|
||||
|
10
vendor/github.com/getkin/kin-openapi/openapi3/ref.go
generated
vendored
Normal file
10
vendor/github.com/getkin/kin-openapi/openapi3/ref.go
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
package openapi3
|
||||
|
||||
//go:generate go run refsgenerator.go
|
||||
|
||||
// Ref is specified by OpenAPI/Swagger 3.0 standard.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#reference-object
|
||||
type Ref struct {
|
||||
Ref string `json:"$ref" yaml:"$ref"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
}
|
1204
vendor/github.com/getkin/kin-openapi/openapi3/refs.go
generated
vendored
1204
vendor/github.com/getkin/kin-openapi/openapi3/refs.go
generated
vendored
File diff suppressed because it is too large
Load Diff
153
vendor/github.com/getkin/kin-openapi/openapi3/refs.tmpl
generated
vendored
Normal file
153
vendor/github.com/getkin/kin-openapi/openapi3/refs.tmpl
generated
vendored
Normal file
@ -0,0 +1,153 @@
|
||||
// Code generated by go generate; DO NOT EDIT.
|
||||
package {{ .Package }}
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/perimeterx/marshmallow"
|
||||
)
|
||||
{{ range $type := .Types }}
|
||||
// {{ $type.Name }}Ref represents either a {{ $type.Name }} or a $ref to a {{ $type.Name }}.
|
||||
// When serializing and both fields are set, Ref is preferred over Value.
|
||||
type {{ $type.Name }}Ref struct {
|
||||
// Extensions only captures fields starting with 'x-' as no other fields
|
||||
// are allowed by the openapi spec.
|
||||
Extensions map[string]any
|
||||
Origin *Origin
|
||||
|
||||
Ref string
|
||||
Value *{{ $type.Name }}
|
||||
extra []string
|
||||
|
||||
refPath *url.URL
|
||||
}
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*{{ $type.Name }}Ref)(nil)
|
||||
|
||||
func (x *{{ $type.Name }}Ref) isEmpty() bool { return x == nil || x.Ref == "" && x.Value == nil }
|
||||
|
||||
// RefString returns the $ref value.
|
||||
func (x *{{ $type.Name }}Ref) RefString() string { return x.Ref }
|
||||
|
||||
// CollectionName returns the JSON string used for a collection of these components.
|
||||
func (x *{{ $type.Name }}Ref) CollectionName() string { return "{{ $type.CollectionName }}" }
|
||||
|
||||
// RefPath returns the path of the $ref relative to the root document.
|
||||
func (x *{{ $type.Name }}Ref) RefPath() *url.URL { return copyURI(x.refPath) }
|
||||
|
||||
func (x *{{ $type.Name }}Ref) setRefPath(u *url.URL) {
|
||||
// Once the refPath is set don't override. References can be loaded
|
||||
// multiple times not all with access to the correct path info.
|
||||
if x.refPath != nil {
|
||||
return
|
||||
}
|
||||
|
||||
x.refPath = copyURI(u)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of {{ $type.Name }}Ref.
|
||||
func (x {{ $type.Name }}Ref) MarshalYAML() (any, error) {
|
||||
if ref := x.Ref; ref != "" {
|
||||
return &Ref{Ref: ref}, nil
|
||||
}
|
||||
return x.Value.MarshalYAML()
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of {{ $type.Name }}Ref.
|
||||
func (x {{ $type.Name }}Ref) MarshalJSON() ([]byte, error) {
|
||||
y, err := x.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(y)
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets {{ $type.Name }}Ref to a copy of data.
|
||||
func (x *{{ $type.Name }}Ref) UnmarshalJSON(data []byte) error {
|
||||
var refOnly Ref
|
||||
if extra, err := marshmallow.Unmarshal(data, &refOnly, marshmallow.WithExcludeKnownFieldsFromMap(true)); err == nil && refOnly.Ref != "" {
|
||||
x.Ref = refOnly.Ref
|
||||
x.Origin = refOnly.Origin
|
||||
if len(extra) != 0 {
|
||||
x.extra = make([]string, 0, len(extra))
|
||||
for key := range extra {
|
||||
x.extra = append(x.extra, key)
|
||||
}
|
||||
sort.Strings(x.extra)
|
||||
for k := range extra {
|
||||
if !strings.HasPrefix(k, "x-") {
|
||||
delete(extra, k)
|
||||
}
|
||||
}
|
||||
if len(extra) != 0 {
|
||||
x.Extensions = extra
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal(data, &x.Value)
|
||||
}
|
||||
|
||||
// Validate returns an error if {{ $type.Name }}Ref does not comply with the OpenAPI spec.
|
||||
func (x *{{ $type.Name }}Ref) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
exProhibited := getValidationOptions(ctx).schemaExtensionsInRefProhibited
|
||||
var extras []string
|
||||
if extra := x.extra; len(extra) != 0 {
|
||||
allowed := getValidationOptions(ctx).extraSiblingFieldsAllowed
|
||||
for _, ex := range extra {
|
||||
if allowed != nil {
|
||||
if _, ok := allowed[ex]; ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
// extras in the Extensions checked below
|
||||
if _, ok := x.Extensions[ex]; !ok {
|
||||
extras = append(extras, ex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if extra := x.Extensions; exProhibited && len(extra) != 0 {
|
||||
allowed := getValidationOptions(ctx).extraSiblingFieldsAllowed
|
||||
for ex := range extra {
|
||||
if allowed != nil {
|
||||
if _, ok := allowed[ex]; ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
extras = append(extras, ex)
|
||||
}
|
||||
}
|
||||
|
||||
if len(extras) != 0 {
|
||||
return fmt.Errorf("extra sibling fields: %+v", extras)
|
||||
}
|
||||
|
||||
if v := x.Value; v != nil {
|
||||
return v.Validate(ctx)
|
||||
}
|
||||
|
||||
return foundUnresolvedRef(x.Ref)
|
||||
}
|
||||
|
||||
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
|
||||
func (x *{{ $type.Name }}Ref) JSONLookup(token string) (any, error) {
|
||||
if token == "$ref" {
|
||||
return x.Ref, nil
|
||||
}
|
||||
|
||||
if v, ok := x.Extensions[token]; ok {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
ptr, _, err := jsonpointer.GetForToken(x.Value, token)
|
||||
return ptr, err
|
||||
}
|
||||
{{ end -}}
|
54
vendor/github.com/getkin/kin-openapi/openapi3/refs_test.tmpl
generated
vendored
Normal file
54
vendor/github.com/getkin/kin-openapi/openapi3/refs_test.tmpl
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
// Code generated by go generate; DO NOT EDIT.
|
||||
package {{ .Package }}
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
{{ range $type := .Types }}
|
||||
func Test{{ $type.Name }}Ref_Extensions(t *testing.T) {
|
||||
data := []byte(`{"$ref":"#/components/schemas/Pet","something":"integer","x-order":1}`)
|
||||
|
||||
ref := {{ $type.Name }}Ref{}
|
||||
err := json.Unmarshal(data, &ref)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// captures extension
|
||||
assert.Equal(t, "#/components/schemas/Pet", ref.Ref)
|
||||
assert.Equal(t, float64(1), ref.Extensions["x-order"])
|
||||
|
||||
// does not capture non-extensions
|
||||
assert.Nil(t, ref.Extensions["something"])
|
||||
|
||||
// validation
|
||||
err = ref.Validate(context.Background())
|
||||
require.EqualError(t, err, "extra sibling fields: [something]")
|
||||
|
||||
err = ref.Validate(context.Background(), ProhibitExtensionsWithRef())
|
||||
require.EqualError(t, err, "extra sibling fields: [something x-order]")
|
||||
|
||||
err = ref.Validate(context.Background(), AllowExtraSiblingFields("something"))
|
||||
assert.ErrorContains(t, err, "found unresolved ref") // expected since value not defined
|
||||
|
||||
// non-extension not json lookable
|
||||
_, err = ref.JSONLookup("something")
|
||||
assert.Error(t, err)
|
||||
{{ if ne $type.Name "Header" }}
|
||||
t.Run("extentions in value", func(t *testing.T) {
|
||||
ref.Value = &{{ $type.Name }}{Extensions: map[string]any{}}
|
||||
ref.Value.Extensions["x-order"] = 2.0
|
||||
|
||||
// prefers the value next to the \$ref over the one in the \$ref.
|
||||
v, err := ref.JSONLookup("x-order")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, float64(1), v)
|
||||
})
|
||||
{{ else }}
|
||||
// Header does not have its own extensions.
|
||||
{{ end -}}
|
||||
}
|
||||
{{ end -}}
|
109
vendor/github.com/getkin/kin-openapi/openapi3/request_body.go
generated
vendored
109
vendor/github.com/getkin/kin-openapi/openapi3/request_body.go
generated
vendored
@ -2,34 +2,19 @@ package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
)
|
||||
|
||||
type RequestBodies map[string]*RequestBodyRef
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*RequestBodyRef)(nil)
|
||||
|
||||
func (r RequestBodies) JSONLookup(token string) (interface{}, error) {
|
||||
ref, ok := r[token]
|
||||
if ok == false {
|
||||
return nil, fmt.Errorf("object has no field %q", token)
|
||||
}
|
||||
|
||||
if ref != nil && ref.Ref != "" {
|
||||
return &Ref{Ref: ref.Ref}, nil
|
||||
}
|
||||
return ref.Value, nil
|
||||
}
|
||||
|
||||
// RequestBody is specified by OpenAPI/Swagger 3.0 standard.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#request-body-object
|
||||
type RequestBody struct {
|
||||
ExtensionProps
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
|
||||
Content Content `json:"content,omitempty" yaml:"content,omitempty"`
|
||||
Content Content `json:"content" yaml:"content"`
|
||||
}
|
||||
|
||||
func NewRequestBody() *RequestBody {
|
||||
@ -89,19 +74,73 @@ func (requestBody *RequestBody) GetMediaType(mediaType string) *MediaType {
|
||||
return m[mediaType]
|
||||
}
|
||||
|
||||
func (requestBody *RequestBody) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(requestBody)
|
||||
}
|
||||
|
||||
func (requestBody *RequestBody) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, requestBody)
|
||||
}
|
||||
|
||||
func (value *RequestBody) Validate(ctx context.Context) error {
|
||||
if v := value.Content; v != nil {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
// MarshalJSON returns the JSON encoding of RequestBody.
|
||||
func (requestBody RequestBody) MarshalJSON() ([]byte, error) {
|
||||
x, err := requestBody.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of RequestBody.
|
||||
func (requestBody RequestBody) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 3+len(requestBody.Extensions))
|
||||
for k, v := range requestBody.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := requestBody.Description; x != "" {
|
||||
m["description"] = requestBody.Description
|
||||
}
|
||||
if x := requestBody.Required; x {
|
||||
m["required"] = x
|
||||
}
|
||||
if x := requestBody.Content; true {
|
||||
m["content"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets RequestBody to a copy of data.
|
||||
func (requestBody *RequestBody) UnmarshalJSON(data []byte) error {
|
||||
type RequestBodyBis RequestBody
|
||||
var x RequestBodyBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "description")
|
||||
delete(x.Extensions, "required")
|
||||
delete(x.Extensions, "content")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*requestBody = RequestBody(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate returns an error if RequestBody does not comply with the OpenAPI spec.
|
||||
func (requestBody *RequestBody) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if requestBody.Content == nil {
|
||||
return errors.New("content of the request body is required")
|
||||
}
|
||||
|
||||
if vo := getValidationOptions(ctx); !vo.examplesValidationDisabled {
|
||||
vo.examplesValidationAsReq, vo.examplesValidationAsRes = true, false
|
||||
}
|
||||
|
||||
if err := requestBody.Content.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return validateExtensions(ctx, requestBody.Extensions)
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets RequestBodies to a copy of data.
|
||||
func (requestBodies *RequestBodies) UnmarshalJSON(data []byte) (err error) {
|
||||
*requestBodies, _, err = unmarshalStringMapP[RequestBodyRef](data)
|
||||
return
|
||||
}
|
||||
|
208
vendor/github.com/getkin/kin-openapi/openapi3/response.go
generated
vendored
208
vendor/github.com/getkin/kin-openapi/openapi3/response.go
generated
vendored
@ -2,60 +2,109 @@ package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
)
|
||||
|
||||
// Responses is specified by OpenAPI/Swagger 3.0 standard.
|
||||
type Responses map[string]*ResponseRef
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#responses-object
|
||||
type Responses struct {
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"-" yaml:"-"`
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*Responses)(nil)
|
||||
|
||||
func NewResponses() Responses {
|
||||
r := make(Responses)
|
||||
r["default"] = &ResponseRef{Value: NewResponse().WithDescription("")}
|
||||
return r
|
||||
m map[string]*ResponseRef
|
||||
}
|
||||
|
||||
func (responses Responses) Default() *ResponseRef {
|
||||
return responses["default"]
|
||||
}
|
||||
|
||||
func (responses Responses) Get(status int) *ResponseRef {
|
||||
return responses[strconv.FormatInt(int64(status), 10)]
|
||||
}
|
||||
|
||||
func (value Responses) Validate(ctx context.Context) error {
|
||||
if len(value) == 0 {
|
||||
return errors.New("the responses object MUST contain at least one response code")
|
||||
// NewResponses builds a responses object with response objects in insertion order.
|
||||
// Given no arguments, NewResponses returns a valid responses object containing a default match-all reponse.
|
||||
func NewResponses(opts ...NewResponsesOption) *Responses {
|
||||
if len(opts) == 0 {
|
||||
return NewResponses(WithName("default", NewResponse().WithDescription("")))
|
||||
}
|
||||
for _, v := range value {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return err
|
||||
responses := NewResponsesWithCapacity(len(opts))
|
||||
for _, opt := range opts {
|
||||
opt(responses)
|
||||
}
|
||||
return responses
|
||||
}
|
||||
|
||||
// NewResponsesOption describes options to NewResponses func
|
||||
type NewResponsesOption func(*Responses)
|
||||
|
||||
// WithStatus adds a status code keyed ResponseRef
|
||||
func WithStatus(status int, responseRef *ResponseRef) NewResponsesOption {
|
||||
return func(responses *Responses) {
|
||||
if r := responseRef; r != nil {
|
||||
code := strconv.FormatInt(int64(status), 10)
|
||||
responses.Set(code, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithName adds a name-keyed Response
|
||||
func WithName(name string, response *Response) NewResponsesOption {
|
||||
return func(responses *Responses) {
|
||||
if r := response; r != nil && name != "" {
|
||||
responses.Set(name, &ResponseRef{Value: r})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Default returns the default response
|
||||
func (responses *Responses) Default() *ResponseRef {
|
||||
return responses.Value("default")
|
||||
}
|
||||
|
||||
// Status returns a ResponseRef for the given status
|
||||
// If an exact match isn't initially found a patterned field is checked using
|
||||
// the first digit to determine the range (eg: 201 to 2XX)
|
||||
// See https://spec.openapis.org/oas/v3.0.3#patterned-fields-0
|
||||
func (responses *Responses) Status(status int) *ResponseRef {
|
||||
st := strconv.FormatInt(int64(status), 10)
|
||||
if rref := responses.Value(st); rref != nil {
|
||||
return rref
|
||||
}
|
||||
if 99 < status && status < 600 {
|
||||
st = string(st[0]) + "XX"
|
||||
switch st {
|
||||
case "1XX", "2XX", "3XX", "4XX", "5XX":
|
||||
return responses.Value(st)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (responses Responses) JSONLookup(token string) (interface{}, error) {
|
||||
ref, ok := responses[token]
|
||||
if ok == false {
|
||||
return nil, fmt.Errorf("invalid token reference: %q", token)
|
||||
// Validate returns an error if Responses does not comply with the OpenAPI spec.
|
||||
func (responses *Responses) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if responses.Len() == 0 {
|
||||
return errors.New("the responses object MUST contain at least one response code")
|
||||
}
|
||||
|
||||
if ref != nil && ref.Ref != "" {
|
||||
return &Ref{Ref: ref.Ref}, nil
|
||||
keys := make([]string, 0, responses.Len())
|
||||
for key := range responses.Map() {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
return ref.Value, nil
|
||||
sort.Strings(keys)
|
||||
for _, key := range keys {
|
||||
v := responses.Value(key)
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return validateExtensions(ctx, responses.Extensions)
|
||||
}
|
||||
|
||||
// Response is specified by OpenAPI/Swagger 3.0 standard.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#response-object
|
||||
type Response struct {
|
||||
ExtensionProps
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
Description *string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
Headers Headers `json:"headers,omitempty" yaml:"headers,omitempty"`
|
||||
Content Content `json:"content,omitempty" yaml:"content,omitempty"`
|
||||
@ -86,23 +135,102 @@ func (response *Response) WithJSONSchemaRef(schema *SchemaRef) *Response {
|
||||
return response
|
||||
}
|
||||
|
||||
func (response *Response) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(response)
|
||||
// MarshalJSON returns the JSON encoding of Response.
|
||||
func (response Response) MarshalJSON() ([]byte, error) {
|
||||
x, err := response.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of Response.
|
||||
func (response Response) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 4+len(response.Extensions))
|
||||
for k, v := range response.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := response.Description; x != nil {
|
||||
m["description"] = x
|
||||
}
|
||||
if x := response.Headers; len(x) != 0 {
|
||||
m["headers"] = x
|
||||
}
|
||||
if x := response.Content; len(x) != 0 {
|
||||
m["content"] = x
|
||||
}
|
||||
if x := response.Links; len(x) != 0 {
|
||||
m["links"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Response to a copy of data.
|
||||
func (response *Response) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, response)
|
||||
type ResponseBis Response
|
||||
var x ResponseBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "description")
|
||||
delete(x.Extensions, "headers")
|
||||
delete(x.Extensions, "content")
|
||||
delete(x.Extensions, "links")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*response = Response(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (value *Response) Validate(ctx context.Context) error {
|
||||
if value.Description == nil {
|
||||
// Validate returns an error if Response does not comply with the OpenAPI spec.
|
||||
func (response *Response) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if response.Description == nil {
|
||||
return errors.New("a short description of the response is required")
|
||||
}
|
||||
if vo := getValidationOptions(ctx); !vo.examplesValidationDisabled {
|
||||
vo.examplesValidationAsReq, vo.examplesValidationAsRes = false, true
|
||||
}
|
||||
|
||||
if content := value.Content; content != nil {
|
||||
if content := response.Content; content != nil {
|
||||
if err := content.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
headers := make([]string, 0, len(response.Headers))
|
||||
for name := range response.Headers {
|
||||
headers = append(headers, name)
|
||||
}
|
||||
sort.Strings(headers)
|
||||
for _, name := range headers {
|
||||
header := response.Headers[name]
|
||||
if err := header.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
links := make([]string, 0, len(response.Links))
|
||||
for name := range response.Links {
|
||||
links = append(links, name)
|
||||
}
|
||||
sort.Strings(links)
|
||||
for _, name := range links {
|
||||
link := response.Links[name]
|
||||
if err := link.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return validateExtensions(ctx, response.Extensions)
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets ResponseBodies to a copy of data.
|
||||
func (responseBodies *ResponseBodies) UnmarshalJSON(data []byte) (err error) {
|
||||
*responseBodies, _, err = unmarshalStringMapP[ResponseRef](data)
|
||||
return
|
||||
}
|
||||
|
1584
vendor/github.com/getkin/kin-openapi/openapi3/schema.go
generated
vendored
1584
vendor/github.com/getkin/kin-openapi/openapi3/schema.go
generated
vendored
File diff suppressed because it is too large
Load Diff
234
vendor/github.com/getkin/kin-openapi/openapi3/schema_formats.go
generated
vendored
234
vendor/github.com/getkin/kin-openapi/openapi3/schema_formats.go
generated
vendored
@ -2,104 +2,170 @@ package openapi3
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"math"
|
||||
"net/netip"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
type (
|
||||
// FormatValidator is an interface for custom format validators.
|
||||
FormatValidator[T any] interface {
|
||||
Validate(value T) error
|
||||
}
|
||||
// StringFormatValidator is a type alias for FormatValidator[string]
|
||||
StringFormatValidator = FormatValidator[string]
|
||||
// NumberFormatValidator is a type alias for FormatValidator[float64]
|
||||
NumberFormatValidator = FormatValidator[float64]
|
||||
// IntegerFormatValidator is a type alias for FormatValidator[int64]
|
||||
IntegerFormatValidator = FormatValidator[int64]
|
||||
)
|
||||
|
||||
var (
|
||||
// SchemaStringFormats is a map of custom string format validators.
|
||||
SchemaStringFormats = make(map[string]StringFormatValidator)
|
||||
// SchemaNumberFormats is a map of custom number format validators.
|
||||
SchemaNumberFormats = make(map[string]NumberFormatValidator)
|
||||
// SchemaIntegerFormats is a map of custom integer format validators.
|
||||
SchemaIntegerFormats = make(map[string]IntegerFormatValidator)
|
||||
)
|
||||
|
||||
const (
|
||||
// FormatOfStringForUUIDOfRFC4122 is an optional predefined format for UUID v1-v5 as specified by RFC4122
|
||||
FormatOfStringForUUIDOfRFC4122 = `^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$`
|
||||
FormatOfStringForUUIDOfRFC4122 = `^(?:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$`
|
||||
|
||||
// FormatOfStringForEmail pattern catches only some suspiciously wrong-looking email addresses.
|
||||
// Use DefineStringFormat(...) if you need something stricter.
|
||||
FormatOfStringForEmail = `^[^@]+@[^@<>",\s]+$`
|
||||
|
||||
// FormatOfStringByte is a regexp for base64-encoded characters, for example, "U3dhZ2dlciByb2Nrcw=="
|
||||
FormatOfStringByte = `(^$|^[a-zA-Z0-9+/\-_]*=*$)`
|
||||
|
||||
// FormatOfStringDate is a RFC3339 date format regexp, for example "2017-07-21".
|
||||
FormatOfStringDate = `^[0-9]{4}-(0[1-9]|10|11|12)-(0[1-9]|[12][0-9]|3[01])$`
|
||||
|
||||
// FormatOfStringDateTime is a RFC3339 date-time format regexp, for example "2017-07-21T17:32:28Z".
|
||||
FormatOfStringDateTime = `^[0-9]{4}-(0[1-9]|10|11|12)-(0[1-9]|[12][0-9]|3[01])T([0-1][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\.[0-9]+)?(Z|(\+|-)[0-9]{2}:[0-9]{2})?$`
|
||||
)
|
||||
|
||||
//FormatCallback custom check on exotic formats
|
||||
type FormatCallback func(Val string) error
|
||||
|
||||
type Format struct {
|
||||
regexp *regexp.Regexp
|
||||
callback FormatCallback
|
||||
}
|
||||
|
||||
//SchemaStringFormats allows for validating strings format
|
||||
var SchemaStringFormats = make(map[string]Format, 8)
|
||||
|
||||
//DefineStringFormat Defines a new regexp pattern for a given format
|
||||
func DefineStringFormat(name string, pattern string) {
|
||||
re, err := regexp.Compile(pattern)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("format %q has invalid pattern %q: %v", name, pattern, err)
|
||||
panic(err)
|
||||
}
|
||||
SchemaStringFormats[name] = Format{regexp: re}
|
||||
}
|
||||
|
||||
// DefineStringFormatCallback adds a validation function for a specific schema format entry
|
||||
func DefineStringFormatCallback(name string, callback FormatCallback) {
|
||||
SchemaStringFormats[name] = Format{callback: callback}
|
||||
}
|
||||
|
||||
func validateIP(ip string) (*net.IP, error) {
|
||||
parsed := net.ParseIP(ip)
|
||||
if parsed == nil {
|
||||
return nil, &SchemaError{
|
||||
Value: ip,
|
||||
Reason: "Not an IP address",
|
||||
}
|
||||
}
|
||||
return &parsed, nil
|
||||
}
|
||||
|
||||
func validateIPv4(ip string) error {
|
||||
parsed, err := validateIP(ip)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if parsed.To4() == nil {
|
||||
return &SchemaError{
|
||||
Value: ip,
|
||||
Reason: "Not an IPv4 address (it's IPv6)",
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func validateIPv6(ip string) error {
|
||||
parsed, err := validateIP(ip)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if parsed.To4() != nil {
|
||||
return &SchemaError{
|
||||
Value: ip,
|
||||
Reason: "Not an IPv6 address (it's IPv4)",
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
// This pattern catches only some suspiciously wrong-looking email addresses.
|
||||
// Use DefineStringFormat(...) if you need something stricter.
|
||||
DefineStringFormat("email", `^[^@]+@[^@<>",\s]+$`)
|
||||
|
||||
// Base64
|
||||
// The pattern supports base64 and b./ase64url. Padding ('=') is supported.
|
||||
DefineStringFormat("byte", `(^$|^[a-zA-Z0-9+/\-_]*=*$)`)
|
||||
|
||||
// date
|
||||
DefineStringFormat("date", `^[0-9]{4}-(0[0-9]|10|11|12)-([0-2][0-9]|30|31)$`)
|
||||
|
||||
// date-time
|
||||
DefineStringFormat("date-time", `^[0-9]{4}-(0[0-9]|10|11|12)-([0-2][0-9]|30|31)T[0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]+)?(Z|(\+|-)[0-9]{2}:[0-9]{2})?$`)
|
||||
|
||||
DefineStringFormatValidator("byte", NewRegexpFormatValidator(FormatOfStringByte))
|
||||
DefineStringFormatValidator("date", NewRegexpFormatValidator(FormatOfStringDate))
|
||||
DefineStringFormatValidator("date-time", NewRegexpFormatValidator(FormatOfStringDateTime))
|
||||
DefineIntegerFormatValidator("int32", NewRangeFormatValidator(int64(math.MinInt32), int64(math.MaxInt32)))
|
||||
DefineIntegerFormatValidator("int64", NewRangeFormatValidator(int64(math.MinInt64), int64(math.MaxInt64)))
|
||||
}
|
||||
|
||||
// DefineIPv4Format opts in ipv4 format validation on top of OAS 3 spec
|
||||
func DefineIPv4Format() {
|
||||
DefineStringFormatCallback("ipv4", validateIPv4)
|
||||
DefineStringFormatValidator("ipv4", NewIPValidator(true))
|
||||
}
|
||||
|
||||
// DefineIPv6Format opts in ipv6 format validation on top of OAS 3 spec
|
||||
func DefineIPv6Format() {
|
||||
DefineStringFormatCallback("ipv6", validateIPv6)
|
||||
DefineStringFormatValidator("ipv6", NewIPValidator(false))
|
||||
}
|
||||
|
||||
type stringRegexpFormatValidator struct {
|
||||
re *regexp.Regexp
|
||||
}
|
||||
|
||||
func (s stringRegexpFormatValidator) Validate(value string) error {
|
||||
if !s.re.MatchString(value) {
|
||||
return fmt.Errorf(`string doesn't match pattern "%s"`, s.re.String())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type callbackValidator[T any] struct {
|
||||
fn func(T) error
|
||||
}
|
||||
|
||||
func (c callbackValidator[T]) Validate(value T) error {
|
||||
return c.fn(value)
|
||||
}
|
||||
|
||||
type rangeFormat[T int64 | float64] struct {
|
||||
min, max T
|
||||
}
|
||||
|
||||
func (r rangeFormat[T]) Validate(value T) error {
|
||||
if value < r.min || value > r.max {
|
||||
return fmt.Errorf("value should be between %v and %v", r.min, r.max)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewRangeFormatValidator creates a new FormatValidator that validates the value is within a given range.
|
||||
func NewRangeFormatValidator[T int64 | float64](min, max T) FormatValidator[T] {
|
||||
return rangeFormat[T]{min: min, max: max}
|
||||
}
|
||||
|
||||
// NewRegexpFormatValidator creates a new FormatValidator that uses a regular expression to validate the value.
|
||||
func NewRegexpFormatValidator(pattern string) StringFormatValidator {
|
||||
re, err := regexp.Compile(pattern)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("string regexp format has invalid pattern %q: %w", pattern, err)
|
||||
panic(err)
|
||||
}
|
||||
return stringRegexpFormatValidator{re: re}
|
||||
}
|
||||
|
||||
// NewCallbackValidator creates a new FormatValidator that uses a callback function to validate the value.
|
||||
func NewCallbackValidator[T any](fn func(T) error) FormatValidator[T] {
|
||||
return callbackValidator[T]{fn: fn}
|
||||
}
|
||||
|
||||
// DefineStringFormatValidator defines a custom format validator for a given string format.
|
||||
func DefineStringFormatValidator(name string, validator StringFormatValidator) {
|
||||
SchemaStringFormats[name] = validator
|
||||
}
|
||||
|
||||
// DefineNumberFormatValidator defines a custom format validator for a given number format.
|
||||
func DefineNumberFormatValidator(name string, validator NumberFormatValidator) {
|
||||
SchemaNumberFormats[name] = validator
|
||||
}
|
||||
|
||||
// DefineIntegerFormatValidator defines a custom format validator for a given integer format.
|
||||
func DefineIntegerFormatValidator(name string, validator IntegerFormatValidator) {
|
||||
SchemaIntegerFormats[name] = validator
|
||||
}
|
||||
|
||||
// DefineStringFormat defines a regexp pattern for a given string format
|
||||
//
|
||||
// Deprecated: Use openapi3.DefineStringFormatValidator(name, NewRegexpFormatValidator(pattern)) instead.
|
||||
func DefineStringFormat(name string, pattern string) {
|
||||
DefineStringFormatValidator(name, NewRegexpFormatValidator(pattern))
|
||||
}
|
||||
|
||||
// DefineStringFormatCallback defines a callback function for a given string format
|
||||
//
|
||||
// Deprecated: Use openapi3.DefineStringFormatValidator(name, NewCallbackValidator(fn)) instead.
|
||||
func DefineStringFormatCallback(name string, callback func(string) error) {
|
||||
DefineStringFormatValidator(name, NewCallbackValidator(callback))
|
||||
}
|
||||
|
||||
// NewIPValidator creates a new FormatValidator that validates the value is an IP address.
|
||||
func NewIPValidator(isIPv4 bool) FormatValidator[string] {
|
||||
return callbackValidator[string]{fn: func(ip string) error {
|
||||
addr, err := netip.ParseAddr(ip)
|
||||
if err != nil {
|
||||
return &SchemaError{
|
||||
Value: ip,
|
||||
Reason: "Not an IP address",
|
||||
}
|
||||
}
|
||||
if isIPv4 && !addr.Is4() {
|
||||
return &SchemaError{
|
||||
Value: ip,
|
||||
Reason: "Not an IPv4 address (it's IPv6)",
|
||||
}
|
||||
}
|
||||
if !isIPv4 && !addr.Is6() {
|
||||
return &SchemaError{
|
||||
Value: ip,
|
||||
Reason: "Not an IPv6 address (it's IPv4)",
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}}
|
||||
}
|
||||
|
35
vendor/github.com/getkin/kin-openapi/openapi3/schema_pattern.go
generated
vendored
Normal file
35
vendor/github.com/getkin/kin-openapi/openapi3/schema_pattern.go
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
package openapi3
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
var patRewriteCodepoints = regexp.MustCompile(`(?P<replaced_with_slash_x>\\u)(?P<code>[0-9A-F]{4})`)
|
||||
|
||||
// See https://pkg.go.dev/regexp/syntax
|
||||
func intoGoRegexp(re string) string {
|
||||
return patRewriteCodepoints.ReplaceAllString(re, `\x{${code}}`)
|
||||
}
|
||||
|
||||
// NOTE: racey WRT [writes to schema.Pattern] vs [reads schema.Pattern then writes to compiledPatterns]
|
||||
func (schema *Schema) compilePattern(c RegexCompilerFunc) (cp RegexMatcher, err error) {
|
||||
pattern := schema.Pattern
|
||||
if c != nil {
|
||||
cp, err = c(pattern)
|
||||
} else {
|
||||
cp, err = regexp.Compile(intoGoRegexp(pattern))
|
||||
}
|
||||
if err != nil {
|
||||
err = &SchemaError{
|
||||
Schema: schema,
|
||||
SchemaField: "pattern",
|
||||
Origin: err,
|
||||
Reason: fmt.Sprintf("cannot compile pattern %q: %v", pattern, err),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var _ bool = compiledPatterns.CompareAndSwap(pattern, nil, cp)
|
||||
return
|
||||
}
|
64
vendor/github.com/getkin/kin-openapi/openapi3/schema_validation_settings.go
generated
vendored
64
vendor/github.com/getkin/kin-openapi/openapi3/schema_validation_settings.go
generated
vendored
@ -1,12 +1,33 @@
|
||||
package openapi3
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// SchemaValidationOption describes options a user has when validating request / response bodies.
|
||||
type SchemaValidationOption func(*schemaValidationSettings)
|
||||
|
||||
type RegexCompilerFunc func(expr string) (RegexMatcher, error)
|
||||
|
||||
type RegexMatcher interface {
|
||||
MatchString(s string) bool
|
||||
}
|
||||
|
||||
type schemaValidationSettings struct {
|
||||
failfast bool
|
||||
multiError bool
|
||||
asreq, asrep bool // exclusive (XOR) fields
|
||||
failfast bool
|
||||
multiError bool
|
||||
asreq, asrep bool // exclusive (XOR) fields
|
||||
formatValidationEnabled bool
|
||||
patternValidationDisabled bool
|
||||
readOnlyValidationDisabled bool
|
||||
writeOnlyValidationDisabled bool
|
||||
|
||||
regexCompiler RegexCompilerFunc
|
||||
|
||||
onceSettingDefaults sync.Once
|
||||
defaultsSet func()
|
||||
|
||||
customizeMessageError func(err *SchemaError) string
|
||||
}
|
||||
|
||||
// FailFast returns schema validation errors quicker.
|
||||
@ -21,10 +42,47 @@ func MultiErrors() SchemaValidationOption {
|
||||
func VisitAsRequest() SchemaValidationOption {
|
||||
return func(s *schemaValidationSettings) { s.asreq, s.asrep = true, false }
|
||||
}
|
||||
|
||||
func VisitAsResponse() SchemaValidationOption {
|
||||
return func(s *schemaValidationSettings) { s.asreq, s.asrep = false, true }
|
||||
}
|
||||
|
||||
// EnableFormatValidation setting makes Validate not return an error when validating documents that mention schema formats that are not defined by the OpenAPIv3 specification.
|
||||
func EnableFormatValidation() SchemaValidationOption {
|
||||
return func(s *schemaValidationSettings) { s.formatValidationEnabled = true }
|
||||
}
|
||||
|
||||
// DisablePatternValidation setting makes Validate not return an error when validating patterns that are not supported by the Go regexp engine.
|
||||
func DisablePatternValidation() SchemaValidationOption {
|
||||
return func(s *schemaValidationSettings) { s.patternValidationDisabled = true }
|
||||
}
|
||||
|
||||
// DisableReadOnlyValidation setting makes Validate not return an error when validating properties marked as read-only
|
||||
func DisableReadOnlyValidation() SchemaValidationOption {
|
||||
return func(s *schemaValidationSettings) { s.readOnlyValidationDisabled = true }
|
||||
}
|
||||
|
||||
// DisableWriteOnlyValidation setting makes Validate not return an error when validating properties marked as write-only
|
||||
func DisableWriteOnlyValidation() SchemaValidationOption {
|
||||
return func(s *schemaValidationSettings) { s.writeOnlyValidationDisabled = true }
|
||||
}
|
||||
|
||||
// DefaultsSet executes the given callback (once) IFF schema validation set default values.
|
||||
func DefaultsSet(f func()) SchemaValidationOption {
|
||||
return func(s *schemaValidationSettings) { s.defaultsSet = f }
|
||||
}
|
||||
|
||||
// SetSchemaErrorMessageCustomizer allows to override the schema error message.
|
||||
// If the passed function returns an empty string, it returns to the previous Error() implementation.
|
||||
func SetSchemaErrorMessageCustomizer(f func(err *SchemaError) string) SchemaValidationOption {
|
||||
return func(s *schemaValidationSettings) { s.customizeMessageError = f }
|
||||
}
|
||||
|
||||
// SetSchemaRegexCompiler allows to override the regex implementation used to validate field "pattern".
|
||||
func SetSchemaRegexCompiler(c RegexCompilerFunc) SchemaValidationOption {
|
||||
return func(s *schemaValidationSettings) { s.regexCompiler = c }
|
||||
}
|
||||
|
||||
func newSchemaValidationSettings(opts ...SchemaValidationOption) *schemaValidationSettings {
|
||||
settings := &schemaValidationSettings{}
|
||||
for _, opt := range opts {
|
||||
|
22
vendor/github.com/getkin/kin-openapi/openapi3/security_requirements.go
generated
vendored
22
vendor/github.com/getkin/kin-openapi/openapi3/security_requirements.go
generated
vendored
@ -15,15 +15,20 @@ func (srs *SecurityRequirements) With(securityRequirement SecurityRequirement) *
|
||||
return srs
|
||||
}
|
||||
|
||||
func (value SecurityRequirements) Validate(ctx context.Context) error {
|
||||
for _, item := range value {
|
||||
if err := item.Validate(ctx); err != nil {
|
||||
// Validate returns an error if SecurityRequirements does not comply with the OpenAPI spec.
|
||||
func (srs SecurityRequirements) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
for _, security := range srs {
|
||||
if err := security.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SecurityRequirement is specified by OpenAPI/Swagger standard version 3.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#security-requirement-object
|
||||
type SecurityRequirement map[string][]string
|
||||
|
||||
func NewSecurityRequirement() SecurityRequirement {
|
||||
@ -38,6 +43,15 @@ func (security SecurityRequirement) Authenticate(provider string, scopes ...stri
|
||||
return security
|
||||
}
|
||||
|
||||
func (value SecurityRequirement) Validate(ctx context.Context) error {
|
||||
// Validate returns an error if SecurityRequirement does not comply with the OpenAPI spec.
|
||||
func (security *SecurityRequirement) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets SecurityRequirement to a copy of data.
|
||||
func (security *SecurityRequirement) UnmarshalJSON(data []byte) (err error) {
|
||||
*security, _, err = unmarshalStringMap[[]string](data)
|
||||
return
|
||||
}
|
||||
|
389
vendor/github.com/getkin/kin-openapi/openapi3/security_scheme.go
generated
vendored
389
vendor/github.com/getkin/kin-openapi/openapi3/security_scheme.go
generated
vendored
@ -2,31 +2,17 @@ package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type SecuritySchemes map[string]*SecuritySchemeRef
|
||||
|
||||
func (s SecuritySchemes) JSONLookup(token string) (interface{}, error) {
|
||||
ref, ok := s[token]
|
||||
if ref == nil || ok == false {
|
||||
return nil, fmt.Errorf("object has no field %q", token)
|
||||
}
|
||||
|
||||
if ref.Ref != "" {
|
||||
return &Ref{Ref: ref.Ref}, nil
|
||||
}
|
||||
return ref.Value, nil
|
||||
}
|
||||
|
||||
var _ jsonpointer.JSONPointable = (*SecuritySchemes)(nil)
|
||||
|
||||
// SecurityScheme is specified by OpenAPI/Swagger standard version 3.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#security-scheme-object
|
||||
type SecurityScheme struct {
|
||||
ExtensionProps
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
Type string `json:"type,omitempty" yaml:"type,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
@ -65,12 +51,70 @@ func NewJWTSecurityScheme() *SecurityScheme {
|
||||
}
|
||||
}
|
||||
|
||||
func (ss *SecurityScheme) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(ss)
|
||||
// MarshalJSON returns the JSON encoding of SecurityScheme.
|
||||
func (ss SecurityScheme) MarshalJSON() ([]byte, error) {
|
||||
x, err := ss.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of SecurityScheme.
|
||||
func (ss SecurityScheme) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 8+len(ss.Extensions))
|
||||
for k, v := range ss.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := ss.Type; x != "" {
|
||||
m["type"] = x
|
||||
}
|
||||
if x := ss.Description; x != "" {
|
||||
m["description"] = x
|
||||
}
|
||||
if x := ss.Name; x != "" {
|
||||
m["name"] = x
|
||||
}
|
||||
if x := ss.In; x != "" {
|
||||
m["in"] = x
|
||||
}
|
||||
if x := ss.Scheme; x != "" {
|
||||
m["scheme"] = x
|
||||
}
|
||||
if x := ss.BearerFormat; x != "" {
|
||||
m["bearerFormat"] = x
|
||||
}
|
||||
if x := ss.Flows; x != nil {
|
||||
m["flows"] = x
|
||||
}
|
||||
if x := ss.OpenIdConnectUrl; x != "" {
|
||||
m["openIdConnectUrl"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets SecurityScheme to a copy of data.
|
||||
func (ss *SecurityScheme) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, ss)
|
||||
type SecuritySchemeBis SecurityScheme
|
||||
var x SecuritySchemeBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "type")
|
||||
delete(x.Extensions, "description")
|
||||
delete(x.Extensions, "name")
|
||||
delete(x.Extensions, "in")
|
||||
delete(x.Extensions, "scheme")
|
||||
delete(x.Extensions, "bearerFormat")
|
||||
delete(x.Extensions, "flows")
|
||||
delete(x.Extensions, "openIdConnectUrl")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*ss = SecurityScheme(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ss *SecurityScheme) WithType(value string) *SecurityScheme {
|
||||
@ -103,15 +147,18 @@ func (ss *SecurityScheme) WithBearerFormat(value string) *SecurityScheme {
|
||||
return ss
|
||||
}
|
||||
|
||||
func (value *SecurityScheme) Validate(ctx context.Context) error {
|
||||
// Validate returns an error if SecurityScheme does not comply with the OpenAPI spec.
|
||||
func (ss *SecurityScheme) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
hasIn := false
|
||||
hasBearerFormat := false
|
||||
hasFlow := false
|
||||
switch value.Type {
|
||||
switch ss.Type {
|
||||
case "apiKey":
|
||||
hasIn = true
|
||||
case "http":
|
||||
scheme := value.Scheme
|
||||
scheme := ss.Scheme
|
||||
switch scheme {
|
||||
case "bearer":
|
||||
hasBearerFormat = true
|
||||
@ -122,52 +169,57 @@ func (value *SecurityScheme) Validate(ctx context.Context) error {
|
||||
case "oauth2":
|
||||
hasFlow = true
|
||||
case "openIdConnect":
|
||||
if value.OpenIdConnectUrl == "" {
|
||||
return fmt.Errorf("no OIDC URL found for openIdConnect security scheme %q", value.Name)
|
||||
if ss.OpenIdConnectUrl == "" {
|
||||
return fmt.Errorf("no OIDC URL found for openIdConnect security scheme %q", ss.Name)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("security scheme 'type' can't be %q", value.Type)
|
||||
return fmt.Errorf("security scheme 'type' can't be %q", ss.Type)
|
||||
}
|
||||
|
||||
// Validate "in" and "name"
|
||||
if hasIn {
|
||||
switch value.In {
|
||||
switch ss.In {
|
||||
case "query", "header", "cookie":
|
||||
default:
|
||||
return fmt.Errorf("security scheme of type 'apiKey' should have 'in'. It can be 'query', 'header' or 'cookie', not %q", value.In)
|
||||
return fmt.Errorf("security scheme of type 'apiKey' should have 'in'. It can be 'query', 'header' or 'cookie', not %q", ss.In)
|
||||
}
|
||||
if value.Name == "" {
|
||||
if ss.Name == "" {
|
||||
return errors.New("security scheme of type 'apiKey' should have 'name'")
|
||||
}
|
||||
} else if len(value.In) > 0 {
|
||||
return fmt.Errorf("security scheme of type %q can't have 'in'", value.Type)
|
||||
} else if len(value.Name) > 0 {
|
||||
return errors.New("security scheme of type 'apiKey' can't have 'name'")
|
||||
} else if len(ss.In) > 0 {
|
||||
return fmt.Errorf("security scheme of type %q can't have 'in'", ss.Type)
|
||||
} else if len(ss.Name) > 0 {
|
||||
return fmt.Errorf("security scheme of type %q can't have 'name'", ss.Type)
|
||||
}
|
||||
|
||||
// Validate "format"
|
||||
// "bearerFormat" is an arbitrary string so we only check if the scheme supports it
|
||||
if !hasBearerFormat && len(value.BearerFormat) > 0 {
|
||||
return fmt.Errorf("security scheme of type %q can't have 'bearerFormat'", value.Type)
|
||||
if !hasBearerFormat && len(ss.BearerFormat) > 0 {
|
||||
return fmt.Errorf("security scheme of type %q can't have 'bearerFormat'", ss.Type)
|
||||
}
|
||||
|
||||
// Validate "flow"
|
||||
if hasFlow {
|
||||
flow := value.Flows
|
||||
flow := ss.Flows
|
||||
if flow == nil {
|
||||
return fmt.Errorf("security scheme of type %q should have 'flows'", value.Type)
|
||||
return fmt.Errorf("security scheme of type %q should have 'flows'", ss.Type)
|
||||
}
|
||||
if err := flow.Validate(ctx); err != nil {
|
||||
return fmt.Errorf("security scheme 'flow' is invalid: %v", err)
|
||||
return fmt.Errorf("security scheme 'flow' is invalid: %w", err)
|
||||
}
|
||||
} else if value.Flows != nil {
|
||||
return fmt.Errorf("security scheme of type %q can't have 'flows'", value.Type)
|
||||
} else if ss.Flows != nil {
|
||||
return fmt.Errorf("security scheme of type %q can't have 'flows'", ss.Type)
|
||||
}
|
||||
return nil
|
||||
|
||||
return validateExtensions(ctx, ss.Extensions)
|
||||
}
|
||||
|
||||
// OAuthFlows is specified by OpenAPI/Swagger standard version 3.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#oauth-flows-object
|
||||
type OAuthFlows struct {
|
||||
ExtensionProps
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
Implicit *OAuthFlow `json:"implicit,omitempty" yaml:"implicit,omitempty"`
|
||||
Password *OAuthFlow `json:"password,omitempty" yaml:"password,omitempty"`
|
||||
ClientCredentials *OAuthFlow `json:"clientCredentials,omitempty" yaml:"clientCredentials,omitempty"`
|
||||
@ -183,59 +235,208 @@ const (
|
||||
oAuthFlowAuthorizationCode
|
||||
)
|
||||
|
||||
func (flows *OAuthFlows) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(flows)
|
||||
// MarshalJSON returns the JSON encoding of OAuthFlows.
|
||||
func (flows OAuthFlows) MarshalJSON() ([]byte, error) {
|
||||
x, err := flows.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of OAuthFlows.
|
||||
func (flows OAuthFlows) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 4+len(flows.Extensions))
|
||||
for k, v := range flows.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := flows.Implicit; x != nil {
|
||||
m["implicit"] = x
|
||||
}
|
||||
if x := flows.Password; x != nil {
|
||||
m["password"] = x
|
||||
}
|
||||
if x := flows.ClientCredentials; x != nil {
|
||||
m["clientCredentials"] = x
|
||||
}
|
||||
if x := flows.AuthorizationCode; x != nil {
|
||||
m["authorizationCode"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets OAuthFlows to a copy of data.
|
||||
func (flows *OAuthFlows) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, flows)
|
||||
}
|
||||
|
||||
func (flows *OAuthFlows) Validate(ctx context.Context) error {
|
||||
if v := flows.Implicit; v != nil {
|
||||
return v.Validate(ctx, oAuthFlowTypeImplicit)
|
||||
type OAuthFlowsBis OAuthFlows
|
||||
var x OAuthFlowsBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
if v := flows.Password; v != nil {
|
||||
return v.Validate(ctx, oAuthFlowTypePassword)
|
||||
}
|
||||
if v := flows.ClientCredentials; v != nil {
|
||||
return v.Validate(ctx, oAuthFlowTypeClientCredentials)
|
||||
}
|
||||
if v := flows.AuthorizationCode; v != nil {
|
||||
return v.Validate(ctx, oAuthFlowAuthorizationCode)
|
||||
}
|
||||
return errors.New("no OAuth flow is defined")
|
||||
}
|
||||
|
||||
type OAuthFlow struct {
|
||||
ExtensionProps
|
||||
AuthorizationURL string `json:"authorizationUrl,omitempty" yaml:"authorizationUrl,omitempty"`
|
||||
TokenURL string `json:"tokenUrl,omitempty" yaml:"tokenUrl,omitempty"`
|
||||
RefreshURL string `json:"refreshUrl,omitempty" yaml:"refreshUrl,omitempty"`
|
||||
Scopes map[string]string `json:"scopes" yaml:"scopes"`
|
||||
}
|
||||
|
||||
func (flow *OAuthFlow) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(flow)
|
||||
}
|
||||
|
||||
func (flow *OAuthFlow) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, flow)
|
||||
}
|
||||
|
||||
func (flow *OAuthFlow) Validate(ctx context.Context, typ oAuthFlowType) error {
|
||||
if typ == oAuthFlowAuthorizationCode || typ == oAuthFlowTypeImplicit {
|
||||
if v := flow.AuthorizationURL; v == "" {
|
||||
return errors.New("an OAuth flow is missing 'authorizationUrl in authorizationCode or implicit '")
|
||||
}
|
||||
}
|
||||
if typ != oAuthFlowTypeImplicit {
|
||||
if v := flow.TokenURL; v == "" {
|
||||
return errors.New("an OAuth flow is missing 'tokenUrl in not implicit'")
|
||||
}
|
||||
}
|
||||
if v := flow.Scopes; v == nil {
|
||||
return errors.New("an OAuth flow is missing 'scopes'")
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "implicit")
|
||||
delete(x.Extensions, "password")
|
||||
delete(x.Extensions, "clientCredentials")
|
||||
delete(x.Extensions, "authorizationCode")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*flows = OAuthFlows(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate returns an error if OAuthFlows does not comply with the OpenAPI spec.
|
||||
func (flows *OAuthFlows) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if v := flows.Implicit; v != nil {
|
||||
if err := v.validate(ctx, oAuthFlowTypeImplicit, opts...); err != nil {
|
||||
return fmt.Errorf("the OAuth flow 'implicit' is invalid: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if v := flows.Password; v != nil {
|
||||
if err := v.validate(ctx, oAuthFlowTypePassword, opts...); err != nil {
|
||||
return fmt.Errorf("the OAuth flow 'password' is invalid: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if v := flows.ClientCredentials; v != nil {
|
||||
if err := v.validate(ctx, oAuthFlowTypeClientCredentials, opts...); err != nil {
|
||||
return fmt.Errorf("the OAuth flow 'clientCredentials' is invalid: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if v := flows.AuthorizationCode; v != nil {
|
||||
if err := v.validate(ctx, oAuthFlowAuthorizationCode, opts...); err != nil {
|
||||
return fmt.Errorf("the OAuth flow 'authorizationCode' is invalid: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return validateExtensions(ctx, flows.Extensions)
|
||||
}
|
||||
|
||||
// OAuthFlow is specified by OpenAPI/Swagger standard version 3.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#oauth-flow-object
|
||||
type OAuthFlow struct {
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
AuthorizationURL string `json:"authorizationUrl,omitempty" yaml:"authorizationUrl,omitempty"`
|
||||
TokenURL string `json:"tokenUrl,omitempty" yaml:"tokenUrl,omitempty"`
|
||||
RefreshURL string `json:"refreshUrl,omitempty" yaml:"refreshUrl,omitempty"`
|
||||
Scopes StringMap `json:"scopes" yaml:"scopes"` // required
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of OAuthFlow.
|
||||
func (flow OAuthFlow) MarshalJSON() ([]byte, error) {
|
||||
x, err := flow.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of OAuthFlow.
|
||||
func (flow OAuthFlow) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 4+len(flow.Extensions))
|
||||
for k, v := range flow.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := flow.AuthorizationURL; x != "" {
|
||||
m["authorizationUrl"] = x
|
||||
}
|
||||
if x := flow.TokenURL; x != "" {
|
||||
m["tokenUrl"] = x
|
||||
}
|
||||
if x := flow.RefreshURL; x != "" {
|
||||
m["refreshUrl"] = x
|
||||
}
|
||||
m["scopes"] = flow.Scopes
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets OAuthFlow to a copy of data.
|
||||
func (flow *OAuthFlow) UnmarshalJSON(data []byte) error {
|
||||
type OAuthFlowBis OAuthFlow
|
||||
var x OAuthFlowBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "authorizationUrl")
|
||||
delete(x.Extensions, "tokenUrl")
|
||||
delete(x.Extensions, "refreshUrl")
|
||||
delete(x.Extensions, "scopes")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*flow = OAuthFlow(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate returns an error if OAuthFlows does not comply with the OpenAPI spec.
|
||||
func (flow *OAuthFlow) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if v := flow.RefreshURL; v != "" {
|
||||
if _, err := url.Parse(v); err != nil {
|
||||
return fmt.Errorf("field 'refreshUrl' is invalid: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if flow.Scopes == nil {
|
||||
return errors.New("field 'scopes' is missing")
|
||||
}
|
||||
|
||||
return validateExtensions(ctx, flow.Extensions)
|
||||
}
|
||||
|
||||
func (flow *OAuthFlow) validate(ctx context.Context, typ oAuthFlowType, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
typeIn := func(types ...oAuthFlowType) bool {
|
||||
for _, ty := range types {
|
||||
if ty == typ {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if in := typeIn(oAuthFlowTypeImplicit, oAuthFlowAuthorizationCode); true {
|
||||
switch {
|
||||
case flow.AuthorizationURL == "" && in:
|
||||
return errors.New("field 'authorizationUrl' is empty or missing")
|
||||
case flow.AuthorizationURL != "" && !in:
|
||||
return errors.New("field 'authorizationUrl' should not be set")
|
||||
case flow.AuthorizationURL != "":
|
||||
if _, err := url.Parse(flow.AuthorizationURL); err != nil {
|
||||
return fmt.Errorf("field 'authorizationUrl' is invalid: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if in := typeIn(oAuthFlowTypePassword, oAuthFlowTypeClientCredentials, oAuthFlowAuthorizationCode); true {
|
||||
switch {
|
||||
case flow.TokenURL == "" && in:
|
||||
return errors.New("field 'tokenUrl' is empty or missing")
|
||||
case flow.TokenURL != "" && !in:
|
||||
return errors.New("field 'tokenUrl' should not be set")
|
||||
case flow.TokenURL != "":
|
||||
if _, err := url.Parse(flow.TokenURL); err != nil {
|
||||
return fmt.Errorf("field 'tokenUrl' is invalid: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return flow.Validate(ctx, opts...)
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets SecuritySchemes to a copy of data.
|
||||
func (securitySchemes *SecuritySchemes) UnmarshalJSON(data []byte) (err error) {
|
||||
*securitySchemes, _, err = unmarshalStringMapP[SecuritySchemeRef](data)
|
||||
return
|
||||
}
|
||||
|
190
vendor/github.com/getkin/kin-openapi/openapi3/server.go
generated
vendored
190
vendor/github.com/getkin/kin-openapi/openapi3/server.go
generated
vendored
@ -2,21 +2,22 @@ package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/getkin/kin-openapi/jsoninfo"
|
||||
)
|
||||
|
||||
// Servers is specified by OpenAPI/Swagger standard version 3.0.
|
||||
// Servers is specified by OpenAPI/Swagger standard version 3.
|
||||
type Servers []*Server
|
||||
|
||||
// Validate ensures servers are per the OpenAPIv3 specification.
|
||||
func (value Servers) Validate(ctx context.Context) error {
|
||||
for _, v := range value {
|
||||
// Validate returns an error if Servers does not comply with the OpenAPI spec.
|
||||
func (servers Servers) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
for _, v := range servers {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -24,6 +25,14 @@ func (value Servers) Validate(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// BasePath returns the base path of the first server in the list, or /.
|
||||
func (servers Servers) BasePath() (string, error) {
|
||||
for _, server := range servers {
|
||||
return server.BasePath()
|
||||
}
|
||||
return "/", nil
|
||||
}
|
||||
|
||||
func (servers Servers) MatchURL(parsedURL *url.URL) (*Server, []string, string) {
|
||||
rawURL := parsedURL.String()
|
||||
if i := strings.IndexByte(rawURL, '?'); i >= 0 {
|
||||
@ -38,20 +47,83 @@ func (servers Servers) MatchURL(parsedURL *url.URL) (*Server, []string, string)
|
||||
return nil, nil, ""
|
||||
}
|
||||
|
||||
// Server is specified by OpenAPI/Swagger standard version 3.0.
|
||||
// Server is specified by OpenAPI/Swagger standard version 3.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#server-object
|
||||
type Server struct {
|
||||
ExtensionProps
|
||||
URL string `json:"url" yaml:"url"`
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
URL string `json:"url" yaml:"url"` // Required
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
Variables map[string]*ServerVariable `json:"variables,omitempty" yaml:"variables,omitempty"`
|
||||
}
|
||||
|
||||
func (server *Server) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(server)
|
||||
// BasePath returns the base path extracted from the default values of variables, if any.
|
||||
// Assumes a valid struct (per Validate()).
|
||||
func (server *Server) BasePath() (string, error) {
|
||||
if server == nil {
|
||||
return "/", nil
|
||||
}
|
||||
|
||||
uri := server.URL
|
||||
for name, svar := range server.Variables {
|
||||
uri = strings.ReplaceAll(uri, "{"+name+"}", svar.Default)
|
||||
}
|
||||
|
||||
u, err := url.ParseRequestURI(uri)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if bp := u.Path; bp != "" {
|
||||
return bp, nil
|
||||
}
|
||||
|
||||
return "/", nil
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of Server.
|
||||
func (server Server) MarshalJSON() ([]byte, error) {
|
||||
x, err := server.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of Server.
|
||||
func (server Server) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 3+len(server.Extensions))
|
||||
for k, v := range server.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
m["url"] = server.URL
|
||||
if x := server.Description; x != "" {
|
||||
m["description"] = x
|
||||
}
|
||||
if x := server.Variables; len(x) != 0 {
|
||||
m["variables"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Server to a copy of data.
|
||||
func (server *Server) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, server)
|
||||
type ServerBis Server
|
||||
var x ServerBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "url")
|
||||
delete(x.Extensions, "description")
|
||||
delete(x.Extensions, "variables")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*server = Server(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (server Server) ParameterNames() ([]string, error) {
|
||||
@ -101,7 +173,7 @@ func (server Server) MatchRawURL(input string) ([]string, string, bool) {
|
||||
} else if ns < 0 {
|
||||
i = np
|
||||
} else {
|
||||
i = int(math.Min(float64(np), float64(ns)))
|
||||
i = min(np, ns)
|
||||
}
|
||||
if i < 0 {
|
||||
i = len(input)
|
||||
@ -125,51 +197,109 @@ func (server Server) MatchRawURL(input string) ([]string, string, bool) {
|
||||
return params, input, true
|
||||
}
|
||||
|
||||
func (value *Server) Validate(ctx context.Context) (err error) {
|
||||
if value.URL == "" {
|
||||
// Validate returns an error if Server does not comply with the OpenAPI spec.
|
||||
func (server *Server) Validate(ctx context.Context, opts ...ValidationOption) (err error) {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if server.URL == "" {
|
||||
return errors.New("value of url must be a non-empty string")
|
||||
}
|
||||
opening, closing := strings.Count(value.URL, "{"), strings.Count(value.URL, "}")
|
||||
|
||||
opening, closing := strings.Count(server.URL, "{"), strings.Count(server.URL, "}")
|
||||
if opening != closing {
|
||||
return errors.New("server URL has mismatched { and }")
|
||||
}
|
||||
if opening != len(value.Variables) {
|
||||
|
||||
if opening != len(server.Variables) {
|
||||
return errors.New("server has undeclared variables")
|
||||
}
|
||||
for name, v := range value.Variables {
|
||||
if !strings.Contains(value.URL, fmt.Sprintf("{%s}", name)) {
|
||||
|
||||
variables := make([]string, 0, len(server.Variables))
|
||||
for name := range server.Variables {
|
||||
variables = append(variables, name)
|
||||
}
|
||||
sort.Strings(variables)
|
||||
for _, name := range variables {
|
||||
v := server.Variables[name]
|
||||
if !strings.Contains(server.URL, "{"+name+"}") {
|
||||
return errors.New("server has undeclared variables")
|
||||
}
|
||||
if err = v.Validate(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
return validateExtensions(ctx, server.Extensions)
|
||||
}
|
||||
|
||||
// ServerVariable is specified by OpenAPI/Swagger standard version 3.0.
|
||||
// ServerVariable is specified by OpenAPI/Swagger standard version 3.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#server-variable-object
|
||||
type ServerVariable struct {
|
||||
ExtensionProps
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
Enum []string `json:"enum,omitempty" yaml:"enum,omitempty"`
|
||||
Default string `json:"default,omitempty" yaml:"default,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
}
|
||||
|
||||
func (serverVariable *ServerVariable) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(serverVariable)
|
||||
// MarshalJSON returns the JSON encoding of ServerVariable.
|
||||
func (serverVariable ServerVariable) MarshalJSON() ([]byte, error) {
|
||||
x, err := serverVariable.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of ServerVariable.
|
||||
func (serverVariable ServerVariable) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 4+len(serverVariable.Extensions))
|
||||
for k, v := range serverVariable.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := serverVariable.Enum; len(x) != 0 {
|
||||
m["enum"] = x
|
||||
}
|
||||
if x := serverVariable.Default; x != "" {
|
||||
m["default"] = x
|
||||
}
|
||||
if x := serverVariable.Description; x != "" {
|
||||
m["description"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets ServerVariable to a copy of data.
|
||||
func (serverVariable *ServerVariable) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, serverVariable)
|
||||
type ServerVariableBis ServerVariable
|
||||
var x ServerVariableBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "enum")
|
||||
delete(x.Extensions, "default")
|
||||
delete(x.Extensions, "description")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*serverVariable = ServerVariable(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (value *ServerVariable) Validate(ctx context.Context) error {
|
||||
if value.Default == "" {
|
||||
data, err := value.MarshalJSON()
|
||||
// Validate returns an error if ServerVariable does not comply with the OpenAPI spec.
|
||||
func (serverVariable *ServerVariable) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if serverVariable.Default == "" {
|
||||
data, err := serverVariable.MarshalJSON()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("field default is required in %s", data)
|
||||
}
|
||||
return nil
|
||||
|
||||
return validateExtensions(ctx, serverVariable.Extensions)
|
||||
}
|
||||
|
88
vendor/github.com/getkin/kin-openapi/openapi3/stringmap.go
generated
vendored
Normal file
88
vendor/github.com/getkin/kin-openapi/openapi3/stringmap.go
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
package openapi3
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// StringMap is a map[string]string that ignores the origin in the underlying json representation.
|
||||
type StringMap map[string]string
|
||||
|
||||
// UnmarshalJSON sets StringMap to a copy of data.
|
||||
func (stringMap *StringMap) UnmarshalJSON(data []byte) (err error) {
|
||||
*stringMap, _, err = unmarshalStringMap[string](data)
|
||||
return
|
||||
}
|
||||
|
||||
// unmarshalStringMapP unmarshals given json into a map[string]*V
|
||||
func unmarshalStringMapP[V any](data []byte) (map[string]*V, *Origin, error) {
|
||||
var m map[string]any
|
||||
if err := json.Unmarshal(data, &m); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
origin, err := popOrigin(m, originKey)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
result := make(map[string]*V, len(m))
|
||||
for k, v := range m {
|
||||
value, err := deepCast[V](v)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
result[k] = value
|
||||
}
|
||||
|
||||
return result, origin, nil
|
||||
}
|
||||
|
||||
// unmarshalStringMap unmarshals given json into a map[string]V
|
||||
func unmarshalStringMap[V any](data []byte) (map[string]V, *Origin, error) {
|
||||
var m map[string]any
|
||||
if err := json.Unmarshal(data, &m); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
origin, err := popOrigin(m, originKey)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
result := make(map[string]V, len(m))
|
||||
for k, v := range m {
|
||||
value, err := deepCast[V](v)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
result[k] = *value
|
||||
}
|
||||
|
||||
return result, origin, nil
|
||||
}
|
||||
|
||||
// deepCast casts any value to a value of type V.
|
||||
func deepCast[V any](value any) (*V, error) {
|
||||
data, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result V
|
||||
if err = json.Unmarshal(data, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// popOrigin removes the origin from the map and returns it.
|
||||
func popOrigin(m map[string]any, key string) (*Origin, error) {
|
||||
if !IncludeOrigin {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
origin, err := deepCast[Origin](m[key])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
delete(m, key)
|
||||
return origin, nil
|
||||
}
|
82
vendor/github.com/getkin/kin-openapi/openapi3/tag.go
generated
vendored
82
vendor/github.com/getkin/kin-openapi/openapi3/tag.go
generated
vendored
@ -1,6 +1,10 @@
|
||||
package openapi3
|
||||
|
||||
import "github.com/getkin/kin-openapi/jsoninfo"
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Tags is specified by OpenAPI/Swagger 3.0 standard.
|
||||
type Tags []*Tag
|
||||
@ -14,18 +18,84 @@ func (tags Tags) Get(name string) *Tag {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate returns an error if Tags does not comply with the OpenAPI spec.
|
||||
func (tags Tags) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
for _, v := range tags {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Tag is specified by OpenAPI/Swagger 3.0 standard.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#tag-object
|
||||
type Tag struct {
|
||||
ExtensionProps
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
ExternalDocs *ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
|
||||
}
|
||||
|
||||
func (t *Tag) MarshalJSON() ([]byte, error) {
|
||||
return jsoninfo.MarshalStrictStruct(t)
|
||||
// MarshalJSON returns the JSON encoding of Tag.
|
||||
func (t Tag) MarshalJSON() ([]byte, error) {
|
||||
x, err := t.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
func (t *Tag) UnmarshalJSON(data []byte) error {
|
||||
return jsoninfo.UnmarshalStrictStruct(data, t)
|
||||
// MarshalYAML returns the YAML encoding of Tag.
|
||||
func (t Tag) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 3+len(t.Extensions))
|
||||
for k, v := range t.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := t.Name; x != "" {
|
||||
m["name"] = x
|
||||
}
|
||||
if x := t.Description; x != "" {
|
||||
m["description"] = x
|
||||
}
|
||||
if x := t.ExternalDocs; x != nil {
|
||||
m["externalDocs"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets Tag to a copy of data.
|
||||
func (t *Tag) UnmarshalJSON(data []byte) error {
|
||||
type TagBis Tag
|
||||
var x TagBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "name")
|
||||
delete(x.Extensions, "description")
|
||||
delete(x.Extensions, "externalDocs")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*t = Tag(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate returns an error if Tag does not comply with the OpenAPI spec.
|
||||
func (t *Tag) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
if v := t.ExternalDocs; v != nil {
|
||||
if err := v.Validate(ctx); err != nil {
|
||||
return fmt.Errorf("invalid external docs: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return validateExtensions(ctx, t.Extensions)
|
||||
}
|
||||
|
142
vendor/github.com/getkin/kin-openapi/openapi3/validation_options.go
generated
vendored
Normal file
142
vendor/github.com/getkin/kin-openapi/openapi3/validation_options.go
generated
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
package openapi3
|
||||
|
||||
import "context"
|
||||
|
||||
// ValidationOption allows the modification of how the OpenAPI document is validated.
|
||||
type ValidationOption func(options *ValidationOptions)
|
||||
|
||||
// ValidationOptions provides configuration for validating OpenAPI documents.
|
||||
type ValidationOptions struct {
|
||||
examplesValidationAsReq, examplesValidationAsRes bool
|
||||
examplesValidationDisabled bool
|
||||
schemaDefaultsValidationDisabled bool
|
||||
schemaFormatValidationEnabled bool
|
||||
schemaPatternValidationDisabled bool
|
||||
schemaExtensionsInRefProhibited bool
|
||||
regexCompilerFunc RegexCompilerFunc
|
||||
extraSiblingFieldsAllowed map[string]struct{}
|
||||
}
|
||||
|
||||
type validationOptionsKey struct{}
|
||||
|
||||
// AllowExtraSiblingFields called as AllowExtraSiblingFields("description") makes Validate not return an error when said field appears next to a $ref.
|
||||
func AllowExtraSiblingFields(fields ...string) ValidationOption {
|
||||
return func(options *ValidationOptions) {
|
||||
if options.extraSiblingFieldsAllowed == nil && len(fields) != 0 {
|
||||
options.extraSiblingFieldsAllowed = make(map[string]struct{}, len(fields))
|
||||
}
|
||||
for _, field := range fields {
|
||||
options.extraSiblingFieldsAllowed[field] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// EnableSchemaFormatValidation makes Validate not return an error when validating documents that mention schema formats that are not defined by the OpenAPIv3 specification.
|
||||
// By default, schema format validation is disabled.
|
||||
func EnableSchemaFormatValidation() ValidationOption {
|
||||
return func(options *ValidationOptions) {
|
||||
options.schemaFormatValidationEnabled = true
|
||||
}
|
||||
}
|
||||
|
||||
// DisableSchemaFormatValidation does the opposite of EnableSchemaFormatValidation.
|
||||
// By default, schema format validation is disabled.
|
||||
func DisableSchemaFormatValidation() ValidationOption {
|
||||
return func(options *ValidationOptions) {
|
||||
options.schemaFormatValidationEnabled = false
|
||||
}
|
||||
}
|
||||
|
||||
// EnableSchemaPatternValidation does the opposite of DisableSchemaPatternValidation.
|
||||
// By default, schema pattern validation is enabled.
|
||||
func EnableSchemaPatternValidation() ValidationOption {
|
||||
return func(options *ValidationOptions) {
|
||||
options.schemaPatternValidationDisabled = false
|
||||
}
|
||||
}
|
||||
|
||||
// DisableSchemaPatternValidation makes Validate not return an error when validating patterns that are not supported by the Go regexp engine.
|
||||
func DisableSchemaPatternValidation() ValidationOption {
|
||||
return func(options *ValidationOptions) {
|
||||
options.schemaPatternValidationDisabled = true
|
||||
}
|
||||
}
|
||||
|
||||
// EnableSchemaDefaultsValidation does the opposite of DisableSchemaDefaultsValidation.
|
||||
// By default, schema default values are validated against their schema.
|
||||
func EnableSchemaDefaultsValidation() ValidationOption {
|
||||
return func(options *ValidationOptions) {
|
||||
options.schemaDefaultsValidationDisabled = false
|
||||
}
|
||||
}
|
||||
|
||||
// DisableSchemaDefaultsValidation disables schemas' default field validation.
|
||||
// By default, schema default values are validated against their schema.
|
||||
func DisableSchemaDefaultsValidation() ValidationOption {
|
||||
return func(options *ValidationOptions) {
|
||||
options.schemaDefaultsValidationDisabled = true
|
||||
}
|
||||
}
|
||||
|
||||
// EnableExamplesValidation does the opposite of DisableExamplesValidation.
|
||||
// By default, all schema examples are validated.
|
||||
func EnableExamplesValidation() ValidationOption {
|
||||
return func(options *ValidationOptions) {
|
||||
options.examplesValidationDisabled = false
|
||||
}
|
||||
}
|
||||
|
||||
// DisableExamplesValidation disables all example schema validation.
|
||||
// By default, all schema examples are validated.
|
||||
func DisableExamplesValidation() ValidationOption {
|
||||
return func(options *ValidationOptions) {
|
||||
options.examplesValidationDisabled = true
|
||||
}
|
||||
}
|
||||
|
||||
// AllowExtensionsWithRef allows extensions (fields starting with 'x-')
|
||||
// as siblings for $ref fields. This is the default.
|
||||
// Non-extension fields are prohibited unless allowed explicitly with the
|
||||
// AllowExtraSiblingFields option.
|
||||
func AllowExtensionsWithRef() ValidationOption {
|
||||
return func(options *ValidationOptions) {
|
||||
options.schemaExtensionsInRefProhibited = false
|
||||
}
|
||||
}
|
||||
|
||||
// ProhibitExtensionsWithRef causes the validation to return an
|
||||
// error if extensions (fields starting with 'x-') are found as
|
||||
// siblings for $ref fields. Non-extension fields are prohibited
|
||||
// unless allowed explicitly with the AllowExtraSiblingFields option.
|
||||
func ProhibitExtensionsWithRef() ValidationOption {
|
||||
return func(options *ValidationOptions) {
|
||||
options.schemaExtensionsInRefProhibited = true
|
||||
}
|
||||
}
|
||||
|
||||
// SetRegexCompiler allows to override the regex implementation used to validate
|
||||
// field "pattern".
|
||||
func SetRegexCompiler(c RegexCompilerFunc) ValidationOption {
|
||||
return func(options *ValidationOptions) {
|
||||
options.regexCompilerFunc = c
|
||||
}
|
||||
}
|
||||
|
||||
// WithValidationOptions allows adding validation options to a context object that can be used when validating any OpenAPI type.
|
||||
func WithValidationOptions(ctx context.Context, opts ...ValidationOption) context.Context {
|
||||
if len(opts) == 0 {
|
||||
return ctx
|
||||
}
|
||||
options := &ValidationOptions{}
|
||||
for _, opt := range opts {
|
||||
opt(options)
|
||||
}
|
||||
return context.WithValue(ctx, validationOptionsKey{}, options)
|
||||
}
|
||||
|
||||
func getValidationOptions(ctx context.Context) *ValidationOptions {
|
||||
if options, ok := ctx.Value(validationOptionsKey{}).(*ValidationOptions); ok {
|
||||
return options
|
||||
}
|
||||
return &ValidationOptions{}
|
||||
}
|
41
vendor/github.com/getkin/kin-openapi/openapi3/visited.go
generated
vendored
Normal file
41
vendor/github.com/getkin/kin-openapi/openapi3/visited.go
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
package openapi3
|
||||
|
||||
func newVisited() visitedComponent {
|
||||
return visitedComponent{
|
||||
header: make(map[*Header]struct{}),
|
||||
schema: make(map[*Schema]struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
type visitedComponent struct {
|
||||
header map[*Header]struct{}
|
||||
schema map[*Schema]struct{}
|
||||
}
|
||||
|
||||
// resetVisited clears visitedComponent map
|
||||
// should be called before recursion over doc *T
|
||||
func (doc *T) resetVisited() {
|
||||
doc.visited = newVisited()
|
||||
}
|
||||
|
||||
// isVisitedHeader returns `true` if the *Header pointer was already visited
|
||||
// otherwise it returns `false`
|
||||
func (doc *T) isVisitedHeader(h *Header) bool {
|
||||
if _, ok := doc.visited.header[h]; ok {
|
||||
return true
|
||||
}
|
||||
|
||||
doc.visited.header[h] = struct{}{}
|
||||
return false
|
||||
}
|
||||
|
||||
// isVisitedHeader returns `true` if the *Schema pointer was already visited
|
||||
// otherwise it returns `false`
|
||||
func (doc *T) isVisitedSchema(s *Schema) bool {
|
||||
if _, ok := doc.visited.schema[s]; ok {
|
||||
return true
|
||||
}
|
||||
|
||||
doc.visited.schema[s] = struct{}{}
|
||||
return false
|
||||
}
|
80
vendor/github.com/getkin/kin-openapi/openapi3/xml.go
generated
vendored
Normal file
80
vendor/github.com/getkin/kin-openapi/openapi3/xml.go
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
package openapi3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// XML is specified by OpenAPI/Swagger standard version 3.
|
||||
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#xml-object
|
||||
type XML struct {
|
||||
Extensions map[string]any `json:"-" yaml:"-"`
|
||||
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
|
||||
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty"`
|
||||
Attribute bool `json:"attribute,omitempty" yaml:"attribute,omitempty"`
|
||||
Wrapped bool `json:"wrapped,omitempty" yaml:"wrapped,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON returns the JSON encoding of XML.
|
||||
func (xml XML) MarshalJSON() ([]byte, error) {
|
||||
x, err := xml.MarshalYAML()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// MarshalYAML returns the YAML encoding of XML.
|
||||
func (xml XML) MarshalYAML() (any, error) {
|
||||
m := make(map[string]any, 5+len(xml.Extensions))
|
||||
for k, v := range xml.Extensions {
|
||||
m[k] = v
|
||||
}
|
||||
if x := xml.Name; x != "" {
|
||||
m["name"] = x
|
||||
}
|
||||
if x := xml.Namespace; x != "" {
|
||||
m["namespace"] = x
|
||||
}
|
||||
if x := xml.Prefix; x != "" {
|
||||
m["prefix"] = x
|
||||
}
|
||||
if x := xml.Attribute; x {
|
||||
m["attribute"] = x
|
||||
}
|
||||
if x := xml.Wrapped; x {
|
||||
m["wrapped"] = x
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets XML to a copy of data.
|
||||
func (xml *XML) UnmarshalJSON(data []byte) error {
|
||||
type XMLBis XML
|
||||
var x XMLBis
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return unmarshalError(err)
|
||||
}
|
||||
_ = json.Unmarshal(data, &x.Extensions)
|
||||
delete(x.Extensions, originKey)
|
||||
delete(x.Extensions, "name")
|
||||
delete(x.Extensions, "namespace")
|
||||
delete(x.Extensions, "prefix")
|
||||
delete(x.Extensions, "attribute")
|
||||
delete(x.Extensions, "wrapped")
|
||||
if len(x.Extensions) == 0 {
|
||||
x.Extensions = nil
|
||||
}
|
||||
*xml = XML(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate returns an error if XML does not comply with the OpenAPI spec.
|
||||
func (xml *XML) Validate(ctx context.Context, opts ...ValidationOption) error {
|
||||
ctx = WithValidationOptions(ctx, opts...)
|
||||
|
||||
return validateExtensions(ctx, xml.Extensions)
|
||||
}
|
61
vendor/github.com/go-openapi/jsonpointer/.golangci.yml
generated
vendored
Normal file
61
vendor/github.com/go-openapi/jsonpointer/.golangci.yml
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
linters-settings:
|
||||
govet:
|
||||
check-shadowing: true
|
||||
golint:
|
||||
min-confidence: 0
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
maligned:
|
||||
suggest-new: true
|
||||
dupl:
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
|
||||
linters:
|
||||
enable-all: true
|
||||
disable:
|
||||
- maligned
|
||||
- unparam
|
||||
- lll
|
||||
- gochecknoinits
|
||||
- gochecknoglobals
|
||||
- funlen
|
||||
- godox
|
||||
- gocognit
|
||||
- whitespace
|
||||
- wsl
|
||||
- wrapcheck
|
||||
- testpackage
|
||||
- nlreturn
|
||||
- gomnd
|
||||
- exhaustivestruct
|
||||
- goerr113
|
||||
- errorlint
|
||||
- nestif
|
||||
- godot
|
||||
- gofumpt
|
||||
- paralleltest
|
||||
- tparallel
|
||||
- thelper
|
||||
- ifshort
|
||||
- exhaustruct
|
||||
- varnamelen
|
||||
- gci
|
||||
- depguard
|
||||
- errchkjson
|
||||
- inamedparam
|
||||
- nonamedreturns
|
||||
- musttag
|
||||
- ireturn
|
||||
- forcetypeassert
|
||||
- cyclop
|
||||
# deprecated linters
|
||||
- deadcode
|
||||
- interfacer
|
||||
- scopelint
|
||||
- varcheck
|
||||
- structcheck
|
||||
- golint
|
||||
- nosnakecase
|
8
vendor/github.com/go-openapi/jsonpointer/README.md
generated
vendored
8
vendor/github.com/go-openapi/jsonpointer/README.md
generated
vendored
@ -1,6 +1,10 @@
|
||||
# gojsonpointer [](https://travis-ci.org/go-openapi/jsonpointer) [](https://codecov.io/gh/go-openapi/jsonpointer) [](https://slackin.goswagger.io)
|
||||
# gojsonpointer [](https://github.com/go-openapi/jsonpointer/actions?query=workflow%3A"go+test") [](https://codecov.io/gh/go-openapi/jsonpointer)
|
||||
|
||||
[](https://slackin.goswagger.io)
|
||||
[](https://raw.githubusercontent.com/go-openapi/jsonpointer/master/LICENSE)
|
||||
[](https://pkg.go.dev/github.com/go-openapi/jsonpointer)
|
||||
[](https://goreportcard.com/report/github.com/go-openapi/jsonpointer)
|
||||
|
||||
[](https://raw.githubusercontent.com/go-openapi/jsonpointer/master/LICENSE) [](http://godoc.org/github.com/go-openapi/jsonpointer)
|
||||
An implementation of JSON Pointer - Go language
|
||||
|
||||
## Status
|
||||
|
191
vendor/github.com/go-openapi/jsonpointer/pointer.go
generated
vendored
191
vendor/github.com/go-openapi/jsonpointer/pointer.go
generated
vendored
@ -26,6 +26,7 @@
|
||||
package jsonpointer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
@ -40,6 +41,7 @@ const (
|
||||
pointerSeparator = `/`
|
||||
|
||||
invalidStart = `JSON pointer must be empty or start with a "` + pointerSeparator
|
||||
notFound = `Can't find the pointer in the document`
|
||||
)
|
||||
|
||||
var jsonPointableType = reflect.TypeOf(new(JSONPointable)).Elem()
|
||||
@ -48,13 +50,13 @@ var jsonSetableType = reflect.TypeOf(new(JSONSetable)).Elem()
|
||||
// JSONPointable is an interface for structs to implement when they need to customize the
|
||||
// json pointer process
|
||||
type JSONPointable interface {
|
||||
JSONLookup(string) (interface{}, error)
|
||||
JSONLookup(string) (any, error)
|
||||
}
|
||||
|
||||
// JSONSetable is an interface for structs to implement when they need to customize the
|
||||
// json pointer process
|
||||
type JSONSetable interface {
|
||||
JSONSet(string, interface{}) error
|
||||
JSONSet(string, any) error
|
||||
}
|
||||
|
||||
// New creates a new json pointer for the given string
|
||||
@ -81,9 +83,7 @@ func (p *Pointer) parse(jsonPointerString string) error {
|
||||
err = errors.New(invalidStart)
|
||||
} else {
|
||||
referenceTokens := strings.Split(jsonPointerString, pointerSeparator)
|
||||
for _, referenceToken := range referenceTokens[1:] {
|
||||
p.referenceTokens = append(p.referenceTokens, referenceToken)
|
||||
}
|
||||
p.referenceTokens = append(p.referenceTokens, referenceTokens[1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,38 +91,58 @@ func (p *Pointer) parse(jsonPointerString string) error {
|
||||
}
|
||||
|
||||
// Get uses the pointer to retrieve a value from a JSON document
|
||||
func (p *Pointer) Get(document interface{}) (interface{}, reflect.Kind, error) {
|
||||
func (p *Pointer) Get(document any) (any, reflect.Kind, error) {
|
||||
return p.get(document, swag.DefaultJSONNameProvider)
|
||||
}
|
||||
|
||||
// Set uses the pointer to set a value from a JSON document
|
||||
func (p *Pointer) Set(document interface{}, value interface{}) (interface{}, error) {
|
||||
func (p *Pointer) Set(document any, value any) (any, error) {
|
||||
return document, p.set(document, value, swag.DefaultJSONNameProvider)
|
||||
}
|
||||
|
||||
// GetForToken gets a value for a json pointer token 1 level deep
|
||||
func GetForToken(document interface{}, decodedToken string) (interface{}, reflect.Kind, error) {
|
||||
func GetForToken(document any, decodedToken string) (any, reflect.Kind, error) {
|
||||
return getSingleImpl(document, decodedToken, swag.DefaultJSONNameProvider)
|
||||
}
|
||||
|
||||
// SetForToken gets a value for a json pointer token 1 level deep
|
||||
func SetForToken(document interface{}, decodedToken string, value interface{}) (interface{}, error) {
|
||||
func SetForToken(document any, decodedToken string, value any) (any, error) {
|
||||
return document, setSingleImpl(document, value, decodedToken, swag.DefaultJSONNameProvider)
|
||||
}
|
||||
|
||||
func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.NameProvider) (interface{}, reflect.Kind, error) {
|
||||
func isNil(input any) bool {
|
||||
if input == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
kind := reflect.TypeOf(input).Kind()
|
||||
switch kind { //nolint:exhaustive
|
||||
case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Chan:
|
||||
return reflect.ValueOf(input).IsNil()
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func getSingleImpl(node any, decodedToken string, nameProvider *swag.NameProvider) (any, reflect.Kind, error) {
|
||||
rValue := reflect.Indirect(reflect.ValueOf(node))
|
||||
kind := rValue.Kind()
|
||||
if isNil(node) {
|
||||
return nil, kind, fmt.Errorf("nil value has not field %q", decodedToken)
|
||||
}
|
||||
|
||||
if rValue.Type().Implements(jsonPointableType) {
|
||||
r, err := node.(JSONPointable).JSONLookup(decodedToken)
|
||||
switch typed := node.(type) {
|
||||
case JSONPointable:
|
||||
r, err := typed.JSONLookup(decodedToken)
|
||||
if err != nil {
|
||||
return nil, kind, err
|
||||
}
|
||||
return r, kind, nil
|
||||
case *any: // case of a pointer to interface, that is not resolved by reflect.Indirect
|
||||
return getSingleImpl(*typed, decodedToken, nameProvider)
|
||||
}
|
||||
|
||||
switch kind {
|
||||
switch kind { //nolint:exhaustive
|
||||
case reflect.Struct:
|
||||
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
|
||||
if !ok {
|
||||
@ -159,7 +179,7 @@ func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.Nam
|
||||
|
||||
}
|
||||
|
||||
func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *swag.NameProvider) error {
|
||||
func setSingleImpl(node, data any, decodedToken string, nameProvider *swag.NameProvider) error {
|
||||
rValue := reflect.Indirect(reflect.ValueOf(node))
|
||||
|
||||
if ns, ok := node.(JSONSetable); ok { // pointer impl
|
||||
@ -170,7 +190,7 @@ func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *sw
|
||||
return node.(JSONSetable).JSONSet(decodedToken, data)
|
||||
}
|
||||
|
||||
switch rValue.Kind() {
|
||||
switch rValue.Kind() { //nolint:exhaustive
|
||||
case reflect.Struct:
|
||||
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
|
||||
if !ok {
|
||||
@ -210,7 +230,7 @@ func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *sw
|
||||
|
||||
}
|
||||
|
||||
func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interface{}, reflect.Kind, error) {
|
||||
func (p *Pointer) get(node any, nameProvider *swag.NameProvider) (any, reflect.Kind, error) {
|
||||
|
||||
if nameProvider == nil {
|
||||
nameProvider = swag.DefaultJSONNameProvider
|
||||
@ -231,8 +251,7 @@ func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interf
|
||||
if err != nil {
|
||||
return nil, knd, err
|
||||
}
|
||||
node, kind = r, knd
|
||||
|
||||
node = r
|
||||
}
|
||||
|
||||
rValue := reflect.ValueOf(node)
|
||||
@ -241,11 +260,11 @@ func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interf
|
||||
return node, kind, nil
|
||||
}
|
||||
|
||||
func (p *Pointer) set(node, data interface{}, nameProvider *swag.NameProvider) error {
|
||||
func (p *Pointer) set(node, data any, nameProvider *swag.NameProvider) error {
|
||||
knd := reflect.ValueOf(node).Kind()
|
||||
|
||||
if knd != reflect.Ptr && knd != reflect.Struct && knd != reflect.Map && knd != reflect.Slice && knd != reflect.Array {
|
||||
return fmt.Errorf("only structs, pointers, maps and slices are supported for setting values")
|
||||
return errors.New("only structs, pointers, maps and slices are supported for setting values")
|
||||
}
|
||||
|
||||
if nameProvider == nil {
|
||||
@ -284,7 +303,7 @@ func (p *Pointer) set(node, data interface{}, nameProvider *swag.NameProvider) e
|
||||
continue
|
||||
}
|
||||
|
||||
switch kind {
|
||||
switch kind { //nolint:exhaustive
|
||||
case reflect.Struct:
|
||||
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
|
||||
if !ok {
|
||||
@ -363,6 +382,128 @@ func (p *Pointer) String() string {
|
||||
return pointerString
|
||||
}
|
||||
|
||||
func (p *Pointer) Offset(document string) (int64, error) {
|
||||
dec := json.NewDecoder(strings.NewReader(document))
|
||||
var offset int64
|
||||
for _, ttk := range p.DecodedTokens() {
|
||||
tk, err := dec.Token()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
switch tk := tk.(type) {
|
||||
case json.Delim:
|
||||
switch tk {
|
||||
case '{':
|
||||
offset, err = offsetSingleObject(dec, ttk)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
case '[':
|
||||
offset, err = offsetSingleArray(dec, ttk)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
default:
|
||||
return 0, fmt.Errorf("invalid token %#v", tk)
|
||||
}
|
||||
default:
|
||||
return 0, fmt.Errorf("invalid token %#v", tk)
|
||||
}
|
||||
}
|
||||
return offset, nil
|
||||
}
|
||||
|
||||
func offsetSingleObject(dec *json.Decoder, decodedToken string) (int64, error) {
|
||||
for dec.More() {
|
||||
offset := dec.InputOffset()
|
||||
tk, err := dec.Token()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
switch tk := tk.(type) {
|
||||
case json.Delim:
|
||||
switch tk {
|
||||
case '{':
|
||||
if err = drainSingle(dec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
case '[':
|
||||
if err = drainSingle(dec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
case string:
|
||||
if tk == decodedToken {
|
||||
return offset, nil
|
||||
}
|
||||
default:
|
||||
return 0, fmt.Errorf("invalid token %#v", tk)
|
||||
}
|
||||
}
|
||||
return 0, fmt.Errorf("token reference %q not found", decodedToken)
|
||||
}
|
||||
|
||||
func offsetSingleArray(dec *json.Decoder, decodedToken string) (int64, error) {
|
||||
idx, err := strconv.Atoi(decodedToken)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("token reference %q is not a number: %v", decodedToken, err)
|
||||
}
|
||||
var i int
|
||||
for i = 0; i < idx && dec.More(); i++ {
|
||||
tk, err := dec.Token()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if delim, isDelim := tk.(json.Delim); isDelim {
|
||||
switch delim {
|
||||
case '{':
|
||||
if err = drainSingle(dec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
case '[':
|
||||
if err = drainSingle(dec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !dec.More() {
|
||||
return 0, fmt.Errorf("token reference %q not found", decodedToken)
|
||||
}
|
||||
return dec.InputOffset(), nil
|
||||
}
|
||||
|
||||
// drainSingle drains a single level of object or array.
|
||||
// The decoder has to guarantee the beginning delim (i.e. '{' or '[') has been consumed.
|
||||
func drainSingle(dec *json.Decoder) error {
|
||||
for dec.More() {
|
||||
tk, err := dec.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if delim, isDelim := tk.(json.Delim); isDelim {
|
||||
switch delim {
|
||||
case '{':
|
||||
if err = drainSingle(dec); err != nil {
|
||||
return err
|
||||
}
|
||||
case '[':
|
||||
if err = drainSingle(dec); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Consumes the ending delim
|
||||
if _, err := dec.Token(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Specific JSON pointer encoding here
|
||||
// ~0 => ~
|
||||
// ~1 => /
|
||||
@ -377,14 +518,14 @@ const (
|
||||
|
||||
// Unescape unescapes a json pointer reference token string to the original representation
|
||||
func Unescape(token string) string {
|
||||
step1 := strings.Replace(token, encRefTok1, decRefTok1, -1)
|
||||
step2 := strings.Replace(step1, encRefTok0, decRefTok0, -1)
|
||||
step1 := strings.ReplaceAll(token, encRefTok1, decRefTok1)
|
||||
step2 := strings.ReplaceAll(step1, encRefTok0, decRefTok0)
|
||||
return step2
|
||||
}
|
||||
|
||||
// Escape escapes a pointer reference token string
|
||||
func Escape(token string) string {
|
||||
step1 := strings.Replace(token, decRefTok0, encRefTok0, -1)
|
||||
step2 := strings.Replace(step1, decRefTok1, encRefTok1, -1)
|
||||
step1 := strings.ReplaceAll(token, decRefTok0, encRefTok0)
|
||||
step2 := strings.ReplaceAll(step1, decRefTok1, encRefTok1)
|
||||
return step2
|
||||
}
|
||||
|
1
vendor/github.com/go-openapi/swag/.gitignore
generated
vendored
1
vendor/github.com/go-openapi/swag/.gitignore
generated
vendored
@ -2,3 +2,4 @@ secrets.yml
|
||||
vendor
|
||||
Godeps
|
||||
.idea
|
||||
*.out
|
||||
|
54
vendor/github.com/go-openapi/swag/.golangci.yml
generated
vendored
54
vendor/github.com/go-openapi/swag/.golangci.yml
generated
vendored
@ -4,14 +4,14 @@ linters-settings:
|
||||
golint:
|
||||
min-confidence: 0
|
||||
gocyclo:
|
||||
min-complexity: 25
|
||||
min-complexity: 45
|
||||
maligned:
|
||||
suggest-new: true
|
||||
dupl:
|
||||
threshold: 100
|
||||
threshold: 200
|
||||
goconst:
|
||||
min-len: 3
|
||||
min-occurrences: 2
|
||||
min-occurrences: 3
|
||||
|
||||
linters:
|
||||
enable-all: true
|
||||
@ -20,35 +20,41 @@ linters:
|
||||
- lll
|
||||
- gochecknoinits
|
||||
- gochecknoglobals
|
||||
- nlreturn
|
||||
- testpackage
|
||||
- funlen
|
||||
- godox
|
||||
- gocognit
|
||||
- whitespace
|
||||
- wsl
|
||||
- wrapcheck
|
||||
- testpackage
|
||||
- nlreturn
|
||||
- gomnd
|
||||
- exhaustive
|
||||
- exhaustivestruct
|
||||
- goerr113
|
||||
- wsl
|
||||
- whitespace
|
||||
- gofumpt
|
||||
- godot
|
||||
- errorlint
|
||||
- nestif
|
||||
- godox
|
||||
- funlen
|
||||
- gci
|
||||
- gocognit
|
||||
- godot
|
||||
- gofumpt
|
||||
- paralleltest
|
||||
- tparallel
|
||||
- thelper
|
||||
- ifshort
|
||||
- gomoddirectives
|
||||
- cyclop
|
||||
- forcetypeassert
|
||||
- ireturn
|
||||
- tagliatelle
|
||||
- varnamelen
|
||||
- goimports
|
||||
- tenv
|
||||
- golint
|
||||
- exhaustruct
|
||||
- nilnil
|
||||
- varnamelen
|
||||
- gci
|
||||
- depguard
|
||||
- errchkjson
|
||||
- inamedparam
|
||||
- nonamedreturns
|
||||
- musttag
|
||||
- ireturn
|
||||
- forcetypeassert
|
||||
- cyclop
|
||||
# deprecated linters
|
||||
- deadcode
|
||||
- interfacer
|
||||
- scopelint
|
||||
- varcheck
|
||||
- structcheck
|
||||
- golint
|
||||
- nosnakecase
|
||||
|
52
vendor/github.com/go-openapi/swag/BENCHMARK.md
generated
vendored
Normal file
52
vendor/github.com/go-openapi/swag/BENCHMARK.md
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
# Benchmarks
|
||||
|
||||
## Name mangling utilities
|
||||
|
||||
```bash
|
||||
go test -bench XXX -run XXX -benchtime 30s
|
||||
```
|
||||
|
||||
### Benchmarks at b3e7a5386f996177e4808f11acb2aa93a0f660df
|
||||
|
||||
```
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
pkg: github.com/go-openapi/swag
|
||||
cpu: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz
|
||||
BenchmarkToXXXName/ToGoName-4 862623 44101 ns/op 10450 B/op 732 allocs/op
|
||||
BenchmarkToXXXName/ToVarName-4 853656 40728 ns/op 10468 B/op 734 allocs/op
|
||||
BenchmarkToXXXName/ToFileName-4 1268312 27813 ns/op 9785 B/op 617 allocs/op
|
||||
BenchmarkToXXXName/ToCommandName-4 1276322 27903 ns/op 9785 B/op 617 allocs/op
|
||||
BenchmarkToXXXName/ToHumanNameLower-4 895334 40354 ns/op 10472 B/op 731 allocs/op
|
||||
BenchmarkToXXXName/ToHumanNameTitle-4 882441 40678 ns/op 10566 B/op 749 allocs/op
|
||||
```
|
||||
|
||||
### Benchmarks after PR #79
|
||||
|
||||
~ x10 performance improvement and ~ /100 memory allocations.
|
||||
|
||||
```
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
pkg: github.com/go-openapi/swag
|
||||
cpu: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz
|
||||
BenchmarkToXXXName/ToGoName-4 9595830 3991 ns/op 42 B/op 5 allocs/op
|
||||
BenchmarkToXXXName/ToVarName-4 9194276 3984 ns/op 62 B/op 7 allocs/op
|
||||
BenchmarkToXXXName/ToFileName-4 17002711 2123 ns/op 147 B/op 7 allocs/op
|
||||
BenchmarkToXXXName/ToCommandName-4 16772926 2111 ns/op 147 B/op 7 allocs/op
|
||||
BenchmarkToXXXName/ToHumanNameLower-4 9788331 3749 ns/op 92 B/op 6 allocs/op
|
||||
BenchmarkToXXXName/ToHumanNameTitle-4 9188260 3941 ns/op 104 B/op 6 allocs/op
|
||||
```
|
||||
|
||||
```
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
pkg: github.com/go-openapi/swag
|
||||
cpu: AMD Ryzen 7 5800X 8-Core Processor
|
||||
BenchmarkToXXXName/ToGoName-16 18527378 1972 ns/op 42 B/op 5 allocs/op
|
||||
BenchmarkToXXXName/ToVarName-16 15552692 2093 ns/op 62 B/op 7 allocs/op
|
||||
BenchmarkToXXXName/ToFileName-16 32161176 1117 ns/op 147 B/op 7 allocs/op
|
||||
BenchmarkToXXXName/ToCommandName-16 32256634 1137 ns/op 147 B/op 7 allocs/op
|
||||
BenchmarkToXXXName/ToHumanNameLower-16 18599661 1946 ns/op 92 B/op 6 allocs/op
|
||||
BenchmarkToXXXName/ToHumanNameTitle-16 17581353 2054 ns/op 105 B/op 6 allocs/op
|
||||
```
|
8
vendor/github.com/go-openapi/swag/README.md
generated
vendored
8
vendor/github.com/go-openapi/swag/README.md
generated
vendored
@ -1,7 +1,8 @@
|
||||
# Swag [](https://travis-ci.org/go-openapi/swag) [](https://codecov.io/gh/go-openapi/swag) [](https://slackin.goswagger.io)
|
||||
# Swag [](https://github.com/go-openapi/swag/actions?query=workflow%3A"go+test") [](https://codecov.io/gh/go-openapi/swag)
|
||||
|
||||
[](https://slackin.goswagger.io)
|
||||
[](https://raw.githubusercontent.com/go-openapi/swag/master/LICENSE)
|
||||
[](http://godoc.org/github.com/go-openapi/swag)
|
||||
[](https://pkg.go.dev/github.com/go-openapi/swag)
|
||||
[](https://goreportcard.com/report/github.com/go-openapi/swag)
|
||||
|
||||
Contains a bunch of helper functions for go-openapi and go-swagger projects.
|
||||
@ -18,4 +19,5 @@ You may also use it standalone for your projects.
|
||||
|
||||
This repo has only few dependencies outside of the standard library:
|
||||
|
||||
* YAML utilities depend on gopkg.in/yaml.v2
|
||||
* YAML utilities depend on `gopkg.in/yaml.v3`
|
||||
* `github.com/mailru/easyjson v0.7.7`
|
||||
|
202
vendor/github.com/go-openapi/swag/initialism_index.go
generated
vendored
Normal file
202
vendor/github.com/go-openapi/swag/initialism_index.go
generated
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package swag
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
// commonInitialisms are common acronyms that are kept as whole uppercased words.
|
||||
commonInitialisms *indexOfInitialisms
|
||||
|
||||
// initialisms is a slice of sorted initialisms
|
||||
initialisms []string
|
||||
|
||||
// a copy of initialisms pre-baked as []rune
|
||||
initialismsRunes [][]rune
|
||||
initialismsUpperCased [][]rune
|
||||
|
||||
isInitialism func(string) bool
|
||||
|
||||
maxAllocMatches int
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769
|
||||
configuredInitialisms := map[string]bool{
|
||||
"ACL": true,
|
||||
"API": true,
|
||||
"ASCII": true,
|
||||
"CPU": true,
|
||||
"CSS": true,
|
||||
"DNS": true,
|
||||
"EOF": true,
|
||||
"GUID": true,
|
||||
"HTML": true,
|
||||
"HTTPS": true,
|
||||
"HTTP": true,
|
||||
"ID": true,
|
||||
"IP": true,
|
||||
"IPv4": true,
|
||||
"IPv6": true,
|
||||
"JSON": true,
|
||||
"LHS": true,
|
||||
"OAI": true,
|
||||
"QPS": true,
|
||||
"RAM": true,
|
||||
"RHS": true,
|
||||
"RPC": true,
|
||||
"SLA": true,
|
||||
"SMTP": true,
|
||||
"SQL": true,
|
||||
"SSH": true,
|
||||
"TCP": true,
|
||||
"TLS": true,
|
||||
"TTL": true,
|
||||
"UDP": true,
|
||||
"UI": true,
|
||||
"UID": true,
|
||||
"UUID": true,
|
||||
"URI": true,
|
||||
"URL": true,
|
||||
"UTF8": true,
|
||||
"VM": true,
|
||||
"XML": true,
|
||||
"XMPP": true,
|
||||
"XSRF": true,
|
||||
"XSS": true,
|
||||
}
|
||||
|
||||
// a thread-safe index of initialisms
|
||||
commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms)
|
||||
initialisms = commonInitialisms.sorted()
|
||||
initialismsRunes = asRunes(initialisms)
|
||||
initialismsUpperCased = asUpperCased(initialisms)
|
||||
maxAllocMatches = maxAllocHeuristic(initialismsRunes)
|
||||
|
||||
// a test function
|
||||
isInitialism = commonInitialisms.isInitialism
|
||||
}
|
||||
|
||||
func asRunes(in []string) [][]rune {
|
||||
out := make([][]rune, len(in))
|
||||
for i, initialism := range in {
|
||||
out[i] = []rune(initialism)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func asUpperCased(in []string) [][]rune {
|
||||
out := make([][]rune, len(in))
|
||||
|
||||
for i, initialism := range in {
|
||||
out[i] = []rune(upper(trim(initialism)))
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func maxAllocHeuristic(in [][]rune) int {
|
||||
heuristic := make(map[rune]int)
|
||||
for _, initialism := range in {
|
||||
heuristic[initialism[0]]++
|
||||
}
|
||||
|
||||
var maxAlloc int
|
||||
for _, val := range heuristic {
|
||||
if val > maxAlloc {
|
||||
maxAlloc = val
|
||||
}
|
||||
}
|
||||
|
||||
return maxAlloc
|
||||
}
|
||||
|
||||
// AddInitialisms add additional initialisms
|
||||
func AddInitialisms(words ...string) {
|
||||
for _, word := range words {
|
||||
// commonInitialisms[upper(word)] = true
|
||||
commonInitialisms.add(upper(word))
|
||||
}
|
||||
// sort again
|
||||
initialisms = commonInitialisms.sorted()
|
||||
initialismsRunes = asRunes(initialisms)
|
||||
initialismsUpperCased = asUpperCased(initialisms)
|
||||
}
|
||||
|
||||
// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms.
|
||||
// Since go1.9, this may be implemented with sync.Map.
|
||||
type indexOfInitialisms struct {
|
||||
sortMutex *sync.Mutex
|
||||
index *sync.Map
|
||||
}
|
||||
|
||||
func newIndexOfInitialisms() *indexOfInitialisms {
|
||||
return &indexOfInitialisms{
|
||||
sortMutex: new(sync.Mutex),
|
||||
index: new(sync.Map),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms {
|
||||
m.sortMutex.Lock()
|
||||
defer m.sortMutex.Unlock()
|
||||
for k, v := range initial {
|
||||
m.index.Store(k, v)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *indexOfInitialisms) isInitialism(key string) bool {
|
||||
_, ok := m.index.Load(key)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (m *indexOfInitialisms) add(key string) *indexOfInitialisms {
|
||||
m.index.Store(key, true)
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *indexOfInitialisms) sorted() (result []string) {
|
||||
m.sortMutex.Lock()
|
||||
defer m.sortMutex.Unlock()
|
||||
m.index.Range(func(key, _ interface{}) bool {
|
||||
k := key.(string)
|
||||
result = append(result, k)
|
||||
return true
|
||||
})
|
||||
sort.Sort(sort.Reverse(byInitialism(result)))
|
||||
return
|
||||
}
|
||||
|
||||
type byInitialism []string
|
||||
|
||||
func (s byInitialism) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
func (s byInitialism) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
func (s byInitialism) Less(i, j int) bool {
|
||||
if len(s[i]) != len(s[j]) {
|
||||
return len(s[i]) < len(s[j])
|
||||
}
|
||||
|
||||
return strings.Compare(s[i], s[j]) > 0
|
||||
}
|
105
vendor/github.com/go-openapi/swag/loading.go
generated
vendored
105
vendor/github.com/go-openapi/swag/loading.go
generated
vendored
@ -21,6 +21,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
@ -40,43 +41,97 @@ var LoadHTTPBasicAuthPassword = ""
|
||||
var LoadHTTPCustomHeaders = map[string]string{}
|
||||
|
||||
// LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in
|
||||
func LoadFromFileOrHTTP(path string) ([]byte, error) {
|
||||
return LoadStrategy(path, os.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path)
|
||||
func LoadFromFileOrHTTP(pth string) ([]byte, error) {
|
||||
return LoadStrategy(pth, os.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(pth)
|
||||
}
|
||||
|
||||
// LoadFromFileOrHTTPWithTimeout loads the bytes from a file or a remote http server based on the path passed in
|
||||
// timeout arg allows for per request overriding of the request timeout
|
||||
func LoadFromFileOrHTTPWithTimeout(path string, timeout time.Duration) ([]byte, error) {
|
||||
return LoadStrategy(path, os.ReadFile, loadHTTPBytes(timeout))(path)
|
||||
func LoadFromFileOrHTTPWithTimeout(pth string, timeout time.Duration) ([]byte, error) {
|
||||
return LoadStrategy(pth, os.ReadFile, loadHTTPBytes(timeout))(pth)
|
||||
}
|
||||
|
||||
// LoadStrategy returns a loader function for a given path or uri
|
||||
func LoadStrategy(path string, local, remote func(string) ([]byte, error)) func(string) ([]byte, error) {
|
||||
if strings.HasPrefix(path, "http") {
|
||||
// LoadStrategy returns a loader function for a given path or URI.
|
||||
//
|
||||
// The load strategy returns the remote load for any path starting with `http`.
|
||||
// So this works for any URI with a scheme `http` or `https`.
|
||||
//
|
||||
// The fallback strategy is to call the local loader.
|
||||
//
|
||||
// The local loader takes a local file system path (absolute or relative) as argument,
|
||||
// or alternatively a `file://...` URI, **without host** (see also below for windows).
|
||||
//
|
||||
// There are a few liberalities, initially intended to be tolerant regarding the URI syntax,
|
||||
// especially on windows.
|
||||
//
|
||||
// Before the local loader is called, the given path is transformed:
|
||||
// - percent-encoded characters are unescaped
|
||||
// - simple paths (e.g. `./folder/file`) are passed as-is
|
||||
// - on windows, occurrences of `/` are replaced by `\`, so providing a relative path such a `folder/file` works too.
|
||||
//
|
||||
// For paths provided as URIs with the "file" scheme, please note that:
|
||||
// - `file://` is simply stripped.
|
||||
// This means that the host part of the URI is not parsed at all.
|
||||
// For example, `file:///folder/file" becomes "/folder/file`,
|
||||
// but `file://localhost/folder/file` becomes `localhost/folder/file` on unix systems.
|
||||
// Similarly, `file://./folder/file` yields `./folder/file`.
|
||||
// - on windows, `file://...` can take a host so as to specify an UNC share location.
|
||||
//
|
||||
// Reminder about windows-specifics:
|
||||
// - `file://host/folder/file` becomes an UNC path like `\\host\folder\file` (no port specification is supported)
|
||||
// - `file:///c:/folder/file` becomes `C:\folder\file`
|
||||
// - `file://c:/folder/file` is tolerated (without leading `/`) and becomes `c:\folder\file`
|
||||
func LoadStrategy(pth string, local, remote func(string) ([]byte, error)) func(string) ([]byte, error) {
|
||||
if strings.HasPrefix(pth, "http") {
|
||||
return remote
|
||||
}
|
||||
return func(pth string) ([]byte, error) {
|
||||
upth, err := pathUnescape(pth)
|
||||
|
||||
return func(p string) ([]byte, error) {
|
||||
upth, err := url.PathUnescape(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if strings.HasPrefix(pth, `file://`) {
|
||||
if runtime.GOOS == "windows" {
|
||||
// support for canonical file URIs on windows.
|
||||
// Zero tolerance here for dodgy URIs.
|
||||
u, _ := url.Parse(upth)
|
||||
if u.Host != "" {
|
||||
// assume UNC name (volume share)
|
||||
// file://host/share/folder\... ==> \\host\share\path\folder
|
||||
// NOTE: UNC port not yet supported
|
||||
upth = strings.Join([]string{`\`, u.Host, u.Path}, `\`)
|
||||
} else {
|
||||
// file:///c:/folder/... ==> just remove the leading slash
|
||||
upth = strings.TrimPrefix(upth, `file:///`)
|
||||
}
|
||||
} else {
|
||||
upth = strings.TrimPrefix(upth, `file://`)
|
||||
if !strings.HasPrefix(p, `file://`) {
|
||||
// regular file path provided: just normalize slashes
|
||||
return local(filepath.FromSlash(upth))
|
||||
}
|
||||
|
||||
if runtime.GOOS != "windows" {
|
||||
// crude processing: this leaves full URIs with a host with a (mostly) unexpected result
|
||||
upth = strings.TrimPrefix(upth, `file://`)
|
||||
|
||||
return local(filepath.FromSlash(upth))
|
||||
}
|
||||
|
||||
// windows-only pre-processing of file://... URIs
|
||||
|
||||
// support for canonical file URIs on windows.
|
||||
u, err := url.Parse(filepath.ToSlash(upth))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if u.Host != "" {
|
||||
// assume UNC name (volume share)
|
||||
// NOTE: UNC port not yet supported
|
||||
|
||||
// when the "host" segment is a drive letter:
|
||||
// file://C:/folder/... => C:\folder
|
||||
upth = path.Clean(strings.Join([]string{u.Host, u.Path}, `/`))
|
||||
if !strings.HasSuffix(u.Host, ":") && u.Host[0] != '.' {
|
||||
// tolerance: if we have a leading dot, this can't be a host
|
||||
// file://host/share/folder\... ==> \\host\share\path\folder
|
||||
upth = "//" + upth
|
||||
}
|
||||
} else {
|
||||
// no host, let's figure out if this is a drive letter
|
||||
upth = strings.TrimPrefix(upth, `file://`)
|
||||
first, _, _ := strings.Cut(strings.TrimPrefix(u.Path, "/"), "/")
|
||||
if strings.HasSuffix(first, ":") {
|
||||
// drive letter in the first segment:
|
||||
// file:///c:/folder/... ==> strip the leading slash
|
||||
upth = strings.TrimPrefix(upth, `/`)
|
||||
}
|
||||
}
|
||||
|
||||
|
72
vendor/github.com/go-openapi/swag/name_lexem.go
generated
vendored
72
vendor/github.com/go-openapi/swag/name_lexem.go
generated
vendored
@ -14,74 +14,80 @@
|
||||
|
||||
package swag
|
||||
|
||||
import "unicode"
|
||||
import (
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
type (
|
||||
nameLexem interface {
|
||||
GetUnsafeGoName() string
|
||||
GetOriginal() string
|
||||
IsInitialism() bool
|
||||
}
|
||||
lexemKind uint8
|
||||
|
||||
initialismNameLexem struct {
|
||||
nameLexem struct {
|
||||
original string
|
||||
matchedInitialism string
|
||||
}
|
||||
|
||||
casualNameLexem struct {
|
||||
original string
|
||||
kind lexemKind
|
||||
}
|
||||
)
|
||||
|
||||
func newInitialismNameLexem(original, matchedInitialism string) *initialismNameLexem {
|
||||
return &initialismNameLexem{
|
||||
const (
|
||||
lexemKindCasualName lexemKind = iota
|
||||
lexemKindInitialismName
|
||||
)
|
||||
|
||||
func newInitialismNameLexem(original, matchedInitialism string) nameLexem {
|
||||
return nameLexem{
|
||||
kind: lexemKindInitialismName,
|
||||
original: original,
|
||||
matchedInitialism: matchedInitialism,
|
||||
}
|
||||
}
|
||||
|
||||
func newCasualNameLexem(original string) *casualNameLexem {
|
||||
return &casualNameLexem{
|
||||
func newCasualNameLexem(original string) nameLexem {
|
||||
return nameLexem{
|
||||
kind: lexemKindCasualName,
|
||||
original: original,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *initialismNameLexem) GetUnsafeGoName() string {
|
||||
return l.matchedInitialism
|
||||
}
|
||||
func (l nameLexem) GetUnsafeGoName() string {
|
||||
if l.kind == lexemKindInitialismName {
|
||||
return l.matchedInitialism
|
||||
}
|
||||
|
||||
var (
|
||||
first rune
|
||||
rest string
|
||||
)
|
||||
|
||||
func (l *casualNameLexem) GetUnsafeGoName() string {
|
||||
var first rune
|
||||
var rest string
|
||||
for i, orig := range l.original {
|
||||
if i == 0 {
|
||||
first = orig
|
||||
continue
|
||||
}
|
||||
|
||||
if i > 0 {
|
||||
rest = l.original[i:]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if len(l.original) > 1 {
|
||||
return string(unicode.ToUpper(first)) + lower(rest)
|
||||
b := poolOfBuffers.BorrowBuffer(utf8.UTFMax + len(rest))
|
||||
defer func() {
|
||||
poolOfBuffers.RedeemBuffer(b)
|
||||
}()
|
||||
b.WriteRune(unicode.ToUpper(first))
|
||||
b.WriteString(lower(rest))
|
||||
return b.String()
|
||||
}
|
||||
|
||||
return l.original
|
||||
}
|
||||
|
||||
func (l *initialismNameLexem) GetOriginal() string {
|
||||
func (l nameLexem) GetOriginal() string {
|
||||
return l.original
|
||||
}
|
||||
|
||||
func (l *casualNameLexem) GetOriginal() string {
|
||||
return l.original
|
||||
}
|
||||
|
||||
func (l *initialismNameLexem) IsInitialism() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (l *casualNameLexem) IsInitialism() bool {
|
||||
return false
|
||||
func (l nameLexem) IsInitialism() bool {
|
||||
return l.kind == lexemKindInitialismName
|
||||
}
|
||||
|
24
vendor/github.com/go-openapi/swag/post_go18.go
generated
vendored
24
vendor/github.com/go-openapi/swag/post_go18.go
generated
vendored
@ -1,24 +0,0 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build go1.8
|
||||
// +build go1.8
|
||||
|
||||
package swag
|
||||
|
||||
import "net/url"
|
||||
|
||||
func pathUnescape(path string) (string, error) {
|
||||
return url.PathUnescape(path)
|
||||
}
|
68
vendor/github.com/go-openapi/swag/post_go19.go
generated
vendored
68
vendor/github.com/go-openapi/swag/post_go19.go
generated
vendored
@ -1,68 +0,0 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build go1.9
|
||||
// +build go1.9
|
||||
|
||||
package swag
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms.
|
||||
// Since go1.9, this may be implemented with sync.Map.
|
||||
type indexOfInitialisms struct {
|
||||
sortMutex *sync.Mutex
|
||||
index *sync.Map
|
||||
}
|
||||
|
||||
func newIndexOfInitialisms() *indexOfInitialisms {
|
||||
return &indexOfInitialisms{
|
||||
sortMutex: new(sync.Mutex),
|
||||
index: new(sync.Map),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms {
|
||||
m.sortMutex.Lock()
|
||||
defer m.sortMutex.Unlock()
|
||||
for k, v := range initial {
|
||||
m.index.Store(k, v)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *indexOfInitialisms) isInitialism(key string) bool {
|
||||
_, ok := m.index.Load(key)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (m *indexOfInitialisms) add(key string) *indexOfInitialisms {
|
||||
m.index.Store(key, true)
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *indexOfInitialisms) sorted() (result []string) {
|
||||
m.sortMutex.Lock()
|
||||
defer m.sortMutex.Unlock()
|
||||
m.index.Range(func(key, value interface{}) bool {
|
||||
k := key.(string)
|
||||
result = append(result, k)
|
||||
return true
|
||||
})
|
||||
sort.Sort(sort.Reverse(byInitialism(result)))
|
||||
return
|
||||
}
|
24
vendor/github.com/go-openapi/swag/pre_go18.go
generated
vendored
24
vendor/github.com/go-openapi/swag/pre_go18.go
generated
vendored
@ -1,24 +0,0 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !go1.8
|
||||
// +build !go1.8
|
||||
|
||||
package swag
|
||||
|
||||
import "net/url"
|
||||
|
||||
func pathUnescape(path string) (string, error) {
|
||||
return url.QueryUnescape(path)
|
||||
}
|
70
vendor/github.com/go-openapi/swag/pre_go19.go
generated
vendored
70
vendor/github.com/go-openapi/swag/pre_go19.go
generated
vendored
@ -1,70 +0,0 @@
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !go1.9
|
||||
// +build !go1.9
|
||||
|
||||
package swag
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms.
|
||||
// Before go1.9, this may be implemented with a mutex on the map.
|
||||
type indexOfInitialisms struct {
|
||||
getMutex *sync.Mutex
|
||||
index map[string]bool
|
||||
}
|
||||
|
||||
func newIndexOfInitialisms() *indexOfInitialisms {
|
||||
return &indexOfInitialisms{
|
||||
getMutex: new(sync.Mutex),
|
||||
index: make(map[string]bool, 50),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms {
|
||||
m.getMutex.Lock()
|
||||
defer m.getMutex.Unlock()
|
||||
for k, v := range initial {
|
||||
m.index[k] = v
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *indexOfInitialisms) isInitialism(key string) bool {
|
||||
m.getMutex.Lock()
|
||||
defer m.getMutex.Unlock()
|
||||
_, ok := m.index[key]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (m *indexOfInitialisms) add(key string) *indexOfInitialisms {
|
||||
m.getMutex.Lock()
|
||||
defer m.getMutex.Unlock()
|
||||
m.index[key] = true
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *indexOfInitialisms) sorted() (result []string) {
|
||||
m.getMutex.Lock()
|
||||
defer m.getMutex.Unlock()
|
||||
for k := range m.index {
|
||||
result = append(result, k)
|
||||
}
|
||||
sort.Sort(sort.Reverse(byInitialism(result)))
|
||||
return
|
||||
}
|
490
vendor/github.com/go-openapi/swag/split.go
generated
vendored
490
vendor/github.com/go-openapi/swag/split.go
generated
vendored
@ -15,124 +15,269 @@
|
||||
package swag
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"sync"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
var nameReplaceTable = map[rune]string{
|
||||
'@': "At ",
|
||||
'&': "And ",
|
||||
'|': "Pipe ",
|
||||
'$': "Dollar ",
|
||||
'!': "Bang ",
|
||||
'-': "",
|
||||
'_': "",
|
||||
}
|
||||
|
||||
type (
|
||||
splitter struct {
|
||||
postSplitInitialismCheck bool
|
||||
initialisms []string
|
||||
initialismsRunes [][]rune
|
||||
initialismsUpperCased [][]rune // initialisms cached in their trimmed, upper-cased version
|
||||
postSplitInitialismCheck bool
|
||||
}
|
||||
|
||||
splitterOption func(*splitter) *splitter
|
||||
splitterOption func(*splitter)
|
||||
|
||||
initialismMatch struct {
|
||||
body []rune
|
||||
start, end int
|
||||
complete bool
|
||||
}
|
||||
initialismMatches []initialismMatch
|
||||
)
|
||||
|
||||
// split calls the splitter; splitter provides more control and post options
|
||||
func split(str string) []string {
|
||||
lexems := newSplitter().split(str)
|
||||
result := make([]string, 0, len(lexems))
|
||||
type (
|
||||
// memory pools of temporary objects.
|
||||
//
|
||||
// These are used to recycle temporarily allocated objects
|
||||
// and relieve the GC from undue pressure.
|
||||
|
||||
for _, lexem := range lexems {
|
||||
matchesPool struct {
|
||||
*sync.Pool
|
||||
}
|
||||
|
||||
buffersPool struct {
|
||||
*sync.Pool
|
||||
}
|
||||
|
||||
lexemsPool struct {
|
||||
*sync.Pool
|
||||
}
|
||||
|
||||
splittersPool struct {
|
||||
*sync.Pool
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
// poolOfMatches holds temporary slices for recycling during the initialism match process
|
||||
poolOfMatches = matchesPool{
|
||||
Pool: &sync.Pool{
|
||||
New: func() any {
|
||||
s := make(initialismMatches, 0, maxAllocMatches)
|
||||
|
||||
return &s
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
poolOfBuffers = buffersPool{
|
||||
Pool: &sync.Pool{
|
||||
New: func() any {
|
||||
return new(bytes.Buffer)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
poolOfLexems = lexemsPool{
|
||||
Pool: &sync.Pool{
|
||||
New: func() any {
|
||||
s := make([]nameLexem, 0, maxAllocMatches)
|
||||
|
||||
return &s
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
poolOfSplitters = splittersPool{
|
||||
Pool: &sync.Pool{
|
||||
New: func() any {
|
||||
s := newSplitter()
|
||||
|
||||
return &s
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// nameReplaceTable finds a word representation for special characters.
|
||||
func nameReplaceTable(r rune) (string, bool) {
|
||||
switch r {
|
||||
case '@':
|
||||
return "At ", true
|
||||
case '&':
|
||||
return "And ", true
|
||||
case '|':
|
||||
return "Pipe ", true
|
||||
case '$':
|
||||
return "Dollar ", true
|
||||
case '!':
|
||||
return "Bang ", true
|
||||
case '-':
|
||||
return "", true
|
||||
case '_':
|
||||
return "", true
|
||||
default:
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
|
||||
// split calls the splitter.
|
||||
//
|
||||
// Use newSplitter for more control and options
|
||||
func split(str string) []string {
|
||||
s := poolOfSplitters.BorrowSplitter()
|
||||
lexems := s.split(str)
|
||||
result := make([]string, 0, len(*lexems))
|
||||
|
||||
for _, lexem := range *lexems {
|
||||
result = append(result, lexem.GetOriginal())
|
||||
}
|
||||
poolOfLexems.RedeemLexems(lexems)
|
||||
poolOfSplitters.RedeemSplitter(s)
|
||||
|
||||
return result
|
||||
|
||||
}
|
||||
|
||||
func (s *splitter) split(str string) []nameLexem {
|
||||
return s.toNameLexems(str)
|
||||
}
|
||||
|
||||
func newSplitter(options ...splitterOption) *splitter {
|
||||
splitter := &splitter{
|
||||
func newSplitter(options ...splitterOption) splitter {
|
||||
s := splitter{
|
||||
postSplitInitialismCheck: false,
|
||||
initialisms: initialisms,
|
||||
initialismsRunes: initialismsRunes,
|
||||
initialismsUpperCased: initialismsUpperCased,
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
splitter = option(splitter)
|
||||
option(&s)
|
||||
}
|
||||
|
||||
return splitter
|
||||
}
|
||||
|
||||
// withPostSplitInitialismCheck allows to catch initialisms after main split process
|
||||
func withPostSplitInitialismCheck(s *splitter) *splitter {
|
||||
s.postSplitInitialismCheck = true
|
||||
return s
|
||||
}
|
||||
|
||||
type (
|
||||
initialismMatch struct {
|
||||
start, end int
|
||||
body []rune
|
||||
complete bool
|
||||
}
|
||||
initialismMatches []*initialismMatch
|
||||
)
|
||||
// withPostSplitInitialismCheck allows to catch initialisms after main split process
|
||||
func withPostSplitInitialismCheck(s *splitter) {
|
||||
s.postSplitInitialismCheck = true
|
||||
}
|
||||
|
||||
func (s *splitter) toNameLexems(name string) []nameLexem {
|
||||
func (p matchesPool) BorrowMatches() *initialismMatches {
|
||||
s := p.Get().(*initialismMatches)
|
||||
*s = (*s)[:0] // reset slice, keep allocated capacity
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (p buffersPool) BorrowBuffer(size int) *bytes.Buffer {
|
||||
s := p.Get().(*bytes.Buffer)
|
||||
s.Reset()
|
||||
|
||||
if s.Cap() < size {
|
||||
s.Grow(size)
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (p lexemsPool) BorrowLexems() *[]nameLexem {
|
||||
s := p.Get().(*[]nameLexem)
|
||||
*s = (*s)[:0] // reset slice, keep allocated capacity
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (p splittersPool) BorrowSplitter(options ...splitterOption) *splitter {
|
||||
s := p.Get().(*splitter)
|
||||
s.postSplitInitialismCheck = false // reset options
|
||||
for _, apply := range options {
|
||||
apply(s)
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (p matchesPool) RedeemMatches(s *initialismMatches) {
|
||||
p.Put(s)
|
||||
}
|
||||
|
||||
func (p buffersPool) RedeemBuffer(s *bytes.Buffer) {
|
||||
p.Put(s)
|
||||
}
|
||||
|
||||
func (p lexemsPool) RedeemLexems(s *[]nameLexem) {
|
||||
p.Put(s)
|
||||
}
|
||||
|
||||
func (p splittersPool) RedeemSplitter(s *splitter) {
|
||||
p.Put(s)
|
||||
}
|
||||
|
||||
func (m initialismMatch) isZero() bool {
|
||||
return m.start == 0 && m.end == 0
|
||||
}
|
||||
|
||||
func (s splitter) split(name string) *[]nameLexem {
|
||||
nameRunes := []rune(name)
|
||||
matches := s.gatherInitialismMatches(nameRunes)
|
||||
if matches == nil {
|
||||
return poolOfLexems.BorrowLexems()
|
||||
}
|
||||
|
||||
return s.mapMatchesToNameLexems(nameRunes, matches)
|
||||
}
|
||||
|
||||
func (s *splitter) gatherInitialismMatches(nameRunes []rune) initialismMatches {
|
||||
matches := make(initialismMatches, 0)
|
||||
func (s splitter) gatherInitialismMatches(nameRunes []rune) *initialismMatches {
|
||||
var matches *initialismMatches
|
||||
|
||||
for currentRunePosition, currentRune := range nameRunes {
|
||||
newMatches := make(initialismMatches, 0, len(matches))
|
||||
// recycle these allocations as we loop over runes
|
||||
// with such recycling, only 2 slices should be allocated per call
|
||||
// instead of o(n).
|
||||
newMatches := poolOfMatches.BorrowMatches()
|
||||
|
||||
// check current initialism matches
|
||||
for _, match := range matches {
|
||||
if keepCompleteMatch := match.complete; keepCompleteMatch {
|
||||
newMatches = append(newMatches, match)
|
||||
continue
|
||||
}
|
||||
|
||||
// drop failed match
|
||||
currentMatchRune := match.body[currentRunePosition-match.start]
|
||||
if !s.initialismRuneEqual(currentMatchRune, currentRune) {
|
||||
continue
|
||||
}
|
||||
|
||||
// try to complete ongoing match
|
||||
if currentRunePosition-match.start == len(match.body)-1 {
|
||||
// we are close; the next step is to check the symbol ahead
|
||||
// if it is a small letter, then it is not the end of match
|
||||
// but beginning of the next word
|
||||
|
||||
if currentRunePosition < len(nameRunes)-1 {
|
||||
nextRune := nameRunes[currentRunePosition+1]
|
||||
if newWord := unicode.IsLower(nextRune); newWord {
|
||||
// oh ok, it was the start of a new word
|
||||
continue
|
||||
}
|
||||
if matches != nil { // skip first iteration
|
||||
for _, match := range *matches {
|
||||
if keepCompleteMatch := match.complete; keepCompleteMatch {
|
||||
*newMatches = append(*newMatches, match)
|
||||
continue
|
||||
}
|
||||
|
||||
match.complete = true
|
||||
match.end = currentRunePosition
|
||||
}
|
||||
// drop failed match
|
||||
currentMatchRune := match.body[currentRunePosition-match.start]
|
||||
if currentMatchRune != currentRune {
|
||||
continue
|
||||
}
|
||||
|
||||
newMatches = append(newMatches, match)
|
||||
// try to complete ongoing match
|
||||
if currentRunePosition-match.start == len(match.body)-1 {
|
||||
// we are close; the next step is to check the symbol ahead
|
||||
// if it is a small letter, then it is not the end of match
|
||||
// but beginning of the next word
|
||||
|
||||
if currentRunePosition < len(nameRunes)-1 {
|
||||
nextRune := nameRunes[currentRunePosition+1]
|
||||
if newWord := unicode.IsLower(nextRune); newWord {
|
||||
// oh ok, it was the start of a new word
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
match.complete = true
|
||||
match.end = currentRunePosition
|
||||
}
|
||||
|
||||
*newMatches = append(*newMatches, match)
|
||||
}
|
||||
}
|
||||
|
||||
// check for new initialism matches
|
||||
for _, initialism := range s.initialisms {
|
||||
initialismRunes := []rune(initialism)
|
||||
if s.initialismRuneEqual(initialismRunes[0], currentRune) {
|
||||
newMatches = append(newMatches, &initialismMatch{
|
||||
for i := range s.initialisms {
|
||||
initialismRunes := s.initialismsRunes[i]
|
||||
if initialismRunes[0] == currentRune {
|
||||
*newMatches = append(*newMatches, initialismMatch{
|
||||
start: currentRunePosition,
|
||||
body: initialismRunes,
|
||||
complete: false,
|
||||
@ -140,24 +285,28 @@ func (s *splitter) gatherInitialismMatches(nameRunes []rune) initialismMatches {
|
||||
}
|
||||
}
|
||||
|
||||
if matches != nil {
|
||||
poolOfMatches.RedeemMatches(matches)
|
||||
}
|
||||
matches = newMatches
|
||||
}
|
||||
|
||||
// up to the caller to redeem this last slice
|
||||
return matches
|
||||
}
|
||||
|
||||
func (s *splitter) mapMatchesToNameLexems(nameRunes []rune, matches initialismMatches) []nameLexem {
|
||||
nameLexems := make([]nameLexem, 0)
|
||||
func (s splitter) mapMatchesToNameLexems(nameRunes []rune, matches *initialismMatches) *[]nameLexem {
|
||||
nameLexems := poolOfLexems.BorrowLexems()
|
||||
|
||||
var lastAcceptedMatch *initialismMatch
|
||||
for _, match := range matches {
|
||||
var lastAcceptedMatch initialismMatch
|
||||
for _, match := range *matches {
|
||||
if !match.complete {
|
||||
continue
|
||||
}
|
||||
|
||||
if firstMatch := lastAcceptedMatch == nil; firstMatch {
|
||||
nameLexems = append(nameLexems, s.breakCasualString(nameRunes[:match.start])...)
|
||||
nameLexems = append(nameLexems, s.breakInitialism(string(match.body)))
|
||||
if firstMatch := lastAcceptedMatch.isZero(); firstMatch {
|
||||
s.appendBrokenDownCasualString(nameLexems, nameRunes[:match.start])
|
||||
*nameLexems = append(*nameLexems, s.breakInitialism(string(match.body)))
|
||||
|
||||
lastAcceptedMatch = match
|
||||
|
||||
@ -169,63 +318,66 @@ func (s *splitter) mapMatchesToNameLexems(nameRunes []rune, matches initialismMa
|
||||
}
|
||||
|
||||
middle := nameRunes[lastAcceptedMatch.end+1 : match.start]
|
||||
nameLexems = append(nameLexems, s.breakCasualString(middle)...)
|
||||
nameLexems = append(nameLexems, s.breakInitialism(string(match.body)))
|
||||
s.appendBrokenDownCasualString(nameLexems, middle)
|
||||
*nameLexems = append(*nameLexems, s.breakInitialism(string(match.body)))
|
||||
|
||||
lastAcceptedMatch = match
|
||||
}
|
||||
|
||||
// we have not found any accepted matches
|
||||
if lastAcceptedMatch == nil {
|
||||
return s.breakCasualString(nameRunes)
|
||||
if lastAcceptedMatch.isZero() {
|
||||
*nameLexems = (*nameLexems)[:0]
|
||||
s.appendBrokenDownCasualString(nameLexems, nameRunes)
|
||||
} else if lastAcceptedMatch.end+1 != len(nameRunes) {
|
||||
rest := nameRunes[lastAcceptedMatch.end+1:]
|
||||
s.appendBrokenDownCasualString(nameLexems, rest)
|
||||
}
|
||||
|
||||
if lastAcceptedMatch.end+1 != len(nameRunes) {
|
||||
rest := nameRunes[lastAcceptedMatch.end+1:]
|
||||
nameLexems = append(nameLexems, s.breakCasualString(rest)...)
|
||||
}
|
||||
poolOfMatches.RedeemMatches(matches)
|
||||
|
||||
return nameLexems
|
||||
}
|
||||
|
||||
func (s *splitter) initialismRuneEqual(a, b rune) bool {
|
||||
return a == b
|
||||
}
|
||||
|
||||
func (s *splitter) breakInitialism(original string) nameLexem {
|
||||
func (s splitter) breakInitialism(original string) nameLexem {
|
||||
return newInitialismNameLexem(original, original)
|
||||
}
|
||||
|
||||
func (s *splitter) breakCasualString(str []rune) []nameLexem {
|
||||
segments := make([]nameLexem, 0)
|
||||
currentSegment := ""
|
||||
func (s splitter) appendBrokenDownCasualString(segments *[]nameLexem, str []rune) {
|
||||
currentSegment := poolOfBuffers.BorrowBuffer(len(str)) // unlike strings.Builder, bytes.Buffer initial storage can reused
|
||||
defer func() {
|
||||
poolOfBuffers.RedeemBuffer(currentSegment)
|
||||
}()
|
||||
|
||||
addCasualNameLexem := func(original string) {
|
||||
segments = append(segments, newCasualNameLexem(original))
|
||||
*segments = append(*segments, newCasualNameLexem(original))
|
||||
}
|
||||
|
||||
addInitialismNameLexem := func(original, match string) {
|
||||
segments = append(segments, newInitialismNameLexem(original, match))
|
||||
*segments = append(*segments, newInitialismNameLexem(original, match))
|
||||
}
|
||||
|
||||
addNameLexem := func(original string) {
|
||||
if s.postSplitInitialismCheck {
|
||||
for _, initialism := range s.initialisms {
|
||||
if upper(initialism) == upper(original) {
|
||||
addInitialismNameLexem(original, initialism)
|
||||
var addNameLexem func(string)
|
||||
if s.postSplitInitialismCheck {
|
||||
addNameLexem = func(original string) {
|
||||
for i := range s.initialisms {
|
||||
if isEqualFoldIgnoreSpace(s.initialismsUpperCased[i], original) {
|
||||
addInitialismNameLexem(original, s.initialisms[i])
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addCasualNameLexem(original)
|
||||
addCasualNameLexem(original)
|
||||
}
|
||||
} else {
|
||||
addNameLexem = addCasualNameLexem
|
||||
}
|
||||
|
||||
for _, rn := range string(str) {
|
||||
if replace, found := nameReplaceTable[rn]; found {
|
||||
if currentSegment != "" {
|
||||
addNameLexem(currentSegment)
|
||||
currentSegment = ""
|
||||
for _, rn := range str {
|
||||
if replace, found := nameReplaceTable(rn); found {
|
||||
if currentSegment.Len() > 0 {
|
||||
addNameLexem(currentSegment.String())
|
||||
currentSegment.Reset()
|
||||
}
|
||||
|
||||
if replace != "" {
|
||||
@ -236,27 +388,121 @@ func (s *splitter) breakCasualString(str []rune) []nameLexem {
|
||||
}
|
||||
|
||||
if !unicode.In(rn, unicode.L, unicode.M, unicode.N, unicode.Pc) {
|
||||
if currentSegment != "" {
|
||||
addNameLexem(currentSegment)
|
||||
currentSegment = ""
|
||||
if currentSegment.Len() > 0 {
|
||||
addNameLexem(currentSegment.String())
|
||||
currentSegment.Reset()
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if unicode.IsUpper(rn) {
|
||||
if currentSegment != "" {
|
||||
addNameLexem(currentSegment)
|
||||
if currentSegment.Len() > 0 {
|
||||
addNameLexem(currentSegment.String())
|
||||
}
|
||||
currentSegment = ""
|
||||
currentSegment.Reset()
|
||||
}
|
||||
|
||||
currentSegment += string(rn)
|
||||
currentSegment.WriteRune(rn)
|
||||
}
|
||||
|
||||
if currentSegment != "" {
|
||||
addNameLexem(currentSegment)
|
||||
if currentSegment.Len() > 0 {
|
||||
addNameLexem(currentSegment.String())
|
||||
}
|
||||
|
||||
return segments
|
||||
}
|
||||
|
||||
// isEqualFoldIgnoreSpace is the same as strings.EqualFold, but
|
||||
// it ignores leading and trailing blank spaces in the compared
|
||||
// string.
|
||||
//
|
||||
// base is assumed to be composed of upper-cased runes, and be already
|
||||
// trimmed.
|
||||
//
|
||||
// This code is heavily inspired from strings.EqualFold.
|
||||
func isEqualFoldIgnoreSpace(base []rune, str string) bool {
|
||||
var i, baseIndex int
|
||||
// equivalent to b := []byte(str), but without data copy
|
||||
b := hackStringBytes(str)
|
||||
|
||||
for i < len(b) {
|
||||
if c := b[i]; c < utf8.RuneSelf {
|
||||
// fast path for ASCII
|
||||
if c != ' ' && c != '\t' {
|
||||
break
|
||||
}
|
||||
i++
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// unicode case
|
||||
r, size := utf8.DecodeRune(b[i:])
|
||||
if !unicode.IsSpace(r) {
|
||||
break
|
||||
}
|
||||
i += size
|
||||
}
|
||||
|
||||
if i >= len(b) {
|
||||
return len(base) == 0
|
||||
}
|
||||
|
||||
for _, baseRune := range base {
|
||||
if i >= len(b) {
|
||||
break
|
||||
}
|
||||
|
||||
if c := b[i]; c < utf8.RuneSelf {
|
||||
// single byte rune case (ASCII)
|
||||
if baseRune >= utf8.RuneSelf {
|
||||
return false
|
||||
}
|
||||
|
||||
baseChar := byte(baseRune)
|
||||
if c != baseChar &&
|
||||
!('a' <= c && c <= 'z' && c-'a'+'A' == baseChar) {
|
||||
return false
|
||||
}
|
||||
|
||||
baseIndex++
|
||||
i++
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// unicode case
|
||||
r, size := utf8.DecodeRune(b[i:])
|
||||
if unicode.ToUpper(r) != baseRune {
|
||||
return false
|
||||
}
|
||||
baseIndex++
|
||||
i += size
|
||||
}
|
||||
|
||||
if baseIndex != len(base) {
|
||||
return false
|
||||
}
|
||||
|
||||
// all passed: now we should only have blanks
|
||||
for i < len(b) {
|
||||
if c := b[i]; c < utf8.RuneSelf {
|
||||
// fast path for ASCII
|
||||
if c != ' ' && c != '\t' {
|
||||
return false
|
||||
}
|
||||
i++
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// unicode case
|
||||
r, size := utf8.DecodeRune(b[i:])
|
||||
if !unicode.IsSpace(r) {
|
||||
return false
|
||||
}
|
||||
|
||||
i += size
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
8
vendor/github.com/go-openapi/swag/string_bytes.go
generated
vendored
Normal file
8
vendor/github.com/go-openapi/swag/string_bytes.go
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
package swag
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// hackStringBytes returns the (unsafe) underlying bytes slice of a string.
|
||||
func hackStringBytes(str string) []byte {
|
||||
return unsafe.Slice(unsafe.StringData(str), len(str))
|
||||
}
|
224
vendor/github.com/go-openapi/swag/util.go
generated
vendored
224
vendor/github.com/go-openapi/swag/util.go
generated
vendored
@ -18,76 +18,25 @@ import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// commonInitialisms are common acronyms that are kept as whole uppercased words.
|
||||
var commonInitialisms *indexOfInitialisms
|
||||
|
||||
// initialisms is a slice of sorted initialisms
|
||||
var initialisms []string
|
||||
|
||||
var isInitialism func(string) bool
|
||||
|
||||
// GoNamePrefixFunc sets an optional rule to prefix go names
|
||||
// which do not start with a letter.
|
||||
//
|
||||
// The prefix function is assumed to return a string that starts with an upper case letter.
|
||||
//
|
||||
// e.g. to help convert "123" into "{prefix}123"
|
||||
//
|
||||
// The default is to prefix with "X"
|
||||
var GoNamePrefixFunc func(string) string
|
||||
|
||||
func init() {
|
||||
// Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769
|
||||
var configuredInitialisms = map[string]bool{
|
||||
"ACL": true,
|
||||
"API": true,
|
||||
"ASCII": true,
|
||||
"CPU": true,
|
||||
"CSS": true,
|
||||
"DNS": true,
|
||||
"EOF": true,
|
||||
"GUID": true,
|
||||
"HTML": true,
|
||||
"HTTPS": true,
|
||||
"HTTP": true,
|
||||
"ID": true,
|
||||
"IP": true,
|
||||
"IPv4": true,
|
||||
"IPv6": true,
|
||||
"JSON": true,
|
||||
"LHS": true,
|
||||
"OAI": true,
|
||||
"QPS": true,
|
||||
"RAM": true,
|
||||
"RHS": true,
|
||||
"RPC": true,
|
||||
"SLA": true,
|
||||
"SMTP": true,
|
||||
"SQL": true,
|
||||
"SSH": true,
|
||||
"TCP": true,
|
||||
"TLS": true,
|
||||
"TTL": true,
|
||||
"UDP": true,
|
||||
"UI": true,
|
||||
"UID": true,
|
||||
"UUID": true,
|
||||
"URI": true,
|
||||
"URL": true,
|
||||
"UTF8": true,
|
||||
"VM": true,
|
||||
"XML": true,
|
||||
"XMPP": true,
|
||||
"XSRF": true,
|
||||
"XSS": true,
|
||||
func prefixFunc(name, in string) string {
|
||||
if GoNamePrefixFunc == nil {
|
||||
return "X" + in
|
||||
}
|
||||
|
||||
// a thread-safe index of initialisms
|
||||
commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms)
|
||||
initialisms = commonInitialisms.sorted()
|
||||
|
||||
// a test function
|
||||
isInitialism = commonInitialisms.isInitialism
|
||||
return GoNamePrefixFunc(name) + in
|
||||
}
|
||||
|
||||
const (
|
||||
@ -156,25 +105,9 @@ func SplitByFormat(data, format string) []string {
|
||||
return result
|
||||
}
|
||||
|
||||
type byInitialism []string
|
||||
|
||||
func (s byInitialism) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
func (s byInitialism) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
func (s byInitialism) Less(i, j int) bool {
|
||||
if len(s[i]) != len(s[j]) {
|
||||
return len(s[i]) < len(s[j])
|
||||
}
|
||||
|
||||
return strings.Compare(s[i], s[j]) > 0
|
||||
}
|
||||
|
||||
// Removes leading whitespaces
|
||||
func trim(str string) string {
|
||||
return strings.Trim(str, " ")
|
||||
return strings.TrimSpace(str)
|
||||
}
|
||||
|
||||
// Shortcut to strings.ToUpper()
|
||||
@ -188,15 +121,20 @@ func lower(str string) string {
|
||||
}
|
||||
|
||||
// Camelize an uppercased word
|
||||
func Camelize(word string) (camelized string) {
|
||||
func Camelize(word string) string {
|
||||
camelized := poolOfBuffers.BorrowBuffer(len(word))
|
||||
defer func() {
|
||||
poolOfBuffers.RedeemBuffer(camelized)
|
||||
}()
|
||||
|
||||
for pos, ru := range []rune(word) {
|
||||
if pos > 0 {
|
||||
camelized += string(unicode.ToLower(ru))
|
||||
camelized.WriteRune(unicode.ToLower(ru))
|
||||
} else {
|
||||
camelized += string(unicode.ToUpper(ru))
|
||||
camelized.WriteRune(unicode.ToUpper(ru))
|
||||
}
|
||||
}
|
||||
return
|
||||
return camelized.String()
|
||||
}
|
||||
|
||||
// ToFileName lowercases and underscores a go type name
|
||||
@ -224,33 +162,40 @@ func ToCommandName(name string) string {
|
||||
|
||||
// ToHumanNameLower represents a code name as a human series of words
|
||||
func ToHumanNameLower(name string) string {
|
||||
in := newSplitter(withPostSplitInitialismCheck).split(name)
|
||||
out := make([]string, 0, len(in))
|
||||
s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck)
|
||||
in := s.split(name)
|
||||
poolOfSplitters.RedeemSplitter(s)
|
||||
out := make([]string, 0, len(*in))
|
||||
|
||||
for _, w := range in {
|
||||
for _, w := range *in {
|
||||
if !w.IsInitialism() {
|
||||
out = append(out, lower(w.GetOriginal()))
|
||||
} else {
|
||||
out = append(out, w.GetOriginal())
|
||||
out = append(out, trim(w.GetOriginal()))
|
||||
}
|
||||
}
|
||||
poolOfLexems.RedeemLexems(in)
|
||||
|
||||
return strings.Join(out, " ")
|
||||
}
|
||||
|
||||
// ToHumanNameTitle represents a code name as a human series of words with the first letters titleized
|
||||
func ToHumanNameTitle(name string) string {
|
||||
in := newSplitter(withPostSplitInitialismCheck).split(name)
|
||||
s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck)
|
||||
in := s.split(name)
|
||||
poolOfSplitters.RedeemSplitter(s)
|
||||
|
||||
out := make([]string, 0, len(in))
|
||||
for _, w := range in {
|
||||
original := w.GetOriginal()
|
||||
out := make([]string, 0, len(*in))
|
||||
for _, w := range *in {
|
||||
original := trim(w.GetOriginal())
|
||||
if !w.IsInitialism() {
|
||||
out = append(out, Camelize(original))
|
||||
} else {
|
||||
out = append(out, original)
|
||||
}
|
||||
}
|
||||
poolOfLexems.RedeemLexems(in)
|
||||
|
||||
return strings.Join(out, " ")
|
||||
}
|
||||
|
||||
@ -264,7 +209,7 @@ func ToJSONName(name string) string {
|
||||
out = append(out, lower(w))
|
||||
continue
|
||||
}
|
||||
out = append(out, Camelize(w))
|
||||
out = append(out, Camelize(trim(w)))
|
||||
}
|
||||
return strings.Join(out, "")
|
||||
}
|
||||
@ -283,35 +228,70 @@ func ToVarName(name string) string {
|
||||
|
||||
// ToGoName translates a swagger name which can be underscored or camel cased to a name that golint likes
|
||||
func ToGoName(name string) string {
|
||||
lexems := newSplitter(withPostSplitInitialismCheck).split(name)
|
||||
s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck)
|
||||
lexems := s.split(name)
|
||||
poolOfSplitters.RedeemSplitter(s)
|
||||
defer func() {
|
||||
poolOfLexems.RedeemLexems(lexems)
|
||||
}()
|
||||
lexemes := *lexems
|
||||
|
||||
result := ""
|
||||
for _, lexem := range lexems {
|
||||
if len(lexemes) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
result := poolOfBuffers.BorrowBuffer(len(name))
|
||||
defer func() {
|
||||
poolOfBuffers.RedeemBuffer(result)
|
||||
}()
|
||||
|
||||
// check if not starting with a letter, upper case
|
||||
firstPart := lexemes[0].GetUnsafeGoName()
|
||||
if lexemes[0].IsInitialism() {
|
||||
firstPart = upper(firstPart)
|
||||
}
|
||||
|
||||
if c := firstPart[0]; c < utf8.RuneSelf {
|
||||
// ASCII
|
||||
switch {
|
||||
case 'A' <= c && c <= 'Z':
|
||||
result.WriteString(firstPart)
|
||||
case 'a' <= c && c <= 'z':
|
||||
result.WriteByte(c - 'a' + 'A')
|
||||
result.WriteString(firstPart[1:])
|
||||
default:
|
||||
result.WriteString(prefixFunc(name, firstPart))
|
||||
// NOTE: no longer check if prefixFunc returns a string that starts with uppercase:
|
||||
// assume this is always the case
|
||||
}
|
||||
} else {
|
||||
// unicode
|
||||
firstRune, _ := utf8.DecodeRuneInString(firstPart)
|
||||
switch {
|
||||
case !unicode.IsLetter(firstRune):
|
||||
result.WriteString(prefixFunc(name, firstPart))
|
||||
case !unicode.IsUpper(firstRune):
|
||||
result.WriteString(prefixFunc(name, firstPart))
|
||||
/*
|
||||
result.WriteRune(unicode.ToUpper(firstRune))
|
||||
result.WriteString(firstPart[offset:])
|
||||
*/
|
||||
default:
|
||||
result.WriteString(firstPart)
|
||||
}
|
||||
}
|
||||
|
||||
for _, lexem := range lexemes[1:] {
|
||||
goName := lexem.GetUnsafeGoName()
|
||||
|
||||
// to support old behavior
|
||||
if lexem.IsInitialism() {
|
||||
goName = upper(goName)
|
||||
}
|
||||
result += goName
|
||||
result.WriteString(goName)
|
||||
}
|
||||
|
||||
if len(result) > 0 {
|
||||
// Only prefix with X when the first character isn't an ascii letter
|
||||
first := []rune(result)[0]
|
||||
if !unicode.IsLetter(first) || (first > unicode.MaxASCII && !unicode.IsUpper(first)) {
|
||||
if GoNamePrefixFunc == nil {
|
||||
return "X" + result
|
||||
}
|
||||
result = GoNamePrefixFunc(name) + result
|
||||
}
|
||||
first = []rune(result)[0]
|
||||
if unicode.IsLetter(first) && !unicode.IsUpper(first) {
|
||||
result = string(append([]rune{unicode.ToUpper(first)}, []rune(result)[1:]...))
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
return result.String()
|
||||
}
|
||||
|
||||
// ContainsStrings searches a slice of strings for a case-sensitive match
|
||||
@ -341,13 +321,22 @@ type zeroable interface {
|
||||
// IsZero returns true when the value passed into the function is a zero value.
|
||||
// This allows for safer checking of interface values.
|
||||
func IsZero(data interface{}) bool {
|
||||
v := reflect.ValueOf(data)
|
||||
// check for nil data
|
||||
switch v.Kind() { //nolint:exhaustive
|
||||
case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
|
||||
if v.IsNil() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// check for things that have an IsZero method instead
|
||||
if vv, ok := data.(zeroable); ok {
|
||||
return vv.IsZero()
|
||||
}
|
||||
|
||||
// continue with slightly more complex reflection
|
||||
v := reflect.ValueOf(data)
|
||||
switch v.Kind() {
|
||||
switch v.Kind() { //nolint:exhaustive
|
||||
case reflect.String:
|
||||
return v.Len() == 0
|
||||
case reflect.Bool:
|
||||
@ -358,24 +347,13 @@ func IsZero(data interface{}) bool {
|
||||
return v.Uint() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float() == 0
|
||||
case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
|
||||
return v.IsNil()
|
||||
case reflect.Struct, reflect.Array:
|
||||
return reflect.DeepEqual(data, reflect.Zero(v.Type()).Interface())
|
||||
case reflect.Invalid:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// AddInitialisms add additional initialisms
|
||||
func AddInitialisms(words ...string) {
|
||||
for _, word := range words {
|
||||
// commonInitialisms[upper(word)] = true
|
||||
commonInitialisms.add(upper(word))
|
||||
}
|
||||
// sort again
|
||||
initialisms = commonInitialisms.sorted()
|
||||
}
|
||||
|
||||
// CommandLineOptionsGroup represents a group of user-defined command line options
|
||||
|
39
vendor/github.com/go-openapi/swag/yaml.go
generated
vendored
39
vendor/github.com/go-openapi/swag/yaml.go
generated
vendored
@ -16,8 +16,11 @@ package swag
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"github.com/mailru/easyjson/jlexer"
|
||||
@ -48,7 +51,7 @@ func BytesToYAMLDoc(data []byte) (interface{}, error) {
|
||||
return nil, err
|
||||
}
|
||||
if document.Kind != yaml.DocumentNode || len(document.Content) != 1 || document.Content[0].Kind != yaml.MappingNode {
|
||||
return nil, fmt.Errorf("only YAML documents that are objects are supported")
|
||||
return nil, errors.New("only YAML documents that are objects are supported")
|
||||
}
|
||||
return &document, nil
|
||||
}
|
||||
@ -147,7 +150,7 @@ func yamlScalar(node *yaml.Node) (interface{}, error) {
|
||||
case yamlTimestamp:
|
||||
return node.Value, nil
|
||||
case yamlNull:
|
||||
return nil, nil
|
||||
return nil, nil //nolint:nilnil
|
||||
default:
|
||||
return nil, fmt.Errorf("YAML tag %q is not supported", node.LongTag())
|
||||
}
|
||||
@ -245,7 +248,27 @@ func (s JSONMapSlice) MarshalYAML() (interface{}, error) {
|
||||
return yaml.Marshal(&n)
|
||||
}
|
||||
|
||||
func isNil(input interface{}) bool {
|
||||
if input == nil {
|
||||
return true
|
||||
}
|
||||
kind := reflect.TypeOf(input).Kind()
|
||||
switch kind { //nolint:exhaustive
|
||||
case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Chan:
|
||||
return reflect.ValueOf(input).IsNil()
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func json2yaml(item interface{}) (*yaml.Node, error) {
|
||||
if isNil(item) {
|
||||
return &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Value: "null",
|
||||
}, nil
|
||||
}
|
||||
|
||||
switch val := item.(type) {
|
||||
case JSONMapSlice:
|
||||
var n yaml.Node
|
||||
@ -265,7 +288,14 @@ func json2yaml(item interface{}) (*yaml.Node, error) {
|
||||
case map[string]interface{}:
|
||||
var n yaml.Node
|
||||
n.Kind = yaml.MappingNode
|
||||
for k, v := range val {
|
||||
keys := make([]string, 0, len(val))
|
||||
for k := range val {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
for _, k := range keys {
|
||||
v := val[k]
|
||||
childNode, err := json2yaml(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -318,8 +348,9 @@ func json2yaml(item interface{}) (*yaml.Node, error) {
|
||||
Tag: yamlBoolScalar,
|
||||
Value: strconv.FormatBool(val),
|
||||
}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unhandled type: %T", val)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// JSONMapItem represents the value of a key in a JSON object held by JSONMapSlice
|
||||
|
26
vendor/github.com/mohae/deepcopy/.gitignore
generated
vendored
Normal file
26
vendor/github.com/mohae/deepcopy/.gitignore
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*~
|
||||
*.out
|
||||
*.log
|
11
vendor/github.com/mohae/deepcopy/.travis.yml
generated
vendored
Normal file
11
vendor/github.com/mohae/deepcopy/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- tip
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: tip
|
||||
|
||||
script:
|
||||
- go test ./...
|
21
vendor/github.com/mohae/deepcopy/LICENSE
generated
vendored
Normal file
21
vendor/github.com/mohae/deepcopy/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Joel
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
8
vendor/github.com/mohae/deepcopy/README.md
generated
vendored
Normal file
8
vendor/github.com/mohae/deepcopy/README.md
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
deepCopy
|
||||
========
|
||||
[](https://godoc.org/github.com/mohae/deepcopy)[](https://travis-ci.org/mohae/deepcopy)
|
||||
|
||||
DeepCopy makes deep copies of things: unexported field values are not copied.
|
||||
|
||||
## Usage
|
||||
cpy := deepcopy.Copy(orig)
|
125
vendor/github.com/mohae/deepcopy/deepcopy.go
generated
vendored
Normal file
125
vendor/github.com/mohae/deepcopy/deepcopy.go
generated
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
// deepcopy makes deep copies of things. A standard copy will copy the
|
||||
// pointers: deep copy copies the values pointed to. Unexported field
|
||||
// values are not copied.
|
||||
//
|
||||
// Copyright (c)2014-2016, Joel Scoble (github.com/mohae), all rights reserved.
|
||||
// License: MIT, for more details check the included LICENSE file.
|
||||
package deepcopy
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Interface for delegating copy process to type
|
||||
type Interface interface {
|
||||
DeepCopy() interface{}
|
||||
}
|
||||
|
||||
// Iface is an alias to Copy; this exists for backwards compatibility reasons.
|
||||
func Iface(iface interface{}) interface{} {
|
||||
return Copy(iface)
|
||||
}
|
||||
|
||||
// Copy creates a deep copy of whatever is passed to it and returns the copy
|
||||
// in an interface{}. The returned value will need to be asserted to the
|
||||
// correct type.
|
||||
func Copy(src interface{}) interface{} {
|
||||
if src == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Make the interface a reflect.Value
|
||||
original := reflect.ValueOf(src)
|
||||
|
||||
// Make a copy of the same type as the original.
|
||||
cpy := reflect.New(original.Type()).Elem()
|
||||
|
||||
// Recursively copy the original.
|
||||
copyRecursive(original, cpy)
|
||||
|
||||
// Return the copy as an interface.
|
||||
return cpy.Interface()
|
||||
}
|
||||
|
||||
// copyRecursive does the actual copying of the interface. It currently has
|
||||
// limited support for what it can handle. Add as needed.
|
||||
func copyRecursive(original, cpy reflect.Value) {
|
||||
// check for implement deepcopy.Interface
|
||||
if original.CanInterface() {
|
||||
if copier, ok := original.Interface().(Interface); ok {
|
||||
cpy.Set(reflect.ValueOf(copier.DeepCopy()))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// handle according to original's Kind
|
||||
switch original.Kind() {
|
||||
case reflect.Ptr:
|
||||
// Get the actual value being pointed to.
|
||||
originalValue := original.Elem()
|
||||
|
||||
// if it isn't valid, return.
|
||||
if !originalValue.IsValid() {
|
||||
return
|
||||
}
|
||||
cpy.Set(reflect.New(originalValue.Type()))
|
||||
copyRecursive(originalValue, cpy.Elem())
|
||||
|
||||
case reflect.Interface:
|
||||
// If this is a nil, don't do anything
|
||||
if original.IsNil() {
|
||||
return
|
||||
}
|
||||
// Get the value for the interface, not the pointer.
|
||||
originalValue := original.Elem()
|
||||
|
||||
// Get the value by calling Elem().
|
||||
copyValue := reflect.New(originalValue.Type()).Elem()
|
||||
copyRecursive(originalValue, copyValue)
|
||||
cpy.Set(copyValue)
|
||||
|
||||
case reflect.Struct:
|
||||
t, ok := original.Interface().(time.Time)
|
||||
if ok {
|
||||
cpy.Set(reflect.ValueOf(t))
|
||||
return
|
||||
}
|
||||
// Go through each field of the struct and copy it.
|
||||
for i := 0; i < original.NumField(); i++ {
|
||||
// The Type's StructField for a given field is checked to see if StructField.PkgPath
|
||||
// is set to determine if the field is exported or not because CanSet() returns false
|
||||
// for settable fields. I'm not sure why. -mohae
|
||||
if original.Type().Field(i).PkgPath != "" {
|
||||
continue
|
||||
}
|
||||
copyRecursive(original.Field(i), cpy.Field(i))
|
||||
}
|
||||
|
||||
case reflect.Slice:
|
||||
if original.IsNil() {
|
||||
return
|
||||
}
|
||||
// Make a new slice and copy each element.
|
||||
cpy.Set(reflect.MakeSlice(original.Type(), original.Len(), original.Cap()))
|
||||
for i := 0; i < original.Len(); i++ {
|
||||
copyRecursive(original.Index(i), cpy.Index(i))
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
if original.IsNil() {
|
||||
return
|
||||
}
|
||||
cpy.Set(reflect.MakeMap(original.Type()))
|
||||
for _, key := range original.MapKeys() {
|
||||
originalValue := original.MapIndex(key)
|
||||
copyValue := reflect.New(originalValue.Type()).Elem()
|
||||
copyRecursive(originalValue, copyValue)
|
||||
copyKey := Copy(key.Interface())
|
||||
cpy.SetMapIndex(reflect.ValueOf(copyKey), copyValue)
|
||||
}
|
||||
|
||||
default:
|
||||
cpy.Set(original)
|
||||
}
|
||||
}
|
20
vendor/github.com/oasdiff/yaml/.gitignore
generated
vendored
Normal file
20
vendor/github.com/oasdiff/yaml/.gitignore
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
# OSX leaves these everywhere on SMB shares
|
||||
._*
|
||||
|
||||
# Eclipse files
|
||||
.classpath
|
||||
.project
|
||||
.settings/**
|
||||
|
||||
# Emacs save files
|
||||
*~
|
||||
|
||||
# Vim-related files
|
||||
[._]*.s[a-w][a-z]
|
||||
[._]s[a-w][a-z]
|
||||
*.un~
|
||||
Session.vim
|
||||
.netrwhist
|
||||
|
||||
# Go test binaries
|
||||
*.test
|
16
vendor/github.com/oasdiff/yaml/.golangci.toml
generated
vendored
Normal file
16
vendor/github.com/oasdiff/yaml/.golangci.toml
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
[run]
|
||||
timeout = "120s"
|
||||
|
||||
[output]
|
||||
format = "colored-line-number"
|
||||
|
||||
[linters]
|
||||
enable = [
|
||||
"gocyclo", "unconvert", "goimports", "unused", "unused",
|
||||
"vetshadow", "nakedret", "errcheck", "revive", "ineffassign",
|
||||
"goconst", "vet", "unparam", "gofmt"
|
||||
]
|
||||
|
||||
[issues]
|
||||
exclude-use-default = false
|
||||
|
50
vendor/github.com/oasdiff/yaml/LICENSE
generated
vendored
Normal file
50
vendor/github.com/oasdiff/yaml/LICENSE
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Sam Ghods
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
133
vendor/github.com/oasdiff/yaml/README.md
generated
vendored
Normal file
133
vendor/github.com/oasdiff/yaml/README.md
generated
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
# YAML marshaling and unmarshaling support for Go
|
||||
|
||||
[](https://github.com/invopop/yaml/actions/workflows/lint.yaml)
|
||||
[](https://github.com/invopop/yaml/actions/workflows/test.yaml)
|
||||
[](https://goreportcard.com/report/github.com/invopop/yaml)
|
||||

|
||||
|
||||
## Fork
|
||||
This fork is an improved version of the invopop/yaml package, designed to include line and column location information for YAML elements during unmarshalling.
|
||||
To include location information use ```UnmarshalWithOrigin``` instead of ```Unmarshal```.
|
||||
The heavy lifting is done by the underlying [oasdiff/yaml3](https://github.com/oasdiff/yaml3) package.
|
||||
|
||||
## Introduction
|
||||
|
||||
A wrapper around [go-yaml](https://github.com/go-yaml/yaml) designed to enable a better way of handling YAML when marshaling to and from structs.
|
||||
|
||||
This is a fork and split of the original [ghodss/yaml](https://github.com/ghodss/yaml) repository which no longer appears to be maintained.
|
||||
|
||||
In short, this library first converts YAML to JSON using go-yaml and then uses `json.Marshal` and `json.Unmarshal` to convert to or from the struct. This means that it effectively reuses the JSON struct tags as well as the custom JSON methods `MarshalJSON` and `UnmarshalJSON` unlike go-yaml. For a detailed overview of the rationale behind this method, [see this blog post](https://web.archive.org/web/20150812020634/http://ghodss.com/2014/the-right-way-to-handle-yaml-in-golang/).
|
||||
|
||||
## Compatibility
|
||||
|
||||
This package uses [go-yaml](https://github.com/go-yaml/yaml) and therefore supports [everything go-yaml supports](https://github.com/go-yaml/yaml#compatibility).
|
||||
|
||||
Tested against Go versions 1.14 and onwards.
|
||||
|
||||
## Caveats
|
||||
|
||||
**Caveat #1:** When using `yaml.Marshal` and `yaml.Unmarshal`, binary data should NOT be preceded with the `!!binary` YAML tag. If you do, go-yaml will convert the binary data from base64 to native binary data, which is not compatible with JSON. You can still use binary in your YAML files though - just store them without the `!!binary` tag and decode the base64 in your code (e.g. in the custom JSON methods `MarshalJSON` and `UnmarshalJSON`). This also has the benefit that your YAML and your JSON binary data will be decoded exactly the same way. As an example:
|
||||
|
||||
```
|
||||
BAD:
|
||||
exampleKey: !!binary gIGC
|
||||
|
||||
GOOD:
|
||||
exampleKey: gIGC
|
||||
... and decode the base64 data in your code.
|
||||
```
|
||||
|
||||
**Caveat #2:** When using `YAMLToJSON` directly, maps with keys that are maps will result in an error since this is not supported by JSON. This error will occur in `Unmarshal` as well since you can't unmarshal map keys anyways since struct fields can't be keys.
|
||||
|
||||
## Installation and usage
|
||||
|
||||
To install, run:
|
||||
|
||||
```
|
||||
$ go get github.com/invopop/yaml
|
||||
```
|
||||
|
||||
And import using:
|
||||
|
||||
```
|
||||
import "github.com/invopop/yaml"
|
||||
```
|
||||
|
||||
Usage is very similar to the JSON library:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/invopop/yaml"
|
||||
)
|
||||
|
||||
type Person struct {
|
||||
Name string `json:"name"` // Affects YAML field names too.
|
||||
Age int `json:"age"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Marshal a Person struct to YAML.
|
||||
p := Person{"John", 30}
|
||||
y, err := yaml.Marshal(p)
|
||||
if err != nil {
|
||||
fmt.Printf("err: %v\n", err)
|
||||
return
|
||||
}
|
||||
fmt.Println(string(y))
|
||||
/* Output:
|
||||
age: 30
|
||||
name: John
|
||||
*/
|
||||
|
||||
// Unmarshal the YAML back into a Person struct.
|
||||
var p2 Person
|
||||
err = yaml.Unmarshal(y, &p2)
|
||||
if err != nil {
|
||||
fmt.Printf("err: %v\n", err)
|
||||
return
|
||||
}
|
||||
fmt.Println(p2)
|
||||
/* Output:
|
||||
{John 30}
|
||||
*/
|
||||
}
|
||||
```
|
||||
|
||||
`yaml.YAMLToJSON` and `yaml.JSONToYAML` methods are also available:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/invopop/yaml"
|
||||
)
|
||||
|
||||
func main() {
|
||||
j := []byte(`{"name": "John", "age": 30}`)
|
||||
y, err := yaml.JSONToYAML(j)
|
||||
if err != nil {
|
||||
fmt.Printf("err: %v\n", err)
|
||||
return
|
||||
}
|
||||
fmt.Println(string(y))
|
||||
/* Output:
|
||||
name: John
|
||||
age: 30
|
||||
*/
|
||||
j2, err := yaml.YAMLToJSON(y)
|
||||
if err != nil {
|
||||
fmt.Printf("err: %v\n", err)
|
||||
return
|
||||
}
|
||||
fmt.Println(string(j2))
|
||||
/* Output:
|
||||
{"age":30,"name":"John"}
|
||||
*/
|
||||
}
|
||||
```
|
499
vendor/github.com/oasdiff/yaml/fields.go
generated
vendored
Normal file
499
vendor/github.com/oasdiff/yaml/fields.go
generated
vendored
Normal file
@ -0,0 +1,499 @@
|
||||
// Copyright 2013 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 yaml
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// indirect walks down v allocating pointers as needed,
|
||||
// until it gets to a non-pointer.
|
||||
// if it encounters an Unmarshaler, indirect stops and returns that.
|
||||
// if decodingNull is true, indirect stops at the last pointer so it can be set to nil.
|
||||
func indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.TextUnmarshaler, reflect.Value) {
|
||||
// If v is a named type and is addressable,
|
||||
// start with its address, so that if the type has pointer methods,
|
||||
// we find them.
|
||||
if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {
|
||||
v = v.Addr()
|
||||
}
|
||||
for {
|
||||
// Load value from interface, but only if the result will be
|
||||
// usefully addressable.
|
||||
if v.Kind() == reflect.Interface && !v.IsNil() {
|
||||
e := v.Elem()
|
||||
if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) {
|
||||
v = e
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if v.Kind() != reflect.Ptr {
|
||||
break
|
||||
}
|
||||
|
||||
if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() {
|
||||
break
|
||||
}
|
||||
if v.IsNil() {
|
||||
if v.CanSet() {
|
||||
v.Set(reflect.New(v.Type().Elem()))
|
||||
} else {
|
||||
v = reflect.New(v.Type().Elem())
|
||||
}
|
||||
}
|
||||
if v.Type().NumMethod() > 0 {
|
||||
if u, ok := v.Interface().(json.Unmarshaler); ok {
|
||||
return u, nil, reflect.Value{}
|
||||
}
|
||||
if u, ok := v.Interface().(encoding.TextUnmarshaler); ok {
|
||||
return nil, u, reflect.Value{}
|
||||
}
|
||||
}
|
||||
v = v.Elem()
|
||||
}
|
||||
return nil, nil, v
|
||||
}
|
||||
|
||||
// A field represents a single field found in a struct.
|
||||
type field struct {
|
||||
name string
|
||||
nameBytes []byte // []byte(name)
|
||||
equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent
|
||||
|
||||
tag bool
|
||||
index []int
|
||||
typ reflect.Type
|
||||
omitEmpty bool
|
||||
quoted bool
|
||||
}
|
||||
|
||||
func fillField(f field) field {
|
||||
f.nameBytes = []byte(f.name)
|
||||
f.equalFold = foldFunc(f.nameBytes)
|
||||
return f
|
||||
}
|
||||
|
||||
// byName sorts field by name, breaking ties with depth,
|
||||
// then breaking ties with "name came from json tag", then
|
||||
// breaking ties with index sequence.
|
||||
type byName []field
|
||||
|
||||
func (x byName) Len() int { return len(x) }
|
||||
|
||||
func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||
|
||||
func (x byName) Less(i, j int) bool {
|
||||
if x[i].name != x[j].name {
|
||||
return x[i].name < x[j].name
|
||||
}
|
||||
if len(x[i].index) != len(x[j].index) {
|
||||
return len(x[i].index) < len(x[j].index)
|
||||
}
|
||||
if x[i].tag != x[j].tag {
|
||||
return x[i].tag
|
||||
}
|
||||
return byIndex(x).Less(i, j)
|
||||
}
|
||||
|
||||
// byIndex sorts field by index sequence.
|
||||
type byIndex []field
|
||||
|
||||
func (x byIndex) Len() int { return len(x) }
|
||||
|
||||
func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||
|
||||
func (x byIndex) Less(i, j int) bool {
|
||||
for k, xik := range x[i].index {
|
||||
if k >= len(x[j].index) {
|
||||
return false
|
||||
}
|
||||
if xik != x[j].index[k] {
|
||||
return xik < x[j].index[k]
|
||||
}
|
||||
}
|
||||
return len(x[i].index) < len(x[j].index)
|
||||
}
|
||||
|
||||
// typeFields returns a list of fields that JSON should recognize for the given type.
|
||||
// The algorithm is breadth-first search over the set of structs to include - the top struct
|
||||
// and then any reachable anonymous structs.
|
||||
func typeFields(t reflect.Type) []field {
|
||||
// Anonymous fields to explore at the current level and the next.
|
||||
current := []field{}
|
||||
next := []field{{typ: t}}
|
||||
|
||||
// Count of queued names for current level and the next.
|
||||
var count, nextCount map[reflect.Type]int
|
||||
|
||||
// Types already visited at an earlier level.
|
||||
visited := map[reflect.Type]bool{}
|
||||
|
||||
// Fields found.
|
||||
var fields []field
|
||||
|
||||
for len(next) > 0 {
|
||||
current, next = next, current[:0]
|
||||
count, nextCount = nextCount, map[reflect.Type]int{}
|
||||
|
||||
for _, f := range current {
|
||||
if visited[f.typ] {
|
||||
continue
|
||||
}
|
||||
visited[f.typ] = true
|
||||
|
||||
// Scan f.typ for fields to include.
|
||||
for i := 0; i < f.typ.NumField(); i++ {
|
||||
sf := f.typ.Field(i)
|
||||
if sf.PkgPath != "" { // unexported
|
||||
continue
|
||||
}
|
||||
tag := sf.Tag.Get("json")
|
||||
if tag == "-" {
|
||||
continue
|
||||
}
|
||||
name, opts := parseTag(tag)
|
||||
if !isValidTag(name) {
|
||||
name = ""
|
||||
}
|
||||
index := make([]int, len(f.index)+1)
|
||||
copy(index, f.index)
|
||||
index[len(f.index)] = i
|
||||
|
||||
ft := sf.Type
|
||||
if ft.Name() == "" && ft.Kind() == reflect.Ptr {
|
||||
// Follow pointer.
|
||||
ft = ft.Elem()
|
||||
}
|
||||
|
||||
// Record found field and index sequence.
|
||||
if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
|
||||
tagged := name != ""
|
||||
if name == "" {
|
||||
name = sf.Name
|
||||
}
|
||||
fields = append(fields, fillField(field{
|
||||
name: name,
|
||||
tag: tagged,
|
||||
index: index,
|
||||
typ: ft,
|
||||
omitEmpty: opts.Contains("omitempty"),
|
||||
quoted: opts.Contains("string"),
|
||||
}))
|
||||
if count[f.typ] > 1 {
|
||||
// If there were multiple instances, add a second,
|
||||
// so that the annihilation code will see a duplicate.
|
||||
// It only cares about the distinction between 1 or 2,
|
||||
// so don't bother generating any more copies.
|
||||
fields = append(fields, fields[len(fields)-1])
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Record new anonymous struct to explore in next round.
|
||||
nextCount[ft]++
|
||||
if nextCount[ft] == 1 {
|
||||
next = append(next, fillField(field{name: ft.Name(), index: index, typ: ft}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sort.Sort(byName(fields))
|
||||
|
||||
// Delete all fields that are hidden by the Go rules for embedded fields,
|
||||
// except that fields with JSON tags are promoted.
|
||||
|
||||
// The fields are sorted in primary order of name, secondary order
|
||||
// of field index length. Loop over names; for each name, delete
|
||||
// hidden fields by choosing the one dominant field that survives.
|
||||
out := fields[:0]
|
||||
for advance, i := 0, 0; i < len(fields); i += advance {
|
||||
// One iteration per name.
|
||||
// Find the sequence of fields with the name of this first field.
|
||||
fi := fields[i]
|
||||
name := fi.name
|
||||
for advance = 1; i+advance < len(fields); advance++ {
|
||||
fj := fields[i+advance]
|
||||
if fj.name != name {
|
||||
break
|
||||
}
|
||||
}
|
||||
if advance == 1 { // Only one field with this name
|
||||
out = append(out, fi)
|
||||
continue
|
||||
}
|
||||
dominant, ok := dominantField(fields[i : i+advance])
|
||||
if ok {
|
||||
out = append(out, dominant)
|
||||
}
|
||||
}
|
||||
|
||||
fields = out
|
||||
sort.Sort(byIndex(fields))
|
||||
|
||||
return fields
|
||||
}
|
||||
|
||||
// dominantField looks through the fields, all of which are known to
|
||||
// have the same name, to find the single field that dominates the
|
||||
// others using Go's embedding rules, modified by the presence of
|
||||
// JSON tags. If there are multiple top-level fields, the boolean
|
||||
// will be false: This condition is an error in Go and we skip all
|
||||
// the fields.
|
||||
func dominantField(fields []field) (field, bool) {
|
||||
// The fields are sorted in increasing index-length order. The winner
|
||||
// must therefore be one with the shortest index length. Drop all
|
||||
// longer entries, which is easy: just truncate the slice.
|
||||
length := len(fields[0].index)
|
||||
tagged := -1 // Index of first tagged field.
|
||||
for i, f := range fields {
|
||||
if len(f.index) > length {
|
||||
fields = fields[:i]
|
||||
break
|
||||
}
|
||||
if f.tag {
|
||||
if tagged >= 0 {
|
||||
// Multiple tagged fields at the same level: conflict.
|
||||
// Return no field.
|
||||
return field{}, false
|
||||
}
|
||||
tagged = i
|
||||
}
|
||||
}
|
||||
if tagged >= 0 {
|
||||
return fields[tagged], true
|
||||
}
|
||||
// All remaining fields have the same length. If there's more than one,
|
||||
// we have a conflict (two fields named "X" at the same level) and we
|
||||
// return no field.
|
||||
if len(fields) > 1 {
|
||||
return field{}, false
|
||||
}
|
||||
return fields[0], true
|
||||
}
|
||||
|
||||
var fieldCache struct {
|
||||
sync.RWMutex
|
||||
m map[reflect.Type][]field
|
||||
}
|
||||
|
||||
// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
|
||||
func cachedTypeFields(t reflect.Type) []field {
|
||||
fieldCache.RLock()
|
||||
f := fieldCache.m[t]
|
||||
fieldCache.RUnlock()
|
||||
if f != nil {
|
||||
return f
|
||||
}
|
||||
|
||||
// Compute fields without lock.
|
||||
// Might duplicate effort but won't hold other computations back.
|
||||
f = typeFields(t)
|
||||
if f == nil {
|
||||
f = []field{}
|
||||
}
|
||||
|
||||
fieldCache.Lock()
|
||||
if fieldCache.m == nil {
|
||||
fieldCache.m = map[reflect.Type][]field{}
|
||||
}
|
||||
fieldCache.m[t] = f
|
||||
fieldCache.Unlock()
|
||||
return f
|
||||
}
|
||||
|
||||
func isValidTag(s string) bool {
|
||||
if s == "" {
|
||||
return false
|
||||
}
|
||||
for _, c := range s {
|
||||
switch {
|
||||
case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c):
|
||||
// Backslash and quote chars are reserved, but
|
||||
// otherwise any punctuation chars are allowed
|
||||
// in a tag name.
|
||||
default:
|
||||
if !unicode.IsLetter(c) && !unicode.IsDigit(c) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const (
|
||||
caseMask = ^byte(0x20) // Mask to ignore case in ASCII.
|
||||
kelvin = '\u212a'
|
||||
smallLongEss = '\u017f'
|
||||
)
|
||||
|
||||
// foldFunc returns one of four different case folding equivalence
|
||||
// functions, from most general (and slow) to fastest:
|
||||
//
|
||||
// 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8
|
||||
// 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S')
|
||||
// 3) asciiEqualFold, no special, but includes non-letters (including _)
|
||||
// 4) simpleLetterEqualFold, no specials, no non-letters.
|
||||
//
|
||||
// The letters S and K are special because they map to 3 runes, not just 2:
|
||||
// - S maps to s and to U+017F 'ſ' Latin small letter long s
|
||||
// - k maps to K and to U+212A 'K' Kelvin sign
|
||||
//
|
||||
// See http://play.golang.org/p/tTxjOc0OGo
|
||||
//
|
||||
// The returned function is specialized for matching against s and
|
||||
// should only be given s. It's not curried for performance reasons.
|
||||
func foldFunc(s []byte) func(s, t []byte) bool {
|
||||
nonLetter := false
|
||||
special := false // special letter
|
||||
for _, b := range s {
|
||||
if b >= utf8.RuneSelf {
|
||||
return bytes.EqualFold
|
||||
}
|
||||
upper := b & caseMask
|
||||
if upper < 'A' || upper > 'Z' {
|
||||
nonLetter = true
|
||||
} else if upper == 'K' || upper == 'S' {
|
||||
// See above for why these letters are special.
|
||||
special = true
|
||||
}
|
||||
}
|
||||
if special {
|
||||
return equalFoldRight
|
||||
}
|
||||
if nonLetter {
|
||||
return asciiEqualFold
|
||||
}
|
||||
return simpleLetterEqualFold
|
||||
}
|
||||
|
||||
// equalFoldRight is a specialization of bytes.EqualFold when s is
|
||||
// known to be all ASCII (including punctuation), but contains an 's',
|
||||
// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t.
|
||||
// See comments on foldFunc.
|
||||
func equalFoldRight(s, t []byte) bool {
|
||||
for _, sb := range s {
|
||||
if len(t) == 0 {
|
||||
return false
|
||||
}
|
||||
tb := t[0]
|
||||
if tb < utf8.RuneSelf {
|
||||
if sb != tb {
|
||||
sbUpper := sb & caseMask
|
||||
if 'A' <= sbUpper && sbUpper <= 'Z' {
|
||||
if sbUpper != tb&caseMask {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
t = t[1:]
|
||||
continue
|
||||
}
|
||||
// sb is ASCII and t is not. t must be either kelvin
|
||||
// sign or long s; sb must be s, S, k, or K.
|
||||
tr, size := utf8.DecodeRune(t)
|
||||
switch sb {
|
||||
case 's', 'S':
|
||||
if tr != smallLongEss {
|
||||
return false
|
||||
}
|
||||
case 'k', 'K':
|
||||
if tr != kelvin {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
return false
|
||||
}
|
||||
t = t[size:]
|
||||
|
||||
}
|
||||
return len(t) <= 0
|
||||
}
|
||||
|
||||
// asciiEqualFold is a specialization of bytes.EqualFold for use when
|
||||
// s is all ASCII (but may contain non-letters) and contains no
|
||||
// special-folding letters.
|
||||
// See comments on foldFunc.
|
||||
func asciiEqualFold(s, t []byte) bool {
|
||||
if len(s) != len(t) {
|
||||
return false
|
||||
}
|
||||
for i, sb := range s {
|
||||
tb := t[i]
|
||||
if sb == tb {
|
||||
continue
|
||||
}
|
||||
if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {
|
||||
if sb&caseMask != tb&caseMask {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// simpleLetterEqualFold is a specialization of bytes.EqualFold for
|
||||
// use when s is all ASCII letters (no underscores, etc) and also
|
||||
// doesn't contain 'k', 'K', 's', or 'S'.
|
||||
// See comments on foldFunc.
|
||||
func simpleLetterEqualFold(s, t []byte) bool {
|
||||
if len(s) != len(t) {
|
||||
return false
|
||||
}
|
||||
for i, b := range s {
|
||||
if b&caseMask != t[i]&caseMask {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// tagOptions is the string following a comma in a struct field's "json"
|
||||
// tag, or the empty string. It does not include the leading comma.
|
||||
type tagOptions string
|
||||
|
||||
// parseTag splits a struct field's json tag into its name and
|
||||
// comma-separated options.
|
||||
func parseTag(tag string) (string, tagOptions) {
|
||||
if idx := strings.Index(tag, ","); idx != -1 {
|
||||
return tag[:idx], tagOptions(tag[idx+1:])
|
||||
}
|
||||
return tag, tagOptions("")
|
||||
}
|
||||
|
||||
// Contains reports whether a comma-separated list of options
|
||||
// contains a particular substr flag. substr must be surrounded by a
|
||||
// string boundary or commas.
|
||||
func (o tagOptions) Contains(optionName string) bool {
|
||||
if len(o) == 0 {
|
||||
return false
|
||||
}
|
||||
s := string(o)
|
||||
for s != "" {
|
||||
var next string
|
||||
i := strings.Index(s, ",")
|
||||
if i >= 0 {
|
||||
s, next = s[:i], s[i+1:]
|
||||
}
|
||||
if s == optionName {
|
||||
return true
|
||||
}
|
||||
s = next
|
||||
}
|
||||
return false
|
||||
}
|
322
vendor/github.com/oasdiff/yaml/yaml.go
generated
vendored
Normal file
322
vendor/github.com/oasdiff/yaml/yaml.go
generated
vendored
Normal file
@ -0,0 +1,322 @@
|
||||
// Package yaml provides a wrapper around go-yaml designed to enable a better
|
||||
// way of handling YAML when marshaling to and from structs.
|
||||
//
|
||||
// In short, this package first converts YAML to JSON using go-yaml and then
|
||||
// uses json.Marshal and json.Unmarshal to convert to or from the struct. This
|
||||
// means that it effectively reuses the JSON struct tags as well as the custom
|
||||
// JSON methods MarshalJSON and UnmarshalJSON unlike go-yaml.
|
||||
package yaml // import "github.com/invopop/yaml"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"github.com/oasdiff/yaml3"
|
||||
)
|
||||
|
||||
// Marshal the object into JSON then converts JSON to YAML and returns the
|
||||
// YAML.
|
||||
func Marshal(o interface{}) ([]byte, error) {
|
||||
j, err := json.Marshal(o)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error marshaling into JSON: %v", err)
|
||||
}
|
||||
|
||||
y, err := JSONToYAML(j)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error converting JSON to YAML: %v", err)
|
||||
}
|
||||
|
||||
return y, nil
|
||||
}
|
||||
|
||||
// JSONOpt is a decoding option for decoding from JSON format.
|
||||
type JSONOpt func(*json.Decoder) *json.Decoder
|
||||
|
||||
// YAMLOpt is a decoding option for decoding from YAML format.
|
||||
type YAMLOpt func(*yaml.Decoder) *yaml.Decoder
|
||||
|
||||
// Unmarshal converts YAML to JSON then uses JSON to unmarshal into an object,
|
||||
// optionally configuring the behavior of the JSON unmarshal.
|
||||
func Unmarshal(y []byte, o interface{}, opts ...JSONOpt) error {
|
||||
return UnmarshalWithOrigin(y, o, false, opts...)
|
||||
}
|
||||
|
||||
// UnmarshalWithOrigin is like Unmarshal but if withOrigin is true, it will
|
||||
// include the origin information in the output.
|
||||
func UnmarshalWithOrigin(y []byte, o interface{}, withOrigin bool, opts ...JSONOpt) error {
|
||||
dec := yaml.NewDecoder(bytes.NewReader(y))
|
||||
dec.Origin(withOrigin)
|
||||
return unmarshal(dec, o, opts)
|
||||
}
|
||||
|
||||
func unmarshal(dec *yaml.Decoder, o interface{}, opts []JSONOpt) error {
|
||||
vo := reflect.ValueOf(o)
|
||||
j, err := yamlToJSON(dec, &vo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error converting YAML to JSON: %v", err)
|
||||
}
|
||||
|
||||
err = jsonUnmarshal(bytes.NewReader(j), o, opts...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error unmarshaling JSON: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// jsonUnmarshal unmarshals the JSON byte stream from the given reader into the
|
||||
// object, optionally applying decoder options prior to decoding. We are not
|
||||
// using json.Unmarshal directly as we want the chance to pass in non-default
|
||||
// options.
|
||||
func jsonUnmarshal(r io.Reader, o interface{}, opts ...JSONOpt) error {
|
||||
d := json.NewDecoder(r)
|
||||
for _, opt := range opts {
|
||||
d = opt(d)
|
||||
}
|
||||
if err := d.Decode(&o); err != nil {
|
||||
return fmt.Errorf("while decoding JSON: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// JSONToYAML converts JSON to YAML.
|
||||
func JSONToYAML(j []byte) ([]byte, error) {
|
||||
// Convert the JSON to an object.
|
||||
var jsonObj interface{}
|
||||
// We are using yaml.Unmarshal here (instead of json.Unmarshal) because the
|
||||
// Go JSON library doesn't try to pick the right number type (int, float,
|
||||
// etc.) when unmarshalling to interface{}, it just picks float64
|
||||
// universally. go-yaml does go through the effort of picking the right
|
||||
// number type, so we can preserve number type throughout this process.
|
||||
err := yaml.Unmarshal(j, &jsonObj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Marshal this object into YAML.
|
||||
return yaml.Marshal(jsonObj)
|
||||
}
|
||||
|
||||
// YAMLToJSON converts YAML to JSON. Since JSON is a subset of YAML,
|
||||
// passing JSON through this method should be a no-op.
|
||||
//
|
||||
// Things YAML can do that are not supported by JSON:
|
||||
// - In YAML you can have binary and null keys in your maps. These are invalid
|
||||
// in JSON. (int and float keys are converted to strings.)
|
||||
// - Binary data in YAML with the !!binary tag is not supported. If you want to
|
||||
// use binary data with this library, encode the data as base64 as usual but do
|
||||
// not use the !!binary tag in your YAML. This will ensure the original base64
|
||||
// encoded data makes it all the way through to the JSON.
|
||||
func YAMLToJSON(y []byte) ([]byte, error) { //nolint:revive
|
||||
dec := yaml.NewDecoder(bytes.NewReader(y))
|
||||
return yamlToJSON(dec, nil)
|
||||
}
|
||||
|
||||
func yamlToJSON(dec *yaml.Decoder, jsonTarget *reflect.Value) ([]byte, error) {
|
||||
// Convert the YAML to an object.
|
||||
var yamlObj interface{}
|
||||
if err := dec.Decode(&yamlObj); err != nil {
|
||||
// Functionality changed in v3 which means we need to ignore EOF error.
|
||||
// See https://github.com/go-yaml/yaml/issues/639
|
||||
if !errors.Is(err, io.EOF) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// YAML objects are not completely compatible with JSON objects (e.g. you
|
||||
// can have non-string keys in YAML). So, convert the YAML-compatible object
|
||||
// to a JSON-compatible object, failing with an error if irrecoverable
|
||||
// incompatibilities happen along the way.
|
||||
jsonObj, err := convertToJSONableObject(yamlObj, jsonTarget)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert this object to JSON and return the data.
|
||||
return json.Marshal(jsonObj)
|
||||
}
|
||||
|
||||
func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (interface{}, error) { //nolint:gocyclo
|
||||
var err error
|
||||
|
||||
// Resolve jsonTarget to a concrete value (i.e. not a pointer or an
|
||||
// interface). We pass decodingNull as false because we're not actually
|
||||
// decoding into the value, we're just checking if the ultimate target is a
|
||||
// string.
|
||||
if jsonTarget != nil {
|
||||
ju, tu, pv := indirect(*jsonTarget, false)
|
||||
// We have a JSON or Text Umarshaler at this level, so we can't be trying
|
||||
// to decode into a string.
|
||||
if ju != nil || tu != nil {
|
||||
jsonTarget = nil
|
||||
} else {
|
||||
jsonTarget = &pv
|
||||
}
|
||||
}
|
||||
|
||||
// go-yaml v3 changed from v2 and now will provide map[string]interface{} by
|
||||
// default and map[interface{}]interface{} when none of the keys strings.
|
||||
// To get around this, we run a pre-loop to convert the map.
|
||||
// JSON only supports strings as keys, so we must convert.
|
||||
|
||||
switch typedYAMLObj := yamlObj.(type) {
|
||||
case map[interface{}]interface{}:
|
||||
// From my reading of go-yaml v2 (specifically the resolve function),
|
||||
// keys can only have the types string, int, int64, float64, binary
|
||||
// (unsupported), or null (unsupported).
|
||||
strMap := make(map[string]interface{})
|
||||
for k, v := range typedYAMLObj {
|
||||
// Resolve the key to a string first.
|
||||
var keyString string
|
||||
switch typedKey := k.(type) {
|
||||
case string:
|
||||
keyString = typedKey
|
||||
case int:
|
||||
keyString = strconv.Itoa(typedKey)
|
||||
case int64:
|
||||
// go-yaml will only return an int64 as a key if the system
|
||||
// architecture is 32-bit and the key's value is between 32-bit
|
||||
// and 64-bit. Otherwise the key type will simply be int.
|
||||
keyString = strconv.FormatInt(typedKey, 10)
|
||||
case float64:
|
||||
// Float64 is now supported in keys
|
||||
keyString = strconv.FormatFloat(typedKey, 'g', -1, 64)
|
||||
case bool:
|
||||
if typedKey {
|
||||
keyString = "true"
|
||||
} else {
|
||||
keyString = "false"
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported map key of type: %s, key: %+#v, value: %+#v",
|
||||
reflect.TypeOf(k), k, v)
|
||||
}
|
||||
strMap[keyString] = v
|
||||
}
|
||||
// replace yamlObj with our new string map
|
||||
yamlObj = strMap
|
||||
}
|
||||
|
||||
// If yamlObj is a number or a boolean, check if jsonTarget is a string -
|
||||
// if so, coerce. Else return normal.
|
||||
// If yamlObj is a map or array, find the field that each key is
|
||||
// unmarshaling to, and when you recurse pass the reflect.Value for that
|
||||
// field back into this function.
|
||||
switch typedYAMLObj := yamlObj.(type) {
|
||||
case map[string]interface{}:
|
||||
for k, v := range typedYAMLObj {
|
||||
|
||||
// jsonTarget should be a struct or a map. If it's a struct, find
|
||||
// the field it's going to map to and pass its reflect.Value. If
|
||||
// it's a map, find the element type of the map and pass the
|
||||
// reflect.Value created from that type. If it's neither, just pass
|
||||
// nil - JSON conversion will error for us if it's a real issue.
|
||||
if jsonTarget != nil {
|
||||
t := *jsonTarget
|
||||
if t.Kind() == reflect.Struct {
|
||||
keyBytes := []byte(k)
|
||||
// Find the field that the JSON library would use.
|
||||
var f *field
|
||||
fields := cachedTypeFields(t.Type())
|
||||
for i := range fields {
|
||||
ff := &fields[i]
|
||||
if bytes.Equal(ff.nameBytes, keyBytes) {
|
||||
f = ff
|
||||
break
|
||||
}
|
||||
// Do case-insensitive comparison.
|
||||
if f == nil && ff.equalFold(ff.nameBytes, keyBytes) {
|
||||
f = ff
|
||||
}
|
||||
}
|
||||
if f != nil {
|
||||
// Find the reflect.Value of the most preferential
|
||||
// struct field.
|
||||
jtf := t.Field(f.index[0])
|
||||
typedYAMLObj[k], err = convertToJSONableObject(v, &jtf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
} else if t.Kind() == reflect.Map {
|
||||
// Create a zero value of the map's element type to use as
|
||||
// the JSON target.
|
||||
jtv := reflect.Zero(t.Type().Elem())
|
||||
typedYAMLObj[k], err = convertToJSONableObject(v, &jtv)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
typedYAMLObj[k], err = convertToJSONableObject(v, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return typedYAMLObj, nil
|
||||
case []interface{}:
|
||||
// We need to recurse into arrays in case there are any
|
||||
// map[interface{}]interface{}'s inside and to convert any
|
||||
// numbers to strings.
|
||||
|
||||
// If jsonTarget is a slice (which it really should be), find the
|
||||
// thing it's going to map to. If it's not a slice, just pass nil
|
||||
// - JSON conversion will error for us if it's a real issue.
|
||||
var jsonSliceElemValue *reflect.Value
|
||||
if jsonTarget != nil {
|
||||
t := *jsonTarget
|
||||
if t.Kind() == reflect.Slice {
|
||||
// By default slices point to nil, but we need a reflect.Value
|
||||
// pointing to a value of the slice type, so we create one here.
|
||||
ev := reflect.Indirect(reflect.New(t.Type().Elem()))
|
||||
jsonSliceElemValue = &ev
|
||||
}
|
||||
}
|
||||
|
||||
// Make and use a new array.
|
||||
arr := make([]interface{}, len(typedYAMLObj))
|
||||
for i, v := range typedYAMLObj {
|
||||
arr[i], err = convertToJSONableObject(v, jsonSliceElemValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return arr, nil
|
||||
default:
|
||||
// If the target type is a string and the YAML type is a number,
|
||||
// convert the YAML type to a string.
|
||||
if jsonTarget != nil && (*jsonTarget).Kind() == reflect.String {
|
||||
// Based on my reading of go-yaml, it may return int, int64,
|
||||
// float64, or uint64.
|
||||
var s string
|
||||
switch typedVal := typedYAMLObj.(type) {
|
||||
case int:
|
||||
s = strconv.FormatInt(int64(typedVal), 10)
|
||||
case int64:
|
||||
s = strconv.FormatInt(typedVal, 10)
|
||||
case float64:
|
||||
s = strconv.FormatFloat(typedVal, 'g', -1, 64)
|
||||
case uint64:
|
||||
s = strconv.FormatUint(typedVal, 10)
|
||||
case bool:
|
||||
if typedVal {
|
||||
s = "true"
|
||||
} else {
|
||||
s = "false"
|
||||
}
|
||||
}
|
||||
if len(s) > 0 {
|
||||
yamlObj = interface{}(s)
|
||||
}
|
||||
}
|
||||
return yamlObj, nil
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user