mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-09 12:37:49 +00:00
Low-level docs for v3 model are now in place
5/6 of the way there!
This commit is contained in:
@@ -8,7 +8,7 @@ import (
|
|||||||
low "github.com/pb33f/libopenapi/datamodel/low/v3"
|
low "github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Link represents an OpenAPI 3+ Link object that is backed by a low-level one.
|
// Link represents a high-level OpenAPI 3+ Link object that is backed by a low-level one.
|
||||||
//
|
//
|
||||||
// The Link object represents a possible design-time link for a response. The presence of a link does not guarantee the
|
// 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
|
// caller’s ability to successfully invoke it, rather it provides a known relationship and traversal mechanism between
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Operation is a high-level representation of an OpenAPI 3+ Operation object, backed by a low-level one.
|
// Operation is a high-level representation of an OpenAPI 3+ Operation object, backed by a low-level one.
|
||||||
|
//
|
||||||
// An Operation is perhaps the most important object of the entire specification. Everything of value
|
// An Operation is perhaps the most important object of the entire specification. Everything of value
|
||||||
// happens here. The entire being for existence of this library and the specification, is this Operation.
|
// happens here. The entire being for existence of this library and the specification, is this Operation.
|
||||||
// - https://spec.openapis.org/oas/v3.1.0#operation-object
|
// - https://spec.openapis.org/oas/v3.1.0#operation-object
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import (
|
|||||||
low "github.com/pb33f/libopenapi/datamodel/low/v3"
|
low "github.com/pb33f/libopenapi/datamodel/low/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RequestBody represents a high-level OpenAPI 3+ RequestBody object,
|
// RequestBody represents a high-level OpenAPI 3+ RequestBody object, backed by a low-level one.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#request-body-object
|
||||||
type RequestBody struct {
|
type RequestBody struct {
|
||||||
Description string
|
Description string
|
||||||
Content map[string]*MediaType
|
Content map[string]*MediaType
|
||||||
@@ -17,6 +18,7 @@ type RequestBody struct {
|
|||||||
low *low.RequestBody
|
low *low.RequestBody
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewRequestBody will create a new high-level RequestBody instance, from a low-level one.
|
||||||
func NewRequestBody(rb *low.RequestBody) *RequestBody {
|
func NewRequestBody(rb *low.RequestBody) *RequestBody {
|
||||||
r := new(RequestBody)
|
r := new(RequestBody)
|
||||||
r.low = rb
|
r.low = rb
|
||||||
@@ -27,6 +29,7 @@ func NewRequestBody(rb *low.RequestBody) *RequestBody {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GoLow returns the low-level RequestBody instance used to create the high-level one.
|
||||||
func (r *RequestBody) GoLow() *low.RequestBody {
|
func (r *RequestBody) GoLow() *low.RequestBody {
|
||||||
return r.low
|
return r.low
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ import low "github.com/pb33f/libopenapi/datamodel/low/v3"
|
|||||||
// to a security scheme declared in the Security Schemes under the Components Object.
|
// to a security scheme declared in the Security Schemes under the Components Object.
|
||||||
//
|
//
|
||||||
// Security Requirement Objects that contain multiple schemes require that all schemes MUST be satisfied for a
|
// Security Requirement Objects that contain multiple schemes require that all schemes MUST be satisfied for a
|
||||||
// request to be authorized. This enables support for scenarios where multiple query parameters or HTTP headers are required to convey security information.
|
// request to be authorized. This enables support for scenarios where multiple query parameters or HTTP headers are
|
||||||
|
// required to convey security information.
|
||||||
//
|
//
|
||||||
// When a list of Security Requirement Objects is defined on the OpenAPI Object or Operation Object, only one of the
|
// When a list of Security Requirement Objects is defined on the OpenAPI Object or Operation Object, only one of the
|
||||||
// Security Requirement Objects in the list needs to be satisfied to authorize the request.
|
// Security Requirement Objects in the list needs to be satisfied to authorize the request.
|
||||||
|
|||||||
@@ -9,15 +9,24 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Callback represents a low-level Callback object for OpenAPI 3+.
|
||||||
|
//
|
||||||
|
// A map of possible out-of band callbacks related to the parent operation. Each value in the map is a
|
||||||
|
// PathItem Object that describes a set of requests that may be initiated by the API provider and the expected
|
||||||
|
// responses. The key value used to identify the path item object is an expression, evaluated at runtime,
|
||||||
|
// that identifies a URL to use for the callback operation.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#callback-object
|
||||||
type Callback struct {
|
type Callback struct {
|
||||||
Expression low.ValueReference[map[low.KeyReference[string]]low.ValueReference[*PathItem]]
|
Expression low.ValueReference[map[low.KeyReference[string]]low.ValueReference[*PathItem]]
|
||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindExpression will locate a string expression and return a ValueReference containing the located PathItem
|
||||||
func (cb *Callback) FindExpression(exp string) *low.ValueReference[*PathItem] {
|
func (cb *Callback) FindExpression(exp string) *low.ValueReference[*PathItem] {
|
||||||
return low.FindItemInMap[*PathItem](exp, cb.Expression.Value)
|
return low.FindItemInMap[*PathItem](exp, cb.Expression.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build will extract extensions, expressions and PathItem objects for Callback
|
||||||
func (cb *Callback) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (cb *Callback) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
cb.Extensions = low.ExtractExtensions(root)
|
cb.Extensions = low.ExtractExtensions(root)
|
||||||
|
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
// Components represents a low-level OpenAPI 3+ Components Object, that is backed by a low-level one.
|
||||||
ComponentsLabel = "components"
|
//
|
||||||
SchemasLabel = "schemas"
|
// Holds a set of reusable objects for different aspects of the OAS. All objects defined within the components object
|
||||||
)
|
// will have no effect on the API unless they are explicitly referenced from properties outside the components object.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#components-object
|
||||||
type Components struct {
|
type Components struct {
|
||||||
Schemas low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*base.SchemaProxy]]
|
Schemas low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*base.SchemaProxy]]
|
||||||
Responses low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Response]]
|
Responses low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Response]]
|
||||||
@@ -31,26 +31,32 @@ type Components struct {
|
|||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindExtension attempts to locate an extension with the supplied key
|
||||||
func (co *Components) FindExtension(ext string) *low.ValueReference[any] {
|
func (co *Components) FindExtension(ext string) *low.ValueReference[any] {
|
||||||
return low.FindItemInMap[any](ext, co.Extensions)
|
return low.FindItemInMap[any](ext, co.Extensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindSchema attempts to locate a SchemaProxy from 'schemas' with a specific name
|
||||||
func (co *Components) FindSchema(schema string) *low.ValueReference[*base.SchemaProxy] {
|
func (co *Components) FindSchema(schema string) *low.ValueReference[*base.SchemaProxy] {
|
||||||
return low.FindItemInMap[*base.SchemaProxy](schema, co.Schemas.Value)
|
return low.FindItemInMap[*base.SchemaProxy](schema, co.Schemas.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindResponse attempts to locate a Response from 'responses' with a specific name
|
||||||
func (co *Components) FindResponse(response string) *low.ValueReference[*Response] {
|
func (co *Components) FindResponse(response string) *low.ValueReference[*Response] {
|
||||||
return low.FindItemInMap[*Response](response, co.Responses.Value)
|
return low.FindItemInMap[*Response](response, co.Responses.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindParameter attempts to locate a Parameter from 'parameters' with a specific name
|
||||||
func (co *Components) FindParameter(response string) *low.ValueReference[*Parameter] {
|
func (co *Components) FindParameter(response string) *low.ValueReference[*Parameter] {
|
||||||
return low.FindItemInMap[*Parameter](response, co.Parameters.Value)
|
return low.FindItemInMap[*Parameter](response, co.Parameters.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindSecurityScheme attempts to locate a SecurityScheme from 'securitySchemes' with a specific name
|
||||||
func (co *Components) FindSecurityScheme(sScheme string) *low.ValueReference[*SecurityScheme] {
|
func (co *Components) FindSecurityScheme(sScheme string) *low.ValueReference[*SecurityScheme] {
|
||||||
return low.FindItemInMap[*SecurityScheme](sScheme, co.SecuritySchemes.Value)
|
return low.FindItemInMap[*SecurityScheme](sScheme, co.SecuritySchemes.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindExample attempts tp
|
||||||
func (co *Components) FindExample(example string) *low.ValueReference[*base.Example] {
|
func (co *Components) FindExample(example string) *low.ValueReference[*base.Example] {
|
||||||
return low.FindItemInMap[*base.Example](example, co.Examples.Value)
|
return low.FindItemInMap[*base.Example](example, co.Examples.Value)
|
||||||
}
|
}
|
||||||
|
|||||||
41
datamodel/low/v3/constants.go
Normal file
41
datamodel/low/v3/constants.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package v3
|
||||||
|
|
||||||
|
// Label definitions used to look up vales in yaml.Node tree.
|
||||||
|
const (
|
||||||
|
ComponentsLabel = "components"
|
||||||
|
SchemasLabel = "schemas"
|
||||||
|
EncodingLabel = "encoding"
|
||||||
|
HeadersLabel = "headers"
|
||||||
|
ParametersLabel = "parameters"
|
||||||
|
RequestBodyLabel = "requestBody"
|
||||||
|
RequestBodiesLabel = "requestBodies"
|
||||||
|
ResponsesLabel = "responses"
|
||||||
|
CallbacksLabel = "callbacks"
|
||||||
|
ContentLabel = "content"
|
||||||
|
PathsLabel = "paths"
|
||||||
|
WebhooksLabel = "webhooks"
|
||||||
|
JSONSchemaDialectLabel = "jsonSchemaDialect"
|
||||||
|
GetLabel = "get"
|
||||||
|
PostLabel = "post"
|
||||||
|
PatchLabel = "patch"
|
||||||
|
PutLabel = "put"
|
||||||
|
DeleteLabel = "delete"
|
||||||
|
OptionsLabel = "options"
|
||||||
|
HeadLabel = "head"
|
||||||
|
TraceLabel = "trace"
|
||||||
|
LinksLabel = "links"
|
||||||
|
DefaultLabel = "default"
|
||||||
|
SecurityLabel = "security"
|
||||||
|
SecuritySchemesLabel = "securitySchemes"
|
||||||
|
OAuthFlowsLabel = "flows"
|
||||||
|
VariablesLabel = "variables"
|
||||||
|
ServersLabel = "servers"
|
||||||
|
ServerLabel = "server"
|
||||||
|
ImplicitLabel = "implicit"
|
||||||
|
PasswordLabel = "password"
|
||||||
|
ClientCredentialsLabel = "clientCredentials"
|
||||||
|
AuthorizationCodeLabel = "authorizationCode"
|
||||||
|
)
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package v3
|
package v3
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"github.com/pb33f/libopenapi/datamodel"
|
"github.com/pb33f/libopenapi/datamodel"
|
||||||
"github.com/pb33f/libopenapi/datamodel/low/base"
|
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -577,3 +578,28 @@ func TestCreateDocument_ExternalDoc_Error(t *testing.T) {
|
|||||||
_, err = CreateDocument(info)
|
_, err = CreateDocument(info)
|
||||||
assert.Len(t, err, 1)
|
assert.Len(t, err, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleCreateDocument() {
|
||||||
|
// How to create a low-level OpenAPI 3 Document
|
||||||
|
|
||||||
|
// load petstore into bytes
|
||||||
|
petstoreBytes, _ := ioutil.ReadFile("../../../test_specs/petstorev3.json")
|
||||||
|
|
||||||
|
// read in specification
|
||||||
|
info, _ := datamodel.ExtractSpecInfo(petstoreBytes)
|
||||||
|
|
||||||
|
// build low-level document model
|
||||||
|
document, errors := CreateDocument(info)
|
||||||
|
|
||||||
|
// if something went wrong, a slice of errors is returned
|
||||||
|
if len(errors) > 0 {
|
||||||
|
for i := range errors {
|
||||||
|
fmt.Printf("error: %s\n", errors[i].Error())
|
||||||
|
}
|
||||||
|
panic("cannot build document")
|
||||||
|
}
|
||||||
|
|
||||||
|
// print out email address from the info > contact object.
|
||||||
|
fmt.Print(document.Info.Value.Contact.Value.Email.Value)
|
||||||
|
// Output: apiteam@swagger.io
|
||||||
|
}
|
||||||
@@ -1,6 +1,11 @@
|
|||||||
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
// Package v3 represents all OpenAPI 3+ low-level models. High-level models are more difficult to navigate
|
||||||
|
// than higher-level models, however they are packed with all the raw AST and node data required to perform
|
||||||
|
// any kind of analysis on the underlying data.
|
||||||
|
//
|
||||||
|
// Every property is wrapped in a NodeReference or a KeyReference or a ValueReference.
|
||||||
package v3
|
package v3
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -10,21 +15,76 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Document struct {
|
type Document struct {
|
||||||
Version low.ValueReference[string]
|
|
||||||
Info low.NodeReference[*base.Info]
|
// Version is the version of OpenAPI being used, extracted from the 'openapi: x.x.x' definition.
|
||||||
JsonSchemaDialect low.NodeReference[string] // 3.1
|
// This is not a standard property of the OpenAPI model, it's a convenience mechanism only.
|
||||||
Webhooks low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*PathItem]] // 3.1
|
Version low.ValueReference[string]
|
||||||
Servers low.NodeReference[[]low.ValueReference[*Server]]
|
|
||||||
Paths low.NodeReference[*Paths]
|
// Info represents a specification Info definitions
|
||||||
Components low.NodeReference[*Components]
|
// Provides metadata about the API. The metadata MAY be used by tooling as required.
|
||||||
Security low.NodeReference[*SecurityRequirement]
|
// - https://spec.openapis.org/oas/v3.1.0#info-object
|
||||||
Tags low.NodeReference[[]low.ValueReference[*base.Tag]]
|
Info low.NodeReference[*base.Info]
|
||||||
ExternalDocs low.NodeReference[*base.ExternalDoc]
|
|
||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
// JsonSchemaDialect is a 3.1+ property that sets the dialect to use for validating *base.Schema definitions
|
||||||
Index *index.SpecIndex
|
// The default value for the $schema keyword within Schema Objects contained within this OAS document.
|
||||||
|
// This MUST be in the form of a URI.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#schema-object
|
||||||
|
JsonSchemaDialect low.NodeReference[string] // 3.1
|
||||||
|
|
||||||
|
// Webhooks is a 3.1+ property that is similar to callbacks, except, this defines incoming webhooks.
|
||||||
|
// The incoming webhooks that MAY be received as part of this API and that the API consumer MAY choose to implement.
|
||||||
|
// Closely related to the callbacks feature, this section describes requests initiated other than by an API call,
|
||||||
|
// for example by an out-of-band registration. The key name is a unique string to refer to each webhook,
|
||||||
|
// while the (optionally referenced) Path Item Object describes a request that may be initiated by the API provider
|
||||||
|
// and the expected responses. An example is available.
|
||||||
|
Webhooks low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*PathItem]] // 3.1
|
||||||
|
|
||||||
|
// Servers is a slice of Server instances which provide connectivity information to a target server. If the servers
|
||||||
|
// property is not provided, or is an empty array, the default value would be a Server Object with a url value of /.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#server-object
|
||||||
|
Servers low.NodeReference[[]low.ValueReference[*Server]]
|
||||||
|
|
||||||
|
// Paths contains all the PathItem definitions for the specification.
|
||||||
|
// The available paths and operations for the API, The most important part of ths spec.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#paths-object
|
||||||
|
Paths low.NodeReference[*Paths]
|
||||||
|
|
||||||
|
// Components is an element to hold various schemas for the document.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#components-object
|
||||||
|
Components low.NodeReference[*Components]
|
||||||
|
|
||||||
|
// Security contains global security requirements/roles for the specification
|
||||||
|
// A declaration of which security mechanisms can be used across the API. The list of values includes alternative
|
||||||
|
// security requirement objects that can be used. Only one of the security requirement objects need to be satisfied
|
||||||
|
// to authorize a request. Individual operations can override this definition. To make security optional,
|
||||||
|
// an empty security requirement ({}) can be included in the array.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#security-requirement-object
|
||||||
|
Security low.NodeReference[*SecurityRequirement]
|
||||||
|
|
||||||
|
// Tags is a slice of base.Tag instances defined by the specification
|
||||||
|
// A list of tags used by the document with additional metadata. The order of the tags can be used to reflect on
|
||||||
|
// their order by the parsing tools. Not all tags that are used by the Operation Object must be declared.
|
||||||
|
// The tags that are not declared MAY be organized randomly or based on the tools’ logic.
|
||||||
|
// Each tag name in the list MUST be unique.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#tag-object
|
||||||
|
Tags low.NodeReference[[]low.ValueReference[*base.Tag]]
|
||||||
|
|
||||||
|
// ExternalDocs is an instance of base.ExternalDoc for.. well, obvious really, innit.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#external-documentation-object
|
||||||
|
ExternalDocs low.NodeReference[*base.ExternalDoc]
|
||||||
|
|
||||||
|
// Extensions contains all custom extensions defined for the top-level document.
|
||||||
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
|
|
||||||
|
// Index is a reference to the *index.SpecIndex that was created for the document and used
|
||||||
|
// as a guide when building out the Document. Ideal if further processing is required on the model and
|
||||||
|
// the original details are required to continue the work.
|
||||||
|
//
|
||||||
|
// This property is not a part of the OpenAPI schema, this is custom to libopenapi.
|
||||||
|
Index *index.SpecIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// TODO: this is early prototype mutation/modification code, keeping it around for later.
|
||||||
//func (d *Document) AddTag() *base.Tag {
|
//func (d *Document) AddTag() *base.Tag {
|
||||||
// t := base.NewTag()
|
// t := base.NewTag()
|
||||||
// //d.Tags.KeyNode
|
// //d.Tags.KeyNode
|
||||||
|
|||||||
@@ -9,10 +9,8 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
// Encoding represents a low-level OpenAPI 3+ Encoding object
|
||||||
EncodingLabel = "encoding"
|
// - https://spec.openapis.org/oas/v3.1.0#encoding-object
|
||||||
)
|
|
||||||
|
|
||||||
type Encoding struct {
|
type Encoding struct {
|
||||||
ContentType low.NodeReference[string]
|
ContentType low.NodeReference[string]
|
||||||
Headers low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Header]]
|
Headers low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Header]]
|
||||||
@@ -21,12 +19,13 @@ type Encoding struct {
|
|||||||
AllowReserved low.NodeReference[bool]
|
AllowReserved low.NodeReference[bool]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindHeader attempts to locate a Header with the supplied name
|
||||||
func (en *Encoding) FindHeader(hType string) *low.ValueReference[*Header] {
|
func (en *Encoding) FindHeader(hType string) *low.ValueReference[*Header] {
|
||||||
return low.FindItemInMap[*Header](hType, en.Headers.Value)
|
return low.FindItemInMap[*Header](hType, en.Headers.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build will extract all Header objects from supplied node.
|
||||||
func (en *Encoding) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (en *Encoding) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
|
|
||||||
headers, hL, hN, err := low.ExtractMap[*Header](HeadersLabel, root, idx)
|
headers, hL, hN, err := low.ExtractMap[*Header](HeadersLabel, root, idx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -38,6 +37,5 @@ func (en *Encoding) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
ValueNode: hN,
|
ValueNode: hN,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
35
datamodel/low/v3/examples_test.go
Normal file
35
datamodel/low/v3/examples_test.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package v3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/pb33f/libopenapi/datamodel"
|
||||||
|
"io/ioutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Example_createLowDocument() {
|
||||||
|
// How to create a low-level OpenAPI 3 Document
|
||||||
|
|
||||||
|
// load petstore into bytes
|
||||||
|
petstoreBytes, _ := ioutil.ReadFile("../../../test_specs/petstorev3.json")
|
||||||
|
|
||||||
|
// read in specification
|
||||||
|
info, _ := datamodel.ExtractSpecInfo(petstoreBytes)
|
||||||
|
|
||||||
|
// build low-level document model
|
||||||
|
document, errors := CreateDocument(info)
|
||||||
|
|
||||||
|
// if something went wrong, a slice of errors is returned
|
||||||
|
if len(errors) > 0 {
|
||||||
|
for i := range errors {
|
||||||
|
fmt.Printf("error: %s\n", errors[i].Error())
|
||||||
|
}
|
||||||
|
panic("cannot build document")
|
||||||
|
}
|
||||||
|
|
||||||
|
// print out email address from the info > contact object.
|
||||||
|
fmt.Print(document.Info.Value.Contact.Value.Email.Value)
|
||||||
|
// Output: apiteam@swagger.io
|
||||||
|
}
|
||||||
@@ -11,10 +11,8 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
// Header represents a low-level OpenAPI 3+ Header object.
|
||||||
HeadersLabel = "headers"
|
// - https://spec.openapis.org/oas/v3.1.0#header-object
|
||||||
)
|
|
||||||
|
|
||||||
type Header struct {
|
type Header struct {
|
||||||
Description low.NodeReference[string]
|
Description low.NodeReference[string]
|
||||||
Required low.NodeReference[bool]
|
Required low.NodeReference[bool]
|
||||||
@@ -30,18 +28,22 @@ type Header struct {
|
|||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindExtension will attempt to locate an extension with the supplied name
|
||||||
func (h *Header) FindExtension(ext string) *low.ValueReference[any] {
|
func (h *Header) FindExtension(ext string) *low.ValueReference[any] {
|
||||||
return low.FindItemInMap[any](ext, h.Extensions)
|
return low.FindItemInMap[any](ext, h.Extensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindExample will attempt to locate an Example with a specified name
|
||||||
func (h *Header) FindExample(eType string) *low.ValueReference[*base.Example] {
|
func (h *Header) FindExample(eType string) *low.ValueReference[*base.Example] {
|
||||||
return low.FindItemInMap[*base.Example](eType, h.Examples.Value)
|
return low.FindItemInMap[*base.Example](eType, h.Examples.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindContent will attempt to locate a MediaType definition, with a specified name
|
||||||
func (h *Header) FindContent(ext string) *low.ValueReference[*MediaType] {
|
func (h *Header) FindContent(ext string) *low.ValueReference[*MediaType] {
|
||||||
return low.FindItemInMap[*MediaType](ext, h.Content.Value)
|
return low.FindItemInMap[*MediaType](ext, h.Content.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build will extract extensions, examples, schema and content/media types from node.
|
||||||
func (h *Header) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (h *Header) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
h.Extensions = low.ExtractExtensions(root)
|
h.Extensions = low.ExtractExtensions(root)
|
||||||
|
|
||||||
@@ -83,6 +85,5 @@ func (h *Header) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
KeyNode: cL,
|
KeyNode: cL,
|
||||||
ValueNode: cN,
|
ValueNode: cN,
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,18 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 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 {
|
type Link struct {
|
||||||
OperationRef low.NodeReference[string]
|
OperationRef low.NodeReference[string]
|
||||||
OperationId low.NodeReference[string]
|
OperationId low.NodeReference[string]
|
||||||
@@ -19,14 +31,17 @@ type Link struct {
|
|||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindParameter will attempt to locate a parameter string value, using a parameter name input.
|
||||||
func (l *Link) FindParameter(pName string) *low.ValueReference[string] {
|
func (l *Link) FindParameter(pName string) *low.ValueReference[string] {
|
||||||
return low.FindItemInMap[string](pName, l.Parameters.Value)
|
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] {
|
func (l *Link) FindExtension(ext string) *low.ValueReference[any] {
|
||||||
return low.FindItemInMap[any](ext, l.Extensions)
|
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 {
|
func (l *Link) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
l.Extensions = low.ExtractExtensions(root)
|
l.Extensions = low.ExtractExtensions(root)
|
||||||
|
|
||||||
@@ -36,6 +51,5 @@ func (l *Link) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
return sErr
|
return sErr
|
||||||
}
|
}
|
||||||
l.Server = ser
|
l.Server = ser
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// MediaType represents a low-level OpenAPI MediaType object.
|
||||||
|
//
|
||||||
|
// Each Media Type Object provides schema and examples for the media type identified by its key.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#media-type-object
|
||||||
type MediaType struct {
|
type MediaType struct {
|
||||||
Schema low.NodeReference[*base.SchemaProxy]
|
Schema low.NodeReference[*base.SchemaProxy]
|
||||||
Example low.NodeReference[any]
|
Example low.NodeReference[any]
|
||||||
@@ -19,22 +23,27 @@ type MediaType struct {
|
|||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindExtension will attempt to locate an extension with the supplied name.
|
||||||
func (mt *MediaType) FindExtension(ext string) *low.ValueReference[any] {
|
func (mt *MediaType) FindExtension(ext string) *low.ValueReference[any] {
|
||||||
return low.FindItemInMap[any](ext, mt.Extensions)
|
return low.FindItemInMap[any](ext, mt.Extensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindPropertyEncoding will attempt to locate an Encoding value with a specific name.
|
||||||
func (mt *MediaType) FindPropertyEncoding(eType string) *low.ValueReference[*Encoding] {
|
func (mt *MediaType) FindPropertyEncoding(eType string) *low.ValueReference[*Encoding] {
|
||||||
return low.FindItemInMap[*Encoding](eType, mt.Encoding.Value)
|
return low.FindItemInMap[*Encoding](eType, mt.Encoding.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindExample will attempt to locate an Example with a specific name.
|
||||||
func (mt *MediaType) FindExample(eType string) *low.ValueReference[*base.Example] {
|
func (mt *MediaType) FindExample(eType string) *low.ValueReference[*base.Example] {
|
||||||
return low.FindItemInMap[*base.Example](eType, mt.Examples.Value)
|
return low.FindItemInMap[*base.Example](eType, mt.Examples.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAllExamples will extract all examples from the MediaType instance.
|
||||||
func (mt *MediaType) GetAllExamples() map[low.KeyReference[string]]low.ValueReference[*base.Example] {
|
func (mt *MediaType) GetAllExamples() map[low.KeyReference[string]]low.ValueReference[*base.Example] {
|
||||||
return mt.Examples.Value
|
return mt.Examples.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build will extract examples, extensions, schema and encoding from node.
|
||||||
func (mt *MediaType) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (mt *MediaType) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
mt.Extensions = low.ExtractExtensions(root)
|
mt.Extensions = low.ExtractExtensions(root)
|
||||||
|
|
||||||
|
|||||||
@@ -9,13 +9,8 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
// OAuthFlows represents a low-level OpenAPI 3+ OAuthFlows object.
|
||||||
ImplicitLabel = "implicit"
|
// - https://spec.openapis.org/oas/v3.1.0#oauth-flows-object
|
||||||
PasswordLabel = "password"
|
|
||||||
ClientCredentialsLabel = "clientCredentials"
|
|
||||||
AuthorizationCodeLabel = "authorizationCode"
|
|
||||||
)
|
|
||||||
|
|
||||||
type OAuthFlows struct {
|
type OAuthFlows struct {
|
||||||
Implicit low.NodeReference[*OAuthFlow]
|
Implicit low.NodeReference[*OAuthFlow]
|
||||||
Password low.NodeReference[*OAuthFlow]
|
Password low.NodeReference[*OAuthFlow]
|
||||||
@@ -24,10 +19,12 @@ type OAuthFlows struct {
|
|||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindExtension will attempt to locate an extension with the supplied name.
|
||||||
func (o *OAuthFlows) FindExtension(ext string) *low.ValueReference[any] {
|
func (o *OAuthFlows) FindExtension(ext string) *low.ValueReference[any] {
|
||||||
return low.FindItemInMap[any](ext, o.Extensions)
|
return low.FindItemInMap[any](ext, o.Extensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build will extract extensions and all OAuthFlow types from the supplied node.
|
||||||
func (o *OAuthFlows) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (o *OAuthFlows) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
o.Extensions = low.ExtractExtensions(root)
|
o.Extensions = low.ExtractExtensions(root)
|
||||||
|
|
||||||
@@ -58,6 +55,8 @@ func (o *OAuthFlows) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OAuthFlow represents a low-level OpenAPI 3+ OAuthFlow object.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#oauth-flow-object
|
||||||
type OAuthFlow struct {
|
type OAuthFlow struct {
|
||||||
AuthorizationUrl low.NodeReference[string]
|
AuthorizationUrl low.NodeReference[string]
|
||||||
TokenUrl low.NodeReference[string]
|
TokenUrl low.NodeReference[string]
|
||||||
@@ -66,14 +65,17 @@ type OAuthFlow struct {
|
|||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindScope attempts to locate a scope using a specified name.
|
||||||
func (o *OAuthFlow) FindScope(scope string) *low.ValueReference[string] {
|
func (o *OAuthFlow) FindScope(scope string) *low.ValueReference[string] {
|
||||||
return low.FindItemInMap[string](scope, o.Scopes.Value)
|
return low.FindItemInMap[string](scope, o.Scopes.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindExtension attempts to locate an extension with a specified key
|
||||||
func (o *OAuthFlow) FindExtension(ext string) *low.ValueReference[any] {
|
func (o *OAuthFlow) FindExtension(ext string) *low.ValueReference[any] {
|
||||||
return low.FindItemInMap[any](ext, o.Extensions)
|
return low.FindItemInMap[any](ext, o.Extensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build will extract extensions from the node.
|
||||||
func (o *OAuthFlow) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (o *OAuthFlow) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
o.Extensions = low.ExtractExtensions(root)
|
o.Extensions = low.ExtractExtensions(root)
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -10,14 +10,11 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
// Operation is a low-level representation of an OpenAPI 3+ Operation object.
|
||||||
ParametersLabel = "parameters"
|
//
|
||||||
RequestBodyLabel = "requestBody"
|
// An Operation is perhaps the most important object of the entire specification. Everything of value
|
||||||
RequestBodiesLabel = "requestBodies"
|
// happens here. The entire being for existence of this library and the specification, is this Operation.
|
||||||
ResponsesLabel = "responses"
|
// - https://spec.openapis.org/oas/v3.1.0#operation-object
|
||||||
CallbacksLabel = "callbacks"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Operation struct {
|
type Operation struct {
|
||||||
Tags low.NodeReference[[]low.ValueReference[string]]
|
Tags low.NodeReference[[]low.ValueReference[string]]
|
||||||
Summary low.NodeReference[string]
|
Summary low.NodeReference[string]
|
||||||
@@ -34,10 +31,12 @@ type Operation struct {
|
|||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindCallback will attempt to locate a Callback instance by the supplied name.
|
||||||
func (o *Operation) FindCallback(callback string) *low.ValueReference[*Callback] {
|
func (o *Operation) FindCallback(callback string) *low.ValueReference[*Callback] {
|
||||||
return low.FindItemInMap[*Callback](callback, o.Callbacks.Value)
|
return low.FindItemInMap[*Callback](callback, o.Callbacks.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build will extract external docs, parameters, request body, responses, callbacks, security and servers.
|
||||||
func (o *Operation) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (o *Operation) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
o.Extensions = low.ExtractExtensions(root)
|
o.Extensions = low.ExtractExtensions(root)
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
// Parameter represents a high-level OpenAPI 3+ Parameter object, that is backed by a low-level one.
|
||||||
ContentLabel = "content"
|
//
|
||||||
)
|
// A unique parameter is defined by a combination of a name and location.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#parameter-object
|
||||||
type Parameter struct {
|
type Parameter struct {
|
||||||
Name low.NodeReference[string]
|
Name low.NodeReference[string]
|
||||||
In low.NodeReference[string]
|
In low.NodeReference[string]
|
||||||
@@ -32,18 +32,22 @@ type Parameter struct {
|
|||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindContent will attempt to locate a MediaType instance using the specified name.
|
||||||
func (p *Parameter) FindContent(cType string) *low.ValueReference[*MediaType] {
|
func (p *Parameter) FindContent(cType string) *low.ValueReference[*MediaType] {
|
||||||
return low.FindItemInMap[*MediaType](cType, p.Content.Value)
|
return low.FindItemInMap[*MediaType](cType, p.Content.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindExample will attempt to locate a base.Example instance using the specified name.
|
||||||
func (p *Parameter) FindExample(eType string) *low.ValueReference[*base.Example] {
|
func (p *Parameter) FindExample(eType string) *low.ValueReference[*base.Example] {
|
||||||
return low.FindItemInMap[*base.Example](eType, p.Examples.Value)
|
return low.FindItemInMap[*base.Example](eType, p.Examples.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindExtension attempts to locate an extension using the specified name.
|
||||||
func (p *Parameter) FindExtension(ext string) *low.ValueReference[any] {
|
func (p *Parameter) FindExtension(ext string) *low.ValueReference[any] {
|
||||||
return low.FindItemInMap[any](ext, p.Extensions)
|
return low.FindItemInMap[any](ext, p.Extensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build will extract examples, extensions and content/media types.
|
||||||
func (p *Parameter) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (p *Parameter) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
p.Extensions = low.ExtractExtensions(root)
|
p.Extensions = low.ExtractExtensions(root)
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,12 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PathItem represents a low-level OpenAPI 3+ PathItem object.
|
||||||
|
//
|
||||||
|
// Describes the operations available on a single path. A Path Item MAY be empty, due to ACL constraints.
|
||||||
|
// The path itself is still exposed to the documentation viewer, but they will not know which operations and parameters
|
||||||
|
// are available.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#path-item-object
|
||||||
type PathItem struct {
|
type PathItem struct {
|
||||||
Description low.NodeReference[string]
|
Description low.NodeReference[string]
|
||||||
Summary low.NodeReference[string]
|
Summary low.NodeReference[string]
|
||||||
@@ -29,10 +35,13 @@ type PathItem struct {
|
|||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindExtension attempts to find an extension
|
||||||
func (p *PathItem) FindExtension(ext string) *low.ValueReference[any] {
|
func (p *PathItem) FindExtension(ext string) *low.ValueReference[any] {
|
||||||
return low.FindItemInMap[any](ext, p.Extensions)
|
return low.FindItemInMap[any](ext, p.Extensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build extracts extensions, parameters, servers and each http method defined.
|
||||||
|
// everything is extracted asynchronously for speed.
|
||||||
func (p *PathItem) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (p *PathItem) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
p.Extensions = low.ExtractExtensions(root)
|
p.Extensions = low.ExtractExtensions(root)
|
||||||
skip := false
|
skip := false
|
||||||
@@ -204,6 +213,5 @@ func (p *PathItem) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
if len(ops) > 0 {
|
if len(ops) > 0 {
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,25 +12,18 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
// Paths represents a high-level OpenAPI 3+ Paths object, that is backed by a low-level one.
|
||||||
PathsLabel = "paths"
|
//
|
||||||
WebhooksLabel = "webhooks"
|
// Holds the relative paths to the individual endpoints and their operations. The path is appended to the URL from the
|
||||||
JSONSchemaDialectLabel = "jsonSchemaDialect"
|
// Server Object in order to construct the full URL. The Paths MAY be empty, due to Access Control List (ACL)
|
||||||
GetLabel = "get"
|
// constraints.
|
||||||
PostLabel = "post"
|
// - https://spec.openapis.org/oas/v3.1.0#paths-object
|
||||||
PatchLabel = "patch"
|
|
||||||
PutLabel = "put"
|
|
||||||
DeleteLabel = "delete"
|
|
||||||
OptionsLabel = "options"
|
|
||||||
HeadLabel = "head"
|
|
||||||
TraceLabel = "trace"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Paths struct {
|
type Paths struct {
|
||||||
PathItems map[low.KeyReference[string]]low.ValueReference[*PathItem]
|
PathItems map[low.KeyReference[string]]low.ValueReference[*PathItem]
|
||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindPath will attempt to locate a PathItem using the provided path string.
|
||||||
func (p *Paths) FindPath(path string) *low.ValueReference[*PathItem] {
|
func (p *Paths) FindPath(path string) *low.ValueReference[*PathItem] {
|
||||||
for k, j := range p.PathItems {
|
for k, j := range p.PathItems {
|
||||||
if k.Value == path {
|
if k.Value == path {
|
||||||
@@ -40,10 +33,12 @@ func (p *Paths) FindPath(path string) *low.ValueReference[*PathItem] {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindExtension will attempt to locate an extension using the specified string.
|
||||||
func (p *Paths) FindExtension(ext string) *low.ValueReference[any] {
|
func (p *Paths) FindExtension(ext string) *low.ValueReference[any] {
|
||||||
return low.FindItemInMap[any](ext, p.Extensions)
|
return low.FindItemInMap[any](ext, p.Extensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build will extract extensions and all PathItems. This happens asynchronously for speed.
|
||||||
func (p *Paths) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (p *Paths) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
p.Extensions = low.ExtractExtensions(root)
|
p.Extensions = low.ExtractExtensions(root)
|
||||||
skip := false
|
skip := false
|
||||||
@@ -126,5 +121,4 @@ func (p *Paths) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
}
|
}
|
||||||
p.PathItems = pathsMap
|
p.PathItems = pathsMap
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,8 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// RequestBody represents a low-level OpenAPI 3+ RequestBody object.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#request-body-object
|
||||||
type RequestBody struct {
|
type RequestBody struct {
|
||||||
Description low.NodeReference[string]
|
Description low.NodeReference[string]
|
||||||
Content low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*MediaType]]
|
Content low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*MediaType]]
|
||||||
@@ -16,14 +18,17 @@ type RequestBody struct {
|
|||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindExtension attemps to locate an extension using the provided name.
|
||||||
func (rb *RequestBody) FindExtension(ext string) *low.ValueReference[any] {
|
func (rb *RequestBody) FindExtension(ext string) *low.ValueReference[any] {
|
||||||
return low.FindItemInMap[any](ext, rb.Extensions)
|
return low.FindItemInMap[any](ext, rb.Extensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindContent attempts to find content/MediaType defined using a specified name.
|
||||||
func (rb *RequestBody) FindContent(cType string) *low.ValueReference[*MediaType] {
|
func (rb *RequestBody) FindContent(cType string) *low.ValueReference[*MediaType] {
|
||||||
return low.FindItemInMap[*MediaType](cType, rb.Content.Value)
|
return low.FindItemInMap[*MediaType](cType, rb.Content.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build will extract extensions and MediaType objects from the node.
|
||||||
func (rb *RequestBody) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (rb *RequestBody) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
rb.Extensions = low.ExtractExtensions(root)
|
rb.Extensions = low.ExtractExtensions(root)
|
||||||
|
|
||||||
|
|||||||
@@ -11,16 +11,26 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
// Responses represents a low-level OpenAPI 3+ Responses object.
|
||||||
LinksLabel = "links"
|
//
|
||||||
DefaultLabel = "default"
|
// It's a container for the expected responses of an operation. The container maps a HTTP response code to the
|
||||||
)
|
// expected response.
|
||||||
|
//
|
||||||
|
// The specification is not necessarily expected to cover all possible HTTP response codes because they may not be
|
||||||
|
// known in advance. However, documentation is expected to cover a successful operation response and any known errors.
|
||||||
|
//
|
||||||
|
// The default MAY be used as a default response object for all HTTP codes that are not covered individually by
|
||||||
|
// the Responses Object.
|
||||||
|
//
|
||||||
|
// The Responses Object MUST contain at least one response code, and if only one response code is provided it SHOULD
|
||||||
|
// be the response for a successful operation call.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#responses-object
|
||||||
type Responses struct {
|
type Responses struct {
|
||||||
Codes map[low.KeyReference[string]]low.ValueReference[*Response]
|
Codes map[low.KeyReference[string]]low.ValueReference[*Response]
|
||||||
Default low.NodeReference[*Response]
|
Default low.NodeReference[*Response]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build will extract default response and all Response objects for each code
|
||||||
func (r *Responses) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (r *Responses) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
if utils.IsNodeMap(root) {
|
if utils.IsNodeMap(root) {
|
||||||
codes, err := low.ExtractMapNoLookup[*Response](root, idx)
|
codes, err := low.ExtractMapNoLookup[*Response](root, idx)
|
||||||
@@ -39,15 +49,22 @@ func (r *Responses) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
r.Default = def
|
r.Default = def
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("responses build failed: vn node is not a map! line %d, col %d", root.Line, root.Column)
|
return fmt.Errorf("responses build failed: vn node is not a map! line %d, col %d",
|
||||||
|
root.Line, root.Column)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindResponseByCode will attempt to locate a Response using an HTTP response code.
|
||||||
func (r *Responses) FindResponseByCode(code string) *low.ValueReference[*Response] {
|
func (r *Responses) FindResponseByCode(code string) *low.ValueReference[*Response] {
|
||||||
return low.FindItemInMap[*Response](code, r.Codes)
|
return low.FindItemInMap[*Response](code, r.Codes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Response represents a high-level OpenAPI 3+ Response object that is backed by a low-level one.
|
||||||
|
//
|
||||||
|
// Describes a single response from an API Operation, including design-time, static links to
|
||||||
|
// operations based on the response.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#response-object
|
||||||
type Response struct {
|
type Response struct {
|
||||||
Description low.NodeReference[string]
|
Description low.NodeReference[string]
|
||||||
Headers low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Header]]
|
Headers low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Header]]
|
||||||
@@ -56,22 +73,27 @@ type Response struct {
|
|||||||
Links low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Link]]
|
Links low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Link]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindExtension will attempt to locate an extension using the supplied key
|
||||||
func (r *Response) FindExtension(ext string) *low.ValueReference[any] {
|
func (r *Response) FindExtension(ext string) *low.ValueReference[any] {
|
||||||
return low.FindItemInMap[any](ext, r.Extensions)
|
return low.FindItemInMap[any](ext, r.Extensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindContent will attempt to locate a MediaType instance using the supplied key.
|
||||||
func (r *Response) FindContent(cType string) *low.ValueReference[*MediaType] {
|
func (r *Response) FindContent(cType string) *low.ValueReference[*MediaType] {
|
||||||
return low.FindItemInMap[*MediaType](cType, r.Content.Value)
|
return low.FindItemInMap[*MediaType](cType, r.Content.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindHeader will attempt to locate a Header instance using the supplied key.
|
||||||
func (r *Response) FindHeader(hType string) *low.ValueReference[*Header] {
|
func (r *Response) FindHeader(hType string) *low.ValueReference[*Header] {
|
||||||
return low.FindItemInMap[*Header](hType, r.Headers.Value)
|
return low.FindItemInMap[*Header](hType, r.Headers.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindLink will attempt to locate a Link instance using the supplied key.
|
||||||
func (r *Response) FindLink(hType string) *low.ValueReference[*Link] {
|
func (r *Response) FindLink(hType string) *low.ValueReference[*Link] {
|
||||||
return low.FindItemInMap[*Link](hType, r.Links.Value)
|
return low.FindItemInMap[*Link](hType, r.Links.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build will extract headers, extensions, content and links from node.
|
||||||
func (r *Response) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (r *Response) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
r.Extensions = low.ExtractExtensions(root)
|
r.Extensions = low.ExtractExtensions(root)
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,16 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
// SecurityScheme represents a low-level OpenAPI 3+ SecurityScheme object.
|
||||||
SecurityLabel = "security"
|
//
|
||||||
SecuritySchemesLabel = "securitySchemes"
|
// Defines a security scheme that can be used by the operations.
|
||||||
OAuthFlowsLabel = "flows"
|
//
|
||||||
)
|
// Supported schemes are HTTP authentication, an API key (either as a header, a cookie parameter or as a query parameter),
|
||||||
|
// mutual TLS (use of a client certificate), OAuth2’s common flows (implicit, password, client credentials and
|
||||||
|
// authorization code) as defined in RFC6749 (https://www.rfc-editor.org/rfc/rfc6749), and OpenID Connect Discovery.
|
||||||
|
// Please note that as of 2020, the implicit flow is about to be deprecated by OAuth 2.0 Security Best Current Practice.
|
||||||
|
// Recommended for most use case is Authorization Code Grant flow with PKCE.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#security-scheme-object
|
||||||
type SecurityScheme struct {
|
type SecurityScheme struct {
|
||||||
Type low.NodeReference[string]
|
Type low.NodeReference[string]
|
||||||
Description low.NodeReference[string]
|
Description low.NodeReference[string]
|
||||||
@@ -28,14 +32,28 @@ type SecurityScheme struct {
|
|||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SecurityRequirement is a low-level representation of an OpenAPI 3+ SecurityRequirement object.
|
||||||
|
//
|
||||||
|
// It lists the required security schemes to execute this operation. The name used for each property MUST correspond
|
||||||
|
// to a security scheme declared in the Security Schemes under the Components Object.
|
||||||
|
//
|
||||||
|
// Security Requirement Objects that contain multiple schemes require that all schemes MUST be satisfied for a
|
||||||
|
// request to be authorized. This enables support for scenarios where multiple query parameters or HTTP headers are
|
||||||
|
// required to convey security information.
|
||||||
|
//
|
||||||
|
// When a list of Security Requirement Objects is defined on the OpenAPI Object or Operation Object, only one of the
|
||||||
|
// Security Requirement Objects in the list needs to be satisfied to authorize the request.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#security-requirement-object
|
||||||
type SecurityRequirement struct {
|
type SecurityRequirement struct {
|
||||||
ValueRequirements []low.ValueReference[map[low.KeyReference[string]][]low.ValueReference[string]]
|
ValueRequirements []low.ValueReference[map[low.KeyReference[string]][]low.ValueReference[string]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindExtension attempts to locate an extension using the supplied key.
|
||||||
func (ss *SecurityScheme) FindExtension(ext string) *low.ValueReference[any] {
|
func (ss *SecurityScheme) FindExtension(ext string) *low.ValueReference[any] {
|
||||||
return low.FindItemInMap[any](ext, ss.Extensions)
|
return low.FindItemInMap[any](ext, ss.Extensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build will extract OAuthFlows and extensions from the node.
|
||||||
func (ss *SecurityScheme) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (ss *SecurityScheme) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
ss.Extensions = low.ExtractExtensions(root)
|
ss.Extensions = low.ExtractExtensions(root)
|
||||||
|
|
||||||
@@ -50,6 +68,7 @@ func (ss *SecurityScheme) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindRequirement will attempt to locate a security requirement string from a supplied name.
|
||||||
func (sr *SecurityRequirement) FindRequirement(name string) []low.ValueReference[string] {
|
func (sr *SecurityRequirement) FindRequirement(name string) []low.ValueReference[string] {
|
||||||
for _, r := range sr.ValueRequirements {
|
for _, r := range sr.ValueRequirements {
|
||||||
for k, v := range r.Value {
|
for k, v := range r.Value {
|
||||||
@@ -61,6 +80,7 @@ func (sr *SecurityRequirement) FindRequirement(name string) []low.ValueReference
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build will extract all security requirements
|
||||||
func (sr *SecurityRequirement) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (sr *SecurityRequirement) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
if utils.IsNodeArray(root) {
|
if utils.IsNodeArray(root) {
|
||||||
var requirements []low.ValueReference[map[low.KeyReference[string]][]low.ValueReference[string]]
|
var requirements []low.ValueReference[map[low.KeyReference[string]][]low.ValueReference[string]]
|
||||||
|
|||||||
@@ -10,22 +10,20 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
// Server represents a low-level OpenAPI 3+ Server object.
|
||||||
VariablesLabel = "variables"
|
// - https://spec.openapis.org/oas/v3.1.0#server-object
|
||||||
ServersLabel = "servers"
|
|
||||||
ServerLabel = "server"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
URL low.NodeReference[string]
|
URL low.NodeReference[string]
|
||||||
Description low.NodeReference[string]
|
Description low.NodeReference[string]
|
||||||
Variables low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*ServerVariable]]
|
Variables low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*ServerVariable]]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) FindVariable(ext string) *low.ValueReference[*ServerVariable] {
|
// FindVariable attempts to locate a ServerVariable instance using the supplied key.
|
||||||
return low.FindItemInMap[*ServerVariable](ext, s.Variables.Value)
|
func (s *Server) FindVariable(serverVar string) *low.ValueReference[*ServerVariable] {
|
||||||
|
return low.FindItemInMap[*ServerVariable](serverVar, s.Variables.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build will extract server variables from the supplied node.
|
||||||
func (s *Server) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (s *Server) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
kn, vars := utils.FindKeyNode(VariablesLabel, root.Content)
|
kn, vars := utils.FindKeyNode(VariablesLabel, root.Content)
|
||||||
if vars == nil {
|
if vars == nil {
|
||||||
|
|||||||
@@ -4,6 +4,13 @@ import (
|
|||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ServerVariable represents a low-level OpenAPI 3+ ServerVariable object.
|
||||||
|
//
|
||||||
|
// ServerVariable is an object representing a Server Variable for server URL template substitution.
|
||||||
|
// - https://spec.openapis.org/oas/v3.1.0#server-variable-object
|
||||||
|
//
|
||||||
|
// This is the only struct that is not Buildable, it's not used by anything other than a Server instance,
|
||||||
|
// and it has nothing to build that requires it to be buildable.
|
||||||
type ServerVariable struct {
|
type ServerVariable struct {
|
||||||
Enum []low.NodeReference[string]
|
Enum []low.NodeReference[string]
|
||||||
Default low.NodeReference[string]
|
Default low.NodeReference[string]
|
||||||
|
|||||||
Reference in New Issue
Block a user