diff --git a/datamodel/high/base/discriminator.go b/datamodel/high/base/discriminator.go index 23bb262..0e18c6f 100644 --- a/datamodel/high/base/discriminator.go +++ b/datamodel/high/base/discriminator.go @@ -8,6 +8,12 @@ import ( ) // Discriminator is only used by OpenAPI 3+ documents, it represents a polymorphic discriminator used for schemas +// +// When request bodies or response payloads may be one of a number of different schemas, a discriminator object can be +// used to aid in serialization, deserialization, and validation. The discriminator is a specific object in a schema +// which is used to inform the consumer of the document of an alternative schema based on the value associated with it. +// +// When using the discriminator, inline schemas will not be considered. // v3 - https://spec.openapis.org/oas/v3.1.0#discriminator-object type Discriminator struct { PropertyName string diff --git a/datamodel/high/base/external_doc.go b/datamodel/high/base/external_doc.go index 916cc81..8589d7c 100644 --- a/datamodel/high/base/external_doc.go +++ b/datamodel/high/base/external_doc.go @@ -9,6 +9,8 @@ import ( ) // ExternalDoc represents an External Documentation object as defined by OpenAPI 2 and 3 +// +// Allows referencing an external resource for extended documentation. // v2 - https://swagger.io/specification/v2/#externalDocumentationObject // v3 - https://spec.openapis.org/oas/v3.1.0#external-documentation-object type ExternalDoc struct { diff --git a/datamodel/high/base/tag.go b/datamodel/high/base/tag.go index 3f7293d..68cc842 100644 --- a/datamodel/high/base/tag.go +++ b/datamodel/high/base/tag.go @@ -9,6 +9,9 @@ import ( ) // Tag represents a high-level Tag instance that is backed by a low-level one. +// +// Adds metadata to a single tag that is used by the Operation Object. It is not mandatory to have a Tag Object per +// tag defined in the Operation Object instances. // - v2: https://swagger.io/specification/v2/#tagObject // - v3: https://swagger.io/specification/#tag-object type Tag struct { diff --git a/datamodel/high/base/xml.go b/datamodel/high/base/xml.go index 8336294..7720496 100644 --- a/datamodel/high/base/xml.go +++ b/datamodel/high/base/xml.go @@ -10,6 +10,11 @@ import ( // XML represents a high-level representation of an XML object defined by all versions of OpenAPI and backed by // low-level XML object. +// +// A metadata object that allows for more fine-tuned XML model definitions. +// +// When using arrays, XML element names are not inferred (for singular/plural forms) and the name property SHOULD be +// used to add that information. See examples for expected behavior. // v2 - https://swagger.io/specification/v2/#xmlObject // v3 - https://swagger.io/specification/#xml-object type XML struct { diff --git a/datamodel/high/v2/definitions.go b/datamodel/high/v2/definitions.go index 80f616a..ae1e247 100644 --- a/datamodel/high/v2/definitions.go +++ b/datamodel/high/v2/definitions.go @@ -10,11 +10,17 @@ import ( low "github.com/pb33f/libopenapi/datamodel/low/v2" ) +// Definitions is a high-level represents of a Swagger / OpenAPI 2 Definitions object, backed by a low-level one. +// +// 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 { Definitions map[string]*highbase.SchemaProxy low *low.Definitions } +// NewDefinitions will create a new high-level instance of a Definition from a low-level one. func NewDefinitions(definitions *low.Definitions) *Definitions { rd := new(Definitions) rd.low = definitions @@ -28,6 +34,7 @@ func NewDefinitions(definitions *low.Definitions) *Definitions { return rd } +// GoLow returns the low-level Definitions object used to create the high-level one. func (d *Definitions) GoLow() *low.Definitions { return d.low } diff --git a/datamodel/high/v2/examples.go b/datamodel/high/v2/examples.go index 0195a11..d863a16 100644 --- a/datamodel/high/v2/examples.go +++ b/datamodel/high/v2/examples.go @@ -5,13 +5,17 @@ package v2 import low "github.com/pb33f/libopenapi/datamodel/low/v2" -type Examples struct { +// Example represents a high-level Swagger / OpenAPI 2 Example object, backed by a low level one. +// Allows sharing examples for operation responses +// - https://swagger.io/specification/v2/#exampleObject +type Example struct { Values map[string]any low *low.Examples } -func NewExamples(examples *low.Examples) *Examples { - e := new(Examples) +// NewExample creates a new high-level Example instance from a low-level one. +func NewExample(examples *low.Examples) *Example { + e := new(Example) e.low = examples if len(examples.Values) > 0 { values := make(map[string]any) @@ -23,6 +27,7 @@ func NewExamples(examples *low.Examples) *Examples { return e } -func (e *Examples) GoLow() *low.Examples { +// GoLow returns the low-level Example used to create the high-level one. +func (e *Example) GoLow() *low.Examples { return e.low } diff --git a/datamodel/high/v2/header.go b/datamodel/high/v2/header.go index aba2658..415b938 100644 --- a/datamodel/high/v2/header.go +++ b/datamodel/high/v2/header.go @@ -8,6 +8,9 @@ import ( low "github.com/pb33f/libopenapi/datamodel/low/v2" ) +// Header Represents a high-level Swagger / OpenAPI 2 Header object, backed by a low-level one. +// 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 string Format string @@ -31,6 +34,7 @@ type Header struct { low *low.Header } +// NewHeader will create a new high-level Swagger / OpenAPI 2 Header instance, from a low-level one. func NewHeader(header *low.Header) *Header { h := new(Header) h.low = header @@ -96,6 +100,7 @@ func NewHeader(header *low.Header) *Header { return h } +// GoLow returns the low-level header used to create the high-level one. func (h *Header) GoLow() *low.Header { return h.low } diff --git a/datamodel/high/v2/items.go b/datamodel/high/v2/items.go index 93d5bbe..88a73c2 100644 --- a/datamodel/high/v2/items.go +++ b/datamodel/high/v2/items.go @@ -5,6 +5,10 @@ package v2 import low "github.com/pb33f/libopenapi/datamodel/low/v2" +// Items is a high-level representation of a Swagger / OpenAPI 2 Items object, backed by a low level one. +// 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 string Format string @@ -26,6 +30,7 @@ type Items struct { low *low.Items } +// NewItems creates a new high-level Items instance from a low-level one. func NewItems(items *low.Items) *Items { i := new(Items) i.low = items @@ -87,6 +92,7 @@ func NewItems(items *low.Items) *Items { return i } +// GoLow returns the low-level Items object that was used to create the high-level one. func (i *Items) GoLow() *low.Items { return i.low } diff --git a/datamodel/high/v2/operation.go b/datamodel/high/v2/operation.go index a9961b9..df86a25 100644 --- a/datamodel/high/v2/operation.go +++ b/datamodel/high/v2/operation.go @@ -9,6 +9,9 @@ import ( low "github.com/pb33f/libopenapi/datamodel/low/v2" ) +// Operation represents a high-level Swagger / OpenAPI 2 Operation object, backed by a low-level one. +// It describes a single API operation on a path. +// - https://swagger.io/specification/v2/#operationObject type Operation struct { Tags []string Summary string @@ -26,6 +29,7 @@ type Operation struct { low *low.Operation } +// NewOperation creates a new high-level Operation instance from a low-level one. func NewOperation(operation *low.Operation) *Operation { o := new(Operation) o.low = operation @@ -93,6 +97,7 @@ func NewOperation(operation *low.Operation) *Operation { return o } +// GoLow returns the low-level operation used to create the high-level one. func (o *Operation) GoLow() *low.Operation { return o.low } diff --git a/datamodel/high/v2/parameter.go b/datamodel/high/v2/parameter.go index de4bc5a..ee40476 100644 --- a/datamodel/high/v2/parameter.go +++ b/datamodel/high/v2/parameter.go @@ -9,6 +9,37 @@ import ( low "github.com/pb33f/libopenapi/datamodel/low/v2" ) +// Parameter represents a high-level Swagger / OpenAPI 2 Parameter object, backed by a low-level one. +// +// 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 string In string @@ -37,6 +68,7 @@ type Parameter struct { low *low.Parameter } +// NewParameter creates a new high-level instance of a Parameter from a low-level one. func NewParameter(parameter *low.Parameter) *Parameter { p := new(Parameter) p.low = parameter @@ -117,6 +149,7 @@ func NewParameter(parameter *low.Parameter) *Parameter { return p } +// GoLow returns the low-level Parameter used to create the high-level one. func (p *Parameter) GoLow() *low.Parameter { return p.low } diff --git a/datamodel/high/v2/parameter_definitions.go b/datamodel/high/v2/parameter_definitions.go index b35ad2e..0544edc 100644 --- a/datamodel/high/v2/parameter_definitions.go +++ b/datamodel/high/v2/parameter_definitions.go @@ -5,11 +5,19 @@ package v2 import low "github.com/pb33f/libopenapi/datamodel/low/v2" +// ParameterDefinitions is a high-level representation of a Swagger / OpenAPI 2 Parameters Definitions object +// that is backed by a low-level one. +// +// 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[string]*Parameter low *low.ParameterDefinitions } +// NewParametersDefinitions creates a new instance of a high-level ParameterDefinitions, from a low-level one. +// Every parameter is extracted asynchronously due to the potential depth func NewParametersDefinitions(parametersDefinitions *low.ParameterDefinitions) *ParameterDefinitions { pd := new(ParameterDefinitions) pd.low = parametersDefinitions @@ -37,6 +45,7 @@ func NewParametersDefinitions(parametersDefinitions *low.ParameterDefinitions) * return pd } +// GoLow returns the low-level ParameterDefinitions instance that backs the low-level one. func (p *ParameterDefinitions) GoLow() *low.ParameterDefinitions { return p.low } diff --git a/datamodel/high/v2/response.go b/datamodel/high/v2/response.go index bd13b44..3e20711 100644 --- a/datamodel/high/v2/response.go +++ b/datamodel/high/v2/response.go @@ -13,7 +13,7 @@ type Response struct { Description string Schema *base.SchemaProxy Headers map[string]*Header - Examples *Examples + Examples *Example Extensions map[string]any low *low.Response } @@ -36,7 +36,7 @@ func NewResponse(response *low.Response) *Response { r.Headers = headers } if !response.Examples.IsEmpty() { - r.Examples = NewExamples(response.Examples.Value) + r.Examples = NewExample(response.Examples.Value) } return r } diff --git a/datamodel/high/v2/swagger.go b/datamodel/high/v2/swagger.go index 5c4f8ff..ce7bac1 100644 --- a/datamodel/high/v2/swagger.go +++ b/datamodel/high/v2/swagger.go @@ -1,6 +1,14 @@ // Copyright 2022 Princess B33f Heavy Industries / Dave Shanley // SPDX-License-Identifier: MIT +// Package v2 represents all Swagger / OpenAPI 2 high-level models. High-level models are easy to navigate +// and simple to extract what ever is required from a specification. +// +// High-level models are backed by low-level ones. There is a 'GoLow()' method available on every high level +// object. 'Going Low' allows engineers to transition from a high-level or 'porcelain' API, to a low-level 'plumbing' +// API, which provides fine grain detail to the underlying AST powering the data, lines, columns, raw nodes etc. +// +// IMPORTANT: As a general rule, Swagger / OpenAPI 2 should be avoided for new projects. package v2 import ( @@ -9,26 +17,84 @@ import ( low "github.com/pb33f/libopenapi/datamodel/low/v2" ) +// Swagger represents a high-level Swagger / OpenAPI 2 document. An instance of Swagger is the root of the specification. type Swagger struct { - Swagger string - Info *base.Info - Host string - BasePath string - Schemes []string - Consumes []string - Produces []string - Paths *Paths - Definitions *Definitions - Parameters *ParameterDefinitions - Responses *ResponsesDefinitions + + // Swagger is the version of Swagger / OpenAPI being used, extracted from the 'swagger: 2.x' definition. + Swagger 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 *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 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 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 []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 []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 []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 *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 *Definitions + + // 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 *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 *ResponsesDefinitions + + // SecurityDefinitions represents security scheme definitions that can be used across the specification. + // - https://swagger.io/specification/v2/#securityDefinitionsObject SecurityDefinitions *SecurityDefinitions - Security []*SecurityRequirement - Tags []*base.Tag - ExternalDocs *base.ExternalDoc - Extensions map[string]any - low *low.Swagger + + // 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 []*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 []*base.Tag + + // ExternalDocs is an instance of base.ExternalDoc for.. well, obvious really, innit. + ExternalDocs *base.ExternalDoc + + // Extensions contains all custom extensions defined for the top-level document. + Extensions map[string]any + low *low.Swagger } +// NewSwaggerDocument will create a new high-level Swagger document from a low-level one. func NewSwaggerDocument(document *low.Swagger) *Swagger { d := new(Swagger) d.low = document @@ -103,10 +169,12 @@ func NewSwaggerDocument(document *low.Swagger) *Swagger { return d } +// GoLow returns the low-level Swagger instance that was used to create the high-level one. func (s *Swagger) GoLow() *low.Swagger { return s.low } +// everything is build async, this little gem holds the results. type asyncResult[T any] struct { key string result T diff --git a/datamodel/high/v3/document.go b/datamodel/high/v3/document.go index d46fcb0..1941587 100644 --- a/datamodel/high/v3/document.go +++ b/datamodel/high/v3/document.go @@ -23,27 +23,38 @@ type Document struct { // This is not a standard property of the OpenAPI model, it's a convenience mechanism only. Version string - // Info presents a specification Info definitions + // Info represents a specification Info definitions + // Provides metadata about the API. The metadata MAY be used by tooling as required. // - https://spec.openapis.org/oas/v3.1.0#info-object Info *base.Info - // Servers is a slice of Server instances + // Servers is a slice of Server instances which provide connectivity information to a target server. If the servers + // property is not provided, or is an empty array, the default value would be a Server Object with a url value of /. // - https://spec.openapis.org/oas/v3.1.0#server-object Servers []*Server // Paths contains all the PathItem definitions for the specification. + // The available paths and operations for the API, The most important part of ths spec. // - https://spec.openapis.org/oas/v3.1.0#paths-object Paths *Paths - // Components contains everything defined as a component (referenced by everything else) + // Components is an element to hold various schemas for the document. // - https://spec.openapis.org/oas/v3.1.0#components-object Components *Components // Security contains global security requirements/roles for the specification + // A declaration of which security mechanisms can be used across the API. The list of values includes alternative + // security requirement objects that can be used. Only one of the security requirement objects need to be satisfied + // to authorize a request. Individual operations can override this definition. To make security optional, + // an empty security requirement ({}) can be included in the array. // - https://spec.openapis.org/oas/v3.1.0#security-requirement-object Security *SecurityRequirement // Tags is a slice of base.Tag instances defined by the specification + // A list of tags used by the document with additional metadata. The order of the tags can be used to reflect on + // their order by the parsing tools. Not all tags that are used by the Operation Object must be declared. + // The tags that are not declared MAY be organized randomly or based on the tools’ logic. + // Each tag name in the list MUST be unique. // - https://spec.openapis.org/oas/v3.1.0#tag-object Tags []*base.Tag @@ -55,10 +66,17 @@ type Document struct { Extensions map[string]any // JsonSchemaDialect is a 3.1+ property that sets the dialect to use for validating *base.Schema definitions + // The default value for the $schema keyword within Schema Objects contained within this OAS document. + // This MUST be in the form of a URI. // - https://spec.openapis.org/oas/v3.1.0#schema-object JsonSchemaDialect string // Webhooks is a 3.1+ property that is similar to callbacks, except, this defines incoming webhooks. + // The incoming webhooks that MAY be received as part of this API and that the API consumer MAY choose to implement. + // Closely related to the callbacks feature, this section describes requests initiated other than by an API call, + // for example by an out-of-band registration. The key name is a unique string to refer to each webhook, + // while the (optionally referenced) Path Item Object describes a request that may be initiated by the API provider + // and the expected responses. An example is available. Webhooks map[string]*PathItem // Index is a reference to the *index.SpecIndex that was created for the document and used diff --git a/datamodel/high/v3/security_scheme.go b/datamodel/high/v3/security_scheme.go index 3fa0594..541eeb4 100644 --- a/datamodel/high/v3/security_scheme.go +++ b/datamodel/high/v3/security_scheme.go @@ -8,6 +8,16 @@ import ( low "github.com/pb33f/libopenapi/datamodel/low/v3" ) +// SecurityScheme represents a high-level OpenAPI 3+ SecurityScheme object that is backed by a low-level one. +// +// Defines a security scheme that can be used by the operations. +// +// Supported schemes are HTTP authentication, an API key (either as a header, a cookie parameter or as a query parameter), +// mutual TLS (use of a client certificate), OAuth2’s common flows (implicit, password, client credentials and +// authorization code) as defined in RFC6749 (https://www.rfc-editor.org/rfc/rfc6749), and OpenID Connect Discovery. +// Please note that as of 2020, the implicit flow is about to be deprecated by OAuth 2.0 Security Best Current Practice. +// Recommended for most use case is Authorization Code Grant flow with PKCE. +// - https://spec.openapis.org/oas/v3.1.0#security-scheme-object type SecurityScheme struct { Type string Description string @@ -21,6 +31,7 @@ type SecurityScheme struct { low *low.SecurityScheme } +// NewSecurityScheme creates a new high-level SecurityScheme from a low-level one. func NewSecurityScheme(ss *low.SecurityScheme) *SecurityScheme { s := new(SecurityScheme) s.low = ss @@ -38,6 +49,7 @@ func NewSecurityScheme(ss *low.SecurityScheme) *SecurityScheme { return s } +// GoLow returns the low-level SecurityScheme that was used to create the high-level one. func (s *SecurityScheme) GoLow() *low.SecurityScheme { return s.low } diff --git a/datamodel/high/v3/server.go b/datamodel/high/v3/server.go index c0e2627..627ab53 100644 --- a/datamodel/high/v3/server.go +++ b/datamodel/high/v3/server.go @@ -5,6 +5,8 @@ package v3 import low "github.com/pb33f/libopenapi/datamodel/low/v3" +// Server represents a high-level OpenAPI 3+ Server object, that is backed by a low level one. +// - https://spec.openapis.org/oas/v3.1.0#server-object type Server struct { URL string Description string @@ -12,6 +14,7 @@ type Server struct { low *low.Server } +// NewServer will create a new high-level Server instance from a low-level one. func NewServer(server *low.Server) *Server { s := new(Server) s.low = server @@ -25,6 +28,7 @@ func NewServer(server *low.Server) *Server { return s } +// GoLow returns the low-level Server instance that was used to create the high-level one func (s *Server) GoLow() *low.Server { return s.low } diff --git a/datamodel/high/v3/server_variable.go b/datamodel/high/v3/server_variable.go index 484243e..ccfe747 100644 --- a/datamodel/high/v3/server_variable.go +++ b/datamodel/high/v3/server_variable.go @@ -5,6 +5,10 @@ package v3 import low "github.com/pb33f/libopenapi/datamodel/low/v3" +// ServerVariable represents a high-level OpenAPI 3+ ServerVariable object, that is backed by a low-level one. +// +// ServerVariable is an object representing a Server Variable for server URL template substitution. +// - https://spec.openapis.org/oas/v3.1.0#server-variable-object type ServerVariable struct { Enum []string Default string @@ -12,6 +16,7 @@ type ServerVariable struct { low *low.ServerVariable } +// NewServerVariable will return a new high-level instance of a ServerVariable from a low-level one. func NewServerVariable(variable *low.ServerVariable) *ServerVariable { v := new(ServerVariable) v.low = variable @@ -27,6 +32,7 @@ func NewServerVariable(variable *low.ServerVariable) *ServerVariable { return v } +// GoLow returns the low-level ServerVariable used to to create the high\-level one. func (s *ServerVariable) GoLow() *low.ServerVariable { return s.low }