MCPcopy Create free account
hub / github.com/getkin/kin-openapi / DefaultRefNameResolver

Function DefaultRefNameResolver

openapi3/internalize_refs.go:30–101  ·  view source on GitHub ↗

DefaultRefResolver is a default implementation of refNameResolver for the InternalizeRefs function. The external reference is internalized to (hopefully) a unique name. If the external reference matches (by path) to another reference in the root document then the name of that component is used. Th

(doc *T, ref ComponentRef)

Source from the content-addressed store, hash-verified

28// This is an injective mapping over a "reasonable" amount of the possible openapi
29// spec domain space but is not perfect. There might be edge cases.
30func DefaultRefNameResolver(doc *T, ref ComponentRef) string {
31 if ref.RefString() == "" || ref.RefPath() == nil {
32 panic("unable to resolve reference to name")
33 }
34
35 name := ref.RefPath()
36
37 // If referring to a component in the root spec, no need to internalize just use
38 // the existing component.
39 // XXX(percivalalb): since this function call is iterating over components behind the
40 // scenes during an internalization call it actually starts interating over
41 // new & replaced internalized components. This might caused some edge cases,
42 // haven't found one yet but this might need to actually be used on a frozen copy
43 // of doc.
44 if nameInRoot, found := ReferencesComponentInRootDocument(doc, ref); found {
45 nameInRoot = strings.TrimPrefix(nameInRoot, "#")
46
47 rootCompURI := copyURI(doc.url)
48 rootCompURI.Fragment = nameInRoot
49 name = rootCompURI
50 }
51
52 filePath, componentPath := name.Path, name.Fragment
53
54 // Cut out the "#/components/<type>" to make the names shorter.
55 // XXX(percivalalb): This might cause collisions but is worth the brevity.
56 if b, a, ok := strings.Cut(componentPath, path.Join("components", ref.CollectionName(), "")); ok {
57 componentPath = path.Join(b, a)
58 }
59
60 if filePath != "" {
61 // If the path is the same as the root doc, just remove.
62 if doc.url != nil && filePath == doc.url.Path {
63 filePath = ""
64 }
65
66 // Remove the path extensions to make this JSON/YAML agnostic.
67 for ext := path.Ext(filePath); len(ext) > 0; ext = path.Ext(filePath) {
68 filePath = strings.TrimSuffix(filePath, ext)
69 }
70
71 // Trim the common prefix with the root doc path.
72 if doc.url != nil {
73 for commonDir := path.Dir(doc.url.Path); /*no common prefix*/ commonDir != "."; commonDir = path.Dir(commonDir) {
74 if p, found := cutDirectories(filePath, commonDir); found {
75 filePath = p
76 break
77 }
78 }
79 }
80 }
81
82 var internalizedName string
83
84 // Trim .'s & slashes from start e.g. otherwise ./doc.yaml would end up as __doc
85 if filePath != "" {
86 internalizedName = strings.TrimLeft(filePath, "./")
87 }

Callers

nothing calls this directly

Calls 6

cutDirectoriesFunction · 0.85
copyURIFunction · 0.70
RefStringMethod · 0.65
RefPathMethod · 0.65
CollectionNameMethod · 0.65

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…