mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-10 12:37:48 +00:00
V2 swagger model in place
tests being written to validate and flush out bugs
This commit is contained in:
10
datamodel/high/3.0/label_constants.go
Normal file
10
datamodel/high/3.0/label_constants.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package v3
|
||||||
|
|
||||||
|
const (
|
||||||
|
NameLabel = "name"
|
||||||
|
DescriptionLabel = "description"
|
||||||
|
ExternalDocsLabel = "externalDocs"
|
||||||
|
)
|
||||||
@@ -35,3 +35,20 @@ func NewTag(tag *low.Tag) *Tag {
|
|||||||
func (t *Tag) GoLow() *low.Tag {
|
func (t *Tag) GoLow() *low.Tag {
|
||||||
return t.low
|
return t.low
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//func (t *Tag) MarshalYAML() (interface{}, error) {
|
||||||
|
// m := make(map[string]interface{})
|
||||||
|
// for i := range t.Extensions {
|
||||||
|
// m[i] = t.Extensions[i]
|
||||||
|
// }
|
||||||
|
// if t.Name != "" {
|
||||||
|
// m[NameLabel] = t.Name
|
||||||
|
// }
|
||||||
|
// if t.Description != "" {
|
||||||
|
// m[DescriptionLabel] = t.Description
|
||||||
|
// }
|
||||||
|
// if t.ExternalDocs != nil {
|
||||||
|
// m[ExternalDocsLabel] = t.ExternalDocs
|
||||||
|
// }
|
||||||
|
// return m, nil
|
||||||
|
//}
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DefinitionsLabel = "definitions"
|
DefinitionsLabel = "definitions"
|
||||||
|
SecurityDefinitionsLabel = "securityDefinitions"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ParameterDefinitions struct {
|
type ParameterDefinitions struct {
|
||||||
@@ -42,13 +43,13 @@ func (r *ResponsesDefinitions) FindResponse(schema string) *low.ValueReference[*
|
|||||||
return low.FindItemInMap[*Response](schema, r.Definitions)
|
return low.FindItemInMap[*Response](schema, r.Definitions)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SecurityDefinitions) FindSecurityScheme(schema string) *low.ValueReference[*SecurityScheme] {
|
func (s *SecurityDefinitions) FindSecurityDefinition(schema string) *low.ValueReference[*SecurityScheme] {
|
||||||
return low.FindItemInMap[*SecurityScheme](schema, s.Definitions)
|
return low.FindItemInMap[*SecurityScheme](schema, s.Definitions)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Definitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (d *Definitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
errorChan := make(chan error)
|
errorChan := make(chan error)
|
||||||
resultChan := make(chan definitionResult)
|
resultChan := make(chan definitionResult[*base.SchemaProxy])
|
||||||
var defLabel *yaml.Node
|
var defLabel *yaml.Node
|
||||||
totalDefinitions := 0
|
totalDefinitions := 0
|
||||||
for i := range root.Content {
|
for i := range root.Content {
|
||||||
@@ -57,12 +58,12 @@ func (d *Definitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
totalDefinitions++
|
totalDefinitions++
|
||||||
var buildFunc = func(label *yaml.Node, value *yaml.Node, idx *index.SpecIndex, r chan definitionResult, 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)
|
obj, err := low.ExtractObjectRaw[*base.SchemaProxy](value, idx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e <- err
|
e <- err
|
||||||
}
|
}
|
||||||
r <- definitionResult{k: label, v: low.ValueReference[any]{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)
|
go buildFunc(defLabel, root.Content[i], idx, resultChan, errorChan)
|
||||||
}
|
}
|
||||||
@@ -74,10 +75,11 @@ func (d *Definitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
case err := <-errorChan:
|
case err := <-errorChan:
|
||||||
return err
|
return err
|
||||||
case sch := <-resultChan:
|
case sch := <-resultChan:
|
||||||
|
completedDefs++
|
||||||
results[low.KeyReference[string]{
|
results[low.KeyReference[string]{
|
||||||
Value: sch.k.Value,
|
Value: sch.k.Value,
|
||||||
KeyNode: sch.k,
|
KeyNode: sch.k,
|
||||||
}] = sch.v.(low.ValueReference[*base.SchemaProxy])
|
}] = sch.v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d.Schemas = results
|
d.Schemas = results
|
||||||
@@ -86,7 +88,7 @@ func (d *Definitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
|
|
||||||
func (pd *ParameterDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (pd *ParameterDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
errorChan := make(chan error)
|
errorChan := make(chan error)
|
||||||
resultChan := make(chan definitionResult)
|
resultChan := make(chan definitionResult[*Parameter])
|
||||||
var defLabel *yaml.Node
|
var defLabel *yaml.Node
|
||||||
totalDefinitions := 0
|
totalDefinitions := 0
|
||||||
for i := range root.Content {
|
for i := range root.Content {
|
||||||
@@ -95,12 +97,12 @@ func (pd *ParameterDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) err
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
totalDefinitions++
|
totalDefinitions++
|
||||||
var buildFunc = func(label *yaml.Node, value *yaml.Node, idx *index.SpecIndex, r chan definitionResult, 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)
|
obj, err := low.ExtractObjectRaw[*Parameter](value, idx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e <- err
|
e <- err
|
||||||
}
|
}
|
||||||
r <- definitionResult{k: label, v: low.ValueReference[any]{Value: obj, ValueNode: value}}
|
r <- definitionResult[*Parameter]{k: label, v: low.ValueReference[*Parameter]{Value: obj, ValueNode: value}}
|
||||||
}
|
}
|
||||||
go buildFunc(defLabel, root.Content[i], idx, resultChan, errorChan)
|
go buildFunc(defLabel, root.Content[i], idx, resultChan, errorChan)
|
||||||
}
|
}
|
||||||
@@ -112,24 +114,25 @@ func (pd *ParameterDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) err
|
|||||||
case err := <-errorChan:
|
case err := <-errorChan:
|
||||||
return err
|
return err
|
||||||
case sch := <-resultChan:
|
case sch := <-resultChan:
|
||||||
|
completedDefs++
|
||||||
results[low.KeyReference[string]{
|
results[low.KeyReference[string]{
|
||||||
Value: sch.k.Value,
|
Value: sch.k.Value,
|
||||||
KeyNode: sch.k,
|
KeyNode: sch.k,
|
||||||
}] = sch.v.(low.ValueReference[*Parameter])
|
}] = sch.v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pd.Definitions = results
|
pd.Definitions = results
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type definitionResult struct {
|
type definitionResult[T any] struct {
|
||||||
k *yaml.Node
|
k *yaml.Node
|
||||||
v any
|
v low.ValueReference[T]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ResponsesDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (r *ResponsesDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
errorChan := make(chan error)
|
errorChan := make(chan error)
|
||||||
resultChan := make(chan definitionResult)
|
resultChan := make(chan definitionResult[*Response])
|
||||||
var defLabel *yaml.Node
|
var defLabel *yaml.Node
|
||||||
totalDefinitions := 0
|
totalDefinitions := 0
|
||||||
for i := range root.Content {
|
for i := range root.Content {
|
||||||
@@ -138,12 +141,12 @@ func (r *ResponsesDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) erro
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
totalDefinitions++
|
totalDefinitions++
|
||||||
var buildFunc = func(label *yaml.Node, value *yaml.Node, idx *index.SpecIndex, r chan definitionResult, 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)
|
obj, err := low.ExtractObjectRaw[*Response](value, idx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e <- err
|
e <- err
|
||||||
}
|
}
|
||||||
r <- definitionResult{k: label, v: low.ValueReference[any]{Value: obj, ValueNode: value}}
|
r <- definitionResult[*Response]{k: label, v: low.ValueReference[*Response]{Value: obj, ValueNode: value}}
|
||||||
}
|
}
|
||||||
go buildFunc(defLabel, root.Content[i], idx, resultChan, errorChan)
|
go buildFunc(defLabel, root.Content[i], idx, resultChan, errorChan)
|
||||||
}
|
}
|
||||||
@@ -155,10 +158,11 @@ func (r *ResponsesDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) erro
|
|||||||
case err := <-errorChan:
|
case err := <-errorChan:
|
||||||
return err
|
return err
|
||||||
case sch := <-resultChan:
|
case sch := <-resultChan:
|
||||||
|
completedDefs++
|
||||||
results[low.KeyReference[string]{
|
results[low.KeyReference[string]{
|
||||||
Value: sch.k.Value,
|
Value: sch.k.Value,
|
||||||
KeyNode: sch.k,
|
KeyNode: sch.k,
|
||||||
}] = sch.v.(low.ValueReference[*Response])
|
}] = sch.v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r.Definitions = results
|
r.Definitions = results
|
||||||
@@ -167,7 +171,7 @@ func (r *ResponsesDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) erro
|
|||||||
|
|
||||||
func (s *SecurityDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (s *SecurityDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
errorChan := make(chan error)
|
errorChan := make(chan error)
|
||||||
resultChan := make(chan definitionResult)
|
resultChan := make(chan definitionResult[*SecurityScheme])
|
||||||
var defLabel *yaml.Node
|
var defLabel *yaml.Node
|
||||||
totalDefinitions := 0
|
totalDefinitions := 0
|
||||||
for i := range root.Content {
|
for i := range root.Content {
|
||||||
@@ -176,12 +180,12 @@ func (s *SecurityDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) error
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
totalDefinitions++
|
totalDefinitions++
|
||||||
var buildFunc = func(label *yaml.Node, value *yaml.Node, idx *index.SpecIndex, r chan definitionResult, 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)
|
obj, err := low.ExtractObjectRaw[*SecurityScheme](value, idx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e <- err
|
e <- err
|
||||||
}
|
}
|
||||||
r <- definitionResult{k: label, v: low.ValueReference[any]{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)
|
go buildFunc(defLabel, root.Content[i], idx, resultChan, errorChan)
|
||||||
}
|
}
|
||||||
@@ -193,10 +197,11 @@ func (s *SecurityDefinitions) Build(root *yaml.Node, idx *index.SpecIndex) error
|
|||||||
case err := <-errorChan:
|
case err := <-errorChan:
|
||||||
return err
|
return err
|
||||||
case sch := <-resultChan:
|
case sch := <-resultChan:
|
||||||
|
completedDefs++
|
||||||
results[low.KeyReference[string]{
|
results[low.KeyReference[string]{
|
||||||
Value: sch.k.Value,
|
Value: sch.k.Value,
|
||||||
KeyNode: sch.k,
|
KeyNode: sch.k,
|
||||||
}] = sch.v.(low.ValueReference[*SecurityScheme])
|
}] = sch.v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.Definitions = results
|
s.Definitions = results
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package v2
|
|||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/index"
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"github.com/pb33f/libopenapi/utils"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -41,8 +42,44 @@ func (h *Header) FindExtension(ext string) *low.ValueReference[any] {
|
|||||||
|
|
||||||
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)
|
||||||
|
items, err := low.ExtractObject[*Items](ItemsLabel, root, idx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
h.Items = items
|
||||||
|
|
||||||
// TODO: build items.
|
_, ln, vn := utils.FindKeyNodeFull(DefaultLabel, root.Content)
|
||||||
|
if vn != nil {
|
||||||
|
var n map[string]interface{}
|
||||||
|
err = vn.Decode(&n)
|
||||||
|
if err != nil {
|
||||||
|
// if not a map, then try an array
|
||||||
|
var k []interface{}
|
||||||
|
err = vn.Decode(&k)
|
||||||
|
if err != nil {
|
||||||
|
// lets just default to interface
|
||||||
|
var j interface{}
|
||||||
|
_ = vn.Decode(&j)
|
||||||
|
h.Default = low.NodeReference[any]{
|
||||||
|
Value: j,
|
||||||
|
KeyNode: ln,
|
||||||
|
ValueNode: vn,
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
h.Default = low.NodeReference[any]{
|
||||||
|
Value: k,
|
||||||
|
KeyNode: ln,
|
||||||
|
ValueNode: vn,
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
h.Default.Value = low.NodeReference[any]{
|
||||||
|
Value: n,
|
||||||
|
KeyNode: ln,
|
||||||
|
ValueNode: vn,
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,13 +12,14 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
DefaultLabel = "default"
|
DefaultLabel = "default"
|
||||||
|
ItemsLabel = "items"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Items struct {
|
type Items struct {
|
||||||
Type low.NodeReference[string]
|
Type low.NodeReference[string]
|
||||||
Format low.NodeReference[string]
|
Format low.NodeReference[string]
|
||||||
CollectionFormat low.NodeReference[string]
|
CollectionFormat low.NodeReference[string]
|
||||||
Items low.NodeReference[string]
|
Items low.NodeReference[*Items]
|
||||||
Default low.NodeReference[any]
|
Default low.NodeReference[any]
|
||||||
Maximum low.NodeReference[int]
|
Maximum low.NodeReference[int]
|
||||||
ExclusiveMaximum low.NodeReference[bool]
|
ExclusiveMaximum low.NodeReference[bool]
|
||||||
@@ -35,6 +36,12 @@ type Items struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *Items) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
func (i *Items) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||||
|
items, iErr := low.ExtractObject[*Items](ItemsLabel, root, idx)
|
||||||
|
if iErr != nil {
|
||||||
|
return iErr
|
||||||
|
}
|
||||||
|
i.Items = items
|
||||||
|
|
||||||
_, ln, vn := utils.FindKeyNodeFull(DefaultLabel, root.Content)
|
_, ln, vn := utils.FindKeyNodeFull(DefaultLabel, root.Content)
|
||||||
if vn != nil {
|
if vn != nil {
|
||||||
var n map[string]interface{}
|
var n map[string]interface{}
|
||||||
|
|||||||
@@ -62,6 +62,19 @@ func (p *PathItem) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
skip = true
|
skip = true
|
||||||
continue
|
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 {
|
if skip {
|
||||||
skip = false
|
skip = false
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ func (r *Response) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
r.Schema = *s
|
if s != nil {
|
||||||
|
r.Schema = *s
|
||||||
|
}
|
||||||
|
|
||||||
//extract headers
|
//extract headers
|
||||||
headers, lN, kN, err := low.ExtractMapFlat[*Header](HeadersLabel, root, idx)
|
headers, lN, kN, err := low.ExtractMapFlat[*Header](HeadersLabel, root, idx)
|
||||||
|
|||||||
@@ -3,9 +3,38 @@
|
|||||||
|
|
||||||
package v2
|
package v2
|
||||||
|
|
||||||
import "github.com/pb33f/libopenapi/datamodel/low"
|
import (
|
||||||
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
|
"github.com/pb33f/libopenapi/index"
|
||||||
|
"github.com/pb33f/libopenapi/utils"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
type Scopes struct {
|
type Scopes struct {
|
||||||
Values low.NodeReference[map[low.KeyReference[string]]low.ValueReference[string]]
|
Values map[low.KeyReference[string]]low.ValueReference[string]
|
||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Scopes) FindScope(scope string) *low.ValueReference[string] {
|
||||||
|
return low.FindItemInMap[string](scope, s.Values)
|
||||||
|
}
|
||||||
|
|
||||||
|
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])
|
||||||
|
if utils.IsNodeMap(root) {
|
||||||
|
for k := range root.Content {
|
||||||
|
if k%2 == 0 {
|
||||||
|
valueMap[low.KeyReference[string]{
|
||||||
|
Value: root.Content[k].Value,
|
||||||
|
KeyNode: root.Content[k],
|
||||||
|
}] = low.ValueReference[string]{
|
||||||
|
Value: root.Content[k+1].Value,
|
||||||
|
ValueNode: root.Content[k+1],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.Values = valueMap
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,10 +14,35 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type SecurityRequirement struct {
|
type SecurityRequirement struct {
|
||||||
Values low.NodeReference[[]low.ValueReference[string]]
|
Values low.ValueReference[map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]]]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SecurityRequirement) Build(_ *yaml.Node, _ *index.SpecIndex) error {
|
func (s *SecurityRequirement) Build(root *yaml.Node, _ *index.SpecIndex) error {
|
||||||
// not implemented.
|
var labelNode *yaml.Node
|
||||||
|
var arr []low.ValueReference[string]
|
||||||
|
valueMap := make(map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]])
|
||||||
|
for i := range root.Content {
|
||||||
|
if i%2 == 0 {
|
||||||
|
labelNode = root.Content[i]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for j := range root.Content[i].Content {
|
||||||
|
arr = append(arr, low.ValueReference[string]{
|
||||||
|
Value: root.Content[i].Content[j].Value,
|
||||||
|
ValueNode: root.Content[i].Content[j],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
valueMap[low.KeyReference[string]{
|
||||||
|
Value: labelNode.Value,
|
||||||
|
KeyNode: labelNode,
|
||||||
|
}] = low.ValueReference[[]low.ValueReference[string]]{
|
||||||
|
Value: arr,
|
||||||
|
ValueNode: root.Content[i],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.Values = low.ValueReference[map[low.KeyReference[string]]low.ValueReference[[]low.ValueReference[string]]]{
|
||||||
|
Value: valueMap,
|
||||||
|
ValueNode: root,
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,26 +4,34 @@
|
|||||||
package v2
|
package v2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pb33f/libopenapi/datamodel/low"
|
"github.com/pb33f/libopenapi/datamodel/low"
|
||||||
"github.com/pb33f/libopenapi/index"
|
"github.com/pb33f/libopenapi/index"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ScopesLabel = "scopes"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SecurityScheme struct {
|
type SecurityScheme struct {
|
||||||
Type low.NodeReference[string]
|
Type low.NodeReference[string]
|
||||||
Description low.NodeReference[string]
|
Description low.NodeReference[string]
|
||||||
Name low.NodeReference[string]
|
Name low.NodeReference[string]
|
||||||
In low.NodeReference[string]
|
In low.NodeReference[string]
|
||||||
Flow low.NodeReference[string]
|
Flow low.NodeReference[string]
|
||||||
AuthorizationUrl low.NodeReference[string]
|
AuthorizationUrl low.NodeReference[string]
|
||||||
TokenUrl low.NodeReference[string]
|
TokenUrl low.NodeReference[string]
|
||||||
Scopes low.NodeReference[*Scopes]
|
Scopes low.NodeReference[*Scopes]
|
||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
// TODO: scopes
|
scopes, sErr := low.ExtractObject[*Scopes](ScopesLabel, root, idx)
|
||||||
return nil
|
if sErr != nil {
|
||||||
|
return sErr
|
||||||
|
}
|
||||||
|
ss.Scopes = scopes
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,24 +15,28 @@ import (
|
|||||||
type documentFunction func(root *yaml.Node, doc *Swagger, idx *index.SpecIndex, c chan<- bool, e chan<- error)
|
type documentFunction func(root *yaml.Node, doc *Swagger, idx *index.SpecIndex, c chan<- bool, e chan<- error)
|
||||||
|
|
||||||
type Swagger struct {
|
type Swagger struct {
|
||||||
Swagger low.ValueReference[string]
|
Swagger low.ValueReference[string]
|
||||||
Info low.NodeReference[*base.Info]
|
Info low.NodeReference[*base.Info]
|
||||||
Host low.NodeReference[string]
|
Host low.NodeReference[string]
|
||||||
BasePath low.NodeReference[string]
|
BasePath low.NodeReference[string]
|
||||||
Schemes low.NodeReference[[]low.ValueReference[string]]
|
Schemes low.NodeReference[[]low.ValueReference[string]]
|
||||||
Consumes low.NodeReference[[]low.ValueReference[string]]
|
Consumes low.NodeReference[[]low.ValueReference[string]]
|
||||||
Produces low.NodeReference[[]low.ValueReference[string]]
|
Produces low.NodeReference[[]low.ValueReference[string]]
|
||||||
Paths low.NodeReference[*Paths]
|
Paths low.NodeReference[*Paths]
|
||||||
Definitions low.NodeReference[*Definitions]
|
Definitions low.NodeReference[*Definitions]
|
||||||
SecurityDefinitions low.NodeReference[*SecurityDefinitions]
|
SecurityDefinitions low.NodeReference[*SecurityDefinitions]
|
||||||
Parameters low.NodeReference[*ParameterDefinitions]
|
Parameters low.NodeReference[*ParameterDefinitions]
|
||||||
ResponsesDefinitions low.NodeReference[*ResponsesDefinitions]
|
Responses low.NodeReference[*ResponsesDefinitions]
|
||||||
Responses low.NodeReference[*Responses]
|
Security low.NodeReference[[]low.ValueReference[*SecurityRequirement]]
|
||||||
Security low.NodeReference[[]low.ValueReference[*SecurityRequirement]]
|
Tags low.NodeReference[[]low.ValueReference[*base.Tag]]
|
||||||
Tags low.NodeReference[[]low.ValueReference[*base.Tag]]
|
ExternalDocs low.NodeReference[*base.ExternalDoc]
|
||||||
ExternalDocs low.NodeReference[*base.ExternalDoc]
|
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
||||||
Extensions map[low.KeyReference[string]]low.ValueReference[any]
|
Index *index.SpecIndex
|
||||||
Index *index.SpecIndex
|
SpecInfo *datamodel.SpecInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Swagger) FindExtension(ext string) *low.ValueReference[any] {
|
||||||
|
return low.FindItemInMap[any](ext, s.Extensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateDocument(info *datamodel.SpecInfo) (*Swagger, []error) {
|
func CreateDocument(info *datamodel.SpecInfo) (*Swagger, []error) {
|
||||||
@@ -43,13 +47,28 @@ func CreateDocument(info *datamodel.SpecInfo) (*Swagger, []error) {
|
|||||||
// build an index
|
// build an index
|
||||||
idx := index.NewSpecIndex(info.RootNode)
|
idx := index.NewSpecIndex(info.RootNode)
|
||||||
doc.Index = idx
|
doc.Index = idx
|
||||||
|
doc.SpecInfo = info
|
||||||
|
|
||||||
|
var errors []error
|
||||||
|
|
||||||
|
// build out swagger scalar variables.
|
||||||
|
bErr := low.BuildModel(info.RootNode, &doc)
|
||||||
|
if bErr != nil {
|
||||||
|
errors = append(errors, bErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract externalDocs
|
||||||
|
extDocs, err := low.ExtractObject[*base.ExternalDoc](base.ExternalDocsLabel, info.RootNode, idx)
|
||||||
|
if err != nil {
|
||||||
|
errors = append(errors, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
doc.ExternalDocs = extDocs
|
||||||
|
|
||||||
// create resolver and check for circular references.
|
// create resolver and check for circular references.
|
||||||
resolve := resolver.NewResolver(idx)
|
resolve := resolver.NewResolver(idx)
|
||||||
_ = resolve.CheckForCircularReferences()
|
_ = resolve.CheckForCircularReferences()
|
||||||
|
|
||||||
var errors []error
|
|
||||||
|
|
||||||
extractionFuncs := []documentFunction{
|
extractionFuncs := []documentFunction{
|
||||||
extractInfo,
|
extractInfo,
|
||||||
extractPaths,
|
extractPaths,
|
||||||
@@ -57,6 +76,8 @@ func CreateDocument(info *datamodel.SpecInfo) (*Swagger, []error) {
|
|||||||
extractParamDefinitions,
|
extractParamDefinitions,
|
||||||
extractResponsesDefinitions,
|
extractResponsesDefinitions,
|
||||||
extractSecurityDefinitions,
|
extractSecurityDefinitions,
|
||||||
|
extractTags,
|
||||||
|
extractSecurity,
|
||||||
}
|
}
|
||||||
doneChan := make(chan bool)
|
doneChan := make(chan bool)
|
||||||
errChan := make(chan error)
|
errChan := make(chan error)
|
||||||
@@ -120,12 +141,12 @@ func extractResponsesDefinitions(root *yaml.Node, doc *Swagger, idx *index.SpecI
|
|||||||
e <- err
|
e <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
doc.ResponsesDefinitions = resp
|
doc.Responses = resp
|
||||||
c <- true
|
c <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractSecurityDefinitions(root *yaml.Node, doc *Swagger, idx *index.SpecIndex, c chan<- bool, e chan<- error) {
|
func extractSecurityDefinitions(root *yaml.Node, doc *Swagger, idx *index.SpecIndex, c chan<- bool, e chan<- error) {
|
||||||
sec, err := low.ExtractObject[*SecurityDefinitions](SecurityLabel, root, idx)
|
sec, err := low.ExtractObject[*SecurityDefinitions](SecurityDefinitionsLabel, root, idx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e <- err
|
e <- err
|
||||||
return
|
return
|
||||||
@@ -133,3 +154,31 @@ func extractSecurityDefinitions(root *yaml.Node, doc *Swagger, idx *index.SpecIn
|
|||||||
doc.SecurityDefinitions = sec
|
doc.SecurityDefinitions = sec
|
||||||
c <- true
|
c <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extractTags(root *yaml.Node, doc *Swagger, idx *index.SpecIndex, c chan<- bool, e chan<- error) {
|
||||||
|
tags, ln, vn, err := low.ExtractArray[*base.Tag](base.TagsLabel, root, idx)
|
||||||
|
if err != nil {
|
||||||
|
e <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
doc.Tags = low.NodeReference[[]low.ValueReference[*base.Tag]]{
|
||||||
|
Value: tags,
|
||||||
|
KeyNode: ln,
|
||||||
|
ValueNode: vn,
|
||||||
|
}
|
||||||
|
c <- true
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractSecurity(root *yaml.Node, doc *Swagger, idx *index.SpecIndex, c chan<- bool, e chan<- error) {
|
||||||
|
sec, ln, vn, err := low.ExtractArray[*SecurityRequirement](SecurityLabel, root, idx)
|
||||||
|
if err != nil {
|
||||||
|
e <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
doc.Security = low.NodeReference[[]low.ValueReference[*SecurityRequirement]]{
|
||||||
|
Value: sec,
|
||||||
|
KeyNode: ln,
|
||||||
|
ValueNode: vn,
|
||||||
|
}
|
||||||
|
c <- true
|
||||||
|
}
|
||||||
|
|||||||
93
datamodel/low/2.0/swagger_test.go
Normal file
93
datamodel/low/2.0/swagger_test.go
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pb33f/libopenapi/datamodel"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"io/ioutil"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var doc *Swagger
|
||||||
|
|
||||||
|
func initTest() {
|
||||||
|
if doc != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data, _ := ioutil.ReadFile("../../../test_specs/petstorev2-complete.yaml")
|
||||||
|
info, _ := datamodel.ExtractSpecInfo(data)
|
||||||
|
var err []error
|
||||||
|
doc, err = CreateDocument(info)
|
||||||
|
wait := true
|
||||||
|
for wait {
|
||||||
|
select {
|
||||||
|
case <-info.JsonParsingChannel:
|
||||||
|
wait = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
panic("broken something")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkCreateDocument(b *testing.B) {
|
||||||
|
data, _ := ioutil.ReadFile("../../../test_specs/petstorev2-complete.yaml")
|
||||||
|
info, _ := datamodel.ExtractSpecInfo(data)
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
doc, _ = CreateDocument(info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateDocument(t *testing.T) {
|
||||||
|
initTest()
|
||||||
|
assert.Equal(t, "2.0", doc.SpecInfo.Version)
|
||||||
|
assert.Equal(t, "1.0.6", doc.Info.Value.Version.Value)
|
||||||
|
assert.Equal(t, "petstore.swagger.io", doc.Host.Value)
|
||||||
|
assert.Equal(t, "/v2", doc.BasePath.Value)
|
||||||
|
assert.Len(t, doc.Parameters.Value.Definitions, 1)
|
||||||
|
assert.Len(t, doc.Tags.Value, 3)
|
||||||
|
assert.Len(t, doc.Schemes.Value, 2)
|
||||||
|
assert.Len(t, doc.Definitions.Value.Schemas, 6)
|
||||||
|
assert.Len(t, doc.SecurityDefinitions.Value.Definitions, 2)
|
||||||
|
assert.Len(t, doc.Paths.Value.PathItems, 14)
|
||||||
|
assert.Len(t, doc.Responses.Value.Definitions, 2)
|
||||||
|
assert.Equal(t, "http://swagger.io", doc.ExternalDocs.Value.URL.Value)
|
||||||
|
assert.Equal(t, true, doc.FindExtension("x-pet").Value)
|
||||||
|
assert.Equal(t, true, doc.FindExtension("X-Pet").Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateDocument_Info(t *testing.T) {
|
||||||
|
initTest()
|
||||||
|
assert.Equal(t, "Swagger Petstore", doc.Info.Value.Title.Value)
|
||||||
|
assert.Equal(t, "apiteam@swagger.io", doc.Info.Value.Contact.Value.Email.Value)
|
||||||
|
assert.Equal(t, "Apache 2.0", doc.Info.Value.License.Value.Name.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateDocument_Parameters(t *testing.T) {
|
||||||
|
initTest()
|
||||||
|
simpleParam := doc.Parameters.Value.FindParameter("simpleParam")
|
||||||
|
assert.NotNil(t, simpleParam)
|
||||||
|
assert.Equal(t, "simple", simpleParam.Value.Name.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateDocument_Tags(t *testing.T) {
|
||||||
|
initTest()
|
||||||
|
assert.Equal(t, "pet", doc.Tags.Value[0].Value.Name.Value)
|
||||||
|
assert.Equal(t, "http://swagger.io", doc.Tags.Value[0].Value.ExternalDocs.Value.URL.Value)
|
||||||
|
assert.Equal(t, "store", doc.Tags.Value[1].Value.Name.Value)
|
||||||
|
assert.Equal(t, "user", doc.Tags.Value[2].Value.Name.Value)
|
||||||
|
assert.Equal(t, "http://swagger.io", doc.Tags.Value[2].Value.ExternalDocs.Value.URL.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateDocument_SecurityDefinitions(t *testing.T) {
|
||||||
|
initTest()
|
||||||
|
apiKey := doc.SecurityDefinitions.Value.FindSecurityDefinition("api_key")
|
||||||
|
assert.Equal(t, "apiKey", apiKey.Value.Type.Value)
|
||||||
|
petStoreAuth := doc.SecurityDefinitions.Value.FindSecurityDefinition("petstore_auth")
|
||||||
|
assert.Equal(t, "oauth2", petStoreAuth.Value.Type.Value)
|
||||||
|
assert.Equal(t, "implicit", petStoreAuth.Value.Flow.Value)
|
||||||
|
assert.Len(t, petStoreAuth.Value.Scopes.Value.Values, 2)
|
||||||
|
assert.Equal(t, "read your pets", petStoreAuth.Value.Scopes.Value.FindScope("read:pets").Value)
|
||||||
|
}
|
||||||
@@ -19,6 +19,9 @@ func FindItemInMap[T any](item string, collection map[KeyReference[string]]Value
|
|||||||
if n.Value == item {
|
if n.Value == item {
|
||||||
return &o
|
return &o
|
||||||
}
|
}
|
||||||
|
if strings.ToLower(n.Value) == strings.ToLower(item) {
|
||||||
|
return &o
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ func BuildModel(node *yaml.Node, model interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// we need to find a matching field in the YAML, the cases may be off, so take no chances.
|
// we need to find a matching field in the YAML, the cases may be off, so take no chances.
|
||||||
cases := []utils.Case{utils.PascalCase, utils.CamelCase, utils.ScreamingSnakeCase,
|
cases := []utils.Case{utils.CamelCase, utils.PascalCase, utils.ScreamingSnakeCase,
|
||||||
utils.SnakeCase, utils.KebabCase, utils.RegularCase}
|
utils.SnakeCase, utils.KebabCase, utils.RegularCase}
|
||||||
|
|
||||||
var vn, kn *yaml.Node
|
var vn, kn *yaml.Node
|
||||||
|
|||||||
@@ -1,30 +1,51 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/pb33f/libopenapi/datamodel"
|
||||||
|
high "github.com/pb33f/libopenapi/datamodel/high/3.0"
|
||||||
|
low "github.com/pb33f/libopenapi/datamodel/low/3.0"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
// testData := `openapi: 3.0.1
|
testData := `openapi: 3.0.1
|
||||||
//info:
|
info:
|
||||||
// title: this is a title
|
title: this is a title
|
||||||
// description: this is a description`
|
description: this is a description
|
||||||
//
|
tags:
|
||||||
// data := []byte(testData)
|
- name: Tag A
|
||||||
// _ = ioutil.WriteFile("sample.yaml", data, 0664)
|
description: cake
|
||||||
//
|
x-hack: true
|
||||||
// info, _ := datamodel.ExtractSpecInfo(data)
|
- name: Tag B
|
||||||
// lowDoc, err := low.CreateDocument(info)
|
description: coffee
|
||||||
// if len(err) > 0 {
|
x-code: hack`
|
||||||
// for e := range err {
|
|
||||||
// fmt.Printf("%e\n", err[e])
|
|
||||||
// }
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// highDoc := high.NewDocument(lowDoc)
|
|
||||||
// fmt.Println(highDoc.Info.Title)
|
|
||||||
// highDoc.Info.GoLow().Title.ValueNode.Value = "let's hack this shizzle"
|
|
||||||
//
|
|
||||||
// modified, _ := yaml.Marshal(info.RootNode)
|
|
||||||
// fmt.Println(string(modified))
|
|
||||||
|
|
||||||
//os.Remove("sample.yaml")
|
data := []byte(testData)
|
||||||
|
_ = ioutil.WriteFile("sample.yaml", data, 0664)
|
||||||
|
|
||||||
|
info, _ := datamodel.ExtractSpecInfo(data)
|
||||||
|
lowDoc, err := low.CreateDocument(info)
|
||||||
|
if len(err) > 0 {
|
||||||
|
for e := range err {
|
||||||
|
fmt.Printf("%e\n", err[e])
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
highDoc := high.NewDocument(lowDoc)
|
||||||
|
fmt.Println(highDoc.Info.Title)
|
||||||
|
|
||||||
|
highDoc.Info.GoLow().Title.ValueNode.Value = "let's hack this shizzle"
|
||||||
|
|
||||||
|
modified, _ := yaml.Marshal(info.RootNode)
|
||||||
|
fmt.Println(string(modified))
|
||||||
|
|
||||||
|
d, _ := yaml.Marshal(highDoc.Tags[0])
|
||||||
|
fmt.Println(d)
|
||||||
|
|
||||||
|
os.Remove("sample.yaml")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
11
sample.yaml
Normal file
11
sample.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
openapi: 3.0.1
|
||||||
|
info:
|
||||||
|
title: this is a title
|
||||||
|
description: this is a description
|
||||||
|
tags:
|
||||||
|
- name: Tag A
|
||||||
|
description: cake
|
||||||
|
x-hack: true
|
||||||
|
- name: Tag B
|
||||||
|
description: coffee
|
||||||
|
x-code: hack
|
||||||
741
test_specs/petstorev2-complete.yaml
Normal file
741
test_specs/petstorev2-complete.yaml
Normal file
@@ -0,0 +1,741 @@
|
|||||||
|
---
|
||||||
|
swagger: '2.0'
|
||||||
|
x-pet: true
|
||||||
|
info:
|
||||||
|
description: 'This is a sample server Petstore server. You can find out more about
|
||||||
|
Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For
|
||||||
|
this sample, you can use the api key `special-key` to test the authorization filters.'
|
||||||
|
version: 1.0.6
|
||||||
|
title: Swagger Petstore
|
||||||
|
termsOfService: http://swagger.io/terms/
|
||||||
|
contact:
|
||||||
|
email: apiteam@swagger.io
|
||||||
|
license:
|
||||||
|
name: Apache 2.0
|
||||||
|
url: http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
host: petstore.swagger.io
|
||||||
|
basePath: "/v2"
|
||||||
|
parameters:
|
||||||
|
simpleParam:
|
||||||
|
in: query
|
||||||
|
name: simple
|
||||||
|
type: string
|
||||||
|
tags:
|
||||||
|
- name: pet
|
||||||
|
description: Everything about your Pets
|
||||||
|
externalDocs:
|
||||||
|
description: Find out more
|
||||||
|
url: http://swagger.io
|
||||||
|
- name: store
|
||||||
|
description: Access to Petstore orders
|
||||||
|
- name: user
|
||||||
|
description: Operations about user
|
||||||
|
externalDocs:
|
||||||
|
description: Find out more about our store
|
||||||
|
url: http://swagger.io
|
||||||
|
schemes:
|
||||||
|
- https
|
||||||
|
- http
|
||||||
|
paths:
|
||||||
|
"/pet/{petId}/uploadImage":
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: uploads an image
|
||||||
|
description: ''
|
||||||
|
operationId: uploadFile
|
||||||
|
consumes:
|
||||||
|
- multipart/form-data
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
parameters:
|
||||||
|
- name: petId
|
||||||
|
in: path
|
||||||
|
description: ID of pet to update
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
- name: additionalMetadata
|
||||||
|
in: formData
|
||||||
|
description: Additional data to pass to server
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: file
|
||||||
|
in: formData
|
||||||
|
description: file to upload
|
||||||
|
required: false
|
||||||
|
type: file
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
headers:
|
||||||
|
myHeader:
|
||||||
|
type: array
|
||||||
|
description: myHeader
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
collectionFormat: csv
|
||||||
|
default: [ one, two, three ]
|
||||||
|
enum: [99,100,101]
|
||||||
|
description: successful operation
|
||||||
|
schema:
|
||||||
|
"$ref": "#/definitions/ApiResponse"
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
"/pet":
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Add a new pet to the store
|
||||||
|
description: ''
|
||||||
|
operationId: addPet
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
parameters:
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
description: Pet object that needs to be added to the store
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
"$ref": "#/definitions/Pet"
|
||||||
|
responses:
|
||||||
|
'405':
|
||||||
|
description: Invalid input
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Update an existing pet
|
||||||
|
description: ''
|
||||||
|
operationId: updatePet
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
parameters:
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
description: Pet object that needs to be added to the store
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
"$ref": "#/definitions/Pet"
|
||||||
|
responses:
|
||||||
|
'400':
|
||||||
|
description: Invalid ID supplied
|
||||||
|
'404':
|
||||||
|
description: Pet not found
|
||||||
|
'405':
|
||||||
|
description: Validation exception
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
"/pet/findByStatus":
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Finds Pets by status
|
||||||
|
description: Multiple status values can be provided with comma separated strings
|
||||||
|
operationId: findPetsByStatus
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
parameters:
|
||||||
|
- name: status
|
||||||
|
in: query
|
||||||
|
description: Status values that need to be considered for filter
|
||||||
|
required: true
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- available
|
||||||
|
- pending
|
||||||
|
- sold
|
||||||
|
default: available
|
||||||
|
collectionFormat: multi
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
"$ref": "#/definitions/Pet"
|
||||||
|
'400':
|
||||||
|
description: Invalid status value
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
"/pet/findByTags":
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Finds Pets by tags
|
||||||
|
description: Multiple tags can be provided with comma separated strings. Use
|
||||||
|
tag1, tag2, tag3 for testing.
|
||||||
|
operationId: findPetsByTags
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
parameters:
|
||||||
|
- name: tags
|
||||||
|
in: query
|
||||||
|
description: Tags to filter by
|
||||||
|
required: true
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
collectionFormat: multi
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
"$ref": "#/definitions/Pet"
|
||||||
|
'400':
|
||||||
|
description: Invalid tag value
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
deprecated: true
|
||||||
|
"/pet/{petId}":
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Find pet by ID
|
||||||
|
description: Returns a single pet
|
||||||
|
operationId: getPetById
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
parameters:
|
||||||
|
- name: petId
|
||||||
|
in: path
|
||||||
|
description: ID of pet to return
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
schema:
|
||||||
|
"$ref": "#/definitions/Pet"
|
||||||
|
'400':
|
||||||
|
description: Invalid ID supplied
|
||||||
|
'404':
|
||||||
|
description: Pet not found
|
||||||
|
security:
|
||||||
|
- api_key: []
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Updates a pet in the store with form data
|
||||||
|
description: ''
|
||||||
|
operationId: updatePetWithForm
|
||||||
|
consumes:
|
||||||
|
- application/x-www-form-urlencoded
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
parameters:
|
||||||
|
- name: petId
|
||||||
|
in: path
|
||||||
|
description: ID of pet that needs to be updated
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
- name: name
|
||||||
|
in: formData
|
||||||
|
description: Updated name of the pet
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: status
|
||||||
|
in: formData
|
||||||
|
description: Updated status of the pet
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'405':
|
||||||
|
description: Invalid input
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Deletes a pet
|
||||||
|
description: ''
|
||||||
|
operationId: deletePet
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
parameters:
|
||||||
|
- name: api_key
|
||||||
|
in: header
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: petId
|
||||||
|
in: path
|
||||||
|
description: Pet id to delete
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
'400':
|
||||||
|
description: Invalid ID supplied
|
||||||
|
'404':
|
||||||
|
description: Pet not found
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
"/store/order":
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- store
|
||||||
|
summary: Place an order for a pet
|
||||||
|
description: ''
|
||||||
|
operationId: placeOrder
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
parameters:
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
description: order placed for purchasing the pet
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
"$ref": "#/definitions/Order"
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
schema:
|
||||||
|
"$ref": "#/definitions/Order"
|
||||||
|
'400':
|
||||||
|
description: Invalid Order
|
||||||
|
"/store/order/{orderId}":
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- store
|
||||||
|
summary: Find purchase order by ID
|
||||||
|
description: For valid response try integer IDs with value >= 1 and <= 10. Other
|
||||||
|
values will generated exceptions
|
||||||
|
operationId: getOrderById
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
parameters:
|
||||||
|
- name: orderId
|
||||||
|
in: path
|
||||||
|
description: ID of pet that needs to be fetched
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
maximum: 10
|
||||||
|
minimum: 1
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
schema:
|
||||||
|
"$ref": "#/definitions/Order"
|
||||||
|
'400':
|
||||||
|
description: Invalid ID supplied
|
||||||
|
'404':
|
||||||
|
description: Order not found
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- store
|
||||||
|
summary: Delete purchase order by ID
|
||||||
|
description: For valid response try integer IDs with positive integer value.
|
||||||
|
Negative or non-integer values will generate API errors
|
||||||
|
operationId: deleteOrder
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
parameters:
|
||||||
|
- name: orderId
|
||||||
|
in: path
|
||||||
|
description: ID of the order that needs to be deleted
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
minimum: 1
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
'400':
|
||||||
|
description: Invalid ID supplied
|
||||||
|
'404':
|
||||||
|
description: Order not found
|
||||||
|
"/store/inventory":
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- store
|
||||||
|
summary: Returns pet inventories by status
|
||||||
|
description: Returns a map of status codes to quantities
|
||||||
|
operationId: getInventory
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
parameters: []
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
security:
|
||||||
|
- api_key: []
|
||||||
|
"/user/createWithArray":
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Creates list of users with given input array
|
||||||
|
description: ''
|
||||||
|
operationId: createUsersWithArrayInput
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
parameters:
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
description: List of user object
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
"$ref": "#/definitions/User"
|
||||||
|
responses:
|
||||||
|
default:
|
||||||
|
description: successful operation
|
||||||
|
"/user/createWithList":
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Creates list of users with given input array
|
||||||
|
description: ''
|
||||||
|
operationId: createUsersWithListInput
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
parameters:
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
description: List of user object
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
"$ref": "#/definitions/User"
|
||||||
|
responses:
|
||||||
|
default:
|
||||||
|
description: successful operation
|
||||||
|
"/user/{username}":
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Get user by user name
|
||||||
|
description: ''
|
||||||
|
operationId: getUserByName
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
parameters:
|
||||||
|
- name: username
|
||||||
|
in: path
|
||||||
|
description: 'The name that needs to be fetched. Use user1 for testing. '
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
schema:
|
||||||
|
"$ref": "#/definitions/User"
|
||||||
|
'400':
|
||||||
|
description: Invalid username supplied
|
||||||
|
'404':
|
||||||
|
description: User not found
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Updated user
|
||||||
|
description: This can only be done by the logged in user.
|
||||||
|
operationId: updateUser
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
parameters:
|
||||||
|
- name: username
|
||||||
|
in: path
|
||||||
|
description: name that need to be updated
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
description: Updated user object
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
"$ref": "#/definitions/User"
|
||||||
|
responses:
|
||||||
|
'400':
|
||||||
|
description: Invalid user supplied
|
||||||
|
'404':
|
||||||
|
description: User not found
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Delete user
|
||||||
|
description: This can only be done by the logged in user.
|
||||||
|
operationId: deleteUser
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
parameters:
|
||||||
|
- name: username
|
||||||
|
in: path
|
||||||
|
description: The name that needs to be deleted
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'400':
|
||||||
|
description: Invalid username supplied
|
||||||
|
'404':
|
||||||
|
description: User not found
|
||||||
|
"/user/login":
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Logs user into the system
|
||||||
|
description: ''
|
||||||
|
operationId: loginUser
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
parameters:
|
||||||
|
- name: username
|
||||||
|
in: query
|
||||||
|
description: The user name for login
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- name: password
|
||||||
|
in: query
|
||||||
|
description: The password for login in clear text
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
headers:
|
||||||
|
X-Expires-After:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
description: date in UTC when token expires
|
||||||
|
X-Rate-Limit:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
description: calls per hour allowed by the user
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
'400':
|
||||||
|
description: Invalid username/password supplied
|
||||||
|
"/user/logout":
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Logs out current logged in user session
|
||||||
|
description: ''
|
||||||
|
operationId: logoutUser
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
parameters: []
|
||||||
|
responses:
|
||||||
|
default:
|
||||||
|
description: successful operation
|
||||||
|
"/user":
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Create user
|
||||||
|
description: This can only be done by the logged in user.
|
||||||
|
operationId: createUser
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
- application/xml
|
||||||
|
parameters:
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
description: Created user object
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
"$ref": "#/definitions/User"
|
||||||
|
responses:
|
||||||
|
default:
|
||||||
|
description: successful operation
|
||||||
|
securityDefinitions:
|
||||||
|
api_key:
|
||||||
|
type: apiKey
|
||||||
|
name: api_key
|
||||||
|
in: header
|
||||||
|
petstore_auth:
|
||||||
|
type: oauth2
|
||||||
|
authorizationUrl: https://petstore.swagger.io/oauth/authorize
|
||||||
|
flow: implicit
|
||||||
|
scopes:
|
||||||
|
read:pets: read your pets
|
||||||
|
write:pets: modify pets in your account
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/ApiResponse'
|
||||||
|
"500":
|
||||||
|
description: Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/ApiResponse'
|
||||||
|
definitions:
|
||||||
|
ApiResponse:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
Category:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
xml:
|
||||||
|
name: Category
|
||||||
|
Pet:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
- photoUrls
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
category:
|
||||||
|
"$ref": "#/definitions/Category"
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
example: doggie
|
||||||
|
photoUrls:
|
||||||
|
type: array
|
||||||
|
xml:
|
||||||
|
wrapped: true
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
xml:
|
||||||
|
name: photoUrl
|
||||||
|
tags:
|
||||||
|
type: array
|
||||||
|
xml:
|
||||||
|
wrapped: true
|
||||||
|
items:
|
||||||
|
xml:
|
||||||
|
name: tag
|
||||||
|
"$ref": "#/definitions/Tag"
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: pet status in the store
|
||||||
|
enum:
|
||||||
|
- available
|
||||||
|
- pending
|
||||||
|
- sold
|
||||||
|
xml:
|
||||||
|
name: Pet
|
||||||
|
Tag:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
xml:
|
||||||
|
name: Tag
|
||||||
|
Order:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
petId:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
quantity:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
shipDate:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: Order Status
|
||||||
|
enum:
|
||||||
|
- placed
|
||||||
|
- approved
|
||||||
|
- delivered
|
||||||
|
complete:
|
||||||
|
type: boolean
|
||||||
|
xml:
|
||||||
|
name: Order
|
||||||
|
User:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
username:
|
||||||
|
type: string
|
||||||
|
firstName:
|
||||||
|
type: string
|
||||||
|
lastName:
|
||||||
|
type: string
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
phone:
|
||||||
|
type: string
|
||||||
|
userStatus:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
description: User Status
|
||||||
|
xml:
|
||||||
|
name: User
|
||||||
|
externalDocs:
|
||||||
|
description: Find out more about Swagger
|
||||||
|
url: http://swagger.io
|
||||||
Reference in New Issue
Block a user