update prometheus dependencies (#5520)
Signed-off-by: junot <junotxiang@kubesphere.io>
This commit is contained in:
2
vendor/github.com/go-openapi/analysis/.gitattributes
generated
vendored
Normal file
2
vendor/github.com/go-openapi/analysis/.gitattributes
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*.go text eol=lf
|
||||
|
||||
28
vendor/github.com/go-openapi/analysis/.golangci.yml
generated
vendored
28
vendor/github.com/go-openapi/analysis/.golangci.yml
generated
vendored
@@ -5,10 +5,12 @@ linters-settings:
|
||||
min-confidence: 0
|
||||
gocyclo:
|
||||
min-complexity: 40
|
||||
gocognit:
|
||||
min-complexity: 40
|
||||
maligned:
|
||||
suggest-new: true
|
||||
dupl:
|
||||
threshold: 100
|
||||
threshold: 150
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 4
|
||||
@@ -27,6 +29,28 @@ linters:
|
||||
- scopelint
|
||||
- godox
|
||||
- gocognit
|
||||
- whitespace
|
||||
#- whitespace
|
||||
- wsl
|
||||
- funlen
|
||||
- testpackage
|
||||
- wrapcheck
|
||||
#- nlreturn
|
||||
- gomnd
|
||||
- goerr113
|
||||
- exhaustivestruct
|
||||
#- errorlint
|
||||
#- nestif
|
||||
- gofumpt
|
||||
- godot
|
||||
- gci
|
||||
- dogsled
|
||||
- paralleltest
|
||||
- tparallel
|
||||
- thelper
|
||||
- ifshort
|
||||
- forbidigo
|
||||
- cyclop
|
||||
- varnamelen
|
||||
- exhaustruct
|
||||
- nonamedreturns
|
||||
- nosnakecase
|
||||
|
||||
13
vendor/github.com/go-openapi/analysis/.travis.yml
generated
vendored
13
vendor/github.com/go-openapi/analysis/.travis.yml
generated
vendored
@@ -1,13 +0,0 @@
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
go:
|
||||
- 1.13.x
|
||||
- 1.14.x
|
||||
install:
|
||||
- go get -u gotest.tools/gotestsum
|
||||
language: go
|
||||
notifications:
|
||||
slack:
|
||||
secure: Sf7kZf7ZGbnwWUMpffHwMu5A0cHkLK2MYY32LNTPj4+/3qC3Ghl7+9v4TSLOqOlCwdRNjOGblAq7s+GDJed6/xgRQl1JtCi1klzZNrYX4q01pgTPvvGcwbBkIYgeMaPeIRcK9OZnud7sRXdttozgTOpytps2U6Js32ip7uj5mHSg2ub0FwoSJwlS6dbezZ8+eDhoha0F/guY99BEwx8Bd+zROrT2TFGsSGOFGN6wFc7moCqTHO/YkWib13a2QNXqOxCCVBy/lt76Wp+JkeFppjHlzs/2lP3EAk13RIUAaesdEUHvIHrzCyNJEd3/+KO2DzsWOYfpktd+KBCvgaYOsoo7ubdT3IROeAegZdCgo/6xgCEsmFc9ZcqCfN5yNx2A+BZ2Vwmpws+bQ1E1+B5HDzzaiLcYfG4X2O210QVGVDLWsv1jqD+uPYeHY2WRfh5ZsIUFvaqgUEnwHwrK44/8REAhQavt1QAj5uJpsRd7CkRVPWRNK+yIky+wgbVUFEchRNmS55E7QWf+W4+4QZkQi7vUTMc9nbTUu2Es9NfvfudOpM2wZbn98fjpb/qq/nRv6Bk+ca+7XD5/IgNLMbWp2ouDdzbiHLCOfDUiHiDJhLfFZx9Bwo7ZwfzeOlbrQX66bx7xRKYmOe4DLrXhNcpbsMa8qbfxlZRCmYbubB/Y8h4=
|
||||
script:
|
||||
- gotestsum -f short-verbose -- -race -timeout=20m -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
28
vendor/github.com/go-openapi/analysis/README.md
generated
vendored
28
vendor/github.com/go-openapi/analysis/README.md
generated
vendored
@@ -1,9 +1,31 @@
|
||||
# OpenAPI initiative analysis [](https://travis-ci.org/go-openapi/analysis) [](https://ci.appveyor.com/project/casualjim/go-openapi/analysis/branch/master) [](https://codecov.io/gh/go-openapi/analysis)
|
||||
# OpenAPI initiative analysis
|
||||
|
||||
[](https://travis-ci.org/go-openapi/analysis)
|
||||
[](https://ci.appveyor.com/project/casualjim/go-openapi/analysis/branch/master)
|
||||
[](https://codecov.io/gh/go-openapi/analysis)
|
||||
[](https://slackin.goswagger.io)
|
||||
[](https://raw.githubusercontent.com/go-openapi/analysis/master/LICENSE)
|
||||
[](http://godoc.org/github.com/go-openapi/analysis)
|
||||
[](https://golangci.com)
|
||||
[](https://pkg.go.dev/github.com/go-openapi/analysis)
|
||||
[](https://goreportcard.com/report/github.com/go-openapi/analysis)
|
||||
|
||||
|
||||
A foundational library to analyze an OAI specification document for easier reasoning about the content.
|
||||
|
||||
## What's inside?
|
||||
|
||||
* A analyzer providing methods to walk the functional content of a specification
|
||||
* A spec flattener producing a self-contained document bundle, while preserving `$ref`s
|
||||
* A spec merger ("mixin") to merge several spec documents into a primary spec
|
||||
* A spec "fixer" ensuring that response descriptions are non empty
|
||||
|
||||
[Documentation](https://godoc.org/github.com/go-openapi/analysis)
|
||||
|
||||
## FAQ
|
||||
|
||||
* Does this library support OpenAPI 3?
|
||||
|
||||
> No.
|
||||
> This package currently only supports OpenAPI 2.0 (aka Swagger 2.0).
|
||||
> There is no plan to make it evolve toward supporting OpenAPI 3.x.
|
||||
> This [discussion thread](https://github.com/go-openapi/spec/issues/21) relates the full story.
|
||||
>
|
||||
|
||||
246
vendor/github.com/go-openapi/analysis/analyzer.go
generated
vendored
246
vendor/github.com/go-openapi/analysis/analyzer.go
generated
vendored
@@ -149,6 +149,7 @@ func New(doc *spec.Swagger) *Spec {
|
||||
}
|
||||
a.reset()
|
||||
a.initialize()
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
@@ -212,7 +213,7 @@ func (s *Spec) initialize() {
|
||||
}
|
||||
}
|
||||
for path, pathItem := range s.AllPaths() {
|
||||
s.analyzeOperations(path, &pathItem)
|
||||
s.analyzeOperations(path, &pathItem) //#nosec
|
||||
}
|
||||
|
||||
for name, parameter := range s.spec.Parameters {
|
||||
@@ -277,7 +278,7 @@ func (s *Spec) analyzeOperations(path string, pi *spec.PathItem) {
|
||||
for i, param := range op.Parameters {
|
||||
refPref := slashpath.Join("/paths", jsonpointer.Escape(path), "parameters", strconv.Itoa(i))
|
||||
if param.Ref.String() != "" {
|
||||
s.references.addParamRef(refPref, ¶m)
|
||||
s.references.addParamRef(refPref, ¶m) //#nosec
|
||||
}
|
||||
if param.Pattern != "" {
|
||||
s.patterns.addParameterPattern(refPref, param.Pattern)
|
||||
@@ -311,6 +312,26 @@ func (s *Spec) analyzeItems(name string, items *spec.Items, prefix, location str
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Spec) analyzeParameter(prefix string, i int, param spec.Parameter) {
|
||||
refPref := slashpath.Join(prefix, "parameters", strconv.Itoa(i))
|
||||
if param.Ref.String() != "" {
|
||||
s.references.addParamRef(refPref, ¶m) //#nosec
|
||||
}
|
||||
|
||||
if param.Pattern != "" {
|
||||
s.patterns.addParameterPattern(refPref, param.Pattern)
|
||||
}
|
||||
|
||||
if len(param.Enum) > 0 {
|
||||
s.enums.addParameterEnum(refPref, param.Enum)
|
||||
}
|
||||
|
||||
s.analyzeItems("items", param.Items, refPref, "parameter")
|
||||
if param.In == "body" && param.Schema != nil {
|
||||
s.analyzeSchema("schema", param.Schema, refPref)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Spec) analyzeOperation(method, path string, op *spec.Operation) {
|
||||
if op == nil {
|
||||
return
|
||||
@@ -319,72 +340,80 @@ func (s *Spec) analyzeOperation(method, path string, op *spec.Operation) {
|
||||
for _, c := range op.Consumes {
|
||||
s.consumes[c] = struct{}{}
|
||||
}
|
||||
|
||||
for _, c := range op.Produces {
|
||||
s.produces[c] = struct{}{}
|
||||
}
|
||||
|
||||
for _, ss := range op.Security {
|
||||
for k := range ss {
|
||||
s.authSchemes[k] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := s.operations[method]; !ok {
|
||||
s.operations[method] = make(map[string]*spec.Operation)
|
||||
}
|
||||
|
||||
s.operations[method][path] = op
|
||||
prefix := slashpath.Join("/paths", jsonpointer.Escape(path), strings.ToLower(method))
|
||||
for i, param := range op.Parameters {
|
||||
refPref := slashpath.Join(prefix, "parameters", strconv.Itoa(i))
|
||||
if param.Ref.String() != "" {
|
||||
s.references.addParamRef(refPref, ¶m)
|
||||
}
|
||||
if param.Pattern != "" {
|
||||
s.patterns.addParameterPattern(refPref, param.Pattern)
|
||||
}
|
||||
if len(param.Enum) > 0 {
|
||||
s.enums.addParameterEnum(refPref, param.Enum)
|
||||
}
|
||||
s.analyzeItems("items", param.Items, refPref, "parameter")
|
||||
if param.In == "body" && param.Schema != nil {
|
||||
s.analyzeSchema("schema", param.Schema, refPref)
|
||||
s.analyzeParameter(prefix, i, param)
|
||||
}
|
||||
|
||||
if op.Responses == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if op.Responses.Default != nil {
|
||||
s.analyzeDefaultResponse(prefix, op.Responses.Default)
|
||||
}
|
||||
|
||||
for k, res := range op.Responses.StatusCodeResponses {
|
||||
s.analyzeResponse(prefix, k, res)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Spec) analyzeDefaultResponse(prefix string, res *spec.Response) {
|
||||
refPref := slashpath.Join(prefix, "responses", "default")
|
||||
if res.Ref.String() != "" {
|
||||
s.references.addResponseRef(refPref, res)
|
||||
}
|
||||
|
||||
for k, v := range res.Headers {
|
||||
hRefPref := slashpath.Join(refPref, "headers", k)
|
||||
s.analyzeItems("items", v.Items, hRefPref, "header")
|
||||
if v.Pattern != "" {
|
||||
s.patterns.addHeaderPattern(hRefPref, v.Pattern)
|
||||
}
|
||||
}
|
||||
if op.Responses != nil {
|
||||
if op.Responses.Default != nil {
|
||||
refPref := slashpath.Join(prefix, "responses", "default")
|
||||
if op.Responses.Default.Ref.String() != "" {
|
||||
s.references.addResponseRef(refPref, op.Responses.Default)
|
||||
}
|
||||
for k, v := range op.Responses.Default.Headers {
|
||||
hRefPref := slashpath.Join(refPref, "headers", k)
|
||||
s.analyzeItems("items", v.Items, hRefPref, "header")
|
||||
if v.Pattern != "" {
|
||||
s.patterns.addHeaderPattern(hRefPref, v.Pattern)
|
||||
}
|
||||
}
|
||||
if op.Responses.Default.Schema != nil {
|
||||
s.analyzeSchema("schema", op.Responses.Default.Schema, refPref)
|
||||
}
|
||||
|
||||
if res.Schema != nil {
|
||||
s.analyzeSchema("schema", res.Schema, refPref)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Spec) analyzeResponse(prefix string, k int, res spec.Response) {
|
||||
refPref := slashpath.Join(prefix, "responses", strconv.Itoa(k))
|
||||
if res.Ref.String() != "" {
|
||||
s.references.addResponseRef(refPref, &res) //#nosec
|
||||
}
|
||||
|
||||
for k, v := range res.Headers {
|
||||
hRefPref := slashpath.Join(refPref, "headers", k)
|
||||
s.analyzeItems("items", v.Items, hRefPref, "header")
|
||||
if v.Pattern != "" {
|
||||
s.patterns.addHeaderPattern(hRefPref, v.Pattern)
|
||||
}
|
||||
for k, res := range op.Responses.StatusCodeResponses {
|
||||
refPref := slashpath.Join(prefix, "responses", strconv.Itoa(k))
|
||||
if res.Ref.String() != "" {
|
||||
s.references.addResponseRef(refPref, &res)
|
||||
}
|
||||
for k, v := range res.Headers {
|
||||
hRefPref := slashpath.Join(refPref, "headers", k)
|
||||
s.analyzeItems("items", v.Items, hRefPref, "header")
|
||||
if v.Pattern != "" {
|
||||
s.patterns.addHeaderPattern(hRefPref, v.Pattern)
|
||||
}
|
||||
if len(v.Enum) > 0 {
|
||||
s.enums.addHeaderEnum(hRefPref, v.Enum)
|
||||
}
|
||||
}
|
||||
if res.Schema != nil {
|
||||
s.analyzeSchema("schema", res.Schema, refPref)
|
||||
}
|
||||
|
||||
if len(v.Enum) > 0 {
|
||||
s.enums.addHeaderEnum(hRefPref, v.Enum)
|
||||
}
|
||||
}
|
||||
|
||||
if res.Schema != nil {
|
||||
s.analyzeSchema("schema", res.Schema, refPref)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Spec) analyzeSchema(name string, schema *spec.Schema, prefix string) {
|
||||
@@ -401,9 +430,11 @@ func (s *Spec) analyzeSchema(name string, schema *spec.Schema, prefix string) {
|
||||
if schema.Ref.String() != "" {
|
||||
s.references.addSchemaRef(refURI, schRef)
|
||||
}
|
||||
|
||||
if schema.Pattern != "" {
|
||||
s.patterns.addSchemaPattern(refURI, schema.Pattern)
|
||||
}
|
||||
|
||||
if len(schema.Enum) > 0 {
|
||||
s.enums.addSchemaEnum(refURI, schema.Enum)
|
||||
}
|
||||
@@ -412,52 +443,63 @@ func (s *Spec) analyzeSchema(name string, schema *spec.Schema, prefix string) {
|
||||
v := v
|
||||
s.analyzeSchema(k, &v, slashpath.Join(refURI, "definitions"))
|
||||
}
|
||||
|
||||
for k, v := range schema.Properties {
|
||||
v := v
|
||||
s.analyzeSchema(k, &v, slashpath.Join(refURI, "properties"))
|
||||
}
|
||||
|
||||
for k, v := range schema.PatternProperties {
|
||||
v := v
|
||||
// NOTE: swagger 2.0 does not support PatternProperties.
|
||||
// However it is possible to analyze this in a schema
|
||||
s.analyzeSchema(k, &v, slashpath.Join(refURI, "patternProperties"))
|
||||
}
|
||||
|
||||
for i := range schema.AllOf {
|
||||
v := &schema.AllOf[i]
|
||||
s.analyzeSchema(strconv.Itoa(i), v, slashpath.Join(refURI, "allOf"))
|
||||
}
|
||||
|
||||
if len(schema.AllOf) > 0 {
|
||||
s.allOfs["#"+refURI] = schRef
|
||||
}
|
||||
|
||||
for i := range schema.AnyOf {
|
||||
v := &schema.AnyOf[i]
|
||||
// NOTE: swagger 2.0 does not support anyOf constructs.
|
||||
// However it is possible to analyze this in a schema
|
||||
s.analyzeSchema(strconv.Itoa(i), v, slashpath.Join(refURI, "anyOf"))
|
||||
}
|
||||
|
||||
for i := range schema.OneOf {
|
||||
v := &schema.OneOf[i]
|
||||
// NOTE: swagger 2.0 does not support oneOf constructs.
|
||||
// However it is possible to analyze this in a schema
|
||||
s.analyzeSchema(strconv.Itoa(i), v, slashpath.Join(refURI, "oneOf"))
|
||||
}
|
||||
|
||||
if schema.Not != nil {
|
||||
// NOTE: swagger 2.0 does not support "not" constructs.
|
||||
// However it is possible to analyze this in a schema
|
||||
s.analyzeSchema("not", schema.Not, refURI)
|
||||
}
|
||||
|
||||
if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil {
|
||||
s.analyzeSchema("additionalProperties", schema.AdditionalProperties.Schema, refURI)
|
||||
}
|
||||
|
||||
if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil {
|
||||
// NOTE: swagger 2.0 does not support AdditionalItems.
|
||||
// However it is possible to analyze this in a schema
|
||||
s.analyzeSchema("additionalItems", schema.AdditionalItems.Schema, refURI)
|
||||
}
|
||||
|
||||
if schema.Items != nil {
|
||||
if schema.Items.Schema != nil {
|
||||
s.analyzeSchema("items", schema.Items.Schema, refURI)
|
||||
}
|
||||
|
||||
for i := range schema.Items.Schemas {
|
||||
sch := &schema.Items.Schemas[i]
|
||||
s.analyzeSchema(strconv.Itoa(i), sch, slashpath.Join(refURI, "items"))
|
||||
@@ -487,8 +529,10 @@ func (s *Spec) SecurityRequirementsFor(operation *spec.Operation) [][]SecurityRe
|
||||
if len(scheme) == 0 {
|
||||
// append a zero object for anonymous
|
||||
result = append(result, []SecurityRequirement{{}})
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
var reqs []SecurityRequirement
|
||||
for k, v := range scheme {
|
||||
if v == nil {
|
||||
@@ -496,8 +540,10 @@ func (s *Spec) SecurityRequirementsFor(operation *spec.Operation) [][]SecurityRe
|
||||
}
|
||||
reqs = append(reqs, SecurityRequirement{Name: k, Scopes: v})
|
||||
}
|
||||
|
||||
result = append(result, reqs)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -512,6 +558,7 @@ func (s *Spec) SecurityDefinitionsForRequirements(requirements []SecurityRequire
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -529,10 +576,12 @@ func (s *Spec) SecurityDefinitionsFor(operation *spec.Operation) map[string]spec
|
||||
// optional requirement
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := result[v.Name]; ok {
|
||||
// duplicate requirement
|
||||
continue
|
||||
}
|
||||
|
||||
if definition, ok := s.spec.SecurityDefinitions[v.Name]; ok {
|
||||
if definition != nil {
|
||||
result[v.Name] = *definition
|
||||
@@ -540,17 +589,18 @@ func (s *Spec) SecurityDefinitionsFor(operation *spec.Operation) map[string]spec
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// ConsumesFor gets the mediatypes for the operation
|
||||
func (s *Spec) ConsumesFor(operation *spec.Operation) []string {
|
||||
|
||||
if len(operation.Consumes) == 0 {
|
||||
cons := make(map[string]struct{}, len(s.spec.Consumes))
|
||||
for _, k := range s.spec.Consumes {
|
||||
cons[k] = struct{}{}
|
||||
}
|
||||
|
||||
return s.structMapKeys(cons)
|
||||
}
|
||||
|
||||
@@ -558,6 +608,7 @@ func (s *Spec) ConsumesFor(operation *spec.Operation) []string {
|
||||
for _, c := range operation.Consumes {
|
||||
cons[c] = struct{}{}
|
||||
}
|
||||
|
||||
return s.structMapKeys(cons)
|
||||
}
|
||||
|
||||
@@ -568,6 +619,7 @@ func (s *Spec) ProducesFor(operation *spec.Operation) []string {
|
||||
for _, k := range s.spec.Produces {
|
||||
prod[k] = struct{}{}
|
||||
}
|
||||
|
||||
return s.structMapKeys(prod)
|
||||
}
|
||||
|
||||
@@ -575,6 +627,7 @@ func (s *Spec) ProducesFor(operation *spec.Operation) []string {
|
||||
for _, c := range operation.Produces {
|
||||
prod[c] = struct{}{}
|
||||
}
|
||||
|
||||
return s.structMapKeys(prod)
|
||||
}
|
||||
|
||||
@@ -587,6 +640,7 @@ func fieldNameFromParam(param *spec.Parameter) string {
|
||||
if nm, ok := param.Extensions.GetString("go-name"); ok {
|
||||
return nm
|
||||
}
|
||||
|
||||
return swag.ToGoName(param.Name)
|
||||
}
|
||||
|
||||
@@ -606,31 +660,38 @@ type ErrorOnParamFunc func(spec.Parameter, error) bool
|
||||
func (s *Spec) paramsAsMap(parameters []spec.Parameter, res map[string]spec.Parameter, callmeOnError ErrorOnParamFunc) {
|
||||
for _, param := range parameters {
|
||||
pr := param
|
||||
if pr.Ref.String() != "" {
|
||||
obj, _, err := pr.Ref.GetPointer().Get(s.spec)
|
||||
if err != nil {
|
||||
if callmeOnError != nil {
|
||||
if callmeOnError(param, fmt.Errorf("invalid reference: %q", pr.Ref.String())) {
|
||||
continue
|
||||
}
|
||||
break
|
||||
} else {
|
||||
panic(fmt.Sprintf("invalid reference: %q", pr.Ref.String()))
|
||||
}
|
||||
}
|
||||
if objAsParam, ok := obj.(spec.Parameter); ok {
|
||||
pr = objAsParam
|
||||
} else {
|
||||
if callmeOnError != nil {
|
||||
if callmeOnError(param, fmt.Errorf("resolved reference is not a parameter: %q", pr.Ref.String())) {
|
||||
continue
|
||||
}
|
||||
break
|
||||
} else {
|
||||
panic(fmt.Sprintf("resolved reference is not a parameter: %q", pr.Ref.String()))
|
||||
}
|
||||
if pr.Ref.String() == "" {
|
||||
res[mapKeyFromParam(&pr)] = pr
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// resolve $ref
|
||||
if callmeOnError == nil {
|
||||
callmeOnError = func(_ spec.Parameter, err error) bool {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
obj, _, err := pr.Ref.GetPointer().Get(s.spec)
|
||||
if err != nil {
|
||||
if callmeOnError(param, fmt.Errorf("invalid reference: %q", pr.Ref.String())) {
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
objAsParam, ok := obj.(spec.Parameter)
|
||||
if !ok {
|
||||
if callmeOnError(param, fmt.Errorf("resolved reference is not a parameter: %q", pr.Ref.String())) {
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
pr = objAsParam
|
||||
res[mapKeyFromParam(&pr)] = pr
|
||||
}
|
||||
}
|
||||
@@ -661,31 +722,34 @@ func (s *Spec) SafeParametersFor(operationID string, callmeOnError ErrorOnParamF
|
||||
for _, v := range bag {
|
||||
res = append(res, v)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
for _, pi := range s.spec.Paths.Paths {
|
||||
if pi.Get != nil && pi.Get.ID == operationID {
|
||||
return gatherParams(&pi, pi.Get)
|
||||
return gatherParams(&pi, pi.Get) //#nosec
|
||||
}
|
||||
if pi.Head != nil && pi.Head.ID == operationID {
|
||||
return gatherParams(&pi, pi.Head)
|
||||
return gatherParams(&pi, pi.Head) //#nosec
|
||||
}
|
||||
if pi.Options != nil && pi.Options.ID == operationID {
|
||||
return gatherParams(&pi, pi.Options)
|
||||
return gatherParams(&pi, pi.Options) //#nosec
|
||||
}
|
||||
if pi.Post != nil && pi.Post.ID == operationID {
|
||||
return gatherParams(&pi, pi.Post)
|
||||
return gatherParams(&pi, pi.Post) //#nosec
|
||||
}
|
||||
if pi.Patch != nil && pi.Patch.ID == operationID {
|
||||
return gatherParams(&pi, pi.Patch)
|
||||
return gatherParams(&pi, pi.Patch) //#nosec
|
||||
}
|
||||
if pi.Put != nil && pi.Put.ID == operationID {
|
||||
return gatherParams(&pi, pi.Put)
|
||||
return gatherParams(&pi, pi.Put) //#nosec
|
||||
}
|
||||
if pi.Delete != nil && pi.Delete.ID == operationID {
|
||||
return gatherParams(&pi, pi.Delete)
|
||||
return gatherParams(&pi, pi.Delete) //#nosec
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -713,6 +777,7 @@ func (s *Spec) SafeParamsFor(method, path string, callmeOnError ErrorOnParamFunc
|
||||
s.paramsAsMap(pi.Parameters, res, callmeOnError)
|
||||
s.paramsAsMap(s.operations[strings.ToUpper(method)][path].Parameters, res, callmeOnError)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -725,6 +790,7 @@ func (s *Spec) OperationForName(operationID string) (string, string, *spec.Opera
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "", "", nil, false
|
||||
}
|
||||
|
||||
@@ -732,8 +798,10 @@ func (s *Spec) OperationForName(operationID string) (string, string, *spec.Opera
|
||||
func (s *Spec) OperationFor(method, path string) (*spec.Operation, bool) {
|
||||
if mp, ok := s.operations[strings.ToUpper(method)]; ok {
|
||||
op, fn := mp[path]
|
||||
|
||||
return op, fn
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
@@ -751,6 +819,7 @@ func (s *Spec) structMapKeys(mp map[string]struct{}) []string {
|
||||
for k := range mp {
|
||||
result = append(result, k)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -759,6 +828,7 @@ func (s *Spec) AllPaths() map[string]spec.PathItem {
|
||||
if s.spec == nil || s.spec.Paths == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return s.spec.Paths.Paths
|
||||
}
|
||||
|
||||
@@ -767,6 +837,7 @@ func (s *Spec) OperationIDs() []string {
|
||||
if len(s.operations) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := make([]string, 0, len(s.operations))
|
||||
for method, v := range s.operations {
|
||||
for p, o := range v {
|
||||
@@ -777,6 +848,7 @@ func (s *Spec) OperationIDs() []string {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -785,12 +857,14 @@ func (s *Spec) OperationMethodPaths() []string {
|
||||
if len(s.operations) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := make([]string, 0, len(s.operations))
|
||||
for method, v := range s.operations {
|
||||
for p := range v {
|
||||
result = append(result, fmt.Sprintf("%s %s", strings.ToUpper(method), p))
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -823,6 +897,7 @@ func (s *Spec) SchemasWithAllOf() (result []SchemaRef) {
|
||||
for _, v := range s.allOfs {
|
||||
result = append(result, v)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -831,6 +906,7 @@ func (s *Spec) AllDefinitions() (result []SchemaRef) {
|
||||
for _, v := range s.allSchemas {
|
||||
result = append(result, v)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -839,6 +915,7 @@ func (s *Spec) AllDefinitionReferences() (result []string) {
|
||||
for _, v := range s.references.schemas {
|
||||
result = append(result, v.String())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -847,6 +924,7 @@ func (s *Spec) AllParameterReferences() (result []string) {
|
||||
for _, v := range s.references.parameters {
|
||||
result = append(result, v.String())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -855,6 +933,7 @@ func (s *Spec) AllResponseReferences() (result []string) {
|
||||
for _, v := range s.references.responses {
|
||||
result = append(result, v.String())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -863,6 +942,7 @@ func (s *Spec) AllPathItemReferences() (result []string) {
|
||||
for _, v := range s.references.pathItems {
|
||||
result = append(result, v.String())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -874,6 +954,7 @@ func (s *Spec) AllItemsReferences() (result []string) {
|
||||
for _, v := range s.references.items {
|
||||
result = append(result, v.String())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -882,6 +963,7 @@ func (s *Spec) AllReferences() (result []string) {
|
||||
for _, v := range s.references.allRefs {
|
||||
result = append(result, v.String())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -893,11 +975,13 @@ func (s *Spec) AllRefs() (result []spec.Ref) {
|
||||
if a == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := set[a]; !ok {
|
||||
set[a] = struct{}{}
|
||||
result = append(result, v)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -906,6 +990,7 @@ func cloneStringMap(source map[string]string) map[string]string {
|
||||
for k, v := range source {
|
||||
res[k] = v
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -914,6 +999,7 @@ func cloneEnumMap(source map[string][]interface{}) map[string][]interface{} {
|
||||
for k, v := range source {
|
||||
res[k] = v
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
|
||||
5
vendor/github.com/go-openapi/analysis/appveyor.yml
generated
vendored
5
vendor/github.com/go-openapi/analysis/appveyor.yml
generated
vendored
@@ -14,12 +14,11 @@ build: off
|
||||
environment:
|
||||
GOPATH: c:\gopath
|
||||
|
||||
stack: go 1.12
|
||||
stack: go 1.16
|
||||
|
||||
test_script:
|
||||
- go test -v -timeout 20m ./...
|
||||
#artifacts:
|
||||
# - path: '%GOPATH%\bin\*.exe'
|
||||
|
||||
deploy: off
|
||||
|
||||
notifications:
|
||||
|
||||
30
vendor/github.com/go-openapi/analysis/debug.go
generated
vendored
30
vendor/github.com/go-openapi/analysis/debug.go
generated
vendored
@@ -15,33 +15,9 @@
|
||||
package analysis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"github.com/go-openapi/analysis/internal/debug"
|
||||
)
|
||||
|
||||
var (
|
||||
// Debug is true when the SWAGGER_DEBUG env var is not empty.
|
||||
// It enables a more verbose logging of the spec analyzer.
|
||||
Debug = os.Getenv("SWAGGER_DEBUG") != ""
|
||||
// analysisLogger is a debug logger for this package
|
||||
analysisLogger *log.Logger
|
||||
)
|
||||
|
||||
func init() {
|
||||
debugOptions()
|
||||
}
|
||||
|
||||
func debugOptions() {
|
||||
analysisLogger = log.New(os.Stdout, "analysis:", log.LstdFlags)
|
||||
}
|
||||
|
||||
func debugLog(msg string, args ...interface{}) {
|
||||
// A private, trivial trace logger, based on go-openapi/spec/expander.go:debugLog()
|
||||
if Debug {
|
||||
_, file1, pos1, _ := runtime.Caller(1)
|
||||
analysisLogger.Printf("%s:%d: %s", filepath.Base(file1), pos1, fmt.Sprintf(msg, args...))
|
||||
}
|
||||
}
|
||||
var debugLog = debug.GetLogger("analysis", os.Getenv("SWAGGER_DEBUG") != "")
|
||||
|
||||
57
vendor/github.com/go-openapi/analysis/fixer.go
generated
vendored
57
vendor/github.com/go-openapi/analysis/fixer.go
generated
vendored
@@ -24,35 +24,38 @@ import "github.com/go-openapi/spec"
|
||||
// due to zero values being omitted upon re-serializing (omitempty) we
|
||||
// lose them unless we stick some chars in there.
|
||||
func FixEmptyResponseDescriptions(s *spec.Swagger) {
|
||||
if s.Paths != nil {
|
||||
for _, v := range s.Paths.Paths {
|
||||
if v.Get != nil {
|
||||
FixEmptyDescs(v.Get.Responses)
|
||||
}
|
||||
if v.Put != nil {
|
||||
FixEmptyDescs(v.Put.Responses)
|
||||
}
|
||||
if v.Post != nil {
|
||||
FixEmptyDescs(v.Post.Responses)
|
||||
}
|
||||
if v.Delete != nil {
|
||||
FixEmptyDescs(v.Delete.Responses)
|
||||
}
|
||||
if v.Options != nil {
|
||||
FixEmptyDescs(v.Options.Responses)
|
||||
}
|
||||
if v.Head != nil {
|
||||
FixEmptyDescs(v.Head.Responses)
|
||||
}
|
||||
if v.Patch != nil {
|
||||
FixEmptyDescs(v.Patch.Responses)
|
||||
}
|
||||
}
|
||||
}
|
||||
for k, v := range s.Responses {
|
||||
FixEmptyDesc(&v)
|
||||
FixEmptyDesc(&v) //#nosec
|
||||
s.Responses[k] = v
|
||||
}
|
||||
|
||||
if s.Paths == nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, v := range s.Paths.Paths {
|
||||
if v.Get != nil {
|
||||
FixEmptyDescs(v.Get.Responses)
|
||||
}
|
||||
if v.Put != nil {
|
||||
FixEmptyDescs(v.Put.Responses)
|
||||
}
|
||||
if v.Post != nil {
|
||||
FixEmptyDescs(v.Post.Responses)
|
||||
}
|
||||
if v.Delete != nil {
|
||||
FixEmptyDescs(v.Delete.Responses)
|
||||
}
|
||||
if v.Options != nil {
|
||||
FixEmptyDescs(v.Options.Responses)
|
||||
}
|
||||
if v.Head != nil {
|
||||
FixEmptyDescs(v.Head.Responses)
|
||||
}
|
||||
if v.Patch != nil {
|
||||
FixEmptyDescs(v.Patch.Responses)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FixEmptyDescs adds "(empty)" as the description for any Response in
|
||||
@@ -60,7 +63,7 @@ func FixEmptyResponseDescriptions(s *spec.Swagger) {
|
||||
func FixEmptyDescs(rs *spec.Responses) {
|
||||
FixEmptyDesc(rs.Default)
|
||||
for k, v := range rs.StatusCodeResponses {
|
||||
FixEmptyDesc(&v)
|
||||
FixEmptyDesc(&v) //#nosec
|
||||
rs.StatusCodeResponses[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
1849
vendor/github.com/go-openapi/analysis/flatten.go
generated
vendored
1849
vendor/github.com/go-openapi/analysis/flatten.go
generated
vendored
File diff suppressed because it is too large
Load Diff
293
vendor/github.com/go-openapi/analysis/flatten_name.go
generated
vendored
Normal file
293
vendor/github.com/go-openapi/analysis/flatten_name.go
generated
vendored
Normal file
@@ -0,0 +1,293 @@
|
||||
package analysis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/analysis/internal/flatten/operations"
|
||||
"github.com/go-openapi/analysis/internal/flatten/replace"
|
||||
"github.com/go-openapi/analysis/internal/flatten/schutils"
|
||||
"github.com/go-openapi/analysis/internal/flatten/sortref"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// InlineSchemaNamer finds a new name for an inlined type
|
||||
type InlineSchemaNamer struct {
|
||||
Spec *spec.Swagger
|
||||
Operations map[string]operations.OpRef
|
||||
flattenContext *context
|
||||
opts *FlattenOpts
|
||||
}
|
||||
|
||||
// Name yields a new name for the inline schema
|
||||
func (isn *InlineSchemaNamer) Name(key string, schema *spec.Schema, aschema *AnalyzedSchema) error {
|
||||
debugLog("naming inlined schema at %s", key)
|
||||
|
||||
parts := sortref.KeyParts(key)
|
||||
for _, name := range namesFromKey(parts, aschema, isn.Operations) {
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// create unique name
|
||||
newName, isOAIGen := uniqifyName(isn.Spec.Definitions, swag.ToJSONName(name))
|
||||
|
||||
// clone schema
|
||||
sch := schutils.Clone(schema)
|
||||
|
||||
// replace values on schema
|
||||
if err := replace.RewriteSchemaToRef(isn.Spec, key,
|
||||
spec.MustCreateRef(path.Join(definitionsPath, newName))); err != nil {
|
||||
return fmt.Errorf("error while creating definition %q from inline schema: %w", newName, err)
|
||||
}
|
||||
|
||||
// rewrite any dependent $ref pointing to this place,
|
||||
// when not already pointing to a top-level definition.
|
||||
//
|
||||
// NOTE: this is important if such referers use arbitrary JSON pointers.
|
||||
an := New(isn.Spec)
|
||||
for k, v := range an.references.allRefs {
|
||||
r, erd := replace.DeepestRef(isn.opts.Swagger(), isn.opts.ExpandOpts(false), v)
|
||||
if erd != nil {
|
||||
return fmt.Errorf("at %s, %w", k, erd)
|
||||
}
|
||||
|
||||
if isn.opts.flattenContext != nil {
|
||||
isn.opts.flattenContext.warnings = append(isn.opts.flattenContext.warnings, r.Warnings...)
|
||||
}
|
||||
|
||||
if r.Ref.String() != key && (r.Ref.String() != path.Join(definitionsPath, newName) || path.Dir(v.String()) == definitionsPath) {
|
||||
continue
|
||||
}
|
||||
|
||||
debugLog("found a $ref to a rewritten schema: %s points to %s", k, v.String())
|
||||
|
||||
// rewrite $ref to the new target
|
||||
if err := replace.UpdateRef(isn.Spec, k,
|
||||
spec.MustCreateRef(path.Join(definitionsPath, newName))); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: this extension is currently not used by go-swagger (provided for information only)
|
||||
sch.AddExtension("x-go-gen-location", GenLocation(parts))
|
||||
|
||||
// save cloned schema to definitions
|
||||
schutils.Save(isn.Spec, newName, sch)
|
||||
|
||||
// keep track of created refs
|
||||
if isn.flattenContext == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
debugLog("track created ref: key=%s, newName=%s, isOAIGen=%t", key, newName, isOAIGen)
|
||||
resolved := false
|
||||
|
||||
if _, ok := isn.flattenContext.newRefs[key]; ok {
|
||||
resolved = isn.flattenContext.newRefs[key].resolved
|
||||
}
|
||||
|
||||
isn.flattenContext.newRefs[key] = &newRef{
|
||||
key: key,
|
||||
newName: newName,
|
||||
path: path.Join(definitionsPath, newName),
|
||||
isOAIGen: isOAIGen,
|
||||
resolved: resolved,
|
||||
schema: sch,
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// uniqifyName yields a unique name for a definition
|
||||
func uniqifyName(definitions spec.Definitions, name string) (string, bool) {
|
||||
isOAIGen := false
|
||||
if name == "" {
|
||||
name = "oaiGen"
|
||||
isOAIGen = true
|
||||
}
|
||||
|
||||
if len(definitions) == 0 {
|
||||
return name, isOAIGen
|
||||
}
|
||||
|
||||
unq := true
|
||||
for k := range definitions {
|
||||
if strings.EqualFold(k, name) {
|
||||
unq = false
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if unq {
|
||||
return name, isOAIGen
|
||||
}
|
||||
|
||||
name += "OAIGen"
|
||||
isOAIGen = true
|
||||
var idx int
|
||||
unique := name
|
||||
_, known := definitions[unique]
|
||||
|
||||
for known {
|
||||
idx++
|
||||
unique = fmt.Sprintf("%s%d", name, idx)
|
||||
_, known = definitions[unique]
|
||||
}
|
||||
|
||||
return unique, isOAIGen
|
||||
}
|
||||
|
||||
func namesFromKey(parts sortref.SplitKey, aschema *AnalyzedSchema, operations map[string]operations.OpRef) []string {
|
||||
var (
|
||||
baseNames [][]string
|
||||
startIndex int
|
||||
)
|
||||
|
||||
if parts.IsOperation() {
|
||||
baseNames, startIndex = namesForOperation(parts, operations)
|
||||
}
|
||||
|
||||
// definitions
|
||||
if parts.IsDefinition() {
|
||||
baseNames, startIndex = namesForDefinition(parts)
|
||||
}
|
||||
|
||||
result := make([]string, 0, len(baseNames))
|
||||
for _, segments := range baseNames {
|
||||
nm := parts.BuildName(segments, startIndex, partAdder(aschema))
|
||||
if nm == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
result = append(result, nm)
|
||||
}
|
||||
sort.Strings(result)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func namesForParam(parts sortref.SplitKey, operations map[string]operations.OpRef) ([][]string, int) {
|
||||
var (
|
||||
baseNames [][]string
|
||||
startIndex int
|
||||
)
|
||||
|
||||
piref := parts.PathItemRef()
|
||||
if piref.String() != "" && parts.IsOperationParam() {
|
||||
if op, ok := operations[piref.String()]; ok {
|
||||
startIndex = 5
|
||||
baseNames = append(baseNames, []string{op.ID, "params", "body"})
|
||||
}
|
||||
} else if parts.IsSharedOperationParam() {
|
||||
pref := parts.PathRef()
|
||||
for k, v := range operations {
|
||||
if strings.HasPrefix(k, pref.String()) {
|
||||
startIndex = 4
|
||||
baseNames = append(baseNames, []string{v.ID, "params", "body"})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return baseNames, startIndex
|
||||
}
|
||||
|
||||
func namesForOperation(parts sortref.SplitKey, operations map[string]operations.OpRef) ([][]string, int) {
|
||||
var (
|
||||
baseNames [][]string
|
||||
startIndex int
|
||||
)
|
||||
|
||||
// params
|
||||
if parts.IsOperationParam() || parts.IsSharedOperationParam() {
|
||||
baseNames, startIndex = namesForParam(parts, operations)
|
||||
}
|
||||
|
||||
// responses
|
||||
if parts.IsOperationResponse() {
|
||||
piref := parts.PathItemRef()
|
||||
if piref.String() != "" {
|
||||
if op, ok := operations[piref.String()]; ok {
|
||||
startIndex = 6
|
||||
baseNames = append(baseNames, []string{op.ID, parts.ResponseName(), "body"})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return baseNames, startIndex
|
||||
}
|
||||
|
||||
func namesForDefinition(parts sortref.SplitKey) ([][]string, int) {
|
||||
nm := parts.DefinitionName()
|
||||
if nm != "" {
|
||||
return [][]string{{parts.DefinitionName()}}, 2
|
||||
}
|
||||
|
||||
return [][]string{}, 0
|
||||
}
|
||||
|
||||
// partAdder knows how to interpret a schema when it comes to build a name from parts
|
||||
func partAdder(aschema *AnalyzedSchema) sortref.PartAdder {
|
||||
return func(part string) []string {
|
||||
segments := make([]string, 0, 2)
|
||||
|
||||
if part == "items" || part == "additionalItems" {
|
||||
if aschema.IsTuple || aschema.IsTupleWithExtra {
|
||||
segments = append(segments, "tuple")
|
||||
} else {
|
||||
segments = append(segments, "items")
|
||||
}
|
||||
|
||||
if part == "additionalItems" {
|
||||
segments = append(segments, part)
|
||||
}
|
||||
|
||||
return segments
|
||||
}
|
||||
|
||||
segments = append(segments, part)
|
||||
|
||||
return segments
|
||||
}
|
||||
}
|
||||
|
||||
func nameFromRef(ref spec.Ref) string {
|
||||
u := ref.GetURL()
|
||||
if u.Fragment != "" {
|
||||
return swag.ToJSONName(path.Base(u.Fragment))
|
||||
}
|
||||
|
||||
if u.Path != "" {
|
||||
bn := path.Base(u.Path)
|
||||
if bn != "" && bn != "/" {
|
||||
ext := path.Ext(bn)
|
||||
if ext != "" {
|
||||
return swag.ToJSONName(bn[:len(bn)-len(ext)])
|
||||
}
|
||||
|
||||
return swag.ToJSONName(bn)
|
||||
}
|
||||
}
|
||||
|
||||
return swag.ToJSONName(strings.ReplaceAll(u.Host, ".", " "))
|
||||
}
|
||||
|
||||
// GenLocation indicates from which section of the specification (models or operations) a definition has been created.
|
||||
//
|
||||
// This is reflected in the output spec with a "x-go-gen-location" extension. At the moment, this is is provided
|
||||
// for information only.
|
||||
func GenLocation(parts sortref.SplitKey) string {
|
||||
switch {
|
||||
case parts.IsOperation():
|
||||
return "operations"
|
||||
case parts.IsDefinition():
|
||||
return "models"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
78
vendor/github.com/go-openapi/analysis/flatten_options.go
generated
vendored
Normal file
78
vendor/github.com/go-openapi/analysis/flatten_options.go
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
package analysis
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
)
|
||||
|
||||
// FlattenOpts configuration for flattening a swagger specification.
|
||||
//
|
||||
// The BasePath parameter is used to locate remote relative $ref found in the specification.
|
||||
// This path is a file: it points to the location of the root document and may be either a local
|
||||
// file path or a URL.
|
||||
//
|
||||
// If none specified, relative references (e.g. "$ref": "folder/schema.yaml#/definitions/...")
|
||||
// found in the spec are searched from the current working directory.
|
||||
type FlattenOpts struct {
|
||||
Spec *Spec // The analyzed spec to work with
|
||||
flattenContext *context // Internal context to track flattening activity
|
||||
|
||||
BasePath string // The location of the root document for this spec to resolve relative $ref
|
||||
|
||||
// Flattening options
|
||||
Expand bool // When true, skip flattening the spec and expand it instead (if Minimal is false)
|
||||
Minimal bool // When true, do not decompose complex structures such as allOf
|
||||
Verbose bool // enable some reporting on possible name conflicts detected
|
||||
RemoveUnused bool // When true, remove unused parameters, responses and definitions after expansion/flattening
|
||||
ContinueOnError bool // Continue when spec expansion issues are found
|
||||
|
||||
/* Extra keys */
|
||||
_ struct{} // require keys
|
||||
}
|
||||
|
||||
// ExpandOpts creates a spec.ExpandOptions to configure expanding a specification document.
|
||||
func (f *FlattenOpts) ExpandOpts(skipSchemas bool) *spec.ExpandOptions {
|
||||
return &spec.ExpandOptions{
|
||||
RelativeBase: f.BasePath,
|
||||
SkipSchemas: skipSchemas,
|
||||
ContinueOnError: f.ContinueOnError,
|
||||
}
|
||||
}
|
||||
|
||||
// Swagger gets the swagger specification for this flatten operation
|
||||
func (f *FlattenOpts) Swagger() *spec.Swagger {
|
||||
return f.Spec.spec
|
||||
}
|
||||
|
||||
// croak logs notifications and warnings about valid, but possibly unwanted constructs resulting
|
||||
// from flattening a spec
|
||||
func (f *FlattenOpts) croak() {
|
||||
if !f.Verbose {
|
||||
return
|
||||
}
|
||||
|
||||
reported := make(map[string]bool, len(f.flattenContext.newRefs))
|
||||
for _, v := range f.Spec.references.allRefs {
|
||||
// warns about duplicate handling
|
||||
for _, r := range f.flattenContext.newRefs {
|
||||
if r.isOAIGen && r.path == v.String() {
|
||||
reported[r.newName] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for k := range reported {
|
||||
log.Printf("warning: duplicate flattened definition name resolved as %s", k)
|
||||
}
|
||||
|
||||
// warns about possible type mismatches
|
||||
uniqueMsg := make(map[string]bool)
|
||||
for _, msg := range f.flattenContext.warnings {
|
||||
if _, ok := uniqueMsg[msg]; ok {
|
||||
continue
|
||||
}
|
||||
log.Printf("warning: %s", msg)
|
||||
uniqueMsg[msg] = true
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
// +build go1.8
|
||||
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,16 +12,30 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package internal
|
||||
package debug
|
||||
|
||||
import "net/url"
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// PathUnescape provides url.PathUnescape(), with seamless
|
||||
// go version support for pre-go1.8
|
||||
//
|
||||
// TODO: this function is currently defined in go-openapi/swag,
|
||||
// but unexported. We might chose to export it, or simple phase
|
||||
// out pre-go1.8 support.
|
||||
func PathUnescape(path string) (string, error) {
|
||||
return url.PathUnescape(path)
|
||||
var (
|
||||
output = os.Stdout
|
||||
)
|
||||
|
||||
// GetLogger provides a prefix debug logger
|
||||
func GetLogger(prefix string, debug bool) func(string, ...interface{}) {
|
||||
if debug {
|
||||
logger := log.New(output, fmt.Sprintf("%s:", prefix), log.LstdFlags)
|
||||
|
||||
return func(msg string, args ...interface{}) {
|
||||
_, file1, pos1, _ := runtime.Caller(1)
|
||||
logger.Printf("%s:%d: %s", filepath.Base(file1), pos1, fmt.Sprintf(msg, args...))
|
||||
}
|
||||
}
|
||||
|
||||
return func(msg string, args ...interface{}) {}
|
||||
}
|
||||
87
vendor/github.com/go-openapi/analysis/internal/flatten/normalize/normalize.go
generated
vendored
Normal file
87
vendor/github.com/go-openapi/analysis/internal/flatten/normalize/normalize.go
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
package normalize
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
)
|
||||
|
||||
// RebaseRef rebases a remote ref relative to a base ref.
|
||||
//
|
||||
// NOTE: does not support JSONschema ID for $ref (we assume we are working with swagger specs here).
|
||||
//
|
||||
// NOTE(windows):
|
||||
// * refs are assumed to have been normalized with drive letter lower cased (from go-openapi/spec)
|
||||
// * "/ in paths may appear as escape sequences
|
||||
func RebaseRef(baseRef string, ref string) string {
|
||||
baseRef, _ = url.PathUnescape(baseRef)
|
||||
ref, _ = url.PathUnescape(ref)
|
||||
|
||||
if baseRef == "" || baseRef == "." || strings.HasPrefix(baseRef, "#") {
|
||||
return ref
|
||||
}
|
||||
|
||||
parts := strings.Split(ref, "#")
|
||||
|
||||
baseParts := strings.Split(baseRef, "#")
|
||||
baseURL, _ := url.Parse(baseParts[0])
|
||||
if strings.HasPrefix(ref, "#") {
|
||||
if baseURL.Host == "" {
|
||||
return strings.Join([]string{baseParts[0], parts[1]}, "#")
|
||||
}
|
||||
|
||||
return strings.Join([]string{baseParts[0], parts[1]}, "#")
|
||||
}
|
||||
|
||||
refURL, _ := url.Parse(parts[0])
|
||||
if refURL.Host != "" || filepath.IsAbs(parts[0]) {
|
||||
// not rebasing an absolute path
|
||||
return ref
|
||||
}
|
||||
|
||||
// there is a relative path
|
||||
var basePath string
|
||||
if baseURL.Host != "" {
|
||||
// when there is a host, standard URI rules apply (with "/")
|
||||
baseURL.Path = path.Dir(baseURL.Path)
|
||||
baseURL.Path = path.Join(baseURL.Path, "/"+parts[0])
|
||||
|
||||
return baseURL.String()
|
||||
}
|
||||
|
||||
// this is a local relative path
|
||||
// basePart[0] and parts[0] are local filesystem directories/files
|
||||
basePath = filepath.Dir(baseParts[0])
|
||||
relPath := filepath.Join(basePath, string(filepath.Separator)+parts[0])
|
||||
if len(parts) > 1 {
|
||||
return strings.Join([]string{relPath, parts[1]}, "#")
|
||||
}
|
||||
|
||||
return relPath
|
||||
}
|
||||
|
||||
// Path renders absolute path on remote file refs
|
||||
//
|
||||
// NOTE(windows):
|
||||
// * refs are assumed to have been normalized with drive letter lower cased (from go-openapi/spec)
|
||||
// * "/ in paths may appear as escape sequences
|
||||
func Path(ref spec.Ref, basePath string) string {
|
||||
uri, _ := url.PathUnescape(ref.String())
|
||||
if ref.HasFragmentOnly || filepath.IsAbs(uri) {
|
||||
return uri
|
||||
}
|
||||
|
||||
refURL, _ := url.Parse(uri)
|
||||
if refURL.Host != "" {
|
||||
return uri
|
||||
}
|
||||
|
||||
parts := strings.Split(uri, "#")
|
||||
// BasePath, parts[0] are local filesystem directories, guaranteed to be absolute at this stage
|
||||
parts[0] = filepath.Join(filepath.Dir(basePath), parts[0])
|
||||
|
||||
return strings.Join(parts, "#")
|
||||
}
|
||||
90
vendor/github.com/go-openapi/analysis/internal/flatten/operations/operations.go
generated
vendored
Normal file
90
vendor/github.com/go-openapi/analysis/internal/flatten/operations/operations.go
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
package operations
|
||||
|
||||
import (
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// AllOpRefsByRef returns an index of sortable operations
|
||||
func AllOpRefsByRef(specDoc Provider, operationIDs []string) map[string]OpRef {
|
||||
return OpRefsByRef(GatherOperations(specDoc, operationIDs))
|
||||
}
|
||||
|
||||
// OpRefsByRef indexes a map of sortable operations
|
||||
func OpRefsByRef(oprefs map[string]OpRef) map[string]OpRef {
|
||||
result := make(map[string]OpRef, len(oprefs))
|
||||
for _, v := range oprefs {
|
||||
result[v.Ref.String()] = v
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// OpRef is an indexable, sortable operation
|
||||
type OpRef struct {
|
||||
Method string
|
||||
Path string
|
||||
Key string
|
||||
ID string
|
||||
Op *spec.Operation
|
||||
Ref spec.Ref
|
||||
}
|
||||
|
||||
// OpRefs is a sortable collection of operations
|
||||
type OpRefs []OpRef
|
||||
|
||||
func (o OpRefs) Len() int { return len(o) }
|
||||
func (o OpRefs) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
|
||||
func (o OpRefs) Less(i, j int) bool { return o[i].Key < o[j].Key }
|
||||
|
||||
// Provider knows how to collect operations from a spec
|
||||
type Provider interface {
|
||||
Operations() map[string]map[string]*spec.Operation
|
||||
}
|
||||
|
||||
// GatherOperations builds a map of sorted operations from a spec
|
||||
func GatherOperations(specDoc Provider, operationIDs []string) map[string]OpRef {
|
||||
var oprefs OpRefs
|
||||
|
||||
for method, pathItem := range specDoc.Operations() {
|
||||
for pth, operation := range pathItem {
|
||||
vv := *operation
|
||||
oprefs = append(oprefs, OpRef{
|
||||
Key: swag.ToGoName(strings.ToLower(method) + " " + pth),
|
||||
Method: method,
|
||||
Path: pth,
|
||||
ID: vv.ID,
|
||||
Op: &vv,
|
||||
Ref: spec.MustCreateRef("#" + path.Join("/paths", jsonpointer.Escape(pth), method)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
sort.Sort(oprefs)
|
||||
|
||||
operations := make(map[string]OpRef)
|
||||
for _, opr := range oprefs {
|
||||
nm := opr.ID
|
||||
if nm == "" {
|
||||
nm = opr.Key
|
||||
}
|
||||
|
||||
oo, found := operations[nm]
|
||||
if found && oo.Method != opr.Method && oo.Path != opr.Path {
|
||||
nm = opr.Key
|
||||
}
|
||||
|
||||
if len(operationIDs) == 0 || swag.ContainsStrings(operationIDs, opr.ID) || swag.ContainsStrings(operationIDs, nm) {
|
||||
opr.ID = nm
|
||||
opr.Op.ID = nm
|
||||
operations[nm] = opr
|
||||
}
|
||||
}
|
||||
|
||||
return operations
|
||||
}
|
||||
434
vendor/github.com/go-openapi/analysis/internal/flatten/replace/replace.go
generated
vendored
Normal file
434
vendor/github.com/go-openapi/analysis/internal/flatten/replace/replace.go
generated
vendored
Normal file
@@ -0,0 +1,434 @@
|
||||
package replace
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/analysis/internal/debug"
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/spec"
|
||||
)
|
||||
|
||||
const definitionsPath = "#/definitions"
|
||||
|
||||
var debugLog = debug.GetLogger("analysis/flatten/replace", os.Getenv("SWAGGER_DEBUG") != "")
|
||||
|
||||
// RewriteSchemaToRef replaces a schema with a Ref
|
||||
func RewriteSchemaToRef(sp *spec.Swagger, key string, ref spec.Ref) error {
|
||||
debugLog("rewriting schema to ref for %s with %s", key, ref.String())
|
||||
_, value, err := getPointerFromKey(sp, key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch refable := value.(type) {
|
||||
case *spec.Schema:
|
||||
return rewriteParentRef(sp, key, ref)
|
||||
|
||||
case spec.Schema:
|
||||
return rewriteParentRef(sp, key, ref)
|
||||
|
||||
case *spec.SchemaOrArray:
|
||||
if refable.Schema != nil {
|
||||
refable.Schema = &spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
}
|
||||
|
||||
case *spec.SchemaOrBool:
|
||||
if refable.Schema != nil {
|
||||
refable.Schema = &spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("no schema with ref found at %s for %T", key, value)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func rewriteParentRef(sp *spec.Swagger, key string, ref spec.Ref) error {
|
||||
parent, entry, pvalue, err := getParentFromKey(sp, key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
debugLog("rewriting holder for %T", pvalue)
|
||||
switch container := pvalue.(type) {
|
||||
case spec.Response:
|
||||
if err := rewriteParentRef(sp, "#"+parent, ref); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case *spec.Response:
|
||||
container.Schema = &spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
case *spec.Responses:
|
||||
statusCode, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", key[1:], err)
|
||||
}
|
||||
resp := container.StatusCodeResponses[statusCode]
|
||||
resp.Schema = &spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
container.StatusCodeResponses[statusCode] = resp
|
||||
|
||||
case map[string]spec.Response:
|
||||
resp := container[entry]
|
||||
resp.Schema = &spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
container[entry] = resp
|
||||
|
||||
case spec.Parameter:
|
||||
if err := rewriteParentRef(sp, "#"+parent, ref); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case map[string]spec.Parameter:
|
||||
param := container[entry]
|
||||
param.Schema = &spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
container[entry] = param
|
||||
|
||||
case []spec.Parameter:
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", key[1:], err)
|
||||
}
|
||||
param := container[idx]
|
||||
param.Schema = &spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
container[idx] = param
|
||||
|
||||
case spec.Definitions:
|
||||
container[entry] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
case map[string]spec.Schema:
|
||||
container[entry] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
case []spec.Schema:
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", key[1:], err)
|
||||
}
|
||||
container[idx] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
case *spec.SchemaOrArray:
|
||||
// NOTE: this is necessarily an array - otherwise, the parent would be *Schema
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", key[1:], err)
|
||||
}
|
||||
container.Schemas[idx] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
case spec.SchemaProperties:
|
||||
container[entry] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
// NOTE: can't have case *spec.SchemaOrBool = parent in this case is *Schema
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unhandled parent schema rewrite %s (%T)", key, pvalue)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getPointerFromKey retrieves the content of the JSON pointer "key"
|
||||
func getPointerFromKey(sp interface{}, key string) (string, interface{}, error) {
|
||||
switch sp.(type) {
|
||||
case *spec.Schema:
|
||||
case *spec.Swagger:
|
||||
default:
|
||||
panic("unexpected type used in getPointerFromKey")
|
||||
}
|
||||
if key == "#/" {
|
||||
return "", sp, nil
|
||||
}
|
||||
// unescape chars in key, e.g. "{}" from path params
|
||||
pth, _ := url.PathUnescape(key[1:])
|
||||
ptr, err := jsonpointer.New(pth)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
value, _, err := ptr.Get(sp)
|
||||
if err != nil {
|
||||
debugLog("error when getting key: %s with path: %s", key, pth)
|
||||
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
return pth, value, nil
|
||||
}
|
||||
|
||||
// getParentFromKey retrieves the container of the JSON pointer "key"
|
||||
func getParentFromKey(sp interface{}, key string) (string, string, interface{}, error) {
|
||||
switch sp.(type) {
|
||||
case *spec.Schema:
|
||||
case *spec.Swagger:
|
||||
default:
|
||||
panic("unexpected type used in getPointerFromKey")
|
||||
}
|
||||
// unescape chars in key, e.g. "{}" from path params
|
||||
pth, _ := url.PathUnescape(key[1:])
|
||||
|
||||
parent, entry := path.Dir(pth), path.Base(pth)
|
||||
debugLog("getting schema holder at: %s, with entry: %s", parent, entry)
|
||||
|
||||
pptr, err := jsonpointer.New(parent)
|
||||
if err != nil {
|
||||
return "", "", nil, err
|
||||
}
|
||||
pvalue, _, err := pptr.Get(sp)
|
||||
if err != nil {
|
||||
return "", "", nil, fmt.Errorf("can't get parent for %s: %w", parent, err)
|
||||
}
|
||||
|
||||
return parent, entry, pvalue, nil
|
||||
}
|
||||
|
||||
// UpdateRef replaces a ref by another one
|
||||
func UpdateRef(sp interface{}, key string, ref spec.Ref) error {
|
||||
switch sp.(type) {
|
||||
case *spec.Schema:
|
||||
case *spec.Swagger:
|
||||
default:
|
||||
panic("unexpected type used in getPointerFromKey")
|
||||
}
|
||||
debugLog("updating ref for %s with %s", key, ref.String())
|
||||
pth, value, err := getPointerFromKey(sp, key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch refable := value.(type) {
|
||||
case *spec.Schema:
|
||||
refable.Ref = ref
|
||||
case *spec.SchemaOrArray:
|
||||
if refable.Schema != nil {
|
||||
refable.Schema.Ref = ref
|
||||
}
|
||||
case *spec.SchemaOrBool:
|
||||
if refable.Schema != nil {
|
||||
refable.Schema.Ref = ref
|
||||
}
|
||||
case spec.Schema:
|
||||
debugLog("rewriting holder for %T", refable)
|
||||
_, entry, pvalue, erp := getParentFromKey(sp, key)
|
||||
if erp != nil {
|
||||
return err
|
||||
}
|
||||
switch container := pvalue.(type) {
|
||||
case spec.Definitions:
|
||||
container[entry] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
case map[string]spec.Schema:
|
||||
container[entry] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
case []spec.Schema:
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", pth, err)
|
||||
}
|
||||
container[idx] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
case *spec.SchemaOrArray:
|
||||
// NOTE: this is necessarily an array - otherwise, the parent would be *Schema
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", pth, err)
|
||||
}
|
||||
container.Schemas[idx] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
case spec.SchemaProperties:
|
||||
container[entry] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
|
||||
|
||||
// NOTE: can't have case *spec.SchemaOrBool = parent in this case is *Schema
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unhandled container type at %s: %T", key, value)
|
||||
}
|
||||
|
||||
default:
|
||||
return fmt.Errorf("no schema with ref found at %s for %T", key, value)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateRefWithSchema replaces a ref with a schema (i.e. re-inline schema)
|
||||
func UpdateRefWithSchema(sp *spec.Swagger, key string, sch *spec.Schema) error {
|
||||
debugLog("updating ref for %s with schema", key)
|
||||
pth, value, err := getPointerFromKey(sp, key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch refable := value.(type) {
|
||||
case *spec.Schema:
|
||||
*refable = *sch
|
||||
case spec.Schema:
|
||||
_, entry, pvalue, erp := getParentFromKey(sp, key)
|
||||
if erp != nil {
|
||||
return err
|
||||
}
|
||||
switch container := pvalue.(type) {
|
||||
case spec.Definitions:
|
||||
container[entry] = *sch
|
||||
|
||||
case map[string]spec.Schema:
|
||||
container[entry] = *sch
|
||||
|
||||
case []spec.Schema:
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", pth, err)
|
||||
}
|
||||
container[idx] = *sch
|
||||
|
||||
case *spec.SchemaOrArray:
|
||||
// NOTE: this is necessarily an array - otherwise, the parent would be *Schema
|
||||
idx, err := strconv.Atoi(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not a number: %w", pth, err)
|
||||
}
|
||||
container.Schemas[idx] = *sch
|
||||
|
||||
case spec.SchemaProperties:
|
||||
container[entry] = *sch
|
||||
|
||||
// NOTE: can't have case *spec.SchemaOrBool = parent in this case is *Schema
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unhandled type for parent of [%s]: %T", key, value)
|
||||
}
|
||||
case *spec.SchemaOrArray:
|
||||
*refable.Schema = *sch
|
||||
// NOTE: can't have case *spec.SchemaOrBool = parent in this case is *Schema
|
||||
case *spec.SchemaOrBool:
|
||||
*refable.Schema = *sch
|
||||
default:
|
||||
return fmt.Errorf("no schema with ref found at %s for %T", key, value)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepestRefResult holds the results from DeepestRef analysis
|
||||
type DeepestRefResult struct {
|
||||
Ref spec.Ref
|
||||
Schema *spec.Schema
|
||||
Warnings []string
|
||||
}
|
||||
|
||||
// DeepestRef finds the first definition ref, from a cascade of nested refs which are not definitions.
|
||||
// - if no definition is found, returns the deepest ref.
|
||||
// - pointers to external files are expanded
|
||||
//
|
||||
// NOTE: all external $ref's are assumed to be already expanded at this stage.
|
||||
func DeepestRef(sp *spec.Swagger, opts *spec.ExpandOptions, ref spec.Ref) (*DeepestRefResult, error) {
|
||||
if !ref.HasFragmentOnly {
|
||||
// we found an external $ref, which is odd at this stage:
|
||||
// do nothing on external $refs
|
||||
return &DeepestRefResult{Ref: ref}, nil
|
||||
}
|
||||
|
||||
currentRef := ref
|
||||
visited := make(map[string]bool, 64)
|
||||
warnings := make([]string, 0, 2)
|
||||
|
||||
DOWNREF:
|
||||
for currentRef.String() != "" {
|
||||
if path.Dir(currentRef.String()) == definitionsPath {
|
||||
// this is a top-level definition: stop here and return this ref
|
||||
return &DeepestRefResult{Ref: currentRef}, nil
|
||||
}
|
||||
|
||||
if _, beenThere := visited[currentRef.String()]; beenThere {
|
||||
return nil,
|
||||
fmt.Errorf("cannot resolve cyclic chain of pointers under %s", currentRef.String())
|
||||
}
|
||||
|
||||
visited[currentRef.String()] = true
|
||||
value, _, err := currentRef.GetPointer().Get(sp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch refable := value.(type) {
|
||||
case *spec.Schema:
|
||||
if refable.Ref.String() == "" {
|
||||
break DOWNREF
|
||||
}
|
||||
currentRef = refable.Ref
|
||||
|
||||
case spec.Schema:
|
||||
if refable.Ref.String() == "" {
|
||||
break DOWNREF
|
||||
}
|
||||
currentRef = refable.Ref
|
||||
|
||||
case *spec.SchemaOrArray:
|
||||
if refable.Schema == nil || refable.Schema != nil && refable.Schema.Ref.String() == "" {
|
||||
break DOWNREF
|
||||
}
|
||||
currentRef = refable.Schema.Ref
|
||||
|
||||
case *spec.SchemaOrBool:
|
||||
if refable.Schema == nil || refable.Schema != nil && refable.Schema.Ref.String() == "" {
|
||||
break DOWNREF
|
||||
}
|
||||
currentRef = refable.Schema.Ref
|
||||
|
||||
case spec.Response:
|
||||
// a pointer points to a schema initially marshalled in responses section...
|
||||
// Attempt to convert this to a schema. If this fails, the spec is invalid
|
||||
asJSON, _ := refable.MarshalJSON()
|
||||
var asSchema spec.Schema
|
||||
|
||||
err := asSchema.UnmarshalJSON(asJSON)
|
||||
if err != nil {
|
||||
return nil,
|
||||
fmt.Errorf("invalid type for resolved JSON pointer %s. Expected a schema a, got: %T",
|
||||
currentRef.String(), value)
|
||||
}
|
||||
warnings = append(warnings, fmt.Sprintf("found $ref %q (response) interpreted as schema", currentRef.String()))
|
||||
|
||||
if asSchema.Ref.String() == "" {
|
||||
break DOWNREF
|
||||
}
|
||||
currentRef = asSchema.Ref
|
||||
|
||||
case spec.Parameter:
|
||||
// a pointer points to a schema initially marshalled in parameters section...
|
||||
// Attempt to convert this to a schema. If this fails, the spec is invalid
|
||||
asJSON, _ := refable.MarshalJSON()
|
||||
var asSchema spec.Schema
|
||||
if err := asSchema.UnmarshalJSON(asJSON); err != nil {
|
||||
return nil,
|
||||
fmt.Errorf("invalid type for resolved JSON pointer %s. Expected a schema a, got: %T",
|
||||
currentRef.String(), value)
|
||||
}
|
||||
|
||||
warnings = append(warnings, fmt.Sprintf("found $ref %q (parameter) interpreted as schema", currentRef.String()))
|
||||
|
||||
if asSchema.Ref.String() == "" {
|
||||
break DOWNREF
|
||||
}
|
||||
currentRef = asSchema.Ref
|
||||
|
||||
default:
|
||||
return nil,
|
||||
fmt.Errorf("unhandled type to resolve JSON pointer %s. Expected a Schema, got: %T",
|
||||
currentRef.String(), value)
|
||||
}
|
||||
}
|
||||
|
||||
// assess what schema we're ending with
|
||||
sch, erv := spec.ResolveRefWithBase(sp, ¤tRef, opts)
|
||||
if erv != nil {
|
||||
return nil, erv
|
||||
}
|
||||
|
||||
if sch == nil {
|
||||
return nil, fmt.Errorf("no schema found at %s", currentRef.String())
|
||||
}
|
||||
|
||||
return &DeepestRefResult{Ref: currentRef, Schema: sch, Warnings: warnings}, nil
|
||||
}
|
||||
29
vendor/github.com/go-openapi/analysis/internal/flatten/schutils/flatten_schema.go
generated
vendored
Normal file
29
vendor/github.com/go-openapi/analysis/internal/flatten/schutils/flatten_schema.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// Package schutils provides tools to save or clone a schema
|
||||
// when flattening a spec.
|
||||
package schutils
|
||||
|
||||
import (
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// Save registers a schema as an entry in spec #/definitions
|
||||
func Save(sp *spec.Swagger, name string, schema *spec.Schema) {
|
||||
if schema == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if sp.Definitions == nil {
|
||||
sp.Definitions = make(map[string]spec.Schema, 150)
|
||||
}
|
||||
|
||||
sp.Definitions[name] = *schema
|
||||
}
|
||||
|
||||
// Clone deep-clones a schema
|
||||
func Clone(schema *spec.Schema) *spec.Schema {
|
||||
var sch spec.Schema
|
||||
_ = swag.FromDynamicJSON(schema, &sch)
|
||||
|
||||
return &sch
|
||||
}
|
||||
201
vendor/github.com/go-openapi/analysis/internal/flatten/sortref/keys.go
generated
vendored
Normal file
201
vendor/github.com/go-openapi/analysis/internal/flatten/sortref/keys.go
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
package sortref
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
"github.com/go-openapi/spec"
|
||||
)
|
||||
|
||||
const (
|
||||
paths = "paths"
|
||||
responses = "responses"
|
||||
parameters = "parameters"
|
||||
definitions = "definitions"
|
||||
)
|
||||
|
||||
var (
|
||||
ignoredKeys map[string]struct{}
|
||||
validMethods map[string]struct{}
|
||||
)
|
||||
|
||||
func init() {
|
||||
ignoredKeys = map[string]struct{}{
|
||||
"schema": {},
|
||||
"properties": {},
|
||||
"not": {},
|
||||
"anyOf": {},
|
||||
"oneOf": {},
|
||||
}
|
||||
|
||||
validMethods = map[string]struct{}{
|
||||
"GET": {},
|
||||
"HEAD": {},
|
||||
"OPTIONS": {},
|
||||
"PATCH": {},
|
||||
"POST": {},
|
||||
"PUT": {},
|
||||
"DELETE": {},
|
||||
}
|
||||
}
|
||||
|
||||
// Key represent a key item constructed from /-separated segments
|
||||
type Key struct {
|
||||
Segments int
|
||||
Key string
|
||||
}
|
||||
|
||||
// Keys is a sortable collable collection of Keys
|
||||
type Keys []Key
|
||||
|
||||
func (k Keys) Len() int { return len(k) }
|
||||
func (k Keys) Swap(i, j int) { k[i], k[j] = k[j], k[i] }
|
||||
func (k Keys) Less(i, j int) bool {
|
||||
return k[i].Segments > k[j].Segments || (k[i].Segments == k[j].Segments && k[i].Key < k[j].Key)
|
||||
}
|
||||
|
||||
// KeyParts construct a SplitKey with all its /-separated segments decomposed. It is sortable.
|
||||
func KeyParts(key string) SplitKey {
|
||||
var res []string
|
||||
for _, part := range strings.Split(key[1:], "/") {
|
||||
if part != "" {
|
||||
res = append(res, jsonpointer.Unescape(part))
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// SplitKey holds of the parts of a /-separated key, soi that their location may be determined.
|
||||
type SplitKey []string
|
||||
|
||||
// IsDefinition is true when the split key is in the #/definitions section of a spec
|
||||
func (s SplitKey) IsDefinition() bool {
|
||||
return len(s) > 1 && s[0] == definitions
|
||||
}
|
||||
|
||||
// DefinitionName yields the name of the definition
|
||||
func (s SplitKey) DefinitionName() string {
|
||||
if !s.IsDefinition() {
|
||||
return ""
|
||||
}
|
||||
|
||||
return s[1]
|
||||
}
|
||||
|
||||
func (s SplitKey) isKeyName(i int) bool {
|
||||
if i <= 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
count := 0
|
||||
for idx := i - 1; idx > 0; idx-- {
|
||||
if s[idx] != "properties" {
|
||||
break
|
||||
}
|
||||
count++
|
||||
}
|
||||
|
||||
return count%2 != 0
|
||||
}
|
||||
|
||||
// PartAdder know how to construct the components of a new name
|
||||
type PartAdder func(string) []string
|
||||
|
||||
// BuildName builds a name from segments
|
||||
func (s SplitKey) BuildName(segments []string, startIndex int, adder PartAdder) string {
|
||||
for i, part := range s[startIndex:] {
|
||||
if _, ignored := ignoredKeys[part]; !ignored || s.isKeyName(startIndex+i) {
|
||||
segments = append(segments, adder(part)...)
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(segments, " ")
|
||||
}
|
||||
|
||||
// IsOperation is true when the split key is in the operations section
|
||||
func (s SplitKey) IsOperation() bool {
|
||||
return len(s) > 1 && s[0] == paths
|
||||
}
|
||||
|
||||
// IsSharedOperationParam is true when the split key is in the parameters section of a path
|
||||
func (s SplitKey) IsSharedOperationParam() bool {
|
||||
return len(s) > 2 && s[0] == paths && s[2] == parameters
|
||||
}
|
||||
|
||||
// IsSharedParam is true when the split key is in the #/parameters section of a spec
|
||||
func (s SplitKey) IsSharedParam() bool {
|
||||
return len(s) > 1 && s[0] == parameters
|
||||
}
|
||||
|
||||
// IsOperationParam is true when the split key is in the parameters section of an operation
|
||||
func (s SplitKey) IsOperationParam() bool {
|
||||
return len(s) > 3 && s[0] == paths && s[3] == parameters
|
||||
}
|
||||
|
||||
// IsOperationResponse is true when the split key is in the responses section of an operation
|
||||
func (s SplitKey) IsOperationResponse() bool {
|
||||
return len(s) > 3 && s[0] == paths && s[3] == responses
|
||||
}
|
||||
|
||||
// IsSharedResponse is true when the split key is in the #/responses section of a spec
|
||||
func (s SplitKey) IsSharedResponse() bool {
|
||||
return len(s) > 1 && s[0] == responses
|
||||
}
|
||||
|
||||
// IsDefaultResponse is true when the split key is the default response for an operation
|
||||
func (s SplitKey) IsDefaultResponse() bool {
|
||||
return len(s) > 4 && s[0] == paths && s[3] == responses && s[4] == "default"
|
||||
}
|
||||
|
||||
// IsStatusCodeResponse is true when the split key is an operation response with a status code
|
||||
func (s SplitKey) IsStatusCodeResponse() bool {
|
||||
isInt := func() bool {
|
||||
_, err := strconv.Atoi(s[4])
|
||||
|
||||
return err == nil
|
||||
}
|
||||
|
||||
return len(s) > 4 && s[0] == paths && s[3] == responses && isInt()
|
||||
}
|
||||
|
||||
// ResponseName yields either the status code or "Default" for a response
|
||||
func (s SplitKey) ResponseName() string {
|
||||
if s.IsStatusCodeResponse() {
|
||||
code, _ := strconv.Atoi(s[4])
|
||||
|
||||
return http.StatusText(code)
|
||||
}
|
||||
|
||||
if s.IsDefaultResponse() {
|
||||
return "Default"
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// PathItemRef constructs a $ref object from a split key of the form /{path}/{method}
|
||||
func (s SplitKey) PathItemRef() spec.Ref {
|
||||
if len(s) < 3 {
|
||||
return spec.Ref{}
|
||||
}
|
||||
|
||||
pth, method := s[1], s[2]
|
||||
if _, isValidMethod := validMethods[strings.ToUpper(method)]; !isValidMethod && !strings.HasPrefix(method, "x-") {
|
||||
return spec.Ref{}
|
||||
}
|
||||
|
||||
return spec.MustCreateRef("#" + path.Join("/", paths, jsonpointer.Escape(pth), strings.ToUpper(method)))
|
||||
}
|
||||
|
||||
// PathRef constructs a $ref object from a split key of the form /paths/{reference}
|
||||
func (s SplitKey) PathRef() spec.Ref {
|
||||
if !s.IsOperation() {
|
||||
return spec.Ref{}
|
||||
}
|
||||
|
||||
return spec.MustCreateRef("#" + path.Join("/", paths, jsonpointer.Escape(s[1])))
|
||||
}
|
||||
141
vendor/github.com/go-openapi/analysis/internal/flatten/sortref/sort_ref.go
generated
vendored
Normal file
141
vendor/github.com/go-openapi/analysis/internal/flatten/sortref/sort_ref.go
generated
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
package sortref
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/analysis/internal/flatten/normalize"
|
||||
"github.com/go-openapi/spec"
|
||||
)
|
||||
|
||||
var depthGroupOrder = []string{
|
||||
"sharedParam", "sharedResponse", "sharedOpParam", "opParam", "codeResponse", "defaultResponse", "definition",
|
||||
}
|
||||
|
||||
type mapIterator struct {
|
||||
len int
|
||||
mapIter *reflect.MapIter
|
||||
}
|
||||
|
||||
func (i *mapIterator) Next() bool {
|
||||
return i.mapIter.Next()
|
||||
}
|
||||
|
||||
func (i *mapIterator) Len() int {
|
||||
return i.len
|
||||
}
|
||||
|
||||
func (i *mapIterator) Key() string {
|
||||
return i.mapIter.Key().String()
|
||||
}
|
||||
|
||||
func mustMapIterator(anyMap interface{}) *mapIterator {
|
||||
val := reflect.ValueOf(anyMap)
|
||||
|
||||
return &mapIterator{mapIter: val.MapRange(), len: val.Len()}
|
||||
}
|
||||
|
||||
// DepthFirst sorts a map of anything. It groups keys by category
|
||||
// (shared params, op param, statuscode response, default response, definitions)
|
||||
// sort groups internally by number of parts in the key and lexical names
|
||||
// flatten groups into a single list of keys
|
||||
func DepthFirst(in interface{}) []string {
|
||||
iterator := mustMapIterator(in)
|
||||
sorted := make([]string, 0, iterator.Len())
|
||||
grouped := make(map[string]Keys, iterator.Len())
|
||||
|
||||
for iterator.Next() {
|
||||
k := iterator.Key()
|
||||
split := KeyParts(k)
|
||||
var pk string
|
||||
|
||||
if split.IsSharedOperationParam() {
|
||||
pk = "sharedOpParam"
|
||||
}
|
||||
if split.IsOperationParam() {
|
||||
pk = "opParam"
|
||||
}
|
||||
if split.IsStatusCodeResponse() {
|
||||
pk = "codeResponse"
|
||||
}
|
||||
if split.IsDefaultResponse() {
|
||||
pk = "defaultResponse"
|
||||
}
|
||||
if split.IsDefinition() {
|
||||
pk = "definition"
|
||||
}
|
||||
if split.IsSharedParam() {
|
||||
pk = "sharedParam"
|
||||
}
|
||||
if split.IsSharedResponse() {
|
||||
pk = "sharedResponse"
|
||||
}
|
||||
grouped[pk] = append(grouped[pk], Key{Segments: len(split), Key: k})
|
||||
}
|
||||
|
||||
for _, pk := range depthGroupOrder {
|
||||
res := grouped[pk]
|
||||
sort.Sort(res)
|
||||
|
||||
for _, v := range res {
|
||||
sorted = append(sorted, v.Key)
|
||||
}
|
||||
}
|
||||
|
||||
return sorted
|
||||
}
|
||||
|
||||
// topMostRefs is able to sort refs by hierarchical then lexicographic order,
|
||||
// yielding refs ordered breadth-first.
|
||||
type topmostRefs []string
|
||||
|
||||
func (k topmostRefs) Len() int { return len(k) }
|
||||
func (k topmostRefs) Swap(i, j int) { k[i], k[j] = k[j], k[i] }
|
||||
func (k topmostRefs) Less(i, j int) bool {
|
||||
li, lj := len(strings.Split(k[i], "/")), len(strings.Split(k[j], "/"))
|
||||
if li == lj {
|
||||
return k[i] < k[j]
|
||||
}
|
||||
|
||||
return li < lj
|
||||
}
|
||||
|
||||
// TopmostFirst sorts references by depth
|
||||
func TopmostFirst(refs []string) []string {
|
||||
res := topmostRefs(refs)
|
||||
sort.Sort(res)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// RefRevIdx is a reverse index for references
|
||||
type RefRevIdx struct {
|
||||
Ref spec.Ref
|
||||
Keys []string
|
||||
}
|
||||
|
||||
// ReverseIndex builds a reverse index for references in schemas
|
||||
func ReverseIndex(schemas map[string]spec.Ref, basePath string) map[string]RefRevIdx {
|
||||
collected := make(map[string]RefRevIdx)
|
||||
for key, schRef := range schemas {
|
||||
// normalize paths before sorting,
|
||||
// so we get together keys that are from the same external file
|
||||
normalizedPath := normalize.Path(schRef, basePath)
|
||||
|
||||
entry, ok := collected[normalizedPath]
|
||||
if ok {
|
||||
entry.Keys = append(entry.Keys, key)
|
||||
collected[normalizedPath] = entry
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
collected[normalizedPath] = RefRevIdx{
|
||||
Ref: schRef,
|
||||
Keys: []string{key},
|
||||
}
|
||||
}
|
||||
|
||||
return collected
|
||||
}
|
||||
192
vendor/github.com/go-openapi/analysis/mixin.go
generated
vendored
192
vendor/github.com/go-openapi/analysis/mixin.go
generated
vendored
@@ -80,6 +80,7 @@ func Mixin(primary *spec.Swagger, mixins ...*spec.Swagger) []string {
|
||||
|
||||
skipped = append(skipped, mergeResponses(primary, m)...)
|
||||
}
|
||||
|
||||
return skipped
|
||||
}
|
||||
|
||||
@@ -90,12 +91,15 @@ func getOpIds(s *spec.Swagger) map[string]bool {
|
||||
if s.Paths == nil {
|
||||
return rv
|
||||
}
|
||||
|
||||
for _, v := range s.Paths.Paths {
|
||||
piops := pathItemOps(v)
|
||||
|
||||
for _, op := range piops {
|
||||
rv[op.ID] = true
|
||||
}
|
||||
}
|
||||
|
||||
return rv
|
||||
}
|
||||
|
||||
@@ -107,6 +111,7 @@ func pathItemOps(p spec.PathItem) []*spec.Operation {
|
||||
rv = appendOp(rv, p.Delete)
|
||||
rv = appendOp(rv, p.Head)
|
||||
rv = appendOp(rv, p.Patch)
|
||||
|
||||
return rv
|
||||
}
|
||||
|
||||
@@ -114,6 +119,7 @@ func appendOp(ops []*spec.Operation, op *spec.Operation) []*spec.Operation {
|
||||
if op == nil {
|
||||
return ops
|
||||
}
|
||||
|
||||
return append(ops, op)
|
||||
}
|
||||
|
||||
@@ -123,10 +129,13 @@ func mergeSecurityDefinitions(primary *spec.Swagger, m *spec.Swagger) (skipped [
|
||||
warn := fmt.Sprintf(
|
||||
"SecurityDefinitions entry '%v' already exists in primary or higher priority mixin, skipping\n", k)
|
||||
skipped = append(skipped, warn)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
primary.SecurityDefinitions[k] = v
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -136,17 +145,21 @@ func mergeSecurityRequirements(primary *spec.Swagger, m *spec.Swagger) (skipped
|
||||
for _, vv := range primary.Security {
|
||||
if reflect.DeepEqual(v, vv) {
|
||||
found = true
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
warn := fmt.Sprintf(
|
||||
"Security requirement: '%v' already exists in primary or higher priority mixin, skipping\n", v)
|
||||
skipped = append(skipped, warn)
|
||||
|
||||
continue
|
||||
}
|
||||
primary.Security = append(primary.Security, v)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -157,10 +170,12 @@ func mergeDefinitions(primary *spec.Swagger, m *spec.Swagger) (skipped []string)
|
||||
warn := fmt.Sprintf(
|
||||
"definitions entry '%v' already exists in primary or higher priority mixin, skipping\n", k)
|
||||
skipped = append(skipped, warn)
|
||||
|
||||
continue
|
||||
}
|
||||
primary.Definitions[k] = v
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -171,6 +186,7 @@ func mergePaths(primary *spec.Swagger, m *spec.Swagger, opIds map[string]bool, m
|
||||
warn := fmt.Sprintf(
|
||||
"paths entry '%v' already exists in primary or higher priority mixin, skipping\n", k)
|
||||
skipped = append(skipped, warn)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -190,6 +206,7 @@ func mergePaths(primary *spec.Swagger, m *spec.Swagger, opIds map[string]bool, m
|
||||
primary.Paths.Paths[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -202,10 +219,12 @@ func mergeParameters(primary *spec.Swagger, m *spec.Swagger) (skipped []string)
|
||||
warn := fmt.Sprintf(
|
||||
"top level parameters entry '%v' already exists in primary or higher priority mixin, skipping\n", k)
|
||||
skipped = append(skipped, warn)
|
||||
|
||||
continue
|
||||
}
|
||||
primary.Parameters[k] = v
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -218,10 +237,12 @@ func mergeResponses(primary *spec.Swagger, m *spec.Swagger) (skipped []string) {
|
||||
warn := fmt.Sprintf(
|
||||
"top level responses entry '%v' already exists in primary or higher priority mixin, skipping\n", k)
|
||||
skipped = append(skipped, warn)
|
||||
|
||||
continue
|
||||
}
|
||||
primary.Responses[k] = v
|
||||
}
|
||||
|
||||
return skipped
|
||||
}
|
||||
|
||||
@@ -231,15 +252,18 @@ func mergeConsumes(primary *spec.Swagger, m *spec.Swagger) []string {
|
||||
for _, vv := range primary.Consumes {
|
||||
if v == vv {
|
||||
found = true
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
// no warning here: we just skip it
|
||||
continue
|
||||
}
|
||||
primary.Consumes = append(primary.Consumes, v)
|
||||
}
|
||||
|
||||
return []string{}
|
||||
}
|
||||
|
||||
@@ -249,15 +273,18 @@ func mergeProduces(primary *spec.Swagger, m *spec.Swagger) []string {
|
||||
for _, vv := range primary.Produces {
|
||||
if v == vv {
|
||||
found = true
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
// no warning here: we just skip it
|
||||
continue
|
||||
}
|
||||
primary.Produces = append(primary.Produces, v)
|
||||
}
|
||||
|
||||
return []string{}
|
||||
}
|
||||
|
||||
@@ -267,17 +294,24 @@ func mergeTags(primary *spec.Swagger, m *spec.Swagger) (skipped []string) {
|
||||
for _, vv := range primary.Tags {
|
||||
if v.Name == vv.Name {
|
||||
found = true
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
warn := fmt.Sprintf(
|
||||
"top level tags entry with name '%v' already exists in primary or higher priority mixin, skipping\n", v.Name)
|
||||
"top level tags entry with name '%v' already exists in primary or higher priority mixin, skipping\n",
|
||||
v.Name,
|
||||
)
|
||||
skipped = append(skipped, warn)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
primary.Tags = append(primary.Tags, v)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -287,110 +321,150 @@ func mergeSchemes(primary *spec.Swagger, m *spec.Swagger) []string {
|
||||
for _, vv := range primary.Schemes {
|
||||
if v == vv {
|
||||
found = true
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
// no warning here: we just skip it
|
||||
continue
|
||||
}
|
||||
primary.Schemes = append(primary.Schemes, v)
|
||||
}
|
||||
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func mergeSwaggerProps(primary *spec.Swagger, m *spec.Swagger) []string {
|
||||
var skipped []string
|
||||
var skipped, skippedInfo, skippedDocs []string
|
||||
|
||||
primary.Extensions, skipped = mergeExtensions(primary.Extensions, m.Extensions)
|
||||
|
||||
// merging details in swagger top properties
|
||||
if primary.Host == "" {
|
||||
primary.Host = m.Host
|
||||
}
|
||||
|
||||
if primary.BasePath == "" {
|
||||
primary.BasePath = m.BasePath
|
||||
}
|
||||
|
||||
if primary.Info == nil {
|
||||
primary.Info = m.Info
|
||||
} else if m.Info != nil {
|
||||
var sk []string
|
||||
primary.Info.Extensions, sk = mergeExtensions(primary.Info.Extensions, m.Info.Extensions)
|
||||
skipped = append(skipped, sk...)
|
||||
if primary.Info.Description == "" {
|
||||
primary.Info.Description = m.Info.Description
|
||||
}
|
||||
if primary.Info.Title == "" {
|
||||
primary.Info.Description = m.Info.Description
|
||||
}
|
||||
if primary.Info.TermsOfService == "" {
|
||||
primary.Info.TermsOfService = m.Info.TermsOfService
|
||||
}
|
||||
if primary.Info.Version == "" {
|
||||
primary.Info.Version = m.Info.Version
|
||||
}
|
||||
|
||||
if primary.Info.Contact == nil {
|
||||
primary.Info.Contact = m.Info.Contact
|
||||
} else if m.Info.Contact != nil {
|
||||
var csk []string
|
||||
primary.Info.Contact.Extensions, csk = mergeExtensions(primary.Info.Contact.Extensions, m.Info.Contact.Extensions)
|
||||
skipped = append(skipped, csk...)
|
||||
if primary.Info.Contact.Name == "" {
|
||||
primary.Info.Contact.Name = m.Info.Contact.Name
|
||||
}
|
||||
if primary.Info.Contact.URL == "" {
|
||||
primary.Info.Contact.URL = m.Info.Contact.URL
|
||||
}
|
||||
if primary.Info.Contact.Email == "" {
|
||||
primary.Info.Contact.Email = m.Info.Contact.Email
|
||||
}
|
||||
}
|
||||
|
||||
if primary.Info.License == nil {
|
||||
primary.Info.License = m.Info.License
|
||||
} else if m.Info.License != nil {
|
||||
var lsk []string
|
||||
primary.Info.License.Extensions, lsk = mergeExtensions(primary.Info.License.Extensions, m.Info.License.Extensions)
|
||||
skipped = append(skipped, lsk...)
|
||||
if primary.Info.License.Name == "" {
|
||||
primary.Info.License.Name = m.Info.License.Name
|
||||
}
|
||||
if primary.Info.License.URL == "" {
|
||||
primary.Info.License.URL = m.Info.License.URL
|
||||
}
|
||||
}
|
||||
|
||||
skippedInfo = mergeInfo(primary.Info, m.Info)
|
||||
skipped = append(skipped, skippedInfo...)
|
||||
}
|
||||
|
||||
if primary.ExternalDocs == nil {
|
||||
primary.ExternalDocs = m.ExternalDocs
|
||||
} else if m.ExternalDocs != nil {
|
||||
if primary.ExternalDocs.Description == "" {
|
||||
primary.ExternalDocs.Description = m.ExternalDocs.Description
|
||||
} else if m != nil {
|
||||
skippedDocs = mergeExternalDocs(primary.ExternalDocs, m.ExternalDocs)
|
||||
skipped = append(skipped, skippedDocs...)
|
||||
}
|
||||
|
||||
return skipped
|
||||
}
|
||||
|
||||
// nolint: unparam
|
||||
func mergeExternalDocs(primary *spec.ExternalDocumentation, m *spec.ExternalDocumentation) []string {
|
||||
if primary.Description == "" {
|
||||
primary.Description = m.Description
|
||||
}
|
||||
|
||||
if primary.URL == "" {
|
||||
primary.URL = m.URL
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func mergeInfo(primary *spec.Info, m *spec.Info) []string {
|
||||
var sk, skipped []string
|
||||
|
||||
primary.Extensions, sk = mergeExtensions(primary.Extensions, m.Extensions)
|
||||
skipped = append(skipped, sk...)
|
||||
|
||||
if primary.Description == "" {
|
||||
primary.Description = m.Description
|
||||
}
|
||||
|
||||
if primary.Title == "" {
|
||||
primary.Description = m.Description
|
||||
}
|
||||
|
||||
if primary.TermsOfService == "" {
|
||||
primary.TermsOfService = m.TermsOfService
|
||||
}
|
||||
|
||||
if primary.Version == "" {
|
||||
primary.Version = m.Version
|
||||
}
|
||||
|
||||
if primary.Contact == nil {
|
||||
primary.Contact = m.Contact
|
||||
} else if m.Contact != nil {
|
||||
var csk []string
|
||||
primary.Contact.Extensions, csk = mergeExtensions(primary.Contact.Extensions, m.Contact.Extensions)
|
||||
skipped = append(skipped, csk...)
|
||||
|
||||
if primary.Contact.Name == "" {
|
||||
primary.Contact.Name = m.Contact.Name
|
||||
}
|
||||
if primary.ExternalDocs.URL == "" {
|
||||
primary.ExternalDocs.URL = m.ExternalDocs.URL
|
||||
|
||||
if primary.Contact.URL == "" {
|
||||
primary.Contact.URL = m.Contact.URL
|
||||
}
|
||||
|
||||
if primary.Contact.Email == "" {
|
||||
primary.Contact.Email = m.Contact.Email
|
||||
}
|
||||
}
|
||||
|
||||
if primary.License == nil {
|
||||
primary.License = m.License
|
||||
} else if m.License != nil {
|
||||
var lsk []string
|
||||
primary.License.Extensions, lsk = mergeExtensions(primary.License.Extensions, m.License.Extensions)
|
||||
skipped = append(skipped, lsk...)
|
||||
|
||||
if primary.License.Name == "" {
|
||||
primary.License.Name = m.License.Name
|
||||
}
|
||||
|
||||
if primary.License.URL == "" {
|
||||
primary.License.URL = m.License.URL
|
||||
}
|
||||
}
|
||||
|
||||
return skipped
|
||||
}
|
||||
|
||||
func mergeExtensions(primary spec.Extensions, m spec.Extensions) (result spec.Extensions, skipped []string) {
|
||||
if primary == nil {
|
||||
result = m
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if m == nil {
|
||||
result = primary
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
result = primary
|
||||
for k, v := range m {
|
||||
if _, found := primary[k]; found {
|
||||
skipped = append(skipped, k)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
primary[k] = v
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -398,33 +472,43 @@ func initPrimary(primary *spec.Swagger) {
|
||||
if primary.SecurityDefinitions == nil {
|
||||
primary.SecurityDefinitions = make(map[string]*spec.SecurityScheme)
|
||||
}
|
||||
|
||||
if primary.Security == nil {
|
||||
primary.Security = make([]map[string][]string, 0, 10)
|
||||
}
|
||||
|
||||
if primary.Produces == nil {
|
||||
primary.Produces = make([]string, 0, 10)
|
||||
}
|
||||
|
||||
if primary.Consumes == nil {
|
||||
primary.Consumes = make([]string, 0, 10)
|
||||
}
|
||||
|
||||
if primary.Tags == nil {
|
||||
primary.Tags = make([]spec.Tag, 0, 10)
|
||||
}
|
||||
|
||||
if primary.Schemes == nil {
|
||||
primary.Schemes = make([]string, 0, 10)
|
||||
}
|
||||
|
||||
if primary.Paths == nil {
|
||||
primary.Paths = &spec.Paths{Paths: make(map[string]spec.PathItem)}
|
||||
}
|
||||
|
||||
if primary.Paths.Paths == nil {
|
||||
primary.Paths.Paths = make(map[string]spec.PathItem)
|
||||
}
|
||||
|
||||
if primary.Definitions == nil {
|
||||
primary.Definitions = make(spec.Definitions)
|
||||
}
|
||||
|
||||
if primary.Parameters == nil {
|
||||
primary.Parameters = make(map[string]spec.Parameter)
|
||||
}
|
||||
|
||||
if primary.Responses == nil {
|
||||
primary.Responses = make(map[string]spec.Response)
|
||||
}
|
||||
|
||||
64
vendor/github.com/go-openapi/analysis/schema.go
generated
vendored
64
vendor/github.com/go-openapi/analysis/schema.go
generated
vendored
@@ -47,6 +47,7 @@ func Schema(opts SchemaOpts) (*AnalyzedSchema, error) {
|
||||
}
|
||||
|
||||
a.inferSimpleSchema()
|
||||
|
||||
return a, nil
|
||||
}
|
||||
|
||||
@@ -123,6 +124,7 @@ func (a *AnalyzedSchema) inferFromRef() error {
|
||||
}
|
||||
a.inherits(rsch)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -142,26 +144,33 @@ func (a *AnalyzedSchema) inferKnownType() {
|
||||
}
|
||||
|
||||
func (a *AnalyzedSchema) inferMap() error {
|
||||
if a.isObjectType() {
|
||||
hasExtra := a.hasProps || a.hasAllOf
|
||||
a.IsMap = a.hasAdditionalProps && !hasExtra
|
||||
a.IsExtendedObject = a.hasAdditionalProps && hasExtra
|
||||
if a.IsMap {
|
||||
if a.schema.AdditionalProperties.Schema != nil {
|
||||
msch, err := Schema(SchemaOpts{
|
||||
Schema: a.schema.AdditionalProperties.Schema,
|
||||
Root: a.root,
|
||||
BasePath: a.basePath,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.IsSimpleMap = msch.IsSimpleSchema
|
||||
} else if a.schema.AdditionalProperties.Allows {
|
||||
a.IsSimpleMap = true
|
||||
}
|
||||
}
|
||||
if !a.isObjectType() {
|
||||
return nil
|
||||
}
|
||||
|
||||
hasExtra := a.hasProps || a.hasAllOf
|
||||
a.IsMap = a.hasAdditionalProps && !hasExtra
|
||||
a.IsExtendedObject = a.hasAdditionalProps && hasExtra
|
||||
|
||||
if !a.IsMap {
|
||||
return nil
|
||||
}
|
||||
|
||||
// maps
|
||||
if a.schema.AdditionalProperties.Schema != nil {
|
||||
msch, err := Schema(SchemaOpts{
|
||||
Schema: a.schema.AdditionalProperties.Schema,
|
||||
Root: a.root,
|
||||
BasePath: a.basePath,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.IsSimpleMap = msch.IsSimpleSchema
|
||||
} else if a.schema.AdditionalProperties.Allows {
|
||||
a.IsSimpleMap = true
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -184,12 +193,15 @@ func (a *AnalyzedSchema) inferArray() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a.IsSimpleArray = itsch.IsSimpleSchema
|
||||
}
|
||||
}
|
||||
|
||||
if a.IsArray && !a.hasItems {
|
||||
a.IsSimpleArray = true
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -218,11 +230,10 @@ func (a *AnalyzedSchema) initializeFlags() {
|
||||
(a.schema.Items.Schema != nil || len(a.schema.Items.Schemas) > 0)
|
||||
|
||||
a.hasAdditionalProps = a.schema.AdditionalProperties != nil &&
|
||||
(a.schema.AdditionalProperties != nil || a.schema.AdditionalProperties.Allows)
|
||||
(a.schema.AdditionalProperties.Schema != nil || a.schema.AdditionalProperties.Allows)
|
||||
|
||||
a.hasAdditionalItems = a.schema.AdditionalItems != nil &&
|
||||
(a.schema.AdditionalItems.Schema != nil || a.schema.AdditionalItems.Allows)
|
||||
|
||||
}
|
||||
|
||||
func (a *AnalyzedSchema) isObjectType() bool {
|
||||
@@ -232,3 +243,14 @@ func (a *AnalyzedSchema) isObjectType() bool {
|
||||
func (a *AnalyzedSchema) isArrayType() bool {
|
||||
return !a.hasRef && (a.schema.Type != nil && a.schema.Type.Contains("array"))
|
||||
}
|
||||
|
||||
// isAnalyzedAsComplex determines if an analyzed schema is eligible to flattening (i.e. it is "complex").
|
||||
//
|
||||
// Complex means the schema is any of:
|
||||
// - a simple type (primitive)
|
||||
// - an array of something (items are possibly complex ; if this is the case, items will generate a definition)
|
||||
// - a map of something (additionalProperties are possibly complex ; if this is the case, additionalProperties will
|
||||
// generate a definition)
|
||||
func (a *AnalyzedSchema) isAnalyzedAsComplex() bool {
|
||||
return !a.IsSimpleSchema && !a.IsArray && !a.IsMap
|
||||
}
|
||||
|
||||
1
vendor/github.com/go-openapi/errors/.gitattributes
generated
vendored
Normal file
1
vendor/github.com/go-openapi/errors/.gitattributes
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.go text eol=lf
|
||||
28
vendor/github.com/go-openapi/errors/.golangci.yml
generated
vendored
28
vendor/github.com/go-openapi/errors/.golangci.yml
generated
vendored
@@ -18,3 +18,31 @@ linters:
|
||||
- maligned
|
||||
- lll
|
||||
- gochecknoglobals
|
||||
- godox
|
||||
- gocognit
|
||||
- whitespace
|
||||
- wsl
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- scopelint
|
||||
- wrapcheck
|
||||
- exhaustivestruct
|
||||
- exhaustive
|
||||
- nlreturn
|
||||
- testpackage
|
||||
- gci
|
||||
- gofumpt
|
||||
- goerr113
|
||||
- gomnd
|
||||
- tparallel
|
||||
- nestif
|
||||
- godot
|
||||
- errorlint
|
||||
- paralleltest
|
||||
- tparallel
|
||||
- cyclop
|
||||
- errname
|
||||
- varnamelen
|
||||
- exhaustruct
|
||||
- maintidx
|
||||
|
||||
13
vendor/github.com/go-openapi/errors/.travis.yml
generated
vendored
13
vendor/github.com/go-openapi/errors/.travis.yml
generated
vendored
@@ -1,13 +0,0 @@
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
go:
|
||||
- 1.13.x
|
||||
- 1.14.x
|
||||
install:
|
||||
- GO111MODULE=off go get -u gotest.tools/gotestsum
|
||||
language: go
|
||||
notifications:
|
||||
slack:
|
||||
secure: gZGp9NaHxi7zawlXJXKY92BGeDR1x0tbIcTyU5nMKLq0fhIaiEBJEeALwZ4VgqsSv3DytSSF5mLH8fevAM3ixE6hxjKQ+lQuf7V/w3btCN1CSWgoua5LOh1kTnqZQtJuRvO4pzoJcT3bJWBsVZ07VGNVzzJEy/zAKCHFqBUCXShw7QemlLBcYWFNqveTlvDIfCzvouoLnPoXwxEpkjxe9uz/ZKZgAnup/fXjC8RFctmgCnkCyvJTk0Y/fZCsufixJrJhshBWTnlrFCzRmgNkz2d+i1Ls3+MJ5EJJ2Tx/A5S63dL49J1f9Kr0AKHADmulSy8JNzIckKwbyFMYUecrsW+Lsu9DhnVMy1jj5pKsJDLRi2iIU3fXTMWbcyQbXjbbnBO2mPdP3Tzme75y4D9fc8hUPeyqVv2BU26NEbQ7EF2pKJ93OXvci7HlwRBgdJa8j6mP2LEDClcPQW00g7N/OZe0cTOMa8L5AwiBlbArwqt9wv6YLJoTG0wpDhzWsFvbCg5bJxe28Yn3fIDD0Lk1I7iSnBbp/5gzF19jmxqvcT8tHRkDL4xfjbENFTZjA5uB4Z4pj4WSyWQILLV/Jwhe3fi9uQwdviFHfj5pnVrmNUiGSOQL672K5wl2c3E9mGwejvsu2dfEz28n7Y/FUnOpY3/cBS0n27JJaerS0zMKNLE=
|
||||
script:
|
||||
- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
7
vendor/github.com/go-openapi/errors/README.md
generated
vendored
7
vendor/github.com/go-openapi/errors/README.md
generated
vendored
@@ -1,7 +1,10 @@
|
||||
# OpenAPI errors [](https://travis-ci.org/go-openapi/errors) [](https://codecov.io/gh/go-openapi/errors) [](https://slackin.goswagger.io)
|
||||
# OpenAPI errors
|
||||
|
||||
[](https://travis-ci.org/go-openapi/errors)
|
||||
[](https://codecov.io/gh/go-openapi/errors)
|
||||
[](https://slackin.goswagger.io)
|
||||
[](https://raw.githubusercontent.com/go-openapi/errors/master/LICENSE)
|
||||
[](http://godoc.org/github.com/go-openapi/errors)
|
||||
[](https://pkg.go.dev/github.com/go-openapi/errors)
|
||||
[](https://golangci.com)
|
||||
[](https://goreportcard.com/report/github.com/go-openapi/errors)
|
||||
|
||||
|
||||
20
vendor/github.com/go-openapi/errors/api.go
generated
vendored
20
vendor/github.com/go-openapi/errors/api.go
generated
vendored
@@ -44,6 +44,14 @@ func (a *apiError) Code() int32 {
|
||||
return a.code
|
||||
}
|
||||
|
||||
// MarshalJSON implements the JSON encoding interface
|
||||
func (a apiError) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(map[string]interface{}{
|
||||
"code": a.code,
|
||||
"message": a.message,
|
||||
})
|
||||
}
|
||||
|
||||
// New creates a new API error with a code and a message
|
||||
func New(code int32, message string, args ...interface{}) Error {
|
||||
if len(args) > 0 {
|
||||
@@ -81,7 +89,17 @@ func (m *MethodNotAllowedError) Code() int32 {
|
||||
return m.code
|
||||
}
|
||||
|
||||
// MarshalJSON implements the JSON encoding interface
|
||||
func (m MethodNotAllowedError) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(map[string]interface{}{
|
||||
"code": m.code,
|
||||
"message": m.message,
|
||||
"allowed": m.Allowed,
|
||||
})
|
||||
}
|
||||
|
||||
func errorAsJSON(err Error) []byte {
|
||||
//nolint:errchkjson
|
||||
b, _ := json.Marshal(struct {
|
||||
Code int32 `json:"code"`
|
||||
Message string `json:"message"`
|
||||
@@ -129,7 +147,7 @@ func ServeError(rw http.ResponseWriter, r *http.Request, err error) {
|
||||
ServeError(rw, r, nil)
|
||||
}
|
||||
case *MethodNotAllowedError:
|
||||
rw.Header().Add("Allow", strings.Join(err.(*MethodNotAllowedError).Allowed, ","))
|
||||
rw.Header().Add("Allow", strings.Join(e.Allowed, ","))
|
||||
rw.WriteHeader(asHTTPCode(int(e.Code())))
|
||||
if r == nil || r.Method != http.MethodHead {
|
||||
_, _ = rw.Write(errorAsJSON(e))
|
||||
|
||||
2
vendor/github.com/go-openapi/errors/doc.go
generated
vendored
2
vendor/github.com/go-openapi/errors/doc.go
generated
vendored
@@ -13,7 +13,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
/*
|
||||
|
||||
Package errors provides an Error interface and several concrete types
|
||||
implementing this interface to manage API errors and JSON-schema validation
|
||||
errors.
|
||||
@@ -23,6 +22,5 @@ it defines.
|
||||
|
||||
It is used throughout the various go-openapi toolkit libraries
|
||||
(https://github.com/go-openapi).
|
||||
|
||||
*/
|
||||
package errors
|
||||
|
||||
26
vendor/github.com/go-openapi/errors/headers.go
generated
vendored
26
vendor/github.com/go-openapi/errors/headers.go
generated
vendored
@@ -15,6 +15,7 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
@@ -38,11 +39,28 @@ func (e *Validation) Code() int32 {
|
||||
return e.code
|
||||
}
|
||||
|
||||
// ValidateName produces an error message name for an aliased property
|
||||
// MarshalJSON implements the JSON encoding interface
|
||||
func (e Validation) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(map[string]interface{}{
|
||||
"code": e.code,
|
||||
"message": e.message,
|
||||
"in": e.In,
|
||||
"name": e.Name,
|
||||
"value": e.Value,
|
||||
"values": e.Values,
|
||||
})
|
||||
}
|
||||
|
||||
// ValidateName sets the name for a validation or updates it for a nested property
|
||||
func (e *Validation) ValidateName(name string) *Validation {
|
||||
if e.Name == "" && name != "" {
|
||||
e.Name = name
|
||||
e.message = name + e.message
|
||||
if name != "" {
|
||||
if e.Name == "" {
|
||||
e.Name = name
|
||||
e.message = name + e.message
|
||||
} else {
|
||||
e.Name = name + "." + e.Name
|
||||
e.message = name + "." + e.message
|
||||
}
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
7
vendor/github.com/go-openapi/errors/middleware.go
generated
vendored
7
vendor/github.com/go-openapi/errors/middleware.go
generated
vendored
@@ -23,12 +23,11 @@ import (
|
||||
// APIVerificationFailed is an error that contains all the missing info for a mismatched section
|
||||
// between the api registrations and the api spec
|
||||
type APIVerificationFailed struct {
|
||||
Section string
|
||||
MissingSpecification []string
|
||||
MissingRegistration []string
|
||||
Section string `json:"section,omitempty"`
|
||||
MissingSpecification []string `json:"missingSpecification,omitempty"`
|
||||
MissingRegistration []string `json:"missingRegistration,omitempty"`
|
||||
}
|
||||
|
||||
//
|
||||
func (v *APIVerificationFailed) Error() string {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
|
||||
|
||||
21
vendor/github.com/go-openapi/errors/parsing.go
generated
vendored
21
vendor/github.com/go-openapi/errors/parsing.go
generated
vendored
@@ -14,7 +14,10 @@
|
||||
|
||||
package errors
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ParseError represents a parsing error
|
||||
type ParseError struct {
|
||||
@@ -35,6 +38,22 @@ func (e *ParseError) Code() int32 {
|
||||
return e.code
|
||||
}
|
||||
|
||||
// MarshalJSON implements the JSON encoding interface
|
||||
func (e ParseError) MarshalJSON() ([]byte, error) {
|
||||
var reason string
|
||||
if e.Reason != nil {
|
||||
reason = e.Reason.Error()
|
||||
}
|
||||
return json.Marshal(map[string]interface{}{
|
||||
"code": e.code,
|
||||
"message": e.message,
|
||||
"in": e.In,
|
||||
"name": e.Name,
|
||||
"value": e.Value,
|
||||
"reason": reason,
|
||||
})
|
||||
}
|
||||
|
||||
const (
|
||||
parseErrorTemplContent = `parsing %s %s from %q failed, because %s`
|
||||
parseErrorTemplContentNoIn = `parsing %s from %q failed, because %s`
|
||||
|
||||
89
vendor/github.com/go-openapi/errors/schema.go
generated
vendored
89
vendor/github.com/go-openapi/errors/schema.go
generated
vendored
@@ -15,6 +15,7 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
@@ -25,6 +26,7 @@ const (
|
||||
typeFailWithData = "%s in %s must be of type %s: %q"
|
||||
typeFailWithError = "%s in %s must be of type %s, because: %s"
|
||||
requiredFail = "%s in %s is required"
|
||||
readOnlyFail = "%s in %s is readOnly"
|
||||
tooLongMessage = "%s in %s should be at most %d chars long"
|
||||
tooShortMessage = "%s in %s should be at least %d chars long"
|
||||
patternFail = "%s in %s should match '%s'"
|
||||
@@ -41,6 +43,7 @@ const (
|
||||
typeFailWithDataNoIn = "%s must be of type %s: %q"
|
||||
typeFailWithErrorNoIn = "%s must be of type %s, because: %s"
|
||||
requiredFailNoIn = "%s is required"
|
||||
readOnlyFailNoIn = "%s is readOnly"
|
||||
tooLongMessageNoIn = "%s should be at most %d chars long"
|
||||
tooShortMessageNoIn = "%s should be at least %d chars long"
|
||||
patternFailNoIn = "%s should match '%s'"
|
||||
@@ -91,6 +94,7 @@ const (
|
||||
UnallowedPropertyCode
|
||||
FailedAllPatternPropsCode
|
||||
MultipleOfMustBePositiveCode
|
||||
ReadOnlyFailCode
|
||||
)
|
||||
|
||||
// CompositeError is an error that groups several errors together
|
||||
@@ -116,6 +120,15 @@ func (c *CompositeError) Error() string {
|
||||
return c.message
|
||||
}
|
||||
|
||||
// MarshalJSON implements the JSON encoding interface
|
||||
func (c CompositeError) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(map[string]interface{}{
|
||||
"code": c.code,
|
||||
"message": c.message,
|
||||
"errors": c.Errors,
|
||||
})
|
||||
}
|
||||
|
||||
// CompositeValidationError an error to wrap a bunch of other errors
|
||||
func CompositeValidationError(errors ...error) *CompositeError {
|
||||
return &CompositeError{
|
||||
@@ -125,6 +138,19 @@ func CompositeValidationError(errors ...error) *CompositeError {
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateName recursively sets the name for all validations or updates them for nested properties
|
||||
func (c *CompositeError) ValidateName(name string) *CompositeError {
|
||||
for i, e := range c.Errors {
|
||||
if ve, ok := e.(*Validation); ok {
|
||||
c.Errors[i] = ve.ValidateName(name)
|
||||
} else if ce, ok := e.(*CompositeError); ok {
|
||||
c.Errors[i] = ce.ValidateName(name)
|
||||
}
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// FailedAllPatternProperties an error for when the property doesn't match a pattern
|
||||
func FailedAllPatternProperties(name, in, key string) *Validation {
|
||||
msg := fmt.Sprintf(failedAllPatternProps, name, key, in)
|
||||
@@ -268,7 +294,7 @@ func DuplicateItems(name, in string) *Validation {
|
||||
}
|
||||
|
||||
// TooManyItems error for when an array contains too many items
|
||||
func TooManyItems(name, in string, max int64) *Validation {
|
||||
func TooManyItems(name, in string, max int64, value interface{}) *Validation {
|
||||
msg := fmt.Sprintf(maxItemsFail, name, in, max)
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(maxItemsFailNoIn, name, max)
|
||||
@@ -278,12 +304,13 @@ func TooManyItems(name, in string, max int64) *Validation {
|
||||
code: MaxItemsFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: value,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
// TooFewItems error for when an array contains too few items
|
||||
func TooFewItems(name, in string, min int64) *Validation {
|
||||
func TooFewItems(name, in string, min int64, value interface{}) *Validation {
|
||||
msg := fmt.Sprintf(minItemsFail, name, in, min)
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(minItemsFailNoIn, name, min)
|
||||
@@ -292,12 +319,13 @@ func TooFewItems(name, in string, min int64) *Validation {
|
||||
code: MinItemsFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: value,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMaximumInt error for when maximum validation fails
|
||||
func ExceedsMaximumInt(name, in string, max int64, exclusive bool) *Validation {
|
||||
func ExceedsMaximumInt(name, in string, max int64, exclusive bool, value interface{}) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
m := maxIncFailNoIn
|
||||
@@ -316,13 +344,13 @@ func ExceedsMaximumInt(name, in string, max int64, exclusive bool) *Validation {
|
||||
code: MaxFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: max,
|
||||
Value: value,
|
||||
message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMaximumUint error for when maximum validation fails
|
||||
func ExceedsMaximumUint(name, in string, max uint64, exclusive bool) *Validation {
|
||||
func ExceedsMaximumUint(name, in string, max uint64, exclusive bool, value interface{}) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
m := maxIncFailNoIn
|
||||
@@ -341,13 +369,13 @@ func ExceedsMaximumUint(name, in string, max uint64, exclusive bool) *Validation
|
||||
code: MaxFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: max,
|
||||
Value: value,
|
||||
message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMaximum error for when maximum validation fails
|
||||
func ExceedsMaximum(name, in string, max float64, exclusive bool) *Validation {
|
||||
func ExceedsMaximum(name, in string, max float64, exclusive bool, value interface{}) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
m := maxIncFailNoIn
|
||||
@@ -366,13 +394,13 @@ func ExceedsMaximum(name, in string, max float64, exclusive bool) *Validation {
|
||||
code: MaxFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: max,
|
||||
Value: value,
|
||||
message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMinimumInt error for when minimum validation fails
|
||||
func ExceedsMinimumInt(name, in string, min int64, exclusive bool) *Validation {
|
||||
func ExceedsMinimumInt(name, in string, min int64, exclusive bool, value interface{}) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
m := minIncFailNoIn
|
||||
@@ -391,13 +419,13 @@ func ExceedsMinimumInt(name, in string, min int64, exclusive bool) *Validation {
|
||||
code: MinFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: min,
|
||||
Value: value,
|
||||
message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMinimumUint error for when minimum validation fails
|
||||
func ExceedsMinimumUint(name, in string, min uint64, exclusive bool) *Validation {
|
||||
func ExceedsMinimumUint(name, in string, min uint64, exclusive bool, value interface{}) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
m := minIncFailNoIn
|
||||
@@ -416,13 +444,13 @@ func ExceedsMinimumUint(name, in string, min uint64, exclusive bool) *Validation
|
||||
code: MinFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: min,
|
||||
Value: value,
|
||||
message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMinimum error for when minimum validation fails
|
||||
func ExceedsMinimum(name, in string, min float64, exclusive bool) *Validation {
|
||||
func ExceedsMinimum(name, in string, min float64, exclusive bool, value interface{}) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
m := minIncFailNoIn
|
||||
@@ -441,13 +469,13 @@ func ExceedsMinimum(name, in string, min float64, exclusive bool) *Validation {
|
||||
code: MinFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: min,
|
||||
Value: value,
|
||||
message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// NotMultipleOf error for when multiple of validation fails
|
||||
func NotMultipleOf(name, in string, multiple interface{}) *Validation {
|
||||
func NotMultipleOf(name, in string, multiple, value interface{}) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(multipleOfFailNoIn, name, multiple)
|
||||
@@ -458,7 +486,7 @@ func NotMultipleOf(name, in string, multiple interface{}) *Validation {
|
||||
code: MultipleOfFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: multiple,
|
||||
Value: value,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
@@ -483,7 +511,7 @@ func EnumFail(name, in string, value interface{}, values []interface{}) *Validat
|
||||
}
|
||||
|
||||
// Required error for when a value is missing
|
||||
func Required(name, in string) *Validation {
|
||||
func Required(name, in string, value interface{}) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(requiredFailNoIn, name)
|
||||
@@ -494,12 +522,30 @@ func Required(name, in string) *Validation {
|
||||
code: RequiredFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: value,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
// ReadOnly error for when a value is present in request
|
||||
func ReadOnly(name, in string, value interface{}) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(readOnlyFailNoIn, name)
|
||||
} else {
|
||||
msg = fmt.Sprintf(readOnlyFail, name, in)
|
||||
}
|
||||
return &Validation{
|
||||
code: ReadOnlyFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: value,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
// TooLong error for when a string is too long
|
||||
func TooLong(name, in string, max int64) *Validation {
|
||||
func TooLong(name, in string, max int64, value interface{}) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(tooLongMessageNoIn, name, max)
|
||||
@@ -510,12 +556,13 @@ func TooLong(name, in string, max int64) *Validation {
|
||||
code: TooLongFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: value,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
// TooShort error for when a string is too short
|
||||
func TooShort(name, in string, min int64) *Validation {
|
||||
func TooShort(name, in string, min int64, value interface{}) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(tooShortMessageNoIn, name, min)
|
||||
@@ -527,13 +574,14 @@ func TooShort(name, in string, min int64) *Validation {
|
||||
code: TooShortFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: value,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
// FailedPattern error for when a string fails a regex pattern match
|
||||
// the pattern that is returned is the ECMA syntax version of the pattern not the golang version.
|
||||
func FailedPattern(name, in, pattern string) *Validation {
|
||||
func FailedPattern(name, in, pattern string, value interface{}) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
msg = fmt.Sprintf(patternFailNoIn, name, pattern)
|
||||
@@ -545,6 +593,7 @@ func FailedPattern(name, in, pattern string) *Validation {
|
||||
code: PatternFailCode,
|
||||
Name: name,
|
||||
In: in,
|
||||
Value: value,
|
||||
message: msg,
|
||||
}
|
||||
}
|
||||
|
||||
5
vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go
generated
vendored
5
vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go
generated
vendored
@@ -26,11 +26,16 @@ var rxDupSlashes = regexp.MustCompile(`/{2,}`)
|
||||
// - FlagLowercaseHost
|
||||
// - FlagRemoveDefaultPort
|
||||
// - FlagRemoveDuplicateSlashes (and this was mixed in with the |)
|
||||
//
|
||||
// This also normalizes the URL into its urlencoded form by removing RawPath and RawFragment.
|
||||
func NormalizeURL(u *url.URL) {
|
||||
lowercaseScheme(u)
|
||||
lowercaseHost(u)
|
||||
removeDefaultPort(u)
|
||||
removeDuplicateSlashes(u)
|
||||
|
||||
u.RawPath = ""
|
||||
u.RawFragment = ""
|
||||
}
|
||||
|
||||
func lowercaseScheme(u *url.URL) {
|
||||
|
||||
22
vendor/github.com/go-openapi/loads/.golangci.yml
generated
vendored
22
vendor/github.com/go-openapi/loads/.golangci.yml
generated
vendored
@@ -20,3 +20,25 @@ linters:
|
||||
- lll
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- godox
|
||||
- gocognit
|
||||
- whitespace
|
||||
- wsl
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- scopelint
|
||||
- wrapcheck
|
||||
- exhaustivestruct
|
||||
- exhaustive
|
||||
- nlreturn
|
||||
- testpackage
|
||||
- gci
|
||||
- gofumpt
|
||||
- goerr113
|
||||
- gomnd
|
||||
- tparallel
|
||||
- nestif
|
||||
- godot
|
||||
- errorlint
|
||||
- paralleltest
|
||||
|
||||
18
vendor/github.com/go-openapi/loads/.travis.yml
generated
vendored
18
vendor/github.com/go-openapi/loads/.travis.yml
generated
vendored
@@ -1,11 +1,23 @@
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
go:
|
||||
- 1.13.x
|
||||
- 1.14.x
|
||||
- 1.16.x
|
||||
- 1.x
|
||||
install:
|
||||
- go get -u gotest.tools/gotestsum
|
||||
- go get gotest.tools/gotestsum
|
||||
language: go
|
||||
arch:
|
||||
- amd64
|
||||
- ppc64le
|
||||
jobs:
|
||||
include:
|
||||
# include linting job, but only for latest go version and amd64 arch
|
||||
- go: 1.x
|
||||
arch: amd64
|
||||
install:
|
||||
go get github.com/golangci/golangci-lint/cmd/golangci-lint
|
||||
script:
|
||||
- golangci-lint run --new-from-rev master
|
||||
notifications:
|
||||
slack:
|
||||
secure: OxkPwVp35qBTUilgWC8xykSj+sGMcj0h8IIOKD+Rflx2schZVlFfdYdyVBM+s9OqeOfvtuvnR9v1Ye2rPKAvcjWdC4LpRGUsgmItZaI6Um8Aj6+K9udCw5qrtZVfOVmRu8LieH//XznWWKdOultUuniW0MLqw5+II87Gd00RWbCGi0hk0PykHe7uK+PDA2BEbqyZ2WKKYCvfB3j+0nrFOHScXqnh0V05l2E83J4+Sgy1fsPy+1WdX58ZlNBG333ibaC1FS79XvKSmTgKRkx3+YBo97u6ZtUmJa5WZjf2OdLG3KIckGWAv6R5xgxeU31N0Ng8L332w/Edpp2O/M2bZwdnKJ8hJQikXIAQbICbr+lTDzsoNzMdEIYcHpJ5hjPbiUl3Bmd+Jnsjf5McgAZDiWIfpCKZ29tPCEkVwRsOCqkyPRMNMzHHmoja495P5jR+ODS7+J8RFg5xgcnOgpP9D4Wlhztlf5WyZMpkLxTUD+bZq2SRf50HfHFXTkfq22zPl3d1eq0yrLwh/Z/fWKkfb6SyysROL8y6s8u3dpFX1YHSg0BR6i913h4aoZw9B2BG27cafLLTwKYsp2dFo1PWl4O6u9giFJIeqwloZHLKKrwh0cBFhB7RH0I58asxkZpCH6uWjJierahmHe7iS+E6i+9oCHkOZ59hmCYNimIs3hM=
|
||||
|
||||
3
vendor/github.com/go-openapi/loads/README.md
generated
vendored
3
vendor/github.com/go-openapi/loads/README.md
generated
vendored
@@ -1,7 +1,6 @@
|
||||
# Loads OAI specs [](https://travis-ci.org/go-openapi/loads) [](https://codecov.io/gh/go-openapi/loads) [](https://slackin.goswagger.io)
|
||||
# Loads OAI specs [](https://travis-ci.org/go-openapi/loads) [](https://codecov.io/gh/go-openapi/loads) [](https://slackin.goswagger.io) [](https://github.com/go-openapi/loads/actions?query=workflow%3A"Go+Test")
|
||||
|
||||
[](https://raw.githubusercontent.com/go-openapi/loads/master/LICENSE) [](http://godoc.org/github.com/go-openapi/loads)
|
||||
[](https://golangci.com)
|
||||
[](https://goreportcard.com/report/github.com/go-openapi/loads)
|
||||
|
||||
Loading of OAI specification documents from local or remote locations. Supports JSON and YAML documents.
|
||||
|
||||
134
vendor/github.com/go-openapi/loads/loaders.go
generated
vendored
Normal file
134
vendor/github.com/go-openapi/loads/loaders.go
generated
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
package loads
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/url"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
var (
|
||||
// Default chain of loaders, defined at the package level.
|
||||
//
|
||||
// By default this matches json and yaml documents.
|
||||
//
|
||||
// May be altered with AddLoader().
|
||||
loaders *loader
|
||||
)
|
||||
|
||||
func init() {
|
||||
jsonLoader := &loader{
|
||||
DocLoaderWithMatch: DocLoaderWithMatch{
|
||||
Match: func(pth string) bool {
|
||||
return true
|
||||
},
|
||||
Fn: JSONDoc,
|
||||
},
|
||||
}
|
||||
|
||||
loaders = jsonLoader.WithHead(&loader{
|
||||
DocLoaderWithMatch: DocLoaderWithMatch{
|
||||
Match: swag.YAMLMatcher,
|
||||
Fn: swag.YAMLDoc,
|
||||
},
|
||||
})
|
||||
|
||||
// sets the global default loader for go-openapi/spec
|
||||
spec.PathLoader = loaders.Load
|
||||
}
|
||||
|
||||
// DocLoader represents a doc loader type
|
||||
type DocLoader func(string) (json.RawMessage, error)
|
||||
|
||||
// DocMatcher represents a predicate to check if a loader matches
|
||||
type DocMatcher func(string) bool
|
||||
|
||||
// DocLoaderWithMatch describes a loading function for a given extension match.
|
||||
type DocLoaderWithMatch struct {
|
||||
Fn DocLoader
|
||||
Match DocMatcher
|
||||
}
|
||||
|
||||
// NewDocLoaderWithMatch builds a DocLoaderWithMatch to be used in load options
|
||||
func NewDocLoaderWithMatch(fn DocLoader, matcher DocMatcher) DocLoaderWithMatch {
|
||||
return DocLoaderWithMatch{
|
||||
Fn: fn,
|
||||
Match: matcher,
|
||||
}
|
||||
}
|
||||
|
||||
type loader struct {
|
||||
DocLoaderWithMatch
|
||||
Next *loader
|
||||
}
|
||||
|
||||
// WithHead adds a loader at the head of the current stack
|
||||
func (l *loader) WithHead(head *loader) *loader {
|
||||
if head == nil {
|
||||
return l
|
||||
}
|
||||
head.Next = l
|
||||
return head
|
||||
}
|
||||
|
||||
// WithNext adds a loader at the trail of the current stack
|
||||
func (l *loader) WithNext(next *loader) *loader {
|
||||
l.Next = next
|
||||
return next
|
||||
}
|
||||
|
||||
// Load the raw document from path
|
||||
func (l *loader) Load(path string) (json.RawMessage, error) {
|
||||
_, erp := url.Parse(path)
|
||||
if erp != nil {
|
||||
return nil, erp
|
||||
}
|
||||
|
||||
var lastErr error = errors.New("no loader matched") // default error if no match was found
|
||||
for ldr := l; ldr != nil; ldr = ldr.Next {
|
||||
if ldr.Match != nil && !ldr.Match(path) {
|
||||
continue
|
||||
}
|
||||
|
||||
// try then move to next one if there is an error
|
||||
b, err := ldr.Fn(path)
|
||||
if err == nil {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
lastErr = err
|
||||
}
|
||||
|
||||
return nil, lastErr
|
||||
}
|
||||
|
||||
// JSONDoc loads a json document from either a file or a remote url
|
||||
func JSONDoc(path string) (json.RawMessage, error) {
|
||||
data, err := swag.LoadFromFileOrHTTP(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.RawMessage(data), nil
|
||||
}
|
||||
|
||||
// AddLoader for a document, executed before other previously set loaders.
|
||||
//
|
||||
// This sets the configuration at the package level.
|
||||
//
|
||||
// NOTE:
|
||||
// * this updates the default loader used by github.com/go-openapi/spec
|
||||
// * since this sets package level globals, you shouln't call this concurrently
|
||||
//
|
||||
func AddLoader(predicate DocMatcher, load DocLoader) {
|
||||
loaders = loaders.WithHead(&loader{
|
||||
DocLoaderWithMatch: DocLoaderWithMatch{
|
||||
Match: predicate,
|
||||
Fn: load,
|
||||
},
|
||||
})
|
||||
|
||||
// sets the global default loader for go-openapi/spec
|
||||
spec.PathLoader = loaders.Load
|
||||
}
|
||||
61
vendor/github.com/go-openapi/loads/options.go
generated
vendored
Normal file
61
vendor/github.com/go-openapi/loads/options.go
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
package loads
|
||||
|
||||
type options struct {
|
||||
loader *loader
|
||||
}
|
||||
|
||||
func defaultOptions() *options {
|
||||
return &options{
|
||||
loader: loaders,
|
||||
}
|
||||
}
|
||||
|
||||
func loaderFromOptions(options []LoaderOption) *loader {
|
||||
opts := defaultOptions()
|
||||
for _, apply := range options {
|
||||
apply(opts)
|
||||
}
|
||||
|
||||
return opts.loader
|
||||
}
|
||||
|
||||
// LoaderOption allows to fine-tune the spec loader behavior
|
||||
type LoaderOption func(*options)
|
||||
|
||||
// WithDocLoader sets a custom loader for loading specs
|
||||
func WithDocLoader(l DocLoader) LoaderOption {
|
||||
return func(opt *options) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
opt.loader = &loader{
|
||||
DocLoaderWithMatch: DocLoaderWithMatch{
|
||||
Fn: l,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithDocLoaderMatches sets a chain of custom loaders for loading specs
|
||||
// for different extension matches.
|
||||
//
|
||||
// Loaders are executed in the order of provided DocLoaderWithMatch'es.
|
||||
func WithDocLoaderMatches(l ...DocLoaderWithMatch) LoaderOption {
|
||||
return func(opt *options) {
|
||||
var final, prev *loader
|
||||
for _, ldr := range l {
|
||||
if ldr.Fn == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if prev == nil {
|
||||
final = &loader{DocLoaderWithMatch: ldr}
|
||||
prev = final
|
||||
continue
|
||||
}
|
||||
|
||||
prev = prev.WithNext(&loader{DocLoaderWithMatch: ldr})
|
||||
}
|
||||
opt.loader = final
|
||||
}
|
||||
}
|
||||
188
vendor/github.com/go-openapi/loads/spec.go
generated
vendored
188
vendor/github.com/go-openapi/loads/spec.go
generated
vendored
@@ -19,69 +19,15 @@ import (
|
||||
"encoding/gob"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/go-openapi/analysis"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// JSONDoc loads a json document from either a file or a remote url
|
||||
func JSONDoc(path string) (json.RawMessage, error) {
|
||||
data, err := swag.LoadFromFileOrHTTP(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.RawMessage(data), nil
|
||||
}
|
||||
|
||||
// DocLoader represents a doc loader type
|
||||
type DocLoader func(string) (json.RawMessage, error)
|
||||
|
||||
// DocMatcher represents a predicate to check if a loader matches
|
||||
type DocMatcher func(string) bool
|
||||
|
||||
var (
|
||||
loaders *loader
|
||||
defaultLoader *loader
|
||||
)
|
||||
|
||||
func init() {
|
||||
defaultLoader = &loader{Match: func(_ string) bool { return true }, Fn: JSONDoc}
|
||||
loaders = defaultLoader
|
||||
spec.PathLoader = loaders.Fn
|
||||
AddLoader(swag.YAMLMatcher, swag.YAMLDoc)
|
||||
|
||||
gob.Register(map[string]interface{}{})
|
||||
gob.Register([]interface{}{})
|
||||
//gob.Register(spec.Refable{})
|
||||
}
|
||||
|
||||
// AddLoader for a document
|
||||
func AddLoader(predicate DocMatcher, load DocLoader) {
|
||||
prev := loaders
|
||||
loaders = &loader{
|
||||
Match: predicate,
|
||||
Fn: load,
|
||||
Next: prev,
|
||||
}
|
||||
spec.PathLoader = loaders.Fn
|
||||
}
|
||||
|
||||
type loader struct {
|
||||
Fn DocLoader
|
||||
Match DocMatcher
|
||||
Next *loader
|
||||
}
|
||||
|
||||
// JSONSpec loads a spec from a json document
|
||||
func JSONSpec(path string) (*Document, error) {
|
||||
data, err := JSONDoc(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// convert to json
|
||||
return Analyzed(data, "")
|
||||
}
|
||||
|
||||
// Document represents a swagger spec document
|
||||
@@ -93,10 +39,21 @@ type Document struct {
|
||||
origSpec *spec.Swagger
|
||||
schema *spec.Schema
|
||||
raw json.RawMessage
|
||||
pathLoader *loader
|
||||
}
|
||||
|
||||
// JSONSpec loads a spec from a json document
|
||||
func JSONSpec(path string, options ...LoaderOption) (*Document, error) {
|
||||
data, err := JSONDoc(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// convert to json
|
||||
return Analyzed(data, "", options...)
|
||||
}
|
||||
|
||||
// Embedded returns a Document based on embedded specs. No analysis is required
|
||||
func Embedded(orig, flat json.RawMessage) (*Document, error) {
|
||||
func Embedded(orig, flat json.RawMessage, options ...LoaderOption) (*Document, error) {
|
||||
var origSpec, flatSpec spec.Swagger
|
||||
if err := json.Unmarshal(orig, &origSpec); err != nil {
|
||||
return nil, err
|
||||
@@ -105,54 +62,38 @@ func Embedded(orig, flat json.RawMessage) (*Document, error) {
|
||||
return nil, err
|
||||
}
|
||||
return &Document{
|
||||
raw: orig,
|
||||
origSpec: &origSpec,
|
||||
spec: &flatSpec,
|
||||
raw: orig,
|
||||
origSpec: &origSpec,
|
||||
spec: &flatSpec,
|
||||
pathLoader: loaderFromOptions(options),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Spec loads a new spec document
|
||||
func Spec(path string) (*Document, error) {
|
||||
specURL, err := url.Parse(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var lastErr error
|
||||
for l := loaders.Next; l != nil; l = l.Next {
|
||||
if loaders.Match(specURL.Path) {
|
||||
b, err2 := loaders.Fn(path)
|
||||
if err2 != nil {
|
||||
lastErr = err2
|
||||
continue
|
||||
}
|
||||
doc, err3 := Analyzed(b, "")
|
||||
if err3 != nil {
|
||||
return nil, err3
|
||||
}
|
||||
if doc != nil {
|
||||
doc.specFilePath = path
|
||||
}
|
||||
return doc, nil
|
||||
}
|
||||
}
|
||||
if lastErr != nil {
|
||||
return nil, lastErr
|
||||
}
|
||||
b, err := defaultLoader.Fn(path)
|
||||
// Spec loads a new spec document from a local or remote path
|
||||
func Spec(path string, options ...LoaderOption) (*Document, error) {
|
||||
|
||||
ldr := loaderFromOptions(options)
|
||||
|
||||
b, err := ldr.Load(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
document, err := Analyzed(b, "", options...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
document, err := Analyzed(b, "")
|
||||
if document != nil {
|
||||
document.specFilePath = path
|
||||
document.pathLoader = ldr
|
||||
}
|
||||
|
||||
return document, err
|
||||
}
|
||||
|
||||
// Analyzed creates a new analyzed spec document
|
||||
func Analyzed(data json.RawMessage, version string) (*Document, error) {
|
||||
// Analyzed creates a new analyzed spec document for a root json.RawMessage.
|
||||
func Analyzed(data json.RawMessage, version string, options ...LoaderOption) (*Document, error) {
|
||||
if version == "" {
|
||||
version = "2.0"
|
||||
}
|
||||
@@ -160,24 +101,13 @@ func Analyzed(data json.RawMessage, version string) (*Document, error) {
|
||||
return nil, fmt.Errorf("spec version %q is not supported", version)
|
||||
}
|
||||
|
||||
raw := data
|
||||
trimmed := bytes.TrimSpace(data)
|
||||
if len(trimmed) > 0 {
|
||||
if trimmed[0] != '{' && trimmed[0] != '[' {
|
||||
yml, err := swag.BytesToYAMLDoc(trimmed)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("analyzed: %v", err)
|
||||
}
|
||||
d, err := swag.YAMLToJSON(yml)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("analyzed: %v", err)
|
||||
}
|
||||
raw = d
|
||||
}
|
||||
raw, err := trimData(data) // trim blanks, then convert yaml docs into json
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
swspec := new(spec.Swagger)
|
||||
if err := json.Unmarshal(raw, swspec); err != nil {
|
||||
if err = json.Unmarshal(raw, swspec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -187,17 +117,44 @@ func Analyzed(data json.RawMessage, version string) (*Document, error) {
|
||||
}
|
||||
|
||||
d := &Document{
|
||||
Analyzer: analysis.New(swspec),
|
||||
schema: spec.MustLoadSwagger20Schema(),
|
||||
spec: swspec,
|
||||
raw: raw,
|
||||
origSpec: origsqspec,
|
||||
Analyzer: analysis.New(swspec),
|
||||
schema: spec.MustLoadSwagger20Schema(),
|
||||
spec: swspec,
|
||||
raw: raw,
|
||||
origSpec: origsqspec,
|
||||
pathLoader: loaderFromOptions(options),
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
func trimData(in json.RawMessage) (json.RawMessage, error) {
|
||||
trimmed := bytes.TrimSpace(in)
|
||||
if len(trimmed) == 0 {
|
||||
return in, nil
|
||||
}
|
||||
|
||||
if trimmed[0] == '{' || trimmed[0] == '[' {
|
||||
return trimmed, nil
|
||||
}
|
||||
|
||||
// assume yaml doc: convert it to json
|
||||
yml, err := swag.BytesToYAMLDoc(trimmed)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("analyzed: %v", err)
|
||||
}
|
||||
|
||||
d, err := swag.YAMLToJSON(yml)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("analyzed: %v", err)
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// Expanded expands the ref fields in the spec document and returns a new spec document
|
||||
func (d *Document) Expanded(options ...*spec.ExpandOptions) (*Document, error) {
|
||||
|
||||
swspec := new(spec.Swagger)
|
||||
if err := json.Unmarshal(d.raw, swspec); err != nil {
|
||||
return nil, err
|
||||
@@ -212,6 +169,16 @@ func (d *Document) Expanded(options ...*spec.ExpandOptions) (*Document, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if expandOptions.PathLoader == nil {
|
||||
if d.pathLoader != nil {
|
||||
// use loader from Document options
|
||||
expandOptions.PathLoader = d.pathLoader.Load
|
||||
} else {
|
||||
// use package level loader
|
||||
expandOptions.PathLoader = loaders.Load
|
||||
}
|
||||
}
|
||||
|
||||
if err := spec.ExpandSpec(swspec, expandOptions); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -262,7 +229,7 @@ func (d *Document) OrigSpec() *spec.Swagger {
|
||||
return d.origSpec
|
||||
}
|
||||
|
||||
// ResetDefinitions gives a shallow copy with the models reset
|
||||
// ResetDefinitions gives a shallow copy with the models reset to the original spec
|
||||
func (d *Document) ResetDefinitions() *Document {
|
||||
defs := make(map[string]spec.Schema, len(d.origSpec.Definitions))
|
||||
for k, v := range d.origSpec.Definitions {
|
||||
@@ -276,6 +243,7 @@ func (d *Document) ResetDefinitions() *Document {
|
||||
// Pristine creates a new pristine document instance based on the input data
|
||||
func (d *Document) Pristine() *Document {
|
||||
dd, _ := Analyzed(d.Raw(), d.Version())
|
||||
dd.pathLoader = d.pathLoader
|
||||
return dd
|
||||
}
|
||||
|
||||
|
||||
1
vendor/github.com/go-openapi/runtime/.gitattributes
generated
vendored
Normal file
1
vendor/github.com/go-openapi/runtime/.gitattributes
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.go text eol=lf
|
||||
44
vendor/github.com/go-openapi/runtime/.golangci.yml
generated
vendored
Normal file
44
vendor/github.com/go-openapi/runtime/.golangci.yml
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
linters-settings:
|
||||
govet:
|
||||
# Using err repeatedly considered as shadowing.
|
||||
check-shadowing: false
|
||||
golint:
|
||||
min-confidence: 0
|
||||
gocyclo:
|
||||
min-complexity: 30
|
||||
maligned:
|
||||
suggest-new: true
|
||||
dupl:
|
||||
threshold: 100
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 4
|
||||
linters:
|
||||
disable:
|
||||
- maligned
|
||||
- lll
|
||||
- gochecknoglobals
|
||||
- godox
|
||||
- gocognit
|
||||
- whitespace
|
||||
- wsl
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- scopelint
|
||||
- wrapcheck
|
||||
- exhaustivestruct
|
||||
- exhaustive
|
||||
- nlreturn
|
||||
- testpackage
|
||||
- gci
|
||||
- gofumpt
|
||||
- goerr113
|
||||
- gomnd
|
||||
- tparallel
|
||||
- nestif
|
||||
- godot
|
||||
- errorlint
|
||||
- noctx
|
||||
- interfacer
|
||||
- nilerr
|
||||
13
vendor/github.com/go-openapi/runtime/.travis.yml
generated
vendored
13
vendor/github.com/go-openapi/runtime/.travis.yml
generated
vendored
@@ -1,13 +0,0 @@
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
go:
|
||||
- 1.13.x
|
||||
- 1.14.x
|
||||
install:
|
||||
- GO111MODULE=off go get -u gotest.tools/gotestsum
|
||||
language: go
|
||||
notifications:
|
||||
slack:
|
||||
secure: EmObnQuM9Mw8J9vpFaKKHqSMN4Wsr/A9+v7ewAD5cEhA0T1P4m7MbJMiJOhxUhj/X+BFh2DamW+P2lT8mybj5wg8wnkQ2BteKA8Tawi6f9PRw2NRheO8tAi8o/npLnlmet0kc93mn+oLuqHw36w4+j5mkOl2FghkfGiUVhwrhkCP7KXQN+3TU87e+/HzQumlJ3nsE+6terVxkH3PmaUTsS5ONaODZfuxFpfb7RsoEl3skHf6d+tr+1nViLxxly7558Nc33C+W1mr0qiEvMLZ+kJ/CpGWBJ6CUJM3jm6hNe2eMuIPwEK2hxZob8c7n22VPap4K6a0bBRoydoDXaba+2sD7Ym6ivDO/DVyL44VeBBLyIiIBylDGQdZH+6SoWm90Qe/i7tnY/T5Ao5igT8f3cfQY1c3EsTfqmlDfrhmACBmwSlgkdVBLTprHL63JMY24LWmh4jhxsmMRZhCL4dze8su1w6pLN/pD1pGHtKYCEVbdTmaM3PblNRFf12XB7qosmQsgUndH4Vq3bTbU0s1pKjeDhRyLvFzvR0TBbo0pDLEoF1A/i5GVFWa7yLZNUDudQERRh7qv/xBl2excIaQ1sV4DSVm7bAE9l6Kp+yeHQJW2uN6Y3X8wu9gB9nv9l5HBze7wh8KE6PyWAOLYYqZg9/sAtsv/2GcQqXcKFF1zcA=
|
||||
script:
|
||||
- gotestsum -f short-verbose -- -race -timeout=20m -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
16
vendor/github.com/go-openapi/runtime/bytestream.go
generated
vendored
16
vendor/github.com/go-openapi/runtime/bytestream.go
generated
vendored
@@ -38,7 +38,7 @@ type byteStreamOpts struct {
|
||||
Close bool
|
||||
}
|
||||
|
||||
// ByteStreamConsumer creates a consmer for byte streams,
|
||||
// ByteStreamConsumer creates a consumer for byte streams,
|
||||
// takes a Writer/BinaryUnmarshaler interface or binary slice by reference,
|
||||
// and reads from the provided reader
|
||||
func ByteStreamConsumer(opts ...byteStreamOpt) Consumer {
|
||||
@@ -58,6 +58,7 @@ func ByteStreamConsumer(opts ...byteStreamOpt) Consumer {
|
||||
close = cl.Close
|
||||
}
|
||||
}
|
||||
//nolint:errcheck // closing a reader wouldn't fail.
|
||||
defer close()
|
||||
|
||||
if wrtr, ok := data.(io.Writer); ok {
|
||||
@@ -76,6 +77,13 @@ func ByteStreamConsumer(opts ...byteStreamOpt) Consumer {
|
||||
return bu.UnmarshalBinary(b)
|
||||
}
|
||||
|
||||
if data != nil {
|
||||
if str, ok := data.(*string); ok {
|
||||
*str = string(b)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if t := reflect.TypeOf(data); data != nil && t.Kind() == reflect.Ptr {
|
||||
v := reflect.Indirect(reflect.ValueOf(data))
|
||||
if t = v.Type(); t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Uint8 {
|
||||
@@ -107,6 +115,7 @@ func ByteStreamProducer(opts ...byteStreamOpt) Producer {
|
||||
close = cl.Close
|
||||
}
|
||||
}
|
||||
//nolint:errcheck // TODO: closing a writer would fail.
|
||||
defer close()
|
||||
|
||||
if rc, ok := data.(io.ReadCloser); ok {
|
||||
@@ -129,6 +138,11 @@ func ByteStreamProducer(opts ...byteStreamOpt) Producer {
|
||||
}
|
||||
|
||||
if data != nil {
|
||||
if str, ok := data.(string); ok {
|
||||
_, err := writer.Write([]byte(str))
|
||||
return err
|
||||
}
|
||||
|
||||
if e, ok := data.(error); ok {
|
||||
_, err := writer.Write([]byte(e.Error()))
|
||||
return err
|
||||
|
||||
20
vendor/github.com/go-openapi/runtime/client/auth_info.go
generated
vendored
20
vendor/github.com/go-openapi/runtime/client/auth_info.go
generated
vendored
@@ -33,7 +33,7 @@ func init() {
|
||||
func BasicAuth(username, password string) runtime.ClientAuthInfoWriter {
|
||||
return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
|
||||
encoded := base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
|
||||
return r.SetHeaderParam("Authorization", "Basic "+encoded)
|
||||
return r.SetHeaderParam(runtime.HeaderAuthorization, "Basic "+encoded)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -56,6 +56,22 @@ func APIKeyAuth(name, in, value string) runtime.ClientAuthInfoWriter {
|
||||
// BearerToken provides a header based oauth2 bearer access token auth info writer
|
||||
func BearerToken(token string) runtime.ClientAuthInfoWriter {
|
||||
return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
|
||||
return r.SetHeaderParam("Authorization", "Bearer "+token)
|
||||
return r.SetHeaderParam(runtime.HeaderAuthorization, "Bearer "+token)
|
||||
})
|
||||
}
|
||||
|
||||
// Compose combines multiple ClientAuthInfoWriters into a single one.
|
||||
// Useful when multiple auth headers are needed.
|
||||
func Compose(auths ...runtime.ClientAuthInfoWriter) runtime.ClientAuthInfoWriter {
|
||||
return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
|
||||
for _, auth := range auths {
|
||||
if auth == nil {
|
||||
continue
|
||||
}
|
||||
if err := auth.AuthenticateRequest(r, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
8
vendor/github.com/go-openapi/runtime/client/keepalive.go
generated
vendored
8
vendor/github.com/go-openapi/runtime/client/keepalive.go
generated
vendored
@@ -2,7 +2,6 @@ package client
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"sync/atomic"
|
||||
)
|
||||
@@ -46,8 +45,11 @@ func (d *drainingReadCloser) Read(p []byte) (n int, err error) {
|
||||
func (d *drainingReadCloser) Close() error {
|
||||
// drain buffer
|
||||
if atomic.LoadUint32(&d.seenEOF) != 1 {
|
||||
//#nosec
|
||||
io.Copy(ioutil.Discard, d.rdr)
|
||||
// If the reader side (a HTTP server) is misbehaving, it still may send
|
||||
// some bytes, but the closer ignores them to keep the underling
|
||||
// connection open.
|
||||
//nolint:errcheck
|
||||
io.Copy(io.Discard, d.rdr)
|
||||
}
|
||||
return d.rdr.Close()
|
||||
}
|
||||
|
||||
207
vendor/github.com/go-openapi/runtime/client/opentelemetry.go
generated
vendored
Normal file
207
vendor/github.com/go-openapi/runtime/client/opentelemetry.go
generated
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/runtime"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.12.0"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
instrumentationVersion = "1.0.0"
|
||||
tracerName = "go-openapi"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
Tracer trace.Tracer
|
||||
Propagator propagation.TextMapPropagator
|
||||
SpanStartOptions []trace.SpanStartOption
|
||||
SpanNameFormatter func(*runtime.ClientOperation) string
|
||||
TracerProvider trace.TracerProvider
|
||||
}
|
||||
|
||||
type OpenTelemetryOpt interface {
|
||||
apply(*config)
|
||||
}
|
||||
|
||||
type optionFunc func(*config)
|
||||
|
||||
func (o optionFunc) apply(c *config) {
|
||||
o(c)
|
||||
}
|
||||
|
||||
// WithTracerProvider specifies a tracer provider to use for creating a tracer.
|
||||
// If none is specified, the global provider is used.
|
||||
func WithTracerProvider(provider trace.TracerProvider) OpenTelemetryOpt {
|
||||
return optionFunc(func(c *config) {
|
||||
if provider != nil {
|
||||
c.TracerProvider = provider
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// WithPropagators configures specific propagators. If this
|
||||
// option isn't specified, then the global TextMapPropagator is used.
|
||||
func WithPropagators(ps propagation.TextMapPropagator) OpenTelemetryOpt {
|
||||
return optionFunc(func(c *config) {
|
||||
if ps != nil {
|
||||
c.Propagator = ps
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// WithSpanOptions configures an additional set of
|
||||
// trace.SpanOptions, which are applied to each new span.
|
||||
func WithSpanOptions(opts ...trace.SpanStartOption) OpenTelemetryOpt {
|
||||
return optionFunc(func(c *config) {
|
||||
c.SpanStartOptions = append(c.SpanStartOptions, opts...)
|
||||
})
|
||||
}
|
||||
|
||||
// WithSpanNameFormatter takes a function that will be called on every
|
||||
// request and the returned string will become the Span Name.
|
||||
func WithSpanNameFormatter(f func(op *runtime.ClientOperation) string) OpenTelemetryOpt {
|
||||
return optionFunc(func(c *config) {
|
||||
c.SpanNameFormatter = f
|
||||
})
|
||||
}
|
||||
|
||||
func defaultTransportFormatter(op *runtime.ClientOperation) string {
|
||||
if op.ID != "" {
|
||||
return op.ID
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s_%s", strings.ToLower(op.Method), op.PathPattern)
|
||||
}
|
||||
|
||||
type openTelemetryTransport struct {
|
||||
transport runtime.ClientTransport
|
||||
host string
|
||||
tracer trace.Tracer
|
||||
config *config
|
||||
}
|
||||
|
||||
func newOpenTelemetryTransport(transport runtime.ClientTransport, host string, opts []OpenTelemetryOpt) *openTelemetryTransport {
|
||||
tr := &openTelemetryTransport{
|
||||
transport: transport,
|
||||
host: host,
|
||||
}
|
||||
|
||||
defaultOpts := []OpenTelemetryOpt{
|
||||
WithSpanOptions(trace.WithSpanKind(trace.SpanKindClient)),
|
||||
WithSpanNameFormatter(defaultTransportFormatter),
|
||||
WithPropagators(otel.GetTextMapPropagator()),
|
||||
WithTracerProvider(otel.GetTracerProvider()),
|
||||
}
|
||||
|
||||
c := newConfig(append(defaultOpts, opts...)...)
|
||||
tr.config = c
|
||||
|
||||
return tr
|
||||
}
|
||||
|
||||
func (t *openTelemetryTransport) Submit(op *runtime.ClientOperation) (interface{}, error) {
|
||||
if op.Context == nil {
|
||||
return t.transport.Submit(op)
|
||||
}
|
||||
|
||||
params := op.Params
|
||||
reader := op.Reader
|
||||
|
||||
var span trace.Span
|
||||
defer func() {
|
||||
if span != nil {
|
||||
span.End()
|
||||
}
|
||||
}()
|
||||
|
||||
op.Params = runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
|
||||
span = t.newOpenTelemetrySpan(op, req.GetHeaderParams())
|
||||
return params.WriteToRequest(req, reg)
|
||||
})
|
||||
|
||||
op.Reader = runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
|
||||
if span != nil {
|
||||
statusCode := response.Code()
|
||||
span.SetAttributes(attribute.Int(string(semconv.HTTPStatusCodeKey), statusCode))
|
||||
span.SetStatus(semconv.SpanStatusFromHTTPStatusCodeAndSpanKind(statusCode, trace.SpanKindClient))
|
||||
}
|
||||
|
||||
return reader.ReadResponse(response, consumer)
|
||||
})
|
||||
|
||||
submit, err := t.transport.Submit(op)
|
||||
if err != nil && span != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
}
|
||||
|
||||
return submit, err
|
||||
}
|
||||
|
||||
func (t *openTelemetryTransport) newOpenTelemetrySpan(op *runtime.ClientOperation, header http.Header) trace.Span {
|
||||
ctx := op.Context
|
||||
|
||||
tracer := t.tracer
|
||||
if tracer == nil {
|
||||
if span := trace.SpanFromContext(ctx); span.SpanContext().IsValid() {
|
||||
tracer = newTracer(span.TracerProvider())
|
||||
} else {
|
||||
tracer = newTracer(otel.GetTracerProvider())
|
||||
}
|
||||
}
|
||||
|
||||
ctx, span := tracer.Start(ctx, t.config.SpanNameFormatter(op), t.config.SpanStartOptions...)
|
||||
|
||||
var scheme string
|
||||
if len(op.Schemes) > 0 {
|
||||
scheme = op.Schemes[0]
|
||||
}
|
||||
|
||||
span.SetAttributes(
|
||||
attribute.String("net.peer.name", t.host),
|
||||
attribute.String(string(semconv.HTTPRouteKey), op.PathPattern),
|
||||
attribute.String(string(semconv.HTTPMethodKey), op.Method),
|
||||
attribute.String("span.kind", trace.SpanKindClient.String()),
|
||||
attribute.String("http.scheme", scheme),
|
||||
)
|
||||
|
||||
carrier := propagation.HeaderCarrier(header)
|
||||
t.config.Propagator.Inject(ctx, carrier)
|
||||
|
||||
return span
|
||||
}
|
||||
|
||||
func newTracer(tp trace.TracerProvider) trace.Tracer {
|
||||
return tp.Tracer(tracerName, trace.WithInstrumentationVersion(version()))
|
||||
}
|
||||
|
||||
func newConfig(opts ...OpenTelemetryOpt) *config {
|
||||
c := &config{
|
||||
Propagator: otel.GetTextMapPropagator(),
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt.apply(c)
|
||||
}
|
||||
|
||||
// Tracer is only initialized if manually specified. Otherwise, can be passed with the tracing context.
|
||||
if c.TracerProvider != nil {
|
||||
c.Tracer = newTracer(c.TracerProvider)
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// Version is the current release version of the go-runtime instrumentation.
|
||||
func version() string {
|
||||
return instrumentationVersion
|
||||
}
|
||||
99
vendor/github.com/go-openapi/runtime/client/opentracing.go
generated
vendored
Normal file
99
vendor/github.com/go-openapi/runtime/client/opentracing.go
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
"github.com/opentracing/opentracing-go/ext"
|
||||
"github.com/opentracing/opentracing-go/log"
|
||||
|
||||
"github.com/go-openapi/runtime"
|
||||
)
|
||||
|
||||
type tracingTransport struct {
|
||||
transport runtime.ClientTransport
|
||||
host string
|
||||
opts []opentracing.StartSpanOption
|
||||
}
|
||||
|
||||
func newOpenTracingTransport(transport runtime.ClientTransport, host string, opts []opentracing.StartSpanOption,
|
||||
) runtime.ClientTransport {
|
||||
return &tracingTransport{
|
||||
transport: transport,
|
||||
host: host,
|
||||
opts: opts,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *tracingTransport) Submit(op *runtime.ClientOperation) (interface{}, error) {
|
||||
if op.Context == nil {
|
||||
return t.transport.Submit(op)
|
||||
}
|
||||
|
||||
params := op.Params
|
||||
reader := op.Reader
|
||||
|
||||
var span opentracing.Span
|
||||
defer func() {
|
||||
if span != nil {
|
||||
span.Finish()
|
||||
}
|
||||
}()
|
||||
|
||||
op.Params = runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
|
||||
span = createClientSpan(op, req.GetHeaderParams(), t.host, t.opts)
|
||||
return params.WriteToRequest(req, reg)
|
||||
})
|
||||
|
||||
op.Reader = runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
|
||||
if span != nil {
|
||||
code := response.Code()
|
||||
ext.HTTPStatusCode.Set(span, uint16(code))
|
||||
if code >= 400 {
|
||||
ext.Error.Set(span, true)
|
||||
}
|
||||
}
|
||||
return reader.ReadResponse(response, consumer)
|
||||
})
|
||||
|
||||
submit, err := t.transport.Submit(op)
|
||||
if err != nil && span != nil {
|
||||
ext.Error.Set(span, true)
|
||||
span.LogFields(log.Error(err))
|
||||
}
|
||||
return submit, err
|
||||
}
|
||||
|
||||
func createClientSpan(op *runtime.ClientOperation, header http.Header, host string,
|
||||
opts []opentracing.StartSpanOption) opentracing.Span {
|
||||
ctx := op.Context
|
||||
span := opentracing.SpanFromContext(ctx)
|
||||
|
||||
if span != nil {
|
||||
opts = append(opts, ext.SpanKindRPCClient)
|
||||
span, _ = opentracing.StartSpanFromContextWithTracer(
|
||||
ctx, span.Tracer(), operationName(op), opts...)
|
||||
|
||||
ext.Component.Set(span, "go-openapi")
|
||||
ext.PeerHostname.Set(span, host)
|
||||
span.SetTag("http.path", op.PathPattern)
|
||||
ext.HTTPMethod.Set(span, op.Method)
|
||||
|
||||
_ = span.Tracer().Inject(
|
||||
span.Context(),
|
||||
opentracing.HTTPHeaders,
|
||||
opentracing.HTTPHeadersCarrier(header))
|
||||
|
||||
return span
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func operationName(op *runtime.ClientOperation) string {
|
||||
if op.ID != "" {
|
||||
return op.ID
|
||||
}
|
||||
return fmt.Sprintf("%s_%s", op.Method, op.PathPattern)
|
||||
}
|
||||
81
vendor/github.com/go-openapi/runtime/client/request.go
generated
vendored
81
vendor/github.com/go-openapi/runtime/client/request.go
generated
vendored
@@ -93,6 +93,15 @@ func (r *request) BuildHTTP(mediaType, basePath string, producers map[string]run
|
||||
func escapeQuotes(s string) string {
|
||||
return strings.NewReplacer("\\", "\\\\", `"`, "\\\"").Replace(s)
|
||||
}
|
||||
|
||||
func logClose(err error, pw *io.PipeWriter) {
|
||||
log.Println(err)
|
||||
closeErr := pw.CloseWithError(err)
|
||||
if closeErr != nil {
|
||||
log.Println(closeErr)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *request) buildHTTP(mediaType, basePath string, producers map[string]runtime.Producer, registry strfmt.Registry, auth runtime.ClientAuthInfoWriter) (*http.Request, error) {
|
||||
// build the data
|
||||
if err := r.writer.WriteToRequest(r, registry); err != nil {
|
||||
@@ -137,8 +146,8 @@ func (r *request) buildHTTP(mediaType, basePath string, producers map[string]run
|
||||
for fn, v := range r.formFields {
|
||||
for _, vi := range v {
|
||||
if err := mp.WriteField(fn, vi); err != nil {
|
||||
pw.CloseWithError(err)
|
||||
log.Println(err)
|
||||
logClose(err, pw)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,18 +161,15 @@ func (r *request) buildHTTP(mediaType, basePath string, producers map[string]run
|
||||
}()
|
||||
for fn, f := range r.fileFields {
|
||||
for _, fi := range f {
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
|
||||
// Need to read the data so that we can detect the content type
|
||||
_, err := io.Copy(buf, fi)
|
||||
buf := make([]byte, 512)
|
||||
size, err := fi.Read(buf)
|
||||
if err != nil {
|
||||
_ = pw.CloseWithError(err)
|
||||
log.Println(err)
|
||||
logClose(err, pw)
|
||||
return
|
||||
}
|
||||
fileBytes := buf.Bytes()
|
||||
fileContentType := http.DetectContentType(fileBytes)
|
||||
|
||||
newFi := runtime.NamedReader(fi.Name(), buf)
|
||||
fileContentType := http.DetectContentType(buf)
|
||||
newFi := runtime.NamedReader(fi.Name(), io.MultiReader(bytes.NewReader(buf[:size]), fi))
|
||||
|
||||
// Create the MIME headers for the new part
|
||||
h := make(textproto.MIMEHeader)
|
||||
@@ -174,11 +180,11 @@ func (r *request) buildHTTP(mediaType, basePath string, producers map[string]run
|
||||
|
||||
wrtr, err := mp.CreatePart(h)
|
||||
if err != nil {
|
||||
pw.CloseWithError(err)
|
||||
log.Println(err)
|
||||
} else if _, err := io.Copy(wrtr, newFi); err != nil {
|
||||
pw.CloseWithError(err)
|
||||
log.Println(err)
|
||||
logClose(err, pw)
|
||||
return
|
||||
}
|
||||
if _, err := io.Copy(wrtr, newFi); err != nil {
|
||||
logClose(err, pw)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,7 +217,7 @@ func (r *request) buildHTTP(mediaType, basePath string, producers map[string]run
|
||||
|
||||
DoneChoosingBodySource:
|
||||
|
||||
if runtime.CanHaveBody(r.method) && body == nil && r.header.Get(runtime.HeaderContentType) == "" {
|
||||
if runtime.CanHaveBody(r.method) && body != nil && r.header.Get(runtime.HeaderContentType) == "" {
|
||||
r.header.Set(runtime.HeaderContentType, mediaType)
|
||||
}
|
||||
|
||||
@@ -273,12 +279,36 @@ DoneChoosingBodySource:
|
||||
}
|
||||
}
|
||||
|
||||
// In case the basePath or the request pathPattern include static query parameters,
|
||||
// parse those out before constructing the final path. The parameters themselves
|
||||
// will be merged with the ones set by the client, with the priority given first to
|
||||
// the ones set by the client, then the path pattern, and lastly the base path.
|
||||
basePathURL, err := url.Parse(basePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
staticQueryParams := basePathURL.Query()
|
||||
|
||||
pathPatternURL, err := url.Parse(r.pathPattern)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for name, values := range pathPatternURL.Query() {
|
||||
if _, present := staticQueryParams[name]; present {
|
||||
staticQueryParams.Del(name)
|
||||
}
|
||||
for _, value := range values {
|
||||
staticQueryParams.Add(name, value)
|
||||
}
|
||||
}
|
||||
|
||||
// create http request
|
||||
var reinstateSlash bool
|
||||
if r.pathPattern != "" && r.pathPattern != "/" && r.pathPattern[len(r.pathPattern)-1] == '/' {
|
||||
if pathPatternURL.Path != "" && pathPatternURL.Path != "/" && pathPatternURL.Path[len(pathPatternURL.Path)-1] == '/' {
|
||||
reinstateSlash = true
|
||||
}
|
||||
urlPath := path.Join(basePath, r.pathPattern)
|
||||
|
||||
urlPath := path.Join(basePathURL.Path, pathPatternURL.Path)
|
||||
for k, v := range r.pathParams {
|
||||
urlPath = strings.Replace(urlPath, "{"+k+"}", url.PathEscape(v), -1)
|
||||
}
|
||||
@@ -291,6 +321,19 @@ DoneChoosingBodySource:
|
||||
return nil, err
|
||||
}
|
||||
|
||||
originalParams := r.GetQueryParams()
|
||||
|
||||
// Merge the query parameters extracted from the basePath with the ones set by
|
||||
// the client in this struct. In case of conflict, the client wins.
|
||||
for k, v := range staticQueryParams {
|
||||
_, present := originalParams[k]
|
||||
if !present {
|
||||
if err = r.SetQueryParam(k, v...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
req.URL.RawQuery = r.query.Encode()
|
||||
req.Header = r.header
|
||||
|
||||
|
||||
6
vendor/github.com/go-openapi/runtime/client/response.go
generated
vendored
6
vendor/github.com/go-openapi/runtime/client/response.go
generated
vendored
@@ -23,6 +23,8 @@ import (
|
||||
|
||||
var _ runtime.ClientResponse = response{}
|
||||
|
||||
func newResponse(resp *http.Response) runtime.ClientResponse { return response{resp: resp} }
|
||||
|
||||
type response struct {
|
||||
resp *http.Response
|
||||
}
|
||||
@@ -39,6 +41,10 @@ func (r response) GetHeader(name string) string {
|
||||
return r.resp.Header.Get(name)
|
||||
}
|
||||
|
||||
func (r response) GetHeaders(name string) []string {
|
||||
return r.resp.Header.Values(name)
|
||||
}
|
||||
|
||||
func (r response) Body() io.ReadCloser {
|
||||
return r.resp.Body
|
||||
}
|
||||
|
||||
104
vendor/github.com/go-openapi/runtime/client/runtime.go
generated
vendored
104
vendor/github.com/go-openapi/runtime/client/runtime.go
generated
vendored
@@ -23,19 +23,21 @@ import (
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"mime"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
|
||||
"github.com/go-openapi/runtime"
|
||||
"github.com/go-openapi/runtime/logger"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/go-openapi/runtime/yamlpc"
|
||||
"github.com/go-openapi/strfmt"
|
||||
)
|
||||
|
||||
// TLSClientOptions to configure client authentication with mutual TLS
|
||||
@@ -80,7 +82,7 @@ type TLSClientOptions struct {
|
||||
ServerName string
|
||||
|
||||
// InsecureSkipVerify controls whether the certificate chain and hostname presented
|
||||
// by the server are validated. If false, any certificate is accepted.
|
||||
// by the server are validated. If true, any certificate is accepted.
|
||||
InsecureSkipVerify bool
|
||||
|
||||
// VerifyPeerCertificate, if not nil, is called after normal
|
||||
@@ -162,7 +164,7 @@ func TLSClientAuth(opts TLSClientOptions) (*tls.Config, error) {
|
||||
cfg.RootCAs = caCertPool
|
||||
} else if opts.CA != "" {
|
||||
// load ca cert
|
||||
caCert, err := ioutil.ReadFile(opts.CA)
|
||||
caCert, err := os.ReadFile(opts.CA)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tls client ca: %v", err)
|
||||
}
|
||||
@@ -179,8 +181,6 @@ func TLSClientAuth(opts TLSClientOptions) (*tls.Config, error) {
|
||||
cfg.ServerName = opts.ServerName
|
||||
}
|
||||
|
||||
cfg.BuildNameToCertificate()
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ type Runtime struct {
|
||||
|
||||
Transport http.RoundTripper
|
||||
Jar http.CookieJar
|
||||
//Spec *spec.Document
|
||||
// Spec *spec.Document
|
||||
Host string
|
||||
BasePath string
|
||||
Formats strfmt.Registry
|
||||
@@ -235,6 +235,7 @@ type Runtime struct {
|
||||
clientOnce *sync.Once
|
||||
client *http.Client
|
||||
schemes []string
|
||||
response ClientResponseFunc
|
||||
}
|
||||
|
||||
// New creates a new default runtime for a swagger api runtime.Client
|
||||
@@ -244,6 +245,7 @@ func New(host, basePath string, schemes []string) *Runtime {
|
||||
|
||||
// TODO: actually infer this stuff from the spec
|
||||
rt.Consumers = map[string]runtime.Consumer{
|
||||
runtime.YAMLMime: yamlpc.YAMLConsumer(),
|
||||
runtime.JSONMime: runtime.JSONConsumer(),
|
||||
runtime.XMLMime: runtime.XMLConsumer(),
|
||||
runtime.TextMime: runtime.TextConsumer(),
|
||||
@@ -252,6 +254,7 @@ func New(host, basePath string, schemes []string) *Runtime {
|
||||
runtime.DefaultMime: runtime.ByteStreamConsumer(),
|
||||
}
|
||||
rt.Producers = map[string]runtime.Producer{
|
||||
runtime.YAMLMime: yamlpc.YAMLProducer(),
|
||||
runtime.JSONMime: runtime.JSONProducer(),
|
||||
runtime.XMLMime: runtime.XMLProducer(),
|
||||
runtime.TextMime: runtime.TextProducer(),
|
||||
@@ -271,6 +274,7 @@ func New(host, basePath string, schemes []string) *Runtime {
|
||||
|
||||
rt.Debug = logger.DebugEnabled()
|
||||
rt.logger = logger.StandardLogger{}
|
||||
rt.response = newResponse
|
||||
|
||||
if len(schemes) > 0 {
|
||||
rt.schemes = schemes
|
||||
@@ -289,6 +293,22 @@ func NewWithClient(host, basePath string, schemes []string, client *http.Client)
|
||||
return rt
|
||||
}
|
||||
|
||||
// WithOpenTracing adds opentracing support to the provided runtime.
|
||||
// A new client span is created for each request.
|
||||
// If the context of the client operation does not contain an active span, no span is created.
|
||||
// The provided opts are applied to each spans - for example to add global tags.
|
||||
func (r *Runtime) WithOpenTracing(opts ...opentracing.StartSpanOption) runtime.ClientTransport {
|
||||
return newOpenTracingTransport(r, r.Host, opts)
|
||||
}
|
||||
|
||||
// WithOpenTelemetry adds opentelemetry support to the provided runtime.
|
||||
// A new client span is created for each request.
|
||||
// If the context of the client operation does not contain an active span, no span is created.
|
||||
// The provided opts are applied to each spans - for example to add global tags.
|
||||
func (r *Runtime) WithOpenTelemetry(opts ...OpenTelemetryOpt) runtime.ClientTransport {
|
||||
return newOpenTelemetryTransport(r, r.Host, opts)
|
||||
}
|
||||
|
||||
func (r *Runtime) pickScheme(schemes []string) string {
|
||||
if v := r.selectScheme(r.schemes); v != "" {
|
||||
return v
|
||||
@@ -317,6 +337,7 @@ func (r *Runtime) selectScheme(schemes []string) string {
|
||||
}
|
||||
return scheme
|
||||
}
|
||||
|
||||
func transportOrDefault(left, right http.RoundTripper) http.RoundTripper {
|
||||
if left == nil {
|
||||
return right
|
||||
@@ -346,26 +367,30 @@ func (r *Runtime) EnableConnectionReuse() {
|
||||
)
|
||||
}
|
||||
|
||||
// Submit a request and when there is a body on success it will turn that into the result
|
||||
// all other things are turned into an api error for swagger which retains the status code
|
||||
func (r *Runtime) Submit(operation *runtime.ClientOperation) (interface{}, error) {
|
||||
params, readResponse, auth := operation.Params, operation.Reader, operation.AuthInfo
|
||||
// takes a client operation and creates equivalent http.Request
|
||||
func (r *Runtime) createHttpRequest(operation *runtime.ClientOperation) (*request, *http.Request, error) {
|
||||
params, _, auth := operation.Params, operation.Reader, operation.AuthInfo
|
||||
|
||||
request, err := newRequest(operation.Method, operation.PathPattern, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var accept []string
|
||||
accept = append(accept, operation.ProducesMediaTypes...)
|
||||
if err = request.SetHeaderParam(runtime.HeaderAccept, accept...); err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if auth == nil && r.DefaultAuthentication != nil {
|
||||
auth = r.DefaultAuthentication
|
||||
auth = runtime.ClientAuthInfoWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
|
||||
if req.GetHeaderParams().Get(runtime.HeaderAuthorization) != "" {
|
||||
return nil
|
||||
}
|
||||
return r.DefaultAuthentication.AuthenticateRequest(req, reg)
|
||||
})
|
||||
}
|
||||
//if auth != nil {
|
||||
// if auth != nil {
|
||||
// if err := auth.AuthenticateRequest(request, r.Formats); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
@@ -382,16 +407,33 @@ func (r *Runtime) Submit(operation *runtime.ClientOperation) (interface{}, error
|
||||
}
|
||||
|
||||
if _, ok := r.Producers[cmt]; !ok && cmt != runtime.MultipartFormMime && cmt != runtime.URLencodedFormMime {
|
||||
return nil, fmt.Errorf("none of producers: %v registered. try %s", r.Producers, cmt)
|
||||
return nil, nil, fmt.Errorf("none of producers: %v registered. try %s", r.Producers, cmt)
|
||||
}
|
||||
|
||||
req, err := request.buildHTTP(cmt, r.BasePath, r.Producers, r.Formats, auth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
req.URL.Scheme = r.pickScheme(operation.Schemes)
|
||||
req.URL.Host = r.Host
|
||||
req.Host = r.Host
|
||||
return request, req, nil
|
||||
}
|
||||
|
||||
func (r *Runtime) CreateHttpRequest(operation *runtime.ClientOperation) (req *http.Request, err error) {
|
||||
_, req, err = r.createHttpRequest(operation)
|
||||
return
|
||||
}
|
||||
|
||||
// Submit a request and when there is a body on success it will turn that into the result
|
||||
// all other things are turned into an api error for swagger which retains the status code
|
||||
func (r *Runtime) Submit(operation *runtime.ClientOperation) (interface{}, error) {
|
||||
_, readResponse, _ := operation.Params, operation.Reader, operation.AuthInfo
|
||||
|
||||
request, req, err := r.createHttpRequest(operation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r.clientOnce.Do(func() {
|
||||
r.client = &http.Client{
|
||||
@@ -438,19 +480,23 @@ func (r *Runtime) Submit(operation *runtime.ClientOperation) (interface{}, error
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
ct := res.Header.Get(runtime.HeaderContentType)
|
||||
if ct == "" { // this should really really never occur
|
||||
ct = r.DefaultMediaType
|
||||
}
|
||||
|
||||
if r.Debug {
|
||||
b, err2 := httputil.DumpResponse(res, true)
|
||||
printBody := true
|
||||
if ct == runtime.DefaultMime {
|
||||
printBody = false // Spare the terminal from a binary blob.
|
||||
}
|
||||
b, err2 := httputil.DumpResponse(res, printBody)
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
}
|
||||
r.logger.Debugf("%s\n", string(b))
|
||||
}
|
||||
|
||||
ct := res.Header.Get(runtime.HeaderContentType)
|
||||
if ct == "" { // this should really really never occur
|
||||
ct = r.DefaultMediaType
|
||||
}
|
||||
|
||||
mt, _, err := mime.ParseMediaType(ct)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse content type: %s", err)
|
||||
@@ -463,7 +509,7 @@ func (r *Runtime) Submit(operation *runtime.ClientOperation) (interface{}, error
|
||||
return nil, fmt.Errorf("no consumer: %q", ct)
|
||||
}
|
||||
}
|
||||
return readResponse.ReadResponse(response{res}, cons)
|
||||
return readResponse.ReadResponse(r.response(res), cons)
|
||||
}
|
||||
|
||||
// SetDebug changes the debug flag.
|
||||
@@ -479,3 +525,13 @@ func (r *Runtime) SetLogger(logger logger.Logger) {
|
||||
r.logger = logger
|
||||
middleware.Logger = logger
|
||||
}
|
||||
|
||||
type ClientResponseFunc = func(*http.Response) runtime.ClientResponse
|
||||
|
||||
// SetResponseReader changes the response reader implementation.
|
||||
func (r *Runtime) SetResponseReader(f ClientResponseFunc) {
|
||||
if f == nil {
|
||||
return
|
||||
}
|
||||
r.response = f
|
||||
}
|
||||
|
||||
53
vendor/github.com/go-openapi/runtime/client_request.go
generated
vendored
53
vendor/github.com/go-openapi/runtime/client_request.go
generated
vendored
@@ -16,7 +16,6 @@ package runtime
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
@@ -79,7 +78,7 @@ type NamedReadCloser interface {
|
||||
func NamedReader(name string, rdr io.Reader) NamedReadCloser {
|
||||
rc, ok := rdr.(io.ReadCloser)
|
||||
if !ok {
|
||||
rc = ioutil.NopCloser(rdr)
|
||||
rc = io.NopCloser(rdr)
|
||||
}
|
||||
return &namedReadCloser{
|
||||
name: name,
|
||||
@@ -101,3 +100,53 @@ func (n *namedReadCloser) Read(p []byte) (int, error) {
|
||||
func (n *namedReadCloser) Name() string {
|
||||
return n.name
|
||||
}
|
||||
|
||||
type TestClientRequest struct {
|
||||
Headers http.Header
|
||||
Body interface{}
|
||||
}
|
||||
|
||||
func (t *TestClientRequest) SetHeaderParam(name string, values ...string) error {
|
||||
if t.Headers == nil {
|
||||
t.Headers = make(http.Header)
|
||||
}
|
||||
t.Headers.Set(name, values[0])
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TestClientRequest) SetQueryParam(_ string, _ ...string) error { return nil }
|
||||
|
||||
func (t *TestClientRequest) SetFormParam(_ string, _ ...string) error { return nil }
|
||||
|
||||
func (t *TestClientRequest) SetPathParam(_ string, _ string) error { return nil }
|
||||
|
||||
func (t *TestClientRequest) SetFileParam(_ string, _ ...NamedReadCloser) error { return nil }
|
||||
|
||||
func (t *TestClientRequest) SetBodyParam(body interface{}) error {
|
||||
t.Body = body
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TestClientRequest) SetTimeout(time.Duration) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TestClientRequest) GetQueryParams() url.Values { return nil }
|
||||
|
||||
func (t *TestClientRequest) GetMethod() string { return "" }
|
||||
|
||||
func (t *TestClientRequest) GetPath() string { return "" }
|
||||
|
||||
func (t *TestClientRequest) GetBody() []byte { return nil }
|
||||
|
||||
func (t *TestClientRequest) GetBodyParam() interface{} {
|
||||
return t.Body
|
||||
}
|
||||
|
||||
func (t *TestClientRequest) GetFileParam() map[string][]NamedReadCloser {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TestClientRequest) GetHeaderParams() http.Header {
|
||||
return t.Headers
|
||||
}
|
||||
|
||||
51
vendor/github.com/go-openapi/runtime/client_response.go
generated
vendored
51
vendor/github.com/go-openapi/runtime/client_response.go
generated
vendored
@@ -15,6 +15,7 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
@@ -25,6 +26,7 @@ type ClientResponse interface {
|
||||
Code() int
|
||||
Message() string
|
||||
GetHeader(string) string
|
||||
GetHeaders(string) []string
|
||||
Body() io.ReadCloser
|
||||
}
|
||||
|
||||
@@ -58,6 +60,51 @@ type APIError struct {
|
||||
Code int
|
||||
}
|
||||
|
||||
func (a *APIError) Error() string {
|
||||
return fmt.Sprintf("%s (status %d): %+v ", a.OperationName, a.Code, a.Response)
|
||||
func (o *APIError) Error() string {
|
||||
var resp []byte
|
||||
if err, ok := o.Response.(error); ok {
|
||||
resp = []byte("'" + err.Error() + "'")
|
||||
} else {
|
||||
resp, _ = json.Marshal(o.Response)
|
||||
}
|
||||
return fmt.Sprintf("%s (status %d): %s", o.OperationName, o.Code, resp)
|
||||
}
|
||||
|
||||
func (o *APIError) String() string {
|
||||
return o.Error()
|
||||
}
|
||||
|
||||
// IsSuccess returns true when this elapse o k response returns a 2xx status code
|
||||
func (o *APIError) IsSuccess() bool {
|
||||
return o.Code/100 == 2
|
||||
}
|
||||
|
||||
// IsRedirect returns true when this elapse o k response returns a 3xx status code
|
||||
func (o *APIError) IsRedirect() bool {
|
||||
return o.Code/100 == 3
|
||||
}
|
||||
|
||||
// IsClientError returns true when this elapse o k response returns a 4xx status code
|
||||
func (o *APIError) IsClientError() bool {
|
||||
return o.Code/100 == 4
|
||||
}
|
||||
|
||||
// IsServerError returns true when this elapse o k response returns a 5xx status code
|
||||
func (o *APIError) IsServerError() bool {
|
||||
return o.Code/100 == 5
|
||||
}
|
||||
|
||||
// IsCode returns true when this elapse o k response returns a 4xx status code
|
||||
func (o *APIError) IsCode(code int) bool {
|
||||
return o.Code == code
|
||||
}
|
||||
|
||||
// A ClientResponseStatus is a common interface implemented by all responses on the generated code
|
||||
// You can use this to treat any client response based on status code
|
||||
type ClientResponseStatus interface {
|
||||
IsSuccess() bool
|
||||
IsRedirect() bool
|
||||
IsClientError() bool
|
||||
IsServerError() bool
|
||||
IsCode(int) bool
|
||||
}
|
||||
|
||||
2
vendor/github.com/go-openapi/runtime/constants.go
generated
vendored
2
vendor/github.com/go-openapi/runtime/constants.go
generated
vendored
@@ -23,6 +23,8 @@ const (
|
||||
|
||||
// HeaderAccept the Accept header
|
||||
HeaderAccept = "Accept"
|
||||
// HeaderAuthorization the Authorization header
|
||||
HeaderAuthorization = "Authorization"
|
||||
|
||||
charsetKey = "charset"
|
||||
|
||||
|
||||
18
vendor/github.com/go-openapi/runtime/file.go
generated
vendored
18
vendor/github.com/go-openapi/runtime/file.go
generated
vendored
@@ -14,20 +14,6 @@
|
||||
|
||||
package runtime
|
||||
|
||||
import "mime/multipart"
|
||||
import "github.com/go-openapi/swag"
|
||||
|
||||
// File represents an uploaded file.
|
||||
type File struct {
|
||||
Data multipart.File
|
||||
Header *multipart.FileHeader
|
||||
}
|
||||
|
||||
// Read bytes from the file
|
||||
func (f *File) Read(p []byte) (n int, err error) {
|
||||
return f.Data.Read(p)
|
||||
}
|
||||
|
||||
// Close the file
|
||||
func (f *File) Close() error {
|
||||
return f.Data.Close()
|
||||
}
|
||||
type File = swag.File
|
||||
|
||||
9
vendor/github.com/go-openapi/runtime/interfaces.go
generated
vendored
9
vendor/github.com/go-openapi/runtime/interfaces.go
generated
vendored
@@ -15,6 +15,7 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
@@ -101,3 +102,11 @@ type Authorizer interface {
|
||||
type Validatable interface {
|
||||
Validate(strfmt.Registry) error
|
||||
}
|
||||
|
||||
// ContextValidatable types implementing this interface allow customizing their validation
|
||||
// this will be used instead of the reflective validation based on the spec document.
|
||||
// the implementations are assumed to have been generated by the swagger tool so they should
|
||||
// contain all the context validations obtained from the spec
|
||||
type ContextValidatable interface {
|
||||
ContextValidate(context.Context, strfmt.Registry) error
|
||||
}
|
||||
|
||||
39
vendor/github.com/go-openapi/runtime/middleware/context.go
generated
vendored
39
vendor/github.com/go-openapi/runtime/middleware/context.go
generated
vendored
@@ -195,6 +195,17 @@ func NewRoutableContext(spec *loads.Document, routableAPI RoutableAPI, routes Ro
|
||||
if spec != nil {
|
||||
an = analysis.New(spec.Spec())
|
||||
}
|
||||
|
||||
return NewRoutableContextWithAnalyzedSpec(spec, an, routableAPI, routes)
|
||||
}
|
||||
|
||||
// NewRoutableContextWithAnalyzedSpec is like NewRoutableContext but takes in input the analysed spec too
|
||||
func NewRoutableContextWithAnalyzedSpec(spec *loads.Document, an *analysis.Spec, routableAPI RoutableAPI, routes Router) *Context {
|
||||
// Either there are no spec doc and analysis, or both of them.
|
||||
if !((spec == nil && an == nil) || (spec != nil && an != nil)) {
|
||||
panic(errors.New(http.StatusInternalServerError, "routable context requires either both spec doc and analysis, or none of them"))
|
||||
}
|
||||
|
||||
ctx := &Context{spec: spec, api: routableAPI, analyzer: an, router: routes}
|
||||
return ctx
|
||||
}
|
||||
@@ -435,6 +446,10 @@ func (c *Context) Authorize(request *http.Request, route *MatchedRoute) (interfa
|
||||
}
|
||||
if route.Authorizer != nil {
|
||||
if err := route.Authorizer.Authorize(request, usr); err != nil {
|
||||
if _, ok := err.(errors.Error); ok {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return nil, nil, errors.New(http.StatusForbidden, err.Error())
|
||||
}
|
||||
}
|
||||
@@ -494,7 +509,9 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
|
||||
|
||||
if resp, ok := data.(Responder); ok {
|
||||
producers := route.Producers
|
||||
prod, ok := producers[format]
|
||||
// producers contains keys with normalized format, if a format has MIME type parameter such as `text/plain; charset=utf-8`
|
||||
// then you must provide `text/plain` to get the correct producer. HOWEVER, format here is not normalized.
|
||||
prod, ok := producers[normalizeOffer(format)]
|
||||
if !ok {
|
||||
prods := c.api.ProducersFor(normalizeOffers([]string{c.api.DefaultProduces()}))
|
||||
pr, ok := prods[c.api.DefaultProduces()]
|
||||
@@ -567,6 +584,26 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
|
||||
c.api.ServeErrorFor(route.Operation.ID)(rw, r, errors.New(http.StatusInternalServerError, "can't produce response"))
|
||||
}
|
||||
|
||||
func (c *Context) APIHandlerSwaggerUI(builder Builder) http.Handler {
|
||||
b := builder
|
||||
if b == nil {
|
||||
b = PassthroughBuilder
|
||||
}
|
||||
|
||||
var title string
|
||||
sp := c.spec.Spec()
|
||||
if sp != nil && sp.Info != nil && sp.Info.Title != "" {
|
||||
title = sp.Info.Title
|
||||
}
|
||||
|
||||
swaggerUIOpts := SwaggerUIOpts{
|
||||
BasePath: c.BasePath(),
|
||||
Title: title,
|
||||
}
|
||||
|
||||
return Spec("", c.spec.Raw(), SwaggerUI(swaggerUIOpts, c.RoutesHandler(b)))
|
||||
}
|
||||
|
||||
// APIHandler returns a handler to serve the API, this includes a swagger spec, router and the contract defined in the swagger spec
|
||||
func (c *Context) APIHandler(builder Builder) http.Handler {
|
||||
b := builder
|
||||
|
||||
6
vendor/github.com/go-openapi/runtime/middleware/denco/router.go
generated
vendored
6
vendor/github.com/go-openapi/runtime/middleware/denco/router.go
generated
vendored
@@ -20,6 +20,9 @@ const (
|
||||
// SeparatorCharacter separates path segments.
|
||||
SeparatorCharacter = '/'
|
||||
|
||||
// PathParamCharacter indicates a RESTCONF path param
|
||||
PathParamCharacter = '='
|
||||
|
||||
// MaxSize is max size of records and internal slice.
|
||||
MaxSize = (1 << 22) - 1
|
||||
)
|
||||
@@ -426,8 +429,9 @@ func makeRecords(srcs []Record) (statics, params []*record) {
|
||||
termChar := string(TerminationCharacter)
|
||||
paramPrefix := string(SeparatorCharacter) + string(ParamCharacter)
|
||||
wildcardPrefix := string(SeparatorCharacter) + string(WildcardCharacter)
|
||||
restconfPrefix := string(PathParamCharacter) + string(ParamCharacter)
|
||||
for _, r := range srcs {
|
||||
if strings.Contains(r.Key, paramPrefix) || strings.Contains(r.Key, wildcardPrefix) {
|
||||
if strings.Contains(r.Key, paramPrefix) || strings.Contains(r.Key, wildcardPrefix) ||strings.Contains(r.Key, restconfPrefix){
|
||||
r.Key += termChar
|
||||
params = append(params, &record{Record: r})
|
||||
} else {
|
||||
|
||||
7
vendor/github.com/go-openapi/runtime/middleware/header/header.go
generated
vendored
7
vendor/github.com/go-openapi/runtime/middleware/header/header.go
generated
vendored
@@ -265,13 +265,16 @@ func expectQuality(s string) (q float64, rest string) {
|
||||
case len(s) == 0:
|
||||
return -1, ""
|
||||
case s[0] == '0':
|
||||
q = 0
|
||||
// q is already 0
|
||||
s = s[1:]
|
||||
case s[0] == '1':
|
||||
s = s[1:]
|
||||
q = 1
|
||||
case s[0] == '.':
|
||||
// q is already 0
|
||||
default:
|
||||
return -1, ""
|
||||
}
|
||||
s = s[1:]
|
||||
if !strings.HasPrefix(s, ".") {
|
||||
return q, s
|
||||
}
|
||||
|
||||
10
vendor/github.com/go-openapi/runtime/middleware/parameter.go
generated
vendored
10
vendor/github.com/go-openapi/runtime/middleware/parameter.go
generated
vendored
@@ -206,7 +206,11 @@ func (p *untypedParamBinder) Bind(request *http.Request, routeParams RouteParams
|
||||
if p.parameter.Type == "file" {
|
||||
file, header, ffErr := request.FormFile(p.parameter.Name)
|
||||
if ffErr != nil {
|
||||
return errors.NewParseError(p.Name, p.parameter.In, "", ffErr)
|
||||
if p.parameter.Required {
|
||||
return errors.NewParseError(p.Name, p.parameter.In, "", ffErr)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
target.Set(reflect.ValueOf(runtime.File{Data: file, Header: header}))
|
||||
return nil
|
||||
@@ -276,7 +280,7 @@ func (p *untypedParamBinder) setFieldValue(target reflect.Value, defaultValue in
|
||||
}
|
||||
|
||||
if (!hasKey || (!p.parameter.AllowEmptyValue && data == "")) && p.parameter.Required && p.parameter.Default == nil {
|
||||
return errors.Required(p.Name, p.parameter.In)
|
||||
return errors.Required(p.Name, p.parameter.In, data)
|
||||
}
|
||||
|
||||
ok, err := p.tryUnmarshaler(target, defaultValue, data)
|
||||
@@ -451,7 +455,7 @@ func (p *untypedParamBinder) readFormattedSliceFieldValue(data string, target re
|
||||
func (p *untypedParamBinder) setSliceFieldValue(target reflect.Value, defaultValue interface{}, data []string, hasKey bool) error {
|
||||
sz := len(data)
|
||||
if (!hasKey || (!p.parameter.AllowEmptyValue && (sz == 0 || (sz == 1 && data[0] == "")))) && p.parameter.Required && defaultValue == nil {
|
||||
return errors.Required(p.Name, p.parameter.In)
|
||||
return errors.Required(p.Name, p.parameter.In, data)
|
||||
}
|
||||
|
||||
defVal := reflect.Zero(target.Type())
|
||||
|
||||
90
vendor/github.com/go-openapi/runtime/middleware/rapidoc.go
generated
vendored
Normal file
90
vendor/github.com/go-openapi/runtime/middleware/rapidoc.go
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"path"
|
||||
)
|
||||
|
||||
// RapiDocOpts configures the RapiDoc middlewares
|
||||
type RapiDocOpts struct {
|
||||
// BasePath for the UI path, defaults to: /
|
||||
BasePath string
|
||||
// Path combines with BasePath for the full UI path, defaults to: docs
|
||||
Path string
|
||||
// SpecURL the url to find the spec for
|
||||
SpecURL string
|
||||
// RapiDocURL for the js that generates the rapidoc site, defaults to: https://cdn.jsdelivr.net/npm/rapidoc/bundles/rapidoc.standalone.js
|
||||
RapiDocURL string
|
||||
// Title for the documentation site, default to: API documentation
|
||||
Title string
|
||||
}
|
||||
|
||||
// EnsureDefaults in case some options are missing
|
||||
func (r *RapiDocOpts) EnsureDefaults() {
|
||||
if r.BasePath == "" {
|
||||
r.BasePath = "/"
|
||||
}
|
||||
if r.Path == "" {
|
||||
r.Path = "docs"
|
||||
}
|
||||
if r.SpecURL == "" {
|
||||
r.SpecURL = "/swagger.json"
|
||||
}
|
||||
if r.RapiDocURL == "" {
|
||||
r.RapiDocURL = rapidocLatest
|
||||
}
|
||||
if r.Title == "" {
|
||||
r.Title = "API documentation"
|
||||
}
|
||||
}
|
||||
|
||||
// RapiDoc creates a middleware to serve a documentation site for a swagger spec.
|
||||
// This allows for altering the spec before starting the http listener.
|
||||
//
|
||||
func RapiDoc(opts RapiDocOpts, next http.Handler) http.Handler {
|
||||
opts.EnsureDefaults()
|
||||
|
||||
pth := path.Join(opts.BasePath, opts.Path)
|
||||
tmpl := template.Must(template.New("rapidoc").Parse(rapidocTemplate))
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
_ = tmpl.Execute(buf, opts)
|
||||
b := buf.Bytes()
|
||||
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path == pth {
|
||||
rw.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
|
||||
_, _ = rw.Write(b)
|
||||
return
|
||||
}
|
||||
|
||||
if next == nil {
|
||||
rw.Header().Set("Content-Type", "text/plain")
|
||||
rw.WriteHeader(http.StatusNotFound)
|
||||
_, _ = rw.Write([]byte(fmt.Sprintf("%q not found", pth)))
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(rw, r)
|
||||
})
|
||||
}
|
||||
|
||||
const (
|
||||
rapidocLatest = "https://unpkg.com/rapidoc/dist/rapidoc-min.js"
|
||||
rapidocTemplate = `<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ .Title }}</title>
|
||||
<meta charset="utf-8"> <!-- Important: rapi-doc uses utf8 charecters -->
|
||||
<script type="module" src="{{ .RapiDocURL }}"></script>
|
||||
</head>
|
||||
<body>
|
||||
<rapi-doc spec-url="{{ .SpecURL }}"></rapi-doc>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
)
|
||||
10
vendor/github.com/go-openapi/runtime/middleware/router.go
generated
vendored
10
vendor/github.com/go-openapi/runtime/middleware/router.go
generated
vendored
@@ -22,6 +22,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/runtime/security"
|
||||
"github.com/go-openapi/swag"
|
||||
|
||||
"github.com/go-openapi/analysis"
|
||||
"github.com/go-openapi/errors"
|
||||
@@ -418,6 +419,15 @@ func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Oper
|
||||
produces := d.analyzer.ProducesFor(operation)
|
||||
parameters := d.analyzer.ParamsFor(method, strings.TrimPrefix(path, bp))
|
||||
|
||||
// add API defaults if not part of the spec
|
||||
if defConsumes := d.api.DefaultConsumes(); defConsumes != "" && !swag.ContainsStringsCI(consumes, defConsumes) {
|
||||
consumes = append(consumes, defConsumes)
|
||||
}
|
||||
|
||||
if defProduces := d.api.DefaultProduces(); defProduces != "" && !swag.ContainsStringsCI(produces, defProduces) {
|
||||
produces = append(produces, defProduces)
|
||||
}
|
||||
|
||||
record := denco.NewRecord(pathConverter.ReplaceAllString(path, ":$1"), &routeEntry{
|
||||
BasePath: bp,
|
||||
PathPattern: path,
|
||||
|
||||
168
vendor/github.com/go-openapi/runtime/middleware/swaggerui.go
generated
vendored
Normal file
168
vendor/github.com/go-openapi/runtime/middleware/swaggerui.go
generated
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"path"
|
||||
)
|
||||
|
||||
// SwaggerUIOpts configures the Swaggerui middlewares
|
||||
type SwaggerUIOpts struct {
|
||||
// BasePath for the UI path, defaults to: /
|
||||
BasePath string
|
||||
// Path combines with BasePath for the full UI path, defaults to: docs
|
||||
Path string
|
||||
// SpecURL the url to find the spec for
|
||||
SpecURL string
|
||||
// OAuthCallbackURL the url called after OAuth2 login
|
||||
OAuthCallbackURL string
|
||||
|
||||
// The three components needed to embed swagger-ui
|
||||
SwaggerURL string
|
||||
SwaggerPresetURL string
|
||||
SwaggerStylesURL string
|
||||
|
||||
Favicon32 string
|
||||
Favicon16 string
|
||||
|
||||
// Title for the documentation site, default to: API documentation
|
||||
Title string
|
||||
}
|
||||
|
||||
// EnsureDefaults in case some options are missing
|
||||
func (r *SwaggerUIOpts) EnsureDefaults() {
|
||||
if r.BasePath == "" {
|
||||
r.BasePath = "/"
|
||||
}
|
||||
if r.Path == "" {
|
||||
r.Path = "docs"
|
||||
}
|
||||
if r.SpecURL == "" {
|
||||
r.SpecURL = "/swagger.json"
|
||||
}
|
||||
if r.OAuthCallbackURL == "" {
|
||||
r.OAuthCallbackURL = path.Join(r.BasePath, r.Path, "oauth2-callback")
|
||||
}
|
||||
if r.SwaggerURL == "" {
|
||||
r.SwaggerURL = swaggerLatest
|
||||
}
|
||||
if r.SwaggerPresetURL == "" {
|
||||
r.SwaggerPresetURL = swaggerPresetLatest
|
||||
}
|
||||
if r.SwaggerStylesURL == "" {
|
||||
r.SwaggerStylesURL = swaggerStylesLatest
|
||||
}
|
||||
if r.Favicon16 == "" {
|
||||
r.Favicon16 = swaggerFavicon16Latest
|
||||
}
|
||||
if r.Favicon32 == "" {
|
||||
r.Favicon32 = swaggerFavicon32Latest
|
||||
}
|
||||
if r.Title == "" {
|
||||
r.Title = "API documentation"
|
||||
}
|
||||
}
|
||||
|
||||
// SwaggerUI creates a middleware to serve a documentation site for a swagger spec.
|
||||
// This allows for altering the spec before starting the http listener.
|
||||
func SwaggerUI(opts SwaggerUIOpts, next http.Handler) http.Handler {
|
||||
opts.EnsureDefaults()
|
||||
|
||||
pth := path.Join(opts.BasePath, opts.Path)
|
||||
tmpl := template.Must(template.New("swaggerui").Parse(swaggeruiTemplate))
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
_ = tmpl.Execute(buf, &opts)
|
||||
b := buf.Bytes()
|
||||
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
if path.Join(r.URL.Path) == pth {
|
||||
rw.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
|
||||
_, _ = rw.Write(b)
|
||||
return
|
||||
}
|
||||
|
||||
if next == nil {
|
||||
rw.Header().Set("Content-Type", "text/plain")
|
||||
rw.WriteHeader(http.StatusNotFound)
|
||||
_, _ = rw.Write([]byte(fmt.Sprintf("%q not found", pth)))
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(rw, r)
|
||||
})
|
||||
}
|
||||
|
||||
const (
|
||||
swaggerLatest = "https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js"
|
||||
swaggerPresetLatest = "https://unpkg.com/swagger-ui-dist/swagger-ui-standalone-preset.js"
|
||||
swaggerStylesLatest = "https://unpkg.com/swagger-ui-dist/swagger-ui.css"
|
||||
swaggerFavicon32Latest = "https://unpkg.com/swagger-ui-dist/favicon-32x32.png"
|
||||
swaggerFavicon16Latest = "https://unpkg.com/swagger-ui-dist/favicon-16x16.png"
|
||||
swaggeruiTemplate = `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{{ .Title }}</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="{{ .SwaggerStylesURL }}" >
|
||||
<link rel="icon" type="image/png" href="{{ .Favicon32 }}" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="{{ .Favicon16 }}" sizes="16x16" />
|
||||
<style>
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="{{ .SwaggerURL }}"> </script>
|
||||
<script src="{{ .SwaggerPresetURL }}"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
// Begin Swagger UI call region
|
||||
const ui = SwaggerUIBundle({
|
||||
url: '{{ .SpecURL }}',
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout",
|
||||
oauth2RedirectUrl: '{{ .OAuthCallbackURL }}'
|
||||
})
|
||||
// End Swagger UI call region
|
||||
|
||||
window.ui = ui
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
)
|
||||
122
vendor/github.com/go-openapi/runtime/middleware/swaggerui_oauth2.go
generated
vendored
Normal file
122
vendor/github.com/go-openapi/runtime/middleware/swaggerui_oauth2.go
generated
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
func SwaggerUIOAuth2Callback(opts SwaggerUIOpts, next http.Handler) http.Handler {
|
||||
opts.EnsureDefaults()
|
||||
|
||||
pth := opts.OAuthCallbackURL
|
||||
tmpl := template.Must(template.New("swaggeroauth").Parse(swaggerOAuthTemplate))
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
_ = tmpl.Execute(buf, &opts)
|
||||
b := buf.Bytes()
|
||||
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
if path.Join(r.URL.Path) == pth {
|
||||
rw.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
|
||||
_, _ = rw.Write(b)
|
||||
return
|
||||
}
|
||||
|
||||
if next == nil {
|
||||
rw.Header().Set("Content-Type", "text/plain")
|
||||
rw.WriteHeader(http.StatusNotFound)
|
||||
_, _ = rw.Write([]byte(fmt.Sprintf("%q not found", pth)))
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(rw, r)
|
||||
})
|
||||
}
|
||||
|
||||
const (
|
||||
swaggerOAuthTemplate = `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{{ .Title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
'use strict';
|
||||
function run () {
|
||||
var oauth2 = window.opener.swaggerUIRedirectOauth2;
|
||||
var sentState = oauth2.state;
|
||||
var redirectUrl = oauth2.redirectUrl;
|
||||
var isValid, qp, arr;
|
||||
|
||||
if (/code|token|error/.test(window.location.hash)) {
|
||||
qp = window.location.hash.substring(1).replace('?', '&');
|
||||
} else {
|
||||
qp = location.search.substring(1);
|
||||
}
|
||||
|
||||
arr = qp.split("&");
|
||||
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
|
||||
qp = qp ? JSON.parse('{' + arr.join() + '}',
|
||||
function (key, value) {
|
||||
return key === "" ? value : decodeURIComponent(value);
|
||||
}
|
||||
) : {};
|
||||
|
||||
isValid = qp.state === sentState;
|
||||
|
||||
if ((
|
||||
oauth2.auth.schema.get("flow") === "accessCode" ||
|
||||
oauth2.auth.schema.get("flow") === "authorizationCode" ||
|
||||
oauth2.auth.schema.get("flow") === "authorization_code"
|
||||
) && !oauth2.auth.code) {
|
||||
if (!isValid) {
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "warning",
|
||||
message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server."
|
||||
});
|
||||
}
|
||||
|
||||
if (qp.code) {
|
||||
delete oauth2.state;
|
||||
oauth2.auth.code = qp.code;
|
||||
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
|
||||
} else {
|
||||
let oauthErrorMsg;
|
||||
if (qp.error) {
|
||||
oauthErrorMsg = "["+qp.error+"]: " +
|
||||
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
|
||||
(qp.error_uri ? "More info: "+qp.error_uri : "");
|
||||
}
|
||||
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "error",
|
||||
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server."
|
||||
});
|
||||
}
|
||||
} else {
|
||||
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
|
||||
}
|
||||
window.close();
|
||||
}
|
||||
|
||||
if (document.readyState !== 'loading') {
|
||||
run();
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
run();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
)
|
||||
2
vendor/github.com/go-openapi/runtime/request.go
generated
vendored
2
vendor/github.com/go-openapi/runtime/request.go
generated
vendored
@@ -48,7 +48,7 @@ func HasBody(r *http.Request) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
if r.Header.Get(http.CanonicalHeaderKey("content-length")) != "" {
|
||||
if r.Header.Get("content-length") != "" {
|
||||
// in this case, no Transfer-Encoding should be present
|
||||
// we have a header set but it was explicitly set to 0, so we assume no body
|
||||
return false
|
||||
|
||||
4
vendor/github.com/go-openapi/runtime/security/authenticator.go
generated
vendored
4
vendor/github.com/go-openapi/runtime/security/authenticator.go
generated
vendored
@@ -220,7 +220,7 @@ func BearerAuth(name string, authenticate ScopedTokenAuthentication) runtime.Aut
|
||||
const prefix = "Bearer "
|
||||
return ScopedAuthenticator(func(r *ScopedAuthRequest) (bool, interface{}, error) {
|
||||
var token string
|
||||
hdr := r.Request.Header.Get("Authorization")
|
||||
hdr := r.Request.Header.Get(runtime.HeaderAuthorization)
|
||||
if strings.HasPrefix(hdr, prefix) {
|
||||
token = strings.TrimPrefix(hdr, prefix)
|
||||
}
|
||||
@@ -250,7 +250,7 @@ func BearerAuthCtx(name string, authenticate ScopedTokenAuthenticationCtx) runti
|
||||
const prefix = "Bearer "
|
||||
return ScopedAuthenticator(func(r *ScopedAuthRequest) (bool, interface{}, error) {
|
||||
var token string
|
||||
hdr := r.Request.Header.Get("Authorization")
|
||||
hdr := r.Request.Header.Get(runtime.HeaderAuthorization)
|
||||
if strings.HasPrefix(hdr, prefix) {
|
||||
token = strings.TrimPrefix(hdr, prefix)
|
||||
}
|
||||
|
||||
1
vendor/github.com/go-openapi/runtime/text.go
generated
vendored
1
vendor/github.com/go-openapi/runtime/text.go
generated
vendored
@@ -41,7 +41,6 @@ func TextConsumer() Consumer {
|
||||
|
||||
// If the buffer is empty, no need to unmarshal it, which causes a panic.
|
||||
if len(b) == 0 {
|
||||
data = ""
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// +build !go1.8
|
||||
|
||||
// Copyright 2015 go-swagger maintainers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,16 +12,29 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package internal
|
||||
package yamlpc
|
||||
|
||||
import "net/url"
|
||||
import (
|
||||
"io"
|
||||
|
||||
// PathUnescape provides url.PathUnescape(), with seamless
|
||||
// go version support for pre-go1.8
|
||||
//
|
||||
// TODO: this function is currently defined in go-openapi/swag,
|
||||
// but unexported. We might chose to export it, or simple phase
|
||||
// out pre-go1.8 support.
|
||||
func PathUnescape(path string) (string, error) {
|
||||
return url.QueryUnescape(path)
|
||||
"github.com/go-openapi/runtime"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// YAMLConsumer creates a consumer for yaml data
|
||||
func YAMLConsumer() runtime.Consumer {
|
||||
return runtime.ConsumerFunc(func(r io.Reader, v interface{}) error {
|
||||
dec := yaml.NewDecoder(r)
|
||||
return dec.Decode(v)
|
||||
})
|
||||
}
|
||||
|
||||
// YAMLProducer creates a producer for yaml data
|
||||
func YAMLProducer() runtime.Producer {
|
||||
return runtime.ProducerFunc(func(w io.Writer, v interface{}) error {
|
||||
enc := yaml.NewEncoder(w)
|
||||
defer enc.Close()
|
||||
return enc.Encode(v)
|
||||
})
|
||||
}
|
||||
14
vendor/github.com/go-openapi/spec/.golangci.yml
generated
vendored
14
vendor/github.com/go-openapi/spec/.golangci.yml
generated
vendored
@@ -26,3 +26,17 @@ linters:
|
||||
- gocognit
|
||||
- whitespace
|
||||
- wsl
|
||||
- wrapcheck
|
||||
- testpackage
|
||||
- nlreturn
|
||||
- gomnd
|
||||
- exhaustivestruct
|
||||
- goerr113
|
||||
- errorlint
|
||||
- nestif
|
||||
- godot
|
||||
- gofumpt
|
||||
- paralleltest
|
||||
- tparallel
|
||||
- thelper
|
||||
- ifshort
|
||||
|
||||
13
vendor/github.com/go-openapi/spec/.travis.yml
generated
vendored
13
vendor/github.com/go-openapi/spec/.travis.yml
generated
vendored
@@ -1,13 +0,0 @@
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
go:
|
||||
- 1.13.x
|
||||
- 1.14.x
|
||||
install:
|
||||
- GO111MODULE=off go get -u gotest.tools/gotestsum
|
||||
language: go
|
||||
notifications:
|
||||
slack:
|
||||
secure: QUWvCkBBK09GF7YtEvHHVt70JOkdlNBG0nIKu/5qc4/nW5HP8I2w0SEf/XR2je0eED1Qe3L/AfMCWwrEj+IUZc3l4v+ju8X8R3Lomhme0Eb0jd1MTMCuPcBT47YCj0M7RON7vXtbFfm1hFJ/jLe5+9FXz0hpXsR24PJc5ZIi/ogNwkaPqG4BmndzecpSh0vc2FJPZUD9LT0I09REY/vXR0oQAalLkW0asGD5taHZTUZq/kBpsNxaAFrLM23i4mUcf33M5fjLpvx5LRICrX/57XpBrDh2TooBU6Qj3CgoY0uPRYUmSNxbVx1czNzl2JtEpb5yjoxfVPQeg0BvQM00G8LJINISR+ohrjhkZmAqchDupAX+yFrxTtORa78CtnIL6z/aTNlgwwVD8kvL/1pFA/JWYmKDmz93mV/+6wubGzNSQCstzjkFA4/iZEKewKUoRIAi/fxyscP6L/rCpmY/4llZZvrnyTqVbt6URWpopUpH4rwYqreXAtJxJsfBJIeSmUIiDIOMGkCTvyTEW3fWGmGoqWtSHLoaWDyAIGb7azb+KvfpWtEcoPFWfSWU+LGee0A/YsUhBl7ADB9A0CJEuR8q4BPpKpfLwPKSiKSAXL7zDkyjExyhtgqbSl2jS+rKIHOZNL8JkCcTP2MKMVd563C5rC5FMKqu3S9m2b6380E=
|
||||
script:
|
||||
- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
32
vendor/github.com/go-openapi/spec/README.md
generated
vendored
32
vendor/github.com/go-openapi/spec/README.md
generated
vendored
@@ -1,10 +1,34 @@
|
||||
# OAI object model [](https://travis-ci.org/go-openapi/spec) [](https://codecov.io/gh/go-openapi/spec) [](https://slackin.goswagger.io)
|
||||
# OAI object model
|
||||
|
||||
[](https://travis-ci.org/go-openapi/spec)
|
||||
<!-- [](https://ci.appveyor.com/project/casualjim/go-openapi/spec/branch/master) -->
|
||||
[](https://codecov.io/gh/go-openapi/spec)
|
||||
[](https://slackin.goswagger.io)
|
||||
[](https://raw.githubusercontent.com/go-openapi/spec/master/LICENSE)
|
||||
[](http://godoc.org/github.com/go-openapi/spec)
|
||||
[](https://golangci.com)
|
||||
[](https://pkg.go.dev/github.com/go-openapi/spec)
|
||||
[](https://goreportcard.com/report/github.com/go-openapi/spec)
|
||||
|
||||
The object model for OpenAPI specification documents.
|
||||
|
||||
Currently supports Swagger 2.0.
|
||||
### FAQ
|
||||
|
||||
* What does this do?
|
||||
|
||||
> 1. This package knows how to marshal and unmarshal Swagger API specifications into a golang object model
|
||||
> 2. It knows how to resolve $ref and expand them to make a single root document
|
||||
|
||||
* How does it play with the rest of the go-openapi packages ?
|
||||
|
||||
> 1. This package is at the core of the go-openapi suite of packages and [code generator](https://github.com/go-swagger/go-swagger)
|
||||
> 2. There is a [spec loading package](https://github.com/go-openapi/loads) to fetch specs as JSON or YAML from local or remote locations
|
||||
> 3. There is a [spec validation package](https://github.com/go-openapi/validate) built on top of it
|
||||
> 4. There is a [spec analysis package](https://github.com/go-openapi/analysis) built on top of it, to analyze, flatten, fix and merge spec documents
|
||||
|
||||
* Does this library support OpenAPI 3?
|
||||
|
||||
> No.
|
||||
> This package currently only supports OpenAPI 2.0 (aka Swagger 2.0).
|
||||
> There is no plan to make it evolve toward supporting OpenAPI 3.x.
|
||||
> This [discussion thread](https://github.com/go-openapi/spec/issues/21) relates the full story.
|
||||
>
|
||||
> An early attempt to support Swagger 3 may be found at: https://github.com/go-openapi/spec3
|
||||
|
||||
32
vendor/github.com/go-openapi/spec/appveyor.yml
generated
vendored
Normal file
32
vendor/github.com/go-openapi/spec/appveyor.yml
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
version: "0.1.{build}"
|
||||
|
||||
clone_folder: C:\go-openapi\spec
|
||||
shallow_clone: true # for startup speed
|
||||
pull_requests:
|
||||
do_not_increment_build_number: true
|
||||
|
||||
#skip_tags: true
|
||||
#skip_branch_with_pr: true
|
||||
|
||||
# appveyor.yml
|
||||
build: off
|
||||
|
||||
environment:
|
||||
GOPATH: c:\gopath
|
||||
|
||||
stack: go 1.15
|
||||
|
||||
test_script:
|
||||
- go test -v -timeout 20m ./...
|
||||
|
||||
deploy: off
|
||||
|
||||
notifications:
|
||||
- provider: Slack
|
||||
incoming_webhook: https://hooks.slack.com/services/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
|
||||
auth_token:
|
||||
secure: Sf7kZf7ZGbnwWUMpffHwMu5A0cHkLK2MYY32LNTPj4+/3qC3Ghl7+9v4TSLOqOlCwdRNjOGblAq7s+GDJed6/xgRQl1JtCi1klzZNrYX4q01pgTPvvGcwbBkIYgeMaPeIRcK9OZnud7sRXdttozgTOpytps2U6Js32ip7uj5mHSg2ub0FwoSJwlS6dbezZ8+eDhoha0F/guY99BEwx8Bd+zROrT2TFGsSGOFGN6wFc7moCqTHO/YkWib13a2QNXqOxCCVBy/lt76Wp+JkeFppjHlzs/2lP3EAk13RIUAaesdEUHvIHrzCyNJEd3/+KO2DzsWOYfpktd+KBCvgaYOsoo7ubdT3IROeAegZdCgo/6xgCEsmFc9ZcqCfN5yNx2A+BZ2Vwmpws+bQ1E1+B5HDzzaiLcYfG4X2O210QVGVDLWsv1jqD+uPYeHY2WRfh5ZsIUFvaqgUEnwHwrK44/8REAhQavt1QAj5uJpsRd7CkRVPWRNK+yIky+wgbVUFEchRNmS55E7QWf+W4+4QZkQi7vUTMc9nbTUu2Es9NfvfudOpM2wZbn98fjpb/qq/nRv6Bk+ca+7XD5/IgNLMbWp2ouDdzbiHLCOfDUiHiDJhLfFZx9Bwo7ZwfzeOlbrQX66bx7xRKYmOe4DLrXhNcpbsMa8qbfxlZRCmYbubB/Y8h4=
|
||||
channel: bots
|
||||
on_build_success: false
|
||||
on_build_failure: true
|
||||
on_build_status_changed: true
|
||||
6
vendor/github.com/go-openapi/spec/bindata.go
generated
vendored
6
vendor/github.com/go-openapi/spec/bindata.go
generated
vendored
@@ -247,9 +247,9 @@ type bintree struct {
|
||||
}
|
||||
|
||||
var _bintree = &bintree{nil, map[string]*bintree{
|
||||
"jsonschema-draft-04.json": &bintree{jsonschemaDraft04Json, map[string]*bintree{}},
|
||||
"v2": &bintree{nil, map[string]*bintree{
|
||||
"schema.json": &bintree{v2SchemaJson, map[string]*bintree{}},
|
||||
"jsonschema-draft-04.json": {jsonschemaDraft04Json, map[string]*bintree{}},
|
||||
"v2": {nil, map[string]*bintree{
|
||||
"schema.json": {v2SchemaJson, map[string]*bintree{}},
|
||||
}},
|
||||
}}
|
||||
|
||||
|
||||
54
vendor/github.com/go-openapi/spec/cache.go
generated
vendored
54
vendor/github.com/go-openapi/spec/cache.go
generated
vendored
@@ -14,7 +14,9 @@
|
||||
|
||||
package spec
|
||||
|
||||
import "sync"
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// ResolutionCache a cache for resolving urls
|
||||
type ResolutionCache interface {
|
||||
@@ -27,12 +29,23 @@ type simpleCache struct {
|
||||
store map[string]interface{}
|
||||
}
|
||||
|
||||
func (s *simpleCache) ShallowClone() ResolutionCache {
|
||||
store := make(map[string]interface{}, len(s.store))
|
||||
s.lock.RLock()
|
||||
for k, v := range s.store {
|
||||
store[k] = v
|
||||
}
|
||||
s.lock.RUnlock()
|
||||
|
||||
return &simpleCache{
|
||||
store: store,
|
||||
}
|
||||
}
|
||||
|
||||
// Get retrieves a cached URI
|
||||
func (s *simpleCache) Get(uri string) (interface{}, bool) {
|
||||
debugLog("getting %q from resolution cache", uri)
|
||||
s.lock.RLock()
|
||||
v, ok := s.store[uri]
|
||||
debugLog("got %q from resolution cache: %t", uri, ok)
|
||||
|
||||
s.lock.RUnlock()
|
||||
return v, ok
|
||||
@@ -45,16 +58,41 @@ func (s *simpleCache) Set(uri string, data interface{}) {
|
||||
s.lock.Unlock()
|
||||
}
|
||||
|
||||
var resCache ResolutionCache
|
||||
var (
|
||||
// resCache is a package level cache for $ref resolution and expansion.
|
||||
// It is initialized lazily by methods that have the need for it: no
|
||||
// memory is allocated unless some expander methods are called.
|
||||
//
|
||||
// It is initialized with JSON schema and swagger schema,
|
||||
// which do not mutate during normal operations.
|
||||
//
|
||||
// All subsequent utilizations of this cache are produced from a shallow
|
||||
// clone of this initial version.
|
||||
resCache *simpleCache
|
||||
onceCache sync.Once
|
||||
|
||||
func init() {
|
||||
resCache = initResolutionCache()
|
||||
_ ResolutionCache = &simpleCache{}
|
||||
)
|
||||
|
||||
// initResolutionCache initializes the URI resolution cache. To be wrapped in a sync.Once.Do call.
|
||||
func initResolutionCache() {
|
||||
resCache = defaultResolutionCache()
|
||||
}
|
||||
|
||||
// initResolutionCache initializes the URI resolution cache
|
||||
func initResolutionCache() ResolutionCache {
|
||||
func defaultResolutionCache() *simpleCache {
|
||||
return &simpleCache{store: map[string]interface{}{
|
||||
"http://swagger.io/v2/schema.json": MustLoadSwagger20Schema(),
|
||||
"http://json-schema.org/draft-04/schema": MustLoadJSONSchemaDraft04(),
|
||||
}}
|
||||
}
|
||||
|
||||
func cacheOrDefault(cache ResolutionCache) ResolutionCache {
|
||||
onceCache.Do(initResolutionCache)
|
||||
|
||||
if cache != nil {
|
||||
return cache
|
||||
}
|
||||
|
||||
// get a shallow clone of the base cache with swagger and json schema
|
||||
return resCache.ShallowClone()
|
||||
}
|
||||
|
||||
3
vendor/github.com/go-openapi/spec/contact_info.go
generated
vendored
3
vendor/github.com/go-openapi/spec/contact_info.go
generated
vendored
@@ -28,12 +28,14 @@ type ContactInfo struct {
|
||||
VendorExtensible
|
||||
}
|
||||
|
||||
// ContactInfoProps hold the properties of a ContactInfo object
|
||||
type ContactInfoProps struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON hydrates ContactInfo from json
|
||||
func (c *ContactInfo) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &c.ContactInfoProps); err != nil {
|
||||
return err
|
||||
@@ -41,6 +43,7 @@ func (c *ContactInfo) UnmarshalJSON(data []byte) error {
|
||||
return json.Unmarshal(data, &c.VendorExtensible)
|
||||
}
|
||||
|
||||
// MarshalJSON produces ContactInfo as json
|
||||
func (c ContactInfo) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(c.ContactInfoProps)
|
||||
if err != nil {
|
||||
|
||||
12
vendor/github.com/go-openapi/spec/debug.go
generated
vendored
12
vendor/github.com/go-openapi/spec/debug.go
generated
vendored
@@ -18,14 +18,16 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"path"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Debug is true when the SWAGGER_DEBUG env var is not empty.
|
||||
//
|
||||
// It enables a more verbose logging of this package.
|
||||
var Debug = os.Getenv("SWAGGER_DEBUG") != ""
|
||||
|
||||
var (
|
||||
// Debug is true when the SWAGGER_DEBUG env var is not empty.
|
||||
// It enables a more verbose logging of this package.
|
||||
Debug = os.Getenv("SWAGGER_DEBUG") != ""
|
||||
// specLogger is a debug logger for this package
|
||||
specLogger *log.Logger
|
||||
)
|
||||
@@ -42,6 +44,6 @@ func debugLog(msg string, args ...interface{}) {
|
||||
// A private, trivial trace logger, based on go-openapi/spec/expander.go:debugLog()
|
||||
if Debug {
|
||||
_, file1, pos1, _ := runtime.Caller(1)
|
||||
specLogger.Printf("%s:%d: %s", filepath.Base(file1), pos1, fmt.Sprintf(msg, args...))
|
||||
specLogger.Printf("%s:%d: %s", path.Base(file1), pos1, fmt.Sprintf(msg, args...))
|
||||
}
|
||||
}
|
||||
|
||||
19
vendor/github.com/go-openapi/spec/errors.go
generated
vendored
Normal file
19
vendor/github.com/go-openapi/spec/errors.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
package spec
|
||||
|
||||
import "errors"
|
||||
|
||||
// Error codes
|
||||
var (
|
||||
// ErrUnknownTypeForReference indicates that a resolved reference was found in an unsupported container type
|
||||
ErrUnknownTypeForReference = errors.New("unknown type for the resolved reference")
|
||||
|
||||
// ErrResolveRefNeedsAPointer indicates that a $ref target must be a valid JSON pointer
|
||||
ErrResolveRefNeedsAPointer = errors.New("resolve ref: target needs to be a pointer")
|
||||
|
||||
// ErrDerefUnsupportedType indicates that a resolved reference was found in an unsupported container type.
|
||||
// At the moment, $ref are supported only inside: schemas, parameters, responses, path items
|
||||
ErrDerefUnsupportedType = errors.New("deref: unsupported type")
|
||||
|
||||
// ErrExpandUnsupportedType indicates that $ref expansion is attempted on some invalid type
|
||||
ErrExpandUnsupportedType = errors.New("expand: unsupported type. Input should be of type *Parameter or *Response")
|
||||
)
|
||||
573
vendor/github.com/go-openapi/spec/expander.go
generated
vendored
573
vendor/github.com/go-openapi/spec/expander.go
generated
vendored
@@ -17,152 +17,51 @@ package spec
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ExpandOptions provides options for spec expand
|
||||
type ExpandOptions struct {
|
||||
RelativeBase string
|
||||
SkipSchemas bool
|
||||
ContinueOnError bool
|
||||
AbsoluteCircularRef bool
|
||||
}
|
||||
|
||||
// ResolveRefWithBase resolves a reference against a context root with preservation of base path
|
||||
func ResolveRefWithBase(root interface{}, ref *Ref, opts *ExpandOptions) (*Schema, error) {
|
||||
resolver, err := defaultSchemaLoader(root, opts, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
specBasePath := ""
|
||||
if opts != nil && opts.RelativeBase != "" {
|
||||
specBasePath, _ = absPath(opts.RelativeBase)
|
||||
}
|
||||
|
||||
result := new(Schema)
|
||||
if err := resolver.Resolve(ref, result, specBasePath); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ResolveRef resolves a reference against a context root
|
||||
// ref is guaranteed to be in root (no need to go to external files)
|
||||
// ResolveRef is ONLY called from the code generation module
|
||||
func ResolveRef(root interface{}, ref *Ref) (*Schema, error) {
|
||||
res, _, err := ref.GetPointer().Get(root)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
switch sch := res.(type) {
|
||||
case Schema:
|
||||
return &sch, nil
|
||||
case *Schema:
|
||||
return sch, nil
|
||||
case map[string]interface{}:
|
||||
b, _ := json.Marshal(sch)
|
||||
newSch := new(Schema)
|
||||
_ = json.Unmarshal(b, newSch)
|
||||
return newSch, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown type for the resolved reference")
|
||||
}
|
||||
}
|
||||
|
||||
// ResolveParameter resolves a parameter reference against a context root
|
||||
func ResolveParameter(root interface{}, ref Ref) (*Parameter, error) {
|
||||
return ResolveParameterWithBase(root, ref, nil)
|
||||
}
|
||||
|
||||
// ResolveParameterWithBase resolves a parameter reference against a context root and base path
|
||||
func ResolveParameterWithBase(root interface{}, ref Ref, opts *ExpandOptions) (*Parameter, error) {
|
||||
resolver, err := defaultSchemaLoader(root, opts, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := new(Parameter)
|
||||
if err := resolver.Resolve(&ref, result, ""); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ResolveResponse resolves response a reference against a context root
|
||||
func ResolveResponse(root interface{}, ref Ref) (*Response, error) {
|
||||
return ResolveResponseWithBase(root, ref, nil)
|
||||
}
|
||||
|
||||
// ResolveResponseWithBase resolves response a reference against a context root and base path
|
||||
func ResolveResponseWithBase(root interface{}, ref Ref, opts *ExpandOptions) (*Response, error) {
|
||||
resolver, err := defaultSchemaLoader(root, opts, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := new(Response)
|
||||
if err := resolver.Resolve(&ref, result, ""); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ResolveItems resolves parameter items reference against a context root and base path.
|
||||
// ExpandOptions provides options for the spec expander.
|
||||
//
|
||||
// NOTE: stricly speaking, this construct is not supported by Swagger 2.0.
|
||||
// Similarly, $ref are forbidden in response headers.
|
||||
func ResolveItems(root interface{}, ref Ref, opts *ExpandOptions) (*Items, error) {
|
||||
resolver, err := defaultSchemaLoader(root, opts, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
basePath := ""
|
||||
if opts.RelativeBase != "" {
|
||||
basePath = opts.RelativeBase
|
||||
}
|
||||
result := new(Items)
|
||||
if err := resolver.Resolve(&ref, result, basePath); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
// RelativeBase is the path to the root document. This can be a remote URL or a path to a local file.
|
||||
//
|
||||
// If left empty, the root document is assumed to be located in the current working directory:
|
||||
// all relative $ref's will be resolved from there.
|
||||
//
|
||||
// PathLoader injects a document loading method. By default, this resolves to the function provided by the SpecLoader package variable.
|
||||
//
|
||||
type ExpandOptions struct {
|
||||
RelativeBase string // the path to the root document to expand. This is a file, not a directory
|
||||
SkipSchemas bool // do not expand schemas, just paths, parameters and responses
|
||||
ContinueOnError bool // continue expanding even after and error is found
|
||||
PathLoader func(string) (json.RawMessage, error) `json:"-"` // the document loading method that takes a path as input and yields a json document
|
||||
AbsoluteCircularRef bool // circular $ref remaining after expansion remain absolute URLs
|
||||
}
|
||||
|
||||
// ResolvePathItem resolves response a path item against a context root and base path
|
||||
func ResolvePathItem(root interface{}, ref Ref, opts *ExpandOptions) (*PathItem, error) {
|
||||
resolver, err := defaultSchemaLoader(root, opts, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func optionsOrDefault(opts *ExpandOptions) *ExpandOptions {
|
||||
if opts != nil {
|
||||
clone := *opts // shallow clone to avoid internal changes to be propagated to the caller
|
||||
if clone.RelativeBase != "" {
|
||||
clone.RelativeBase = normalizeBase(clone.RelativeBase)
|
||||
}
|
||||
// if the relative base is empty, let the schema loader choose a pseudo root document
|
||||
return &clone
|
||||
}
|
||||
basePath := ""
|
||||
if opts.RelativeBase != "" {
|
||||
basePath = opts.RelativeBase
|
||||
}
|
||||
result := new(PathItem)
|
||||
if err := resolver.Resolve(&ref, result, basePath); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
return &ExpandOptions{}
|
||||
}
|
||||
|
||||
// ExpandSpec expands the references in a swagger spec
|
||||
func ExpandSpec(spec *Swagger, options *ExpandOptions) error {
|
||||
resolver, err := defaultSchemaLoader(spec, options, nil, nil)
|
||||
// Just in case this ever returns an error.
|
||||
if resolver.shouldStopOnError(err) {
|
||||
return err
|
||||
}
|
||||
options = optionsOrDefault(options)
|
||||
resolver := defaultSchemaLoader(spec, options, nil, nil)
|
||||
|
||||
// getting the base path of the spec to adjust all subsequent reference resolutions
|
||||
specBasePath := ""
|
||||
if options != nil && options.RelativeBase != "" {
|
||||
specBasePath, _ = absPath(options.RelativeBase)
|
||||
}
|
||||
specBasePath := options.RelativeBase
|
||||
|
||||
if options == nil || !options.SkipSchemas {
|
||||
if !options.SkipSchemas {
|
||||
for key, definition := range spec.Definitions {
|
||||
var def *Schema
|
||||
var err error
|
||||
if def, err = expandSchema(definition, []string{fmt.Sprintf("#/definitions/%s", key)}, resolver, specBasePath); resolver.shouldStopOnError(err) {
|
||||
parentRefs := make([]string, 0, 10)
|
||||
parentRefs = append(parentRefs, fmt.Sprintf("#/definitions/%s", key))
|
||||
|
||||
def, err := expandSchema(definition, parentRefs, resolver, specBasePath)
|
||||
if resolver.shouldStopOnError(err) {
|
||||
return err
|
||||
}
|
||||
if def != nil {
|
||||
@@ -189,157 +88,136 @@ func ExpandSpec(spec *Swagger, options *ExpandOptions) error {
|
||||
|
||||
if spec.Paths != nil {
|
||||
for key := range spec.Paths.Paths {
|
||||
path := spec.Paths.Paths[key]
|
||||
if err := expandPathItem(&path, resolver, specBasePath); resolver.shouldStopOnError(err) {
|
||||
pth := spec.Paths.Paths[key]
|
||||
if err := expandPathItem(&pth, resolver, specBasePath); resolver.shouldStopOnError(err) {
|
||||
return err
|
||||
}
|
||||
spec.Paths.Paths[key] = path
|
||||
spec.Paths.Paths[key] = pth
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
const rootBase = "root"
|
||||
// baseForRoot loads in the cache the root document and produces a fake "root" base path entry
|
||||
const rootBase = ".root"
|
||||
|
||||
// baseForRoot loads in the cache the root document and produces a fake ".root" base path entry
|
||||
// for further $ref resolution
|
||||
//
|
||||
// Setting the cache is optional and this parameter may safely be left to nil.
|
||||
func baseForRoot(root interface{}, cache ResolutionCache) string {
|
||||
// cache the root document to resolve $ref's
|
||||
if root != nil {
|
||||
base, _ := absPath(rootBase)
|
||||
normalizedBase := normalizeAbsPath(base)
|
||||
debugLog("setting root doc in cache at: %s", normalizedBase)
|
||||
if cache == nil {
|
||||
cache = resCache
|
||||
}
|
||||
cache.Set(normalizedBase, root)
|
||||
return rootBase
|
||||
if root == nil {
|
||||
return ""
|
||||
}
|
||||
return ""
|
||||
|
||||
// cache the root document to resolve $ref's
|
||||
normalizedBase := normalizeBase(rootBase)
|
||||
cache.Set(normalizedBase, root)
|
||||
|
||||
return normalizedBase
|
||||
}
|
||||
|
||||
// ExpandSchema expands the refs in the schema object with reference to the root object
|
||||
// go-openapi/validate uses this function
|
||||
// notice that it is impossible to reference a json schema in a different file other than root
|
||||
// ExpandSchema expands the refs in the schema object with reference to the root object.
|
||||
//
|
||||
// go-openapi/validate uses this function.
|
||||
//
|
||||
// Notice that it is impossible to reference a json schema in a different document other than root
|
||||
// (use ExpandSchemaWithBasePath to resolve external references).
|
||||
//
|
||||
// Setting the cache is optional and this parameter may safely be left to nil.
|
||||
func ExpandSchema(schema *Schema, root interface{}, cache ResolutionCache) error {
|
||||
cache = cacheOrDefault(cache)
|
||||
if root == nil {
|
||||
root = schema
|
||||
}
|
||||
|
||||
opts := &ExpandOptions{
|
||||
// when a root is specified, cache the root as an in-memory document for $ref retrieval
|
||||
RelativeBase: baseForRoot(root, cache),
|
||||
SkipSchemas: false,
|
||||
ContinueOnError: false,
|
||||
// when no base path is specified, remaining $ref (circular) are rendered with an absolute path
|
||||
AbsoluteCircularRef: true,
|
||||
}
|
||||
|
||||
return ExpandSchemaWithBasePath(schema, cache, opts)
|
||||
}
|
||||
|
||||
// ExpandSchemaWithBasePath expands the refs in the schema object, base path configured through expand options
|
||||
// ExpandSchemaWithBasePath expands the refs in the schema object, base path configured through expand options.
|
||||
//
|
||||
// Setting the cache is optional and this parameter may safely be left to nil.
|
||||
func ExpandSchemaWithBasePath(schema *Schema, cache ResolutionCache, opts *ExpandOptions) error {
|
||||
if schema == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var basePath string
|
||||
if opts.RelativeBase != "" {
|
||||
basePath, _ = absPath(opts.RelativeBase)
|
||||
}
|
||||
cache = cacheOrDefault(cache)
|
||||
|
||||
resolver, err := defaultSchemaLoader(nil, opts, cache, nil)
|
||||
opts = optionsOrDefault(opts)
|
||||
|
||||
resolver := defaultSchemaLoader(nil, opts, cache, nil)
|
||||
|
||||
parentRefs := make([]string, 0, 10)
|
||||
s, err := expandSchema(*schema, parentRefs, resolver, opts.RelativeBase)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
refs := []string{""}
|
||||
var s *Schema
|
||||
if s, err = expandSchema(*schema, refs, resolver, basePath); err != nil {
|
||||
return err
|
||||
if s != nil {
|
||||
// guard for when continuing on error
|
||||
*schema = *s
|
||||
}
|
||||
*schema = *s
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func expandItems(target Schema, parentRefs []string, resolver *schemaLoader, basePath string) (*Schema, error) {
|
||||
if target.Items != nil {
|
||||
if target.Items.Schema != nil {
|
||||
t, err := expandSchema(*target.Items.Schema, parentRefs, resolver, basePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
*target.Items.Schema = *t
|
||||
}
|
||||
for i := range target.Items.Schemas {
|
||||
t, err := expandSchema(target.Items.Schemas[i], parentRefs, resolver, basePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
target.Items.Schemas[i] = *t
|
||||
}
|
||||
if target.Items == nil {
|
||||
return &target, nil
|
||||
}
|
||||
|
||||
// array
|
||||
if target.Items.Schema != nil {
|
||||
t, err := expandSchema(*target.Items.Schema, parentRefs, resolver, basePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
*target.Items.Schema = *t
|
||||
}
|
||||
|
||||
// tuple
|
||||
for i := range target.Items.Schemas {
|
||||
t, err := expandSchema(target.Items.Schemas[i], parentRefs, resolver, basePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
target.Items.Schemas[i] = *t
|
||||
}
|
||||
|
||||
return &target, nil
|
||||
}
|
||||
|
||||
func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, basePath string) (*Schema, error) {
|
||||
if target.Ref.String() == "" && target.Ref.IsRoot() {
|
||||
// normalizing is important
|
||||
newRef := normalizeFileRef(&target.Ref, basePath)
|
||||
newRef := normalizeRef(&target.Ref, basePath)
|
||||
target.Ref = *newRef
|
||||
return &target, nil
|
||||
|
||||
}
|
||||
|
||||
// change the base path of resolution when an ID is encountered
|
||||
// otherwise the basePath should inherit the parent's
|
||||
// important: ID can be relative path
|
||||
if target.ID != "" {
|
||||
debugLog("schema has ID: %s", target.ID)
|
||||
// handling the case when id is a folder
|
||||
// remember that basePath has to be a file
|
||||
refPath := target.ID
|
||||
if strings.HasSuffix(target.ID, "/") {
|
||||
// path.Clean here would not work correctly if basepath is http
|
||||
refPath = fmt.Sprintf("%s%s", refPath, "placeholder.json")
|
||||
}
|
||||
basePath = normalizePaths(refPath, basePath)
|
||||
basePath, _ = resolver.setSchemaID(target, target.ID, basePath)
|
||||
}
|
||||
|
||||
var t *Schema
|
||||
// if Ref is found, everything else doesn't matter
|
||||
// Ref also changes the resolution scope of children expandSchema
|
||||
if target.Ref.String() != "" {
|
||||
// here the resolution scope is changed because a $ref was encountered
|
||||
normalizedRef := normalizeFileRef(&target.Ref, basePath)
|
||||
normalizedBasePath := normalizedRef.RemoteURI()
|
||||
return expandSchemaRef(target, parentRefs, resolver, basePath)
|
||||
}
|
||||
|
||||
if resolver.isCircular(normalizedRef, basePath, parentRefs...) {
|
||||
// this means there is a cycle in the recursion tree: return the Ref
|
||||
// - circular refs cannot be expanded. We leave them as ref.
|
||||
// - denormalization means that a new local file ref is set relative to the original basePath
|
||||
debugLog("shortcut circular ref: basePath: %s, normalizedPath: %s, normalized ref: %s",
|
||||
basePath, normalizedBasePath, normalizedRef.String())
|
||||
if !resolver.options.AbsoluteCircularRef {
|
||||
target.Ref = *denormalizeFileRef(normalizedRef, normalizedBasePath, resolver.context.basePath)
|
||||
} else {
|
||||
target.Ref = *normalizedRef
|
||||
}
|
||||
return &target, nil
|
||||
for k := range target.Definitions {
|
||||
tt, err := expandSchema(target.Definitions[k], parentRefs, resolver, basePath)
|
||||
if resolver.shouldStopOnError(err) {
|
||||
return &target, err
|
||||
}
|
||||
|
||||
debugLog("basePath: %s: calling Resolve with target: %#v", basePath, target)
|
||||
if err := resolver.Resolve(&target.Ref, &t, basePath); resolver.shouldStopOnError(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if t != nil {
|
||||
parentRefs = append(parentRefs, normalizedRef.String())
|
||||
var err error
|
||||
transitiveResolver, err := resolver.transitiveResolver(basePath, target.Ref)
|
||||
if transitiveResolver.shouldStopOnError(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
basePath = resolver.updateBasePath(transitiveResolver, normalizedBasePath)
|
||||
|
||||
return expandSchema(*t, parentRefs, transitiveResolver, basePath)
|
||||
if tt != nil {
|
||||
target.Definitions[k] = *tt
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,15 +234,21 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
|
||||
if resolver.shouldStopOnError(err) {
|
||||
return &target, err
|
||||
}
|
||||
target.AllOf[i] = *t
|
||||
if t != nil {
|
||||
target.AllOf[i] = *t
|
||||
}
|
||||
}
|
||||
|
||||
for i := range target.AnyOf {
|
||||
t, err := expandSchema(target.AnyOf[i], parentRefs, resolver, basePath)
|
||||
if resolver.shouldStopOnError(err) {
|
||||
return &target, err
|
||||
}
|
||||
target.AnyOf[i] = *t
|
||||
if t != nil {
|
||||
target.AnyOf[i] = *t
|
||||
}
|
||||
}
|
||||
|
||||
for i := range target.OneOf {
|
||||
t, err := expandSchema(target.OneOf[i], parentRefs, resolver, basePath)
|
||||
if resolver.shouldStopOnError(err) {
|
||||
@@ -374,6 +258,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
|
||||
target.OneOf[i] = *t
|
||||
}
|
||||
}
|
||||
|
||||
if target.Not != nil {
|
||||
t, err := expandSchema(*target.Not, parentRefs, resolver, basePath)
|
||||
if resolver.shouldStopOnError(err) {
|
||||
@@ -383,6 +268,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
|
||||
*target.Not = *t
|
||||
}
|
||||
}
|
||||
|
||||
for k := range target.Properties {
|
||||
t, err := expandSchema(target.Properties[k], parentRefs, resolver, basePath)
|
||||
if resolver.shouldStopOnError(err) {
|
||||
@@ -392,6 +278,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
|
||||
target.Properties[k] = *t
|
||||
}
|
||||
}
|
||||
|
||||
if target.AdditionalProperties != nil && target.AdditionalProperties.Schema != nil {
|
||||
t, err := expandSchema(*target.AdditionalProperties.Schema, parentRefs, resolver, basePath)
|
||||
if resolver.shouldStopOnError(err) {
|
||||
@@ -401,6 +288,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
|
||||
*target.AdditionalProperties.Schema = *t
|
||||
}
|
||||
}
|
||||
|
||||
for k := range target.PatternProperties {
|
||||
t, err := expandSchema(target.PatternProperties[k], parentRefs, resolver, basePath)
|
||||
if resolver.shouldStopOnError(err) {
|
||||
@@ -410,6 +298,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
|
||||
target.PatternProperties[k] = *t
|
||||
}
|
||||
}
|
||||
|
||||
for k := range target.Dependencies {
|
||||
if target.Dependencies[k].Schema != nil {
|
||||
t, err := expandSchema(*target.Dependencies[k].Schema, parentRefs, resolver, basePath)
|
||||
@@ -421,6 +310,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if target.AdditionalItems != nil && target.AdditionalItems.Schema != nil {
|
||||
t, err := expandSchema(*target.AdditionalItems.Schema, parentRefs, resolver, basePath)
|
||||
if resolver.shouldStopOnError(err) {
|
||||
@@ -430,42 +320,73 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
|
||||
*target.AdditionalItems.Schema = *t
|
||||
}
|
||||
}
|
||||
for k := range target.Definitions {
|
||||
t, err := expandSchema(target.Definitions[k], parentRefs, resolver, basePath)
|
||||
if resolver.shouldStopOnError(err) {
|
||||
return &target, err
|
||||
}
|
||||
if t != nil {
|
||||
target.Definitions[k] = *t
|
||||
}
|
||||
}
|
||||
return &target, nil
|
||||
}
|
||||
|
||||
func expandSchemaRef(target Schema, parentRefs []string, resolver *schemaLoader, basePath string) (*Schema, error) {
|
||||
// if a Ref is found, all sibling fields are skipped
|
||||
// Ref also changes the resolution scope of children expandSchema
|
||||
|
||||
// here the resolution scope is changed because a $ref was encountered
|
||||
normalizedRef := normalizeRef(&target.Ref, basePath)
|
||||
normalizedBasePath := normalizedRef.RemoteURI()
|
||||
|
||||
if resolver.isCircular(normalizedRef, basePath, parentRefs...) {
|
||||
// this means there is a cycle in the recursion tree: return the Ref
|
||||
// - circular refs cannot be expanded. We leave them as ref.
|
||||
// - denormalization means that a new local file ref is set relative to the original basePath
|
||||
debugLog("short circuit circular ref: basePath: %s, normalizedPath: %s, normalized ref: %s",
|
||||
basePath, normalizedBasePath, normalizedRef.String())
|
||||
if !resolver.options.AbsoluteCircularRef {
|
||||
target.Ref = denormalizeRef(normalizedRef, resolver.context.basePath, resolver.context.rootID)
|
||||
} else {
|
||||
target.Ref = *normalizedRef
|
||||
}
|
||||
return &target, nil
|
||||
}
|
||||
|
||||
var t *Schema
|
||||
err := resolver.Resolve(&target.Ref, &t, basePath)
|
||||
if resolver.shouldStopOnError(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if t == nil {
|
||||
// guard for when continuing on error
|
||||
return &target, nil
|
||||
}
|
||||
|
||||
parentRefs = append(parentRefs, normalizedRef.String())
|
||||
transitiveResolver := resolver.transitiveResolver(basePath, target.Ref)
|
||||
|
||||
basePath = resolver.updateBasePath(transitiveResolver, normalizedBasePath)
|
||||
|
||||
return expandSchema(*t, parentRefs, transitiveResolver, basePath)
|
||||
}
|
||||
|
||||
func expandPathItem(pathItem *PathItem, resolver *schemaLoader, basePath string) error {
|
||||
if pathItem == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
parentRefs := []string{}
|
||||
parentRefs := make([]string, 0, 10)
|
||||
if err := resolver.deref(pathItem, parentRefs, basePath); resolver.shouldStopOnError(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if pathItem.Ref.String() != "" {
|
||||
transitiveResolver, err := resolver.transitiveResolver(basePath, pathItem.Ref)
|
||||
if transitiveResolver.shouldStopOnError(err) {
|
||||
return err
|
||||
}
|
||||
transitiveResolver := resolver.transitiveResolver(basePath, pathItem.Ref)
|
||||
basePath = transitiveResolver.updateBasePath(resolver, basePath)
|
||||
resolver = transitiveResolver
|
||||
}
|
||||
pathItem.Ref = Ref{}
|
||||
|
||||
for idx := range pathItem.Parameters {
|
||||
if err := expandParameterOrResponse(&(pathItem.Parameters[idx]), resolver, basePath); resolver.shouldStopOnError(err) {
|
||||
pathItem.Ref = Ref{}
|
||||
for i := range pathItem.Parameters {
|
||||
if err := expandParameterOrResponse(&(pathItem.Parameters[i]), resolver, basePath); resolver.shouldStopOnError(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
ops := []*Operation{
|
||||
pathItem.Get,
|
||||
pathItem.Head,
|
||||
@@ -480,6 +401,7 @@ func expandPathItem(pathItem *PathItem, resolver *schemaLoader, basePath string)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -496,71 +418,65 @@ func expandOperation(op *Operation, resolver *schemaLoader, basePath string) err
|
||||
op.Parameters[i] = param
|
||||
}
|
||||
|
||||
if op.Responses != nil {
|
||||
responses := op.Responses
|
||||
if err := expandParameterOrResponse(responses.Default, resolver, basePath); resolver.shouldStopOnError(err) {
|
||||
if op.Responses == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
responses := op.Responses
|
||||
if err := expandParameterOrResponse(responses.Default, resolver, basePath); resolver.shouldStopOnError(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
for code := range responses.StatusCodeResponses {
|
||||
response := responses.StatusCodeResponses[code]
|
||||
if err := expandParameterOrResponse(&response, resolver, basePath); resolver.shouldStopOnError(err) {
|
||||
return err
|
||||
}
|
||||
for code := range responses.StatusCodeResponses {
|
||||
response := responses.StatusCodeResponses[code]
|
||||
if err := expandParameterOrResponse(&response, resolver, basePath); resolver.shouldStopOnError(err) {
|
||||
return err
|
||||
}
|
||||
responses.StatusCodeResponses[code] = response
|
||||
}
|
||||
responses.StatusCodeResponses[code] = response
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExpandResponseWithRoot expands a response based on a root document, not a fetchable document
|
||||
//
|
||||
// Notice that it is impossible to reference a json schema in a different document other than root
|
||||
// (use ExpandResponse to resolve external references).
|
||||
//
|
||||
// Setting the cache is optional and this parameter may safely be left to nil.
|
||||
func ExpandResponseWithRoot(response *Response, root interface{}, cache ResolutionCache) error {
|
||||
cache = cacheOrDefault(cache)
|
||||
opts := &ExpandOptions{
|
||||
RelativeBase: baseForRoot(root, cache),
|
||||
SkipSchemas: false,
|
||||
ContinueOnError: false,
|
||||
// when no base path is specified, remaining $ref (circular) are rendered with an absolute path
|
||||
AbsoluteCircularRef: true,
|
||||
}
|
||||
resolver, err := defaultSchemaLoader(root, opts, nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
RelativeBase: baseForRoot(root, cache),
|
||||
}
|
||||
resolver := defaultSchemaLoader(root, opts, cache, nil)
|
||||
|
||||
return expandParameterOrResponse(response, resolver, opts.RelativeBase)
|
||||
}
|
||||
|
||||
// ExpandResponse expands a response based on a basepath
|
||||
// This is the exported version of expandResponse
|
||||
// all refs inside response will be resolved relative to basePath
|
||||
//
|
||||
// All refs inside response will be resolved relative to basePath
|
||||
func ExpandResponse(response *Response, basePath string) error {
|
||||
var specBasePath string
|
||||
if basePath != "" {
|
||||
specBasePath, _ = absPath(basePath)
|
||||
}
|
||||
opts := &ExpandOptions{
|
||||
RelativeBase: specBasePath,
|
||||
}
|
||||
resolver, err := defaultSchemaLoader(nil, opts, nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := optionsOrDefault(&ExpandOptions{
|
||||
RelativeBase: basePath,
|
||||
})
|
||||
resolver := defaultSchemaLoader(nil, opts, nil, nil)
|
||||
|
||||
return expandParameterOrResponse(response, resolver, opts.RelativeBase)
|
||||
}
|
||||
|
||||
// ExpandParameterWithRoot expands a parameter based on a root document, not a fetchable document
|
||||
// ExpandParameterWithRoot expands a parameter based on a root document, not a fetchable document.
|
||||
//
|
||||
// Notice that it is impossible to reference a json schema in a different document other than root
|
||||
// (use ExpandParameter to resolve external references).
|
||||
func ExpandParameterWithRoot(parameter *Parameter, root interface{}, cache ResolutionCache) error {
|
||||
cache = cacheOrDefault(cache)
|
||||
|
||||
opts := &ExpandOptions{
|
||||
RelativeBase: baseForRoot(root, cache),
|
||||
SkipSchemas: false,
|
||||
ContinueOnError: false,
|
||||
// when no base path is specified, remaining $ref (circular) are rendered with an absolute path
|
||||
AbsoluteCircularRef: true,
|
||||
}
|
||||
resolver, err := defaultSchemaLoader(root, opts, nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
RelativeBase: baseForRoot(root, cache),
|
||||
}
|
||||
resolver := defaultSchemaLoader(root, opts, cache, nil)
|
||||
|
||||
return expandParameterOrResponse(parameter, resolver, opts.RelativeBase)
|
||||
}
|
||||
@@ -569,24 +485,20 @@ func ExpandParameterWithRoot(parameter *Parameter, root interface{}, cache Resol
|
||||
// This is the exported version of expandParameter
|
||||
// all refs inside parameter will be resolved relative to basePath
|
||||
func ExpandParameter(parameter *Parameter, basePath string) error {
|
||||
var specBasePath string
|
||||
if basePath != "" {
|
||||
specBasePath, _ = absPath(basePath)
|
||||
}
|
||||
opts := &ExpandOptions{
|
||||
RelativeBase: specBasePath,
|
||||
}
|
||||
resolver, err := defaultSchemaLoader(nil, opts, nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := optionsOrDefault(&ExpandOptions{
|
||||
RelativeBase: basePath,
|
||||
})
|
||||
resolver := defaultSchemaLoader(nil, opts, nil, nil)
|
||||
|
||||
return expandParameterOrResponse(parameter, resolver, opts.RelativeBase)
|
||||
}
|
||||
|
||||
func getRefAndSchema(input interface{}) (*Ref, *Schema, error) {
|
||||
var ref *Ref
|
||||
var sch *Schema
|
||||
var (
|
||||
ref *Ref
|
||||
sch *Schema
|
||||
)
|
||||
|
||||
switch refable := input.(type) {
|
||||
case *Parameter:
|
||||
if refable == nil {
|
||||
@@ -601,8 +513,9 @@ func getRefAndSchema(input interface{}) (*Ref, *Schema, error) {
|
||||
ref = &refable.Ref
|
||||
sch = refable.Schema
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("expand: unsupported type %T. Input should be of type *Parameter or *Response", input)
|
||||
return nil, nil, fmt.Errorf("unsupported type: %T: %w", input, ErrExpandUnsupportedType)
|
||||
}
|
||||
|
||||
return ref, sch, nil
|
||||
}
|
||||
|
||||
@@ -611,41 +524,71 @@ func expandParameterOrResponse(input interface{}, resolver *schemaLoader, basePa
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ref == nil {
|
||||
return nil
|
||||
}
|
||||
parentRefs := []string{}
|
||||
if err := resolver.deref(input, parentRefs, basePath); resolver.shouldStopOnError(err) {
|
||||
|
||||
parentRefs := make([]string, 0, 10)
|
||||
if err = resolver.deref(input, parentRefs, basePath); resolver.shouldStopOnError(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
ref, sch, _ := getRefAndSchema(input)
|
||||
if ref.String() != "" {
|
||||
transitiveResolver, err := resolver.transitiveResolver(basePath, *ref)
|
||||
if transitiveResolver.shouldStopOnError(err) {
|
||||
return err
|
||||
}
|
||||
transitiveResolver := resolver.transitiveResolver(basePath, *ref)
|
||||
basePath = resolver.updateBasePath(transitiveResolver, basePath)
|
||||
resolver = transitiveResolver
|
||||
}
|
||||
|
||||
if sch != nil && sch.Ref.String() != "" {
|
||||
// schema expanded to a $ref in another root
|
||||
var ern error
|
||||
sch.Ref, ern = NewRef(normalizePaths(sch.Ref.String(), ref.RemoteURI()))
|
||||
if sch == nil {
|
||||
// nothing to be expanded
|
||||
if ref != nil {
|
||||
*ref = Ref{}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if sch.Ref.String() != "" {
|
||||
rebasedRef, ern := NewRef(normalizeURI(sch.Ref.String(), basePath))
|
||||
if ern != nil {
|
||||
return ern
|
||||
}
|
||||
|
||||
switch {
|
||||
case resolver.isCircular(&rebasedRef, basePath, parentRefs...):
|
||||
// this is a circular $ref: stop expansion
|
||||
if !resolver.options.AbsoluteCircularRef {
|
||||
sch.Ref = denormalizeRef(&rebasedRef, resolver.context.basePath, resolver.context.rootID)
|
||||
} else {
|
||||
sch.Ref = rebasedRef
|
||||
}
|
||||
case !resolver.options.SkipSchemas:
|
||||
// schema expanded to a $ref in another root
|
||||
sch.Ref = rebasedRef
|
||||
debugLog("rebased to: %s", sch.Ref.String())
|
||||
default:
|
||||
// skip schema expansion but rebase $ref to schema
|
||||
sch.Ref = denormalizeRef(&rebasedRef, resolver.context.basePath, resolver.context.rootID)
|
||||
}
|
||||
}
|
||||
|
||||
if ref != nil {
|
||||
*ref = Ref{}
|
||||
}
|
||||
|
||||
if !resolver.options.SkipSchemas && sch != nil {
|
||||
// expand schema
|
||||
if !resolver.options.SkipSchemas {
|
||||
s, err := expandSchema(*sch, parentRefs, resolver, basePath)
|
||||
if resolver.shouldStopOnError(err) {
|
||||
return err
|
||||
}
|
||||
if s == nil {
|
||||
// guard for when continuing on error
|
||||
return nil
|
||||
}
|
||||
*sch = *s
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
6
vendor/github.com/go-openapi/spec/header.go
generated
vendored
6
vendor/github.com/go-openapi/spec/header.go
generated
vendored
@@ -141,6 +141,12 @@ func (h *Header) AllowDuplicates() *Header {
|
||||
return h
|
||||
}
|
||||
|
||||
// WithValidations is a fluent method to set header validations
|
||||
func (h *Header) WithValidations(val CommonValidations) *Header {
|
||||
h.SetValidations(SchemaValidations{CommonValidations: val})
|
||||
return h
|
||||
}
|
||||
|
||||
// MarshalJSON marshal this to JSON
|
||||
func (h Header) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(h.CommonValidations)
|
||||
|
||||
22
vendor/github.com/go-openapi/spec/items.go
generated
vendored
22
vendor/github.com/go-openapi/spec/items.go
generated
vendored
@@ -53,22 +53,6 @@ func (s *SimpleSchema) ItemsTypeName() string {
|
||||
return s.Items.TypeName()
|
||||
}
|
||||
|
||||
// CommonValidations describe common JSON-schema validations
|
||||
type CommonValidations struct {
|
||||
Maximum *float64 `json:"maximum,omitempty"`
|
||||
ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"`
|
||||
Minimum *float64 `json:"minimum,omitempty"`
|
||||
ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"`
|
||||
MaxLength *int64 `json:"maxLength,omitempty"`
|
||||
MinLength *int64 `json:"minLength,omitempty"`
|
||||
Pattern string `json:"pattern,omitempty"`
|
||||
MaxItems *int64 `json:"maxItems,omitempty"`
|
||||
MinItems *int64 `json:"minItems,omitempty"`
|
||||
UniqueItems bool `json:"uniqueItems,omitempty"`
|
||||
MultipleOf *float64 `json:"multipleOf,omitempty"`
|
||||
Enum []interface{} `json:"enum,omitempty"`
|
||||
}
|
||||
|
||||
// Items a limited subset of JSON-Schema's items object.
|
||||
// It is used by parameter definitions that are not located in "body".
|
||||
//
|
||||
@@ -180,6 +164,12 @@ func (i *Items) AllowDuplicates() *Items {
|
||||
return i
|
||||
}
|
||||
|
||||
// WithValidations is a fluent method to set Items validations
|
||||
func (i *Items) WithValidations(val CommonValidations) *Items {
|
||||
i.SetValidations(SchemaValidations{CommonValidations: val})
|
||||
return i
|
||||
}
|
||||
|
||||
// UnmarshalJSON hydrates this items instance with the data from JSON
|
||||
func (i *Items) UnmarshalJSON(data []byte) error {
|
||||
var validations CommonValidations
|
||||
|
||||
3
vendor/github.com/go-openapi/spec/license.go
generated
vendored
3
vendor/github.com/go-openapi/spec/license.go
generated
vendored
@@ -28,11 +28,13 @@ type License struct {
|
||||
VendorExtensible
|
||||
}
|
||||
|
||||
// LicenseProps holds the properties of a License object
|
||||
type LicenseProps struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON hydrates License from json
|
||||
func (l *License) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &l.LicenseProps); err != nil {
|
||||
return err
|
||||
@@ -40,6 +42,7 @@ func (l *License) UnmarshalJSON(data []byte) error {
|
||||
return json.Unmarshal(data, &l.VendorExtensible)
|
||||
}
|
||||
|
||||
// MarshalJSON produces License as json
|
||||
func (l License) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(l.LicenseProps)
|
||||
if err != nil {
|
||||
|
||||
264
vendor/github.com/go-openapi/spec/normalizer.go
generated
vendored
264
vendor/github.com/go-openapi/spec/normalizer.go
generated
vendored
@@ -15,138 +15,188 @@
|
||||
package spec
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// normalize absolute path for cache.
|
||||
// on Windows, drive letters should be converted to lower as scheme in net/url.URL
|
||||
func normalizeAbsPath(path string) string {
|
||||
u, err := url.Parse(path)
|
||||
const fileScheme = "file"
|
||||
|
||||
// normalizeURI ensures that all $ref paths used internally by the expander are canonicalized.
|
||||
//
|
||||
// NOTE(windows): there is a tolerance over the strict URI format on windows.
|
||||
//
|
||||
// The normalizer accepts relative file URLs like 'Path\File.JSON' as well as absolute file URLs like
|
||||
// 'C:\Path\file.Yaml'.
|
||||
//
|
||||
// Both are canonicalized with a "file://" scheme, slashes and a lower-cased path:
|
||||
// 'file:///c:/path/file.yaml'
|
||||
//
|
||||
// URLs can be specified with a file scheme, like in 'file:///folder/file.json' or
|
||||
// 'file:///c:\folder\File.json'.
|
||||
//
|
||||
// URLs like file://C:\folder are considered invalid (i.e. there is no host 'c:\folder') and a "repair"
|
||||
// is attempted.
|
||||
//
|
||||
// The base path argument is assumed to be canonicalized (e.g. using normalizeBase()).
|
||||
func normalizeURI(refPath, base string) string {
|
||||
refURL, err := parseURL(refPath)
|
||||
if err != nil {
|
||||
debugLog("normalize absolute path failed: %s", err)
|
||||
return path
|
||||
}
|
||||
return u.String()
|
||||
}
|
||||
|
||||
// base or refPath could be a file path or a URL
|
||||
// given a base absolute path and a ref path, return the absolute path of refPath
|
||||
// 1) if refPath is absolute, return it
|
||||
// 2) if refPath is relative, join it with basePath keeping the scheme, hosts, and ports if exists
|
||||
// base could be a directory or a full file path
|
||||
func normalizePaths(refPath, base string) string {
|
||||
refURL, _ := url.Parse(refPath)
|
||||
if path.IsAbs(refURL.Path) || filepath.IsAbs(refPath) {
|
||||
// refPath is actually absolute
|
||||
if refURL.Host != "" {
|
||||
return refPath
|
||||
}
|
||||
parts := strings.Split(refPath, "#")
|
||||
result := filepath.FromSlash(parts[0])
|
||||
if len(parts) == 2 {
|
||||
result += "#" + parts[1]
|
||||
}
|
||||
return result
|
||||
specLogger.Printf("warning: invalid URI in $ref %q: %v", refPath, err)
|
||||
refURL, refPath = repairURI(refPath)
|
||||
}
|
||||
|
||||
// relative refPath
|
||||
baseURL, _ := url.Parse(base)
|
||||
if !strings.HasPrefix(refPath, "#") {
|
||||
// combining paths
|
||||
if baseURL.Host != "" {
|
||||
baseURL.Path = path.Join(path.Dir(baseURL.Path), refURL.Path)
|
||||
} else { // base is a file
|
||||
newBase := fmt.Sprintf("%s#%s", filepath.Join(filepath.Dir(base), filepath.FromSlash(refURL.Path)), refURL.Fragment)
|
||||
return newBase
|
||||
}
|
||||
fixWindowsURI(refURL, refPath) // noop on non-windows OS
|
||||
|
||||
refURL.Path = path.Clean(refURL.Path)
|
||||
if refURL.Path == "." {
|
||||
refURL.Path = ""
|
||||
}
|
||||
|
||||
r := MustCreateRef(refURL.String())
|
||||
if r.IsCanonical() {
|
||||
return refURL.String()
|
||||
}
|
||||
|
||||
baseURL, _ := parseURL(base)
|
||||
if path.IsAbs(refURL.Path) {
|
||||
baseURL.Path = refURL.Path
|
||||
} else if refURL.Path != "" {
|
||||
baseURL.Path = path.Join(path.Dir(baseURL.Path), refURL.Path)
|
||||
}
|
||||
// copying fragment from ref to base
|
||||
baseURL.Fragment = refURL.Fragment
|
||||
|
||||
return baseURL.String()
|
||||
}
|
||||
|
||||
// denormalizePaths returns to simplest notation on file $ref,
|
||||
// i.e. strips the absolute path and sets a path relative to the base path.
|
||||
// denormalizeRef returns the simplest notation for a normalized $ref, given the path of the original root document.
|
||||
//
|
||||
// This is currently used when we rewrite ref after a circular ref has been detected
|
||||
func denormalizeFileRef(ref *Ref, relativeBase, originalRelativeBase string) *Ref {
|
||||
debugLog("denormalizeFileRef for: %s", ref.String())
|
||||
// When calling this, we assume that:
|
||||
// * $ref is a canonical URI
|
||||
// * originalRelativeBase is a canonical URI
|
||||
//
|
||||
// denormalizeRef is currently used when we rewrite a $ref after a circular $ref has been detected.
|
||||
// In this case, expansion stops and normally renders the internal canonical $ref.
|
||||
//
|
||||
// This internal $ref is eventually rebased to the original RelativeBase used for the expansion.
|
||||
//
|
||||
// There is a special case for schemas that are anchored with an "id":
|
||||
// in that case, the rebasing is performed // against the id only if this is an anchor for the initial root document.
|
||||
// All other intermediate "id"'s found along the way are ignored for the purpose of rebasing.
|
||||
func denormalizeRef(ref *Ref, originalRelativeBase, id string) Ref {
|
||||
debugLog("denormalizeRef called:\n$ref: %q\noriginal: %s\nroot ID:%s", ref.String(), originalRelativeBase, id)
|
||||
|
||||
if ref.String() == "" || ref.IsRoot() || ref.HasFragmentOnly {
|
||||
return ref
|
||||
}
|
||||
// strip relativeBase from URI
|
||||
relativeBaseURL, _ := url.Parse(relativeBase)
|
||||
relativeBaseURL.Fragment = ""
|
||||
|
||||
if relativeBaseURL.IsAbs() && strings.HasPrefix(ref.String(), relativeBase) {
|
||||
// this should work for absolute URI (e.g. http://...): we have an exact match, just trim prefix
|
||||
r, _ := NewRef(strings.TrimPrefix(ref.String(), relativeBase))
|
||||
return &r
|
||||
// short circuit: $ref to current doc
|
||||
return *ref
|
||||
}
|
||||
|
||||
if relativeBaseURL.IsAbs() {
|
||||
// other absolute URL get unchanged (i.e. with a non-empty scheme)
|
||||
return ref
|
||||
if id != "" {
|
||||
idBaseURL, err := parseURL(id)
|
||||
if err == nil { // if the schema id is not usable as a URI, ignore it
|
||||
if ref, ok := rebase(ref, idBaseURL, true); ok { // rebase, but keep references to root unchaged (do not want $ref: "")
|
||||
// $ref relative to the ID of the schema in the root document
|
||||
return ref
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for relative file URIs:
|
||||
originalRelativeBaseURL, _ := url.Parse(originalRelativeBase)
|
||||
originalRelativeBaseURL.Fragment = ""
|
||||
if strings.HasPrefix(ref.String(), originalRelativeBaseURL.String()) {
|
||||
// the resulting ref is in the expanded spec: return a local ref
|
||||
r, _ := NewRef(strings.TrimPrefix(ref.String(), originalRelativeBaseURL.String()))
|
||||
return &r
|
||||
originalRelativeBaseURL, _ := parseURL(originalRelativeBase)
|
||||
|
||||
r, _ := rebase(ref, originalRelativeBaseURL, false)
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func rebase(ref *Ref, v *url.URL, notEqual bool) (Ref, bool) {
|
||||
var newBase url.URL
|
||||
|
||||
u := ref.GetURL()
|
||||
|
||||
if u.Scheme != v.Scheme || u.Host != v.Host {
|
||||
return *ref, false
|
||||
}
|
||||
|
||||
// check if we may set a relative path, considering the original base path for this spec.
|
||||
// Example:
|
||||
// spec is located at /mypath/spec.json
|
||||
// my normalized ref points to: /mypath/item.json#/target
|
||||
// expected result: item.json#/target
|
||||
parts := strings.Split(ref.String(), "#")
|
||||
relativePath, err := filepath.Rel(path.Dir(originalRelativeBaseURL.String()), parts[0])
|
||||
docPath := v.Path
|
||||
v.Path = path.Dir(v.Path)
|
||||
|
||||
if v.Path == "." {
|
||||
v.Path = ""
|
||||
} else if !strings.HasSuffix(v.Path, "/") {
|
||||
v.Path += "/"
|
||||
}
|
||||
|
||||
newBase.Fragment = u.Fragment
|
||||
|
||||
if strings.HasPrefix(u.Path, docPath) {
|
||||
newBase.Path = strings.TrimPrefix(u.Path, docPath)
|
||||
} else {
|
||||
newBase.Path = strings.TrimPrefix(u.Path, v.Path)
|
||||
}
|
||||
|
||||
if notEqual && newBase.Path == "" && newBase.Fragment == "" {
|
||||
// do not want rebasing to end up in an empty $ref
|
||||
return *ref, false
|
||||
}
|
||||
|
||||
if path.IsAbs(newBase.Path) {
|
||||
// whenever we end up with an absolute path, specify the scheme and host
|
||||
newBase.Scheme = v.Scheme
|
||||
newBase.Host = v.Host
|
||||
}
|
||||
|
||||
return MustCreateRef(newBase.String()), true
|
||||
}
|
||||
|
||||
// normalizeRef canonicalize a Ref, using a canonical relativeBase as its absolute anchor
|
||||
func normalizeRef(ref *Ref, relativeBase string) *Ref {
|
||||
r := MustCreateRef(normalizeURI(ref.String(), relativeBase))
|
||||
return &r
|
||||
}
|
||||
|
||||
// normalizeBase performs a normalization of the input base path.
|
||||
//
|
||||
// This always yields a canonical URI (absolute), usable for the document cache.
|
||||
//
|
||||
// It ensures that all further internal work on basePath may safely assume
|
||||
// a non-empty, cross-platform, canonical URI (i.e. absolute).
|
||||
//
|
||||
// This normalization tolerates windows paths (e.g. C:\x\y\File.dat) and transform this
|
||||
// in a file:// URL with lower cased drive letter and path.
|
||||
//
|
||||
// See also: https://en.wikipedia.org/wiki/File_URI_scheme
|
||||
func normalizeBase(in string) string {
|
||||
u, err := parseURL(in)
|
||||
if err != nil {
|
||||
// there is no common ancestor (e.g. different drives on windows)
|
||||
// leaves the ref unchanged
|
||||
return ref
|
||||
specLogger.Printf("warning: invalid URI in RelativeBase %q: %v", in, err)
|
||||
u, in = repairURI(in)
|
||||
}
|
||||
if len(parts) == 2 {
|
||||
relativePath += "#" + parts[1]
|
||||
|
||||
u.Fragment = "" // any fragment in the base is irrelevant
|
||||
|
||||
fixWindowsURI(u, in) // noop on non-windows OS
|
||||
|
||||
u.Path = path.Clean(u.Path)
|
||||
if u.Path == "." { // empty after Clean()
|
||||
u.Path = ""
|
||||
}
|
||||
r, _ := NewRef(relativePath)
|
||||
return &r
|
||||
}
|
||||
|
||||
// relativeBase could be an ABSOLUTE file path or an ABSOLUTE URL
|
||||
func normalizeFileRef(ref *Ref, relativeBase string) *Ref {
|
||||
// This is important for when the reference is pointing to the root schema
|
||||
if ref.String() == "" {
|
||||
r, _ := NewRef(relativeBase)
|
||||
return &r
|
||||
}
|
||||
|
||||
debugLog("normalizing %s against %s", ref.String(), relativeBase)
|
||||
|
||||
s := normalizePaths(ref.String(), relativeBase)
|
||||
r, _ := NewRef(s)
|
||||
return &r
|
||||
}
|
||||
|
||||
// absPath returns the absolute path of a file
|
||||
func absPath(fname string) (string, error) {
|
||||
if strings.HasPrefix(fname, "http") {
|
||||
return fname, nil
|
||||
}
|
||||
if filepath.IsAbs(fname) {
|
||||
return fname, nil
|
||||
}
|
||||
wd, err := os.Getwd()
|
||||
return filepath.Join(wd, fname), err
|
||||
|
||||
if u.Scheme != "" {
|
||||
if path.IsAbs(u.Path) || u.Scheme != fileScheme {
|
||||
// this is absolute or explicitly not a local file: we're good
|
||||
return u.String()
|
||||
}
|
||||
}
|
||||
|
||||
// no scheme or file scheme with relative path: assume file and make it absolute
|
||||
// enforce scheme file://... with absolute path.
|
||||
//
|
||||
// If the input path is relative, we anchor the path to the current working directory.
|
||||
// NOTE: we may end up with a host component. Leave it unchanged: e.g. file://host/folder/file.json
|
||||
|
||||
u.Scheme = fileScheme
|
||||
u.Path = absPath(u.Path) // platform-dependent
|
||||
u.RawQuery = "" // any query component is irrelevant for a base
|
||||
return u.String()
|
||||
}
|
||||
|
||||
44
vendor/github.com/go-openapi/spec/normalizer_nonwindows.go
generated
vendored
Normal file
44
vendor/github.com/go-openapi/spec/normalizer_nonwindows.go
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
// 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 spec
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// absPath makes a file path absolute and compatible with a URI path component.
|
||||
//
|
||||
// The parameter must be a path, not an URI.
|
||||
func absPath(in string) string {
|
||||
anchored, err := filepath.Abs(in)
|
||||
if err != nil {
|
||||
specLogger.Printf("warning: could not resolve current working directory: %v", err)
|
||||
return in
|
||||
}
|
||||
return anchored
|
||||
}
|
||||
|
||||
func repairURI(in string) (*url.URL, string) {
|
||||
u, _ := parseURL("")
|
||||
debugLog("repaired URI: original: %q, repaired: %q", in, "")
|
||||
return u, ""
|
||||
}
|
||||
|
||||
func fixWindowsURI(u *url.URL, in string) {
|
||||
}
|
||||
154
vendor/github.com/go-openapi/spec/normalizer_windows.go
generated
vendored
Normal file
154
vendor/github.com/go-openapi/spec/normalizer_windows.go
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
// -build windows
|
||||
|
||||
// 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 spec
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// absPath makes a file path absolute and compatible with a URI path component
|
||||
//
|
||||
// The parameter must be a path, not an URI.
|
||||
func absPath(in string) string {
|
||||
// NOTE(windows): filepath.Abs exhibits a special behavior on windows for empty paths.
|
||||
// See https://github.com/golang/go/issues/24441
|
||||
if in == "" {
|
||||
in = "."
|
||||
}
|
||||
|
||||
anchored, err := filepath.Abs(in)
|
||||
if err != nil {
|
||||
specLogger.Printf("warning: could not resolve current working directory: %v", err)
|
||||
return in
|
||||
}
|
||||
|
||||
pth := strings.ReplaceAll(strings.ToLower(anchored), `\`, `/`)
|
||||
if !strings.HasPrefix(pth, "/") {
|
||||
pth = "/" + pth
|
||||
}
|
||||
|
||||
return path.Clean(pth)
|
||||
}
|
||||
|
||||
// repairURI tolerates invalid file URIs with common typos
|
||||
// such as 'file://E:\folder\file', that break the regular URL parser.
|
||||
//
|
||||
// Adopting the same defaults as for unixes (e.g. return an empty path) would
|
||||
// result into a counter-intuitive result for that case (e.g. E:\folder\file is
|
||||
// eventually resolved as the current directory). The repair will detect the missing "/".
|
||||
//
|
||||
// Note that this only works for the file scheme.
|
||||
func repairURI(in string) (*url.URL, string) {
|
||||
const prefix = fileScheme + "://"
|
||||
if !strings.HasPrefix(in, prefix) {
|
||||
// giving up: resolve to empty path
|
||||
u, _ := parseURL("")
|
||||
|
||||
return u, ""
|
||||
}
|
||||
|
||||
// attempt the repair, stripping the scheme should be sufficient
|
||||
u, _ := parseURL(strings.TrimPrefix(in, prefix))
|
||||
debugLog("repaired URI: original: %q, repaired: %q", in, u.String())
|
||||
|
||||
return u, u.String()
|
||||
}
|
||||
|
||||
// fixWindowsURI tolerates an absolute file path on windows such as C:\Base\File.yaml or \\host\share\Base\File.yaml
|
||||
// and makes it a canonical URI: file:///c:/base/file.yaml
|
||||
//
|
||||
// Catch 22 notes for Windows:
|
||||
//
|
||||
// * There may be a drive letter on windows (it is lower-cased)
|
||||
// * There may be a share UNC, e.g. \\server\folder\data.xml
|
||||
// * Paths are case insensitive
|
||||
// * Paths may already contain slashes
|
||||
// * Paths must be slashed
|
||||
//
|
||||
// NOTE: there is no escaping. "/" may be valid separators just like "\".
|
||||
// We don't use ToSlash() (which escapes everything) because windows now also
|
||||
// tolerates the use of "/". Hence, both C:\File.yaml and C:/File.yaml will work.
|
||||
func fixWindowsURI(u *url.URL, in string) {
|
||||
drive := filepath.VolumeName(in)
|
||||
|
||||
if len(drive) > 0 {
|
||||
if len(u.Scheme) == 1 && strings.EqualFold(u.Scheme, drive[:1]) { // a path with a drive letter
|
||||
u.Scheme = fileScheme
|
||||
u.Host = ""
|
||||
u.Path = strings.Join([]string{drive, u.Opaque, u.Path}, `/`) // reconstruct the full path component (no fragment, no query)
|
||||
} else if u.Host == "" && strings.HasPrefix(u.Path, drive) { // a path with a \\host volume
|
||||
// NOTE: the special host@port syntax for UNC is not supported (yet)
|
||||
u.Scheme = fileScheme
|
||||
|
||||
// this is a modified version of filepath.Dir() to apply on the VolumeName itself
|
||||
i := len(drive) - 1
|
||||
for i >= 0 && !os.IsPathSeparator(drive[i]) {
|
||||
i--
|
||||
}
|
||||
host := drive[:i] // \\host\share => host
|
||||
|
||||
u.Path = strings.TrimPrefix(u.Path, host)
|
||||
u.Host = strings.TrimPrefix(host, `\\`)
|
||||
}
|
||||
|
||||
u.Opaque = ""
|
||||
u.Path = strings.ReplaceAll(strings.ToLower(u.Path), `\`, `/`)
|
||||
|
||||
// ensure we form an absolute path
|
||||
if !strings.HasPrefix(u.Path, "/") {
|
||||
u.Path = "/" + u.Path
|
||||
}
|
||||
|
||||
u.Path = path.Clean(u.Path)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if u.Scheme == fileScheme {
|
||||
// Handle dodgy cases for file://{...} URIs on windows.
|
||||
// A canonical URI should always be followed by an absolute path.
|
||||
//
|
||||
// Examples:
|
||||
// * file:///folder/file => valid, unchanged
|
||||
// * file:///c:\folder\file => slashed
|
||||
// * file:///./folder/file => valid, cleaned to remove the dot
|
||||
// * file:///.\folder\file => remapped to cwd
|
||||
// * file:///. => dodgy, remapped to / (consistent with the behavior on unix)
|
||||
// * file:///.. => dodgy, remapped to / (consistent with the behavior on unix)
|
||||
if (!path.IsAbs(u.Path) && !filepath.IsAbs(u.Path)) || (strings.HasPrefix(u.Path, `/.`) && strings.Contains(u.Path, `\`)) {
|
||||
// ensure we form an absolute path
|
||||
u.Path, _ = filepath.Abs(strings.TrimLeft(u.Path, `/`))
|
||||
if !strings.HasPrefix(u.Path, "/") {
|
||||
u.Path = "/" + u.Path
|
||||
}
|
||||
}
|
||||
u.Path = strings.ToLower(u.Path)
|
||||
}
|
||||
|
||||
// NOTE: lower case normalization does not propagate to inner resources,
|
||||
// generated when rebasing: when joining a relative URI with a file to an absolute base,
|
||||
// only the base is currently lower-cased.
|
||||
//
|
||||
// For now, we assume this is good enough for most use cases
|
||||
// and try not to generate too many differences
|
||||
// between the output produced on different platforms.
|
||||
u.Path = path.Clean(strings.ReplaceAll(u.Path, `\`, `/`))
|
||||
}
|
||||
1
vendor/github.com/go-openapi/spec/operation.go
generated
vendored
1
vendor/github.com/go-openapi/spec/operation.go
generated
vendored
@@ -25,7 +25,6 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
//gob.Register(map[string][]interface{}{})
|
||||
gob.Register(map[string]interface{}{})
|
||||
gob.Register([]interface{}{})
|
||||
}
|
||||
|
||||
11
vendor/github.com/go-openapi/spec/parameter.go
generated
vendored
11
vendor/github.com/go-openapi/spec/parameter.go
generated
vendored
@@ -39,8 +39,7 @@ func PathParam(name string) *Parameter {
|
||||
|
||||
// BodyParam creates a body parameter
|
||||
func BodyParam(name string, schema *Schema) *Parameter {
|
||||
return &Parameter{ParamProps: ParamProps{Name: name, In: "body", Schema: schema},
|
||||
SimpleSchema: SimpleSchema{Type: "object"}}
|
||||
return &Parameter{ParamProps: ParamProps{Name: name, In: "body", Schema: schema}}
|
||||
}
|
||||
|
||||
// FormDataParam creates a body parameter
|
||||
@@ -58,7 +57,7 @@ func FileParam(name string) *Parameter {
|
||||
func SimpleArrayParam(name, tpe, fmt string) *Parameter {
|
||||
return &Parameter{ParamProps: ParamProps{Name: name},
|
||||
SimpleSchema: SimpleSchema{Type: jsonArray, CollectionFormat: "csv",
|
||||
Items: &Items{SimpleSchema: SimpleSchema{Type: "string", Format: fmt}}}}
|
||||
Items: &Items{SimpleSchema: SimpleSchema{Type: tpe, Format: fmt}}}}
|
||||
}
|
||||
|
||||
// ParamRef creates a parameter that's a json reference
|
||||
@@ -278,6 +277,12 @@ func (p *Parameter) AllowDuplicates() *Parameter {
|
||||
return p
|
||||
}
|
||||
|
||||
// WithValidations is a fluent method to set parameter validations
|
||||
func (p *Parameter) WithValidations(val CommonValidations) *Parameter {
|
||||
p.SetValidations(SchemaValidations{CommonValidations: val})
|
||||
return p
|
||||
}
|
||||
|
||||
// UnmarshalJSON hydrates this items instance with the data from JSON
|
||||
func (p *Parameter) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &p.CommonValidations); err != nil {
|
||||
|
||||
91
vendor/github.com/go-openapi/spec/properties.go
generated
vendored
Normal file
91
vendor/github.com/go-openapi/spec/properties.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
package spec
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// OrderSchemaItem holds a named schema (e.g. from a property of an object)
|
||||
type OrderSchemaItem struct {
|
||||
Name string
|
||||
Schema
|
||||
}
|
||||
|
||||
// OrderSchemaItems is a sortable slice of named schemas.
|
||||
// The ordering is defined by the x-order schema extension.
|
||||
type OrderSchemaItems []OrderSchemaItem
|
||||
|
||||
// MarshalJSON produces a json object with keys defined by the name schemas
|
||||
// of the OrderSchemaItems slice, keeping the original order of the slice.
|
||||
func (items OrderSchemaItems) MarshalJSON() ([]byte, error) {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
buf.WriteString("{")
|
||||
for i := range items {
|
||||
if i > 0 {
|
||||
buf.WriteString(",")
|
||||
}
|
||||
buf.WriteString("\"")
|
||||
buf.WriteString(items[i].Name)
|
||||
buf.WriteString("\":")
|
||||
bs, err := json.Marshal(&items[i].Schema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf.Write(bs)
|
||||
}
|
||||
buf.WriteString("}")
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func (items OrderSchemaItems) Len() int { return len(items) }
|
||||
func (items OrderSchemaItems) Swap(i, j int) { items[i], items[j] = items[j], items[i] }
|
||||
func (items OrderSchemaItems) Less(i, j int) (ret bool) {
|
||||
ii, oki := items[i].Extensions.GetString("x-order")
|
||||
ij, okj := items[j].Extensions.GetString("x-order")
|
||||
if oki {
|
||||
if okj {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
defer func() {
|
||||
if err = recover(); err != nil {
|
||||
ret = items[i].Name < items[j].Name
|
||||
}
|
||||
}()
|
||||
ret = reflect.ValueOf(ii).String() < reflect.ValueOf(ij).String()
|
||||
}
|
||||
}()
|
||||
return reflect.ValueOf(ii).Int() < reflect.ValueOf(ij).Int()
|
||||
}
|
||||
return true
|
||||
} else if okj {
|
||||
return false
|
||||
}
|
||||
return items[i].Name < items[j].Name
|
||||
}
|
||||
|
||||
// SchemaProperties is a map representing the properties of a Schema object.
|
||||
// It knows how to transform its keys into an ordered slice.
|
||||
type SchemaProperties map[string]Schema
|
||||
|
||||
// ToOrderedSchemaItems transforms the map of properties into a sortable slice
|
||||
func (properties SchemaProperties) ToOrderedSchemaItems() OrderSchemaItems {
|
||||
items := make(OrderSchemaItems, 0, len(properties))
|
||||
for k, v := range properties {
|
||||
items = append(items, OrderSchemaItem{
|
||||
Name: k,
|
||||
Schema: v,
|
||||
})
|
||||
}
|
||||
sort.Sort(items)
|
||||
return items
|
||||
}
|
||||
|
||||
// MarshalJSON produces properties as json, keeping their order.
|
||||
func (properties SchemaProperties) MarshalJSON() ([]byte, error) {
|
||||
if properties == nil {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
return json.Marshal(properties.ToOrderedSchemaItems())
|
||||
}
|
||||
4
vendor/github.com/go-openapi/spec/ref.go
generated
vendored
4
vendor/github.com/go-openapi/spec/ref.go
generated
vendored
@@ -48,7 +48,7 @@ type Ref struct {
|
||||
// RemoteURI gets the remote uri part of the ref
|
||||
func (r *Ref) RemoteURI() string {
|
||||
if r.String() == "" {
|
||||
return r.String()
|
||||
return ""
|
||||
}
|
||||
|
||||
u := *r.GetURL()
|
||||
@@ -68,7 +68,7 @@ func (r *Ref) IsValidURI(basepaths ...string) bool {
|
||||
}
|
||||
|
||||
if r.HasFullURL {
|
||||
//#nosec
|
||||
//nolint:noctx,gosec
|
||||
rr, err := http.Get(v)
|
||||
if err != nil {
|
||||
return false
|
||||
|
||||
127
vendor/github.com/go-openapi/spec/resolver.go
generated
vendored
Normal file
127
vendor/github.com/go-openapi/spec/resolver.go
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
package spec
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
func resolveAnyWithBase(root interface{}, ref *Ref, result interface{}, options *ExpandOptions) error {
|
||||
options = optionsOrDefault(options)
|
||||
resolver := defaultSchemaLoader(root, options, nil, nil)
|
||||
|
||||
if err := resolver.Resolve(ref, result, options.RelativeBase); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResolveRefWithBase resolves a reference against a context root with preservation of base path
|
||||
func ResolveRefWithBase(root interface{}, ref *Ref, options *ExpandOptions) (*Schema, error) {
|
||||
result := new(Schema)
|
||||
|
||||
if err := resolveAnyWithBase(root, ref, result, options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ResolveRef resolves a reference for a schema against a context root
|
||||
// ref is guaranteed to be in root (no need to go to external files)
|
||||
//
|
||||
// ResolveRef is ONLY called from the code generation module
|
||||
func ResolveRef(root interface{}, ref *Ref) (*Schema, error) {
|
||||
res, _, err := ref.GetPointer().Get(root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch sch := res.(type) {
|
||||
case Schema:
|
||||
return &sch, nil
|
||||
case *Schema:
|
||||
return sch, nil
|
||||
case map[string]interface{}:
|
||||
newSch := new(Schema)
|
||||
if err = swag.DynamicJSONToStruct(sch, newSch); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newSch, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("type: %T: %w", sch, ErrUnknownTypeForReference)
|
||||
}
|
||||
}
|
||||
|
||||
// ResolveParameterWithBase resolves a parameter reference against a context root and base path
|
||||
func ResolveParameterWithBase(root interface{}, ref Ref, options *ExpandOptions) (*Parameter, error) {
|
||||
result := new(Parameter)
|
||||
|
||||
if err := resolveAnyWithBase(root, &ref, result, options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ResolveParameter resolves a parameter reference against a context root
|
||||
func ResolveParameter(root interface{}, ref Ref) (*Parameter, error) {
|
||||
return ResolveParameterWithBase(root, ref, nil)
|
||||
}
|
||||
|
||||
// ResolveResponseWithBase resolves response a reference against a context root and base path
|
||||
func ResolveResponseWithBase(root interface{}, ref Ref, options *ExpandOptions) (*Response, error) {
|
||||
result := new(Response)
|
||||
|
||||
err := resolveAnyWithBase(root, &ref, result, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ResolveResponse resolves response a reference against a context root
|
||||
func ResolveResponse(root interface{}, ref Ref) (*Response, error) {
|
||||
return ResolveResponseWithBase(root, ref, nil)
|
||||
}
|
||||
|
||||
// ResolvePathItemWithBase resolves response a path item against a context root and base path
|
||||
func ResolvePathItemWithBase(root interface{}, ref Ref, options *ExpandOptions) (*PathItem, error) {
|
||||
result := new(PathItem)
|
||||
|
||||
if err := resolveAnyWithBase(root, &ref, result, options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ResolvePathItem resolves response a path item against a context root and base path
|
||||
//
|
||||
// Deprecated: use ResolvePathItemWithBase instead
|
||||
func ResolvePathItem(root interface{}, ref Ref, options *ExpandOptions) (*PathItem, error) {
|
||||
return ResolvePathItemWithBase(root, ref, options)
|
||||
}
|
||||
|
||||
// ResolveItemsWithBase resolves parameter items reference against a context root and base path.
|
||||
//
|
||||
// NOTE: stricly speaking, this construct is not supported by Swagger 2.0.
|
||||
// Similarly, $ref are forbidden in response headers.
|
||||
func ResolveItemsWithBase(root interface{}, ref Ref, options *ExpandOptions) (*Items, error) {
|
||||
result := new(Items)
|
||||
|
||||
if err := resolveAnyWithBase(root, &ref, result, options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ResolveItems resolves parameter items reference against a context root and base path.
|
||||
//
|
||||
// Deprecated: use ResolveItemsWithBase instead
|
||||
func ResolveItems(root interface{}, ref Ref, options *ExpandOptions) (*Items, error) {
|
||||
return ResolveItemsWithBase(root, ref, options)
|
||||
}
|
||||
25
vendor/github.com/go-openapi/spec/response.go
generated
vendored
25
vendor/github.com/go-openapi/spec/response.go
generated
vendored
@@ -23,7 +23,7 @@ import (
|
||||
|
||||
// ResponseProps properties specific to a response
|
||||
type ResponseProps struct {
|
||||
Description string `json:"description,omitempty"`
|
||||
Description string `json:"description"`
|
||||
Schema *Schema `json:"schema,omitempty"`
|
||||
Headers map[string]Header `json:"headers,omitempty"`
|
||||
Examples map[string]interface{} `json:"examples,omitempty"`
|
||||
@@ -63,10 +63,31 @@ func (r *Response) UnmarshalJSON(data []byte) error {
|
||||
|
||||
// MarshalJSON converts this items object to JSON
|
||||
func (r Response) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(r.ResponseProps)
|
||||
var (
|
||||
b1 []byte
|
||||
err error
|
||||
)
|
||||
|
||||
if r.Ref.String() == "" {
|
||||
// when there is no $ref, empty description is rendered as an empty string
|
||||
b1, err = json.Marshal(r.ResponseProps)
|
||||
} else {
|
||||
// when there is $ref inside the schema, description should be omitempty-ied
|
||||
b1, err = json.Marshal(struct {
|
||||
Description string `json:"description,omitempty"`
|
||||
Schema *Schema `json:"schema,omitempty"`
|
||||
Headers map[string]Header `json:"headers,omitempty"`
|
||||
Examples map[string]interface{} `json:"examples,omitempty"`
|
||||
}{
|
||||
Description: r.ResponseProps.Description,
|
||||
Schema: r.ResponseProps.Schema,
|
||||
Examples: r.ResponseProps.Examples,
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b2, err := json.Marshal(r.Refable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
123
vendor/github.com/go-openapi/spec/schema.go
generated
vendored
123
vendor/github.com/go-openapi/spec/schema.go
generated
vendored
@@ -17,7 +17,6 @@ package spec
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
@@ -145,7 +144,7 @@ func (r *SchemaURL) fromMap(v map[string]interface{}) error {
|
||||
}
|
||||
if vv, ok := v["$schema"]; ok {
|
||||
if str, ok := vv.(string); ok {
|
||||
u, err := url.Parse(str)
|
||||
u, err := parseURL(str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -158,41 +157,41 @@ func (r *SchemaURL) fromMap(v map[string]interface{}) error {
|
||||
|
||||
// SchemaProps describes a JSON schema (draft 4)
|
||||
type SchemaProps struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Ref Ref `json:"-"`
|
||||
Schema SchemaURL `json:"-"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Type StringOrArray `json:"type,omitempty"`
|
||||
Nullable bool `json:"nullable,omitempty"`
|
||||
Format string `json:"format,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Default interface{} `json:"default,omitempty"`
|
||||
Maximum *float64 `json:"maximum,omitempty"`
|
||||
ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"`
|
||||
Minimum *float64 `json:"minimum,omitempty"`
|
||||
ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"`
|
||||
MaxLength *int64 `json:"maxLength,omitempty"`
|
||||
MinLength *int64 `json:"minLength,omitempty"`
|
||||
Pattern string `json:"pattern,omitempty"`
|
||||
MaxItems *int64 `json:"maxItems,omitempty"`
|
||||
MinItems *int64 `json:"minItems,omitempty"`
|
||||
UniqueItems bool `json:"uniqueItems,omitempty"`
|
||||
MultipleOf *float64 `json:"multipleOf,omitempty"`
|
||||
Enum []interface{} `json:"enum,omitempty"`
|
||||
MaxProperties *int64 `json:"maxProperties,omitempty"`
|
||||
MinProperties *int64 `json:"minProperties,omitempty"`
|
||||
Required []string `json:"required,omitempty"`
|
||||
Items *SchemaOrArray `json:"items,omitempty"`
|
||||
AllOf []Schema `json:"allOf,omitempty"`
|
||||
OneOf []Schema `json:"oneOf,omitempty"`
|
||||
AnyOf []Schema `json:"anyOf,omitempty"`
|
||||
Not *Schema `json:"not,omitempty"`
|
||||
Properties map[string]Schema `json:"properties,omitempty"`
|
||||
AdditionalProperties *SchemaOrBool `json:"additionalProperties,omitempty"`
|
||||
PatternProperties map[string]Schema `json:"patternProperties,omitempty"`
|
||||
Dependencies Dependencies `json:"dependencies,omitempty"`
|
||||
AdditionalItems *SchemaOrBool `json:"additionalItems,omitempty"`
|
||||
Definitions Definitions `json:"definitions,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Ref Ref `json:"-"`
|
||||
Schema SchemaURL `json:"-"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Type StringOrArray `json:"type,omitempty"`
|
||||
Nullable bool `json:"nullable,omitempty"`
|
||||
Format string `json:"format,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Default interface{} `json:"default,omitempty"`
|
||||
Maximum *float64 `json:"maximum,omitempty"`
|
||||
ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"`
|
||||
Minimum *float64 `json:"minimum,omitempty"`
|
||||
ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"`
|
||||
MaxLength *int64 `json:"maxLength,omitempty"`
|
||||
MinLength *int64 `json:"minLength,omitempty"`
|
||||
Pattern string `json:"pattern,omitempty"`
|
||||
MaxItems *int64 `json:"maxItems,omitempty"`
|
||||
MinItems *int64 `json:"minItems,omitempty"`
|
||||
UniqueItems bool `json:"uniqueItems,omitempty"`
|
||||
MultipleOf *float64 `json:"multipleOf,omitempty"`
|
||||
Enum []interface{} `json:"enum,omitempty"`
|
||||
MaxProperties *int64 `json:"maxProperties,omitempty"`
|
||||
MinProperties *int64 `json:"minProperties,omitempty"`
|
||||
Required []string `json:"required,omitempty"`
|
||||
Items *SchemaOrArray `json:"items,omitempty"`
|
||||
AllOf []Schema `json:"allOf,omitempty"`
|
||||
OneOf []Schema `json:"oneOf,omitempty"`
|
||||
AnyOf []Schema `json:"anyOf,omitempty"`
|
||||
Not *Schema `json:"not,omitempty"`
|
||||
Properties SchemaProperties `json:"properties,omitempty"`
|
||||
AdditionalProperties *SchemaOrBool `json:"additionalProperties,omitempty"`
|
||||
PatternProperties SchemaProperties `json:"patternProperties,omitempty"`
|
||||
Dependencies Dependencies `json:"dependencies,omitempty"`
|
||||
AdditionalItems *SchemaOrBool `json:"additionalItems,omitempty"`
|
||||
Definitions Definitions `json:"definitions,omitempty"`
|
||||
}
|
||||
|
||||
// SwaggerSchemaProps are additional properties supported by swagger schemas, but not JSON-schema (draft 4)
|
||||
@@ -513,6 +512,56 @@ func (s *Schema) AsUnwrappedXML() *Schema {
|
||||
return s
|
||||
}
|
||||
|
||||
// SetValidations defines all schema validations.
|
||||
//
|
||||
// NOTE: Required, ReadOnly, AllOf, AnyOf, OneOf and Not are not considered.
|
||||
func (s *Schema) SetValidations(val SchemaValidations) {
|
||||
s.Maximum = val.Maximum
|
||||
s.ExclusiveMaximum = val.ExclusiveMaximum
|
||||
s.Minimum = val.Minimum
|
||||
s.ExclusiveMinimum = val.ExclusiveMinimum
|
||||
s.MaxLength = val.MaxLength
|
||||
s.MinLength = val.MinLength
|
||||
s.Pattern = val.Pattern
|
||||
s.MaxItems = val.MaxItems
|
||||
s.MinItems = val.MinItems
|
||||
s.UniqueItems = val.UniqueItems
|
||||
s.MultipleOf = val.MultipleOf
|
||||
s.Enum = val.Enum
|
||||
s.MinProperties = val.MinProperties
|
||||
s.MaxProperties = val.MaxProperties
|
||||
s.PatternProperties = val.PatternProperties
|
||||
}
|
||||
|
||||
// WithValidations is a fluent method to set schema validations
|
||||
func (s *Schema) WithValidations(val SchemaValidations) *Schema {
|
||||
s.SetValidations(val)
|
||||
return s
|
||||
}
|
||||
|
||||
// Validations returns a clone of the validations for this schema
|
||||
func (s Schema) Validations() SchemaValidations {
|
||||
return SchemaValidations{
|
||||
CommonValidations: CommonValidations{
|
||||
Maximum: s.Maximum,
|
||||
ExclusiveMaximum: s.ExclusiveMaximum,
|
||||
Minimum: s.Minimum,
|
||||
ExclusiveMinimum: s.ExclusiveMinimum,
|
||||
MaxLength: s.MaxLength,
|
||||
MinLength: s.MinLength,
|
||||
Pattern: s.Pattern,
|
||||
MaxItems: s.MaxItems,
|
||||
MinItems: s.MinItems,
|
||||
UniqueItems: s.UniqueItems,
|
||||
MultipleOf: s.MultipleOf,
|
||||
Enum: s.Enum,
|
||||
},
|
||||
MinProperties: s.MinProperties,
|
||||
MaxProperties: s.MaxProperties,
|
||||
PatternProperties: s.PatternProperties,
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalJSON marshal this to JSON
|
||||
func (s Schema) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(s.SchemaProps)
|
||||
|
||||
245
vendor/github.com/go-openapi/spec/schema_loader.go
generated
vendored
245
vendor/github.com/go-openapi/spec/schema_loader.go
generated
vendored
@@ -25,35 +25,50 @@ import (
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// PathLoader function to use when loading remote refs
|
||||
var PathLoader func(string) (json.RawMessage, error)
|
||||
|
||||
func init() {
|
||||
PathLoader = func(path string) (json.RawMessage, error) {
|
||||
data, err := swag.LoadFromFileOrHTTP(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.RawMessage(data), nil
|
||||
// PathLoader is a function to use when loading remote refs.
|
||||
//
|
||||
// This is a package level default. It may be overridden or bypassed by
|
||||
// specifying the loader in ExpandOptions.
|
||||
//
|
||||
// NOTE: if you are using the go-openapi/loads package, it will override
|
||||
// this value with its own default (a loader to retrieve YAML documents as
|
||||
// well as JSON ones).
|
||||
var PathLoader = func(pth string) (json.RawMessage, error) {
|
||||
data, err := swag.LoadFromFileOrHTTP(pth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.RawMessage(data), nil
|
||||
}
|
||||
|
||||
// resolverContext allows to share a context during spec processing.
|
||||
// At the moment, it just holds the index of circular references found.
|
||||
type resolverContext struct {
|
||||
// circulars holds all visited circular references, which allows shortcuts.
|
||||
// NOTE: this is not just a performance improvement: it is required to figure out
|
||||
// circular references which participate several cycles.
|
||||
// circulars holds all visited circular references, to shortcircuit $ref resolution.
|
||||
//
|
||||
// This structure is privately instantiated and needs not be locked against
|
||||
// concurrent access, unless we chose to implement a parallel spec walking.
|
||||
circulars map[string]bool
|
||||
basePath string
|
||||
loadDoc func(string) (json.RawMessage, error)
|
||||
rootID string
|
||||
}
|
||||
|
||||
func newResolverContext(originalBasePath string) *resolverContext {
|
||||
func newResolverContext(options *ExpandOptions) *resolverContext {
|
||||
expandOptions := optionsOrDefault(options)
|
||||
|
||||
// path loader may be overridden by options
|
||||
var loader func(string) (json.RawMessage, error)
|
||||
if expandOptions.PathLoader == nil {
|
||||
loader = PathLoader
|
||||
} else {
|
||||
loader = expandOptions.PathLoader
|
||||
}
|
||||
|
||||
return &resolverContext{
|
||||
circulars: make(map[string]bool),
|
||||
basePath: originalBasePath, // keep the root base path in context
|
||||
basePath: expandOptions.RelativeBase, // keep the root base path in context
|
||||
loadDoc: loader,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,21 +77,20 @@ type schemaLoader struct {
|
||||
options *ExpandOptions
|
||||
cache ResolutionCache
|
||||
context *resolverContext
|
||||
loadDoc func(string) (json.RawMessage, error)
|
||||
}
|
||||
|
||||
func (r *schemaLoader) transitiveResolver(basePath string, ref Ref) (*schemaLoader, error) {
|
||||
func (r *schemaLoader) transitiveResolver(basePath string, ref Ref) *schemaLoader {
|
||||
if ref.IsRoot() || ref.HasFragmentOnly {
|
||||
return r, nil
|
||||
return r
|
||||
}
|
||||
|
||||
baseRef, _ := NewRef(basePath)
|
||||
currentRef := normalizeFileRef(&ref, basePath)
|
||||
baseRef := MustCreateRef(basePath)
|
||||
currentRef := normalizeRef(&ref, basePath)
|
||||
if strings.HasPrefix(currentRef.String(), baseRef.String()) {
|
||||
return r, nil
|
||||
return r
|
||||
}
|
||||
|
||||
// Set a new root to resolve against
|
||||
// set a new root against which to resolve
|
||||
rootURL := currentRef.GetURL()
|
||||
rootURL.Fragment = ""
|
||||
root, _ := r.cache.Get(rootURL.String())
|
||||
@@ -85,35 +99,36 @@ func (r *schemaLoader) transitiveResolver(basePath string, ref Ref) (*schemaLoad
|
||||
// traversing multiple documents
|
||||
newOptions := r.options
|
||||
newOptions.RelativeBase = rootURL.String()
|
||||
debugLog("setting new root: %s", newOptions.RelativeBase)
|
||||
|
||||
return defaultSchemaLoader(root, newOptions, r.cache, r.context)
|
||||
}
|
||||
|
||||
func (r *schemaLoader) updateBasePath(transitive *schemaLoader, basePath string) string {
|
||||
if transitive != r {
|
||||
debugLog("got a new resolver")
|
||||
if transitive.options != nil && transitive.options.RelativeBase != "" {
|
||||
basePath, _ = absPath(transitive.options.RelativeBase)
|
||||
debugLog("new basePath = %s", basePath)
|
||||
return normalizeBase(transitive.options.RelativeBase)
|
||||
}
|
||||
}
|
||||
|
||||
return basePath
|
||||
}
|
||||
|
||||
func (r *schemaLoader) resolveRef(ref *Ref, target interface{}, basePath string) error {
|
||||
tgt := reflect.ValueOf(target)
|
||||
if tgt.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("resolve ref: target needs to be a pointer")
|
||||
return ErrResolveRefNeedsAPointer
|
||||
}
|
||||
|
||||
refURL := ref.GetURL()
|
||||
if refURL == nil {
|
||||
if ref.GetURL() == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var res interface{}
|
||||
var data interface{}
|
||||
var err error
|
||||
var (
|
||||
res interface{}
|
||||
data interface{}
|
||||
err error
|
||||
)
|
||||
|
||||
// Resolve against the root if it isn't nil, and if ref is pointing at the root, or has a fragment only which means
|
||||
// it is pointing somewhere in the root.
|
||||
root := r.root
|
||||
@@ -122,12 +137,11 @@ func (r *schemaLoader) resolveRef(ref *Ref, target interface{}, basePath string)
|
||||
root, _, _, _ = r.load(baseRef.GetURL())
|
||||
}
|
||||
}
|
||||
|
||||
if (ref.IsRoot() || ref.HasFragmentOnly) && root != nil {
|
||||
data = root
|
||||
} else {
|
||||
baseRef := normalizeFileRef(ref, basePath)
|
||||
debugLog("current ref is: %s", ref.String())
|
||||
debugLog("current ref normalized file: %s", baseRef.String())
|
||||
baseRef := normalizeRef(ref, basePath)
|
||||
data, _, _, err = r.load(baseRef.GetURL())
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -150,52 +164,60 @@ func (r *schemaLoader) load(refURL *url.URL) (interface{}, url.URL, bool, error)
|
||||
toFetch.Fragment = ""
|
||||
|
||||
var err error
|
||||
path := toFetch.String()
|
||||
if path == rootBase {
|
||||
path, err = absPath(rootBase)
|
||||
if err != nil {
|
||||
return nil, url.URL{}, false, err
|
||||
}
|
||||
}
|
||||
normalized := normalizeAbsPath(path)
|
||||
pth := toFetch.String()
|
||||
normalized := normalizeBase(pth)
|
||||
debugLog("loading doc from: %s", normalized)
|
||||
|
||||
data, fromCache := r.cache.Get(normalized)
|
||||
if !fromCache {
|
||||
b, err := r.loadDoc(normalized)
|
||||
if err != nil {
|
||||
debugLog("unable to load the document: %v", err)
|
||||
return nil, url.URL{}, false, err
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(b, &data); err != nil {
|
||||
return nil, url.URL{}, false, err
|
||||
}
|
||||
r.cache.Set(normalized, data)
|
||||
unescaped, err := url.PathUnescape(normalized)
|
||||
if err != nil {
|
||||
return nil, url.URL{}, false, err
|
||||
}
|
||||
|
||||
return data, toFetch, fromCache, nil
|
||||
u := url.URL{Path: unescaped}
|
||||
|
||||
data, fromCache := r.cache.Get(u.RequestURI())
|
||||
if fromCache {
|
||||
return data, toFetch, fromCache, nil
|
||||
}
|
||||
|
||||
b, err := r.context.loadDoc(normalized)
|
||||
if err != nil {
|
||||
return nil, url.URL{}, false, err
|
||||
}
|
||||
|
||||
var doc interface{}
|
||||
if err := json.Unmarshal(b, &doc); err != nil {
|
||||
return nil, url.URL{}, false, err
|
||||
}
|
||||
r.cache.Set(normalized, doc)
|
||||
|
||||
return doc, toFetch, fromCache, nil
|
||||
}
|
||||
|
||||
// isCircular detects cycles in sequences of $ref.
|
||||
//
|
||||
// It relies on a private context (which needs not be locked).
|
||||
func (r *schemaLoader) isCircular(ref *Ref, basePath string, parentRefs ...string) (foundCycle bool) {
|
||||
normalizedRef := normalizePaths(ref.String(), basePath)
|
||||
normalizedRef := normalizeURI(ref.String(), basePath)
|
||||
if _, ok := r.context.circulars[normalizedRef]; ok {
|
||||
// circular $ref has been already detected in another explored cycle
|
||||
foundCycle = true
|
||||
return
|
||||
}
|
||||
foundCycle = swag.ContainsStringsCI(parentRefs, normalizedRef)
|
||||
foundCycle = swag.ContainsStrings(parentRefs, normalizedRef) // normalized windows url's are lower cased
|
||||
if foundCycle {
|
||||
r.context.circulars[normalizedRef] = true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Resolve resolves a reference against basePath and stores the result in target
|
||||
// Resolve is not in charge of following references, it only resolves ref by following its URL
|
||||
// if the schema that ref is referring to has more refs in it. Resolve doesn't resolve them
|
||||
// if basePath is an empty string, ref is resolved against the root schema stored in the schemaLoader struct
|
||||
// Resolve resolves a reference against basePath and stores the result in target.
|
||||
//
|
||||
// Resolve is not in charge of following references: it only resolves ref by following its URL.
|
||||
//
|
||||
// If the schema the ref is referring to holds nested refs, Resolve doesn't resolve them.
|
||||
//
|
||||
// If basePath is an empty string, ref is resolved against the root schema stored in the schemaLoader struct
|
||||
func (r *schemaLoader) Resolve(ref *Ref, target interface{}, basePath string) error {
|
||||
return r.resolveRef(ref, target, basePath)
|
||||
}
|
||||
@@ -212,30 +234,32 @@ func (r *schemaLoader) deref(input interface{}, parentRefs []string, basePath st
|
||||
case *PathItem:
|
||||
ref = &refable.Ref
|
||||
default:
|
||||
return fmt.Errorf("deref: unsupported type %T", input)
|
||||
return fmt.Errorf("unsupported type: %T: %w", input, ErrDerefUnsupportedType)
|
||||
}
|
||||
|
||||
curRef := ref.String()
|
||||
if curRef != "" {
|
||||
normalizedRef := normalizeFileRef(ref, basePath)
|
||||
normalizedBasePath := normalizedRef.RemoteURI()
|
||||
|
||||
if r.isCircular(normalizedRef, basePath, parentRefs...) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := r.resolveRef(ref, input, basePath); r.shouldStopOnError(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
// NOTE(fredbi): removed basePath check => needs more testing
|
||||
if ref.String() != "" && ref.String() != curRef {
|
||||
parentRefs = append(parentRefs, normalizedRef.String())
|
||||
return r.deref(input, parentRefs, normalizedBasePath)
|
||||
}
|
||||
if curRef == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
normalizedRef := normalizeRef(ref, basePath)
|
||||
normalizedBasePath := normalizedRef.RemoteURI()
|
||||
|
||||
if r.isCircular(normalizedRef, basePath, parentRefs...) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := r.resolveRef(ref, input, basePath); r.shouldStopOnError(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if ref.String() == "" || ref.String() == curRef {
|
||||
// done with rereferencing
|
||||
return nil
|
||||
}
|
||||
|
||||
parentRefs = append(parentRefs, normalizedRef.String())
|
||||
return r.deref(input, parentRefs, normalizedBasePath)
|
||||
}
|
||||
|
||||
func (r *schemaLoader) shouldStopOnError(err error) bool {
|
||||
@@ -250,30 +274,65 @@ func (r *schemaLoader) shouldStopOnError(err error) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *schemaLoader) setSchemaID(target interface{}, id, basePath string) (string, string) {
|
||||
debugLog("schema has ID: %s", id)
|
||||
|
||||
// handling the case when id is a folder
|
||||
// remember that basePath has to point to a file
|
||||
var refPath string
|
||||
if strings.HasSuffix(id, "/") {
|
||||
// ensure this is detected as a file, not a folder
|
||||
refPath = fmt.Sprintf("%s%s", id, "placeholder.json")
|
||||
} else {
|
||||
refPath = id
|
||||
}
|
||||
|
||||
// updates the current base path
|
||||
// * important: ID can be a relative path
|
||||
// * registers target to be fetchable from the new base proposed by this id
|
||||
newBasePath := normalizeURI(refPath, basePath)
|
||||
|
||||
// store found IDs for possible future reuse in $ref
|
||||
r.cache.Set(newBasePath, target)
|
||||
|
||||
// the root document has an ID: all $ref relative to that ID may
|
||||
// be rebased relative to the root document
|
||||
if basePath == r.context.basePath {
|
||||
debugLog("root document is a schema with ID: %s (normalized as:%s)", id, newBasePath)
|
||||
r.context.rootID = newBasePath
|
||||
}
|
||||
|
||||
return newBasePath, refPath
|
||||
}
|
||||
|
||||
func defaultSchemaLoader(
|
||||
root interface{},
|
||||
expandOptions *ExpandOptions,
|
||||
cache ResolutionCache,
|
||||
context *resolverContext) (*schemaLoader, error) {
|
||||
context *resolverContext) *schemaLoader {
|
||||
|
||||
if cache == nil {
|
||||
cache = resCache
|
||||
}
|
||||
if expandOptions == nil {
|
||||
expandOptions = &ExpandOptions{}
|
||||
}
|
||||
absBase, _ := absPath(expandOptions.RelativeBase)
|
||||
if context == nil {
|
||||
context = newResolverContext(absBase)
|
||||
|
||||
cache = cacheOrDefault(cache)
|
||||
|
||||
if expandOptions.RelativeBase == "" {
|
||||
// if no relative base is provided, assume the root document
|
||||
// contains all $ref, or at least, that the relative documents
|
||||
// may be resolved from the current working directory.
|
||||
expandOptions.RelativeBase = baseForRoot(root, cache)
|
||||
}
|
||||
debugLog("effective expander options: %#v", expandOptions)
|
||||
|
||||
if context == nil {
|
||||
context = newResolverContext(expandOptions)
|
||||
}
|
||||
|
||||
return &schemaLoader{
|
||||
root: root,
|
||||
options: expandOptions,
|
||||
cache: cache,
|
||||
context: context,
|
||||
loadDoc: func(path string) (json.RawMessage, error) {
|
||||
debugLog("fetching document at %q", path)
|
||||
return PathLoader(path)
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
44
vendor/github.com/go-openapi/spec/security_scheme.go
generated
vendored
44
vendor/github.com/go-openapi/spec/security_scheme.go
generated
vendored
@@ -82,12 +82,12 @@ func OAuth2AccessToken(authorizationURL, tokenURL string) *SecurityScheme {
|
||||
type SecuritySchemeProps struct {
|
||||
Description string `json:"description,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name,omitempty"` // api key
|
||||
In string `json:"in,omitempty"` // api key
|
||||
Flow string `json:"flow,omitempty"` // oauth2
|
||||
AuthorizationURL string `json:"authorizationUrl,omitempty"` // oauth2
|
||||
TokenURL string `json:"tokenUrl,omitempty"` // oauth2
|
||||
Scopes map[string]string `json:"scopes,omitempty"` // oauth2
|
||||
Name string `json:"name,omitempty"` // api key
|
||||
In string `json:"in,omitempty"` // api key
|
||||
Flow string `json:"flow,omitempty"` // oauth2
|
||||
AuthorizationURL string `json:"authorizationUrl"` // oauth2
|
||||
TokenURL string `json:"tokenUrl,omitempty"` // oauth2
|
||||
Scopes map[string]string `json:"scopes,omitempty"` // oauth2
|
||||
}
|
||||
|
||||
// AddScope adds a scope to this security scheme
|
||||
@@ -120,10 +120,40 @@ func (s SecurityScheme) JSONLookup(token string) (interface{}, error) {
|
||||
|
||||
// MarshalJSON marshal this to JSON
|
||||
func (s SecurityScheme) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(s.SecuritySchemeProps)
|
||||
var (
|
||||
b1 []byte
|
||||
err error
|
||||
)
|
||||
|
||||
if s.Type == oauth2 && (s.Flow == "implicit" || s.Flow == "accessCode") {
|
||||
// when oauth2 for implicit or accessCode flows, empty AuthorizationURL is added as empty string
|
||||
b1, err = json.Marshal(s.SecuritySchemeProps)
|
||||
} else {
|
||||
// when not oauth2, empty AuthorizationURL should be omitted
|
||||
b1, err = json.Marshal(struct {
|
||||
Description string `json:"description,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name,omitempty"` // api key
|
||||
In string `json:"in,omitempty"` // api key
|
||||
Flow string `json:"flow,omitempty"` // oauth2
|
||||
AuthorizationURL string `json:"authorizationUrl,omitempty"` // oauth2
|
||||
TokenURL string `json:"tokenUrl,omitempty"` // oauth2
|
||||
Scopes map[string]string `json:"scopes,omitempty"` // oauth2
|
||||
}{
|
||||
Description: s.Description,
|
||||
Type: s.Type,
|
||||
Name: s.Name,
|
||||
In: s.In,
|
||||
Flow: s.Flow,
|
||||
AuthorizationURL: s.AuthorizationURL,
|
||||
TokenURL: s.TokenURL,
|
||||
Scopes: s.Scopes,
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b2, err := json.Marshal(s.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
14
vendor/github.com/go-openapi/spec/spec.go
generated
vendored
14
vendor/github.com/go-openapi/spec/spec.go
generated
vendored
@@ -14,7 +14,9 @@
|
||||
|
||||
package spec
|
||||
|
||||
import "encoding/json"
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
//go:generate curl -L --progress -o ./schemas/v2/schema.json http://swagger.io/v2/schema.json
|
||||
//go:generate curl -L --progress -o ./schemas/jsonschema-draft-04.json http://json-schema.org/draft-04/schema
|
||||
@@ -28,16 +30,6 @@ const (
|
||||
JSONSchemaURL = "http://json-schema.org/draft-04/schema#"
|
||||
)
|
||||
|
||||
var (
|
||||
jsonSchema *Schema
|
||||
swaggerSchema *Schema
|
||||
)
|
||||
|
||||
func init() {
|
||||
jsonSchema = MustLoadJSONSchemaDraft04()
|
||||
swaggerSchema = MustLoadSwagger20Schema()
|
||||
}
|
||||
|
||||
// MustLoadJSONSchemaDraft04 panics when Swagger20Schema returns an error
|
||||
func MustLoadJSONSchemaDraft04() *Schema {
|
||||
d, e := JSONSchemaDraft04()
|
||||
|
||||
174
vendor/github.com/go-openapi/spec/unused.go
generated
vendored
174
vendor/github.com/go-openapi/spec/unused.go
generated
vendored
@@ -1,174 +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.
|
||||
|
||||
package spec
|
||||
|
||||
/*
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
)
|
||||
|
||||
// Some currently unused functions and definitions that
|
||||
// used to be part of the expander.
|
||||
|
||||
// Moved here for the record and possible future reuse
|
||||
|
||||
var (
|
||||
idPtr, _ = jsonpointer.New("/id")
|
||||
refPtr, _ = jsonpointer.New("/$ref")
|
||||
)
|
||||
|
||||
func idFromNode(node interface{}) (*Ref, error) {
|
||||
if idValue, _, err := idPtr.Get(node); err == nil {
|
||||
if refStr, ok := idValue.(string); ok && refStr != "" {
|
||||
idRef, err := NewRef(refStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &idRef, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func nextRef(startingNode interface{}, startingRef *Ref, ptr *jsonpointer.Pointer) *Ref {
|
||||
if startingRef == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if ptr == nil {
|
||||
return startingRef
|
||||
}
|
||||
|
||||
ret := startingRef
|
||||
var idRef *Ref
|
||||
node := startingNode
|
||||
|
||||
for _, tok := range ptr.DecodedTokens() {
|
||||
node, _, _ = jsonpointer.GetForToken(node, tok)
|
||||
if node == nil {
|
||||
break
|
||||
}
|
||||
|
||||
idRef, _ = idFromNode(node)
|
||||
if idRef != nil {
|
||||
nw, err := ret.Inherits(*idRef)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
ret = nw
|
||||
}
|
||||
|
||||
refRef, _, _ := refPtr.Get(node)
|
||||
if refRef != nil {
|
||||
var rf Ref
|
||||
switch value := refRef.(type) {
|
||||
case string:
|
||||
rf, _ = NewRef(value)
|
||||
}
|
||||
nw, err := ret.Inherits(rf)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
nwURL := nw.GetURL()
|
||||
if nwURL.Scheme == "file" || (nwURL.Scheme == "" && nwURL.Host == "") {
|
||||
nwpt := filepath.ToSlash(nwURL.Path)
|
||||
if filepath.IsAbs(nwpt) {
|
||||
_, err := os.Stat(nwpt)
|
||||
if err != nil {
|
||||
nwURL.Path = filepath.Join(".", nwpt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = nw
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// basePathFromSchemaID returns a new basePath based on an existing basePath and a schema ID
|
||||
func basePathFromSchemaID(oldBasePath, id string) string {
|
||||
u, err := url.Parse(oldBasePath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
uid, err := url.Parse(id)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if path.IsAbs(uid.Path) {
|
||||
return id
|
||||
}
|
||||
u.Path = path.Join(path.Dir(u.Path), uid.Path)
|
||||
return u.String()
|
||||
}
|
||||
*/
|
||||
|
||||
// type ExtraSchemaProps map[string]interface{}
|
||||
|
||||
// // JSONSchema represents a structure that is a json schema draft 04
|
||||
// type JSONSchema struct {
|
||||
// SchemaProps
|
||||
// ExtraSchemaProps
|
||||
// }
|
||||
|
||||
// // MarshalJSON marshal this to JSON
|
||||
// func (s JSONSchema) MarshalJSON() ([]byte, error) {
|
||||
// b1, err := json.Marshal(s.SchemaProps)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// b2, err := s.Ref.MarshalJSON()
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// b3, err := s.Schema.MarshalJSON()
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// b4, err := json.Marshal(s.ExtraSchemaProps)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return swag.ConcatJSON(b1, b2, b3, b4), nil
|
||||
// }
|
||||
|
||||
// // UnmarshalJSON marshal this from JSON
|
||||
// func (s *JSONSchema) UnmarshalJSON(data []byte) error {
|
||||
// var sch JSONSchema
|
||||
// if err := json.Unmarshal(data, &sch.SchemaProps); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if err := json.Unmarshal(data, &sch.Ref); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if err := json.Unmarshal(data, &sch.Schema); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if err := json.Unmarshal(data, &sch.ExtraSchemaProps); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// *s = sch
|
||||
// return nil
|
||||
// }
|
||||
8
vendor/github.com/go-openapi/spec/url_go18.go
generated
vendored
Normal file
8
vendor/github.com/go-openapi/spec/url_go18.go
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
//go:build !go1.19
|
||||
// +build !go1.19
|
||||
|
||||
package spec
|
||||
|
||||
import "net/url"
|
||||
|
||||
var parseURL = url.Parse
|
||||
14
vendor/github.com/go-openapi/spec/url_go19.go
generated
vendored
Normal file
14
vendor/github.com/go-openapi/spec/url_go19.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build go1.19
|
||||
// +build go1.19
|
||||
|
||||
package spec
|
||||
|
||||
import "net/url"
|
||||
|
||||
func parseURL(s string) (*url.URL, error) {
|
||||
u, err := url.Parse(s)
|
||||
if err == nil {
|
||||
u.OmitHost = false
|
||||
}
|
||||
return u, err
|
||||
}
|
||||
215
vendor/github.com/go-openapi/spec/validations.go
generated
vendored
Normal file
215
vendor/github.com/go-openapi/spec/validations.go
generated
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
package spec
|
||||
|
||||
// CommonValidations describe common JSON-schema validations
|
||||
type CommonValidations struct {
|
||||
Maximum *float64 `json:"maximum,omitempty"`
|
||||
ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"`
|
||||
Minimum *float64 `json:"minimum,omitempty"`
|
||||
ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"`
|
||||
MaxLength *int64 `json:"maxLength,omitempty"`
|
||||
MinLength *int64 `json:"minLength,omitempty"`
|
||||
Pattern string `json:"pattern,omitempty"`
|
||||
MaxItems *int64 `json:"maxItems,omitempty"`
|
||||
MinItems *int64 `json:"minItems,omitempty"`
|
||||
UniqueItems bool `json:"uniqueItems,omitempty"`
|
||||
MultipleOf *float64 `json:"multipleOf,omitempty"`
|
||||
Enum []interface{} `json:"enum,omitempty"`
|
||||
}
|
||||
|
||||
// SetValidations defines all validations for a simple schema.
|
||||
//
|
||||
// NOTE: the input is the larger set of validations available for schemas.
|
||||
// For simple schemas, MinProperties and MaxProperties are ignored.
|
||||
func (v *CommonValidations) SetValidations(val SchemaValidations) {
|
||||
v.Maximum = val.Maximum
|
||||
v.ExclusiveMaximum = val.ExclusiveMaximum
|
||||
v.Minimum = val.Minimum
|
||||
v.ExclusiveMinimum = val.ExclusiveMinimum
|
||||
v.MaxLength = val.MaxLength
|
||||
v.MinLength = val.MinLength
|
||||
v.Pattern = val.Pattern
|
||||
v.MaxItems = val.MaxItems
|
||||
v.MinItems = val.MinItems
|
||||
v.UniqueItems = val.UniqueItems
|
||||
v.MultipleOf = val.MultipleOf
|
||||
v.Enum = val.Enum
|
||||
}
|
||||
|
||||
type clearedValidation struct {
|
||||
Validation string
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
type clearedValidations []clearedValidation
|
||||
|
||||
func (c clearedValidations) apply(cbs []func(string, interface{})) {
|
||||
for _, cb := range cbs {
|
||||
for _, cleared := range c {
|
||||
cb(cleared.Validation, cleared.Value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ClearNumberValidations clears all number validations.
|
||||
//
|
||||
// Some callbacks may be set by the caller to capture changed values.
|
||||
func (v *CommonValidations) ClearNumberValidations(cbs ...func(string, interface{})) {
|
||||
done := make(clearedValidations, 0, 5)
|
||||
defer func() {
|
||||
done.apply(cbs)
|
||||
}()
|
||||
|
||||
if v.Minimum != nil {
|
||||
done = append(done, clearedValidation{Validation: "minimum", Value: v.Minimum})
|
||||
v.Minimum = nil
|
||||
}
|
||||
if v.Maximum != nil {
|
||||
done = append(done, clearedValidation{Validation: "maximum", Value: v.Maximum})
|
||||
v.Maximum = nil
|
||||
}
|
||||
if v.ExclusiveMaximum {
|
||||
done = append(done, clearedValidation{Validation: "exclusiveMaximum", Value: v.ExclusiveMaximum})
|
||||
v.ExclusiveMaximum = false
|
||||
}
|
||||
if v.ExclusiveMinimum {
|
||||
done = append(done, clearedValidation{Validation: "exclusiveMinimum", Value: v.ExclusiveMinimum})
|
||||
v.ExclusiveMinimum = false
|
||||
}
|
||||
if v.MultipleOf != nil {
|
||||
done = append(done, clearedValidation{Validation: "multipleOf", Value: v.MultipleOf})
|
||||
v.MultipleOf = nil
|
||||
}
|
||||
}
|
||||
|
||||
// ClearStringValidations clears all string validations.
|
||||
//
|
||||
// Some callbacks may be set by the caller to capture changed values.
|
||||
func (v *CommonValidations) ClearStringValidations(cbs ...func(string, interface{})) {
|
||||
done := make(clearedValidations, 0, 3)
|
||||
defer func() {
|
||||
done.apply(cbs)
|
||||
}()
|
||||
|
||||
if v.Pattern != "" {
|
||||
done = append(done, clearedValidation{Validation: "pattern", Value: v.Pattern})
|
||||
v.Pattern = ""
|
||||
}
|
||||
if v.MinLength != nil {
|
||||
done = append(done, clearedValidation{Validation: "minLength", Value: v.MinLength})
|
||||
v.MinLength = nil
|
||||
}
|
||||
if v.MaxLength != nil {
|
||||
done = append(done, clearedValidation{Validation: "maxLength", Value: v.MaxLength})
|
||||
v.MaxLength = nil
|
||||
}
|
||||
}
|
||||
|
||||
// ClearArrayValidations clears all array validations.
|
||||
//
|
||||
// Some callbacks may be set by the caller to capture changed values.
|
||||
func (v *CommonValidations) ClearArrayValidations(cbs ...func(string, interface{})) {
|
||||
done := make(clearedValidations, 0, 3)
|
||||
defer func() {
|
||||
done.apply(cbs)
|
||||
}()
|
||||
|
||||
if v.MaxItems != nil {
|
||||
done = append(done, clearedValidation{Validation: "maxItems", Value: v.MaxItems})
|
||||
v.MaxItems = nil
|
||||
}
|
||||
if v.MinItems != nil {
|
||||
done = append(done, clearedValidation{Validation: "minItems", Value: v.MinItems})
|
||||
v.MinItems = nil
|
||||
}
|
||||
if v.UniqueItems {
|
||||
done = append(done, clearedValidation{Validation: "uniqueItems", Value: v.UniqueItems})
|
||||
v.UniqueItems = false
|
||||
}
|
||||
}
|
||||
|
||||
// Validations returns a clone of the validations for a simple schema.
|
||||
//
|
||||
// NOTE: in the context of simple schema objects, MinProperties, MaxProperties
|
||||
// and PatternProperties remain unset.
|
||||
func (v CommonValidations) Validations() SchemaValidations {
|
||||
return SchemaValidations{
|
||||
CommonValidations: v,
|
||||
}
|
||||
}
|
||||
|
||||
// HasNumberValidations indicates if the validations are for numbers or integers
|
||||
func (v CommonValidations) HasNumberValidations() bool {
|
||||
return v.Maximum != nil || v.Minimum != nil || v.MultipleOf != nil
|
||||
}
|
||||
|
||||
// HasStringValidations indicates if the validations are for strings
|
||||
func (v CommonValidations) HasStringValidations() bool {
|
||||
return v.MaxLength != nil || v.MinLength != nil || v.Pattern != ""
|
||||
}
|
||||
|
||||
// HasArrayValidations indicates if the validations are for arrays
|
||||
func (v CommonValidations) HasArrayValidations() bool {
|
||||
return v.MaxItems != nil || v.MinItems != nil || v.UniqueItems
|
||||
}
|
||||
|
||||
// HasEnum indicates if the validation includes some enum constraint
|
||||
func (v CommonValidations) HasEnum() bool {
|
||||
return len(v.Enum) > 0
|
||||
}
|
||||
|
||||
// SchemaValidations describes the validation properties of a schema
|
||||
//
|
||||
// NOTE: at this moment, this is not embedded in SchemaProps because this would induce a breaking change
|
||||
// in the exported members: all initializers using litterals would fail.
|
||||
type SchemaValidations struct {
|
||||
CommonValidations
|
||||
|
||||
PatternProperties SchemaProperties `json:"patternProperties,omitempty"`
|
||||
MaxProperties *int64 `json:"maxProperties,omitempty"`
|
||||
MinProperties *int64 `json:"minProperties,omitempty"`
|
||||
}
|
||||
|
||||
// HasObjectValidations indicates if the validations are for objects
|
||||
func (v SchemaValidations) HasObjectValidations() bool {
|
||||
return v.MaxProperties != nil || v.MinProperties != nil || v.PatternProperties != nil
|
||||
}
|
||||
|
||||
// SetValidations for schema validations
|
||||
func (v *SchemaValidations) SetValidations(val SchemaValidations) {
|
||||
v.CommonValidations.SetValidations(val)
|
||||
v.PatternProperties = val.PatternProperties
|
||||
v.MaxProperties = val.MaxProperties
|
||||
v.MinProperties = val.MinProperties
|
||||
}
|
||||
|
||||
// Validations for a schema
|
||||
func (v SchemaValidations) Validations() SchemaValidations {
|
||||
val := v.CommonValidations.Validations()
|
||||
val.PatternProperties = v.PatternProperties
|
||||
val.MinProperties = v.MinProperties
|
||||
val.MaxProperties = v.MaxProperties
|
||||
return val
|
||||
}
|
||||
|
||||
// ClearObjectValidations returns a clone of the validations with all object validations cleared.
|
||||
//
|
||||
// Some callbacks may be set by the caller to capture changed values.
|
||||
func (v *SchemaValidations) ClearObjectValidations(cbs ...func(string, interface{})) {
|
||||
done := make(clearedValidations, 0, 3)
|
||||
defer func() {
|
||||
done.apply(cbs)
|
||||
}()
|
||||
|
||||
if v.MaxProperties != nil {
|
||||
done = append(done, clearedValidation{Validation: "maxProperties", Value: v.MaxProperties})
|
||||
v.MaxProperties = nil
|
||||
}
|
||||
if v.MinProperties != nil {
|
||||
done = append(done, clearedValidation{Validation: "minProperties", Value: v.MinProperties})
|
||||
v.MinProperties = nil
|
||||
}
|
||||
if v.PatternProperties != nil {
|
||||
done = append(done, clearedValidation{Validation: "patternProperties", Value: v.PatternProperties})
|
||||
v.PatternProperties = nil
|
||||
}
|
||||
}
|
||||
2
vendor/github.com/go-openapi/strfmt/.gitattributes
generated
vendored
Normal file
2
vendor/github.com/go-openapi/strfmt/.gitattributes
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*.go text eol=lf
|
||||
|
||||
14
vendor/github.com/go-openapi/strfmt/.golangci.yml
generated
vendored
14
vendor/github.com/go-openapi/strfmt/.golangci.yml
generated
vendored
@@ -25,6 +25,20 @@ linters:
|
||||
- whitespace
|
||||
- wsl
|
||||
- funlen
|
||||
- wrapcheck
|
||||
- testpackage
|
||||
- nlreturn
|
||||
- gofumpt
|
||||
- goerr113
|
||||
- gci
|
||||
- gomnd
|
||||
- godot
|
||||
- exhaustivestruct
|
||||
- paralleltest
|
||||
- varnamelen
|
||||
- ireturn
|
||||
- exhaustruct
|
||||
#- thelper
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
|
||||
15
vendor/github.com/go-openapi/strfmt/.travis.yml
generated
vendored
15
vendor/github.com/go-openapi/strfmt/.travis.yml
generated
vendored
@@ -1,15 +0,0 @@
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
go:
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
install:
|
||||
- GO111MODULE=off go get -u gotest.tools/gotestsum
|
||||
language: go
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
notifications:
|
||||
slack:
|
||||
secure: zE5AtIYTpYfQPnTzP+EaQPN7JKtfFAGv6PrJqoIZLOXa8B6zGb6+J1JRNNxWi7faWbyJOxa4FSSsuPsKZMycUK6wlLFIdhDxwqeo7Ew8r6rdZKdfUHQggfNS9wO79ARoNYUDHtmnaBUS+eWSM1YqSc4i99QxyyfuURLOeAaA/q14YbdlTlaw3lrZ0qT92ot1FnVGNOx064zuHtFeUf+jAVRMZ6Q3rvqllwIlPszE6rmHGXBt2VoJxRaBetdwd7FgkcYw9FPXKHhadwC7/75ZAdmxIukhxNMw4Tr5NuPcqNcnbYLenDP7B3lssGVIrP4BRSqekS1d/tqvdvnnFWHMwrNCkSnSc065G5+qWTlXKAemIclgiXXqE2furBNLm05MDdG8fn5epS0UNarkjD+zX336RiqwBlOX4KbF+vPyqcO98CsN0lnd+H6loc9reiTHs37orFFpQ+309av9be2GGsHUsRB9ssIyrewmhAccOmkRtr2dVTZJNFQwa5Kph5TNJuTjnZEwG/xUkEX2YSfwShOsb062JWiflV6PJdnl80pc9Tn7D5sO5Bf9DbijGRJwwP+YiiJtwtr+vsvS+n4sM0b5eqm4UoRo+JJO8ffoJtHS7ItuyRbVQCwEPJ4221WLcf5PquEEDdAPwR+K4Gj8qTXqTDdxOiES1xFUKVgmzhI=
|
||||
script:
|
||||
- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
2
vendor/github.com/go-openapi/strfmt/README.md
generated
vendored
2
vendor/github.com/go-openapi/strfmt/README.md
generated
vendored
@@ -38,6 +38,7 @@ It also provides convenient extensions to go-openapi users.
|
||||
- ssn
|
||||
- uuid, uuid3, uuid4, uuid5
|
||||
- cidr (e.g. "192.0.2.1/24", "2001:db8:a0b:12f0::1/32")
|
||||
- ulid (e.g. "00000PP9HGSBSSDZ1JTEXBJ0PW", [spec](https://github.com/ulid/spec))
|
||||
|
||||
> NOTE: as the name stands for, this package is intended to support string formatting only.
|
||||
> It does not provide validation for numerical values with swagger format extension for JSON types "number" or
|
||||
@@ -84,3 +85,4 @@ List of defined types:
|
||||
- UUID3
|
||||
- UUID4
|
||||
- UUID5
|
||||
- [ULID](https://github.com/ulid/spec)
|
||||
|
||||
6
vendor/github.com/go-openapi/strfmt/bson.go
generated
vendored
6
vendor/github.com/go-openapi/strfmt/bson.go
generated
vendored
@@ -39,10 +39,10 @@ func IsBSONObjectID(str string) bool {
|
||||
// ObjectId represents a BSON object ID (alias to go.mongodb.org/mongo-driver/bson/primitive.ObjectID)
|
||||
//
|
||||
// swagger:strfmt bsonobjectid
|
||||
type ObjectId bsonprim.ObjectID
|
||||
type ObjectId bsonprim.ObjectID //nolint:revive
|
||||
|
||||
// NewObjectId creates a ObjectId from a Hex String
|
||||
func NewObjectId(hex string) ObjectId {
|
||||
func NewObjectId(hex string) ObjectId { //nolint:revive
|
||||
oid, err := bsonprim.ObjectIDFromHex(hex)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -95,7 +95,7 @@ func (id ObjectId) Value() (driver.Value, error) {
|
||||
}
|
||||
|
||||
func (id ObjectId) String() string {
|
||||
return bsonprim.ObjectID(id).String()
|
||||
return bsonprim.ObjectID(id).Hex()
|
||||
}
|
||||
|
||||
// MarshalJSON returns the ObjectId as JSON
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user