packages feed

json-spec-openapi 0.2.1.1 → 0.3.0.0

raw patch · 4 files changed

+104/−62 lines, 4 filesdep ~json-specPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: json-spec

API changes (from Hackage documentation)

- Data.JsonSpec.OpenApi: instance (Data.JsonSpec.OpenApi.Schemaable ('Data.JsonSpec.Spec.JsonObject more), Data.JsonSpec.OpenApi.Refable spec, GHC.TypeLits.KnownSymbol key) => Data.JsonSpec.OpenApi.Schemaable ('Data.JsonSpec.Spec.JsonObject ('(key, spec) : more))
+ Data.JsonSpec.OpenApi: instance (Data.JsonSpec.OpenApi.Schemaable ('Data.JsonSpec.Spec.JsonObject more), Data.JsonSpec.OpenApi.Refable spec, GHC.TypeLits.KnownSymbol key) => Data.JsonSpec.OpenApi.Schemaable ('Data.JsonSpec.Spec.JsonObject ('Data.JsonSpec.Spec.Optional key spec : more))
+ Data.JsonSpec.OpenApi: instance (Data.JsonSpec.OpenApi.Schemaable ('Data.JsonSpec.Spec.JsonObject more), Data.JsonSpec.OpenApi.Refable spec, GHC.TypeLits.KnownSymbol key) => Data.JsonSpec.OpenApi.Schemaable ('Data.JsonSpec.Spec.JsonObject ('Data.JsonSpec.Spec.Required key spec : more))

Files

README.md view
@@ -12,18 +12,18 @@ ```haskell data User = User   {      name :: Text-  , lastLogin :: UTCTime+  , lastLogin :: Maybe UTCTime   }   deriving ToSchema via (EncodingSchema User) -- <-- ToSchema instance defined here instance HasJsonEncodingSpec User where   type EncodingSpec User =     JsonObject-      '[ '("name", JsonString)-       , '("last-login", JsonDateTime)+      '[ Required "name" JsonString+       , Optional "last-login" JsonDateTime        ]   toJSONStructure user =     (Field @"name" (name user),-    (Field @"last-login" (lastLogin user),+    (fmap (Field @"last-login") (lastLogin user),     ())) ``` @@ -43,8 +43,7 @@     }   },   "required": [-    "name",-    "last-login"+    "name"   ],   "type": "object" }
json-spec-openapi.cabal view
@@ -1,6 +1,6 @@ cabal-version:       3.0 name:                json-spec-openapi-version:             0.2.1.1+version:             0.3.0.0 synopsis:            json-spec-openapi description:   This package provides a way to produce@@ -14,18 +14,18 @@    > data User = User   >   {      name :: Text-  >   , lastLogin :: UTCTime+  >   , lastLogin :: Maybe UTCTime   >   }   >   deriving ToSchema via (EncodingSchema User) -- <-- ToSchema instance defined here   > instance HasJsonEncodingSpec User where   >   type EncodingSpec User =   >     JsonObject-  >       '[ '("name", JsonString)-  >        , '("last-login", JsonDateTime)+  >       '[ Required "name" JsonString+  >        , Optional "last-login" JsonDateTime   >        ]   >   toJSONStructure user =   >     (Field @"name" (name user),-  >     (Field @"last-login" (lastLogin user),+  >     (fmap (Field @"last-login") (lastLogin user),   >     ()))    Calling `Data.Aeson.encode (Data.OpenApi3.toSchema (Proxy :: Proxy User))`@@ -43,8 +43,7 @@   >     }   >   },   >   "required": [-  >     "name",-  >     "last-login"+  >     "name"   >   ],   >   "type": "object"   > }@@ -65,7 +64,7 @@     , aeson                     >= 2.2.1.0  && < 2.3     , base                      >= 4.19.0.0 && < 4.20     , insert-ordered-containers >= 0.2.5.3  && < 0.3-    , json-spec                 >= 0.2.1.3  && < 0.3+    , json-spec                 >= 0.3.0.0  && < 0.4     , lens                      >= 5.2.3    && < 5.3     , openapi3                  >= 3.2.4    && < 3.3     , text                      >= 2.1      && < 2.2
src/Data/JsonSpec/OpenApi.hs view
@@ -25,18 +25,18 @@    > data User = User   >   {      name :: Text-  >   , lastLogin :: UTCTime+  >   , lastLogin :: Maybe UTCTime   >   }   >   deriving ToSchema via (EncodingSchema User) -- <-- ToSchema instance defined here   > instance HasJsonEncodingSpec User where   >   type EncodingSpec User =   >     JsonObject-  >       '[ '("name", JsonString)-  >        , '("last-login", JsonDateTime)+  >       '[ Required "name" JsonString+  >        , Optional "last-login" JsonDateTime   >        ]   >   toJSONStructure user =   >     (Field @"name" (name user),-  >     (Field @"last-login" (lastLogin user),+  >     (fmap (Field @"last-login") (lastLogin user),   >     ()))    Calling @'Data.Aeson.encode' ('Data.OpenApi3.toSchema' ('Proxy' :: 'Proxy' User))@@@ -54,8 +54,7 @@   >     }   >   },   >   "required": [-  >     "name",-  >     "last-login"+  >     "name"   >   ],   >   "type": "object"   > }@@ -66,17 +65,17 @@    > data User = User   >   {      name :: Text-  >   , lastLogin :: UTCTime+  >   , lastLogin :: Maybe UTCTime   >   }   > instance HasJsonEncodingSpec User where   >   type EncodingSpec User =   >     JsonObject-  >       '[ '("name", JsonString)-  >        , '("last-login", JsonDateTime)+  >       '[ Required "name" JsonString+  >        , Optional "last-login" JsonDateTime   >        ]   >   toJSONStructure user =   >     (Field @"name" (name user),-  >     (Field @"last-login" (lastLogin user),+  >     (fmap (Field @"last-login") (lastLogin user),   >     ()))   > instance ToSchema User where   >   declareNamedSchema _proxy =@@ -102,10 +101,11 @@ import Control.Lens (At(at), (&), over, set) import Data.Aeson (ToJSON(toJSON)) import Data.Functor.Identity (Identity(runIdentity))-import Data.JsonSpec (HasJsonDecodingSpec(DecodingSpec),-  HasJsonEncodingSpec(EncodingSpec), Specification(JsonArray, JsonBool,-  JsonDateTime, JsonEither, JsonInt, JsonLet, JsonNullable, JsonNum,-  JsonObject, JsonRef, JsonString, JsonTag))+import Data.JsonSpec (FieldSpec(Optional, Required),+  HasJsonDecodingSpec(DecodingSpec), HasJsonEncodingSpec(EncodingSpec),+  Specification(JsonArray, JsonBool, JsonDateTime, JsonEither, JsonInt,+  JsonLet, JsonNullable, JsonNum, JsonObject, JsonRef, JsonString,+  JsonTag)) import Data.OpenApi (AdditionalProperties(AdditionalPropertiesAllowed),   HasAdditionalProperties(additionalProperties), HasEnum(enum_),   HasFormat(format), HasItems(items), HasOneOf(oneOf),@@ -277,27 +277,36 @@       mempty         & set type_ (Just OpenApiObject)         & set additionalProperties (Just (AdditionalPropertiesAllowed False))-instance {- Schemaable ('JsonObject ( '(key, spec) : more )) -}+instance {- Schemaable ('JsonObject ( Optional key spec : more )) -}     ( Schemaable ('JsonObject more)     , Refable spec     , KnownSymbol key     )   =>-    Schemaable ('JsonObject ( '(key, spec) : more ))+    Schemaable ('JsonObject ( Optional key spec : more ))   where     schemaable Proxy = do-      let-        propertyName :: Text-        propertyName = sym @key-       propertySchema <- refable (Proxy @spec)       more <- schemaable (Proxy @('JsonObject more))       pure $         more           & over               properties-              (set (at propertyName) (Just propertySchema))-          & over required (propertyName:)+              (set (at (sym @key)) (Just propertySchema))+instance {- Schemaable ('JsonObject ( Required key spec : more )) -}+    ( Schemaable ('JsonObject more)+    , Refable spec+    , KnownSymbol key+    )+  =>+    Schemaable (JsonObject ( Required key spec : more ))+  where+    schemaable Proxy = do+      schema <- schemaable (Proxy @(JsonObject ( Optional key spec : more )))+      pure $+        schema+          & over required (sym @key:)+ instance (Schemaable spec) => Schemaable ('JsonArray spec) where   schemaable Proxy = do     elementSchema <- schemaable (Proxy @spec)
test/test.hs view
@@ -8,23 +8,25 @@ {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE ViewPatterns #-}  module Main (main) where  import Control.Lens (At(at), (&), set) import Data.Aeson (ToJSON(toJSON), FromJSON, encode)-import Data.JsonSpec (Field(Field), HasJsonDecodingSpec(DecodingSpec,-  fromJSONStructure), HasJsonEncodingSpec(EncodingSpec, toJSONStructure),-  SpecJSON(SpecJSON), Specification(JsonArray, JsonBool, JsonDateTime,-  JsonEither, JsonInt, JsonLet, JsonNullable, JsonNum, JsonObject,-  JsonRef, JsonString, JsonTag))+import Data.JsonSpec (Field(Field, unField), FieldSpec(Optional,+  Required), HasJsonDecodingSpec(DecodingSpec, fromJSONStructure),+  HasJsonEncodingSpec(EncodingSpec, toJSONStructure), SpecJSON(SpecJSON),+  Specification(JsonArray, JsonBool, JsonDateTime, JsonEither, JsonInt,+  JsonLet, JsonNullable, JsonNum, JsonObject, JsonRef, JsonString,+  JsonTag)) import Data.JsonSpec.OpenApi (EncodingSchema, toOpenApiSchema) import Data.OpenApi (Definitions, ToSchema) import Data.Proxy (Proxy(Proxy)) import Data.Text (Text) import Data.Time (UTCTime)-import Prelude (Applicative(pure), Bool(False), Maybe(Just),-  Monoid(mempty), ($), Eq, IO, Show)+import Prelude (Applicative(pure), Bool(False), Functor(fmap),+  Maybe(Just), Monoid(mempty), ($), Eq, IO, Show) import Test.Hspec (describe, hspec, it, shouldBe) import qualified Data.HashMap.Strict.InsOrd as HMI import qualified Data.OpenApi as OA@@ -52,14 +54,14 @@               JsonEither                 (                   JsonObject-                    '[ '("tag", JsonTag "a")-                     , '("content", JsonString)+                    '[ Required "tag" (JsonTag "a")+                     , Required "content" JsonString                      ]                 )                 (                   JsonObject-                    '[ '("tag", JsonTag "b")-                     , '("content", JsonString)+                    '[ Required "tag" (JsonTag "b")+                     , Required "content" JsonString                      ]                 )             ))@@ -109,8 +111,8 @@           actual =             toOpenApiSchema (Proxy @(               JsonObject '[-                '("Foo", JsonString),-                '("Bar", JsonString)+                Required "Foo" JsonString,+                Required "Bar" JsonString               ]             )) @@ -149,8 +151,8 @@             toOpenApiSchema (Proxy @(               JsonArray (                 JsonObject '[-                  '("Foo", JsonString),-                  '("Bar", JsonString)+                  Required "Foo" JsonString,+                  Required "Bar" JsonString                 ]               )             ))@@ -213,6 +215,35 @@         in           encode actual `shouldBe` encode expected +      it "optional" $+        let+          actual :: (Definitions OA.Schema, OA.Schema)+          actual =+            toOpenApiSchema (Proxy @(+              JsonObject '[+                Required "foo" JsonString,+                Optional "bar" JsonString+              ]+            ))++          expected :: (Definitions OA.Schema, OA.Schema)+          expected =+            ( mempty+            , mempty+                & set OA.type_ (Just OA.OpenApiObject)+                & set OA.properties (+                    mempty+                      & set (at "foo") (Just (OA.Inline stringSchema))+                      & set (at "bar") (Just (OA.Inline stringSchema))+                  )+                & set OA.required ["foo"]+                & set+                    OA.additionalProperties+                    (Just (OA.AdditionalPropertiesAllowed False))+            )+        in+          encode actual `shouldBe` encode expected+       it "date-time" $         let           actual :: (Definitions OA.Schema, OA.Schema)@@ -237,7 +268,7 @@               ]               (                 JsonObject '[-                  '("foo", JsonRef "thing")+                  Required "foo" (JsonRef "thing")                 ]               )             ))@@ -285,11 +316,11 @@           actual =             toOpenApiSchema (Proxy @(               JsonObject '[-                '("foo",+                Required "foo" (                   JsonLet                     '[ '("thing", JsonString)]                     (JsonRef "thing")-                 )+                )               ]             )) @@ -310,7 +341,7 @@         in           actual `shouldBe` expected -    describe "EncodingSpec" $+    describe "EncodingSchema" $       it "works" $         let           actual :: OA.Schema@@ -325,7 +356,7 @@                     & set (at "name") (Just (OA.Inline stringSchema))                     & set (at "last-login") (Just (OA.Inline dateSchema))                 )-              & set OA.required ["name", "last-login"]+              & set OA.required ["name"]               & set                   OA.additionalProperties                   (Just (OA.AdditionalPropertiesAllowed False))@@ -334,28 +365,32 @@           encode actual `shouldBe` encode expected  +{-+  This is the example used in the docs. If you update it, then update+  the docs as well.+-} data User = User   {      name :: Text-  , lastLogin :: UTCTime+  , lastLogin :: Maybe UTCTime   }   deriving stock (Show, Eq)-  deriving ToSchema via (EncodingSchema User)+  deriving ToSchema via (EncodingSchema User) -- <-- ToSchema instance defined here   deriving (ToJSON, FromJSON) via (SpecJSON User) instance HasJsonEncodingSpec User where   type EncodingSpec User =     JsonObject-      '[ '("name", JsonString)-       , '("last-login", JsonDateTime)+      '[ Required "name" JsonString+       , Optional "last-login" JsonDateTime        ]   toJSONStructure user =     (Field @"name" (name user),-    (Field @"last-login" (lastLogin user),+    (fmap (Field @"last-login") (lastLogin user),     ())) instance HasJsonDecodingSpec User where   type DecodingSpec User = EncodingSpec User   fromJSONStructure       (Field @"name" name,-      (Field @"last-login" lastLogin,+      (fmap (unField @"last-login") ->  lastLogin,       ()))     =       pure User { name , lastLogin }