mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-06 04:20:11 +00:00
Also ran `gofmt` across the entire project. Things need cleaning up. Signed-off-by: Dave Shanley <dave@quobix.com>
105 lines
3.3 KiB
Go
105 lines
3.3 KiB
Go
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||
// SPDX-License-Identifier: MIT
|
||
|
||
package v3
|
||
|
||
import (
|
||
"crypto/sha256"
|
||
"fmt"
|
||
"github.com/pb33f/libopenapi/datamodel/low"
|
||
"github.com/pb33f/libopenapi/index"
|
||
"gopkg.in/yaml.v3"
|
||
"sort"
|
||
"strings"
|
||
)
|
||
|
||
// Link represents a low-level OpenAPI 3+ Link object.
|
||
//
|
||
// The Link object represents a possible design-time link for a response. The presence of a link does not guarantee the
|
||
// caller’s ability to successfully invoke it, rather it provides a known relationship and traversal mechanism between
|
||
// responses and other operations.
|
||
//
|
||
// Unlike dynamic links (i.e. links provided in the response payload), the OAS linking mechanism does not require
|
||
// link information in the runtime response.
|
||
//
|
||
// For computing links, and providing instructions to execute them, a runtime expression is used for accessing values
|
||
// in an operation and using them as parameters while invoking the linked operation.
|
||
// - https://spec.openapis.org/oas/v3.1.0#link-object
|
||
type Link struct {
|
||
OperationRef low.NodeReference[string]
|
||
OperationId low.NodeReference[string]
|
||
Parameters low.NodeReference[map[low.KeyReference[string]]low.ValueReference[string]]
|
||
RequestBody low.NodeReference[string]
|
||
Description low.NodeReference[string]
|
||
Server low.NodeReference[*Server]
|
||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||
*low.Reference
|
||
}
|
||
|
||
// GetExtensions returns all Link extensions and satisfies the low.HasExtensions interface.
|
||
func (l *Link) GetExtensions() map[low.KeyReference[string]]low.ValueReference[any] {
|
||
return l.Extensions
|
||
}
|
||
|
||
// FindParameter will attempt to locate a parameter string value, using a parameter name input.
|
||
func (l *Link) FindParameter(pName string) *low.ValueReference[string] {
|
||
return low.FindItemInMap[string](pName, l.Parameters.Value)
|
||
}
|
||
|
||
// FindExtension will attempt to locate an extension with a specific key
|
||
func (l *Link) FindExtension(ext string) *low.ValueReference[any] {
|
||
return low.FindItemInMap[any](ext, l.Extensions)
|
||
}
|
||
|
||
// Build will extract extensions and servers from the node.
|
||
func (l *Link) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||
l.Reference = new(low.Reference)
|
||
l.Extensions = low.ExtractExtensions(root)
|
||
// extract server.
|
||
ser, sErr := low.ExtractObject[*Server](ServerLabel, root, idx)
|
||
if sErr != nil {
|
||
return sErr
|
||
}
|
||
l.Server = ser
|
||
return nil
|
||
}
|
||
|
||
// Hash will return a consistent SHA256 Hash of the Link object
|
||
func (l *Link) Hash() [32]byte {
|
||
var f []string
|
||
if l.Description.Value != "" {
|
||
f = append(f, l.Description.Value)
|
||
}
|
||
if l.OperationRef.Value != "" {
|
||
f = append(f, l.OperationRef.Value)
|
||
}
|
||
if l.OperationId.Value != "" {
|
||
f = append(f, l.OperationId.Value)
|
||
}
|
||
if l.RequestBody.Value != "" {
|
||
f = append(f, l.RequestBody.Value)
|
||
}
|
||
if l.Server.Value != nil {
|
||
f = append(f, low.GenerateHashString(l.Server.Value))
|
||
}
|
||
// todo: needs ordering.
|
||
|
||
keys := make([]string, len(l.Parameters.Value))
|
||
z := 0
|
||
for k := range l.Parameters.Value {
|
||
keys[z] = l.Parameters.Value[k].Value
|
||
z++
|
||
}
|
||
sort.Strings(keys)
|
||
f = append(f, keys...)
|
||
keys = make([]string, len(l.Extensions))
|
||
z = 0
|
||
for k := range l.Extensions {
|
||
keys[z] = fmt.Sprintf("%s-%x", k.Value, sha256.Sum256([]byte(fmt.Sprint(l.Extensions[k].Value))))
|
||
z++
|
||
}
|
||
sort.Strings(keys)
|
||
f = append(f, keys...)
|
||
return sha256.Sum256([]byte(strings.Join(f, "|")))
|
||
}
|