From b5bcd71617fd31686e538427298c0a98751968f3 Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Tue, 30 Jul 2024 16:22:44 +0200 Subject: [PATCH] openapi3: export `ComponentRef` for usage in `RefNameResolver` (#998) * Export ComponentRef for usage in RefNameResolver * run ./docs.sh Signed-off-by: Pierre Fenoll --------- Signed-off-by: Pierre Fenoll Co-authored-by: chris.smith --- .github/docs/openapi3.txt | 14 ++++++++++---- openapi3/helpers.go | 16 ++++++++-------- openapi3/internalize_refs.go | 6 +++--- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/.github/docs/openapi3.txt b/.github/docs/openapi3.txt index 3a7caf2c..09f1192a 100644 --- a/.github/docs/openapi3.txt +++ b/.github/docs/openapi3.txt @@ -96,7 +96,7 @@ FUNCTIONS func BoolPtr(value bool) *bool BoolPtr is a helper for defining OpenAPI schemas. -func DefaultRefNameResolver(doc *T, ref componentRef) string +func DefaultRefNameResolver(doc *T, ref ComponentRef) string DefaultRefResolver is a default implementation of refNameResolver for the InternalizeRefs function. @@ -150,7 +150,7 @@ func Int64Ptr(value int64) *int64 func ReadFromFile(loader *Loader, location *url.URL) ([]byte, error) ReadFromFile is a ReadFromURIFunc which reads local file URIs. -func ReferencesComponentInRootDocument(doc *T, ref componentRef) (string, bool) +func ReferencesComponentInRootDocument(doc *T, ref ComponentRef) (string, bool) 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 @@ -316,6 +316,12 @@ func (m Callbacks) JSONLookup(token string) (any, error) JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable +type ComponentRef interface { + RefString() string + RefPath() *url.URL + CollectionName() string +} + type Components struct { Extensions map[string]any `json:"-" yaml:"-"` @@ -1227,7 +1233,7 @@ type Ref struct { Ref is specified by OpenAPI/Swagger 3.0 standard. See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#reference-object -type RefNameResolver func(*T, componentRef) string +type RefNameResolver func(*T, ComponentRef) string RefNameResolver maps a component to an name that is used as it's internalized name. @@ -1990,7 +1996,7 @@ func (doc *T) AddServer(server *Server) func (doc *T) AddServers(servers ...*Server) -func (doc *T) InternalizeRefs(ctx context.Context, refNameResolver func(*T, componentRef) string) +func (doc *T) InternalizeRefs(ctx context.Context, refNameResolver func(*T, ComponentRef) string) InternalizeRefs removes all references to external files from the spec and moves them to the components section. diff --git a/openapi3/helpers.go b/openapi3/helpers.go index cb1ed3a9..d50b3d84 100644 --- a/openapi3/helpers.go +++ b/openapi3/helpers.go @@ -71,7 +71,7 @@ func copyURI(u *url.URL) *url.URL { return &c } -type componentRef interface { +type ComponentRef interface { RefString() string RefPath() *url.URL CollectionName() string @@ -88,7 +88,7 @@ type componentRef interface { // /schema/other.yaml $ref: ../records.yaml // // The records.yaml reference in the 2 latter refers to the same document. -func refersToSameDocument(o1 componentRef, o2 componentRef) bool { +func refersToSameDocument(o1 ComponentRef, o2 ComponentRef) bool { if o1 == nil || o2 == nil { return false } @@ -107,7 +107,7 @@ func refersToSameDocument(o1 componentRef, o2 componentRef) bool { // referencesRootDocument returns if the $ref points to the root document of the OpenAPI spec. // // If the document has no location, perhaps loaded from data in memory, it always returns false. -func referencesRootDocument(doc *T, ref componentRef) bool { +func referencesRootDocument(doc *T, ref ComponentRef) bool { if doc.url == nil || ref == nil || ref.RefPath() == nil { return false } @@ -171,7 +171,7 @@ func referenceURIMatch(u1 *url.URL, u2 *url.URL) bool { // This would also return... // // #/components/schemas/Record -func ReferencesComponentInRootDocument(doc *T, ref componentRef) (string, bool) { +func ReferencesComponentInRootDocument(doc *T, ref ComponentRef) (string, bool) { if ref == nil || ref.RefString() == "" { return "", false } @@ -197,19 +197,19 @@ func ReferencesComponentInRootDocument(doc *T, ref componentRef) (string, bool) panic(err) // unreachable } - var components map[string]componentRef + var components map[string]ComponentRef - componentRefType := reflect.TypeOf(new(componentRef)).Elem() + componentRefType := reflect.TypeOf(new(ComponentRef)).Elem() if t := reflect.TypeOf(collection); t.Kind() == reflect.Map && t.Key().Kind() == reflect.String && t.Elem().AssignableTo(componentRefType) { v := reflect.ValueOf(collection) - components = make(map[string]componentRef, v.Len()) + components = make(map[string]ComponentRef, v.Len()) for _, key := range v.MapKeys() { strct := v.MapIndex(key) // Type assertion safe, already checked via reflection above. - components[key.Interface().(string)] = strct.Interface().(componentRef) + components[key.Interface().(string)] = strct.Interface().(ComponentRef) } } else { return "", false diff --git a/openapi3/internalize_refs.go b/openapi3/internalize_refs.go index b4742864..01f5dad8 100644 --- a/openapi3/internalize_refs.go +++ b/openapi3/internalize_refs.go @@ -10,7 +10,7 @@ import ( // // The function should avoid name collisions (i.e. be a injective mapping). // It must only contain characters valid for fixed field names: [IdentifierRegExp]. -type RefNameResolver func(*T, componentRef) string +type RefNameResolver func(*T, ComponentRef) string // DefaultRefResolver is a default implementation of refNameResolver for the // InternalizeRefs function. @@ -27,7 +27,7 @@ type RefNameResolver func(*T, componentRef) string // // This is an injective mapping over a "reasonable" amount of the possible openapi // spec domain space but is not perfect. There might be edge cases. -func DefaultRefNameResolver(doc *T, ref componentRef) string { +func DefaultRefNameResolver(doc *T, ref ComponentRef) string { if ref.RefString() == "" || ref.RefPath() == nil { panic("unable to resolve reference to name") } @@ -490,7 +490,7 @@ func (doc *T) derefPaths(paths map[string]*PathItem, refNameResolver RefNameReso // Example: // // doc.InternalizeRefs(context.Background(), nil) -func (doc *T) InternalizeRefs(ctx context.Context, refNameResolver func(*T, componentRef) string) { +func (doc *T) InternalizeRefs(ctx context.Context, refNameResolver func(*T, ComponentRef) string) { doc.resetVisited() if refNameResolver == nil {