ReferencesComponentInRootDocument returns if the given component reference references the same document or element as another component reference in the root document's '#/components/ '. If it does, it returns the name of it in the form '#/components/ /NameXXX' Of course given a component
(doc *T, ref ComponentRef)
| 185 | // |
| 186 | // #/components/schemas/Record |
| 187 | func ReferencesComponentInRootDocument(doc *T, ref ComponentRef) (string, bool) { |
| 188 | if ref == nil || ref.RefString() == "" { |
| 189 | return "", false |
| 190 | } |
| 191 | |
| 192 | // Case 1: |
| 193 | // Something like: ../another-folder/document.json#/myElement |
| 194 | if isRemoteReference(ref.RefString()) && isRootComponentReference(ref.RefString(), ref.CollectionName()) { |
| 195 | // Determine if it is *this* root doc. |
| 196 | if referencesRootDocument(doc, ref) { |
| 197 | _, name, _ := strings.Cut(ref.RefString(), path.Join("#/components/", ref.CollectionName())) |
| 198 | |
| 199 | return path.Join("#/components/", ref.CollectionName(), name), true |
| 200 | } |
| 201 | } |
| 202 | |
| 203 | // If there are no schemas defined in the root document return early. |
| 204 | if doc.Components == nil { |
| 205 | return "", false |
| 206 | } |
| 207 | |
| 208 | collection, _, err := jsonpointer.GetForToken(doc.Components, ref.CollectionName()) |
| 209 | if err != nil { |
| 210 | panic(err) // unreachable |
| 211 | } |
| 212 | |
| 213 | var components map[string]ComponentRef |
| 214 | |
| 215 | componentRefType := reflect.TypeFor[ComponentRef]() |
| 216 | if t := reflect.TypeOf(collection); t.Kind() == reflect.Map && |
| 217 | t.Key().Kind() == reflect.String && |
| 218 | t.Elem().AssignableTo(componentRefType) { |
| 219 | v := reflect.ValueOf(collection) |
| 220 | |
| 221 | components = make(map[string]ComponentRef, v.Len()) |
| 222 | for _, key := range v.MapKeys() { |
| 223 | strct := v.MapIndex(key) |
| 224 | // Type assertion safe, already checked via reflection above. |
| 225 | components[key.Interface().(string)] = strct.Interface().(ComponentRef) |
| 226 | } |
| 227 | } else { |
| 228 | return "", false |
| 229 | } |
| 230 | |
| 231 | // Case 2: |
| 232 | // Something like: ../openapi.yaml#/components/schemas/myElement |
| 233 | for _, name := range componentNames(components) { |
| 234 | s := components[name] |
| 235 | // Must be a reference to a YAML file. |
| 236 | if !isWholeDocumentReference(s.RefString()) { |
| 237 | continue |
| 238 | } |
| 239 | |
| 240 | // Is the schema a ref to the same resource. |
| 241 | if !refersToSameDocument(s, ref) { |
| 242 | continue |
| 243 | } |
| 244 |
searching dependent graphs…