diff --git a/utils/adapter.go b/utils/adapter.go index 6863442..85c3738 100644 --- a/utils/adapter.go +++ b/utils/adapter.go @@ -276,25 +276,25 @@ func NewMCPFromCustomParser(baseURL string, extraHeaders map[string]string, pars if mediaType.Schema != nil { for propName, propSchema := range mediaType.Schema.Properties { props[propName] = propSchema - props["type"] = propSchema.Type - if propSchema.Enum != nil { - props["enum"] = propSchema.Enum - } - if propSchema.Format != "" { - props["format"] = propSchema.Format - } - if propSchema.Default != nil { - props["default"] = propSchema.Default - } - if propSchema.Description != "" { - props["description"] = propSchema.Description - } - if propSchema.Items != nil { - props["items"] = propSchema.Items - } - if propSchema.Properties != nil { - props["properties"] = propSchema.Properties - } + //props["type"] = propSchema.Type + //if propSchema.Enum != nil { + // props["enum"] = propSchema.Enum + //} + //if propSchema.Format != "" { + // props["format"] = propSchema.Format + //} + //if propSchema.Default != nil { + // props["default"] = propSchema.Default + //} + //if propSchema.Description != "" { + // props["description"] = propSchema.Description + //} + //if propSchema.Items != nil { + // props["items"] = propSchema.Items + //} + //if propSchema.Properties != nil { + // props["properties"] = propSchema.Properties + //} } } } diff --git a/utils/parser.go b/utils/parser.go index 4f1dba9..1ef64bb 100644 --- a/utils/parser.go +++ b/utils/parser.go @@ -75,11 +75,12 @@ type Schema struct { Format string `json:"format,omitempty"` Description string `json:"description,omitempty"` Default interface{} `json:"default,omitempty"` + Example interface{} `json:"example,omitempty"` Enum []interface{} `json:"enum,omitempty"` Properties map[string]Schema `json:"properties,omitempty"` Items *Schema `json:"items,omitempty"` Required []string `json:"required,omitempty"` - Ref string + Ref string `json:"ref,omitempty"` } // SimpleOpenAPIParser is a simple parser for OpenAPI specifications @@ -247,7 +248,11 @@ func (p *SimpleOpenAPIParser) APIs() []APIEndpoint { // Parse request body if requestBodyObj, ok := operationObj["requestBody"].(map[string]interface{}); ok { - requestBody := RequestBody{ + if ref, ok := resolveRef(requestBodyObj, p.document); ok { + requestBodyObj = ref + } + + requestBody := RequestBody{ // initialization Content: make(map[string]MediaType), } @@ -314,6 +319,9 @@ func (p *SimpleOpenAPIParser) APIs() []APIEndpoint { // parseSchema parses a JSON schema object func (p *SimpleOpenAPIParser) parseSchema(schemaObj map[string]interface{}) Schema { + if ref, ok := resolveRef(schemaObj, p.document); ok { + schemaObj = ref + } schema := Schema{ Properties: make(map[string]Schema), } @@ -334,6 +342,10 @@ func (p *SimpleOpenAPIParser) parseSchema(schemaObj map[string]interface{}) Sche schema.Default = defaultValue } + if exampleValue, ok := schemaObj["example"]; ok { + schema.Example = exampleValue + } + if enum, ok := schemaObj["enum"].([]interface{}); ok { schema.Enum = enum } @@ -402,3 +414,42 @@ func ParseOpenAPIFromYAML(data []byte) (OpenAPIParser, error) { func ParseOpenAPIFromJSON(data []byte) (OpenAPIParser, error) { return NewSimpleOpenAPIParser(data) } + +/* +check & retrieve if it refers components + +targetObj: part of the document which is the target to be checked + +doc: entire document which allows to access component field + +return (ref obj, is ref) +*/ +func resolveRef(targetObj map[string]interface{}, doc map[string]interface{}) (map[string]interface{}, bool) { + if ref, ok := targetObj["$ref"].(string); ok { + hierarchy := strings.Split(ref, "/")[1:] + res, ok := lookUpComponent(doc, hierarchy) + if ok { + return res, true + } + } + return nil, false +} + +// iterate look up with hierarchical doc, keys +func lookUpComponent(doc map[string]interface{}, keys []string) (map[string]interface{}, bool) { + var cur interface{} = doc + + for _, key := range keys { // idx, item + curMap, ok := cur.(map[string]interface{}) + if !ok { + return nil, false + } + cur, ok = curMap[key] + if !ok { + return nil, false + } + } + + ref, ok := cur.(map[string]interface{}) + return ref, ok +}