mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-10 04:20:24 +00:00
v2 low-level docs are now in also.
That is now 6/6! Time to tune up the README again next.
This commit is contained in:
@@ -10,8 +10,8 @@ import (
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// Creating a new high-level OpenAPI 3+ document from an OpenAPI specification.
|
||||
func Example() {
|
||||
// An example of how to create a new high-level OpenAPI 3+ document from an OpenAPI specification.
|
||||
func Example_createHighLevelOpenAPIDocument() {
|
||||
// Load in an OpenAPI 3+ specification as a byte slice.
|
||||
data, _ := ioutil.ReadFile("../../../test_specs/petstorev3.json")
|
||||
|
||||
|
||||
25
datamodel/low/v2/constants.go
Normal file
25
datamodel/low/v2/constants.go
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v2
|
||||
|
||||
const (
|
||||
DefinitionsLabel = "definitions"
|
||||
SecurityDefinitionsLabel = "securityDefinitions"
|
||||
ExamplesLabel = "examples"
|
||||
HeadersLabel = "headers"
|
||||
DefaultLabel = "default"
|
||||
ItemsLabel = "items"
|
||||
ParametersLabel = "parameters"
|
||||
PathsLabel = "paths"
|
||||
GetLabel = "get"
|
||||
PostLabel = "post"
|
||||
PatchLabel = "patch"
|
||||
PutLabel = "put"
|
||||
DeleteLabel = "delete"
|
||||
OptionsLabel = "options"
|
||||
HeadLabel = "head"
|
||||
SecurityLabel = "security"
|
||||
ScopesLabel = "scopes"
|
||||
ResponsesLabel = "responses"
|
||||
)
|
||||
@@ -10,43 +10,63 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const (
|
||||
DefinitionsLabel = "definitions"
|
||||
SecurityDefinitionsLabel = "securityDefinitions"
|
||||
)
|
||||
|
||||
// ParameterDefinitions is a low-level representation of a Swagger / OpenAPI 2 Parameters Definitions object.
|
||||
//
|
||||
// ParameterDefinitions holds parameters to be reused across operations. Parameter definitions can be
|
||||
// referenced to the ones defined here. It does not define global operation parameters
|
||||
// - https://swagger.io/specification/v2/#parametersDefinitionsObject
|
||||
type ParameterDefinitions struct {
|
||||
Definitions map[low.KeyReference[string]]low.ValueReference[*Parameter]
|
||||
}
|
||||
|
||||
// ResponsesDefinitions is a low-level representation of a Swagger / OpenAPI 2 Responses Definitions object.
|
||||
//
|
||||
// ResponsesDefinitions is an object to hold responses to be reused across operations. Response definitions can be
|
||||
// referenced to the ones defined here. It does not define global operation responses
|
||||
// - https://swagger.io/specification/v2/#responsesDefinitionsObject
|
||||
type ResponsesDefinitions struct {
|
||||
Definitions map[low.KeyReference[string]]low.ValueReference[*Response]
|
||||
}
|
||||
|
||||
// SecurityDefinitions is a low-level representation of a Swagger / OpenAPI 2 Security Definitions object.
|
||||
//
|
||||
// A declaration of the security schemes available to be used in the specification. This does not enforce the security
|
||||
// schemes on the operations and only serves to provide the relevant details for each scheme
|
||||
// - https://swagger.io/specification/v2/#securityDefinitionsObject
|
||||
type SecurityDefinitions struct {
|
||||
Definitions map[low.KeyReference[string]]low.ValueReference[*SecurityScheme]
|
||||
}
|
||||
|
||||
// Definitions is a low-level representation of a Swagger / OpenAPI 2 Definitions object
|
||||
//
|
||||
// An object to hold data types that can be consumed and produced by operations. These data types can be primitives,
|
||||
// arrays or models.
|
||||
// - https://swagger.io/specification/v2/#definitionsObject
|
||||
type Definitions struct {
|
||||
Schemas map[low.KeyReference[string]]low.ValueReference[*base.SchemaProxy]
|
||||
}
|
||||
|
||||
// FindSchema will attempt to locate a base.SchemaProxy instance using a name.
|
||||
func (d *Definitions) FindSchema(schema string) *low.ValueReference[*base.SchemaProxy] {
|
||||
return low.FindItemInMap[*base.SchemaProxy](schema, d.Schemas)
|
||||
}
|
||||
|
||||
func (pd *ParameterDefinitions) FindParameter(schema string) *low.ValueReference[*Parameter] {
|
||||
return low.FindItemInMap[*Parameter](schema, pd.Definitions)
|
||||
// FindParameter will attempt to locate a Parameter instance using a name.
|
||||
func (pd *ParameterDefinitions) FindParameter(parameter string) *low.ValueReference[*Parameter] {
|
||||
return low.FindItemInMap[*Parameter](parameter, pd.Definitions)
|
||||
}
|
||||
|
||||
func (r *ResponsesDefinitions) FindResponse(schema string) *low.ValueReference[*Response] {
|
||||
return low.FindItemInMap[*Response](schema, r.Definitions)
|
||||
// FindResponse will attempt to locate a Response instance using a name.
|
||||
func (r *ResponsesDefinitions) FindResponse(response string) *low.ValueReference[*Response] {
|
||||
return low.FindItemInMap[*Response](response, r.Definitions)
|
||||
}
|
||||
|
||||
func (s *SecurityDefinitions) FindSecurityDefinition(schema string) *low.ValueReference[*SecurityScheme] {
|
||||
return low.FindItemInMap[*SecurityScheme](schema, s.Definitions)
|
||||
// FindSecurityDefinition will attempt to locate a SecurityScheme using a name.
|
||||
func (s *SecurityDefinitions) FindSecurityDefinition(securityDef string) *low.ValueReference[*SecurityScheme] {
|
||||
return low.FindItemInMap[*SecurityScheme](securityDef, s.Definitions)
|
||||
}
|
||||
|
||||
// Build will extract all definitions into SchemaProxy instances.
|
||||
func (d *Definitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
errorChan := make(chan error)
|
||||
resultChan := make(chan definitionResult[*base.SchemaProxy])
|
||||
@@ -58,12 +78,16 @@ func (d *Definitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
continue
|
||||
}
|
||||
totalDefinitions++
|
||||
var buildFunc = func(label *yaml.Node, value *yaml.Node, idx *index.SpecIndex, r chan definitionResult[*base.SchemaProxy], e chan error) {
|
||||
var buildFunc = func(label *yaml.Node, value *yaml.Node, idx *index.SpecIndex,
|
||||
r chan definitionResult[*base.SchemaProxy], e chan error) {
|
||||
|
||||
obj, err := low.ExtractObjectRaw[*base.SchemaProxy](value, idx)
|
||||
if err != nil {
|
||||
e <- err
|
||||
}
|
||||
r <- definitionResult[*base.SchemaProxy]{k: label, v: low.ValueReference[*base.SchemaProxy]{Value: obj, ValueNode: value}}
|
||||
r <- definitionResult[*base.SchemaProxy]{k: label, v: low.ValueReference[*base.SchemaProxy]{
|
||||
Value: obj, ValueNode: value,
|
||||
}}
|
||||
}
|
||||
go buildFunc(defLabel, root.Content[i], idx, resultChan, errorChan)
|
||||
}
|
||||
@@ -86,6 +110,7 @@ func (d *Definitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build will extract all ParameterDefinitions into Parameter instances.
|
||||
func (pd *ParameterDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
errorChan := make(chan error)
|
||||
resultChan := make(chan definitionResult[*Parameter])
|
||||
@@ -97,7 +122,9 @@ func (pd *ParameterDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) err
|
||||
continue
|
||||
}
|
||||
totalDefinitions++
|
||||
var buildFunc = func(label *yaml.Node, value *yaml.Node, idx *index.SpecIndex, r chan definitionResult[*Parameter], e chan error) {
|
||||
var buildFunc = func(label *yaml.Node, value *yaml.Node, idx *index.SpecIndex,
|
||||
r chan definitionResult[*Parameter], e chan error) {
|
||||
|
||||
obj, err := low.ExtractObjectRaw[*Parameter](value, idx)
|
||||
if err != nil {
|
||||
e <- err
|
||||
@@ -125,11 +152,13 @@ func (pd *ParameterDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) err
|
||||
return nil
|
||||
}
|
||||
|
||||
// re-usable struct for holding results as k/v pairs.
|
||||
type definitionResult[T any] struct {
|
||||
k *yaml.Node
|
||||
v low.ValueReference[T]
|
||||
}
|
||||
|
||||
// Build will extract all ResponsesDefinitions into Response instances.
|
||||
func (r *ResponsesDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
errorChan := make(chan error)
|
||||
resultChan := make(chan definitionResult[*Response])
|
||||
@@ -141,7 +170,9 @@ func (r *ResponsesDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) erro
|
||||
continue
|
||||
}
|
||||
totalDefinitions++
|
||||
var buildFunc = func(label *yaml.Node, value *yaml.Node, idx *index.SpecIndex, r chan definitionResult[*Response], e chan error) {
|
||||
var buildFunc = func(label *yaml.Node, value *yaml.Node, idx *index.SpecIndex,
|
||||
r chan definitionResult[*Response], e chan error) {
|
||||
|
||||
obj, err := low.ExtractObjectRaw[*Response](value, idx)
|
||||
if err != nil {
|
||||
e <- err
|
||||
@@ -169,6 +200,7 @@ func (r *ResponsesDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build will extract all SecurityDefinitions into SecurityScheme instances.
|
||||
func (s *SecurityDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
errorChan := make(chan error)
|
||||
resultChan := make(chan definitionResult[*SecurityScheme])
|
||||
@@ -180,12 +212,16 @@ func (s *SecurityDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) error
|
||||
continue
|
||||
}
|
||||
totalDefinitions++
|
||||
var buildFunc = func(label *yaml.Node, value *yaml.Node, idx *index.SpecIndex, r chan definitionResult[*SecurityScheme], e chan error) {
|
||||
var buildFunc = func(label *yaml.Node, value *yaml.Node, idx *index.SpecIndex,
|
||||
r chan definitionResult[*SecurityScheme], e chan error) {
|
||||
|
||||
obj, err := low.ExtractObjectRaw[*SecurityScheme](value, idx)
|
||||
if err != nil {
|
||||
e <- err
|
||||
}
|
||||
r <- definitionResult[*SecurityScheme]{k: label, v: low.ValueReference[*SecurityScheme]{Value: obj, ValueNode: value}}
|
||||
r <- definitionResult[*SecurityScheme]{k: label, v: low.ValueReference[*SecurityScheme]{
|
||||
Value: obj, ValueNode: value,
|
||||
}}
|
||||
}
|
||||
go buildFunc(defLabel, root.Content[i], idx, resultChan, errorChan)
|
||||
}
|
||||
|
||||
@@ -9,18 +9,19 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const (
|
||||
ExamplesLabel = "examples"
|
||||
)
|
||||
|
||||
// Examples represents a low-level Swagger / OpenAPI 2 Example object.
|
||||
// Allows sharing examples for operation responses
|
||||
// - https://swagger.io/specification/v2/#exampleObject
|
||||
type Examples struct {
|
||||
Values map[low.KeyReference[string]]low.ValueReference[any]
|
||||
}
|
||||
|
||||
// FindExample attempts to locate an example value, using a key label.
|
||||
func (e *Examples) FindExample(name string) *low.ValueReference[any] {
|
||||
return low.FindItemInMap[any](name, e.Values)
|
||||
}
|
||||
|
||||
// Build will extract all examples and will attempt to unmarshal content into a map or slice based on type.
|
||||
func (e *Examples) Build(root *yaml.Node, _ *index.SpecIndex) error {
|
||||
var keyNode, currNode *yaml.Node
|
||||
var err error
|
||||
|
||||
@@ -10,10 +10,10 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const (
|
||||
HeadersLabel = "headers"
|
||||
)
|
||||
|
||||
// Header Represents a low-level Swagger / OpenAPI 2 Header object.
|
||||
//
|
||||
// A Header is essentially identical to a Parameter, except it does not contain 'name' or 'in' properties.
|
||||
// - https://swagger.io/specification/v2/#headerObject
|
||||
type Header struct {
|
||||
Type low.NodeReference[string]
|
||||
Format low.NodeReference[string]
|
||||
@@ -36,10 +36,12 @@ type Header struct {
|
||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||
}
|
||||
|
||||
// FindExtension will attempt to locate an extension value using a name lookup.
|
||||
func (h *Header) FindExtension(ext string) *low.ValueReference[any] {
|
||||
return low.FindItemInMap[any](ext, h.Extensions)
|
||||
}
|
||||
|
||||
// Build will build out items, extensions and default value from the supplied node.
|
||||
func (h *Header) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
h.Extensions = low.ExtractExtensions(root)
|
||||
items, err := low.ExtractObject[*Items](ItemsLabel, root, idx)
|
||||
|
||||
@@ -10,11 +10,11 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultLabel = "default"
|
||||
ItemsLabel = "items"
|
||||
)
|
||||
|
||||
// Items is a low-level representation of a Swagger / OpenAPI 2 Items object.
|
||||
//
|
||||
// Items is a limited subset of JSON-Schema's items object. It is used by parameter definitions that are not
|
||||
// located in "body"
|
||||
// - https://swagger.io/specification/v2/#itemsObject
|
||||
type Items struct {
|
||||
Type low.NodeReference[string]
|
||||
Format low.NodeReference[string]
|
||||
@@ -35,6 +35,7 @@ type Items struct {
|
||||
MultipleOf low.NodeReference[int]
|
||||
}
|
||||
|
||||
// Build will build out items and default value.
|
||||
func (i *Items) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
items, iErr := low.ExtractObject[*Items](ItemsLabel, root, idx)
|
||||
if iErr != nil {
|
||||
|
||||
@@ -10,6 +10,10 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Operation represents a low-level Swagger / OpenAPI 2 Operation object.
|
||||
//
|
||||
// It describes a single API operation on a path.
|
||||
// - https://swagger.io/specification/v2/#operationObject
|
||||
type Operation struct {
|
||||
Tags low.NodeReference[[]low.ValueReference[string]]
|
||||
Summary low.NodeReference[string]
|
||||
@@ -26,6 +30,7 @@ type Operation struct {
|
||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||
}
|
||||
|
||||
// Build will extract external docs, extensions, parameters, responses and security requirements.
|
||||
func (o *Operation) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
o.Extensions = low.ExtractExtensions(root)
|
||||
|
||||
|
||||
66
datamodel/low/v2/package_test.go
Normal file
66
datamodel/low/v2/package_test.go
Normal file
@@ -0,0 +1,66 @@
|
||||
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/pb33f/libopenapi/datamodel"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// How to create a low-level Swagger / OpenAPI 2 Document from a specification
|
||||
func Example_createLowLevelSwaggerDocument() {
|
||||
|
||||
// How to create a low-level OpenAPI 2 Document
|
||||
|
||||
// load petstore into bytes
|
||||
petstoreBytes, _ := ioutil.ReadFile("../../../test_specs/petstorev2.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
|
||||
|
||||
}
|
||||
|
||||
// How to create a low-level Swagger / OpenAPI 2 Document from a specification
|
||||
func ExampleCreateDocument() {
|
||||
|
||||
// How to create a low-level OpenAPI 2 Document
|
||||
|
||||
// load petstore into bytes
|
||||
petstoreBytes, _ := ioutil.ReadFile("../../../test_specs/petstorev2.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,37 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const (
|
||||
ParametersLabel = "parameters"
|
||||
)
|
||||
|
||||
// Parameter represents a low-level Swagger / OpenAPI 2 Parameter object.
|
||||
//
|
||||
// A unique parameter is defined by a combination of a name and location.
|
||||
//
|
||||
// There are five possible parameter types.
|
||||
//
|
||||
// Path
|
||||
// Used together with Path Templating, where the parameter value is actually part of the operation's URL.
|
||||
// This does not include the host or base path of the API. For example, in /items/{itemId}, the path parameter is itemId.
|
||||
// Query
|
||||
// Parameters that are appended to the URL. For example, in /items?id=###, the query parameter is id.
|
||||
// Header
|
||||
// Custom headers that are expected as part of the request.
|
||||
// Body
|
||||
// The payload that's appended to the HTTP request. Since there can only be one payload, there can only be one body parameter.
|
||||
// The name of the body parameter has no effect on the parameter itself and is used for documentation purposes only.
|
||||
// Since Form parameters are also in the payload, body and form parameters cannot exist together for the same operation.
|
||||
// Form
|
||||
// Used to describe the payload of an HTTP request when either application/x-www-form-urlencoded, multipart/form-data
|
||||
// or both are used as the content type of the request (in Swagger's definition, the consumes property of an operation).
|
||||
// This is the only parameter type that can be used to send files, thus supporting the file type. Since form parameters
|
||||
// are sent in the payload, they cannot be declared together with a body parameter for the same operation. Form
|
||||
// parameters have a different format based on the content-type used (for further details,
|
||||
// consult http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4):
|
||||
// application/x-www-form-urlencoded - Similar to the format of Query parameters but as a payload. For example,
|
||||
// foo=1&bar=swagger - both foo and bar are form parameters. This is normally used for simple parameters that are
|
||||
// being transferred.
|
||||
// multipart/form-data - each parameter takes a section in the payload with an internal header. For example, for
|
||||
// the header Content-Disposition: form-data; name="submit-name" the name of the parameter is
|
||||
// submit-name. This type of form parameters is more commonly used for file transfers
|
||||
// https://swagger.io/specification/v2/#parameterObject
|
||||
type Parameter struct {
|
||||
Name low.NodeReference[string]
|
||||
In low.NodeReference[string]
|
||||
@@ -42,10 +69,12 @@ type Parameter struct {
|
||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||
}
|
||||
|
||||
// FindExtension attempts to locate a extension value given a name.
|
||||
func (p *Parameter) FindExtension(ext string) *low.ValueReference[any] {
|
||||
return low.FindItemInMap[any](ext, p.Extensions)
|
||||
}
|
||||
|
||||
// Build will extract out extensions, schema, items and default value
|
||||
func (p *Parameter) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
p.Extensions = low.ExtractExtensions(root)
|
||||
sch, sErr := base.ExtractSchema(root, idx)
|
||||
|
||||
@@ -4,168 +4,177 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"github.com/pb33f/libopenapi/datamodel/low"
|
||||
"github.com/pb33f/libopenapi/index"
|
||||
"gopkg.in/yaml.v3"
|
||||
"strings"
|
||||
"sync"
|
||||
"github.com/pb33f/libopenapi/datamodel/low"
|
||||
"github.com/pb33f/libopenapi/index"
|
||||
"gopkg.in/yaml.v3"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// PathItem represents a low-level Swagger / OpenAPI 2 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 tooling, but will not know which operations and parameters
|
||||
// are available.
|
||||
// - https://swagger.io/specification/v2/#pathItemObject
|
||||
type PathItem struct {
|
||||
Ref low.NodeReference[string]
|
||||
Get low.NodeReference[*Operation]
|
||||
Put low.NodeReference[*Operation]
|
||||
Post low.NodeReference[*Operation]
|
||||
Delete low.NodeReference[*Operation]
|
||||
Options low.NodeReference[*Operation]
|
||||
Head low.NodeReference[*Operation]
|
||||
Patch low.NodeReference[*Operation]
|
||||
Parameters low.NodeReference[[]low.ValueReference[*Parameter]]
|
||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||
Ref low.NodeReference[string]
|
||||
Get low.NodeReference[*Operation]
|
||||
Put low.NodeReference[*Operation]
|
||||
Post low.NodeReference[*Operation]
|
||||
Delete low.NodeReference[*Operation]
|
||||
Options low.NodeReference[*Operation]
|
||||
Head low.NodeReference[*Operation]
|
||||
Patch low.NodeReference[*Operation]
|
||||
Parameters low.NodeReference[[]low.ValueReference[*Parameter]]
|
||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||
}
|
||||
|
||||
// FindExtension will attempt to locate an extension given a name.
|
||||
func (p *PathItem) FindExtension(ext string) *low.ValueReference[any] {
|
||||
return low.FindItemInMap[any](ext, p.Extensions)
|
||||
return low.FindItemInMap[any](ext, p.Extensions)
|
||||
}
|
||||
|
||||
// Build will extract extensions, parameters and operations for all methods. Every method is handled
|
||||
// asynchronously, in order to keep things moving quickly for complex operations.
|
||||
func (p *PathItem) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
p.Extensions = low.ExtractExtensions(root)
|
||||
skip := false
|
||||
var currentNode *yaml.Node
|
||||
p.Extensions = low.ExtractExtensions(root)
|
||||
skip := false
|
||||
var currentNode *yaml.Node
|
||||
|
||||
var wg sync.WaitGroup
|
||||
var errors []error
|
||||
var wg sync.WaitGroup
|
||||
var errors []error
|
||||
|
||||
var ops []low.NodeReference[*Operation]
|
||||
var ops []low.NodeReference[*Operation]
|
||||
|
||||
// extract parameters
|
||||
params, ln, vn, pErr := low.ExtractArray[*Parameter](ParametersLabel, root, idx)
|
||||
if pErr != nil {
|
||||
return pErr
|
||||
}
|
||||
if params != nil {
|
||||
p.Parameters = low.NodeReference[[]low.ValueReference[*Parameter]]{
|
||||
Value: params,
|
||||
KeyNode: ln,
|
||||
ValueNode: vn,
|
||||
}
|
||||
}
|
||||
// extract parameters
|
||||
params, ln, vn, pErr := low.ExtractArray[*Parameter](ParametersLabel, root, idx)
|
||||
if pErr != nil {
|
||||
return pErr
|
||||
}
|
||||
if params != nil {
|
||||
p.Parameters = low.NodeReference[[]low.ValueReference[*Parameter]]{
|
||||
Value: params,
|
||||
KeyNode: ln,
|
||||
ValueNode: vn,
|
||||
}
|
||||
}
|
||||
|
||||
for i, pathNode := range root.Content {
|
||||
if strings.HasPrefix(strings.ToLower(pathNode.Value), "x-") {
|
||||
skip = true
|
||||
continue
|
||||
}
|
||||
// because (for some reason) the spec for swagger docs allows for a '$ref' property for path items.
|
||||
// this is kinda nuts, because '$ref' is a reserved keyword for JSON references, which is ALSO used
|
||||
// in swagger. Why this choice was made, I do not know.
|
||||
if strings.Contains(strings.ToLower(pathNode.Value), "$ref") {
|
||||
rn := root.Content[i+1]
|
||||
p.Ref = low.NodeReference[string]{
|
||||
Value: rn.Value,
|
||||
ValueNode: rn,
|
||||
KeyNode: pathNode,
|
||||
}
|
||||
skip = true
|
||||
continue
|
||||
}
|
||||
if skip {
|
||||
skip = false
|
||||
continue
|
||||
}
|
||||
if i%2 == 0 {
|
||||
currentNode = pathNode
|
||||
continue
|
||||
}
|
||||
for i, pathNode := range root.Content {
|
||||
if strings.HasPrefix(strings.ToLower(pathNode.Value), "x-") {
|
||||
skip = true
|
||||
continue
|
||||
}
|
||||
// because (for some reason) the spec for swagger docs allows for a '$ref' property for path items.
|
||||
// this is kinda nuts, because '$ref' is a reserved keyword for JSON references, which is ALSO used
|
||||
// in swagger. Why this choice was made, I do not know.
|
||||
if strings.Contains(strings.ToLower(pathNode.Value), "$ref") {
|
||||
rn := root.Content[i+1]
|
||||
p.Ref = low.NodeReference[string]{
|
||||
Value: rn.Value,
|
||||
ValueNode: rn,
|
||||
KeyNode: pathNode,
|
||||
}
|
||||
skip = true
|
||||
continue
|
||||
}
|
||||
if skip {
|
||||
skip = false
|
||||
continue
|
||||
}
|
||||
if i%2 == 0 {
|
||||
currentNode = pathNode
|
||||
continue
|
||||
}
|
||||
|
||||
// the only thing we now care about is handling operations, filter out anything that's not a verb.
|
||||
switch currentNode.Value {
|
||||
case GetLabel:
|
||||
break
|
||||
case PostLabel:
|
||||
break
|
||||
case PutLabel:
|
||||
break
|
||||
case PatchLabel:
|
||||
break
|
||||
case DeleteLabel:
|
||||
break
|
||||
case HeadLabel:
|
||||
break
|
||||
case OptionsLabel:
|
||||
break
|
||||
default:
|
||||
continue // ignore everything else.
|
||||
}
|
||||
// the only thing we now care about is handling operations, filter out anything that's not a verb.
|
||||
switch currentNode.Value {
|
||||
case GetLabel:
|
||||
break
|
||||
case PostLabel:
|
||||
break
|
||||
case PutLabel:
|
||||
break
|
||||
case PatchLabel:
|
||||
break
|
||||
case DeleteLabel:
|
||||
break
|
||||
case HeadLabel:
|
||||
break
|
||||
case OptionsLabel:
|
||||
break
|
||||
default:
|
||||
continue // ignore everything else.
|
||||
}
|
||||
|
||||
var op Operation
|
||||
var op Operation
|
||||
|
||||
wg.Add(1)
|
||||
wg.Add(1)
|
||||
|
||||
go low.BuildModelAsync(pathNode, &op, &wg, &errors)
|
||||
go low.BuildModelAsync(pathNode, &op, &wg, &errors)
|
||||
|
||||
opRef := low.NodeReference[*Operation]{
|
||||
Value: &op,
|
||||
KeyNode: currentNode,
|
||||
ValueNode: pathNode,
|
||||
}
|
||||
opRef := low.NodeReference[*Operation]{
|
||||
Value: &op,
|
||||
KeyNode: currentNode,
|
||||
ValueNode: pathNode,
|
||||
}
|
||||
|
||||
ops = append(ops, opRef)
|
||||
ops = append(ops, opRef)
|
||||
|
||||
switch currentNode.Value {
|
||||
case GetLabel:
|
||||
p.Get = opRef
|
||||
case PostLabel:
|
||||
p.Post = opRef
|
||||
case PutLabel:
|
||||
p.Put = opRef
|
||||
case PatchLabel:
|
||||
p.Patch = opRef
|
||||
case DeleteLabel:
|
||||
p.Delete = opRef
|
||||
case HeadLabel:
|
||||
p.Head = opRef
|
||||
case OptionsLabel:
|
||||
p.Options = opRef
|
||||
}
|
||||
}
|
||||
switch currentNode.Value {
|
||||
case GetLabel:
|
||||
p.Get = opRef
|
||||
case PostLabel:
|
||||
p.Post = opRef
|
||||
case PutLabel:
|
||||
p.Put = opRef
|
||||
case PatchLabel:
|
||||
p.Patch = opRef
|
||||
case DeleteLabel:
|
||||
p.Delete = opRef
|
||||
case HeadLabel:
|
||||
p.Head = opRef
|
||||
case OptionsLabel:
|
||||
p.Options = opRef
|
||||
}
|
||||
}
|
||||
|
||||
//all operations have been superficially built,
|
||||
//now we need to build out the operation, we will do this asynchronously for speed.
|
||||
opBuildChan := make(chan bool)
|
||||
opErrorChan := make(chan error)
|
||||
//all operations have been superficially built,
|
||||
//now we need to build out the operation, we will do this asynchronously for speed.
|
||||
opBuildChan := make(chan bool)
|
||||
opErrorChan := make(chan error)
|
||||
|
||||
var buildOpFunc = func(op low.NodeReference[*Operation], ch chan<- bool, errCh chan<- error) {
|
||||
er := op.Value.Build(op.ValueNode, idx)
|
||||
if er != nil {
|
||||
errCh <- er
|
||||
}
|
||||
ch <- true
|
||||
}
|
||||
var buildOpFunc = func(op low.NodeReference[*Operation], ch chan<- bool, errCh chan<- error) {
|
||||
er := op.Value.Build(op.ValueNode, idx)
|
||||
if er != nil {
|
||||
errCh <- er
|
||||
}
|
||||
ch <- true
|
||||
}
|
||||
|
||||
if len(ops) <= 0 {
|
||||
return nil // nothing to do.
|
||||
}
|
||||
if len(ops) <= 0 {
|
||||
return nil // nothing to do.
|
||||
}
|
||||
|
||||
for _, op := range ops {
|
||||
go buildOpFunc(op, opBuildChan, opErrorChan)
|
||||
}
|
||||
for _, op := range ops {
|
||||
go buildOpFunc(op, opBuildChan, opErrorChan)
|
||||
}
|
||||
|
||||
n := 0
|
||||
total := len(ops)
|
||||
for n < total {
|
||||
select {
|
||||
case buildError := <-opErrorChan:
|
||||
return buildError
|
||||
case <-opBuildChan:
|
||||
n++
|
||||
}
|
||||
}
|
||||
n := 0
|
||||
total := len(ops)
|
||||
for n < total {
|
||||
select {
|
||||
case buildError := <-opErrorChan:
|
||||
return buildError
|
||||
case <-opBuildChan:
|
||||
n++
|
||||
}
|
||||
}
|
||||
|
||||
// make sure we don't exit before the path is finished building.
|
||||
if len(ops) > 0 {
|
||||
wg.Wait()
|
||||
}
|
||||
// make sure we don't exit before the path is finished building.
|
||||
if len(ops) > 0 {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -10,22 +10,13 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
PathsLabel = "paths"
|
||||
GetLabel = "get"
|
||||
PostLabel = "post"
|
||||
PatchLabel = "patch"
|
||||
PutLabel = "put"
|
||||
DeleteLabel = "delete"
|
||||
OptionsLabel = "options"
|
||||
HeadLabel = "head"
|
||||
)
|
||||
|
||||
// Paths represents a low-level Swagger / OpenAPI Paths object.
|
||||
type Paths struct {
|
||||
PathItems map[low.KeyReference[string]]low.ValueReference[*PathItem]
|
||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||
}
|
||||
|
||||
// FindPath attempts to locate a PathItem instance, given a path key.
|
||||
func (p *Paths) FindPath(path string) *low.ValueReference[*PathItem] {
|
||||
for k, j := range p.PathItems {
|
||||
if k.Value == path {
|
||||
@@ -35,10 +26,12 @@ func (p *Paths) FindPath(path string) *low.ValueReference[*PathItem] {
|
||||
return nil
|
||||
}
|
||||
|
||||
// FindExtension will attempt to locate an extension value given a name.
|
||||
func (p *Paths) FindExtension(ext string) *low.ValueReference[any] {
|
||||
return low.FindItemInMap[any](ext, p.Extensions)
|
||||
}
|
||||
|
||||
// Build will extract extensions and paths from node.
|
||||
func (p *Paths) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
p.Extensions = low.ExtractExtensions(root)
|
||||
skip := false
|
||||
|
||||
@@ -10,10 +10,10 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const (
|
||||
ResponsesLabel = "responses"
|
||||
)
|
||||
|
||||
// Response is a representation of a high-level Swagger / OpenAPI 2 Response object, backed by a low-level one.
|
||||
//
|
||||
// Response describes a single response from an API Operation
|
||||
// - https://swagger.io/specification/v2/#responseObject
|
||||
type Response struct {
|
||||
Description low.NodeReference[string]
|
||||
Schema low.NodeReference[*base.SchemaProxy]
|
||||
@@ -22,14 +22,17 @@ type Response struct {
|
||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||
}
|
||||
|
||||
// FindExtension will attempt to locate an extension value given a key to lookup.
|
||||
func (r *Response) FindExtension(ext string) *low.ValueReference[any] {
|
||||
return low.FindItemInMap[any](ext, r.Extensions)
|
||||
}
|
||||
|
||||
// FindHeader will attempt to locate a Header value, given a key
|
||||
func (r *Response) FindHeader(hType string) *low.ValueReference[*Header] {
|
||||
return low.FindItemInMap[*Header](hType, r.Headers.Value)
|
||||
}
|
||||
|
||||
// Build will extract schema, extensions, examples and headers from node
|
||||
func (r *Response) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
r.Extensions = low.ExtractExtensions(root)
|
||||
s, err := base.ExtractSchema(root, idx)
|
||||
|
||||
@@ -11,12 +11,14 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Responses is a low-level representation of a Swagger / OpenAPI 2 Responses object.
|
||||
type Responses struct {
|
||||
Codes map[low.KeyReference[string]]low.ValueReference[*Response]
|
||||
Default low.NodeReference[*Response]
|
||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||
}
|
||||
|
||||
// Build will extract default value and extensions from node.
|
||||
func (r *Responses) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
r.Extensions = low.ExtractExtensions(root)
|
||||
|
||||
@@ -42,6 +44,7 @@ func (r *Responses) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// FindResponseByCode will attempt to locate a Response instance using an HTTP response code string.
|
||||
func (r *Responses) FindResponseByCode(code string) *low.ValueReference[*Response] {
|
||||
return low.FindItemInMap[*Response](code, r.Codes)
|
||||
}
|
||||
|
||||
@@ -10,15 +10,21 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Scopes is a low-level representation of a Swagger / OpenAPI 2 OAuth2 Scopes object.
|
||||
//
|
||||
// Scopes lists the available scopes for an OAuth2 security scheme.
|
||||
// - https://swagger.io/specification/v2/#scopesObject
|
||||
type Scopes struct {
|
||||
Values map[low.KeyReference[string]]low.ValueReference[string]
|
||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||
}
|
||||
|
||||
// FindScope will attempt to locate a scope string using a key.
|
||||
func (s *Scopes) FindScope(scope string) *low.ValueReference[string] {
|
||||
return low.FindItemInMap[string](scope, s.Values)
|
||||
}
|
||||
|
||||
// Build will extract scope values and extensions from node.
|
||||
func (s *Scopes) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
s.Extensions = low.ExtractExtensions(root)
|
||||
valueMap := make(map[low.KeyReference[string]]low.ValueReference[string])
|
||||
|
||||
@@ -9,14 +9,18 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const (
|
||||
SecurityLabel = "security"
|
||||
)
|
||||
|
||||
// SecurityRequirement is a low-level representation of a Swagger / OpenAPI 2 SecurityRequirement object.
|
||||
//
|
||||
// SecurityRequirement lists the required security schemes to execute this operation. The object can have multiple
|
||||
// security schemes declared in it which are all required (that is, there is a logical AND between the schemes).
|
||||
//
|
||||
// The name used for each property MUST correspond to a security scheme declared in the Security Definitions
|
||||
// - https://swagger.io/specification/v2/#securityDefinitionsObject
|
||||
type SecurityRequirement struct {
|
||||
Values low.ValueReference[map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]]]
|
||||
}
|
||||
|
||||
// Build will extract security requirements from the node (the structure is odd, to be honest)
|
||||
func (s *SecurityRequirement) Build(root *yaml.Node, _ *index.SpecIndex) error {
|
||||
var labelNode *yaml.Node
|
||||
var arr []low.ValueReference[string]
|
||||
|
||||
@@ -9,10 +9,12 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const (
|
||||
ScopesLabel = "scopes"
|
||||
)
|
||||
|
||||
// SecurityScheme is a low-level representation of a Swagger / OpenAPI 2 SecurityScheme object.
|
||||
//
|
||||
// SecurityScheme allows the definition of a security scheme that can be used by the operations. Supported schemes are
|
||||
// basic authentication, an API key (either as a header or as a query parameter) and OAuth2's common flows
|
||||
// (implicit, password, application and access code)
|
||||
// - https://swagger.io/specification/v2/#securityDefinitionsObject
|
||||
type SecurityScheme struct {
|
||||
Type low.NodeReference[string]
|
||||
Description low.NodeReference[string]
|
||||
@@ -25,6 +27,7 @@ type SecurityScheme struct {
|
||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||
}
|
||||
|
||||
// Build will extract extensions and scopes from the node.
|
||||
func (ss *SecurityScheme) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
ss.Extensions = low.ExtractExtensions(root)
|
||||
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Package v2 represents all Swagger / OpenAPI 2 low-level models.
|
||||
//
|
||||
// Low-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.
|
||||
//
|
||||
// IMPORTANT: As a general rule, Swagger / OpenAPI 2 should be avoided for new projects.
|
||||
package v2
|
||||
|
||||
import (
|
||||
@@ -12,29 +20,98 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// processes a property of a Swagger document asynchronously using bool and error channels for signals.
|
||||
type documentFunction func(root *yaml.Node, doc *Swagger, idx *index.SpecIndex, c chan<- bool, e chan<- error)
|
||||
|
||||
// Swagger represents a high-level Swagger / OpenAPI 2 document. An instance of Swagger is the root of the specification.
|
||||
type Swagger struct {
|
||||
Swagger low.ValueReference[string]
|
||||
Info low.NodeReference[*base.Info]
|
||||
Host low.NodeReference[string]
|
||||
BasePath low.NodeReference[string]
|
||||
Schemes low.NodeReference[[]low.ValueReference[string]]
|
||||
Consumes low.NodeReference[[]low.ValueReference[string]]
|
||||
Produces low.NodeReference[[]low.ValueReference[string]]
|
||||
Paths low.NodeReference[*Paths]
|
||||
Definitions low.NodeReference[*Definitions]
|
||||
|
||||
// Swagger is the version of Swagger / OpenAPI being used, extracted from the 'swagger: 2.x' definition.
|
||||
Swagger low.ValueReference[string]
|
||||
|
||||
// Info represents a specification Info definition.
|
||||
// Provides metadata about the API. The metadata can be used by the clients if needed.
|
||||
// - https://swagger.io/specification/v2/#infoObject
|
||||
Info low.NodeReference[*base.Info]
|
||||
|
||||
// Host is The host (name or ip) serving the API. This MUST be the host only and does not include the scheme nor
|
||||
// sub-paths. It MAY include a port. If the host is not included, the host serving the documentation is to be used
|
||||
// (including the port). The host does not support path templating.
|
||||
Host low.NodeReference[string]
|
||||
|
||||
// BasePath is The base path on which the API is served, which is relative to the host. If it is not included,
|
||||
// the API is served directly under the host. The value MUST start with a leading slash (/).
|
||||
// The basePath does not support path templating.
|
||||
BasePath low.NodeReference[string]
|
||||
|
||||
// Schemes represents the transfer protocol of the API. Values MUST be from the list: "http", "https", "ws", "wss".
|
||||
// If the schemes is not included, the default scheme to be used is the one used to access
|
||||
// the Swagger definition itself.
|
||||
Schemes low.NodeReference[[]low.ValueReference[string]]
|
||||
|
||||
// Consumes is a list of MIME types the APIs can consume. This is global to all APIs but can be overridden on
|
||||
// specific API calls. Value MUST be as described under Mime Types.
|
||||
Consumes low.NodeReference[[]low.ValueReference[string]]
|
||||
|
||||
// Produces is a list of MIME types the APIs can produce. This is global to all APIs but can be overridden on
|
||||
// specific API calls. Value MUST be as described under Mime Types.
|
||||
Produces low.NodeReference[[]low.ValueReference[string]]
|
||||
|
||||
// Paths are the paths and operations for the API. Perhaps the most important part of the specification.
|
||||
// - https://swagger.io/specification/v2/#pathsObject
|
||||
Paths low.NodeReference[*Paths]
|
||||
|
||||
// Definitions is an object to hold data types produced and consumed by operations. It's composed of Schema instances
|
||||
// - https://swagger.io/specification/v2/#definitionsObject
|
||||
Definitions low.NodeReference[*Definitions]
|
||||
|
||||
// SecurityDefinitions represents security scheme definitions that can be used across the specification.
|
||||
// - https://swagger.io/specification/v2/#securityDefinitionsObject
|
||||
SecurityDefinitions low.NodeReference[*SecurityDefinitions]
|
||||
Parameters low.NodeReference[*ParameterDefinitions]
|
||||
Responses low.NodeReference[*ResponsesDefinitions]
|
||||
Security low.NodeReference[[]low.ValueReference[*SecurityRequirement]]
|
||||
Tags low.NodeReference[[]low.ValueReference[*base.Tag]]
|
||||
ExternalDocs low.NodeReference[*base.ExternalDoc]
|
||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||
Index *index.SpecIndex
|
||||
SpecInfo *datamodel.SpecInfo
|
||||
|
||||
// Parameters is an object to hold parameters that can be used across operations.
|
||||
// This property does not define global parameters for all operations.
|
||||
// - https://swagger.io/specification/v2/#parametersDefinitionsObject
|
||||
Parameters low.NodeReference[*ParameterDefinitions]
|
||||
|
||||
// Responses is an object to hold responses that can be used across operations.
|
||||
// This property does not define global responses for all operations.
|
||||
// - https://swagger.io/specification/v2/#responsesDefinitionsObject
|
||||
Responses low.NodeReference[*ResponsesDefinitions]
|
||||
|
||||
// Security is a declaration of which security schemes are applied for the API as a whole. The list of values
|
||||
// describes alternative security schemes that can be used (that is, there is a logical OR between the security
|
||||
// requirements). Individual operations can override this definition.
|
||||
// - https://swagger.io/specification/v2/#securityRequirementObject
|
||||
Security low.NodeReference[[]low.ValueReference[*SecurityRequirement]]
|
||||
|
||||
// Tags are A list of tags used by the specification 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://swagger.io/specification/v2/#tagObject
|
||||
Tags low.NodeReference[[]low.ValueReference[*base.Tag]]
|
||||
|
||||
// ExternalDocs is an instance of base.ExternalDoc for.. well, obvious really, innit mate?
|
||||
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
|
||||
|
||||
// SpecInfo is a reference to the datamodel.SpecInfo instance created when the specification was read.
|
||||
//
|
||||
// This property is not a part of the OpenAPI schema, this is custom to libopenapi.
|
||||
SpecInfo *datamodel.SpecInfo
|
||||
}
|
||||
|
||||
// FindExte
|
||||
func (s *Swagger) FindExtension(ext string) *low.ValueReference[any] {
|
||||
return low.FindItemInMap[any](ext, s.Extensions)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Package v3 represents all OpenAPI 3+ low-level models. High-level models are more difficult to navigate
|
||||
// Package v3 represents all OpenAPI 3+ low-level models. Low-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.
|
||||
//
|
||||
|
||||
@@ -9,7 +9,8 @@ import (
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
func Example_createLowDocument() {
|
||||
// How to create a low-level OpenAPI 3+ Document from an OpenAPI specification
|
||||
func Example_createLowLevelOpenAPIDocument() {
|
||||
// How to create a low-level OpenAPI 3 Document
|
||||
|
||||
// load petstore into bytes
|
||||
|
||||
Reference in New Issue
Block a user