mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-06 04:20:11 +00:00
fix: Issue #82
The index can now accept multiple parameters with the same name, as long as they have different `in` types.
This commit is contained in:
@@ -98,96 +98,96 @@ func CreateClosedAPIIndexConfig() *SpecIndexConfig {
|
||||
// quick direct access to paths, operations, tags are all available. No need to walk the entire node tree in rules,
|
||||
// everything is pre-walked if you need it.
|
||||
type SpecIndex struct {
|
||||
allRefs map[string]*Reference // all (deduplicated) refs
|
||||
rawSequencedRefs []*Reference // all raw references in sequence as they are scanned, not deduped.
|
||||
linesWithRefs map[int]bool // lines that link to references.
|
||||
allMappedRefs map[string]*Reference // these are the located mapped refs
|
||||
allMappedRefsSequenced []*ReferenceMapped // sequenced mapped refs
|
||||
refsByLine map[string]map[int]bool // every reference and the lines it's referenced from
|
||||
pathRefs map[string]map[string]*Reference // all path references
|
||||
paramOpRefs map[string]map[string]map[string]*Reference // params in operations.
|
||||
paramCompRefs map[string]*Reference // params in components
|
||||
paramAllRefs map[string]*Reference // combined components and ops
|
||||
paramInlineDuplicates map[string][]*Reference // inline params all with the same name
|
||||
globalTagRefs map[string]*Reference // top level global tags
|
||||
securitySchemeRefs map[string]*Reference // top level security schemes
|
||||
requestBodiesRefs map[string]*Reference // top level request bodies
|
||||
responsesRefs map[string]*Reference // top level responses
|
||||
headersRefs map[string]*Reference // top level responses
|
||||
examplesRefs map[string]*Reference // top level examples
|
||||
securityRequirementRefs map[string]map[string][]*Reference // (NOT $ref) but a name based lookup for requirements
|
||||
callbacksRefs map[string]map[string][]*Reference // all links
|
||||
linksRefs map[string]map[string][]*Reference // all callbacks
|
||||
operationTagsRefs map[string]map[string][]*Reference // tags found in operations
|
||||
operationDescriptionRefs map[string]map[string]*Reference // descriptions in operations.
|
||||
operationSummaryRefs map[string]map[string]*Reference // summaries in operations
|
||||
callbackRefs map[string]*Reference // top level callback refs
|
||||
serversRefs []*Reference // all top level server refs
|
||||
rootServersNode *yaml.Node // servers root node
|
||||
opServersRefs map[string]map[string][]*Reference // all operation level server overrides.
|
||||
polymorphicRefs map[string]*Reference // every reference to a polymorphic ref
|
||||
polymorphicAllOfRefs []*Reference // every reference to 'allOf' references
|
||||
polymorphicOneOfRefs []*Reference // every reference to 'oneOf' references
|
||||
polymorphicAnyOfRefs []*Reference // every reference to 'anyOf' references
|
||||
externalDocumentsRef []*Reference // all external documents in spec
|
||||
rootSecurity []*Reference // root security definitions.
|
||||
rootSecurityNode *yaml.Node // root security node.
|
||||
refsWithSiblings map[string]Reference // references with sibling elements next to them
|
||||
pathRefsLock sync.Mutex // create lock for all refs maps, we want to build data as fast as we can
|
||||
externalDocumentsCount int // number of externalDocument nodes found
|
||||
operationTagsCount int // number of unique tags in operations
|
||||
globalTagsCount int // number of global tags defined
|
||||
totalTagsCount int // number unique tags in spec
|
||||
securitySchemesCount int // security schemes
|
||||
globalRequestBodiesCount int // component request bodies
|
||||
globalResponsesCount int // component responses
|
||||
globalHeadersCount int // component headers
|
||||
globalExamplesCount int // component examples
|
||||
globalLinksCount int // component links
|
||||
globalCallbacksCount int // component callbacks
|
||||
globalCallbacks int // component callbacks.
|
||||
pathCount int // number of paths
|
||||
operationCount int // number of operations
|
||||
operationParamCount int // number of params defined in operations
|
||||
componentParamCount int // number of params defined in components
|
||||
componentsInlineParamUniqueCount int // number of inline params with unique names
|
||||
componentsInlineParamDuplicateCount int // number of inline params with duplicate names
|
||||
schemaCount int // number of schemas
|
||||
refCount int // total ref count
|
||||
root *yaml.Node // the root document
|
||||
pathsNode *yaml.Node // paths node
|
||||
tagsNode *yaml.Node // tags node
|
||||
componentsNode *yaml.Node // components node
|
||||
parametersNode *yaml.Node // components/parameters node
|
||||
allParametersNode map[string]*Reference // all parameters node
|
||||
allParameters map[string]*Reference // all parameters (components/defs)
|
||||
schemasNode *yaml.Node // components/schemas node
|
||||
allInlineSchemaDefinitions []*Reference // all schemas found in document outside of components (openapi) or definitions (swagger).
|
||||
allInlineSchemaObjectDefinitions []*Reference // all schemas that are objects found in document outside of components (openapi) or definitions (swagger).
|
||||
allComponentSchemaDefinitions map[string]*Reference // all schemas found in components (openapi) or definitions (swagger).
|
||||
securitySchemesNode *yaml.Node // components/securitySchemes node
|
||||
allSecuritySchemes map[string]*Reference // all security schemes / definitions.
|
||||
requestBodiesNode *yaml.Node // components/requestBodies node
|
||||
allRequestBodies map[string]*Reference // all request bodies
|
||||
responsesNode *yaml.Node // components/responses node
|
||||
allResponses map[string]*Reference // all responses
|
||||
headersNode *yaml.Node // components/headers node
|
||||
allHeaders map[string]*Reference // all headers
|
||||
examplesNode *yaml.Node // components/examples node
|
||||
allExamples map[string]*Reference // all components examples
|
||||
linksNode *yaml.Node // components/links node
|
||||
allLinks map[string]*Reference // all links
|
||||
callbacksNode *yaml.Node // components/callbacks node
|
||||
allCallbacks map[string]*Reference // all components examples
|
||||
externalDocumentsNode *yaml.Node // external documents node
|
||||
allExternalDocuments map[string]*Reference // all external documents
|
||||
externalSpecIndex map[string]*SpecIndex // create a primary index of all external specs and componentIds
|
||||
refErrors []error // errors when indexing references
|
||||
operationParamErrors []error // errors when indexing parameters
|
||||
allDescriptions []*DescriptionReference // every single description found in the spec.
|
||||
allSummaries []*DescriptionReference // every single summary found in the spec.
|
||||
allEnums []*EnumReference // every single enum found in the spec.
|
||||
allObjectsWithProperties []*ObjectReference // every single object with properties found in the spec.
|
||||
allRefs map[string]*Reference // all (deduplicated) refs
|
||||
rawSequencedRefs []*Reference // all raw references in sequence as they are scanned, not deduped.
|
||||
linesWithRefs map[int]bool // lines that link to references.
|
||||
allMappedRefs map[string]*Reference // these are the located mapped refs
|
||||
allMappedRefsSequenced []*ReferenceMapped // sequenced mapped refs
|
||||
refsByLine map[string]map[int]bool // every reference and the lines it's referenced from
|
||||
pathRefs map[string]map[string]*Reference // all path references
|
||||
paramOpRefs map[string]map[string]map[string][]*Reference // params in operations.
|
||||
paramCompRefs map[string]*Reference // params in components
|
||||
paramAllRefs map[string]*Reference // combined components and ops
|
||||
paramInlineDuplicateNames map[string][]*Reference // inline params all with the same name
|
||||
globalTagRefs map[string]*Reference // top level global tags
|
||||
securitySchemeRefs map[string]*Reference // top level security schemes
|
||||
requestBodiesRefs map[string]*Reference // top level request bodies
|
||||
responsesRefs map[string]*Reference // top level responses
|
||||
headersRefs map[string]*Reference // top level responses
|
||||
examplesRefs map[string]*Reference // top level examples
|
||||
securityRequirementRefs map[string]map[string][]*Reference // (NOT $ref) but a name based lookup for requirements
|
||||
callbacksRefs map[string]map[string][]*Reference // all links
|
||||
linksRefs map[string]map[string][]*Reference // all callbacks
|
||||
operationTagsRefs map[string]map[string][]*Reference // tags found in operations
|
||||
operationDescriptionRefs map[string]map[string]*Reference // descriptions in operations.
|
||||
operationSummaryRefs map[string]map[string]*Reference // summaries in operations
|
||||
callbackRefs map[string]*Reference // top level callback refs
|
||||
serversRefs []*Reference // all top level server refs
|
||||
rootServersNode *yaml.Node // servers root node
|
||||
opServersRefs map[string]map[string][]*Reference // all operation level server overrides.
|
||||
polymorphicRefs map[string]*Reference // every reference to a polymorphic ref
|
||||
polymorphicAllOfRefs []*Reference // every reference to 'allOf' references
|
||||
polymorphicOneOfRefs []*Reference // every reference to 'oneOf' references
|
||||
polymorphicAnyOfRefs []*Reference // every reference to 'anyOf' references
|
||||
externalDocumentsRef []*Reference // all external documents in spec
|
||||
rootSecurity []*Reference // root security definitions.
|
||||
rootSecurityNode *yaml.Node // root security node.
|
||||
refsWithSiblings map[string]Reference // references with sibling elements next to them
|
||||
pathRefsLock sync.Mutex // create lock for all refs maps, we want to build data as fast as we can
|
||||
externalDocumentsCount int // number of externalDocument nodes found
|
||||
operationTagsCount int // number of unique tags in operations
|
||||
globalTagsCount int // number of global tags defined
|
||||
totalTagsCount int // number unique tags in spec
|
||||
securitySchemesCount int // security schemes
|
||||
globalRequestBodiesCount int // component request bodies
|
||||
globalResponsesCount int // component responses
|
||||
globalHeadersCount int // component headers
|
||||
globalExamplesCount int // component examples
|
||||
globalLinksCount int // component links
|
||||
globalCallbacksCount int // component callbacks
|
||||
globalCallbacks int // component callbacks.
|
||||
pathCount int // number of paths
|
||||
operationCount int // number of operations
|
||||
operationParamCount int // number of params defined in operations
|
||||
componentParamCount int // number of params defined in components
|
||||
componentsInlineParamUniqueCount int // number of inline params with unique names
|
||||
componentsInlineParamDuplicateCount int // number of inline params with duplicate names
|
||||
schemaCount int // number of schemas
|
||||
refCount int // total ref count
|
||||
root *yaml.Node // the root document
|
||||
pathsNode *yaml.Node // paths node
|
||||
tagsNode *yaml.Node // tags node
|
||||
componentsNode *yaml.Node // components node
|
||||
parametersNode *yaml.Node // components/parameters node
|
||||
allParametersNode map[string]*Reference // all parameters node
|
||||
allParameters map[string]*Reference // all parameters (components/defs)
|
||||
schemasNode *yaml.Node // components/schemas node
|
||||
allInlineSchemaDefinitions []*Reference // all schemas found in document outside of components (openapi) or definitions (swagger).
|
||||
allInlineSchemaObjectDefinitions []*Reference // all schemas that are objects found in document outside of components (openapi) or definitions (swagger).
|
||||
allComponentSchemaDefinitions map[string]*Reference // all schemas found in components (openapi) or definitions (swagger).
|
||||
securitySchemesNode *yaml.Node // components/securitySchemes node
|
||||
allSecuritySchemes map[string]*Reference // all security schemes / definitions.
|
||||
requestBodiesNode *yaml.Node // components/requestBodies node
|
||||
allRequestBodies map[string]*Reference // all request bodies
|
||||
responsesNode *yaml.Node // components/responses node
|
||||
allResponses map[string]*Reference // all responses
|
||||
headersNode *yaml.Node // components/headers node
|
||||
allHeaders map[string]*Reference // all headers
|
||||
examplesNode *yaml.Node // components/examples node
|
||||
allExamples map[string]*Reference // all components examples
|
||||
linksNode *yaml.Node // components/links node
|
||||
allLinks map[string]*Reference // all links
|
||||
callbacksNode *yaml.Node // components/callbacks node
|
||||
allCallbacks map[string]*Reference // all components examples
|
||||
externalDocumentsNode *yaml.Node // external documents node
|
||||
allExternalDocuments map[string]*Reference // all external documents
|
||||
externalSpecIndex map[string]*SpecIndex // create a primary index of all external specs and componentIds
|
||||
refErrors []error // errors when indexing references
|
||||
operationParamErrors []error // errors when indexing parameters
|
||||
allDescriptions []*DescriptionReference // every single description found in the spec.
|
||||
allSummaries []*DescriptionReference // every single summary found in the spec.
|
||||
allEnums []*EnumReference // every single enum found in the spec.
|
||||
allObjectsWithProperties []*ObjectReference // every single object with properties found in the spec.
|
||||
enumCount int
|
||||
descriptionCount int
|
||||
summaryCount int
|
||||
|
||||
@@ -52,13 +52,13 @@ func boostrapIndexCollections(rootNode *yaml.Node, index *SpecIndex) {
|
||||
index.refsByLine = make(map[string]map[int]bool)
|
||||
index.linesWithRefs = make(map[int]bool)
|
||||
index.pathRefs = make(map[string]map[string]*Reference)
|
||||
index.paramOpRefs = make(map[string]map[string]map[string]*Reference)
|
||||
index.paramOpRefs = make(map[string]map[string]map[string][]*Reference)
|
||||
index.operationTagsRefs = make(map[string]map[string][]*Reference)
|
||||
index.operationDescriptionRefs = make(map[string]map[string]*Reference)
|
||||
index.operationSummaryRefs = make(map[string]map[string]*Reference)
|
||||
index.paramCompRefs = make(map[string]*Reference)
|
||||
index.paramAllRefs = make(map[string]*Reference)
|
||||
index.paramInlineDuplicates = make(map[string][]*Reference)
|
||||
index.paramInlineDuplicateNames = make(map[string][]*Reference)
|
||||
index.globalTagRefs = make(map[string]*Reference)
|
||||
index.securitySchemeRefs = make(map[string]*Reference)
|
||||
index.requestBodiesRefs = make(map[string]*Reference)
|
||||
|
||||
@@ -202,7 +202,7 @@ func (index *SpecIndex) GetMappedReferencesSequenced() []*ReferenceMapped {
|
||||
}
|
||||
|
||||
// GetOperationParameterReferences will return all references to operation parameters
|
||||
func (index *SpecIndex) GetOperationParameterReferences() map[string]map[string]map[string]*Reference {
|
||||
func (index *SpecIndex) GetOperationParameterReferences() map[string]map[string]map[string][]*Reference {
|
||||
return index.paramOpRefs
|
||||
}
|
||||
|
||||
@@ -310,7 +310,7 @@ func (index *SpecIndex) GetAllCallbacks() map[string]*Reference {
|
||||
|
||||
// GetInlineOperationDuplicateParameters will return a map of duplicates located in operation parameters.
|
||||
func (index *SpecIndex) GetInlineOperationDuplicateParameters() map[string][]*Reference {
|
||||
return index.paramInlineDuplicates
|
||||
return index.paramInlineDuplicateNames
|
||||
}
|
||||
|
||||
// GetReferencesWithSiblings will return a map of all the references with sibling nodes (illegal)
|
||||
@@ -359,7 +359,7 @@ func (index *SpecIndex) GetOperationTags() map[string]map[string][]*Reference {
|
||||
}
|
||||
|
||||
// GetAllParametersFromOperations will return all paths indexed in the document
|
||||
func (index *SpecIndex) GetAllParametersFromOperations() map[string]map[string]map[string]*Reference {
|
||||
func (index *SpecIndex) GetAllParametersFromOperations() map[string]map[string]map[string][]*Reference {
|
||||
return index.paramOpRefs
|
||||
}
|
||||
|
||||
@@ -1104,14 +1104,23 @@ func (index *SpecIndex) GetOperationsParameterCount() int {
|
||||
for mName, mValue := range params {
|
||||
for pName, pValue := range mValue {
|
||||
if !strings.HasPrefix(pName, "#") {
|
||||
index.paramInlineDuplicates[pName] = append(index.paramInlineDuplicates[pName], pValue)
|
||||
index.paramAllRefs[fmt.Sprintf("%s:::%s", path, mName)] = pValue
|
||||
index.paramInlineDuplicateNames[pName] = append(index.paramInlineDuplicateNames[pName], pValue...)
|
||||
for i := range pValue {
|
||||
if pValue[i] != nil {
|
||||
_, in := utils.FindKeyNodeTop("in", pValue[i].Node.Content)
|
||||
if in != nil {
|
||||
index.paramAllRefs[fmt.Sprintf("%s:::%s:::%s", path, mName, in.Value)] = pValue[i]
|
||||
} else {
|
||||
index.paramAllRefs[fmt.Sprintf("%s:::%s", path, mName)] = pValue[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
index.operationParamCount = len(index.paramCompRefs) + len(index.paramInlineDuplicates)
|
||||
index.operationParamCount = len(index.paramCompRefs) + len(index.paramInlineDuplicateNames)
|
||||
return index.operationParamCount
|
||||
}
|
||||
|
||||
@@ -1120,7 +1129,7 @@ func (index *SpecIndex) GetInlineDuplicateParamCount() int {
|
||||
if index.componentsInlineParamDuplicateCount > 0 {
|
||||
return index.componentsInlineParamDuplicateCount
|
||||
}
|
||||
dCount := len(index.paramInlineDuplicates) - index.countUniqueInlineDuplicates()
|
||||
dCount := len(index.paramInlineDuplicateNames) - index.countUniqueInlineDuplicates()
|
||||
index.componentsInlineParamDuplicateCount = dCount
|
||||
return dCount
|
||||
}
|
||||
|
||||
@@ -661,7 +661,7 @@ paths:
|
||||
|
||||
index := NewSpecIndex(&rootNode)
|
||||
|
||||
assert.NotNil(t, index.GetAllParametersFromOperations()["/cakes"]["post"]["coffee-time.yaml"].Node)
|
||||
assert.NotNil(t, index.GetAllParametersFromOperations()["/cakes"]["post"]["coffee-time.yaml"][0].Node)
|
||||
}
|
||||
|
||||
func TestSpecIndex_lookupRemoteReference_SeenSourceSimulation_BadJSON(t *testing.T) {
|
||||
@@ -775,18 +775,18 @@ components:
|
||||
if assert.Contains(t, params, "/") {
|
||||
if assert.Contains(t, params["/"], "top") {
|
||||
if assert.Contains(t, params["/"]["top"], "#/components/parameters/param1") {
|
||||
assert.Equal(t, "$.components.parameters.param1", params["/"]["top"]["#/components/parameters/param1"].Path)
|
||||
assert.Equal(t, "$.components.parameters.param1", params["/"]["top"]["#/components/parameters/param1"][0].Path)
|
||||
}
|
||||
if assert.Contains(t, params["/"]["top"], "paramour.yaml#/components/parameters/param3") {
|
||||
assert.Equal(t, "$.components.parameters.param3", params["/"]["top"]["paramour.yaml#/components/parameters/param3"].Path)
|
||||
assert.Equal(t, "$.components.parameters.param3", params["/"]["top"]["paramour.yaml#/components/parameters/param3"][0].Path)
|
||||
}
|
||||
}
|
||||
if assert.Contains(t, params["/"], "get") {
|
||||
if assert.Contains(t, params["/"]["get"], "#/components/parameters/param2") {
|
||||
assert.Equal(t, "$.components.parameters.param2", params["/"]["get"]["#/components/parameters/param2"].Path)
|
||||
assert.Equal(t, "$.components.parameters.param2", params["/"]["get"]["#/components/parameters/param2"][0].Path)
|
||||
}
|
||||
if assert.Contains(t, params["/"]["get"], "test") {
|
||||
assert.Equal(t, "$.paths./.get.parameters[2]", params["/"]["get"]["test"].Path)
|
||||
assert.Equal(t, "$.paths./.get.parameters[2]", params["/"]["get"]["test"][0].Path)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -854,6 +854,103 @@ func TestSpecIndex_schemaComponentsHaveParentsAndPaths(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpecIndex_ParamsWithDuplicateNamesButUniqueInTypes(t *testing.T) {
|
||||
yml := `openapi: 3.1.0
|
||||
info:
|
||||
title: Test
|
||||
version: 0.0.1
|
||||
servers:
|
||||
- url: http://localhost:35123
|
||||
paths:
|
||||
/example/{action}:
|
||||
parameters:
|
||||
- name: fastAction
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: fastAction
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
get:
|
||||
operationId: example
|
||||
parameters:
|
||||
- name: action
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: action
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: OK`
|
||||
|
||||
var rootNode yaml.Node
|
||||
yaml.Unmarshal([]byte(yml), &rootNode)
|
||||
|
||||
idx := NewSpecIndex(&rootNode)
|
||||
|
||||
assert.Len(t, idx.paramAllRefs, 4)
|
||||
assert.Len(t, idx.paramInlineDuplicateNames, 2)
|
||||
assert.Len(t, idx.operationParamErrors, 0)
|
||||
assert.Len(t, idx.refErrors, 0)
|
||||
|
||||
}
|
||||
|
||||
func TestSpecIndex_ParamsWithDuplicateNamesAndSameInTypes(t *testing.T) {
|
||||
yml := `openapi: 3.1.0
|
||||
info:
|
||||
title: Test
|
||||
version: 0.0.1
|
||||
servers:
|
||||
- url: http://localhost:35123
|
||||
paths:
|
||||
/example/{action}:
|
||||
parameters:
|
||||
- name: fastAction
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: fastAction
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
get:
|
||||
operationId: example
|
||||
parameters:
|
||||
- name: action
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: action
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: OK`
|
||||
|
||||
var rootNode yaml.Node
|
||||
yaml.Unmarshal([]byte(yml), &rootNode)
|
||||
|
||||
idx := NewSpecIndex(&rootNode)
|
||||
|
||||
assert.Len(t, idx.paramAllRefs, 3)
|
||||
assert.Len(t, idx.paramInlineDuplicateNames, 2)
|
||||
assert.Len(t, idx.operationParamErrors, 1)
|
||||
assert.Len(t, idx.refErrors, 0)
|
||||
}
|
||||
|
||||
func TestSpecIndex_foundObjectsWithProperties(t *testing.T) {
|
||||
yml := `paths:
|
||||
/test:
|
||||
|
||||
@@ -261,7 +261,7 @@ func (index *SpecIndex) countUniqueInlineDuplicates() int {
|
||||
return index.componentsInlineParamUniqueCount
|
||||
}
|
||||
unique := 0
|
||||
for _, p := range index.paramInlineDuplicates {
|
||||
for _, p := range index.paramInlineDuplicateNames {
|
||||
if len(p) == 1 {
|
||||
unique++
|
||||
}
|
||||
@@ -279,13 +279,13 @@ func (index *SpecIndex) scanOperationParams(params []*yaml.Node, pathItemNode *y
|
||||
paramRef := index.allMappedRefs[paramRefName]
|
||||
|
||||
if index.paramOpRefs[pathItemNode.Value] == nil {
|
||||
index.paramOpRefs[pathItemNode.Value] = make(map[string]map[string]*Reference)
|
||||
index.paramOpRefs[pathItemNode.Value][method] = make(map[string]*Reference)
|
||||
index.paramOpRefs[pathItemNode.Value] = make(map[string]map[string][]*Reference)
|
||||
index.paramOpRefs[pathItemNode.Value][method] = make(map[string][]*Reference)
|
||||
|
||||
}
|
||||
// if we know the path, but it's a new method
|
||||
if index.paramOpRefs[pathItemNode.Value][method] == nil {
|
||||
index.paramOpRefs[pathItemNode.Value][method] = make(map[string]*Reference)
|
||||
index.paramOpRefs[pathItemNode.Value][method] = make(map[string][]*Reference)
|
||||
}
|
||||
|
||||
// if this is a duplicate, add an error and ignore it
|
||||
@@ -302,7 +302,8 @@ func (index *SpecIndex) scanOperationParams(params []*yaml.Node, pathItemNode *y
|
||||
Path: path,
|
||||
})
|
||||
} else {
|
||||
index.paramOpRefs[pathItemNode.Value][method][paramRefName] = paramRef
|
||||
index.paramOpRefs[pathItemNode.Value][method][paramRefName] =
|
||||
append(index.paramOpRefs[pathItemNode.Value][method][paramRefName], paramRef)
|
||||
}
|
||||
|
||||
continue
|
||||
@@ -334,30 +335,47 @@ func (index *SpecIndex) scanOperationParams(params []*yaml.Node, pathItemNode *y
|
||||
Path: path,
|
||||
}
|
||||
if index.paramOpRefs[pathItemNode.Value] == nil {
|
||||
index.paramOpRefs[pathItemNode.Value] = make(map[string]map[string]*Reference)
|
||||
index.paramOpRefs[pathItemNode.Value][method] = make(map[string]*Reference)
|
||||
index.paramOpRefs[pathItemNode.Value] = make(map[string]map[string][]*Reference)
|
||||
index.paramOpRefs[pathItemNode.Value][method] = make(map[string][]*Reference)
|
||||
}
|
||||
|
||||
// if we know the path but this is a new method.
|
||||
if index.paramOpRefs[pathItemNode.Value][method] == nil {
|
||||
index.paramOpRefs[pathItemNode.Value][method] = make(map[string]*Reference)
|
||||
index.paramOpRefs[pathItemNode.Value][method] = make(map[string][]*Reference)
|
||||
}
|
||||
|
||||
// if this is a duplicate, add an error and ignore it
|
||||
if index.paramOpRefs[pathItemNode.Value][method][ref.Name] != nil {
|
||||
path := fmt.Sprintf("$.paths.%s.%s.parameters[%d]", pathItemNode.Value, method, i)
|
||||
if method == "top" {
|
||||
path = fmt.Sprintf("$.paths.%s.parameters[%d]", pathItemNode.Value, i)
|
||||
}
|
||||
// if this is a duplicate name, check if the `in` type is also the same, if so, it's a duplicate.
|
||||
if len(index.paramOpRefs[pathItemNode.Value][method][ref.Name]) > 0 {
|
||||
|
||||
index.operationParamErrors = append(index.operationParamErrors, &IndexingError{
|
||||
Err: fmt.Errorf("the `%s` operation parameter at path `%s`, "+
|
||||
"index %d has a duplicate name `%s`", method, pathItemNode.Value, i, vn.Value),
|
||||
Node: param,
|
||||
Path: path,
|
||||
})
|
||||
currentNode := ref.Node
|
||||
checkNodes := index.paramOpRefs[pathItemNode.Value][method][ref.Name]
|
||||
_, currentIn := utils.FindKeyNodeTop("in", currentNode.Content)
|
||||
|
||||
for _, checkNode := range checkNodes {
|
||||
|
||||
_, checkIn := utils.FindKeyNodeTop("in", checkNode.Node.Content)
|
||||
|
||||
if currentIn != nil && checkIn != nil && currentIn.Value == checkIn.Value {
|
||||
|
||||
path := fmt.Sprintf("$.paths.%s.%s.parameters[%d]", pathItemNode.Value, method, i)
|
||||
if method == "top" {
|
||||
path = fmt.Sprintf("$.paths.%s.parameters[%d]", pathItemNode.Value, i)
|
||||
}
|
||||
|
||||
index.operationParamErrors = append(index.operationParamErrors, &IndexingError{
|
||||
Err: fmt.Errorf("the `%s` operation parameter at path `%s`, "+
|
||||
"index %d has a duplicate name `%s` and `in` type", method, pathItemNode.Value, i, vn.Value),
|
||||
Node: param,
|
||||
Path: path,
|
||||
})
|
||||
} else {
|
||||
index.paramOpRefs[pathItemNode.Value][method][ref.Name] =
|
||||
append(index.paramOpRefs[pathItemNode.Value][method][ref.Name], ref)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
index.paramOpRefs[pathItemNode.Value][method][ref.Name] = ref
|
||||
index.paramOpRefs[pathItemNode.Value][method][ref.Name] =
|
||||
append(index.paramOpRefs[pathItemNode.Value][method][ref.Name], ref)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user