@@ -1,6 +1,6 @@
1+{-# LANGUAGE CPP #-}
12{-# LANGUAGE DataKinds #-}
23{-# LANGUAGE DeriveDataTypeable #-}
3−{-# LANGUAGE DeriveFunctor #-}
44{-# LANGUAGE DeriveGeneric #-}
55{-# LANGUAGE DeriveTraversable #-}
66{-# LANGUAGE FlexibleContexts #-}
@@ -14,7 +14,7 @@
1414{-# LANGUAGE TemplateHaskell #-}
1515{-# LANGUAGE TypeFamilies #-}
1616{-# LANGUAGE UndecidableInstances #-}
17−module Data.Swagger.Internal where
17+module Data.OpenApi.Internal where
1818
1919import Prelude ()
2020import Prelude.Compat
@@ -22,6 +22,9 @@ import Prelude.Compat
2222import Control.Applicative
2323import Control.Lens ((&), (.~), (?~))
2424import Data.Aeson hiding (Encoding)
25+#if MIN_VERSION_aeson(2,0,0)
26+import qualified Data.Aeson.KeyMap as KeyMap
27+#endif
2528import qualified Data.Aeson.Types as JSON
2629import Data.Data (Constr, Data (..), DataType, Fixity (..), Typeable,
2730 constrIndex, mkConstr, mkDataType)
@@ -46,58 +49,56 @@ import Text.Read (readMaybe)
4649import Data.HashMap.Strict.InsOrd (InsOrdHashMap)
4750import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap
4851
52+import Data.OpenApi.Aeson.Compat (deleteKey)
53+import Data.OpenApi.Internal.AesonUtils (AesonDefaultValue (..), HasSwaggerAesonOptions (..),
54+ mkSwaggerAesonOptions, saoAdditionalPairs, saoSubObject,
55+ sopSwaggerGenericParseJSON, sopSwaggerGenericToEncoding,
56+ sopSwaggerGenericToJSON, sopSwaggerGenericToJSONWithOpts)
57+import Data.OpenApi.Internal.Utils
4958import Generics.SOP.TH (deriveGeneric)
50−import Data.Swagger.Internal.AesonUtils (sopSwaggerGenericToJSON
51− ,sopSwaggerGenericToJSONWithOpts
52− ,sopSwaggerGenericParseJSON
53− ,HasSwaggerAesonOptions(..)
54− ,AesonDefaultValue(..)
55− ,mkSwaggerAesonOptions
56− ,saoAdditionalPairs
57− ,saoSubObject)
58−import Data.Swagger.Internal.Utils
59−import Data.Swagger.Internal.AesonUtils (sopSwaggerGenericToEncoding)
6059
6160-- $setup
6261-- >>> :seti -XDataKinds
6362-- >>> import Data.Aeson
63+-- >>> import Data.ByteString.Lazy.Char8 as BSL
64+-- >>> import Data.OpenApi.Internal.Utils
6465
6566-- | A list of definitions that can be used in references.
6667type Definitions = InsOrdHashMap Text
6768
6869-- | This is the root document object for the API specification.
69−data Swagger = Swagger
70+data OpenApi = OpenApi
7071 { -- | Provides metadata about the API.
7172 -- The metadata can be used by the clients if needed.
72− _swaggerInfo :: Info
73+ _openApiInfo :: Info
7374
7475 -- | An array of Server Objects, which provide connectivity information
7576 -- to a target server. If the servers property is not provided, or is an empty array,
7677 -- the default value would be a 'Server' object with a url value of @/@.
77− , _swaggerServers :: [Server]
78+ , _openApiServers :: [Server]
7879
7980 -- | The available paths and operations for the API.
80− , _swaggerPaths :: InsOrdHashMap FilePath PathItem
81+ , _openApiPaths :: InsOrdHashMap FilePath PathItem
8182
8283 -- | An element to hold various schemas for the specification.
83− , _swaggerComponents :: Components
84+ , _openApiComponents :: Components
8485
8586 -- | A declaration of which security mechanisms can be used across the API.
8687 -- The list of values includes alternative security requirement objects that can be used.
8788 -- Only one of the security requirement objects need to be satisfied to authorize a request.
8889 -- Individual operations can override this definition.
8990 -- To make security optional, an empty security requirement can be included in the array.
90− , _swaggerSecurity :: [SecurityRequirement]
91+ , _openApiSecurity :: [SecurityRequirement]
9192
9293 -- | A list of tags used by the specification with additional metadata.
9394 -- The order of the tags can be used to reflect on their order by the parsing tools.
9495 -- Not all tags that are used by the 'Operation' Object must be declared.
9596 -- The tags that are not declared MAY be organized randomly or based on the tools' logic.
9697 -- Each tag name in the list MUST be unique.
97− , _swaggerTags :: InsOrdHashSet Tag
98+ , _openApiTags :: InsOrdHashSet Tag
9899
99100 -- | Additional external documentation.
100− , _swaggerExternalDocs :: Maybe ExternalDocs
101+ , _openApiExternalDocs :: Maybe ExternalDocs
101102 } deriving (Eq, Show, Generic, Data, Typeable)
102103
103104-- | The object provides metadata about the API.
@@ -194,10 +195,10 @@ data Components = Components
194195 , _componentsParameters :: Definitions Param
195196 , _componentsExamples :: Definitions Example
196197 , _componentsRequestBodies :: Definitions RequestBody
197− , _componentsHeader :: Definitions Header
198− , _componentsSecuritySchemes :: Definitions SecurityScheme
199−-- , _componentsLinks
200−-- , _componentsCallbacks
198+ , _componentsHeaders :: Definitions Header
199+ , _componentsSecuritySchemes :: SecurityDefinitions
200+ , _componentsLinks :: Definitions Link
201+ , _componentsCallbacks :: Definitions Callback
201202 } deriving (Eq, Show, Generic, Data, Typeable)
202203
203204-- | Describes the operations available on a single path.
@@ -287,7 +288,11 @@ data Operation = Operation
287288 -- | The list of possible responses as they are returned from executing this operation.
288289 , _operationResponses :: Responses
289290
290− -- TODO callbacks
291+ -- | A map of possible out-of band callbacks related to the parent operation.
292+ -- The key is a unique identifier for the 'Callback' Object.
293+ -- Each value in the map is a 'Callback' Object that describes a request
294+ -- that may be initiated by the API provider and the expected responses.
295+ , _operationCallbacks :: InsOrdHashMap Text (Referenced Callback)
291296
292297 -- | Declares this operation to be deprecated.
293298 -- Usage of the declared operation should be refrained.
@@ -332,9 +337,11 @@ data RequestBody = RequestBody
332337 -- | The content of the request body.
333338 -- The key is a media type or media type range and the value describes it.
334339 -- For requests that match multiple keys, only the most specific key is applicable.
335− -- e.g. @text/plain@ overrides @text/*@
340+ -- e.g. @text/plain@ overrides @text/\*@
336341 , _requestBodyContent :: InsOrdHashMap MediaType MediaTypeObject
337342
343+ -- | Determines if the request body is required in the request.
344+ -- Defaults to 'False'.
338345 , _requestBodyRequired :: Maybe Bool
339346 } deriving (Eq, Show, Generic, Data, Typeable)
340347
@@ -387,7 +394,7 @@ data Encoding = Encoding
387394 -- for other primitive types – @text/plain@; for object - @application/json@;
388395 -- for array – the default is defined based on the inner type.
389396 -- The value can be a specific media type (e.g. @application/json@),
390− -- a wildcard media type (e.g. @image/*@), or a comma-separated list of the two types.
397+ -- a wildcard media type (e.g. @image/\*@), or a comma-separated list of the two types.
391398 _encodingContentType :: Maybe MediaType
392399
393400 -- | A map allowing additional information to be provided as headers,
@@ -427,11 +434,11 @@ mimeListConstr :: Constr
427434mimeListConstr = mkConstr mimeListDataType "MimeList" ["getMimeList"] Prefix
428435
429436mimeListDataType :: DataType
430−mimeListDataType = mkDataType "Data.Swagger.MimeList" [mimeListConstr]
437+mimeListDataType = mkDataType "Data.OpenApi.MimeList" [mimeListConstr]
431438
432439instance Data MimeList where
433440 gunfold k z c = case constrIndex c of
434− 1 -> k (z (\xs -> MimeList (map fromString xs)))
441+ 1 -> k (z (MimeList . map fromString))
435442 _ -> error $ "Data.Data.gunfold: Constructor " ++ show c ++ " is not of type MimeList."
436443 toConstr (MimeList _) = mimeListConstr
437444 dataTypeOf _ = mimeListDataType
@@ -445,7 +452,7 @@ data Param = Param
445452
446453 -- | A brief description of the parameter.
447454 -- This could contain examples of use.
448− -- GFM syntax can be used for rich text representation.
455+ -- CommonMark syntax MAY be used for rich text representation.
449456 , _paramDescription :: Maybe Text
450457
451458 -- | Determines whether this parameter is mandatory.
@@ -465,6 +472,13 @@ data Param = Param
465472 -- a parameter with an empty value. Default value is @false@.
466473 , _paramAllowEmptyValue :: Maybe Bool
467474
475+ -- | Determines whether the parameter value SHOULD allow reserved characters,
476+ -- as defined by [RFC3986](https://tools.ietf.org/html/rfc3986#section-2.2)
477+ -- @:/?#[]@!$&'()*+,;=@ to be included without percent-encoding.
478+ -- This property only applies to parameters with an '_paramIn' value of 'ParamQuery'.
479+ -- The default value is 'False'.
480+ , _paramAllowReserved :: Maybe Bool
481+
468482 -- | Parameter schema.
469483 , _paramSchema :: Maybe (Referenced Schema)
470484
@@ -495,6 +509,10 @@ data Param = Param
495509 -- Furthermore, if referencing a schema that contains an example,
496510 -- the examples value SHALL override the example provided by the schema.
497511 , _paramExamples :: InsOrdHashMap Text (Referenced Example)
512+
513+ -- TODO
514+ -- _paramContent :: InsOrdHashMap MediaType MediaTypeObject
515+ -- should be singleton. mutually exclusive with _paramSchema.
498516 } deriving (Eq, Show, Generic, Data, Typeable)
499517
500518data Example = Example
@@ -519,27 +537,63 @@ data Example = Example
519537 , _exampleExternalValue :: Maybe URL
520538 } deriving (Eq, Show, Generic, Typeable, Data)
521539
522−-- | Items for @'SwaggerArray'@ schemas.
540+data ExpressionOrValue
541+ = Expression Text
542+ | Value Value
543+ deriving (Eq, Show, Generic, Typeable, Data)
544+
545+-- | The Link object represents a possible design-time link for a response.
546+-- The presence of a link does not guarantee the caller's ability to successfully invoke it,
547+-- rather it provides a known relationship and traversal mechanism between responses and other operations.
548+data Link = Link
549+ { -- | A relative or absolute URI reference to an OAS operation.
550+ -- This field is mutually exclusive of the '_linkOperationId' field,
551+ -- and MUST point to an 'Operation' Object. Relative '_linkOperationRef'
552+ -- values MAY be used to locate an existing 'Operation' Object in the OpenAPI definition.
553+ _linkOperationRef :: Maybe Text
554+
555+ -- | The name of an /existing/, resolvable OAS operation, as defined with a unique
556+ -- '_operationOperationId'. This field is mutually exclusive of the '_linkOperationRef' field.
557+ , _linkOperationId :: Maybe Text
558+
559+ -- | A map representing parameters to pass to an operation as specified with '_linkOperationId'
560+ -- or identified via '_linkOperationRef'. The key is the parameter name to be used, whereas
561+ -- the value can be a constant or an expression to be evaluated and passed to the linked operation.
562+ -- The parameter name can be qualified using the parameter location @[{in}.]{name}@
563+ -- for operations that use the same parameter name in different locations (e.g. path.id).
564+ , _linkParameters :: InsOrdHashMap Text ExpressionOrValue
565+
566+ -- | A literal value or @{expression}@ to use as a request body when calling the target operation.
567+ , _linkRequestBody :: Maybe ExpressionOrValue
568+
569+ -- | A description of the link.
570+ , _linkDescription :: Maybe Text
571+
572+ -- | A server object to be used by the target operation.
573+ , _linkServer :: Maybe Server
574+ } deriving (Eq, Show, Generic, Typeable, Data)
575+
576+-- | Items for @'OpenApiArray'@ schemas.
523577--
524578-- __Warning__: OpenAPI 3.0 does not support tuple arrays. However, OpenAPI 3.1 will, as
525579-- it will incorporate Json Schema mostly verbatim.
526580--
527−-- @'SwaggerItemsObject'@ should be used to specify homogenous array @'Schema'@s.
581+-- @'OpenApiItemsObject'@ should be used to specify homogenous array @'Schema'@s.
528582--
529−-- @'SwaggerItemsArray'@ should be used to specify tuple @'Schema'@s.
530−data SwaggerItems where
531− SwaggerItemsObject :: Referenced Schema -> SwaggerItems
532− SwaggerItemsArray :: [Referenced Schema] -> SwaggerItems
583+-- @'OpenApiItemsArray'@ should be used to specify tuple @'Schema'@s.
584+data OpenApiItems where
585+ OpenApiItemsObject :: Referenced Schema -> OpenApiItems
586+ OpenApiItemsArray :: [Referenced Schema] -> OpenApiItems
533587 deriving (Eq, Show, Typeable, Data)
534588
535−data SwaggerType where
536− SwaggerString :: SwaggerType
537− SwaggerNumber :: SwaggerType
538− SwaggerInteger :: SwaggerType
539− SwaggerBoolean :: SwaggerType
540− SwaggerArray :: SwaggerType
541− SwaggerNull :: SwaggerType
542− SwaggerObject :: SwaggerType
589+data OpenApiType where
590+ OpenApiString :: OpenApiType
591+ OpenApiNumber :: OpenApiType
592+ OpenApiInteger :: OpenApiType
593+ OpenApiBoolean :: OpenApiType
594+ OpenApiArray :: OpenApiType
595+ OpenApiNull :: OpenApiType
596+ OpenApiObject :: OpenApiType
543597 deriving (Eq, Show, Typeable, Generic, Data)
544598
545599data ParamLocation
@@ -584,9 +638,33 @@ data Schema = Schema
584638 , _schemaMaxProperties :: Maybe Integer
585639 , _schemaMinProperties :: Maybe Integer
586640
587− , _schemaParamSchema :: ParamSchema
641+ , -- | Declares the value of the parameter that the server will use if none is provided,
642+ -- for example a @"count"@ to control the number of results per page might default to @100@
643+ -- if not supplied by the client in the request.
644+ -- (Note: "default" has no meaning for required parameters.)
645+ -- Unlike JSON Schema this value MUST conform to the defined type for this parameter.
646+ _schemaDefault :: Maybe Value
647+
648+ , _schemaType :: Maybe OpenApiType
649+ , _schemaFormat :: Maybe Format
650+ , _schemaItems :: Maybe OpenApiItems
651+ , _schemaMaximum :: Maybe Scientific
652+ , _schemaExclusiveMaximum :: Maybe Bool
653+ , _schemaMinimum :: Maybe Scientific
654+ , _schemaExclusiveMinimum :: Maybe Bool
655+ , _schemaMaxLength :: Maybe Integer
656+ , _schemaMinLength :: Maybe Integer
657+ , _schemaPattern :: Maybe Pattern
658+ , _schemaMaxItems :: Maybe Integer
659+ , _schemaMinItems :: Maybe Integer
660+ , _schemaUniqueItems :: Maybe Bool
661+ , _schemaEnum :: Maybe [Value]
662+ , _schemaMultipleOf :: Maybe Scientific
588663 } deriving (Eq, Show, Generic, Data, Typeable)
589664
665+-- | Regex pattern for @string@ type.
666+type Pattern = Text
667+
590668data Discriminator = Discriminator
591669 { -- | The name of the property in the payload that will hold the discriminator value.
592670 _discriminatorPropertyName :: Text
@@ -602,37 +680,9 @@ data NamedSchema = NamedSchema
602680 , _namedSchemaSchema :: Schema
603681 } deriving (Eq, Show, Generic, Data, Typeable)
604682
605−-- | Regex pattern for @string@ type.
606−type Pattern = Text
607−
608−data ParamSchema = ParamSchema
609− { -- | Declares the value of the parameter that the server will use if none is provided,
610− -- for example a @"count"@ to control the number of results per page might default to @100@
611− -- if not supplied by the client in the request.
612− -- (Note: "default" has no meaning for required parameters.)
613− -- Unlike JSON Schema this value MUST conform to the defined type for this parameter.
614− _paramSchemaDefault :: Maybe Value
615−
616− , _paramSchemaType :: Maybe SwaggerType
617− , _paramSchemaFormat :: Maybe Format
618− , _paramSchemaItems :: Maybe SwaggerItems
619− , _paramSchemaMaximum :: Maybe Scientific
620− , _paramSchemaExclusiveMaximum :: Maybe Bool
621− , _paramSchemaMinimum :: Maybe Scientific
622− , _paramSchemaExclusiveMinimum :: Maybe Bool
623− , _paramSchemaMaxLength :: Maybe Integer
624− , _paramSchemaMinLength :: Maybe Integer
625− , _paramSchemaPattern :: Maybe Pattern
626− , _paramSchemaMaxItems :: Maybe Integer
627− , _paramSchemaMinItems :: Maybe Integer
628− , _paramSchemaUniqueItems :: Maybe Bool
629− , _paramSchemaEnum :: Maybe [Value]
630− , _paramSchemaMultipleOf :: Maybe Scientific
631− } deriving (Eq, Show, Generic, Typeable, Data)
632−
633683data Xml = Xml
634684 { -- | Replaces the name of the element/attribute used for the described schema property.
635− -- When defined within the @'SwaggerItems'@ (items), it will affect the name of the individual XML elements within the list.
685+ -- When defined within the @'OpenApiItems'@ (items), it will affect the name of the individual XML elements within the list.
636686 -- When defined alongside type being array (outside the items),
637687 -- it will affect the wrapping element and only if wrapped is true.
638688 -- If wrapped is false, it will be ignored.
@@ -684,25 +734,44 @@ data Response = Response
684734 -- | A map containing descriptions of potential response payloads.
685735 -- The key is a media type or media type range and the value describes it.
686736 -- For responses that match multiple keys, only the most specific key is applicable.
687− -- e.g. @text/plain@ overrides @text/*@.
737+ -- e.g. @text/plain@ overrides @text/\*@.
688738 , _responseContent :: InsOrdHashMap MediaType MediaTypeObject
689739
690740 -- | Maps a header name to its definition.
691741 , _responseHeaders :: InsOrdHashMap HeaderName (Referenced Header)
692742
693− -- TODO links
743+ -- | A map of operations links that can be followed from the response.
744+ -- The key of the map is a short name for the link, following the naming
745+ -- constraints of the names for 'Component' Objects.
746+ , _responseLinks :: InsOrdHashMap Text (Referenced Link)
694747 } deriving (Eq, Show, Generic, Data, Typeable)
695748
696749instance IsString Response where
697− fromString s = Response (fromString s) mempty mempty
750+ fromString s = Response (fromString s) mempty mempty mempty
751+
752+-- | A map of possible out-of band callbacks related to the parent operation.
753+-- Each value in the map is a 'PathItem' Object that describes a set of requests that
754+-- may be initiated by the API provider and the expected responses.
755+-- The key value used to identify the path item object is an expression, evaluated at runtime,
756+-- that identifies a URL to use for the callback operation.
757+newtype Callback = Callback (InsOrdHashMap Text PathItem)
758+ deriving (Eq, Show, Generic, Data, Typeable)
698759
699760type HeaderName = Text
700761
701−
702−-- TODO this is mostly a copy of 'Param'.
762+-- | Header fields have the same meaning as for 'Param'.
763+--
764+-- Style is always treated as 'StyleSimple', as it is the only value allowed for headers.
703765data Header = Header
704766 { -- | A short description of the header.
705− _headerDescription :: Maybe Text
767+ _headerDescription :: Maybe HeaderName
768+
769+ , _headerRequired :: Maybe Bool
770+ , _headerDeprecated :: Maybe Bool
771+ , _headerAllowEmptyValue :: Maybe Bool
772+ , _headerExplode :: Maybe Bool
773+ , _headerExample :: Maybe Value
774+ , _headerExamples :: InsOrdHashMap Text (Referenced Example)
706775
707776 , _headerSchema :: Maybe (Referenced Schema)
708777 } deriving (Eq, Show, Generic, Data, Typeable)
@@ -728,17 +797,17 @@ type AuthorizationURL = Text
728797-- | The token URL to be used for OAuth2 flow. This SHOULD be in the form of a URL.
729798type TokenURL = Text
730799
731−data OAuth2ImplicitFlow = OAuth2ImplicitFlow
732− { _oAuth2ImplicitFlowAuthorizationUrl :: AuthorizationURL
733− } deriving (Eq, Show, Generic, Data, Typeable)
800+newtype OAuth2ImplicitFlow
801+ = OAuth2ImplicitFlow {_oAuth2ImplicitFlowAuthorizationUrl :: AuthorizationURL}
802+ deriving (Eq, Show, Generic, Data, Typeable)
734803
735−data OAuth2PasswordFlow = OAuth2PasswordFlow
736− { _oAuth2PasswordFlowTokenUrl :: TokenURL
737− } deriving (Eq, Show, Generic, Data, Typeable)
804+newtype OAuth2PasswordFlow
805+ = OAuth2PasswordFlow {_oAuth2PasswordFlowTokenUrl :: TokenURL}
806+ deriving (Eq, Show, Generic, Data, Typeable)
738807
739−data OAuth2ClientCredentialsFlow = OAuth2ClientCredentialsFlow
740− { _oAuth2ClientCredentialsFlowTokenUrl :: TokenURL
741− } deriving (Eq, Show, Generic, Data, Typeable)
808+newtype OAuth2ClientCredentialsFlow
809+ = OAuth2ClientCredentialsFlow {_oAuth2ClientCredentialsFlowTokenUrl :: TokenURL}
810+ deriving (Eq, Show, Generic, Data, Typeable)
742811
743812data OAuth2AuthorizationCodeFlow = OAuth2AuthorizationCodeFlow
744813 { _oAuth2AuthorizationCodeFlowAuthorizationUrl :: AuthorizationURL
@@ -771,8 +840,50 @@ data OAuth2Flows = OAuth2Flows
771840 , _oAuth2FlowsAuthorizationCode :: Maybe (OAuth2Flow OAuth2AuthorizationCodeFlow)
772841 } deriving (Eq, Show, Generic, Data, Typeable)
773842
843+type BearerFormat = Text
844+
845+data HttpSchemeType
846+ = HttpSchemeBearer (Maybe BearerFormat)
847+ | HttpSchemeBasic
848+ | HttpSchemeCustom Text
849+ deriving (Eq, Show, Generic, Data, Typeable)
850+
851+-- |
852+--
853+-- >>> BSL.putStrLn $ encodePretty (SecuritySchemeHttp (HttpSchemeBearer Nothing))
854+-- {
855+-- "scheme": "bearer",
856+-- "type": "http"
857+-- }
858+--
859+-- >>> BSL.putStrLn $ encodePretty (SecuritySchemeHttp (HttpSchemeBearer (Just "jwt")))
860+-- {
861+-- "bearerFormat": "jwt",
862+-- "scheme": "bearer",
863+-- "type": "http"
864+-- }
865+--
866+-- >>> BSL.putStrLn $ encodePretty (SecuritySchemeHttp HttpSchemeBasic)
867+-- {
868+-- "scheme": "basic",
869+-- "type": "http"
870+-- }
871+--
872+-- >>> BSL.putStrLn $ encodePretty (SecuritySchemeHttp (HttpSchemeCustom "CANARY"))
873+-- {
874+-- "scheme": "CANARY",
875+-- "type": "http"
876+-- }
877+--
878+-- >>> BSL.putStrLn $ encodePretty (SecuritySchemeApiKey (ApiKeyParams "id" ApiKeyCookie))
879+-- {
880+-- "in": "cookie",
881+-- "name": "id",
882+-- "type": "apiKey"
883+-- }
884+--
774885data SecuritySchemeType
775− = SecuritySchemeHttp
886+ = SecuritySchemeHttp HttpSchemeType
776887 | SecuritySchemeApiKey ApiKeyParams
777888 | SecuritySchemeOAuth2 OAuth2Flows
778889 | SecuritySchemeOpenIdConnect URL
@@ -807,7 +918,7 @@ data Tag = Tag
807918 _tagName :: TagName
808919
809920 -- | A short description for the tag.
810− -- GFM syntax can be used for rich text representation.
921+ -- [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation.
811922 , _tagDescription :: Maybe Text
812923
813924 -- | Additional external documentation for this tag.
@@ -822,7 +933,7 @@ instance IsString Tag where
822933-- | Allows referencing an external resource for extended documentation.
823934data ExternalDocs = ExternalDocs
824935 { -- | A short description of the target documentation.
825− -- GFM syntax can be used for rich text representation.
936+ -- [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation.
826937 _externalDocsDescription :: Maybe Text
827938
828939 -- | The URL for the target documentation.
@@ -869,18 +980,18 @@ deriveGeneric ''MediaTypeObject
869980deriveGeneric ''Responses
870981deriveGeneric ''SecurityScheme
871982deriveGeneric ''Schema
872−deriveGeneric ''ParamSchema
873−deriveGeneric ''Swagger
983+deriveGeneric ''OpenApi
874984deriveGeneric ''Example
875985deriveGeneric ''Encoding
986+deriveGeneric ''Link
876987
877988-- =======================================================================
878989-- Monoid instances
879990-- =======================================================================
880991
881−instance Semigroup Swagger where
992+instance Semigroup OpenApi where
882993 (<>) = genericMappend
883−instance Monoid Swagger where
994+instance Monoid OpenApi where
884995 mempty = genericMempty
885996 mappend = (<>)
886997
@@ -914,12 +1025,6 @@ instance Monoid Schema where
9141025 mempty = genericMempty
9151026 mappend = (<>)
9161027
917−instance Semigroup ParamSchema where
918− (<>) = genericMappend
919−instance Monoid ParamSchema where
920− mempty = genericMempty
921− mappend = (<>)
922−
9231028instance Semigroup Param where
9241029 (<>) = genericMappend
9251030instance Monoid Param where
@@ -1014,19 +1119,19 @@ instance SwaggerMonoid Info
10141119instance SwaggerMonoid Components
10151120instance SwaggerMonoid PathItem
10161121instance SwaggerMonoid Schema
1017−instance SwaggerMonoid ParamSchema
10181122instance SwaggerMonoid Param
10191123instance SwaggerMonoid Responses
10201124instance SwaggerMonoid Response
10211125instance SwaggerMonoid ExternalDocs
10221126instance SwaggerMonoid Operation
10231127instance (Eq a, Hashable a) => SwaggerMonoid (InsOrdHashSet a)
1128+instance SwaggerMonoid SecurityDefinitions
10241129
10251130instance SwaggerMonoid MimeList
10261131deriving instance SwaggerMonoid URL
10271132
1028−instance SwaggerMonoid SwaggerType where
1029− swaggerMempty = SwaggerString
1133+instance SwaggerMonoid OpenApiType where
1134+ swaggerMempty = OpenApiString
10301135 swaggerMappend _ y = y
10311136
10321137instance SwaggerMonoid ParamLocation where
@@ -1049,7 +1154,7 @@ instance Monoid a => SwaggerMonoid (Referenced a) where
10491154instance ToJSON Style where
10501155 toJSON = genericToJSON (jsonPrefix "Style")
10511156
1052−instance ToJSON SwaggerType where
1157+instance ToJSON OpenApiType where
10531158 toJSON = genericToJSON (jsonPrefix "Swagger")
10541159
10551160instance ToJSON ParamLocation where
@@ -1104,7 +1209,7 @@ instance ToJSON OAuth2AuthorizationCodeFlow where
11041209instance FromJSON Style where
11051210 parseJSON = genericParseJSON (jsonPrefix "Style")
11061211
1107−instance FromJSON SwaggerType where
1212+instance FromJSON OpenApiType where
11081213 parseJSON = genericParseJSON (jsonPrefix "Swagger")
11091214
11101215instance FromJSON ParamLocation where
@@ -1169,8 +1274,19 @@ instance ToJSON OAuth2Flows where
11691274 toEncoding = sopSwaggerGenericToEncoding
11701275
11711276instance ToJSON SecuritySchemeType where
1172− toJSON SecuritySchemeHttp
1173− = object [ "type" .= ("http" :: Text) ]
1277+ toJSON (SecuritySchemeHttp ty) = case ty of
1278+ HttpSchemeBearer mFmt ->
1279+ object $ [ "type" .= ("http" :: Text)
1280+ , "scheme" .= ("bearer" :: Text)
1281+ ] <> maybe [] (\t -> ["bearerFormat" .= t]) mFmt
1282+ HttpSchemeBasic ->
1283+ object [ "type" .= ("http" :: Text)
1284+ , "scheme" .= ("basic" :: Text)
1285+ ]
1286+ HttpSchemeCustom t ->
1287+ object [ "type" .= ("http" :: Text)
1288+ , "scheme" .= t
1289+ ]
11741290 toJSON (SecuritySchemeApiKey params)
11751291 = toJSON params
11761292 <+> object [ "type" .= ("apiKey" :: Text) ]
@@ -1183,9 +1299,9 @@ instance ToJSON SecuritySchemeType where
11831299 , "openIdConnectUrl" .= url
11841300 ]
11851301
1186−instance ToJSON Swagger where
1302+instance ToJSON OpenApi where
11871303 toJSON a = sopSwaggerGenericToJSON a &
1188− if InsOrdHashMap.null (_swaggerPaths a)
1304+ if InsOrdHashMap.null (_openApiPaths a)
11891305 then (<+> object ["paths" .= object []])
11901306 else id
11911307 toEncoding = sopSwaggerGenericToEncoding
@@ -1199,8 +1315,8 @@ instance ToJSON SecurityScheme where
11991315 toEncoding = sopSwaggerGenericToEncoding
12001316
12011317instance ToJSON Schema where
1202− toJSON = sopSwaggerGenericToJSON
1203− toEncoding = sopSwaggerGenericToEncoding
1318+ toJSON = sopSwaggerGenericToJSONWithOpts $
1319+ mkSwaggerAesonOptions "schema" & saoSubObject ?~ "items"
12041320
12051321instance ToJSON Header where
12061322 toJSON = sopSwaggerGenericToJSON
@@ -1209,17 +1325,21 @@ instance ToJSON Header where
12091325-- | As for nullary schema for 0-arity type constructors, see
12101326-- <https://github.com/GetShopTV/swagger2/issues/167>.
12111327--
1212−-- >>> encode (SwaggerItemsArray [])
1213−-- "{\"example\":[],\"items\":{},\"maxItems\":0}"
1328+-- >>> BSL.putStrLn $ encodePretty (OpenApiItemsArray [])
1329+-- {
1330+-- "example": [],
1331+-- "items": {},
1332+-- "maxItems": 0
1333+-- }
12141334--
1215−instance ToJSON SwaggerItems where
1216− toJSON (SwaggerItemsObject x) = object [ "items" .= x ]
1217− toJSON (SwaggerItemsArray []) = object
1335+instance ToJSON OpenApiItems where
1336+ toJSON (OpenApiItemsObject x) = object [ "items" .= x ]
1337+ toJSON (OpenApiItemsArray []) = object
12181338 [ "items" .= object []
12191339 , "maxItems" .= (0 :: Int)
12201340 , "example" .= Array mempty
12211341 ]
1222− toJSON (SwaggerItemsArray x) = object [ "items" .= x ]
1342+ toJSON (OpenApiItemsArray x) = object [ "items" .= x ]
12231343
12241344instance ToJSON Components where
12251345 toJSON = sopSwaggerGenericToJSON
@@ -1264,6 +1384,10 @@ instance ToJSON Encoding where
12641384 toJSON = sopSwaggerGenericToJSON
12651385 toEncoding = sopSwaggerGenericToEncoding
12661386
1387+instance ToJSON Link where
1388+ toJSON = sopSwaggerGenericToJSON
1389+ toEncoding = sopSwaggerGenericToEncoding
1390+
12671391instance ToJSON SecurityDefinitions where
12681392 toJSON (SecurityDefinitions sd) = toJSON sd
12691393
@@ -1280,16 +1404,20 @@ instance ToJSON (Referenced Response) where toJSON = referencedToJSON "#/compone
12801404instance ToJSON (Referenced RequestBody) where toJSON = referencedToJSON "#/components/requestBodies/"
12811405instance ToJSON (Referenced Example) where toJSON = referencedToJSON "#/components/examples/"
12821406instance ToJSON (Referenced Header) where toJSON = referencedToJSON "#/components/headers/"
1283−
1284−instance ToJSON ParamSchema where
1285− -- TODO: this is a bit fishy, why we need sub object only in `ToJSON`?
1286− toJSON = sopSwaggerGenericToJSONWithOpts $
1287− mkSwaggerAesonOptions "paramSchema" & saoSubObject ?~ "items"
1407+instance ToJSON (Referenced Link) where toJSON = referencedToJSON "#/components/links/"
1408+instance ToJSON (Referenced Callback) where toJSON = referencedToJSON "#/components/callbacks/"
12881409
12891410instance ToJSON AdditionalProperties where
12901411 toJSON (AdditionalPropertiesAllowed b) = toJSON b
12911412 toJSON (AdditionalPropertiesSchema s) = toJSON s
12921413
1414+instance ToJSON ExpressionOrValue where
1415+ toJSON (Expression expr) = toJSON expr
1416+ toJSON (Value val) = toJSON val
1417+
1418+instance ToJSON Callback where
1419+ toJSON (Callback ps) = toJSON ps
1420+
12931421-- =======================================================================
12941422-- Manual FromJSON instances
12951423-- =======================================================================
@@ -1311,14 +1439,19 @@ instance FromJSON SecuritySchemeType where
13111439 parseJSON js@(Object o) = do
13121440 (t :: Text) <- o .: "type"
13131441 case t of
1314− "http" -> pure SecuritySchemeHttp
1442+ "http" -> do
1443+ scheme <- o .: "scheme"
1444+ SecuritySchemeHttp <$> case scheme of
1445+ "bearer" -> HttpSchemeBearer <$> (o .:! "bearerFormat")
1446+ "basic" -> pure HttpSchemeBasic
1447+ t -> pure $ HttpSchemeCustom t
13151448 "apiKey" -> SecuritySchemeApiKey <$> parseJSON js
13161449 "oauth2" -> SecuritySchemeOAuth2 <$> (o .: "flows")
13171450 "openIdConnect" -> SecuritySchemeOpenIdConnect <$> (o .: "openIdConnectUrl")
13181451 _ -> empty
13191452 parseJSON _ = empty
13201453
1321−instance FromJSON Swagger where
1454+instance FromJSON OpenApi where
13221455 parseJSON = sopSwaggerGenericParseJSON
13231456
13241457instance FromJSON Server where
@@ -1330,27 +1463,28 @@ instance FromJSON SecurityScheme where
13301463instance FromJSON Schema where
13311464 parseJSON = fmap nullaryCleanup . sopSwaggerGenericParseJSON
13321465 where nullaryCleanup :: Schema -> Schema
1333− nullaryCleanup s@Schema{_schemaParamSchema=ps} =
1334− if _paramSchemaItems ps == Just (SwaggerItemsArray [])
1466+ nullaryCleanup s =
1467+ if _schemaItems s == Just (OpenApiItemsArray [])
13351468 then s { _schemaExample = Nothing
1336− , _schemaParamSchema = ps { _paramSchemaMaxItems = Nothing } }
1469+ , _schemaMaxItems = Nothing
1470+ }
13371471 else s
13381472
13391473instance FromJSON Header where
13401474 parseJSON = sopSwaggerGenericParseJSON
13411475
1342−instance FromJSON SwaggerItems where
1476+instance FromJSON OpenApiItems where
13431477 parseJSON js@(Object obj)
1344− | null obj = pure $ SwaggerItemsArray [] -- Nullary schema.
1345− | otherwise = SwaggerItemsObject <$> parseJSON js
1346− parseJSON js@(Array _) = SwaggerItemsArray <$> parseJSON js
1478+ | null obj = pure $ OpenApiItemsArray [] -- Nullary schema.
1479+ | otherwise = OpenApiItemsObject <$> parseJSON js
1480+ parseJSON js@(Array _) = OpenApiItemsArray <$> parseJSON js
13471481 parseJSON _ = empty
13481482
13491483instance FromJSON Components where
13501484 parseJSON = sopSwaggerGenericParseJSON
13511485
13521486instance FromJSON MimeList where
1353− parseJSON js = (MimeList . map fromString) <$> parseJSON js
1487+ parseJSON js = MimeList . map fromString <$> parseJSON js
13541488
13551489instance FromJSON Param where
13561490 parseJSON = sopSwaggerGenericParseJSON
@@ -1358,7 +1492,7 @@ instance FromJSON Param where
13581492instance FromJSON Responses where
13591493 parseJSON (Object o) = Responses
13601494 <$> o .:? "default"
1361− <*> (parseJSON (Object (HashMap.delete "default" o)))
1495+ <*> parseJSON (Object (deleteKey "default" o))
13621496 parseJSON _ = empty
13631497
13641498instance FromJSON Example where
@@ -1385,6 +1519,9 @@ instance FromJSON MediaTypeObject where
13851519instance FromJSON Encoding where
13861520 parseJSON = sopSwaggerGenericParseJSON
13871521
1522+instance FromJSON Link where
1523+ parseJSON = sopSwaggerGenericParseJSON
1524+
13881525instance FromJSON Reference where
13891526 parseJSON (Object o) = Reference <$> o .: "$ref"
13901527 parseJSON _ = empty
@@ -1408,17 +1545,24 @@ instance FromJSON (Referenced Response) where parseJSON = referencedParseJSON "#
14081545instance FromJSON (Referenced RequestBody) where parseJSON = referencedParseJSON "#/components/requestBodies/"
14091546instance FromJSON (Referenced Example) where parseJSON = referencedParseJSON "#/components/examples/"
14101547instance FromJSON (Referenced Header) where parseJSON = referencedParseJSON "#/components/headers/"
1548+instance FromJSON (Referenced Link) where parseJSON = referencedParseJSON "#/components/links/"
1549+instance FromJSON (Referenced Callback) where parseJSON = referencedParseJSON "#/components/callbacks/"
14111550
14121551instance FromJSON Xml where
14131552 parseJSON = genericParseJSON (jsonPrefix "xml")
14141553
1415−instance FromJSON ParamSchema where
1416− parseJSON = sopSwaggerGenericParseJSON
1417−
14181554instance FromJSON AdditionalProperties where
14191555 parseJSON (Bool b) = pure $ AdditionalPropertiesAllowed b
14201556 parseJSON js = AdditionalPropertiesSchema <$> parseJSON js
14211557
1558+-- | All strings are parsed as expressions
1559+instance FromJSON ExpressionOrValue where
1560+ parseJSON (String expr) = pure $ Expression expr
1561+ parseJSON v = pure $ Value v
1562+
1563+instance FromJSON Callback where
1564+ parseJSON = fmap Callback . parseJSON
1565+
14221566instance HasSwaggerAesonOptions Server where
14231567 swaggerAesonOptions _ = mkSwaggerAesonOptions "server"
14241568instance HasSwaggerAesonOptions Components where
@@ -1447,19 +1591,18 @@ instance HasSwaggerAesonOptions SecurityScheme where
14471591 swaggerAesonOptions _ = mkSwaggerAesonOptions "securityScheme" & saoSubObject ?~ "type"
14481592instance HasSwaggerAesonOptions Schema where
14491593 swaggerAesonOptions _ = mkSwaggerAesonOptions "schema" & saoSubObject ?~ "paramSchema"
1450−instance HasSwaggerAesonOptions Swagger where
1594+instance HasSwaggerAesonOptions OpenApi where
14511595 swaggerAesonOptions _ = mkSwaggerAesonOptions "swagger" & saoAdditionalPairs .~ [("openapi", "3.0.0")]
14521596instance HasSwaggerAesonOptions Example where
14531597 swaggerAesonOptions _ = mkSwaggerAesonOptions "example"
14541598instance HasSwaggerAesonOptions Encoding where
14551599 swaggerAesonOptions _ = mkSwaggerAesonOptions "encoding"
14561600
1457−instance HasSwaggerAesonOptions ParamSchema where
1458− swaggerAesonOptions _ = mkSwaggerAesonOptions "paramSchema"
1601+instance HasSwaggerAesonOptions Link where
1602+ swaggerAesonOptions _ = mkSwaggerAesonOptions "link"
14591603
14601604instance AesonDefaultValue Server
14611605instance AesonDefaultValue Components
1462−instance AesonDefaultValue ParamSchema
14631606instance AesonDefaultValue OAuth2ImplicitFlow
14641607instance AesonDefaultValue OAuth2PasswordFlow
14651608instance AesonDefaultValue OAuth2ClientCredentialsFlow
@@ -1467,7 +1610,10 @@ instance AesonDefaultValue OAuth2AuthorizationCodeFlow
14671610instance AesonDefaultValue p => AesonDefaultValue (OAuth2Flow p)
14681611instance AesonDefaultValue Responses
14691612instance AesonDefaultValue SecuritySchemeType
1470−instance AesonDefaultValue SwaggerType
1613+instance AesonDefaultValue OpenApiType
14711614instance AesonDefaultValue MimeList where defaultValue = Just mempty
14721615instance AesonDefaultValue Info
14731616instance AesonDefaultValue ParamLocation
1617+instance AesonDefaultValue Link
1618+instance AesonDefaultValue SecurityDefinitions where
1619+ defaultValue = Just mempty