From 9644e2df8d6020194a77cda55f13d01be2d5e83b Mon Sep 17 00:00:00 2001 From: Owen Harvey Date: Tue, 5 Sep 2023 16:00:01 +1000 Subject: [PATCH 01/15] WPB-4240: Initial work on the bulk of the updates. Now onto harder parts. --- libs/brig-types/brig-types.cabal | 2 +- libs/brig-types/default.nix | 4 +- .../test/unit/Test/Brig/Roundtrip.hs | 2 +- libs/deriving-swagger2/default.nix | 4 +- .../deriving-swagger2/deriving-swagger2.cabal | 4 +- .../deriving-swagger2/src/Deriving/Swagger.hs | 8 ++-- libs/extended/default.nix | 4 +- libs/extended/extended.cabal | 2 +- libs/extended/src/Servant/API/Extended.hs | 8 ++-- .../extended/src/Servant/API/Extended/RawM.hs | 6 +-- libs/schema-profunctor/default.nix | 6 +-- .../schema-profunctor/schema-profunctor.cabal | 6 +-- libs/schema-profunctor/src/Data/Schema.hs | 27 ++++++----- .../test/unit/Test/Data/Schema.hs | 10 ++-- libs/types-common/default.nix | 4 +- libs/types-common/src/Data/Code.hs | 4 +- .../src/Data/CommaSeparatedList.hs | 6 +-- libs/types-common/src/Data/Domain.hs | 2 +- libs/types-common/src/Data/Handle.hs | 2 +- libs/types-common/src/Data/Id.hs | 4 +- libs/types-common/src/Data/Json/Util.hs | 8 ++-- libs/types-common/src/Data/LegalHold.hs | 2 +- libs/types-common/src/Data/List1.hs | 6 +-- libs/types-common/src/Data/Misc.hs | 8 ++-- libs/types-common/src/Data/Nonce.hs | 4 +- libs/types-common/src/Data/Qualified.hs | 4 +- libs/types-common/src/Data/Range.hs | 10 ++-- libs/types-common/src/Data/Text/Ascii.hs | 4 +- libs/types-common/types-common.cabal | 2 +- libs/wai-utilities/default.nix | 4 +- .../src/Network/Wai/Utilities/Headers.hs | 2 +- libs/wai-utilities/wai-utilities.cabal | 2 +- libs/wire-api-federation/default.nix | 4 +- .../src/Wire/API/Federation/Version.hs | 2 +- .../wire-api-federation.cabal | 2 +- libs/wire-api/default.nix | 10 ++-- libs/wire-api/src/Wire/API/Asset.hs | 2 +- libs/wire-api/src/Wire/API/Call/Config.hs | 2 +- libs/wire-api/src/Wire/API/Connection.hs | 4 +- libs/wire-api/src/Wire/API/Conversation.hs | 2 +- .../src/Wire/API/Conversation/Action.hs | 2 +- .../wire-api/src/Wire/API/Conversation/Bot.hs | 2 +- .../src/Wire/API/Conversation/Code.hs | 2 +- .../src/Wire/API/Conversation/Member.hs | 2 +- .../src/Wire/API/Conversation/Role.hs | 2 +- .../src/Wire/API/Conversation/Typing.hs | 2 +- libs/wire-api/src/Wire/API/CustomBackend.hs | 2 +- libs/wire-api/src/Wire/API/Error.hs | 21 +++++---- libs/wire-api/src/Wire/API/Error/Empty.hs | 2 +- libs/wire-api/src/Wire/API/Error/Galley.hs | 2 +- .../src/Wire/API/Event/Conversation.hs | 2 +- .../src/Wire/API/Event/FeatureConfig.hs | 2 +- .../wire-api/src/Wire/API/Event/Federation.hs | 2 +- libs/wire-api/src/Wire/API/Event/Team.hs | 2 +- .../wire-api/src/Wire/API/FederationStatus.hs | 2 +- .../src/Wire/API/Internal/BulkPush.hs | 2 +- .../src/Wire/API/Internal/Notification.hs | 2 +- libs/wire-api/src/Wire/API/MLS/CipherSuite.hs | 4 +- .../wire-api/src/Wire/API/MLS/CommitBundle.hs | 2 +- libs/wire-api/src/Wire/API/MLS/Credential.hs | 6 +-- libs/wire-api/src/Wire/API/MLS/Group.hs | 2 +- libs/wire-api/src/Wire/API/MLS/KeyPackage.hs | 2 +- libs/wire-api/src/Wire/API/MLS/Keys.hs | 2 +- libs/wire-api/src/Wire/API/MLS/Message.hs | 2 +- .../src/Wire/API/MLS/PublicGroupState.hs | 2 +- .../src/Wire/API/MLS/Serialisation.hs | 2 +- .../src/Wire/API/MLS/SubConversation.hs | 2 +- libs/wire-api/src/Wire/API/MLS/Welcome.hs | 2 +- .../src/Wire/API/MakesFederatedCall.hs | 11 +++-- libs/wire-api/src/Wire/API/Message.hs | 6 +-- libs/wire-api/src/Wire/API/Notification.hs | 4 +- libs/wire-api/src/Wire/API/OAuth.hs | 6 +-- libs/wire-api/src/Wire/API/Properties.hs | 2 +- libs/wire-api/src/Wire/API/Provider/Bot.hs | 2 +- .../wire-api/src/Wire/API/Provider/Service.hs | 2 +- libs/wire-api/src/Wire/API/Push/V2/Token.hs | 4 +- libs/wire-api/src/Wire/API/RawJson.hs | 2 +- libs/wire-api/src/Wire/API/Routes/API.hs | 8 ++-- .../wire-api/src/Wire/API/Routes/AssetBody.hs | 6 +-- libs/wire-api/src/Wire/API/Routes/Bearer.hs | 10 ++-- libs/wire-api/src/Wire/API/Routes/Cookies.hs | 6 +-- .../Wire/API/Routes/FederationDomainConfig.hs | 2 +- .../src/Wire/API/Routes/Internal/Brig.hs | 8 ++-- .../API/Routes/Internal/Brig/Connection.hs | 2 +- .../src/Wire/API/Routes/Internal/Brig/EJPD.hs | 2 +- .../Wire/API/Routes/Internal/Brig/OAuth.hs | 2 +- .../API/Routes/Internal/Brig/SearchIndex.hs | 2 +- .../src/Wire/API/Routes/Internal/Cannon.hs | 4 +- .../src/Wire/API/Routes/Internal/Cargohold.hs | 4 +- .../src/Wire/API/Routes/Internal/Galley.hs | 4 +- .../Internal/Galley/ConversationsIntra.hs | 2 +- .../Galley/TeamFeatureNoConfigMulti.hs | 2 +- .../API/Routes/Internal/Galley/TeamsIntra.hs | 2 +- .../src/Wire/API/Routes/Internal/LegalHold.hs | 9 ++-- .../src/Wire/API/Routes/Internal/Spar.hs | 4 +- .../src/Wire/API/Routes/LowLevelStream.hs | 11 +++-- .../src/Wire/API/Routes/MultiTablePaging.hs | 2 +- .../Wire/API/Routes/MultiTablePaging/State.hs | 2 +- .../wire-api/src/Wire/API/Routes/MultiVerb.hs | 46 ++++++++++--------- libs/wire-api/src/Wire/API/Routes/Named.hs | 11 +++-- libs/wire-api/src/Wire/API/Routes/Public.hs | 28 +++++------ .../src/Wire/API/Routes/Public/Brig.hs | 6 +-- .../src/Wire/API/Routes/Public/Brig/Bot.hs | 2 +- .../src/Wire/API/Routes/Public/Brig/OAuth.hs | 2 +- .../src/Wire/API/Routes/Public/Cargohold.hs | 2 +- .../src/Wire/API/Routes/Public/Galley.hs | 2 +- .../src/Wire/API/Routes/Public/Galley/Bot.hs | 2 +- .../API/Routes/Public/Galley/Conversation.hs | 2 +- .../API/Routes/Public/Galley/CustomBackend.hs | 2 +- .../Wire/API/Routes/Public/Galley/Feature.hs | 2 +- .../API/Routes/Public/Galley/LegalHold.hs | 2 +- .../src/Wire/API/Routes/Public/Galley/MLS.hs | 2 +- .../API/Routes/Public/Galley/Messaging.hs | 2 +- .../src/Wire/API/Routes/Public/Galley/Team.hs | 2 +- .../Routes/Public/Galley/TeamConversation.hs | 2 +- .../API/Routes/Public/Galley/TeamMember.hs | 2 +- .../src/Wire/API/Routes/Public/Spar.hs | 2 +- .../src/Wire/API/Routes/Public/Util.hs | 2 +- .../src/Wire/API/Routes/QualifiedCapture.hs | 10 ++-- libs/wire-api/src/Wire/API/Routes/Version.hs | 2 +- .../wire-api/src/Wire/API/Routes/Versioned.hs | 12 ++--- .../wire-api/src/Wire/API/Routes/WebSocket.hs | 8 ++-- libs/wire-api/src/Wire/API/ServantProto.hs | 2 +- libs/wire-api/src/Wire/API/SwaggerHelper.hs | 4 +- libs/wire-api/src/Wire/API/SwaggerServant.hs | 6 +-- libs/wire-api/src/Wire/API/SystemSettings.hs | 4 +- libs/wire-api/src/Wire/API/Team.hs | 2 +- .../src/Wire/API/Team/Conversation.hs | 2 +- libs/wire-api/src/Wire/API/Team/Feature.hs | 2 +- libs/wire-api/src/Wire/API/Team/Invitation.hs | 2 +- libs/wire-api/src/Wire/API/Team/LegalHold.hs | 2 +- .../src/Wire/API/Team/LegalHold/External.hs | 2 +- .../src/Wire/API/Team/LegalHold/Internal.hs | 2 +- libs/wire-api/src/Wire/API/Team/Member.hs | 4 +- libs/wire-api/src/Wire/API/Team/Permission.hs | 2 +- libs/wire-api/src/Wire/API/Team/Role.hs | 2 +- .../src/Wire/API/Team/SearchVisibility.hs | 2 +- libs/wire-api/src/Wire/API/Team/Size.hs | 2 +- libs/wire-api/src/Wire/API/Unreachable.hs | 2 +- libs/wire-api/src/Wire/API/User.hs | 2 +- libs/wire-api/src/Wire/API/User/Activation.hs | 4 +- libs/wire-api/src/Wire/API/User/Auth.hs | 4 +- .../src/Wire/API/User/Auth/LegalHold.hs | 2 +- .../wire-api/src/Wire/API/User/Auth/ReAuth.hs | 2 +- libs/wire-api/src/Wire/API/User/Auth/Sso.hs | 2 +- libs/wire-api/src/Wire/API/User/Client.hs | 4 +- .../Wire/API/User/Client/DPoPAccessToken.hs | 4 +- .../src/Wire/API/User/Client/Prekey.hs | 2 +- libs/wire-api/src/Wire/API/User/Handle.hs | 2 +- libs/wire-api/src/Wire/API/User/Identity.hs | 4 +- .../src/Wire/API/User/IdentityProvider.hs | 2 +- libs/wire-api/src/Wire/API/User/Orphans.hs | 8 ++-- libs/wire-api/src/Wire/API/User/Password.hs | 4 +- libs/wire-api/src/Wire/API/User/Profile.hs | 2 +- libs/wire-api/src/Wire/API/User/RichInfo.hs | 2 +- libs/wire-api/src/Wire/API/User/Saml.hs | 2 +- libs/wire-api/src/Wire/API/User/Scim.hs | 2 +- libs/wire-api/src/Wire/API/User/Search.hs | 4 +- libs/wire-api/src/Wire/API/UserMap.hs | 2 +- libs/wire-api/src/Wire/API/Wrapped.hs | 2 +- .../unit/Test/Wire/API/Roundtrip/Aeson.hs | 2 +- .../test/unit/Test/Wire/API/Swagger.hs | 2 +- libs/wire-api/wire-api.cabal | 6 +-- nix/haskell-pins.nix | 7 --- nix/manual-overrides.nix | 1 - services/brig/brig.cabal | 4 +- services/brig/default.nix | 8 ++-- services/brig/src/Brig/API/Internal.hs | 2 +- services/brig/src/Brig/API/Public.hs | 4 +- services/brig/src/Brig/API/Public/Swagger.hs | 6 +-- services/brig/src/Brig/User/EJPD.hs | 2 +- services/spar/default.nix | 8 ++-- services/spar/spar.cabal | 4 +- services/spar/test/Arbitrary.hs | 2 +- services/spar/test/Test/Spar/APISpec.hs | 2 +- tools/fedcalls/default.nix | 4 +- tools/fedcalls/fedcalls.cabal | 2 +- tools/fedcalls/src/Main.hs | 2 +- tools/stern/default.nix | 8 ++-- tools/stern/src/Stern/API/Routes.hs | 6 +-- tools/stern/src/Stern/Types.hs | 2 +- tools/stern/stern.cabal | 5 +- 182 files changed, 382 insertions(+), 381 deletions(-) diff --git a/libs/brig-types/brig-types.cabal b/libs/brig-types/brig-types.cabal index fb0afa4af77..0a00f68eff4 100644 --- a/libs/brig-types/brig-types.cabal +++ b/libs/brig-types/brig-types.cabal @@ -156,8 +156,8 @@ test-suite brig-types-tests , brig-types , bytestring-conversion >=0.3.1 , imports + , openapi3 >=3.2 && <3.2.3 , QuickCheck >=2.9 - , swagger2 >=2.5 , tasty , tasty-hunit , tasty-quickcheck diff --git a/libs/brig-types/default.nix b/libs/brig-types/default.nix index 49028b0de48..173b83591b0 100644 --- a/libs/brig-types/default.nix +++ b/libs/brig-types/default.nix @@ -13,8 +13,8 @@ , gitignoreSource , imports , lib +, openapi3 , QuickCheck -, swagger2 , tasty , tasty-hunit , tasty-quickcheck @@ -47,8 +47,8 @@ mkDerivation { base bytestring-conversion imports + openapi3 QuickCheck - swagger2 tasty tasty-hunit tasty-quickcheck diff --git a/libs/brig-types/test/unit/Test/Brig/Roundtrip.hs b/libs/brig-types/test/unit/Test/Brig/Roundtrip.hs index 9ea421c6c2f..5e4ada038e8 100644 --- a/libs/brig-types/test/unit/Test/Brig/Roundtrip.hs +++ b/libs/brig-types/test/unit/Test/Brig/Roundtrip.hs @@ -20,7 +20,7 @@ module Test.Brig.Roundtrip where import Data.Aeson (FromJSON, ToJSON, parseJSON, toJSON) import Data.Aeson.Types (parseEither) import Data.ByteString.Conversion -import Data.Swagger (ToSchema, validatePrettyToJSON) +import Data.OpenApi (ToSchema, validatePrettyToJSON) import Imports import Test.Tasty (TestTree) import Test.Tasty.QuickCheck (Arbitrary, counterexample, testProperty, (.&&.), (===)) diff --git a/libs/deriving-swagger2/default.nix b/libs/deriving-swagger2/default.nix index fdf39de254a..5359dbec579 100644 --- a/libs/deriving-swagger2/default.nix +++ b/libs/deriving-swagger2/default.nix @@ -8,12 +8,12 @@ , gitignoreSource , imports , lib -, swagger2 +, openapi3 }: mkDerivation { pname = "deriving-swagger2"; version = "0.1.0"; src = gitignoreSource ./.; - libraryHaskellDepends = [ base extra imports swagger2 ]; + libraryHaskellDepends = [ base extra imports openapi3 ]; license = lib.licenses.agpl3Only; } diff --git a/libs/deriving-swagger2/deriving-swagger2.cabal b/libs/deriving-swagger2/deriving-swagger2.cabal index 4d68184d8c4..b4aff6eb7be 100644 --- a/libs/deriving-swagger2/deriving-swagger2.cabal +++ b/libs/deriving-swagger2/deriving-swagger2.cabal @@ -62,9 +62,9 @@ library -Wredundant-constraints -Wunused-packages build-depends: - base >=4 && <5 + base >=4 && <5 , extra , imports - , swagger2 >=0.6 + , openapi3 >=3.2.0 && <3.2.3 default-language: GHC2021 diff --git a/libs/deriving-swagger2/src/Deriving/Swagger.hs b/libs/deriving-swagger2/src/Deriving/Swagger.hs index 3f0fc3b56f9..eac90ab583b 100644 --- a/libs/deriving-swagger2/src/Deriving/Swagger.hs +++ b/libs/deriving-swagger2/src/Deriving/Swagger.hs @@ -22,10 +22,10 @@ module Deriving.Swagger where import Data.Char qualified as Char import Data.Kind (Constraint) import Data.List.Extra (stripSuffix) +import Data.OpenApi (SchemaOptions, ToSchema (..), constructorTagModifier, defaultSchemaOptions, fieldLabelModifier, genericDeclareNamedSchema) +import Data.OpenApi.Internal.Schema (GToSchema) +import Data.OpenApi.Internal.TypeShape (TypeHasSimpleShape) import Data.Proxy (Proxy (..)) -import Data.Swagger (SchemaOptions, ToSchema (..), constructorTagModifier, defaultSchemaOptions, fieldLabelModifier, genericDeclareNamedSchema) -import Data.Swagger.Internal.Schema (GToSchema) -import Data.Swagger.Internal.TypeShape (TypeHasSimpleShape) import GHC.Generics (Generic (Rep)) import GHC.TypeLits (ErrorMessage (Text), KnownSymbol, Symbol, TypeError, symbolVal) import Imports @@ -96,6 +96,8 @@ instance (StringModifier f, SwaggerOptions xs) => SwaggerOptions (ConstructorTag instance ( SwaggerOptions t, + Typeable t, + Typeable a, Generic a, GToSchema (Rep a), TypeHasSimpleShape a "genericDeclareNamedSchemaUnrestricted" diff --git a/libs/extended/default.nix b/libs/extended/default.nix index d2fd00ab9cb..b44a955a35f 100644 --- a/libs/extended/default.nix +++ b/libs/extended/default.nix @@ -27,8 +27,8 @@ , servant , servant-client , servant-client-core +, servant-openapi3 , servant-server -, servant-swagger , temporary , text , tinylog @@ -60,8 +60,8 @@ mkDerivation { servant servant-client servant-client-core + servant-openapi3 servant-server - servant-swagger text tinylog unliftio diff --git a/libs/extended/extended.cabal b/libs/extended/extended.cabal index 2271f8d1312..389b59b9447 100644 --- a/libs/extended/extended.cabal +++ b/libs/extended/extended.cabal @@ -98,8 +98,8 @@ library , servant , servant-client , servant-client-core + , servant-openapi3 , servant-server - , servant-swagger , text , tinylog , unliftio diff --git a/libs/extended/src/Servant/API/Extended.hs b/libs/extended/src/Servant/API/Extended.hs index 322b029f1b4..c1e87f38beb 100644 --- a/libs/extended/src/Servant/API/Extended.hs +++ b/libs/extended/src/Servant/API/Extended.hs @@ -31,8 +31,8 @@ import Network.Wai import Servant.API import Servant.API.ContentTypes import Servant.API.Modifiers +import Servant.OpenApi import Servant.Server.Internal -import Servant.Swagger import Prelude () -- | Like 'ReqBody'', but takes parsers that throw 'ServerError', not 'String'. @tag@ is used @@ -108,10 +108,10 @@ instance Right v -> pure v instance - HasSwagger (ReqBody' '[Required, Strict] cts a :> api) => - HasSwagger (ReqBodyCustomError cts tag a :> api) + HasOpenApi (ReqBody' '[Required, Strict] cts a :> api) => + HasOpenApi (ReqBodyCustomError cts tag a :> api) where - toSwagger Proxy = toSwagger (Proxy @(ReqBody' '[Required, Strict] cts a :> api)) + toOpenApi Proxy = toOpenApi (Proxy @(ReqBody' '[Required, Strict] cts a :> api)) instance RoutesToPaths rest => RoutesToPaths (ReqBodyCustomError' mods list tag a :> rest) where getRoutes = getRoutes @rest diff --git a/libs/extended/src/Servant/API/Extended/RawM.hs b/libs/extended/src/Servant/API/Extended/RawM.hs index 9f1e1a6395f..f5108d12329 100644 --- a/libs/extended/src/Servant/API/Extended/RawM.hs +++ b/libs/extended/src/Servant/API/Extended/RawM.hs @@ -10,11 +10,11 @@ import Data.Proxy import Imports import Network.Wai import Servant.API (Raw) +import Servant.OpenApi import Servant.Server hiding (respond) import Servant.Server.Internal.Delayed import Servant.Server.Internal.RouteResult import Servant.Server.Internal.Router -import Servant.Swagger type ApplicationM m = Request -> (Response -> IO ResponseReceived) -> m ResponseReceived @@ -51,8 +51,8 @@ instance HasServer RawM context where hoistServerWithContext _ _ f srvM req respond = f (srvM req respond) -instance HasSwagger RawM where - toSwagger _ = toSwagger (Proxy @Raw) +instance HasOpenApi RawM where + toOpenApi _ = toOpenApi (Proxy @Raw) instance RoutesToPaths RawM where getRoutes = [] diff --git a/libs/schema-profunctor/default.nix b/libs/schema-profunctor/default.nix index a498d97378b..bede1bdeae6 100644 --- a/libs/schema-profunctor/default.nix +++ b/libs/schema-profunctor/default.nix @@ -14,8 +14,8 @@ , insert-ordered-containers , lens , lib +, openapi3 , profunctors -, swagger2 , tasty , tasty-hunit , text @@ -34,8 +34,8 @@ mkDerivation { containers imports lens + openapi3 profunctors - swagger2 text transformers vector @@ -47,7 +47,7 @@ mkDerivation { imports insert-ordered-containers lens - swagger2 + openapi3 tasty tasty-hunit text diff --git a/libs/schema-profunctor/schema-profunctor.cabal b/libs/schema-profunctor/schema-profunctor.cabal index c9c534c0165..f89bbbd2eda 100644 --- a/libs/schema-profunctor/schema-profunctor.cabal +++ b/libs/schema-profunctor/schema-profunctor.cabal @@ -69,8 +69,8 @@ library , containers , imports , lens + , openapi3 >=3.2.0 && <3.2.3 , profunctors - , swagger2 >=2 && <2.9 , text , transformers , vector @@ -135,12 +135,12 @@ test-suite schemas-tests build-depends: aeson , aeson-qq - , base >=4 && <5 + , base >=4 && <5 , imports , insert-ordered-containers , lens + , openapi3 >=3.2 && <3.2.3 , schema-profunctor - , swagger2 , tasty , tasty-hunit , text diff --git a/libs/schema-profunctor/src/Data/Schema.hs b/libs/schema-profunctor/src/Data/Schema.hs index 548ed8bfbe0..13afafd4c8c 100644 --- a/libs/schema-profunctor/src/Data/Schema.hs +++ b/libs/schema-profunctor/src/Data/Schema.hs @@ -101,12 +101,11 @@ import Data.List.NonEmpty (NonEmpty) import Data.List.NonEmpty qualified as NonEmpty import Data.Map qualified as Map import Data.Monoid hiding (Product) +import Data.OpenApi qualified as S +import Data.OpenApi.Declare qualified as S import Data.Profunctor (Star (..)) import Data.Proxy (Proxy (..)) import Data.Set qualified as Set -import Data.Swagger qualified as S -import Data.Swagger.Declare qualified as S -import Data.Swagger.Internal qualified as S import Data.Text qualified as T import Data.Text.Lazy qualified as TL import Data.Vector qualified as V @@ -643,7 +642,7 @@ text name = (A.withText (T.unpack name) pure) (pure . A.String) where - d = mempty & S.type_ ?~ S.SwaggerString + d = mempty & S.type_ ?~ S.OpenApiString -- | A schema for a textual value with possible failure. parsedText :: @@ -783,7 +782,7 @@ instance HasSchemaRef doc => HasField doc SwaggerDoc where where f ref = mempty - & S.type_ ?~ S.SwaggerObject + & S.type_ ?~ S.OpenApiObject & S.properties . at name ?~ ref & S.required .~ [name] @@ -799,8 +798,8 @@ instance HasSchemaRef ndoc => HasArray ndoc SwaggerDoc where f :: S.Referenced S.Schema -> S.Schema f ref = mempty - & S.type_ ?~ S.SwaggerArray - & S.items ?~ S.SwaggerItemsObject ref + & S.type_ ?~ S.OpenApiArray + & S.items ?~ S.OpenApiItemsObject ref instance HasSchemaRef ndoc => HasMap ndoc SwaggerDoc where mkMap = fmap f . schemaRef @@ -808,7 +807,7 @@ instance HasSchemaRef ndoc => HasMap ndoc SwaggerDoc where f :: S.Referenced S.Schema -> S.Schema f ref = mempty - & S.type_ ?~ S.SwaggerObject + & S.type_ ?~ S.OpenApiObject & S.additionalProperties ?~ S.AdditionalPropertiesSchema ref class HasMinItems s a where @@ -818,19 +817,19 @@ instance HasMinItems SwaggerDoc (Maybe Integer) where minItems = declared . S.minItems instance HasEnum Text NamedSwaggerDoc where - mkEnum = mkSwaggerEnum S.SwaggerString + mkEnum = mkSwaggerEnum S.OpenApiString instance HasEnum Integer NamedSwaggerDoc where - mkEnum = mkSwaggerEnum S.SwaggerInteger + mkEnum = mkSwaggerEnum S.OpenApiInteger instance HasEnum Natural NamedSwaggerDoc where - mkEnum = mkSwaggerEnum S.SwaggerInteger + mkEnum = mkSwaggerEnum S.OpenApiInteger instance HasEnum Bool NamedSwaggerDoc where - mkEnum = mkSwaggerEnum S.SwaggerBoolean + mkEnum = mkSwaggerEnum S.OpenApiBoolean mkSwaggerEnum :: - S.SwaggerType 'S.SwaggerKindSchema -> + S.OpenApiType -> Text -> [A.Value] -> NamedSwaggerDoc @@ -862,7 +861,7 @@ newtype Schema a = Schema {getSchema :: a} schemaToSwagger :: forall a. ToSchema a => Proxy a -> Declare S.NamedSchema schemaToSwagger _ = runDeclare (schemaDoc (schema @a)) -instance ToSchema a => S.ToSchema (Schema a) where +instance (Typeable a, ToSchema a) => S.ToSchema (Schema a) where declareNamedSchema _ = schemaToSwagger (Proxy @a) -- | JSON serialiser for an instance of 'ToSchema'. diff --git a/libs/schema-profunctor/test/unit/Test/Data/Schema.hs b/libs/schema-profunctor/test/unit/Test/Data/Schema.hs index 5ee7af68a77..d29b69b2365 100644 --- a/libs/schema-profunctor/test/unit/Test/Data/Schema.hs +++ b/libs/schema-profunctor/test/unit/Test/Data/Schema.hs @@ -27,10 +27,10 @@ import Data.Aeson.QQ import Data.Aeson.Types qualified as A import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap import Data.List.NonEmpty (NonEmpty ((:|))) +import Data.OpenApi qualified as S +import Data.OpenApi.Declare qualified as S import Data.Proxy import Data.Schema hiding (getName) -import Data.Swagger qualified as S -import Data.Swagger.Declare qualified as S import Data.Text qualified as Text import Imports import Test.Tasty @@ -290,7 +290,7 @@ testNonEmptySchema = Nothing -> assertFailure "expected schema to have a property called 'nl'" Just (S.Ref _) -> assertFailure "expected property 'nl' to have inline schema" Just (S.Inline nlSch) -> do - assertEqual "type should be Array" (Just S.SwaggerArray) (nlSch ^. S.type_) + assertEqual "type should be Array" (Just S.OpenApiArray) (nlSch ^. S.type_) assertEqual "minItems should be 1" (Just 1) (nlSch ^. S.minItems) testRefField :: TestTree @@ -332,7 +332,7 @@ testEnumType = assertEqual "Text enum has Swagger type \"string\"" (s1 ^. S.type_) - (Just S.SwaggerString) + (Just S.OpenApiString) let e2 :: ValueSchema NamedSwaggerDoc Integer e2 = enum @Integer "IntEnum" (element (3 :: Integer) (3 :: Integer)) @@ -340,7 +340,7 @@ testEnumType = assertEqual "Integer enum has Swagger type \"integer\"" (s2 ^. S.type_) - (Just S.SwaggerInteger) + (Just S.OpenApiInteger) testNullable :: TestTree testNullable = diff --git a/libs/types-common/default.nix b/libs/types-common/default.nix index 8b4da990200..a5c57f5f05d 100644 --- a/libs/types-common/default.nix +++ b/libs/types-common/default.nix @@ -32,6 +32,7 @@ , lens-datetime , lib , mime +, openapi3 , optparse-applicative , pem , protobuf @@ -40,7 +41,6 @@ , random , schema-profunctor , servant-server -, swagger2 , tagged , tasty , tasty-hunit @@ -86,6 +86,7 @@ mkDerivation { lens lens-datetime mime + openapi3 optparse-applicative pem protobuf @@ -94,7 +95,6 @@ mkDerivation { random schema-profunctor servant-server - swagger2 tagged tasty tasty-hunit diff --git a/libs/types-common/src/Data/Code.hs b/libs/types-common/src/Data/Code.hs index 1820d85f403..ba176629701 100644 --- a/libs/types-common/src/Data/Code.hs +++ b/libs/types-common/src/Data/Code.hs @@ -31,11 +31,11 @@ import Data.Aeson.TH import Data.Bifunctor (Bifunctor (first)) import Data.ByteString.Conversion import Data.Json.Util +import Data.OpenApi qualified as S +import Data.OpenApi.ParamSchema import Data.Proxy (Proxy (Proxy)) import Data.Range import Data.Schema -import Data.Swagger qualified as S -import Data.Swagger.ParamSchema import Data.Text (pack) import Data.Text.Ascii import Data.Text.Encoding (encodeUtf8) diff --git a/libs/types-common/src/Data/CommaSeparatedList.hs b/libs/types-common/src/Data/CommaSeparatedList.hs index 8e3ebd0edd8..8c13c49f4cf 100644 --- a/libs/types-common/src/Data/CommaSeparatedList.hs +++ b/libs/types-common/src/Data/CommaSeparatedList.hs @@ -22,9 +22,9 @@ module Data.CommaSeparatedList where import Control.Lens ((?~)) import Data.Bifunctor qualified as Bifunctor import Data.ByteString.Conversion (FromByteString, List, fromList, parser, runParser) +import Data.OpenApi import Data.Proxy (Proxy (..)) import Data.Range (Bounds, Range) -import Data.Swagger (CollectionFormat (CollectionCSV), SwaggerItems (SwaggerItemsPrimitive), SwaggerType (SwaggerString), ToParamSchema (..), items, type_) import Data.Text qualified as Text import Data.Text.Encoding (encodeUtf8) import Imports @@ -40,10 +40,10 @@ instance FromByteString (List a) => FromHttpApiData (CommaSeparatedList a) where CommaSeparatedList . fromList <$> Bifunctor.first Text.pack (runParser parser $ encodeUtf8 t) instance ToParamSchema (CommaSeparatedList a) where - toParamSchema _ = mempty & type_ ?~ SwaggerString + toParamSchema _ = mempty & type_ ?~ OpenApiString -- | TODO: is this obsoleted by the instances in "Data.Range"? instance (ToParamSchema a, ToParamSchema (Range n m [a])) => ToParamSchema (Range n m (CommaSeparatedList a)) where toParamSchema _ = toParamSchema (Proxy @(Range n m [a])) - & items ?~ SwaggerItemsPrimitive (Just CollectionCSV) (toParamSchema (Proxy @a)) + & items ?~ OpenApiItemsArray [Inline $ toParamSchema (Proxy @a)] diff --git a/libs/types-common/src/Data/Domain.hs b/libs/types-common/src/Data/Domain.hs index 8f96dc18bcb..6f9d0884405 100644 --- a/libs/types-common/src/Data/Domain.hs +++ b/libs/types-common/src/Data/Domain.hs @@ -31,8 +31,8 @@ import Data.ByteString qualified as BS import Data.ByteString.Builder qualified as Builder import Data.ByteString.Char8 qualified as BS.Char8 import Data.ByteString.Conversion +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Data.Text qualified as Text import Data.Text.Encoding qualified as Text.E import Imports hiding (isAlphaNum) diff --git a/libs/types-common/src/Data/Handle.hs b/libs/types-common/src/Data/Handle.hs index 0d1e5220076..29d1570cc32 100644 --- a/libs/types-common/src/Data/Handle.hs +++ b/libs/types-common/src/Data/Handle.hs @@ -31,8 +31,8 @@ import Data.Bifunctor (Bifunctor (first)) import Data.ByteString qualified as BS import Data.ByteString.Conversion (FromByteString (parser), ToByteString) import Data.Hashable (Hashable) +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Data.Text qualified as Text import Data.Text.Encoding qualified as Text.E import Imports diff --git a/libs/types-common/src/Data/Id.hs b/libs/types-common/src/Data/Id.hs index cae7c686ce7..528725f888b 100644 --- a/libs/types-common/src/Data/Id.hs +++ b/libs/types-common/src/Data/Id.hs @@ -71,11 +71,11 @@ import Data.ByteString.Lazy qualified as L import Data.Char qualified as Char import Data.Default (Default (..)) import Data.Hashable (Hashable) +import Data.OpenApi qualified as S +import Data.OpenApi.Internal.ParamSchema (ToParamSchema (..)) import Data.ProtocolBuffers.Internal import Data.Proxy import Data.Schema -import Data.Swagger qualified as S -import Data.Swagger.Internal.ParamSchema (ToParamSchema (..)) import Data.Text qualified as T import Data.Text.Encoding (decodeUtf8, encodeUtf8) import Data.Text.Lazy (toStrict) diff --git a/libs/types-common/src/Data/Json/Util.hs b/libs/types-common/src/Data/Json/Util.hs index 62e7168d728..408dfe41cbc 100644 --- a/libs/types-common/src/Data/Json/Util.hs +++ b/libs/types-common/src/Data/Json/Util.hs @@ -62,8 +62,8 @@ import Data.ByteString.Builder qualified as BB import Data.ByteString.Conversion qualified as BS import Data.ByteString.Lazy qualified as L import Data.Fixed +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Data.Text qualified as Text import Data.Text.Encoding qualified as Text import Data.Text.Encoding.Error qualified as Text @@ -161,7 +161,7 @@ instance ToJSONObject A.Object where instance S.ToParamSchema A.Object where toParamSchema _ = - mempty & S.type_ ?~ S.SwaggerString + mempty & S.type_ ?~ S.OpenApiString instance ToSchema A.Object where schema = @@ -209,7 +209,7 @@ instance ToHttpApiData Base64ByteString where toUrlPiece = Text.decodeUtf8With Text.lenientDecode . B64U.encodeUnpadded . fromBase64ByteString instance S.ToParamSchema Base64ByteString where - toParamSchema _ = mempty & S.type_ ?~ S.SwaggerString + toParamSchema _ = mempty & S.type_ ?~ S.OpenApiString -- base64("example") ~> "ZXhhbXBsZQo=" base64SchemaN :: ValueSchema NamedSwaggerDoc ByteString @@ -245,7 +245,7 @@ instance ToHttpApiData Base64ByteStringL where toUrlPiece = toUrlPiece . base64ToStrict instance S.ToParamSchema Base64ByteStringL where - toParamSchema _ = mempty & S.type_ ?~ S.SwaggerString + toParamSchema _ = mempty & S.type_ ?~ S.OpenApiString base64SchemaLN :: ValueSchema NamedSwaggerDoc LByteString base64SchemaLN = L.toStrict .= fmap L.fromStrict base64SchemaN diff --git a/libs/types-common/src/Data/LegalHold.hs b/libs/types-common/src/Data/LegalHold.hs index 7b328820e6c..02955c03f3d 100644 --- a/libs/types-common/src/Data/LegalHold.hs +++ b/libs/types-common/src/Data/LegalHold.hs @@ -20,8 +20,8 @@ module Data.LegalHold where import Cassandra.CQL import Control.Lens ((?~)) import Data.Aeson hiding (constructorTagModifier) +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Imports import Test.QuickCheck diff --git a/libs/types-common/src/Data/List1.hs b/libs/types-common/src/Data/List1.hs index f77d578fed9..8a1d31555d2 100644 --- a/libs/types-common/src/Data/List1.hs +++ b/libs/types-common/src/Data/List1.hs @@ -25,8 +25,8 @@ import Cassandra import Data.Aeson import Data.List.NonEmpty (NonEmpty) import Data.List.NonEmpty qualified as N +import Data.OpenApi qualified as Swagger import Data.Schema as S -import Data.Swagger qualified as Swagger import Imports import Test.QuickCheck (Arbitrary) import Test.QuickCheck.Instances () @@ -72,8 +72,8 @@ instance ToSchema a => ToSchema (List1 a) where instance Swagger.ToParamSchema (List1 a) where toParamSchema _ = mempty - { Swagger._paramSchemaType = Just Swagger.SwaggerArray, - Swagger._paramSchemaMinLength = Just 1 + { Swagger._schemaType = Just Swagger.OpenApiArray, + Swagger._schemaMinLength = Just 1 } instance (Cql a) => Cql (List1 a) where diff --git a/libs/types-common/src/Data/Misc.hs b/libs/types-common/src/Data/Misc.hs index 1b81d37aa31..0fd9115a820 100644 --- a/libs/types-common/src/Data/Misc.hs +++ b/libs/types-common/src/Data/Misc.hs @@ -77,9 +77,9 @@ import Data.ByteString.Char8 (unpack) import Data.ByteString.Conversion import Data.ByteString.Lazy (toStrict) import Data.IP (IP (IPv4, IPv6), toIPv4, toIPv6b) +import Data.OpenApi qualified as S import Data.Range import Data.Schema -import Data.Swagger qualified as S import Data.Text qualified as Text import Data.Text.Encoding (decodeUtf8, encodeUtf8) import GHC.TypeLits (Nat) @@ -100,7 +100,7 @@ newtype IpAddr = IpAddr {ipAddr :: IP} deriving (A.ToJSON, A.FromJSON, S.ToSchema) via (Schema IpAddr) instance S.ToParamSchema IpAddr where - toParamSchema _ = mempty & S.type_ ?~ S.SwaggerString + toParamSchema _ = mempty & S.type_ ?~ S.OpenApiString instance FromHttpApiData IpAddr where parseQueryParam p = first Text.pack (runParser parser (encodeUtf8 p)) @@ -314,7 +314,7 @@ deriving via deriving via (Schema (Fingerprint a)) instance - (ToSchema (Fingerprint a)) => + (Typeable a, ToSchema (Fingerprint a)) => S.ToSchema (Fingerprint a) instance ToSchema (Fingerprint Rsa) where @@ -378,7 +378,7 @@ deriving via (Schema (PlainTextPassword' tag)) instance ToSchema (PlainTextPassw deriving via (Schema (PlainTextPassword' tag)) instance ToSchema (PlainTextPassword' tag) => ToJSON (PlainTextPassword' tag) -deriving via (Schema (PlainTextPassword' tag)) instance ToSchema (PlainTextPassword' tag) => S.ToSchema (PlainTextPassword' tag) +deriving via (Schema (PlainTextPassword' tag)) instance (KnownNat tag, ToSchema (PlainTextPassword' tag)) => S.ToSchema (PlainTextPassword' tag) instance Show (PlainTextPassword' minLen) where show _ = "PlainTextPassword' " diff --git a/libs/types-common/src/Data/Nonce.hs b/libs/types-common/src/Data/Nonce.hs index 91befc4c3e8..1f094bab764 100644 --- a/libs/types-common/src/Data/Nonce.hs +++ b/libs/types-common/src/Data/Nonce.hs @@ -31,10 +31,10 @@ import Data.Aeson qualified as A import Data.ByteString.Base64.URL qualified as Base64 import Data.ByteString.Conversion import Data.ByteString.Lazy (fromStrict, toStrict) +import Data.OpenApi qualified as S +import Data.OpenApi.ParamSchema import Data.Proxy (Proxy (Proxy)) import Data.Schema -import Data.Swagger qualified as S -import Data.Swagger.ParamSchema import Data.UUID as UUID (UUID, fromByteString, toByteString) import Data.UUID.V4 (nextRandom) import Imports diff --git a/libs/types-common/src/Data/Qualified.hs b/libs/types-common/src/Data/Qualified.hs index 964f91e1ef5..71870361047 100644 --- a/libs/types-common/src/Data/Qualified.hs +++ b/libs/types-common/src/Data/Qualified.hs @@ -55,8 +55,8 @@ import Data.Domain (Domain) import Data.Handle (Handle (..)) import Data.Id import Data.Map qualified as Map +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Imports hiding (local) import Test.QuickCheck (Arbitrary (arbitrary)) @@ -198,7 +198,7 @@ instance KnownIdTag t => ToJSON (Qualified (Id t)) where instance KnownIdTag t => FromJSON (Qualified (Id t)) where parseJSON = schemaParseJSON -instance KnownIdTag t => S.ToSchema (Qualified (Id t)) where +instance (Typeable t, KnownIdTag t) => S.ToSchema (Qualified (Id t)) where declareNamedSchema = schemaToSwagger instance ToJSON (Qualified Handle) where diff --git a/libs/types-common/src/Data/Range.hs b/libs/types-common/src/Data/Range.hs index e4c5be14781..3d22a494930 100644 --- a/libs/types-common/src/Data/Range.hs +++ b/libs/types-common/src/Data/Range.hs @@ -74,13 +74,13 @@ import Data.List.NonEmpty (NonEmpty) import Data.List.NonEmpty qualified as N import Data.List1 (List1, toNonEmpty) import Data.Map qualified as Map +import Data.OpenApi (Schema, ToParamSchema (..)) +import Data.OpenApi qualified as S import Data.Proxy -import Data.Schema +import Data.Schema hiding (Schema) import Data.Sequence (Seq) import Data.Sequence qualified as Seq import Data.Set qualified as Set -import Data.Swagger (ParamSchema, ToParamSchema (..)) -import Data.Swagger qualified as S import Data.Text qualified as T import Data.Text.Ascii (AsciiChar, AsciiChars, AsciiText, fromAsciiChars) import Data.Text.Ascii qualified as Ascii @@ -232,7 +232,7 @@ instance (KnownNat n, KnownNat m) => ToParamSchema (Range n m TL.Text) where & S.maxLength ?~ fromKnownNat (Proxy @n) & S.minLength ?~ fromKnownNat (Proxy @m) -instance S.ToSchema a => S.ToSchema (Range n m a) where +instance (KnownNat n, S.ToSchema a, KnownNat m) => S.ToSchema (Range n m a) where declareNamedSchema _ = S.declareNamedSchema (Proxy @a) @@ -316,7 +316,7 @@ rappend (Range a) (Range b) = Range (a <> b) rsingleton :: a -> Range 1 1 [a] rsingleton = Range . pure -rangedNumToParamSchema :: forall a n m t. (ToParamSchema a, Num a, KnownNat n, KnownNat m) => Proxy (Range n m a) -> ParamSchema t +rangedNumToParamSchema :: forall a n m. (ToParamSchema a, Num a, KnownNat n, KnownNat m) => Proxy (Range n m a) -> Schema rangedNumToParamSchema _ = toParamSchema (Proxy @a) & S.minimum_ ?~ fromKnownNat (Proxy @n) diff --git a/libs/types-common/src/Data/Text/Ascii.hs b/libs/types-common/src/Data/Text/Ascii.hs index 70712eabdba..0fac4b07e2f 100644 --- a/libs/types-common/src/Data/Text/Ascii.hs +++ b/libs/types-common/src/Data/Text/Ascii.hs @@ -86,8 +86,8 @@ import Data.ByteString.Base64.URL qualified as B64Url import Data.ByteString.Char8 qualified as C8 import Data.ByteString.Conversion import Data.Hashable (Hashable) +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Data.Text qualified as Text import Data.Text.Encoding (decodeLatin1, decodeUtf8') import Imports @@ -156,7 +156,7 @@ instance AsciiChars c => ToJSON (AsciiText c) where instance AsciiChars c => FromJSON (AsciiText c) where parseJSON = schemaParseJSON -instance AsciiChars c => S.ToSchema (AsciiText c) where +instance (Typeable c, AsciiChars c) => S.ToSchema (AsciiText c) where declareNamedSchema = schemaToSwagger instance AsciiChars c => Cql (AsciiText c) where diff --git a/libs/types-common/types-common.cabal b/libs/types-common/types-common.cabal index 9f2eb9391c7..7c137d1b8fc 100644 --- a/libs/types-common/types-common.cabal +++ b/libs/types-common/types-common.cabal @@ -116,6 +116,7 @@ library , lens >=4.10 , lens-datetime >=0.3 , mime >=0.4.0.2 + , openapi3 >=3.2.0 && <3.2.3 , optparse-applicative >=0.10 , pem , protobuf >=0.2 @@ -124,7 +125,6 @@ library , random >=1.1 , schema-profunctor , servant-server - , swagger2 , tagged >=0.8 , tasty >=0.11 , tasty-hunit diff --git a/libs/wai-utilities/default.nix b/libs/wai-utilities/default.nix index 33988b17bfd..bc345ab3586 100644 --- a/libs/wai-utilities/default.nix +++ b/libs/wai-utilities/default.nix @@ -18,12 +18,12 @@ , lib , metrics-core , metrics-wai +, openapi3 , pipes , prometheus-client , schema-profunctor , servant-server , streaming-commons -, swagger2 , text , tinylog , types-common @@ -52,12 +52,12 @@ mkDerivation { kan-extensions metrics-core metrics-wai + openapi3 pipes prometheus-client schema-profunctor servant-server streaming-commons - swagger2 text tinylog types-common diff --git a/libs/wai-utilities/src/Network/Wai/Utilities/Headers.hs b/libs/wai-utilities/src/Network/Wai/Utilities/Headers.hs index 2cf2b2e644e..f1673e7de13 100644 --- a/libs/wai-utilities/src/Network/Wai/Utilities/Headers.hs +++ b/libs/wai-utilities/src/Network/Wai/Utilities/Headers.hs @@ -18,7 +18,7 @@ module Network.Wai.Utilities.Headers where import Data.ByteString.Conversion (FromByteString (..), ToByteString (..), fromByteString', toByteString') -import Data.Swagger.ParamSchema (ToParamSchema (..)) +import Data.OpenApi.ParamSchema (ToParamSchema (..)) import Data.Text as T import Imports import Servant (FromHttpApiData (..), Proxy (Proxy), ToHttpApiData (..)) diff --git a/libs/wai-utilities/wai-utilities.cabal b/libs/wai-utilities/wai-utilities.cabal index 44a3769dbf1..88acae83a04 100644 --- a/libs/wai-utilities/wai-utilities.cabal +++ b/libs/wai-utilities/wai-utilities.cabal @@ -86,12 +86,12 @@ library , kan-extensions , metrics-core >=0.1 , metrics-wai >=0.5.7 + , openapi3 >=3.2 && <3.2.3 , pipes >=4.1 , prometheus-client , schema-profunctor , servant-server , streaming-commons >=0.1 - , swagger2 , text >=0.11 , tinylog >=0.8 , types-common >=0.12 diff --git a/libs/wire-api-federation/default.nix b/libs/wire-api-federation/default.nix index 2ac0f43e549..0275616b33e 100644 --- a/libs/wire-api-federation/default.nix +++ b/libs/wire-api-federation/default.nix @@ -26,6 +26,7 @@ , lib , metrics-wai , mtl +, openapi3 , QuickCheck , schema-profunctor , servant @@ -34,7 +35,6 @@ , servant-server , singletons , singletons-th -, swagger2 , text , time , transformers @@ -66,6 +66,7 @@ mkDerivation { lens metrics-wai mtl + openapi3 QuickCheck schema-profunctor servant @@ -73,7 +74,6 @@ mkDerivation { servant-client-core servant-server singletons-th - swagger2 text time transformers diff --git a/libs/wire-api-federation/src/Wire/API/Federation/Version.hs b/libs/wire-api-federation/src/Wire/API/Federation/Version.hs index 3a433e3fb2a..0f3e113db95 100644 --- a/libs/wire-api-federation/src/Wire/API/Federation/Version.hs +++ b/libs/wire-api-federation/src/Wire/API/Federation/Version.hs @@ -21,10 +21,10 @@ module Wire.API.Federation.Version where import Control.Lens ((?~)) import Data.Aeson (FromJSON (..), ToJSON (..)) +import Data.OpenApi qualified as S import Data.Schema import Data.Set qualified as Set import Data.Singletons.TH -import Data.Swagger qualified as S import Imports import Wire.API.VersionInfo diff --git a/libs/wire-api-federation/wire-api-federation.cabal b/libs/wire-api-federation/wire-api-federation.cabal index 53862a2f92f..1c2f3b76e74 100644 --- a/libs/wire-api-federation/wire-api-federation.cabal +++ b/libs/wire-api-federation/wire-api-federation.cabal @@ -97,6 +97,7 @@ library , lens , metrics-wai , mtl + , openapi3 >=3.2 && <3.2.3 , QuickCheck >=2.13 , schema-profunctor , servant >=0.16 @@ -104,7 +105,6 @@ library , servant-client-core , servant-server , singletons-th - , swagger2 , text >=0.11 , time >=1.8 , transformers diff --git a/libs/wire-api/default.nix b/libs/wire-api/default.nix index e6ec675d546..b76f3159a94 100644 --- a/libs/wire-api/default.nix +++ b/libs/wire-api/default.nix @@ -61,6 +61,7 @@ , metrics-wai , mime , mtl +, openapi3 , pem , polysemy , pretty @@ -81,13 +82,12 @@ , servant-client-core , servant-conduit , servant-multipart +, servant-openapi3 , servant-server -, servant-swagger , singletons , singletons-base , singletons-th , sop-core -, swagger2 , tagged , tasty , tasty-hspec @@ -167,6 +167,7 @@ mkDerivation { metrics-wai mime mtl + openapi3 pem polysemy proto-lens @@ -185,13 +186,12 @@ mkDerivation { servant-client-core servant-conduit servant-multipart + servant-openapi3 servant-server - servant-swagger singletons singletons-base singletons-th sop-core - swagger2 tagged text time @@ -239,6 +239,7 @@ mkDerivation { lens memory metrics-wai + openapi3 pem pretty process @@ -247,7 +248,6 @@ mkDerivation { schema-profunctor servant servant-server - swagger2 tasty tasty-hspec tasty-hunit diff --git a/libs/wire-api/src/Wire/API/Asset.hs b/libs/wire-api/src/Wire/API/Asset.hs index d8505a038f1..5a678e2c75a 100644 --- a/libs/wire-api/src/Wire/API/Asset.hs +++ b/libs/wire-api/src/Wire/API/Asset.hs @@ -74,11 +74,11 @@ import Data.ByteString.Conversion import Data.ByteString.Lazy qualified as LBS import Data.Id import Data.Json.Util (UTCTimeMillis (fromUTCTimeMillis), toUTCTimeMillis) +import Data.OpenApi qualified as S import Data.Proxy import Data.Qualified import Data.SOP import Data.Schema -import Data.Swagger qualified as S import Data.Text qualified as T import Data.Text.Ascii (AsciiBase64Url) import Data.Text.Encoding qualified as T diff --git a/libs/wire-api/src/Wire/API/Call/Config.hs b/libs/wire-api/src/Wire/API/Call/Config.hs index a458891e34c..18289ca1706 100644 --- a/libs/wire-api/src/Wire/API/Call/Config.hs +++ b/libs/wire-api/src/Wire/API/Call/Config.hs @@ -81,8 +81,8 @@ import Data.ByteString.Conversion qualified as BC import Data.IP qualified as IP import Data.List.NonEmpty (NonEmpty) import Data.Misc (HttpsUrl (..), IpAddr (IpAddr), Port (..)) +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Data.Text qualified as Text import Data.Text.Ascii import Data.Text.Encoding qualified as TE diff --git a/libs/wire-api/src/Wire/API/Connection.hs b/libs/wire-api/src/Wire/API/Connection.hs index a093c10c72e..138b6c3eb4b 100644 --- a/libs/wire-api/src/Wire/API/Connection.hs +++ b/libs/wire-api/src/Wire/API/Connection.hs @@ -45,10 +45,10 @@ import Control.Lens ((?~)) import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.Id import Data.Json.Util (UTCTimeMillis) +import Data.OpenApi qualified as S import Data.Qualified (Qualified (qUnqualified), deprecatedSchema) import Data.Range import Data.Schema -import Data.Swagger qualified as S import Data.Text as Text import Imports import Servant.API @@ -142,7 +142,7 @@ data Relation deriving (FromJSON, ToJSON, S.ToSchema) via (Schema Relation) instance S.ToParamSchema Relation where - toParamSchema _ = mempty & S.type_ ?~ S.SwaggerString + toParamSchema _ = mempty & S.type_ ?~ S.OpenApiString -- | 'updateConnectionInternal', requires knowledge of the previous state (before -- 'MissingLegalholdConsent'), but the clients don't need that information. To avoid having diff --git a/libs/wire-api/src/Wire/API/Conversation.hs b/libs/wire-api/src/Wire/API/Conversation.hs index f28e178727a..2fb84a10e21 100644 --- a/libs/wire-api/src/Wire/API/Conversation.hs +++ b/libs/wire-api/src/Wire/API/Conversation.hs @@ -96,12 +96,12 @@ import Data.List.NonEmpty (NonEmpty) import Data.List1 import Data.Map qualified as Map import Data.Misc +import Data.OpenApi qualified as S import Data.Qualified import Data.Range (Range, fromRange, rangedSchema) import Data.SOP import Data.Schema import Data.Set qualified as Set -import Data.Swagger qualified as S import Data.UUID qualified as UUID import Data.UUID.V5 qualified as UUIDV5 import Imports diff --git a/libs/wire-api/src/Wire/API/Conversation/Action.hs b/libs/wire-api/src/Wire/API/Conversation/Action.hs index 8d8b9883cc8..9229278dbc4 100644 --- a/libs/wire-api/src/Wire/API/Conversation/Action.hs +++ b/libs/wire-api/src/Wire/API/Conversation/Action.hs @@ -38,10 +38,10 @@ import Data.Aeson.KeyMap qualified as A import Data.Id import Data.Kind import Data.List.NonEmpty qualified as NonEmptyList +import Data.OpenApi qualified as S import Data.Qualified (Qualified) import Data.Schema hiding (tag) import Data.Singletons.TH -import Data.Swagger qualified as S import Data.Time.Clock import Imports import Wire.API.Conversation diff --git a/libs/wire-api/src/Wire/API/Conversation/Bot.hs b/libs/wire-api/src/Wire/API/Conversation/Bot.hs index 2fd4a442cb3..f46a83869d4 100644 --- a/libs/wire-api/src/Wire/API/Conversation/Bot.hs +++ b/libs/wire-api/src/Wire/API/Conversation/Bot.hs @@ -28,8 +28,8 @@ where import Data.Aeson qualified as A import Data.Id +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Imports import Wire.API.Event.Conversation (Event) import Wire.API.User.Client.Prekey (Prekey) diff --git a/libs/wire-api/src/Wire/API/Conversation/Code.hs b/libs/wire-api/src/Wire/API/Conversation/Code.hs index b99b4012df2..51a142ddd09 100644 --- a/libs/wire-api/src/Wire/API/Conversation/Code.hs +++ b/libs/wire-api/src/Wire/API/Conversation/Code.hs @@ -40,8 +40,8 @@ import Data.ByteString.Conversion (toByteString') -- FUTUREWORK: move content of Data.Code here? import Data.Code as Code import Data.Misc +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Imports import URI.ByteString qualified as URI import Wire.Arbitrary (Arbitrary, GenericUniform (..)) diff --git a/libs/wire-api/src/Wire/API/Conversation/Member.hs b/libs/wire-api/src/Wire/API/Conversation/Member.hs index 2bb1d7e3817..704edcaf810 100644 --- a/libs/wire-api/src/Wire/API/Conversation/Member.hs +++ b/libs/wire-api/src/Wire/API/Conversation/Member.hs @@ -38,9 +38,9 @@ import Control.Lens ((?~)) import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.Aeson qualified as A import Data.Id +import Data.OpenApi qualified as S import Data.Qualified import Data.Schema -import Data.Swagger qualified as S import Imports import Test.QuickCheck qualified as QC import Wire.API.Conversation.Role diff --git a/libs/wire-api/src/Wire/API/Conversation/Role.hs b/libs/wire-api/src/Wire/API/Conversation/Role.hs index 1df79697f80..edb97c23f42 100644 --- a/libs/wire-api/src/Wire/API/Conversation/Role.hs +++ b/libs/wire-api/src/Wire/API/Conversation/Role.hs @@ -68,11 +68,11 @@ import Data.Aeson.TH qualified as A import Data.Attoparsec.Text import Data.ByteString.Conversion import Data.Hashable +import Data.OpenApi qualified as S import Data.Range (fromRange, genRangeText) import Data.Schema import Data.Set qualified as Set import Data.Singletons.TH -import Data.Swagger qualified as S import Deriving.Swagger qualified as S import GHC.TypeLits import Imports diff --git a/libs/wire-api/src/Wire/API/Conversation/Typing.hs b/libs/wire-api/src/Wire/API/Conversation/Typing.hs index 65e728c87c6..076dbde5e47 100644 --- a/libs/wire-api/src/Wire/API/Conversation/Typing.hs +++ b/libs/wire-api/src/Wire/API/Conversation/Typing.hs @@ -21,8 +21,8 @@ module Wire.API.Conversation.Typing where import Data.Aeson (FromJSON (..), ToJSON (..)) +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Imports import Wire.Arbitrary (Arbitrary, GenericUniform (..)) diff --git a/libs/wire-api/src/Wire/API/CustomBackend.hs b/libs/wire-api/src/Wire/API/CustomBackend.hs index 73c3a525a06..f7c12e0140d 100644 --- a/libs/wire-api/src/Wire/API/CustomBackend.hs +++ b/libs/wire-api/src/Wire/API/CustomBackend.hs @@ -24,8 +24,8 @@ where import Control.Lens ((?~)) import Data.Misc (HttpsUrl) +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Deriving.Aeson import Imports import Wire.Arbitrary (Arbitrary, GenericUniform (..)) diff --git a/libs/wire-api/src/Wire/API/Error.hs b/libs/wire-api/src/Wire/API/Error.hs index 304f11596ec..ed992945fbf 100644 --- a/libs/wire-api/src/Wire/API/Error.hs +++ b/libs/wire-api/src/Wire/API/Error.hs @@ -51,10 +51,10 @@ import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.Aeson qualified as A import Data.Kind import Data.Metrics.Servant +import Data.OpenApi qualified as S import Data.Proxy import Data.SOP import Data.Schema -import Data.Swagger qualified as S import Data.Text qualified as Text import Data.Text.Lazy qualified as LT import GHC.TypeLits @@ -65,7 +65,8 @@ import Network.Wai.Utilities.JSONResponse import Polysemy import Polysemy.Error import Servant -import Servant.Swagger +import Servant.OpenApi +import Servant.OpenApi (HasOpenApi (toOpenApi)) import Wire.API.Routes.MultiVerb import Wire.API.Routes.Named (Named) import Wire.API.Routes.Version @@ -185,23 +186,23 @@ instance (HasServer api ctx) => HasServer (CanThrowMany es :> api) ctx where hoistServerWithContext _ = hoistServerWithContext (Proxy @api) instance - (HasSwagger api, IsSwaggerError e) => - HasSwagger (CanThrow e :> api) + (HasOpenApi api, IsSwaggerError e) => + HasOpenApi (CanThrow e :> api) where - toSwagger _ = addToSwagger @e (toSwagger (Proxy @api)) + toOpenApi _ = addToOpenApi @e (toOpenApi (Proxy @api)) type instance SpecialiseToVersion v (CanThrowMany es :> api) = CanThrowMany es :> SpecialiseToVersion v api -instance HasSwagger api => HasSwagger (CanThrowMany '() :> api) where - toSwagger _ = toSwagger (Proxy @api) +instance HasOpenApi api => HasOpenApi (CanThrowMany '() :> api) where + toOpenApi _ = toOpenApi (Proxy @api) instance - (HasSwagger (CanThrowMany es :> api), IsSwaggerError e) => - HasSwagger (CanThrowMany '(e, es) :> api) + (HasOpenApi (CanThrowMany es :> api), IsSwaggerError e) => + HasOpenApi (CanThrowMany '(e, es) :> api) where - toSwagger _ = addToSwagger @e (toSwagger (Proxy @(CanThrowMany es :> api))) + toOpenApi _ = addToOpenApi @e (toOpenApi (Proxy @(CanThrowMany es :> api))) type family DeclaredErrorEffects api :: EffectRow where DeclaredErrorEffects (CanThrow e :> api) = (ErrorEffect e ': DeclaredErrorEffects api) diff --git a/libs/wire-api/src/Wire/API/Error/Empty.hs b/libs/wire-api/src/Wire/API/Error/Empty.hs index 474841ef1fd..290c75c978d 100644 --- a/libs/wire-api/src/Wire/API/Error/Empty.hs +++ b/libs/wire-api/src/Wire/API/Error/Empty.hs @@ -18,7 +18,7 @@ module Wire.API.Error.Empty where import Control.Lens ((.~)) -import Data.Swagger qualified as S +import Data.OpenApi qualified as S import Data.Text qualified as Text import GHC.TypeLits import Imports diff --git a/libs/wire-api/src/Wire/API/Error/Galley.hs b/libs/wire-api/src/Wire/API/Error/Galley.hs index 48aba881d42..27b16684a16 100644 --- a/libs/wire-api/src/Wire/API/Error/Galley.hs +++ b/libs/wire-api/src/Wire/API/Error/Galley.hs @@ -37,11 +37,11 @@ import Control.Lens ((%~), (.~), (?~)) import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.Containers.ListUtils import Data.Domain +import Data.OpenApi qualified as S import Data.Proxy import Data.Qualified import Data.Schema import Data.Singletons.TH (genSingletons) -import Data.Swagger qualified as S import Data.Tagged import GHC.TypeLits import Imports diff --git a/libs/wire-api/src/Wire/API/Event/Conversation.hs b/libs/wire-api/src/Wire/API/Event/Conversation.hs index 2aeb06e131d..b83a3221123 100644 --- a/libs/wire-api/src/Wire/API/Event/Conversation.hs +++ b/libs/wire-api/src/Wire/API/Event/Conversation.hs @@ -71,10 +71,10 @@ import Data.Aeson qualified as A import Data.Aeson.KeyMap qualified as KeyMap import Data.Id import Data.Json.Util +import Data.OpenApi qualified as S import Data.Qualified import Data.SOP import Data.Schema -import Data.Swagger qualified as S import Data.Time import Imports import Test.QuickCheck qualified as QC diff --git a/libs/wire-api/src/Wire/API/Event/FeatureConfig.hs b/libs/wire-api/src/Wire/API/Event/FeatureConfig.hs index e6982d8f45f..32e67dcfaf6 100644 --- a/libs/wire-api/src/Wire/API/Event/FeatureConfig.hs +++ b/libs/wire-api/src/Wire/API/Event/FeatureConfig.hs @@ -26,8 +26,8 @@ import Data.Aeson (toJSON) import Data.Aeson qualified as A import Data.Aeson.KeyMap qualified as KeyMap import Data.Json.Util (ToJSONObject (toJSONObject)) +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import GHC.TypeLits (KnownSymbol) import Imports import Test.QuickCheck.Gen (oneof) diff --git a/libs/wire-api/src/Wire/API/Event/Federation.hs b/libs/wire-api/src/Wire/API/Event/Federation.hs index cc38b1e2795..ea180477419 100644 --- a/libs/wire-api/src/Wire/API/Event/Federation.hs +++ b/libs/wire-api/src/Wire/API/Event/Federation.hs @@ -12,8 +12,8 @@ import Data.Aeson qualified as A import Data.Aeson.KeyMap qualified as KeyMap import Data.Domain import Data.Json.Util (ToJSONObject (toJSONObject)) +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Imports import Test.QuickCheck.Gen import Wire.Arbitrary diff --git a/libs/wire-api/src/Wire/API/Event/Team.hs b/libs/wire-api/src/Wire/API/Event/Team.hs index a6404dd851b..d5dac32eb39 100644 --- a/libs/wire-api/src/Wire/API/Event/Team.hs +++ b/libs/wire-api/src/Wire/API/Event/Team.hs @@ -42,8 +42,8 @@ import Data.Aeson.KeyMap qualified as KeyMap import Data.Aeson.Types (Parser) import Data.Id (ConvId, TeamId, UserId) import Data.Json.Util +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Data.Time (UTCTime) import Imports import Test.QuickCheck qualified as QC diff --git a/libs/wire-api/src/Wire/API/FederationStatus.hs b/libs/wire-api/src/Wire/API/FederationStatus.hs index 257d95c96b3..b0e7a3c9859 100644 --- a/libs/wire-api/src/Wire/API/FederationStatus.hs +++ b/libs/wire-api/src/Wire/API/FederationStatus.hs @@ -10,8 +10,8 @@ import Data.Aeson (FromJSON (..), ToJSON (..), (.:)) import Data.Aeson qualified as A import Data.Aeson.Types qualified as A import Data.Domain +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Imports import Wire.Arbitrary diff --git a/libs/wire-api/src/Wire/API/Internal/BulkPush.hs b/libs/wire-api/src/Wire/API/Internal/BulkPush.hs index 8c07c074a2c..0ffb9eec618 100644 --- a/libs/wire-api/src/Wire/API/Internal/BulkPush.hs +++ b/libs/wire-api/src/Wire/API/Internal/BulkPush.hs @@ -20,9 +20,9 @@ module Wire.API.Internal.BulkPush where import Control.Lens import Data.Aeson import Data.Id +import Data.OpenApi qualified as Swagger import Data.Schema (ValueSchema) import Data.Schema qualified as S -import Data.Swagger qualified as Swagger import Imports import Wire.API.Internal.Notification diff --git a/libs/wire-api/src/Wire/API/Internal/Notification.hs b/libs/wire-api/src/Wire/API/Internal/Notification.hs index 3c252180668..849c8125460 100644 --- a/libs/wire-api/src/Wire/API/Internal/Notification.hs +++ b/libs/wire-api/src/Wire/API/Internal/Notification.hs @@ -45,8 +45,8 @@ import Control.Lens (makeLenses) import Data.Aeson import Data.Id import Data.List1 +import Data.OpenApi qualified as Swagger import Data.Schema qualified as S -import Data.Swagger qualified as Swagger import Imports hiding (cs) import Wire.API.Notification diff --git a/libs/wire-api/src/Wire/API/MLS/CipherSuite.hs b/libs/wire-api/src/Wire/API/MLS/CipherSuite.hs index 4327cee928d..c6d93ac2e4e 100644 --- a/libs/wire-api/src/Wire/API/MLS/CipherSuite.hs +++ b/libs/wire-api/src/Wire/API/MLS/CipherSuite.hs @@ -25,10 +25,10 @@ import Crypto.Hash.Algorithms import Crypto.KDF.HKDF qualified as HKDF import Crypto.PubKey.Ed25519 qualified as Ed25519 import Data.Aeson (parseJSON, toJSON) +import Data.OpenApi qualified as S +import Data.OpenApi.Internal.Schema qualified as S import Data.Proxy import Data.Schema -import Data.Swagger qualified as S -import Data.Swagger.Internal.Schema qualified as S import Data.Word import Imports import Wire.API.MLS.Credential diff --git a/libs/wire-api/src/Wire/API/MLS/CommitBundle.hs b/libs/wire-api/src/Wire/API/MLS/CommitBundle.hs index a6c4e6753cd..8cff3683009 100644 --- a/libs/wire-api/src/Wire/API/MLS/CommitBundle.hs +++ b/libs/wire-api/src/Wire/API/MLS/CommitBundle.hs @@ -20,9 +20,9 @@ module Wire.API.MLS.CommitBundle where import Control.Lens (view, (.~), (?~)) import Data.Bifunctor (first) import Data.ByteString qualified as BS +import Data.OpenApi qualified as S import Data.ProtoLens (decodeMessage, encodeMessage) import Data.ProtoLens qualified (Message (defMessage)) -import Data.Swagger qualified as S import Data.Text qualified as T import Imports import Proto.Mls qualified diff --git a/libs/wire-api/src/Wire/API/MLS/Credential.hs b/libs/wire-api/src/Wire/API/MLS/Credential.hs index dc229102392..b3c92866f53 100644 --- a/libs/wire-api/src/Wire/API/MLS/Credential.hs +++ b/libs/wire-api/src/Wire/API/MLS/Credential.hs @@ -32,9 +32,9 @@ import Data.Binary.Parser import Data.Binary.Parser.Char8 import Data.Domain import Data.Id +import Data.OpenApi qualified as S import Data.Qualified import Data.Schema -import Data.Swagger qualified as S import Data.Text qualified as T import Data.UUID import Imports @@ -123,7 +123,7 @@ instance FromJSONKey SignatureSchemeTag where fromJSONKey = Aeson.FromJSONKeyTextParser parseSignatureScheme instance S.ToParamSchema SignatureSchemeTag where - toParamSchema _ = mempty & S.type_ ?~ S.SwaggerString + toParamSchema _ = mempty & S.type_ ?~ S.OpenApiString instance FromHttpApiData SignatureSchemeTag where parseQueryParam = note "Unknown signature scheme" . signatureSchemeFromName @@ -206,7 +206,7 @@ instance FromJSONKey SignaturePurpose where either fail pure . signaturePurposeFromName instance S.ToParamSchema SignaturePurpose where - toParamSchema _ = mempty & S.type_ ?~ S.SwaggerString + toParamSchema _ = mempty & S.type_ ?~ S.OpenApiString instance FromHttpApiData SignaturePurpose where parseQueryParam = first T.pack . signaturePurposeFromName diff --git a/libs/wire-api/src/Wire/API/MLS/Group.hs b/libs/wire-api/src/Wire/API/MLS/Group.hs index fbbefd015e1..4cff768d633 100644 --- a/libs/wire-api/src/Wire/API/MLS/Group.hs +++ b/libs/wire-api/src/Wire/API/MLS/Group.hs @@ -23,9 +23,9 @@ import Data.ByteArray (convert) import Data.ByteString.Conversion import Data.Id import Data.Json.Util +import Data.OpenApi qualified as S import Data.Qualified import Data.Schema -import Data.Swagger qualified as S import Imports import Wire.API.MLS.Serialisation import Wire.Arbitrary diff --git a/libs/wire-api/src/Wire/API/MLS/KeyPackage.hs b/libs/wire-api/src/Wire/API/MLS/KeyPackage.hs index 51a7267450f..a692179a9bc 100644 --- a/libs/wire-api/src/Wire/API/MLS/KeyPackage.hs +++ b/libs/wire-api/src/Wire/API/MLS/KeyPackage.hs @@ -49,9 +49,9 @@ import Data.ByteString qualified as B import Data.ByteString.Lazy qualified as LBS import Data.Id import Data.Json.Util +import Data.OpenApi qualified as S import Data.Qualified import Data.Schema -import Data.Swagger qualified as S import Imports hiding (cs) import Test.QuickCheck import Web.HttpApiData diff --git a/libs/wire-api/src/Wire/API/MLS/Keys.hs b/libs/wire-api/src/Wire/API/MLS/Keys.hs index 3bb54a9be20..9819b2c1f64 100644 --- a/libs/wire-api/src/Wire/API/MLS/Keys.hs +++ b/libs/wire-api/src/Wire/API/MLS/Keys.hs @@ -29,8 +29,8 @@ import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.ByteArray import Data.Json.Util import Data.Map qualified as Map +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Imports import Wire.API.MLS.Credential diff --git a/libs/wire-api/src/Wire/API/MLS/Message.hs b/libs/wire-api/src/Wire/API/MLS/Message.hs index 517ef2a7fa6..b24e8742988 100644 --- a/libs/wire-api/src/Wire/API/MLS/Message.hs +++ b/libs/wire-api/src/Wire/API/MLS/Message.hs @@ -51,9 +51,9 @@ import Data.Binary.Put import Data.ByteArray qualified as BA import Data.Json.Util import Data.Kind +import Data.OpenApi qualified as S import Data.Schema import Data.Singletons.TH -import Data.Swagger qualified as S import Imports hiding (cs) import Test.QuickCheck hiding (label) import Wire.API.Event.Conversation diff --git a/libs/wire-api/src/Wire/API/MLS/PublicGroupState.hs b/libs/wire-api/src/Wire/API/MLS/PublicGroupState.hs index 870b46f549d..fb467228d3b 100644 --- a/libs/wire-api/src/Wire/API/MLS/PublicGroupState.hs +++ b/libs/wire-api/src/Wire/API/MLS/PublicGroupState.hs @@ -22,7 +22,7 @@ import Data.Binary import Data.Binary.Get import Data.Binary.Put import Data.ByteString.Lazy qualified as LBS -import Data.Swagger qualified as S +import Data.OpenApi qualified as S import Imports import Test.QuickCheck hiding (label) import Wire.API.MLS.CipherSuite diff --git a/libs/wire-api/src/Wire/API/MLS/Serialisation.hs b/libs/wire-api/src/Wire/API/MLS/Serialisation.hs index 946bcbc7c39..f0e7f997c26 100644 --- a/libs/wire-api/src/Wire/API/MLS/Serialisation.hs +++ b/libs/wire-api/src/Wire/API/MLS/Serialisation.hs @@ -59,9 +59,9 @@ import Data.ByteString qualified as BS import Data.ByteString.Lazy qualified as LBS import Data.Json.Util import Data.Kind +import Data.OpenApi qualified as S import Data.Proxy import Data.Schema -import Data.Swagger qualified as S import Data.Text qualified as Text import Imports diff --git a/libs/wire-api/src/Wire/API/MLS/SubConversation.hs b/libs/wire-api/src/Wire/API/MLS/SubConversation.hs index 69ec37ade05..8d46721f7b5 100644 --- a/libs/wire-api/src/Wire/API/MLS/SubConversation.hs +++ b/libs/wire-api/src/Wire/API/MLS/SubConversation.hs @@ -26,8 +26,8 @@ import Control.Lens.Tuple (_1) import Control.Monad.Except import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.Id +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Data.Text qualified as T import Imports import Servant (FromHttpApiData (..), ToHttpApiData (toQueryParam)) diff --git a/libs/wire-api/src/Wire/API/MLS/Welcome.hs b/libs/wire-api/src/Wire/API/MLS/Welcome.hs index ac95b53dee0..2bb8e117eed 100644 --- a/libs/wire-api/src/Wire/API/MLS/Welcome.hs +++ b/libs/wire-api/src/Wire/API/MLS/Welcome.hs @@ -17,7 +17,7 @@ module Wire.API.MLS.Welcome where -import Data.Swagger qualified as S +import Data.OpenApi qualified as S import Imports hiding (cs) import Wire.API.MLS.CipherSuite import Wire.API.MLS.Commit diff --git a/libs/wire-api/src/Wire/API/MakesFederatedCall.hs b/libs/wire-api/src/Wire/API/MakesFederatedCall.hs index fbc133d6728..c90d2fec92a 100644 --- a/libs/wire-api/src/Wire/API/MakesFederatedCall.hs +++ b/libs/wire-api/src/Wire/API/MakesFederatedCall.hs @@ -35,16 +35,17 @@ import Data.Aeson import Data.Constraint import Data.Kind import Data.Metrics.Servant +import Data.OpenApi.Operation (addExtensions) import Data.Proxy import Data.Schema -import Data.Swagger.Operation (addExtensions) import Data.Text qualified as T import GHC.TypeLits import Imports import Servant.API import Servant.Client +import Servant.OpenApi +import Servant.OpenApi (HasOpenApi (toOpenApi)) import Servant.Server -import Servant.Swagger import Test.QuickCheck (Arbitrary) import TransitiveAnns.Types import Unsafe.Coerce (unsafeCoerce) @@ -158,9 +159,9 @@ type instance -- | 'MakesFederatedCall' annotates the swagger documentation with an extension -- tag @x-wire-makes-federated-calls-to@. -instance (HasSwagger api, KnownSymbol name, KnownSymbol (ShowComponent comp)) => HasSwagger (MakesFederatedCall comp name :> api :: Type) where - toSwagger _ = - toSwagger (Proxy @api) +instance (HasOpenApi api, KnownSymbol name, KnownSymbol (ShowComponent comp)) => HasOpenApi (MakesFederatedCall comp name :> api :: Type) where + toOpenApi _ = + toOpenApi (Proxy @api) & addExtensions mergeJSONArray [ ( "wire-makes-federated-call-to", diff --git a/libs/wire-api/src/Wire/API/Message.hs b/libs/wire-api/src/Wire/API/Message.hs index e258cc3e74a..3b651796e21 100644 --- a/libs/wire-api/src/Wire/API/Message.hs +++ b/libs/wire-api/src/Wire/API/Message.hs @@ -67,6 +67,7 @@ import Data.Domain (Domain, domainText, mkDomain) import Data.Id import Data.Json.Util import Data.Map.Strict qualified as Map +import Data.OpenApi qualified as S import Data.ProtoLens qualified as ProtoLens import Data.ProtoLens.Field qualified as ProtoLens import Data.ProtocolBuffers qualified as Protobuf @@ -74,7 +75,6 @@ import Data.Qualified (Qualified (..)) import Data.Schema import Data.Serialize (runGet) import Data.Set qualified as Set -import Data.Swagger qualified as S import Data.Text.Read qualified as Reader import Data.UUID qualified as UUID import Imports @@ -553,7 +553,7 @@ data IgnoreMissing deriving (Show, Eq) instance S.ToParamSchema IgnoreMissing where - toParamSchema _ = mempty & S.type_ ?~ S.SwaggerString + toParamSchema _ = mempty & S.type_ ?~ S.OpenApiString instance FromHttpApiData IgnoreMissing where parseQueryParam = \case @@ -566,7 +566,7 @@ data ReportMissing | ReportMissingList (Set UserId) instance S.ToParamSchema ReportMissing where - toParamSchema _ = mempty & S.type_ ?~ S.SwaggerString + toParamSchema _ = mempty & S.type_ ?~ S.OpenApiString instance FromHttpApiData ReportMissing where parseQueryParam = \case diff --git a/libs/wire-api/src/Wire/API/Notification.hs b/libs/wire-api/src/Wire/API/Notification.hs index 3e808c02ef2..85ef11124b4 100644 --- a/libs/wire-api/src/Wire/API/Notification.hs +++ b/libs/wire-api/src/Wire/API/Notification.hs @@ -45,10 +45,10 @@ import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap import Data.Id import Data.Json.Util import Data.List.NonEmpty (NonEmpty) +import Data.OpenApi (ToParamSchema (..)) +import Data.OpenApi qualified as S import Data.SOP import Data.Schema -import Data.Swagger (ToParamSchema (..)) -import Data.Swagger qualified as S import Data.Time.Clock (UTCTime) import Imports import Servant diff --git a/libs/wire-api/src/Wire/API/OAuth.hs b/libs/wire-api/src/Wire/API/OAuth.hs index b34b3ae38d6..cbdcf757524 100644 --- a/libs/wire-api/src/Wire/API/OAuth.hs +++ b/libs/wire-api/src/Wire/API/OAuth.hs @@ -31,11 +31,11 @@ import Data.ByteString.Lazy (toStrict) import Data.Either.Combinators (mapLeft) import Data.HashMap.Strict qualified as HM import Data.Id as Id +import Data.OpenApi (ToParamSchema (..)) +import Data.OpenApi qualified as S import Data.Range import Data.Schema import Data.Set qualified as Set -import Data.Swagger (ToParamSchema (..)) -import Data.Swagger qualified as S import Data.Text qualified as T import Data.Text.Ascii import Data.Text.Encoding qualified as TE @@ -45,7 +45,7 @@ import GHC.TypeLits (Nat, symbolVal) import Imports hiding (exp, head) import Prelude.Singletons (Show_) import Servant hiding (Handler, JSON, Tagged, addHeader, respond) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Test.QuickCheck (Arbitrary (..)) import URI.ByteString import URI.ByteString.QQ qualified as URI.QQ diff --git a/libs/wire-api/src/Wire/API/Properties.hs b/libs/wire-api/src/Wire/API/Properties.hs index 70e03c71437..186e79d6c90 100644 --- a/libs/wire-api/src/Wire/API/Properties.hs +++ b/libs/wire-api/src/Wire/API/Properties.hs @@ -30,7 +30,7 @@ import Data.Aeson (FromJSON (..), ToJSON (..), Value) import Data.Aeson qualified as A import Data.ByteString.Conversion import Data.Hashable (Hashable) -import Data.Swagger qualified as S +import Data.OpenApi qualified as S import Data.Text.Ascii import Imports import Servant diff --git a/libs/wire-api/src/Wire/API/Provider/Bot.hs b/libs/wire-api/src/Wire/API/Provider/Bot.hs index 0db3cabeaff..e8a1f5b1c4a 100644 --- a/libs/wire-api/src/Wire/API/Provider/Bot.hs +++ b/libs/wire-api/src/Wire/API/Provider/Bot.hs @@ -34,8 +34,8 @@ import Control.Lens (makeLenses) import Data.Aeson qualified as A import Data.Handle (Handle) import Data.Id +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Imports import Wire.API.Conversation.Member (OtherMember (..)) import Wire.API.User.Profile (ColourId, Name) diff --git a/libs/wire-api/src/Wire/API/Provider/Service.hs b/libs/wire-api/src/Wire/API/Provider/Service.hs index 28a1e5609a1..c1110a58f25 100644 --- a/libs/wire-api/src/Wire/API/Provider/Service.hs +++ b/libs/wire-api/src/Wire/API/Provider/Service.hs @@ -61,11 +61,11 @@ import Data.Id import Data.Json.Util ((#)) import Data.List1 (List1) import Data.Misc (HttpsUrl (..), PlainTextPassword6) +import Data.OpenApi qualified as S import Data.PEM (PEM, pemParseBS, pemWriteLBS) import Data.Proxy import Data.Range (Range) import Data.Schema -import Data.Swagger qualified as S import Data.Text qualified as Text import Data.Text.Ascii import Data.Text.Encoding qualified as Text diff --git a/libs/wire-api/src/Wire/API/Push/V2/Token.hs b/libs/wire-api/src/Wire/API/Push/V2/Token.hs index ee8e828670d..0cf7b292af4 100644 --- a/libs/wire-api/src/Wire/API/Push/V2/Token.hs +++ b/libs/wire-api/src/Wire/API/Push/V2/Token.hs @@ -47,10 +47,10 @@ import Data.Aeson qualified as A import Data.Attoparsec.ByteString (takeByteString) import Data.ByteString.Conversion import Data.Id +import Data.OpenApi (ToParamSchema) +import Data.OpenApi qualified as S import Data.SOP import Data.Schema -import Data.Swagger (ToParamSchema) -import Data.Swagger qualified as S import Generics.SOP qualified as GSOP import Imports import Servant diff --git a/libs/wire-api/src/Wire/API/RawJson.hs b/libs/wire-api/src/Wire/API/RawJson.hs index fd0517ea289..1e0e8985e8f 100644 --- a/libs/wire-api/src/Wire/API/RawJson.hs +++ b/libs/wire-api/src/Wire/API/RawJson.hs @@ -20,7 +20,7 @@ module Wire.API.RawJson where import Control.Lens -import Data.Swagger qualified as Swagger +import Data.OpenApi qualified as Swagger import Imports import Servant import Test.QuickCheck diff --git a/libs/wire-api/src/Wire/API/Routes/API.hs b/libs/wire-api/src/Wire/API/Routes/API.hs index b43569bf76f..d86f3a3f371 100644 --- a/libs/wire-api/src/Wire/API/Routes/API.hs +++ b/libs/wire-api/src/Wire/API/Routes/API.hs @@ -31,14 +31,14 @@ where import Data.Domain import Data.Kind +import Data.OpenApi qualified as S import Data.Proxy -import Data.Swagger qualified as S import Imports import Polysemy import Polysemy.Error import Polysemy.Internal import Servant hiding (Union) -import Servant.Swagger +import Servant.OpenApi import Wire.API.Error import Wire.API.Routes.Named import Wire.API.Routes.Version @@ -47,8 +47,8 @@ class ServiceAPI service (v :: Version) where type ServiceAPIRoutes service type SpecialisedAPIRoutes v service :: Type type SpecialisedAPIRoutes v service = SpecialiseToVersion v (ServiceAPIRoutes service) - serviceSwagger :: HasSwagger (SpecialisedAPIRoutes v service) => S.Swagger - serviceSwagger = toSwagger (Proxy @(SpecialisedAPIRoutes v service)) + serviceSwagger :: HasOpenApi (SpecialisedAPIRoutes v service) => S.Swagger + serviceSwagger = toOpenApi (Proxy @(SpecialisedAPIRoutes v service)) instance ServiceAPI VersionAPITag v where type ServiceAPIRoutes VersionAPITag = VersionAPI diff --git a/libs/wire-api/src/Wire/API/Routes/AssetBody.hs b/libs/wire-api/src/Wire/API/Routes/AssetBody.hs index 2b6989d308b..4998c10f538 100644 --- a/libs/wire-api/src/Wire/API/Routes/AssetBody.hs +++ b/libs/wire-api/src/Wire/API/Routes/AssetBody.hs @@ -25,13 +25,13 @@ where import Conduit import Data.ByteString.Lazy qualified as LBS -import Data.Swagger -import Data.Swagger.Internal.Schema +import Data.OpenApi +import Data.OpenApi.Internal.Schema import Imports import Network.HTTP.Media ((//)) import Servant import Servant.Conduit () -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () data MultipartMixed diff --git a/libs/wire-api/src/Wire/API/Routes/Bearer.hs b/libs/wire-api/src/Wire/API/Routes/Bearer.hs index 545db5254df..7351fc66064 100644 --- a/libs/wire-api/src/Wire/API/Routes/Bearer.hs +++ b/libs/wire-api/src/Wire/API/Routes/Bearer.hs @@ -21,11 +21,11 @@ import Control.Lens ((<>~)) import Data.ByteString qualified as BS import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap import Data.Metrics.Servant -import Data.Swagger hiding (Header) +import Data.OpenApi hiding (Header) import Data.Text.Encoding qualified as T import Imports import Servant -import Servant.Swagger +import Servant.OpenApi import Wire.API.Routes.Version newtype Bearer a = Bearer {unBearer :: a} @@ -47,9 +47,9 @@ type instance SpecialiseToVersion v (Bearer a :> api) = Bearer a :> SpecialiseToVersion v api -instance HasSwagger api => HasSwagger (Bearer a :> api) where - toSwagger _ = - toSwagger (Proxy @api) +instance HasOpenApi api => HasOpenApi (Bearer a :> api) where + toOpenApi _ = + toOpenApi (Proxy @api) & security <>~ [SecurityRequirement $ InsOrdHashMap.singleton "ZAuth" []] instance RoutesToPaths api => RoutesToPaths (Bearer a :> api) where diff --git a/libs/wire-api/src/Wire/API/Routes/Cookies.hs b/libs/wire-api/src/Wire/API/Routes/Cookies.hs index 10383904ccb..2449f074c76 100644 --- a/libs/wire-api/src/Wire/API/Routes/Cookies.hs +++ b/libs/wire-api/src/Wire/API/Routes/Cookies.hs @@ -27,7 +27,7 @@ import Data.Text.Encoding qualified as T import GHC.TypeLits import Imports import Servant -import Servant.Swagger +import Servant.OpenApi import Web.Cookie (parseCookies) import Wire.API.Routes.Version @@ -63,8 +63,8 @@ type instance SpecialiseToVersion v (Cookies cs :> api) = Cookies cs :> SpecialiseToVersion v api -instance HasSwagger api => HasSwagger (Cookies cs :> api) where - toSwagger _ = toSwagger (Proxy @api) +instance HasOpenApi api => HasOpenApi (Cookies cs :> api) where + toOpenApi _ = toOpenApi (Proxy @api) class CookieArgs (cs :: [Type]) where -- example: AddArgs ["foo" :: Foo, "bar" :: Bar] a = Foo -> Bar -> a diff --git a/libs/wire-api/src/Wire/API/Routes/FederationDomainConfig.hs b/libs/wire-api/src/Wire/API/Routes/FederationDomainConfig.hs index 5ce5e7ca871..8530f78275a 100644 --- a/libs/wire-api/src/Wire/API/Routes/FederationDomainConfig.hs +++ b/libs/wire-api/src/Wire/API/Routes/FederationDomainConfig.hs @@ -26,8 +26,8 @@ where import Control.Lens ((?~)) import Data.Aeson (FromJSON, ToJSON) import Data.Domain (Domain) +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import GHC.Generics import Imports import Wire.API.User.Search (FederatedUserSearchPolicy) diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Brig.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Brig.hs index beab0e82a20..aabe0799692 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Brig.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Brig.hs @@ -46,14 +46,14 @@ import Data.CommaSeparatedList import Data.Domain (Domain) import Data.Handle (Handle) import Data.Id as Id +import Data.OpenApi (HasInfo (info), HasTitle (title), Swagger) +import Data.OpenApi qualified as S import Data.Qualified (Qualified) import Data.Schema hiding (swaggerDoc) -import Data.Swagger (HasInfo (info), HasTitle (title), Swagger) -import Data.Swagger qualified as S import Imports hiding (head) import Servant hiding (Handler, WithStatus, addHeader, respond) -import Servant.Swagger (HasSwagger (toSwagger)) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi (HasOpenApi (toOpenApi)) +import Servant.OpenApi.Internal.Orphans () import Wire.API.Connection import Wire.API.Error import Wire.API.Error.Brig diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Brig/Connection.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Brig/Connection.hs index f9226607259..7f3d76810cf 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Brig/Connection.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Brig/Connection.hs @@ -21,9 +21,9 @@ module Wire.API.Routes.Internal.Brig.Connection where import Data.Aeson (FromJSON, ToJSON) import Data.Id +import Data.OpenApi qualified as S import Data.Qualified import Data.Schema -import Data.Swagger qualified as S import Imports import Wire.API.Connection diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Brig/EJPD.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Brig/EJPD.hs index efd26df2ee0..93db38b2974 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Brig/EJPD.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Brig/EJPD.hs @@ -28,7 +28,7 @@ where import Data.Aeson hiding (json) import Data.Handle (Handle) import Data.Id (TeamId, UserId) -import Data.Swagger (ToSchema) +import Data.OpenApi (ToSchema) import Deriving.Swagger (CamelToSnake, CustomSwagger (..), FieldLabelModifier, StripSuffix) import Imports hiding (head) import Test.QuickCheck (Arbitrary) diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Brig/OAuth.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Brig/OAuth.hs index a8a2747af7d..8974da4c27c 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Brig/OAuth.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Brig/OAuth.hs @@ -20,7 +20,7 @@ module Wire.API.Routes.Internal.Brig.OAuth where import Data.Id (OAuthClientId) import Servant (JSON) import Servant hiding (Handler, JSON, Tagged, addHeader, respond) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Wire.API.Error import Wire.API.OAuth import Wire.API.Routes.Named (Named (..)) diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Brig/SearchIndex.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Brig/SearchIndex.hs index 6b45b977e68..0cca4948901 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Brig/SearchIndex.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Brig/SearchIndex.hs @@ -19,7 +19,7 @@ module Wire.API.Routes.Internal.Brig.SearchIndex where import Servant (JSON) import Servant hiding (Handler, JSON, Tagged, addHeader, respond) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Wire.API.Routes.Named (Named (..)) type ISearchIndexAPI = diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Cannon.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Cannon.hs index ff0fe916a1a..e6ac2fa4964 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Cannon.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Cannon.hs @@ -2,10 +2,10 @@ module Wire.API.Routes.Internal.Cannon where import Control.Lens ((.~)) import Data.Id -import Data.Swagger (HasInfo (info), HasTitle (title), Swagger) +import Data.OpenApi (HasInfo (info), HasTitle (title), Swagger) import Imports import Servant -import Servant.Swagger (HasSwagger (toSwagger)) +import Servant.OpenApi (HasOpenApi (toOpenApi)) import Wire.API.Error import Wire.API.Error.Cannon import Wire.API.Internal.BulkPush diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Cargohold.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Cargohold.hs index 825623ac9c6..47d4266b603 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Cargohold.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Cargohold.hs @@ -18,10 +18,10 @@ module Wire.API.Routes.Internal.Cargohold where import Control.Lens -import Data.Swagger +import Data.OpenApi import Imports import Servant -import Servant.Swagger +import Servant.OpenApi import Wire.API.Routes.MultiVerb type InternalAPI = diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Galley.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Galley.hs index e9d4e7e834f..5177c34c5ee 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Galley.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Galley.hs @@ -19,13 +19,13 @@ module Wire.API.Routes.Internal.Galley where import Control.Lens ((.~)) import Data.Id as Id +import Data.OpenApi (Swagger, info, title) import Data.Range -import Data.Swagger (Swagger, info, title) import GHC.TypeLits (AppendSymbol) import Imports hiding (head) import Servant hiding (JSON, WithStatus) import Servant qualified hiding (WithStatus) -import Servant.Swagger +import Servant.OpenApi import Wire.API.ApplyMods import Wire.API.Conversation.Role import Wire.API.Error diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Galley/ConversationsIntra.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Galley/ConversationsIntra.hs index cd81ed7473e..b644906cd95 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Galley/ConversationsIntra.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Galley/ConversationsIntra.hs @@ -26,9 +26,9 @@ where import Data.Aeson qualified as A import Data.Aeson.Types (FromJSON, ToJSON) import Data.Id (ConvId, UserId) +import Data.OpenApi qualified as Swagger import Data.Qualified import Data.Schema -import Data.Swagger qualified as Swagger import Imports data DesiredMembership = Included | Excluded diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Galley/TeamFeatureNoConfigMulti.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Galley/TeamFeatureNoConfigMulti.hs index fdb40b05aec..9f96c0b024c 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Galley/TeamFeatureNoConfigMulti.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Galley/TeamFeatureNoConfigMulti.hs @@ -24,8 +24,8 @@ where import Data.Aeson qualified as A import Data.Id +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Imports import Wire.API.Team.Feature qualified as Public diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Galley/TeamsIntra.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Galley/TeamsIntra.hs index 09432560ea5..0bc3ae5a593 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Galley/TeamsIntra.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Galley/TeamsIntra.hs @@ -31,8 +31,8 @@ import Control.Lens ((?~)) import Data.Aeson import Data.Currency qualified as Currency import Data.Json.Util +import Data.OpenApi qualified as Swagger import Data.Schema qualified as S -import Data.Swagger qualified as Swagger import Data.Time (UTCTime) import Imports import Test.QuickCheck.Arbitrary (Arbitrary) diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/LegalHold.hs b/libs/wire-api/src/Wire/API/Routes/Internal/LegalHold.hs index 69d114dca82..ffde2e561c3 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/LegalHold.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/LegalHold.hs @@ -19,11 +19,12 @@ module Wire.API.Routes.Internal.LegalHold where import Control.Lens import Data.Id +import Data.OpenApi (OpenApi) +import Data.OpenApi.Lens import Data.Proxy -import Data.Swagger import Imports import Servant.API hiding (Header, WithStatus) -import Servant.Swagger +import Servant.OpenApi import Wire.API.Team.Feature type InternalLegalHoldAPI = @@ -38,7 +39,7 @@ type InternalLegalHoldAPI = :> Put '[] NoContent ) -swaggerDoc :: Swagger +swaggerDoc :: OpenApi swaggerDoc = - toSwagger (Proxy @InternalLegalHoldAPI) + toOpenApi (Proxy @InternalLegalHoldAPI) & info . title .~ "Wire-Server internal legalhold API" diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Spar.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Spar.hs index 63f2358f5e1..265b6e29cff 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Spar.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Spar.hs @@ -19,10 +19,10 @@ module Wire.API.Routes.Internal.Spar where import Control.Lens import Data.Id -import Data.Swagger +import Data.OpenApi import Imports import Servant -import Servant.Swagger +import Servant.OpenApi import Wire.API.User import Wire.API.User.Saml diff --git a/libs/wire-api/src/Wire/API/Routes/LowLevelStream.hs b/libs/wire-api/src/Wire/API/Routes/LowLevelStream.hs index d9287bd5fa9..385eb9e5531 100644 --- a/libs/wire-api/src/Wire/API/Routes/LowLevelStream.hs +++ b/libs/wire-api/src/Wire/API/Routes/LowLevelStream.hs @@ -22,8 +22,8 @@ import Data.ByteString.Char8 as B8 import Data.CaseInsensitive qualified as CI import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap import Data.Metrics.Servant +import Data.OpenApi qualified as S import Data.Proxy -import Data.Swagger qualified as S import Data.Text qualified as Text import GHC.TypeLits import Imports @@ -33,10 +33,11 @@ import Network.Wai import Servant.API import Servant.API.ContentTypes import Servant.API.Status +import Servant.OpenApi (HasOpenApi (toOpenApi)) +import Servant.OpenApi as S +import Servant.OpenApi.Internal as S import Servant.Server hiding (respond) import Servant.Server.Internal -import Servant.Swagger as S -import Servant.Swagger.Internal as S import Wire.API.Routes.Version -- FUTUREWORK: make it possible to generate headers at runtime @@ -91,9 +92,9 @@ type instance instance (Accept ctype, KnownNat status, KnownSymbol desc, SwaggerMethod method) => - HasSwagger (LowLevelStream method status headers desc ctype) + HasOpenApi (LowLevelStream method status headers desc ctype) where - toSwagger _ = + toOpenApi _ = mempty & S.paths . at "/" diff --git a/libs/wire-api/src/Wire/API/Routes/MultiTablePaging.hs b/libs/wire-api/src/Wire/API/Routes/MultiTablePaging.hs index e0438210f77..29a00f89cc2 100644 --- a/libs/wire-api/src/Wire/API/Routes/MultiTablePaging.hs +++ b/libs/wire-api/src/Wire/API/Routes/MultiTablePaging.hs @@ -26,10 +26,10 @@ where import Control.Lens ((?~)) import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.Kind +import Data.OpenApi qualified as S import Data.Proxy import Data.Range import Data.Schema -import Data.Swagger qualified as S import Data.Text qualified as Text import GHC.TypeLits import Imports diff --git a/libs/wire-api/src/Wire/API/Routes/MultiTablePaging/State.hs b/libs/wire-api/src/Wire/API/Routes/MultiTablePaging/State.hs index 197e44a959b..7d43b3009be 100644 --- a/libs/wire-api/src/Wire/API/Routes/MultiTablePaging/State.hs +++ b/libs/wire-api/src/Wire/API/Routes/MultiTablePaging/State.hs @@ -26,9 +26,9 @@ import Data.Attoparsec.ByteString qualified as AB import Data.ByteString qualified as BS import Data.ByteString.Base64.URL qualified as Base64Url import Data.Either.Combinators (mapLeft) +import Data.OpenApi qualified as S import Data.Proxy import Data.Schema -import Data.Swagger qualified as S import Data.Text qualified as Text import Data.Text.Encoding qualified as Text import GHC.TypeLits diff --git a/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs b/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs index db16fb8fc01..30bcfe84bee 100644 --- a/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs +++ b/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs @@ -60,12 +60,14 @@ import Data.HashMap.Strict.InsOrd (InsOrdHashMap) import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap import Data.Kind import Data.Metrics.Servant +import Data.OpenApi hiding (HasServer, Response, contentType) +import Data.OpenApi qualified as S hiding (HasServer, Response, contentType) +import Data.OpenApi.Declare qualified as S +import Data.OpenApi.Lens qualified as S import Data.Proxy import Data.SOP import Data.Sequence (Seq, (<|), pattern (:<|)) import Data.Sequence qualified as Seq -import Data.Swagger qualified as S -import Data.Swagger.Declare qualified as S import Data.Text qualified as Text import Data.Text.Encoding qualified as Text import Data.Typeable @@ -82,10 +84,10 @@ import Servant.API.ContentTypes import Servant.API.Status (KnownStatus (..)) import Servant.Client import Servant.Client.Core hiding (addHeader) +import Servant.OpenApi as S +import Servant.OpenApi.Internal as S import Servant.Server import Servant.Server.Internal -import Servant.Swagger as S -import Servant.Swagger.Internal as S import Servant.Types.SourceT type Declare = S.Declare (S.Definitions S.Schema) @@ -150,7 +152,7 @@ instance MonadPlus UnrenderResult where mplus m@(UnrenderSuccess _) _ = m class IsSwaggerResponse a where - responseSwagger :: Declare S.Response + responseSwagger :: Declare S.Responses type family ResponseType a :: Type @@ -191,7 +193,7 @@ instance (AllMimeRender cs a, AllMimeUnrender cs a, KnownStatus s) => IsResponse Nothing -> empty Just f -> either UnrenderError UnrenderSuccess (f (responseBody output)) -simpleResponseSwagger :: forall a desc. (S.ToSchema a, KnownSymbol desc) => Declare S.Response +simpleResponseSwagger :: forall a desc. (S.ToSchema a, KnownSymbol desc) => Declare S.Responses simpleResponseSwagger = do ref <- S.declareSchemaRef (Proxy @a) pure $ @@ -423,7 +425,7 @@ instance (responseSwagger @r) class IsSwaggerResponseList as where - responseListSwagger :: Declare (InsOrdHashMap S.HttpStatusCode S.Response) + responseListSwagger :: Declare (InsOrdHashMap S.HttpStatusCode S.Responses) type family ResponseTypes (as :: [Type]) where ResponseTypes '[] = '[] @@ -473,7 +475,7 @@ instance <$> responseSwagger @a <*> responseListSwagger @as -combineResponseSwagger :: S.Response -> S.Response -> S.Response +combineResponseSwagger :: S.Responses -> S.Responses -> S.Responses combineResponseSwagger r1 r2 = r1 & S.description <>~ ("\n\n" <> r2 ^. S.description) @@ -698,44 +700,44 @@ instance fromUnion (S (S x)) = case x of {} instance - (SwaggerMethod method, IsSwaggerResponseList as) => - S.HasSwagger (MultiVerb method '() as r) + (OpenApiMethod method, IsSwaggerResponseList as) => + S.HasOpenApi (MultiVerb method '() as r) where - toSwagger _ = + toOpenApi _ = mempty - & S.definitions <>~ defs + & S.components . S.schemas <>~ defs & S.paths . at "/" ?~ ( mempty & method ?~ ( mempty - & S.responses . S.responses .~ fmap S.Inline responses + & S.responses . S.responses .~ fmap S.Inline resps ) ) where - method = S.swaggerMethod (Proxy @method) - (defs, responses) = S.runDeclare (responseListSwagger @as) mempty + method = S.openApiMethod (Proxy @method) + (defs, resps) = S.runDeclare (responseListSwagger @as) mempty instance - (SwaggerMethod method, IsSwaggerResponseList as, AllMime cs) => - S.HasSwagger (MultiVerb method (cs :: [Type]) as r) + (OpenApiMethod method, IsSwaggerResponseList as, AllMime cs) => + S.HasOpenApi (MultiVerb method (cs :: [Type]) as r) where - toSwagger _ = + toOpenApi _ = mempty - & S.definitions <>~ defs + & S.components . S.schemas <>~ defs & S.paths . at "/" ?~ ( mempty & method ?~ ( mempty & S.produces ?~ S.MimeList (nubOrd cs) - & S.responses . S.responses .~ fmap S.Inline responses + & S.responses . S.responses .~ fmap S.Inline resps ) ) where - method = S.swaggerMethod (Proxy @method) + method = S.openApiMethod (Proxy @method) cs = allMime (Proxy @cs) - (defs, responses) = S.runDeclare (responseListSwagger @as) mempty + (defs, resps) = S.runDeclare (responseListSwagger @as) mempty class Typeable a => IsWaiBody a where responseToWai :: ResponseF a -> Wai.Response diff --git a/libs/wire-api/src/Wire/API/Routes/Named.hs b/libs/wire-api/src/Wire/API/Routes/Named.hs index 804e3161ea2..e1cfc815f86 100644 --- a/libs/wire-api/src/Wire/API/Routes/Named.hs +++ b/libs/wire-api/src/Wire/API/Routes/Named.hs @@ -22,14 +22,15 @@ module Wire.API.Routes.Named where import Control.Lens ((%~)) import Data.Kind import Data.Metrics.Servant +import Data.OpenApi.Lens hiding (HasServer) +import Data.OpenApi.Operation import Data.Proxy -import Data.Swagger import GHC.TypeLits import Imports import Servant import Servant.Client import Servant.Client.Core (clientIn) -import Servant.Swagger +import Servant.OpenApi -- | See http://docs.wire.com/developer/developer/servant.html#named-and-internal-route-ids-in-swagger newtype Named name x = Named {unnamed :: x} @@ -46,9 +47,9 @@ instance {-# OVERLAPPABLE #-} KnownSymbol a => RenderableSymbol a where instance {-# OVERLAPPING #-} (RenderableSymbol a, RenderableSymbol b) => RenderableSymbol '(a, b) where renderSymbol = "(" <> (renderSymbol @a) <> ", " <> (renderSymbol @b) <> ")" -instance (HasSwagger api, RenderableSymbol name) => HasSwagger (Named name api) where - toSwagger _ = - toSwagger (Proxy @api) +instance (HasOpenApi api, RenderableSymbol name) => HasOpenApi (Named name api) where + toOpenApi _ = + toOpenApi (Proxy @api) & allOperations . description %~ (Just (dscr <> "\n\n") <>) where dscr :: Text diff --git a/libs/wire-api/src/Wire/API/Routes/Public.hs b/libs/wire-api/src/Wire/API/Routes/Public.hs index a9d5ab6646b..da1531415c7 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public.hs @@ -44,18 +44,18 @@ import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap import Data.Id as Id import Data.Kind import Data.Metrics.Servant +import Data.OpenApi hiding (Header) import Data.Qualified -import Data.Swagger hiding (Header) import GHC.Base (Symbol) import GHC.TypeLits (KnownSymbol) import Imports hiding (All, head) import Network.Wai qualified as Wai import Servant hiding (Handler, JSON, addHeader, respond) import Servant.API.Modifiers +import Servant.OpenApi (HasOpenApi (toOpenApi)) import Servant.Server.Internal.Delayed import Servant.Server.Internal.DelayedIO import Servant.Server.Internal.Router (Router) -import Servant.Swagger (HasSwagger (toSwagger)) import Wire.API.OAuth qualified as OAuth import Wire.API.Routes.Version @@ -223,8 +223,8 @@ type ZHostValue = Text type ZOptHostHeader = Header' '[Servant.Optional, Strict] "Z-Host" ZHostValue -instance HasSwagger api => HasSwagger (ZHostOpt :> api) where - toSwagger _ = toSwagger (Proxy @api) +instance HasOpenApi api => HasOpenApi (ZHostOpt :> api) where + toOpenApi _ = toOpenApi (Proxy @api) type instance SpecialiseToVersion v (ZHostOpt :> api) = ZHostOpt :> SpecialiseToVersion v api @@ -244,11 +244,11 @@ type instance SpecialiseToVersion v (ZAuthServant t opts :> api) = ZAuthServant t opts :> SpecialiseToVersion v api -instance HasSwagger api => HasSwagger (ZAuthServant 'ZAuthUser _opts :> api) where - toSwagger _ = addZAuthSwagger (toSwagger (Proxy @api)) +instance HasOpenApi api => HasOpenApi (ZAuthServant 'ZAuthUser _opts :> api) where + toOpenApi _ = addZAuthSwagger (toSwagger (Proxy @api)) -instance HasSwagger api => HasSwagger (ZAuthServant 'ZLocalAuthUser opts :> api) where - toSwagger _ = addZAuthSwagger (toSwagger (Proxy @api)) +instance HasOpenApi api => HasOpenApi (ZAuthServant 'ZLocalAuthUser opts :> api) where + toOpenApi _ = addZAuthSwagger (toSwagger (Proxy @api)) instance HasLink endpoint => HasLink (ZAuthServant usr opts :> endpoint) where type MkLink (ZAuthServant _ _ :> endpoint) a = MkLink endpoint a @@ -256,10 +256,10 @@ instance HasLink endpoint => HasLink (ZAuthServant usr opts :> endpoint) where instance {-# OVERLAPPABLE #-} - HasSwagger api => - HasSwagger (ZAuthServant ztype _opts :> api) + HasOpenApi api => + HasOpenApi (ZAuthServant ztype _opts :> api) where - toSwagger _ = toSwagger (Proxy @api) + toOpenApi _ = toOpenApi (Proxy @api) instance ( HasContextEntry (ctx .++ DefaultErrorFormatters) ErrorFormatters, @@ -331,10 +331,10 @@ type instance DescriptionOAuthScope scope :> SpecialiseToVersion v api instance - (HasSwagger api, OAuth.IsOAuthScope scope) => - HasSwagger (DescriptionOAuthScope scope :> api) + (HasOpenApi api, OAuth.IsOAuthScope scope) => + HasOpenApi (DescriptionOAuthScope scope :> api) where - toSwagger _ = addScopeDescription @scope (toSwagger (Proxy @api)) + toOpenApi _ = addScopeDescription @scope (toOpenApi (Proxy @api)) addScopeDescription :: forall scope. OAuth.IsOAuthScope scope => Swagger -> Swagger addScopeDescription = allOperations . description %~ Just . (<> "\nOAuth scope: `" <> cs (toByteString (OAuth.toOAuthScope @scope)) <> "`") . fold diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs b/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs index d83004bb54b..9b5a9317ee0 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs @@ -28,18 +28,18 @@ import Data.Handle import Data.Id as Id import Data.Misc (IpAddr) import Data.Nonce (Nonce) +import Data.OpenApi hiding (Contact, Header, Schema, ToSchema) +import Data.OpenApi qualified as S import Data.Qualified (Qualified (..)) import Data.Range import Data.SOP import Data.Schema as Schema -import Data.Swagger hiding (Contact, Header, Schema, ToSchema) -import Data.Swagger qualified as S import Generics.SOP qualified as GSOP import Imports hiding (head) import Network.Wai.Utilities import Servant (JSON) import Servant hiding (Handler, JSON, addHeader, respond) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Wire.API.Call.Config (RTCConfiguration) import Wire.API.Connection hiding (MissingLegalholdConsent) import Wire.API.Error diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Brig/Bot.hs b/libs/wire-api/src/Wire/API/Routes/Public/Brig/Bot.hs index 285202fb993..7e3259d8fca 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Brig/Bot.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Brig/Bot.hs @@ -22,7 +22,7 @@ import Data.Id as Id import Imports import Servant (JSON) import Servant hiding (Handler, JSON, Tagged, addHeader, respond) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Wire.API.Conversation.Bot import Wire.API.Error (CanThrow, ErrorResponse) import Wire.API.Error.Brig (BrigError (..)) diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Brig/OAuth.hs b/libs/wire-api/src/Wire/API/Routes/Public/Brig/OAuth.hs index 0a4adf52401..a096c78d975 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Brig/OAuth.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Brig/OAuth.hs @@ -22,7 +22,7 @@ import Data.SOP import Imports hiding (exp, head) import Servant (JSON) import Servant hiding (Handler, JSON, Tagged, addHeader, respond) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Wire.API.Error import Wire.API.OAuth import Wire.API.Routes.API diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Cargohold.hs b/libs/wire-api/src/Wire/API/Routes/Public/Cargohold.hs index 1ce9dd600cc..a1dc8001504 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Cargohold.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Cargohold.hs @@ -24,7 +24,7 @@ import Data.Qualified import Data.SOP import Imports import Servant -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import URI.ByteString import Wire.API.Asset import Wire.API.Error diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Galley.hs b/libs/wire-api/src/Wire/API/Routes/Public/Galley.hs index d24c473738e..52ec0ee5022 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Galley.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Galley.hs @@ -21,7 +21,7 @@ module Wire.API.Routes.Public.Galley where import Servant hiding (WithStatus) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Wire.API.Routes.API import Wire.API.Routes.Public.Galley.Bot import Wire.API.Routes.Public.Galley.Conversation diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Galley/Bot.hs b/libs/wire-api/src/Wire/API/Routes/Public/Galley/Bot.hs index 2c4752fda43..3eb711a96c8 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Galley/Bot.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Galley/Bot.hs @@ -18,7 +18,7 @@ module Wire.API.Routes.Public.Galley.Bot where import Servant hiding (WithStatus) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Wire.API.Error import Wire.API.Error.Galley import Wire.API.MakesFederatedCall diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Galley/Conversation.hs b/libs/wire-api/src/Wire/API/Routes/Public/Galley/Conversation.hs index 9b0b1250937..7c57c2cd9eb 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Galley/Conversation.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Galley/Conversation.hs @@ -24,7 +24,7 @@ import Data.Range import Data.SOP (I (..), NS (..)) import Imports hiding (head) import Servant hiding (WithStatus) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Wire.API.Conversation import Wire.API.Conversation.Code import Wire.API.Conversation.Role diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Galley/CustomBackend.hs b/libs/wire-api/src/Wire/API/Routes/Public/Galley/CustomBackend.hs index 079858baa0e..607a6e62573 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Galley/CustomBackend.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Galley/CustomBackend.hs @@ -19,7 +19,7 @@ module Wire.API.Routes.Public.Galley.CustomBackend where import Data.Domain import Servant hiding (WithStatus) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Wire.API.CustomBackend import Wire.API.Error import Wire.API.Error.Galley diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Galley/Feature.hs b/libs/wire-api/src/Wire/API/Routes/Public/Galley/Feature.hs index 1a7a5d11965..3c26645025d 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Galley/Feature.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Galley/Feature.hs @@ -20,7 +20,7 @@ module Wire.API.Routes.Public.Galley.Feature where import Data.Id import GHC.TypeLits import Servant hiding (WithStatus) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Wire.API.ApplyMods import Wire.API.Conversation.Role import Wire.API.Error diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Galley/LegalHold.hs b/libs/wire-api/src/Wire/API/Routes/Public/Galley/LegalHold.hs index 24848c46fd2..8a8b576f2c3 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Galley/LegalHold.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Galley/LegalHold.hs @@ -21,7 +21,7 @@ import Data.Id import GHC.Generics import Generics.SOP qualified as GSOP import Servant hiding (WithStatus) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Wire.API.Conversation.Role import Wire.API.Error import Wire.API.Error.Galley diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Galley/MLS.hs b/libs/wire-api/src/Wire/API/Routes/Public/Galley/MLS.hs index f026628c4e6..c54f9260512 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Galley/MLS.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Galley/MLS.hs @@ -18,7 +18,7 @@ module Wire.API.Routes.Public.Galley.MLS where import Servant hiding (WithStatus) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Wire.API.Error import Wire.API.Error.Galley import Wire.API.Event.Conversation diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Galley/Messaging.hs b/libs/wire-api/src/Wire/API/Routes/Public/Galley/Messaging.hs index b5f07834e7f..72aa70f4125 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Galley/Messaging.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Galley/Messaging.hs @@ -22,7 +22,7 @@ import Data.SOP import Generics.SOP qualified as GSOP import Imports import Servant hiding (WithStatus) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Wire.API.Error import Wire.API.Error.Brig qualified as BrigError import Wire.API.Error.Galley diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Galley/Team.hs b/libs/wire-api/src/Wire/API/Routes/Public/Galley/Team.hs index 3d3571dd23c..fd3fd392a4a 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Galley/Team.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Galley/Team.hs @@ -20,7 +20,7 @@ module Wire.API.Routes.Public.Galley.Team where import Data.Id import Imports import Servant hiding (WithStatus) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Wire.API.Error import Wire.API.Error.Galley import Wire.API.Routes.MultiVerb diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Galley/TeamConversation.hs b/libs/wire-api/src/Wire/API/Routes/Public/Galley/TeamConversation.hs index ce5fed146d5..a6a2c8aceb4 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Galley/TeamConversation.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Galley/TeamConversation.hs @@ -19,7 +19,7 @@ module Wire.API.Routes.Public.Galley.TeamConversation where import Data.Id import Servant hiding (WithStatus) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Wire.API.Conversation.Role import Wire.API.Error import Wire.API.Error.Galley diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Galley/TeamMember.hs b/libs/wire-api/src/Wire/API/Routes/Public/Galley/TeamMember.hs index 6d14ebc1483..4c71df03e49 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Galley/TeamMember.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Galley/TeamMember.hs @@ -23,7 +23,7 @@ import Data.Range import GHC.Generics import Generics.SOP qualified as GSOP import Servant hiding (WithStatus) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Wire.API.Error import Wire.API.Error.Galley import Wire.API.Routes.CSV diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs b/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs index 59b98ddc9eb..bb3144cb32a 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs @@ -25,7 +25,7 @@ import SAML2.WebSSO qualified as SAML import Servant import Servant.API.Extended import Servant.Multipart -import Servant.Swagger +import Servant.OpenApi import URI.ByteString qualified as URI import Web.Scim.Capabilities.MetaSchema as Scim.Meta import Web.Scim.Class.Auth as Scim.Auth diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Util.hs b/libs/wire-api/src/Wire/API/Routes/Public/Util.hs index 694230f7574..ab34186bb12 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Util.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Util.hs @@ -23,7 +23,7 @@ module Wire.API.Routes.Public.Util where import Control.Comonad import Data.SOP (I (..), NS (..)) import Servant -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Wire.API.Routes.MultiVerb instance diff --git a/libs/wire-api/src/Wire/API/Routes/QualifiedCapture.hs b/libs/wire-api/src/Wire/API/Routes/QualifiedCapture.hs index f54cccf4f36..48537e75b0e 100644 --- a/libs/wire-api/src/Wire/API/Routes/QualifiedCapture.hs +++ b/libs/wire-api/src/Wire/API/Routes/QualifiedCapture.hs @@ -24,16 +24,16 @@ where import Data.Domain import Data.Kind import Data.Metrics.Servant +import Data.OpenApi import Data.Qualified -import Data.Swagger import GHC.TypeLits import Imports import Servant import Servant.API.Description import Servant.API.Modifiers import Servant.Client.Core.HasClient +import Servant.OpenApi import Servant.Server.Internal.ErrorFormatter -import Servant.Swagger import Wire.API.Routes.Version -- | Capture a value qualified by a domain, with modifiers. @@ -58,14 +58,14 @@ type instance instance ( Typeable a, ToParamSchema a, - HasSwagger api, + HasOpenApi api, KnownSymbol capture, KnownSymbol (AppendSymbol capture "_domain"), KnownSymbol (FoldDescription mods) ) => - HasSwagger (QualifiedCapture' mods capture a :> api) + HasOpenApi (QualifiedCapture' mods capture a :> api) where - toSwagger _ = toSwagger (Proxy @(WithDomain mods capture a api)) + toOpenApi _ = toOpenApi (Proxy @(WithDomain mods capture a api)) instance ( KnownSymbol capture, diff --git a/libs/wire-api/src/Wire/API/Routes/Version.hs b/libs/wire-api/src/Wire/API/Routes/Version.hs index 826da8873a5..d2b2ce0888d 100644 --- a/libs/wire-api/src/Wire/API/Routes/Version.hs +++ b/libs/wire-api/src/Wire/API/Routes/Version.hs @@ -52,9 +52,9 @@ import Data.Binary.Builder qualified as Builder import Data.ByteString.Conversion (ToByteString (builder), toByteString') import Data.ByteString.Lazy qualified as LBS import Data.Domain +import Data.OpenApi qualified as S import Data.Schema import Data.Singletons.Base.TH -import Data.Swagger qualified as S import Data.Text qualified as Text import Data.Text.Encoding as Text import GHC.TypeLits diff --git a/libs/wire-api/src/Wire/API/Routes/Versioned.hs b/libs/wire-api/src/Wire/API/Routes/Versioned.hs index 1ca7bac0587..1bfb9e3ea92 100644 --- a/libs/wire-api/src/Wire/API/Routes/Versioned.hs +++ b/libs/wire-api/src/Wire/API/Routes/Versioned.hs @@ -20,15 +20,15 @@ module Wire.API.Routes.Versioned where import Data.Aeson (FromJSON, ToJSON) import Data.Kind import Data.Metrics.Servant +import Data.OpenApi qualified as S import Data.Schema import Data.Singletons -import Data.Swagger qualified as S import GHC.TypeLits import Imports import Servant import Servant.API.ContentTypes -import Servant.Swagger -import Servant.Swagger.Internal +import Servant.OpenApi +import Servant.OpenApi.Internal import Wire.API.Routes.MultiVerb import Wire.API.Routes.Version @@ -63,12 +63,12 @@ type instance instance ( S.ToSchema (Versioned v a), - HasSwagger api, + HasOpenApi api, AllAccept cts ) => - HasSwagger (VersionedReqBody v cts a :> api) + HasOpenApi (VersionedReqBody v cts a :> api) where - toSwagger _ = toSwagger (Proxy @(ReqBody cts (Versioned v a) :> api)) + toOpenApi _ = toOpenApi (Proxy @(ReqBody cts (Versioned v a) :> api)) -------------------------------------------------------------------------------- -- Versioned responses diff --git a/libs/wire-api/src/Wire/API/Routes/WebSocket.hs b/libs/wire-api/src/Wire/API/Routes/WebSocket.hs index 72354d95bc1..e0f3f658242 100644 --- a/libs/wire-api/src/Wire/API/Routes/WebSocket.hs +++ b/libs/wire-api/src/Wire/API/Routes/WebSocket.hs @@ -21,16 +21,16 @@ import Control.Lens import Control.Monad.Trans.Resource import Data.HashMap.Strict.InsOrd import Data.Metrics.Servant +import Data.OpenApi import Data.Proxy -import Data.Swagger import Imports import Network.Wai.Handler.WebSockets import Network.WebSockets +import Servant.OpenApi import Servant.Server hiding (respond) import Servant.Server.Internal.Delayed import Servant.Server.Internal.RouteResult import Servant.Server.Internal.Router -import Servant.Swagger import Wire.API.Routes.Version -- | A websocket that relates to a 'PendingConnection' @@ -65,8 +65,8 @@ instance HasServer WebSocketPending ctx where type instance SpecialiseToVersion v WebSocketPending = WebSocketPending -instance HasSwagger WebSocketPending where - toSwagger _ = +instance HasOpenApi WebSocketPending where + toOpenApi _ = mempty & paths . at "/" diff --git a/libs/wire-api/src/Wire/API/ServantProto.hs b/libs/wire-api/src/Wire/API/ServantProto.hs index 3eb06458fab..6e2dbd6140b 100644 --- a/libs/wire-api/src/Wire/API/ServantProto.hs +++ b/libs/wire-api/src/Wire/API/ServantProto.hs @@ -19,7 +19,7 @@ module Wire.API.ServantProto where import Data.ByteString.Lazy qualified as LBS import Data.List.NonEmpty (NonEmpty (..)) -import Data.Swagger +import Data.OpenApi import Imports import Network.HTTP.Media ((//)) import Servant diff --git a/libs/wire-api/src/Wire/API/SwaggerHelper.hs b/libs/wire-api/src/Wire/API/SwaggerHelper.hs index 9e1927156c1..43e760cdcb5 100644 --- a/libs/wire-api/src/Wire/API/SwaggerHelper.hs +++ b/libs/wire-api/src/Wire/API/SwaggerHelper.hs @@ -19,8 +19,8 @@ module Wire.API.SwaggerHelper where import Control.Lens import Data.Containers.ListUtils (nubOrd) -import Data.Swagger hiding (Contact, Header, Schema, ToSchema) -import Data.Swagger qualified as S +import Data.OpenApi hiding (Contact, Header, Schema, ToSchema) +import Data.OpenApi qualified as S import Imports hiding (head) cleanupSwagger :: Swagger -> Swagger diff --git a/libs/wire-api/src/Wire/API/SwaggerServant.hs b/libs/wire-api/src/Wire/API/SwaggerServant.hs index 89973fb59ae..5c3918cf39c 100644 --- a/libs/wire-api/src/Wire/API/SwaggerServant.hs +++ b/libs/wire-api/src/Wire/API/SwaggerServant.hs @@ -25,7 +25,7 @@ import Data.Metrics.Servant import Data.Proxy import Imports hiding (head) import Servant -import Servant.Swagger (HasSwagger (toSwagger)) +import Servant.OpenApi (HasOpenApi (toOpenApi)) -- | A type-level tag that lets us omit any branch from Swagger docs. -- @@ -34,8 +34,8 @@ import Servant.Swagger (HasSwagger (toSwagger)) -- it's only justification is laziness. data OmitDocs -instance HasSwagger (OmitDocs :> a) where - toSwagger _ = mempty +instance HasOpenApi (OmitDocs :> a) where + toOpenApi _ = mempty instance HasServer api ctx => HasServer (OmitDocs :> api) ctx where type ServerT (OmitDocs :> api) m = ServerT api m diff --git a/libs/wire-api/src/Wire/API/SystemSettings.hs b/libs/wire-api/src/Wire/API/SystemSettings.hs index d6098ac4ec5..d07d7152a44 100644 --- a/libs/wire-api/src/Wire/API/SystemSettings.hs +++ b/libs/wire-api/src/Wire/API/SystemSettings.hs @@ -19,10 +19,10 @@ module Wire.API.SystemSettings where import Control.Lens hiding ((.=)) import Data.Aeson qualified as A +import Data.OpenApi qualified as S import Data.Schema as Schema -import Data.Swagger qualified as S import Imports -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Test.QuickCheck import Wire.Arbitrary diff --git a/libs/wire-api/src/Wire/API/Team.hs b/libs/wire-api/src/Wire/API/Team.hs index fe3ed5e596c..87fad624fe5 100644 --- a/libs/wire-api/src/Wire/API/Team.hs +++ b/libs/wire-api/src/Wire/API/Team.hs @@ -76,9 +76,9 @@ import Data.ByteString.Conversion import Data.Code qualified as Code import Data.Id (TeamId, UserId) import Data.Misc (PlainTextPassword6) +import Data.OpenApi qualified as S import Data.Range import Data.Schema -import Data.Swagger qualified as S import Data.Text.Encoding qualified as T import Imports import Test.QuickCheck.Gen (suchThat) diff --git a/libs/wire-api/src/Wire/API/Team/Conversation.hs b/libs/wire-api/src/Wire/API/Team/Conversation.hs index ae020086104..3822a614923 100644 --- a/libs/wire-api/src/Wire/API/Team/Conversation.hs +++ b/libs/wire-api/src/Wire/API/Team/Conversation.hs @@ -35,8 +35,8 @@ where import Control.Lens (makeLenses, (?~)) import Data.Aeson qualified as A import Data.Id (ConvId) +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Imports import Wire.Arbitrary (Arbitrary, GenericUniform (..)) diff --git a/libs/wire-api/src/Wire/API/Team/Feature.hs b/libs/wire-api/src/Wire/API/Team/Feature.hs index 5e3a3bf9f39..2ccdb709649 100644 --- a/libs/wire-api/src/Wire/API/Team/Feature.hs +++ b/libs/wire-api/src/Wire/API/Team/Feature.hs @@ -98,10 +98,10 @@ import Data.Either.Extra (maybeToEither) import Data.Id import Data.Kind import Data.Misc (HttpsUrl) +import Data.OpenApi qualified as S import Data.Proxy import Data.Schema import Data.Scientific (toBoundedInteger) -import Data.Swagger qualified as S import Data.Text qualified as T import Data.Text.Encoding qualified as T import Data.Text.Lazy qualified as TL diff --git a/libs/wire-api/src/Wire/API/Team/Invitation.hs b/libs/wire-api/src/Wire/API/Team/Invitation.hs index 8593c67ce97..4ef104dc8a4 100644 --- a/libs/wire-api/src/Wire/API/Team/Invitation.hs +++ b/libs/wire-api/src/Wire/API/Team/Invitation.hs @@ -32,9 +32,9 @@ import Data.Aeson qualified as A import Data.ByteString.Conversion import Data.Id import Data.Json.Util +import Data.OpenApi qualified as S import Data.SOP import Data.Schema -import Data.Swagger qualified as S import Data.Text.Encoding qualified as TE import Imports import Servant (FromHttpApiData (..), ToHttpApiData (..)) diff --git a/libs/wire-api/src/Wire/API/Team/LegalHold.hs b/libs/wire-api/src/Wire/API/Team/LegalHold.hs index d72dafb5da8..fe6c88c32f2 100644 --- a/libs/wire-api/src/Wire/API/Team/LegalHold.hs +++ b/libs/wire-api/src/Wire/API/Team/LegalHold.hs @@ -35,9 +35,9 @@ import Data.Aeson.Types qualified as A import Data.Id import Data.LegalHold import Data.Misc +import Data.OpenApi qualified as S hiding (info) import Data.Proxy import Data.Schema -import Data.Swagger qualified as S hiding (info) import Deriving.Aeson import Imports import Wire.API.Provider diff --git a/libs/wire-api/src/Wire/API/Team/LegalHold/External.hs b/libs/wire-api/src/Wire/API/Team/LegalHold/External.hs index ea892087bfe..8dc5fd14366 100644 --- a/libs/wire-api/src/Wire/API/Team/LegalHold/External.hs +++ b/libs/wire-api/src/Wire/API/Team/LegalHold/External.hs @@ -34,7 +34,7 @@ where import Data.Aeson hiding (fieldLabelModifier) import Data.Id import Data.Json.Util ((#)) -import Data.Swagger +import Data.OpenApi import Imports import Wire.API.User.Client.Prekey import Wire.Arbitrary (Arbitrary, GenericUniform (..)) diff --git a/libs/wire-api/src/Wire/API/Team/LegalHold/Internal.hs b/libs/wire-api/src/Wire/API/Team/LegalHold/Internal.hs index cb3915f4a38..e706f472fc6 100644 --- a/libs/wire-api/src/Wire/API/Team/LegalHold/Internal.hs +++ b/libs/wire-api/src/Wire/API/Team/LegalHold/Internal.hs @@ -29,8 +29,8 @@ import Data.Aeson import Data.Id import Data.Json.Util import Data.Misc +import Data.OpenApi qualified as Swagger import Data.Schema qualified as Schema -import Data.Swagger qualified as Swagger import Imports import Wire.API.Provider import Wire.API.Provider.Service diff --git a/libs/wire-api/src/Wire/API/Team/Member.hs b/libs/wire-api/src/Wire/API/Team/Member.hs index d47061389b5..c962bcf8c00 100644 --- a/libs/wire-api/src/Wire/API/Team/Member.hs +++ b/libs/wire-api/src/Wire/API/Team/Member.hs @@ -74,10 +74,10 @@ import Data.Json.Util import Data.Kind import Data.LegalHold (UserLegalHoldStatus (..), defUserLegalHoldStatus) import Data.Misc (PlainTextPassword6) +import Data.OpenApi (ToParamSchema (..)) +import Data.OpenApi.Schema qualified as S import Data.Proxy import Data.Schema -import Data.Swagger (ToParamSchema (..)) -import Data.Swagger.Schema qualified as S import GHC.TypeLits import Imports import Wire.API.Routes.MultiTablePaging (MultiTablePage (..)) diff --git a/libs/wire-api/src/Wire/API/Team/Permission.hs b/libs/wire-api/src/Wire/API/Team/Permission.hs index be29d6b46d1..49a9893b370 100644 --- a/libs/wire-api/src/Wire/API/Team/Permission.hs +++ b/libs/wire-api/src/Wire/API/Team/Permission.hs @@ -48,10 +48,10 @@ import Control.Error.Util qualified as Err import Control.Lens (makeLenses, (?~), (^.)) import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.Bits (testBit, (.|.)) +import Data.OpenApi qualified as S import Data.Schema import Data.Set qualified as Set import Data.Singletons.Base.TH -import Data.Swagger qualified as S import Imports import Wire.API.Util.Aeson (CustomEncoded (..)) import Wire.Arbitrary (Arbitrary (arbitrary), GenericUniform (..)) diff --git a/libs/wire-api/src/Wire/API/Team/Role.hs b/libs/wire-api/src/Wire/API/Team/Role.hs index 424065e66c0..4707d3d9884 100644 --- a/libs/wire-api/src/Wire/API/Team/Role.hs +++ b/libs/wire-api/src/Wire/API/Team/Role.hs @@ -29,8 +29,8 @@ import Control.Lens ((?~)) import Data.Aeson import Data.Attoparsec.ByteString.Char8 (string) import Data.ByteString.Conversion (FromByteString (..), ToByteString (..)) +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Data.Text qualified as T import Imports import Servant.API (FromHttpApiData, parseQueryParam) diff --git a/libs/wire-api/src/Wire/API/Team/SearchVisibility.hs b/libs/wire-api/src/Wire/API/Team/SearchVisibility.hs index b41300a8b7a..76d530f6f15 100644 --- a/libs/wire-api/src/Wire/API/Team/SearchVisibility.hs +++ b/libs/wire-api/src/Wire/API/Team/SearchVisibility.hs @@ -24,8 +24,8 @@ module Wire.API.Team.SearchVisibility where import Control.Lens ((?~)) +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Deriving.Aeson import Imports import Wire.Arbitrary (Arbitrary, GenericUniform (..)) diff --git a/libs/wire-api/src/Wire/API/Team/Size.hs b/libs/wire-api/src/Wire/API/Team/Size.hs index 811a7a094e6..ce0d8fe6468 100644 --- a/libs/wire-api/src/Wire/API/Team/Size.hs +++ b/libs/wire-api/src/Wire/API/Team/Size.hs @@ -22,8 +22,8 @@ where import Control.Lens ((?~)) import Data.Aeson qualified as A +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Imports import Numeric.Natural diff --git a/libs/wire-api/src/Wire/API/Unreachable.hs b/libs/wire-api/src/Wire/API/Unreachable.hs index baf37558eff..54055ae6359 100644 --- a/libs/wire-api/src/Wire/API/Unreachable.hs +++ b/libs/wire-api/src/Wire/API/Unreachable.hs @@ -28,9 +28,9 @@ import Data.Aeson qualified as A import Data.Id import Data.List.NonEmpty import Data.List.NonEmpty qualified as NE +import Data.OpenApi qualified as S import Data.Qualified import Data.Schema -import Data.Swagger qualified as S import Imports newtype UnreachableUsers = UnreachableUsers {unreachableUsers :: NonEmpty (Qualified UserId)} diff --git a/libs/wire-api/src/Wire/API/User.hs b/libs/wire-api/src/Wire/API/User.hs index 9404502ca68..3ea0e88106f 100644 --- a/libs/wire-api/src/Wire/API/User.hs +++ b/libs/wire-api/src/Wire/API/User.hs @@ -177,13 +177,13 @@ import Data.Json.Util (UTCTimeMillis, (#)) import Data.LegalHold (UserLegalHoldStatus) import Data.List.NonEmpty (NonEmpty (..)) import Data.Misc (PlainTextPassword6, PlainTextPassword8) +import Data.OpenApi qualified as S import Data.Qualified import Data.Range import Data.SOP import Data.Schema import Data.Schema qualified as Schema import Data.Set qualified as Set -import Data.Swagger qualified as S import Data.Text qualified as T import Data.Text.Ascii import Data.Text.Encoding qualified as T diff --git a/libs/wire-api/src/Wire/API/User/Activation.hs b/libs/wire-api/src/Wire/API/User/Activation.hs index 7777b2c25b8..e14b30bc326 100644 --- a/libs/wire-api/src/Wire/API/User/Activation.hs +++ b/libs/wire-api/src/Wire/API/User/Activation.hs @@ -40,9 +40,9 @@ import Data.Aeson qualified as A import Data.Aeson.Types (Parser) import Data.ByteString.Conversion import Data.Data (Proxy (Proxy)) +import Data.OpenApi (ToParamSchema) +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger (ToParamSchema) -import Data.Swagger qualified as S import Data.Text.Ascii import Data.Tuple.Extra (fst3, snd3, thd3) import Imports diff --git a/libs/wire-api/src/Wire/API/User/Auth.hs b/libs/wire-api/src/Wire/API/User/Auth.hs index 8670a4bc20e..df15827e2e2 100644 --- a/libs/wire-api/src/Wire/API/User/Auth.hs +++ b/libs/wire-api/src/Wire/API/User/Auth.hs @@ -71,9 +71,9 @@ import Data.Handle (Handle) import Data.Id import Data.Json.Util import Data.Misc (PlainTextPassword6) +import Data.OpenApi qualified as S import Data.SOP import Data.Schema -import Data.Swagger qualified as S import Data.Text qualified as T import Data.Text.Encoding qualified as T import Data.Text.Lazy.Encoding qualified as LT @@ -554,7 +554,7 @@ utcToSetCookie c = } instance S.ToParamSchema UserTokenCookie where - toParamSchema _ = mempty & S.type_ ?~ S.SwaggerString + toParamSchema _ = mempty & S.type_ ?~ S.OpenApiString instance FromHttpApiData UserTokenCookie where parseHeader = utcFromSetCookie . parseSetCookie diff --git a/libs/wire-api/src/Wire/API/User/Auth/LegalHold.hs b/libs/wire-api/src/Wire/API/User/Auth/LegalHold.hs index 951b2c19ab2..b1f20c416a8 100644 --- a/libs/wire-api/src/Wire/API/User/Auth/LegalHold.hs +++ b/libs/wire-api/src/Wire/API/User/Auth/LegalHold.hs @@ -21,8 +21,8 @@ import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.Aeson qualified as A import Data.Id import Data.Misc +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Imports import Wire.API.User.Auth diff --git a/libs/wire-api/src/Wire/API/User/Auth/ReAuth.hs b/libs/wire-api/src/Wire/API/User/Auth/ReAuth.hs index 040698e848a..0892089a90d 100644 --- a/libs/wire-api/src/Wire/API/User/Auth/ReAuth.hs +++ b/libs/wire-api/src/Wire/API/User/Auth/ReAuth.hs @@ -25,8 +25,8 @@ import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.Aeson qualified as A import Data.Code import Data.Misc +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Imports import Wire.API.User diff --git a/libs/wire-api/src/Wire/API/User/Auth/Sso.hs b/libs/wire-api/src/Wire/API/User/Auth/Sso.hs index 6e061536e01..0c9daa86859 100644 --- a/libs/wire-api/src/Wire/API/User/Auth/Sso.hs +++ b/libs/wire-api/src/Wire/API/User/Auth/Sso.hs @@ -20,8 +20,8 @@ module Wire.API.User.Auth.Sso where import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.Aeson qualified as A import Data.Id +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Imports import Wire.API.User.Auth diff --git a/libs/wire-api/src/Wire/API/User/Client.hs b/libs/wire-api/src/Wire/API/User/Client.hs index 761d8b7337e..ea69ade56db 100644 --- a/libs/wire-api/src/Wire/API/User/Client.hs +++ b/libs/wire-api/src/Wire/API/User/Client.hs @@ -83,11 +83,11 @@ import Data.Id import Data.Json.Util import Data.Map.Strict qualified as Map import Data.Misc (Latitude (..), Location, Longitude (..), PlainTextPassword6, latitude, location, longitude) +import Data.OpenApi hiding (Schema, ToSchema, schema) +import Data.OpenApi qualified as Swagger import Data.Qualified import Data.Schema import Data.Set qualified as Set -import Data.Swagger hiding (Schema, ToSchema, schema) -import Data.Swagger qualified as Swagger import Data.Text.Encoding qualified as Text.E import Data.Time.Clock import Data.UUID (toASCIIBytes) diff --git a/libs/wire-api/src/Wire/API/User/Client/DPoPAccessToken.hs b/libs/wire-api/src/Wire/API/User/Client/DPoPAccessToken.hs index df719886f37..99ed6e13d92 100644 --- a/libs/wire-api/src/Wire/API/User/Client/DPoPAccessToken.hs +++ b/libs/wire-api/src/Wire/API/User/Client/DPoPAccessToken.hs @@ -22,10 +22,10 @@ module Wire.API.User.Client.DPoPAccessToken where import Data.Aeson (FromJSON, ToJSON) import Data.ByteString.Conversion (FromByteString (..), ToByteString (..), fromByteString', toByteString') +import Data.OpenApi qualified as S +import Data.OpenApi.ParamSchema (ToParamSchema (..)) import Data.SOP import Data.Schema -import Data.Swagger qualified as S -import Data.Swagger.ParamSchema (ToParamSchema (..)) import Data.Text as T import Data.Text.Encoding (decodeUtf8, encodeUtf8) import Imports diff --git a/libs/wire-api/src/Wire/API/User/Client/Prekey.hs b/libs/wire-api/src/Wire/API/User/Client/Prekey.hs index 4f03328465a..f58eaa000ed 100644 --- a/libs/wire-api/src/Wire/API/User/Client/Prekey.hs +++ b/libs/wire-api/src/Wire/API/User/Client/Prekey.hs @@ -35,8 +35,8 @@ where import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.Hashable (hash) import Data.Id +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Imports import Wire.Arbitrary (Arbitrary (arbitrary), GenericUniform (..)) diff --git a/libs/wire-api/src/Wire/API/User/Handle.hs b/libs/wire-api/src/Wire/API/User/Handle.hs index 08242a6dfe9..3db27ef8c12 100644 --- a/libs/wire-api/src/Wire/API/User/Handle.hs +++ b/libs/wire-api/src/Wire/API/User/Handle.hs @@ -28,10 +28,10 @@ import Control.Applicative import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.Aeson qualified as A import Data.Id (UserId) +import Data.OpenApi qualified as S import Data.Qualified (Qualified (..), deprecatedSchema) import Data.Range import Data.Schema -import Data.Swagger qualified as S import Imports import Wire.Arbitrary (Arbitrary, GenericUniform (..)) diff --git a/libs/wire-api/src/Wire/API/User/Identity.hs b/libs/wire-api/src/Wire/API/User/Identity.hs index c71bec44864..013da379b15 100644 --- a/libs/wire-api/src/Wire/API/User/Identity.hs +++ b/libs/wire-api/src/Wire/API/User/Identity.hs @@ -61,9 +61,9 @@ import Data.Attoparsec.Text import Data.Bifunctor (first) import Data.ByteString.Conversion import Data.CaseInsensitive qualified as CI +import Data.OpenApi (ToParamSchema (..)) +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger (ToParamSchema (..)) -import Data.Swagger qualified as S import Data.Text qualified as Text import Data.Text.Encoding (decodeUtf8', encodeUtf8) import Data.Time.Clock diff --git a/libs/wire-api/src/Wire/API/User/IdentityProvider.hs b/libs/wire-api/src/Wire/API/User/IdentityProvider.hs index e17db47e465..6d89141ba47 100644 --- a/libs/wire-api/src/Wire/API/User/IdentityProvider.hs +++ b/libs/wire-api/src/Wire/API/User/IdentityProvider.hs @@ -30,8 +30,8 @@ import Data.ByteString.Conversion qualified as BSC import Data.HashMap.Strict.InsOrd (InsOrdHashMap) import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap import Data.Id (TeamId) +import Data.OpenApi import Data.Proxy (Proxy (Proxy)) -import Data.Swagger import Imports import Network.HTTP.Media ((//)) import SAML2.WebSSO (IdPConfig) diff --git a/libs/wire-api/src/Wire/API/User/Orphans.hs b/libs/wire-api/src/Wire/API/User/Orphans.hs index 05f49534e4f..7331b156410 100644 --- a/libs/wire-api/src/Wire/API/User/Orphans.hs +++ b/libs/wire-api/src/Wire/API/User/Orphans.hs @@ -26,8 +26,8 @@ import Data.Char import Data.Currency qualified as Currency import Data.ISO3166_CountryCodes import Data.LanguageCodes +import Data.OpenApi import Data.Proxy -import Data.Swagger import Data.UUID import Data.X509 as X509 import Imports @@ -35,7 +35,7 @@ import SAML2.WebSSO qualified as SAML import SAML2.WebSSO.Types.TH (deriveJSONOptions) import Servant.API ((:>)) import Servant.Multipart qualified as SM -import Servant.Swagger +import Servant.OpenApi import URI.ByteString deriving instance Generic ISO639_1 @@ -110,8 +110,8 @@ instance ToSchema SAML.SPMetadata where instance ToSchema Void where declareNamedSchema _ = declareNamedSchema (Proxy @String) -instance HasSwagger route => HasSwagger (SM.MultipartForm SM.Mem resp :> route) where - toSwagger _proxy = toSwagger (Proxy @route) +instance HasOpenApi route => HasOpenApi (SM.MultipartForm SM.Mem resp :> route) where + toOpenApi _proxy = toOpenApi (Proxy @route) instance ToSchema SAML.IdPId where declareNamedSchema _ = declareNamedSchema (Proxy @UUID) diff --git a/libs/wire-api/src/Wire/API/User/Password.hs b/libs/wire-api/src/Wire/API/User/Password.hs index 2a6b9bf20ed..4f14e4ca7c6 100644 --- a/libs/wire-api/src/Wire/API/User/Password.hs +++ b/libs/wire-api/src/Wire/API/User/Password.hs @@ -36,11 +36,11 @@ import Data.Aeson qualified as A import Data.Aeson.Types (Parser) import Data.ByteString.Conversion import Data.Misc (PlainTextPassword8) +import Data.OpenApi qualified as S +import Data.OpenApi.ParamSchema import Data.Proxy (Proxy (Proxy)) import Data.Range (Ranged (..)) import Data.Schema as Schema -import Data.Swagger qualified as S -import Data.Swagger.ParamSchema import Data.Text.Ascii import Data.Tuple.Extra (fst3, snd3, thd3) import Imports diff --git a/libs/wire-api/src/Wire/API/User/Profile.hs b/libs/wire-api/src/Wire/API/User/Profile.hs index 8f03b39b375..ae018f20b75 100644 --- a/libs/wire-api/src/Wire/API/User/Profile.hs +++ b/libs/wire-api/src/Wire/API/User/Profile.hs @@ -58,9 +58,9 @@ import Data.Attoparsec.Text import Data.ByteString.Conversion import Data.ISO3166_CountryCodes import Data.LanguageCodes +import Data.OpenApi qualified as S import Data.Range import Data.Schema -import Data.Swagger qualified as S import Data.Text qualified as Text import Imports import Wire.API.Asset (AssetKey (..)) diff --git a/libs/wire-api/src/Wire/API/User/RichInfo.hs b/libs/wire-api/src/Wire/API/User/RichInfo.hs index ef0eac713e8..32a3db8fa19 100644 --- a/libs/wire-api/src/Wire/API/User/RichInfo.hs +++ b/libs/wire-api/src/Wire/API/User/RichInfo.hs @@ -52,8 +52,8 @@ import Data.CaseInsensitive (CI) import Data.CaseInsensitive qualified as CI import Data.List.Extra (nubOrdOn) import Data.Map qualified as Map +import Data.OpenApi qualified as S import Data.Schema -import Data.Swagger qualified as S import Data.Text qualified as Text import Imports import Test.QuickCheck qualified as QC diff --git a/libs/wire-api/src/Wire/API/User/Saml.hs b/libs/wire-api/src/Wire/API/User/Saml.hs index 8ff2e27c954..09ad0d24367 100644 --- a/libs/wire-api/src/Wire/API/User/Saml.hs +++ b/libs/wire-api/src/Wire/API/User/Saml.hs @@ -30,8 +30,8 @@ import Data.Aeson hiding (fieldLabelModifier) import Data.Aeson.TH hiding (fieldLabelModifier) import Data.ByteString.Builder qualified as Builder import Data.Id (UserId) +import Data.OpenApi import Data.Proxy (Proxy (Proxy)) -import Data.Swagger import Data.Text qualified as T import Data.Time import GHC.TypeLits (KnownSymbol, symbolVal) diff --git a/libs/wire-api/src/Wire/API/User/Scim.hs b/libs/wire-api/src/Wire/API/User/Scim.hs index f3440beea7b..76c5a3755ae 100644 --- a/libs/wire-api/src/Wire/API/User/Scim.hs +++ b/libs/wire-api/src/Wire/API/User/Scim.hs @@ -59,8 +59,8 @@ import Data.Id (ScimTokenId, TeamId, UserId) import Data.Json.Util ((#)) import Data.Map qualified as Map import Data.Misc (PlainTextPassword6) +import Data.OpenApi hiding (Operation) import Data.Proxy -import Data.Swagger hiding (Operation) import Data.Text.Encoding (encodeUtf8) import Data.Time.Clock (UTCTime) import Imports diff --git a/libs/wire-api/src/Wire/API/User/Search.hs b/libs/wire-api/src/Wire/API/User/Search.hs index 819f0111ab0..0ad5dcaa34b 100644 --- a/libs/wire-api/src/Wire/API/User/Search.hs +++ b/libs/wire-api/src/Wire/API/User/Search.hs @@ -43,11 +43,11 @@ import Data.ByteString.Conversion (FromByteString (..), ToByteString (..)) import Data.Either.Combinators (mapLeft) import Data.Id (TeamId, UserId) import Data.Json.Util (UTCTimeMillis) +import Data.OpenApi (ToParamSchema (..)) +import Data.OpenApi qualified as S import Data.Proxy import Data.Qualified import Data.Schema -import Data.Swagger (ToParamSchema (..)) -import Data.Swagger qualified as S import Data.Text qualified as T import Data.Text.Ascii (AsciiBase64Url, toText, validateBase64Url) import Imports diff --git a/libs/wire-api/src/Wire/API/UserMap.hs b/libs/wire-api/src/Wire/API/UserMap.hs index bcf41da1559..51ed966e0ff 100644 --- a/libs/wire-api/src/Wire/API/UserMap.hs +++ b/libs/wire-api/src/Wire/API/UserMap.hs @@ -24,9 +24,9 @@ import Data.Aeson (FromJSON, ToJSON (toJSON)) import Data.Domain (Domain) import Data.Id (UserId) import Data.Map qualified as Map +import Data.OpenApi (HasDescription (description), HasExample (example), NamedSchema (..), ToSchema (..), declareSchema, toSchema) import Data.Proxy (Proxy (..)) import Data.Set qualified as Set -import Data.Swagger (HasDescription (description), HasExample (example), NamedSchema (..), ToSchema (..), declareSchema, toSchema) import Data.Text qualified as Text import Data.Typeable (typeRep) import Imports diff --git a/libs/wire-api/src/Wire/API/Wrapped.hs b/libs/wire-api/src/Wire/API/Wrapped.hs index f6d71142a5f..0dc9d6edf4f 100644 --- a/libs/wire-api/src/Wire/API/Wrapped.hs +++ b/libs/wire-api/src/Wire/API/Wrapped.hs @@ -21,8 +21,8 @@ import Control.Lens ((.~), (?~)) import Data.Aeson import Data.Aeson.Key qualified as Key import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap +import Data.OpenApi import Data.Proxy (Proxy (..)) -import Data.Swagger import Data.Text qualified as Text import GHC.TypeLits (KnownSymbol, Symbol, symbolVal) import Imports diff --git a/libs/wire-api/test/unit/Test/Wire/API/Roundtrip/Aeson.hs b/libs/wire-api/test/unit/Test/Wire/API/Roundtrip/Aeson.hs index 79433dbd2d7..ed5c9ed1dc0 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Roundtrip/Aeson.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Roundtrip/Aeson.hs @@ -20,7 +20,7 @@ module Test.Wire.API.Roundtrip.Aeson (tests) where import Data.Aeson (FromJSON, ToJSON, parseJSON, toJSON) import Data.Aeson.Types (parseEither) import Data.Id (ConvId) -import Data.Swagger (ToSchema, validatePrettyToJSON) +import Data.OpenApi (ToSchema, validatePrettyToJSON) import Imports import Test.Tasty qualified as T import Test.Tasty.QuickCheck (Arbitrary, counterexample, testProperty, (.&&.), (===)) diff --git a/libs/wire-api/test/unit/Test/Wire/API/Swagger.hs b/libs/wire-api/test/unit/Test/Wire/API/Swagger.hs index 8de2cb6ad16..bab30d63e56 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Swagger.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Swagger.hs @@ -18,7 +18,7 @@ module Test.Wire.API.Swagger (tests) where import Data.Aeson (ToJSON) -import Data.Swagger (ToSchema, validatePrettyToJSON) +import Data.OpenApi (ToSchema, validatePrettyToJSON) import Imports import Test.Tasty qualified as T import Test.Tasty.QuickCheck (Arbitrary, counterexample, testProperty) diff --git a/libs/wire-api/wire-api.cabal b/libs/wire-api/wire-api.cabal index e488149d735..fb49f7fda89 100644 --- a/libs/wire-api/wire-api.cabal +++ b/libs/wire-api/wire-api.cabal @@ -270,6 +270,7 @@ library , metrics-wai , mime >=0.4 , mtl + , openapi3 >=3.2 && <3.2.3 , pem >=0.2 , polysemy , proto-lens @@ -288,13 +289,12 @@ library , servant-client-core , servant-conduit , servant-multipart + , servant-openapi3 , servant-server - , servant-swagger , singletons , singletons-base , singletons-th , sop-core - , swagger2 , tagged , text >=0.11 , time >=1.4 @@ -748,12 +748,12 @@ test-suite wire-api-tests , imports , memory , metrics-wai + , openapi3 >=3.2 && <3.2.3 , process , QuickCheck , schema-profunctor , servant , servant-server - , swagger2 , tasty , tasty-hspec , tasty-hunit diff --git a/nix/haskell-pins.nix b/nix/haskell-pins.nix index 291ea06526f..3dd60216d1b 100644 --- a/nix/haskell-pins.nix +++ b/nix/haskell-pins.nix @@ -133,13 +133,6 @@ let sha256 = "sha256-g2lbKt3+hToVFQvaHOa9dg4HqAL7YgReo8fy7wQavmY="; }; }; - swagger2 = { - src = fetchgit { - url = "https://github.com/GetShopTV/swagger2"; - rev = "d79deca03b714cdd4531217831a8305068b2e8f9"; - sha256 = "sha256-R3p0L0TgM0Bspe5z6vauwdPq9TmEWpMC53DBkMtCEoE="; - }; - }; # MR: https://gitlab.com/twittner/cql-io/-/merge_requests/20 cql-io = { src = fetchgit { diff --git a/nix/manual-overrides.nix b/nix/manual-overrides.nix index 74c0da56158..f8764ed2c16 100644 --- a/nix/manual-overrides.nix +++ b/nix/manual-overrides.nix @@ -20,7 +20,6 @@ hself: hsuper: { servant-swagger-ui = hlib.doJailbreak hsuper.servant-swagger-ui; servant-swagger-ui-core = hlib.doJailbreak hsuper.servant-swagger-ui-core; sodium-crypto-sign = hlib.addPkgconfigDepend hsuper.sodium-crypto-sign libsodium.dev; - swagger2 = hlib.doJailbreak hsuper.swagger2; text-icu-translit = hlib.markUnbroken (hlib.dontCheck hsuper.text-icu-translit); text-short = hlib.dontCheck hsuper.text-short; type-errors = hlib.dontCheck hsuper.type-errors; diff --git a/services/brig/brig.cabal b/services/brig/brig.cabal index 998ff4edf7b..ab8dea22ec1 100644 --- a/services/brig/brig.cabal +++ b/services/brig/brig.cabal @@ -257,6 +257,7 @@ library , mwc-random , network >=2.4 , network-conduit-tls + , openapi3 >=3.2 && <3.2.3 , optparse-applicative >=0.11 , polysemy , polysemy-plugin @@ -273,15 +274,14 @@ library , schema-profunctor , scientific >=0.3.4 , servant + , servant-openapi3 , servant-server - , servant-swagger , servant-swagger-ui , sodium-crypto-sign >=0.1 , split >=0.2 , ssl-util , statistics >=0.13 , stomp-queue >=0.3 - , swagger2 , template >=0.2 , template-haskell , text >=0.11 diff --git a/services/brig/default.nix b/services/brig/default.nix index e5859de9282..e17576c196d 100644 --- a/services/brig/default.nix +++ b/services/brig/default.nix @@ -85,6 +85,7 @@ , network , network-conduit-tls , network-uri +, openapi3 , optparse-applicative , pem , pipes @@ -110,8 +111,8 @@ , servant , servant-client , servant-client-core +, servant-openapi3 , servant-server -, servant-swagger , servant-swagger-ui , sodium-crypto-sign , spar @@ -120,7 +121,6 @@ , statistics , stomp-queue , streaming-commons -, swagger2 , tasty , tasty-cannon , tasty-hunit @@ -235,6 +235,7 @@ mkDerivation { mwc-random network network-conduit-tls + openapi3 optparse-applicative polysemy polysemy-plugin @@ -251,15 +252,14 @@ mkDerivation { schema-profunctor scientific servant + servant-openapi3 servant-server - servant-swagger servant-swagger-ui sodium-crypto-sign split ssl-util statistics stomp-queue - swagger2 template template-haskell text diff --git a/services/brig/src/Brig/API/Internal.hs b/services/brig/src/Brig/API/Internal.hs index cd2393132ee..67f4e0d7e96 100644 --- a/services/brig/src/Brig/API/Internal.hs +++ b/services/brig/src/Brig/API/Internal.hs @@ -78,7 +78,7 @@ import Network.Wai.Routing hiding (toList) import Network.Wai.Utilities as Utilities import Polysemy import Servant hiding (Handler, JSON, addHeader, respond) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import System.Logger qualified as Lg import System.Logger.Class qualified as Log import System.Random (randomRIO) diff --git a/services/brig/src/Brig/API/Public.hs b/services/brig/src/Brig/API/Public.hs index 46665c7122f..9aed2db83c8 100644 --- a/services/brig/src/Brig/API/Public.hs +++ b/services/brig/src/Brig/API/Public.hs @@ -88,9 +88,9 @@ import Data.List.NonEmpty (nonEmpty) import Data.Map.Strict qualified as Map import Data.Misc (IpAddr (..)) import Data.Nonce (Nonce, randomNonce) +import Data.OpenApi qualified as S import Data.Qualified import Data.Range -import Data.Swagger qualified as S import Data.Text qualified as Text import Data.Text.Ascii qualified as Ascii import Data.Text.Lazy (pack) @@ -104,7 +104,7 @@ import Network.Wai.Utilities as Utilities import Polysemy import Servant hiding (Handler, JSON, addHeader, respond) import Servant qualified -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Servant.Swagger.UI import System.Logger.Class qualified as Log import Util.Logging (logFunction, logHandle, logTeam, logUser) diff --git a/services/brig/src/Brig/API/Public/Swagger.hs b/services/brig/src/Brig/API/Public/Swagger.hs index 0f81a74a4d4..3debaac9ba1 100644 --- a/services/brig/src/Brig/API/Public/Swagger.hs +++ b/services/brig/src/Brig/API/Public/Swagger.hs @@ -18,8 +18,8 @@ import Data.Aeson qualified as A import Data.FileEmbed import Data.HashMap.Strict.InsOrd qualified as HM import Data.HashSet.InsOrd qualified as InsOrdSet -import Data.Swagger qualified as S -import Data.Swagger.Declare qualified as S +import Data.OpenApi qualified as S +import Data.OpenApi.Declare qualified as S import Data.Text qualified as T import FileEmbedLzma import GHC.TypeLits @@ -27,7 +27,7 @@ import Imports hiding (head) import Language.Haskell.TH import Network.Socket import Servant -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Servant.Swagger.UI import Wire.API.Event.Conversation qualified import Wire.API.Event.FeatureConfig qualified diff --git a/services/brig/src/Brig/User/EJPD.hs b/services/brig/src/Brig/User/EJPD.hs index 07116e81207..fea8e51a37a 100644 --- a/services/brig/src/Brig/User/EJPD.hs +++ b/services/brig/src/Brig/User/EJPD.hs @@ -36,7 +36,7 @@ import Data.Id (UserId) import Data.Set qualified as Set import Imports hiding (head) import Polysemy (Member) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi.Internal.Orphans () import Wire.API.Connection (Relation, RelationWithHistory (..), relationDropHistory) import Wire.API.Push.Token qualified as PushTok import Wire.API.Routes.Internal.Brig.EJPD (EJPDRequestBody (EJPDRequestBody), EJPDResponseBody (EJPDResponseBody), EJPDResponseItem (EJPDResponseItem)) diff --git a/services/spar/default.nix b/services/spar/default.nix index 4bd791dfcfe..e5b1d9bd105 100644 --- a/services/spar/default.nix +++ b/services/spar/default.nix @@ -41,6 +41,7 @@ , MonadRandom , mtl , network-uri +, openapi3 , optparse-applicative , polysemy , polysemy-check @@ -53,10 +54,9 @@ , saml2-web-sso , servant , servant-multipart +, servant-openapi3 , servant-server -, servant-swagger , silently -, swagger2 , tasty-hunit , text , text-latin1 @@ -211,14 +211,14 @@ mkDerivation { metrics-wai mtl network-uri + openapi3 polysemy polysemy-plugin polysemy-wire-zoo QuickCheck saml2-web-sso servant - servant-swagger - swagger2 + servant-openapi3 time tinylog types-common diff --git a/services/spar/spar.cabal b/services/spar/spar.cabal index 568034cedde..5bb672c0d97 100644 --- a/services/spar/spar.cabal +++ b/services/spar/spar.cabal @@ -618,15 +618,15 @@ test-suite spec , metrics-wai , mtl , network-uri + , openapi3 >=3.2 && <3.2.3 , polysemy , polysemy-plugin , polysemy-wire-zoo , QuickCheck , saml2-web-sso >=0.19 , servant - , servant-swagger + , servant-openapi3 , spar - , swagger2 , time , tinylog , types-common diff --git a/services/spar/test/Arbitrary.hs b/services/spar/test/Arbitrary.hs index d8b2daf6839..44d8f38ddac 100644 --- a/services/spar/test/Arbitrary.hs +++ b/services/spar/test/Arbitrary.hs @@ -24,8 +24,8 @@ module Arbitrary where import Data.Aeson import Data.Id (TeamId, UserId) +import Data.OpenApi hiding (Header (..)) import Data.Proxy -import Data.Swagger hiding (Header (..)) import Imports import SAML2.WebSSO.Test.Arbitrary () import SAML2.WebSSO.Types diff --git a/services/spar/test/Test/Spar/APISpec.hs b/services/spar/test/Test/Spar/APISpec.hs index 07bfdb8fde3..a82d00c40f6 100644 --- a/services/spar/test/Test/Spar/APISpec.hs +++ b/services/spar/test/Test/Spar/APISpec.hs @@ -27,7 +27,7 @@ import Data.Metrics.Servant (routesToPaths) import Data.Metrics.Test (pathsConsistencyCheck) import Data.Proxy (Proxy (Proxy)) import Imports -import Servant.Swagger (validateEveryToJSON) +import Servant.OpenApi (validateEveryToJSON) import Spar.API as API import Test.Hspec (Spec, describe, it, shouldBe, shouldSatisfy) import Test.QuickCheck (property) diff --git a/tools/fedcalls/default.nix b/tools/fedcalls/default.nix index 133e6e886bd..dd14e7a2859 100644 --- a/tools/fedcalls/default.nix +++ b/tools/fedcalls/default.nix @@ -11,7 +11,7 @@ , insert-ordered-containers , language-dot , lib -, swagger2 +, openapi3 , wire-api }: mkDerivation { @@ -27,7 +27,7 @@ mkDerivation { imports insert-ordered-containers language-dot - swagger2 + openapi3 wire-api ]; description = "Generate a dot file from swagger docs representing calls to federated instances"; diff --git a/tools/fedcalls/fedcalls.cabal b/tools/fedcalls/fedcalls.cabal index a7bf9ac1981..f01972e0d21 100644 --- a/tools/fedcalls/fedcalls.cabal +++ b/tools/fedcalls/fedcalls.cabal @@ -69,7 +69,7 @@ executable fedcalls , imports , insert-ordered-containers , language-dot - , swagger2 + , openapi3 >=3.2.0 && <3.2.3 , wire-api default-language: GHC2021 diff --git a/tools/fedcalls/src/Main.hs b/tools/fedcalls/src/Main.hs index c1b4471da9f..9769a40b074 100644 --- a/tools/fedcalls/src/Main.hs +++ b/tools/fedcalls/src/Main.hs @@ -27,7 +27,7 @@ import Data.Aeson as A import Data.Aeson.Types qualified as A import Data.HashMap.Strict.InsOrd qualified as HM import Data.Map qualified as M -import Data.Swagger +import Data.OpenApi ( PathItem, Swagger, _operationExtensions, diff --git a/tools/stern/default.nix b/tools/stern/default.nix index c8c64c0d784..3a5afeaa844 100644 --- a/tools/stern/default.nix +++ b/tools/stern/default.nix @@ -28,16 +28,16 @@ , lib , metrics-wai , mtl +, openapi3 , optparse-applicative , random , retry , schema-profunctor , servant +, servant-openapi3 , servant-server -, servant-swagger , servant-swagger-ui , split -, swagger2 , tagged , tasty , tasty-hunit @@ -78,13 +78,13 @@ mkDerivation { lens metrics-wai mtl + openapi3 schema-profunctor servant + servant-openapi3 servant-server - servant-swagger servant-swagger-ui split - swagger2 text tinylog transformers diff --git a/tools/stern/src/Stern/API/Routes.hs b/tools/stern/src/Stern/API/Routes.hs index f3e7116d514..5fd3ec39959 100644 --- a/tools/stern/src/Stern/API/Routes.hs +++ b/tools/stern/src/Stern/API/Routes.hs @@ -32,14 +32,14 @@ import Data.Aeson qualified as A import Data.Handle import Data.Id import Data.Kind +import Data.OpenApi qualified as S import Data.Schema qualified as Schema -import Data.Swagger qualified as S import Imports hiding (head) import Network.HTTP.Types.Status import Network.Wai.Utilities import Servant hiding (Handler, WithStatus (..), addHeader, respond) -import Servant.Swagger (HasSwagger (toSwagger)) -import Servant.Swagger.Internal.Orphans () +import Servant.OpenApi (HasOpenApi (toOpenApi)) +import Servant.OpenApi.Internal.Orphans () import Servant.Swagger.UI import Stern.Types import Wire.API.CustomBackend diff --git a/tools/stern/src/Stern/Types.hs b/tools/stern/src/Stern/Types.hs index b62994c943d..08f16b8d80f 100644 --- a/tools/stern/src/Stern/Types.hs +++ b/tools/stern/src/Stern/Types.hs @@ -30,10 +30,10 @@ import Data.Aeson import Data.Aeson.TH import Data.ByteString.Conversion import Data.Json.Util +import Data.OpenApi qualified as Swagger import Data.Proxy import Data.Range import Data.Schema qualified as S -import Data.Swagger qualified as Swagger import Galley.Types.Teams import Imports import Servant.API diff --git a/tools/stern/stern.cabal b/tools/stern/stern.cabal index 0a4be042c59..efd4b2f08e9 100644 --- a/tools/stern/stern.cabal +++ b/tools/stern/stern.cabal @@ -91,13 +91,13 @@ library , lens >=4.4 , metrics-wai >=0.3 , mtl >=2.1 + , openapi3 >=3.2 && <3.2.3 , schema-profunctor , servant + , servant-openapi3 , servant-server - , servant-swagger , servant-swagger-ui , split >=0.2 - , swagger2 , text >=1.1 , tinylog >=0.10 , transformers >=0.3 @@ -110,6 +110,7 @@ library , wire-api >=0.1 , yaml + -- openapi3 version 3.2.3 is marked as broken in nix default-language: GHC2021 executable stern From c6e8fce9e5cf0b160e9fdb8f985b55fc1831c19a Mon Sep 17 00:00:00 2001 From: Owen Harvey Date: Tue, 5 Sep 2023 16:50:07 +1000 Subject: [PATCH 02/15] WPB-4240: Commiting WIP while I investigate a possible GHC bug. --- libs/deriving-swagger2/src/Deriving/Swagger.hs | 10 ++++++---- libs/schema-profunctor/src/Data/Schema.hs | 1 + libs/types-common/src/Data/Misc.hs | 9 ++++----- libs/wire-api/src/Wire/API/Error.hs | 1 - libs/wire-api/src/Wire/API/MakesFederatedCall.hs | 1 - 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/libs/deriving-swagger2/src/Deriving/Swagger.hs b/libs/deriving-swagger2/src/Deriving/Swagger.hs index eac90ab583b..921741b4317 100644 --- a/libs/deriving-swagger2/src/Deriving/Swagger.hs +++ b/libs/deriving-swagger2/src/Deriving/Swagger.hs @@ -81,6 +81,7 @@ import Imports -- | A newtype wrapper which gives ToSchema instances with modified options. -- 't' has to have an instance of the 'SwaggerOptions' class. newtype CustomSwagger t a = CustomSwagger {unCustomSwagger :: a} + deriving (Generic, Typeable) class SwaggerOptions xs where swaggerOptions :: SchemaOptions @@ -94,16 +95,17 @@ instance (StringModifier f, SwaggerOptions xs) => SwaggerOptions (FieldLabelModi instance (StringModifier f, SwaggerOptions xs) => SwaggerOptions (ConstructorTagModifier f ': xs) where swaggerOptions = (swaggerOptions @xs) {constructorTagModifier = getStringModifier @f} -instance +type Constraints t a = ( SwaggerOptions t, Typeable t, Typeable a, + ToSchema a, Generic a, GToSchema (Rep a), TypeHasSimpleShape a "genericDeclareNamedSchemaUnrestricted" - ) => - ToSchema (CustomSwagger t a) - where + ) + +instance (Constraints t a) => ToSchema (CustomSwagger t a) where declareNamedSchema _ = genericDeclareNamedSchema (swaggerOptions @t) (Proxy @a) -- ** Specify __what__ to modify diff --git a/libs/schema-profunctor/src/Data/Schema.hs b/libs/schema-profunctor/src/Data/Schema.hs index 13afafd4c8c..03e26432c7a 100644 --- a/libs/schema-profunctor/src/Data/Schema.hs +++ b/libs/schema-profunctor/src/Data/Schema.hs @@ -857,6 +857,7 @@ class ToSchema a where -- Newtype wrappers for deriving via newtype Schema a = Schema {getSchema :: a} + deriving (Generic) schemaToSwagger :: forall a. ToSchema a => Proxy a -> Declare S.NamedSchema schemaToSwagger _ = runDeclare (schemaDoc (schema @a)) diff --git a/libs/types-common/src/Data/Misc.hs b/libs/types-common/src/Data/Misc.hs index 0fd9115a820..a8304864c9b 100644 --- a/libs/types-common/src/Data/Misc.hs +++ b/libs/types-common/src/Data/Misc.hs @@ -77,7 +77,9 @@ import Data.ByteString.Char8 (unpack) import Data.ByteString.Conversion import Data.ByteString.Lazy (toStrict) import Data.IP (IP (IPv4, IPv6), toIPv4, toIPv6b) +import Data.OpenApi (declareNamedSchema) import Data.OpenApi qualified as S +import Data.Proxy import Data.Range import Data.Schema import Data.Text qualified as Text @@ -311,11 +313,8 @@ deriving via (ToSchema (Fingerprint a)) => FromJSON (Fingerprint a) -deriving via - (Schema (Fingerprint a)) - instance - (Typeable a, ToSchema (Fingerprint a)) => - S.ToSchema (Fingerprint a) +instance Typeable a => S.ToSchema (Fingerprint a) where + declareNamedSchema _ = declareNamedSchema $ Proxy @(Schema (Fingerprint a)) instance ToSchema (Fingerprint Rsa) where schema = diff --git a/libs/wire-api/src/Wire/API/Error.hs b/libs/wire-api/src/Wire/API/Error.hs index ed992945fbf..18a8fcce8cf 100644 --- a/libs/wire-api/src/Wire/API/Error.hs +++ b/libs/wire-api/src/Wire/API/Error.hs @@ -66,7 +66,6 @@ import Polysemy import Polysemy.Error import Servant import Servant.OpenApi -import Servant.OpenApi (HasOpenApi (toOpenApi)) import Wire.API.Routes.MultiVerb import Wire.API.Routes.Named (Named) import Wire.API.Routes.Version diff --git a/libs/wire-api/src/Wire/API/MakesFederatedCall.hs b/libs/wire-api/src/Wire/API/MakesFederatedCall.hs index c90d2fec92a..da6cf0e181a 100644 --- a/libs/wire-api/src/Wire/API/MakesFederatedCall.hs +++ b/libs/wire-api/src/Wire/API/MakesFederatedCall.hs @@ -44,7 +44,6 @@ import Imports import Servant.API import Servant.Client import Servant.OpenApi -import Servant.OpenApi (HasOpenApi (toOpenApi)) import Servant.Server import Test.QuickCheck (Arbitrary) import TransitiveAnns.Types From fcfd322cd1a08333b626386fe5146e01776dfb3a Mon Sep 17 00:00:00 2001 From: Owen Harvey Date: Wed, 6 Sep 2023 19:03:38 +1000 Subject: [PATCH 03/15] Fixed the compiler bug, back onto the changeover from swagger2 to openapi3 --- libs/brig-types/brig-types.cabal | 2 +- .../deriving-swagger2/deriving-swagger2.cabal | 4 +- .../deriving-swagger2/src/Deriving/Swagger.hs | 17 ++---- .../schema-profunctor/schema-profunctor.cabal | 6 +- libs/types-common/src/Data/Misc.hs | 11 ++-- libs/types-common/types-common.cabal | 2 +- libs/wai-utilities/wai-utilities.cabal | 2 +- .../wire-api-federation.cabal | 2 +- libs/wire-api/src/Wire/API/Asset.hs | 4 +- libs/wire-api/src/Wire/API/Error.hs | 12 ++-- libs/wire-api/src/Wire/API/Error/Brig.hs | 5 +- libs/wire-api/src/Wire/API/Error/Cannon.hs | 5 +- libs/wire-api/src/Wire/API/Error/Cargohold.hs | 5 +- libs/wire-api/src/Wire/API/Error/Galley.hs | 18 +++--- libs/wire-api/src/Wire/API/Error/Gundeck.hs | 5 +- .../src/Wire/API/MakesFederatedCall.hs | 35 ++++++----- libs/wire-api/src/Wire/API/OAuth.hs | 4 +- libs/wire-api/src/Wire/API/Properties.hs | 4 +- libs/wire-api/src/Wire/API/RawJson.hs | 2 +- libs/wire-api/src/Wire/API/Routes/API.hs | 2 +- libs/wire-api/src/Wire/API/Routes/Bearer.hs | 2 +- .../src/Wire/API/Routes/Internal/Brig.hs | 6 +- .../src/Wire/API/Routes/Internal/Cannon.hs | 6 +- .../src/Wire/API/Routes/Internal/Cargohold.hs | 4 +- .../src/Wire/API/Routes/Internal/Galley.hs | 6 +- .../src/Wire/API/Routes/Internal/Spar.hs | 4 +- .../src/Wire/API/Routes/LowLevelStream.hs | 12 ++-- .../src/Wire/API/Routes/MultiTablePaging.hs | 7 ++- .../wire-api/src/Wire/API/Routes/MultiVerb.hs | 60 ++++++++++--------- libs/wire-api/src/Wire/API/Routes/Public.hs | 19 +++--- .../src/Wire/API/Routes/Public/Spar.hs | 2 +- .../src/Wire/API/Routes/QualifiedCapture.hs | 5 +- .../wire-api/src/Wire/API/Routes/Versioned.hs | 2 +- .../wire-api/src/Wire/API/Routes/WebSocket.hs | 4 +- libs/wire-api/src/Wire/API/SwaggerHelper.hs | 8 ++- libs/wire-api/src/Wire/API/Team/Feature.hs | 8 +-- libs/wire-api/src/Wire/API/Team/Invitation.hs | 2 +- libs/wire-api/src/Wire/API/Team/LegalHold.hs | 4 +- libs/wire-api/src/Wire/API/Team/Member.hs | 6 +- libs/wire-api/src/Wire/API/Team/Role.hs | 2 +- libs/wire-api/src/Wire/API/User.hs | 6 +- libs/wire-api/src/Wire/API/User/Client.hs | 6 +- libs/wire-api/src/Wire/API/User/Identity.hs | 2 +- .../src/Wire/API/User/IdentityProvider.hs | 8 +-- libs/wire-api/src/Wire/API/User/Orphans.hs | 2 +- libs/wire-api/src/Wire/API/User/Scim.hs | 8 +-- libs/wire-api/src/Wire/API/User/Search.hs | 4 +- libs/wire-api/src/Wire/API/UserMap.hs | 2 +- libs/wire-api/src/Wire/API/Wrapped.hs | 2 +- libs/wire-api/wire-api.cabal | 4 +- nix/manual-overrides.nix | 1 + services/brig/brig.cabal | 2 +- services/spar/spar.cabal | 2 +- tools/fedcalls/fedcalls.cabal | 2 +- tools/stern/src/Stern/Types.hs | 6 +- tools/stern/stern.cabal | 3 +- 56 files changed, 194 insertions(+), 182 deletions(-) diff --git a/libs/brig-types/brig-types.cabal b/libs/brig-types/brig-types.cabal index 0a00f68eff4..faac2030515 100644 --- a/libs/brig-types/brig-types.cabal +++ b/libs/brig-types/brig-types.cabal @@ -156,7 +156,7 @@ test-suite brig-types-tests , brig-types , bytestring-conversion >=0.3.1 , imports - , openapi3 >=3.2 && <3.2.3 + , openapi3 , QuickCheck >=2.9 , tasty , tasty-hunit diff --git a/libs/deriving-swagger2/deriving-swagger2.cabal b/libs/deriving-swagger2/deriving-swagger2.cabal index b4aff6eb7be..6e5b3f9de4a 100644 --- a/libs/deriving-swagger2/deriving-swagger2.cabal +++ b/libs/deriving-swagger2/deriving-swagger2.cabal @@ -62,9 +62,9 @@ library -Wredundant-constraints -Wunused-packages build-depends: - base >=4 && <5 + base >=4 && <5 , extra , imports - , openapi3 >=3.2.0 && <3.2.3 + , openapi3 default-language: GHC2021 diff --git a/libs/deriving-swagger2/src/Deriving/Swagger.hs b/libs/deriving-swagger2/src/Deriving/Swagger.hs index 921741b4317..aea688714ee 100644 --- a/libs/deriving-swagger2/src/Deriving/Swagger.hs +++ b/libs/deriving-swagger2/src/Deriving/Swagger.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE RankNTypes #-} + -- This file is part of the Wire Server implementation. -- -- Copyright (C) 2022 Wire Swiss GmbH @@ -22,9 +24,8 @@ module Deriving.Swagger where import Data.Char qualified as Char import Data.Kind (Constraint) import Data.List.Extra (stripSuffix) -import Data.OpenApi (SchemaOptions, ToSchema (..), constructorTagModifier, defaultSchemaOptions, fieldLabelModifier, genericDeclareNamedSchema) import Data.OpenApi.Internal.Schema (GToSchema) -import Data.OpenApi.Internal.TypeShape (TypeHasSimpleShape) +import Data.OpenApi.Schema import Data.Proxy (Proxy (..)) import GHC.Generics (Generic (Rep)) import GHC.TypeLits (ErrorMessage (Text), KnownSymbol, Symbol, TypeError, symbolVal) @@ -95,17 +96,7 @@ instance (StringModifier f, SwaggerOptions xs) => SwaggerOptions (FieldLabelModi instance (StringModifier f, SwaggerOptions xs) => SwaggerOptions (ConstructorTagModifier f ': xs) where swaggerOptions = (swaggerOptions @xs) {constructorTagModifier = getStringModifier @f} -type Constraints t a = - ( SwaggerOptions t, - Typeable t, - Typeable a, - ToSchema a, - Generic a, - GToSchema (Rep a), - TypeHasSimpleShape a "genericDeclareNamedSchemaUnrestricted" - ) - -instance (Constraints t a) => ToSchema (CustomSwagger t a) where +instance (SwaggerOptions t, Generic a, Typeable a, GToSchema (Rep a), Typeable (CustomSwagger t a)) => ToSchema (CustomSwagger t a) where declareNamedSchema _ = genericDeclareNamedSchema (swaggerOptions @t) (Proxy @a) -- ** Specify __what__ to modify diff --git a/libs/schema-profunctor/schema-profunctor.cabal b/libs/schema-profunctor/schema-profunctor.cabal index f89bbbd2eda..236a68a841b 100644 --- a/libs/schema-profunctor/schema-profunctor.cabal +++ b/libs/schema-profunctor/schema-profunctor.cabal @@ -69,7 +69,7 @@ library , containers , imports , lens - , openapi3 >=3.2.0 && <3.2.3 + , openapi3 , profunctors , text , transformers @@ -135,11 +135,11 @@ test-suite schemas-tests build-depends: aeson , aeson-qq - , base >=4 && <5 + , base >=4 && <5 , imports , insert-ordered-containers , lens - , openapi3 >=3.2 && <3.2.3 + , openapi3 , schema-profunctor , tasty , tasty-hunit diff --git a/libs/types-common/src/Data/Misc.hs b/libs/types-common/src/Data/Misc.hs index a8304864c9b..8acd18dee2b 100644 --- a/libs/types-common/src/Data/Misc.hs +++ b/libs/types-common/src/Data/Misc.hs @@ -77,9 +77,7 @@ import Data.ByteString.Char8 (unpack) import Data.ByteString.Conversion import Data.ByteString.Lazy (toStrict) import Data.IP (IP (IPv4, IPv6), toIPv4, toIPv6b) -import Data.OpenApi (declareNamedSchema) import Data.OpenApi qualified as S -import Data.Proxy import Data.Range import Data.Schema import Data.Text qualified as Text @@ -298,7 +296,7 @@ data Rsa newtype Fingerprint a = Fingerprint { fingerprintBytes :: ByteString } - deriving stock (Eq, Show, Generic) + deriving stock (Eq, Show, Generic, Typeable) deriving newtype (FromByteString, ToByteString, NFData) deriving via @@ -313,8 +311,11 @@ deriving via (ToSchema (Fingerprint a)) => FromJSON (Fingerprint a) -instance Typeable a => S.ToSchema (Fingerprint a) where - declareNamedSchema _ = declareNamedSchema $ Proxy @(Schema (Fingerprint a)) +deriving via + (Schema (Fingerprint a)) + instance + (Typeable (Fingerprint a), ToSchema (Fingerprint a)) => + S.ToSchema (Fingerprint a) instance ToSchema (Fingerprint Rsa) where schema = diff --git a/libs/types-common/types-common.cabal b/libs/types-common/types-common.cabal index 7c137d1b8fc..4ce602225f1 100644 --- a/libs/types-common/types-common.cabal +++ b/libs/types-common/types-common.cabal @@ -116,7 +116,7 @@ library , lens >=4.10 , lens-datetime >=0.3 , mime >=0.4.0.2 - , openapi3 >=3.2.0 && <3.2.3 + , openapi3 , optparse-applicative >=0.10 , pem , protobuf >=0.2 diff --git a/libs/wai-utilities/wai-utilities.cabal b/libs/wai-utilities/wai-utilities.cabal index 88acae83a04..1c1ae75cbcc 100644 --- a/libs/wai-utilities/wai-utilities.cabal +++ b/libs/wai-utilities/wai-utilities.cabal @@ -86,7 +86,7 @@ library , kan-extensions , metrics-core >=0.1 , metrics-wai >=0.5.7 - , openapi3 >=3.2 && <3.2.3 + , openapi3 , pipes >=4.1 , prometheus-client , schema-profunctor diff --git a/libs/wire-api-federation/wire-api-federation.cabal b/libs/wire-api-federation/wire-api-federation.cabal index 1c2f3b76e74..b19ff51c99d 100644 --- a/libs/wire-api-federation/wire-api-federation.cabal +++ b/libs/wire-api-federation/wire-api-federation.cabal @@ -97,7 +97,7 @@ library , lens , metrics-wai , mtl - , openapi3 >=3.2 && <3.2.3 + , openapi3 , QuickCheck >=2.13 , schema-profunctor , servant >=0.16 diff --git a/libs/wire-api/src/Wire/API/Asset.hs b/libs/wire-api/src/Wire/API/Asset.hs index 5a678e2c75a..1658056c6d0 100644 --- a/libs/wire-api/src/Wire/API/Asset.hs +++ b/libs/wire-api/src/Wire/API/Asset.hs @@ -109,7 +109,7 @@ deriving via Schema (Asset' key) instance ToSchema (Asset' key) => (ToJSON (Asse deriving via Schema (Asset' key) instance ToSchema (Asset' key) => (FromJSON (Asset' key)) -deriving via Schema (Asset' key) instance ToSchema (Asset' key) => (S.ToSchema (Asset' key)) +deriving via Schema (Asset' key) instance (Typeable key, ToSchema (Asset' key)) => (S.ToSchema (Asset' key)) -- Generate expiry time with millisecond precision instance Arbitrary key => Arbitrary (Asset' key) where @@ -394,7 +394,7 @@ instance FromHttpApiData (AssetLocation Absolute) where instance S.ToParamSchema (AssetLocation r) where toParamSchema _ = mempty - & S.type_ ?~ S.SwaggerString + & S.type_ ?~ S.OpenApiString & S.format ?~ "url" -- | An asset as returned by the download API: if the asset is local, only a diff --git a/libs/wire-api/src/Wire/API/Error.hs b/libs/wire-api/src/Wire/API/Error.hs index 18a8fcce8cf..424f4c20cf6 100644 --- a/libs/wire-api/src/Wire/API/Error.hs +++ b/libs/wire-api/src/Wire/API/Error.hs @@ -211,15 +211,15 @@ type family DeclaredErrorEffects api :: EffectRow where DeclaredErrorEffects (Named n api) = DeclaredErrorEffects api DeclaredErrorEffects api = '[] -errorResponseSwagger :: forall e. KnownError e => S.Response +errorResponseSwagger :: forall e. (Typeable e, KnownError e) => S.Response errorResponseSwagger = mempty & S.description .~ (eMessage err <> " (label: `" <> eLabel err <> "`)") - & S.schema ?~ S.Inline (S.toSchema (Proxy @(SStaticError e))) + & S.content . traverse . S.schema ?~ S.Inline (S.toSchema (Proxy @(SStaticError e))) where err = dynError @e -addErrorResponseToSwagger :: Int -> S.Response -> S.Swagger -> S.Swagger +addErrorResponseToSwagger :: Int -> S.Response -> S.OpenApi -> S.OpenApi addErrorResponseToSwagger code resp = S.allOperations . S.responses @@ -233,7 +233,7 @@ addErrorResponseToSwagger code resp = addRef (Just (S.Inline resp1)) = S.Inline (combineResponseSwagger resp1 resp) addRef (Just r@(S.Ref _)) = r -addStaticErrorToSwagger :: forall e. KnownError e => S.Swagger -> S.Swagger +addStaticErrorToSwagger :: forall e. (Typeable e, KnownError e) => S.OpenApi -> S.OpenApi addStaticErrorToSwagger = addErrorResponseToSwagger (fromIntegral (eCode (dynError @e))) @@ -244,7 +244,7 @@ type family MapError (e :: k) :: StaticError type family ErrorEffect (e :: k) :: Effect class IsSwaggerError e where - addToSwagger :: S.Swagger -> S.Swagger + addToOpenApi :: S.OpenApi -> S.OpenApi -- | An effect for a static error type with no data. type ErrorS e = Error (Tagged e ()) @@ -323,7 +323,7 @@ instance KnownError (MapError e) => AsConstructor '[] (ErrorResponse e) where toConstructor _ = Nil fromConstructor _ = dynError @(MapError e) -instance KnownError (MapError e) => IsSwaggerResponse (ErrorResponse e) where +instance (KnownError (MapError e), Typeable (MapError e)) => IsSwaggerResponse (ErrorResponse e) where responseSwagger = pure $ errorResponseSwagger @(MapError e) instance diff --git a/libs/wire-api/src/Wire/API/Error/Brig.hs b/libs/wire-api/src/Wire/API/Error/Brig.hs index 8544a58d50d..85a280b171c 100644 --- a/libs/wire-api/src/Wire/API/Error/Brig.hs +++ b/libs/wire-api/src/Wire/API/Error/Brig.hs @@ -17,6 +17,7 @@ module Wire.API.Error.Brig where +import Data.Data import Wire.API.Error data BrigError @@ -86,8 +87,8 @@ data BrigError | ServiceDisabled | InvalidBot -instance KnownError (MapError e) => IsSwaggerError (e :: BrigError) where - addToSwagger = addStaticErrorToSwagger @(MapError e) +instance (Typeable (MapError e), KnownError (MapError e)) => IsSwaggerError (e :: BrigError) where + addToOpenApi = addStaticErrorToSwagger @(MapError e) type instance MapError 'ServiceDisabled = 'StaticError 403 "service-disabled" "The desired service is currently disabled." diff --git a/libs/wire-api/src/Wire/API/Error/Cannon.hs b/libs/wire-api/src/Wire/API/Error/Cannon.hs index 7cdca830697..6dea237c1fc 100644 --- a/libs/wire-api/src/Wire/API/Error/Cannon.hs +++ b/libs/wire-api/src/Wire/API/Error/Cannon.hs @@ -17,14 +17,15 @@ module Wire.API.Error.Cannon where +import Data.Data import Wire.API.Error data CannonError = ClientGone | PresenceNotRegistered -instance KnownError (MapError e) => IsSwaggerError (e :: CannonError) where - addToSwagger = addStaticErrorToSwagger @(MapError e) +instance (Typeable (MapError e), KnownError (MapError e)) => IsSwaggerError (e :: CannonError) where + addToOpenApi = addStaticErrorToSwagger @(MapError e) type instance MapError 'ClientGone = 'StaticError 410 "general" "client gone" diff --git a/libs/wire-api/src/Wire/API/Error/Cargohold.hs b/libs/wire-api/src/Wire/API/Error/Cargohold.hs index 26087509d12..0c4f17015cc 100644 --- a/libs/wire-api/src/Wire/API/Error/Cargohold.hs +++ b/libs/wire-api/src/Wire/API/Error/Cargohold.hs @@ -17,6 +17,7 @@ module Wire.API.Error.Cargohold where +import Data.Typeable import Wire.API.Error data CargoholdError @@ -26,8 +27,8 @@ data CargoholdError | InvalidLength | NoMatchingAssetEndpoint -instance KnownError (MapError e) => IsSwaggerError (e :: CargoholdError) where - addToSwagger = addStaticErrorToSwagger @(MapError e) +instance (Typeable (MapError e), KnownError (MapError e)) => IsSwaggerError (e :: CargoholdError) where + addToOpenApi = addStaticErrorToSwagger @(MapError e) type instance MapError 'AssetNotFound = 'StaticError 404 "not-found" "Asset not found" diff --git a/libs/wire-api/src/Wire/API/Error/Galley.hs b/libs/wire-api/src/Wire/API/Error/Galley.hs index 27b16684a16..9e5962550c1 100644 --- a/libs/wire-api/src/Wire/API/Error/Galley.hs +++ b/libs/wire-api/src/Wire/API/Error/Galley.hs @@ -139,8 +139,8 @@ data GalleyError $(genSingletons [''GalleyError]) -instance KnownError (MapError e) => IsSwaggerError (e :: GalleyError) where - addToSwagger = addStaticErrorToSwagger @(MapError e) +instance (Typeable (MapError e), KnownError (MapError e)) => IsSwaggerError (e :: GalleyError) where + addToOpenApi = addStaticErrorToSwagger @(MapError e) instance KnownError (MapError e) => APIError (Tagged (e :: GalleyError) ()) where toResponse _ = toResponse $ dynError @(MapError e) @@ -324,7 +324,7 @@ type instance MapError 'VerificationCodeAuthFailed = 'StaticError 403 "code-auth type instance MapError 'VerificationCodeRequired = 'StaticError 403 "code-authentication-required" "Verification code required" instance IsSwaggerError AuthenticationError where - addToSwagger = + addToOpenApi = addStaticErrorToSwagger @(MapError 'ReAuthFailed) . addStaticErrorToSwagger @(MapError 'VerificationCodeAuthFailed) . addStaticErrorToSwagger @(MapError 'VerificationCodeRequired) @@ -351,7 +351,7 @@ data TeamFeatureError instance IsSwaggerError TeamFeatureError where -- Do not display in Swagger - addToSwagger = id + addToOpenApi = id type instance MapError 'AppLockInactivityTimeoutTooLow = 'StaticError 400 "inactivity-timeout-too-low" "Applock inactivity timeout must be at least 30 seconds" @@ -398,7 +398,7 @@ type instance ErrorEffect MLSProposalFailure = Error MLSProposalFailure -- Proposal failures are only reported generically in Swagger instance IsSwaggerError MLSProposalFailure where - addToSwagger = S.allOperations . S.description %~ Just . (<> desc) . fold + addToOpenApi = S.allOperations . S.description %~ Just . (<> desc) . fold where desc = "\n\n**Note**: this endpoint can execute proposals, and therefore \ @@ -449,11 +449,11 @@ instance ToSchema NonFederatingBackends where nonFederatingBackendsFromList instance IsSwaggerError NonFederatingBackends where - addToSwagger = + addToOpenApi = addErrorResponseToSwagger (HTTP.statusCode nonFederatingBackendsStatus) $ mempty & S.description .~ "Adding members to the conversation is not possible because the backends involved do not form a fully connected graph" - & S.schema ?~ S.Inline (S.toSchema (Proxy @NonFederatingBackends)) + & S.content . traverse . S.schema ?~ S.Inline (S.toSchema (Proxy @NonFederatingBackends)) type instance ErrorEffect NonFederatingBackends = Error NonFederatingBackends @@ -486,11 +486,11 @@ instance ToSchema UnreachableBackends where <$> (.backends) .= field "unreachable_backends" (array schema) instance IsSwaggerError UnreachableBackends where - addToSwagger = + addToOpenApi = addErrorResponseToSwagger (HTTP.statusCode unreachableBackendsStatus) $ mempty & S.description .~ "Some domains are unreachable" - & S.schema ?~ S.Inline (S.toSchema (Proxy @UnreachableBackends)) + & S.content . traverse . S.schema ?~ S.Inline (S.toSchema (Proxy @UnreachableBackends)) type instance ErrorEffect UnreachableBackends = Error UnreachableBackends diff --git a/libs/wire-api/src/Wire/API/Error/Gundeck.hs b/libs/wire-api/src/Wire/API/Error/Gundeck.hs index f28432f45f1..ac9b6ce363f 100644 --- a/libs/wire-api/src/Wire/API/Error/Gundeck.hs +++ b/libs/wire-api/src/Wire/API/Error/Gundeck.hs @@ -17,6 +17,7 @@ module Wire.API.Error.Gundeck where +import Data.Typeable import Wire.API.Error data GundeckError @@ -28,8 +29,8 @@ data GundeckError | TokenNotFound | NotificationNotFound -instance KnownError (MapError e) => IsSwaggerError (e :: GundeckError) where - addToSwagger = addStaticErrorToSwagger @(MapError e) +instance (Typeable (MapError e), KnownError (MapError e)) => IsSwaggerError (e :: GundeckError) where + addToOpenApi = addStaticErrorToSwagger @(MapError e) type instance MapError 'AddTokenErrorNoBudget = 'StaticError 413 "sns-thread-budget-reached" "Too many concurrent calls to SNS; is SNS down?" diff --git a/libs/wire-api/src/Wire/API/MakesFederatedCall.hs b/libs/wire-api/src/Wire/API/MakesFederatedCall.hs index da6cf0e181a..6b5f6f262a3 100644 --- a/libs/wire-api/src/Wire/API/MakesFederatedCall.hs +++ b/libs/wire-api/src/Wire/API/MakesFederatedCall.hs @@ -35,10 +35,8 @@ import Data.Aeson import Data.Constraint import Data.Kind import Data.Metrics.Servant -import Data.OpenApi.Operation (addExtensions) import Data.Proxy import Data.Schema -import Data.Text qualified as T import GHC.TypeLits import Imports import Servant.API @@ -161,21 +159,26 @@ type instance instance (HasOpenApi api, KnownSymbol name, KnownSymbol (ShowComponent comp)) => HasOpenApi (MakesFederatedCall comp name :> api :: Type) where toOpenApi _ = toOpenApi (Proxy @api) - & addExtensions - mergeJSONArray - [ ( "wire-makes-federated-call-to", - Array - [ Array - [ String $ T.pack $ symbolVal $ Proxy @(ShowComponent comp), - String $ T.pack $ symbolVal $ Proxy @name - ] - ] - ) - ] -mergeJSONArray :: Value -> Value -> Value -mergeJSONArray (Array x) (Array y) = Array $ x <> y -mergeJSONArray _ _ = error "impossible! bug in construction of federated calls JSON" +-- TODO & FUTUREWORK: openapi3 doesn't use an underlying aeson Value +-- structure to build up the schema. To enable extensions, we will need +-- to update the structures in openapi3 to include an extensions field, +-- likely holding a Value type. +-- & addExtensions +-- mergeJSONArray +-- [ ( "wire-makes-federated-call-to", +-- Array +-- [ Array +-- [ String $ T.pack $ symbolVal $ Proxy @(ShowComponent comp), +-- String $ T.pack $ symbolVal $ Proxy @name +-- ] +-- ] +-- ) +-- ] +-- +-- mergeJSONArray :: Value -> Value -> Value +-- mergeJSONArray (Array x) (Array y) = Array $ x <> y +-- mergeJSONArray _ _ = error "impossible! bug in construction of federated calls JSON" instance HasClient m api => HasClient m (MakesFederatedCall comp name :> api :: Type) where type Client m (MakesFederatedCall comp name :> api) = Client m api diff --git a/libs/wire-api/src/Wire/API/OAuth.hs b/libs/wire-api/src/Wire/API/OAuth.hs index cbdcf757524..293d154885c 100644 --- a/libs/wire-api/src/Wire/API/OAuth.hs +++ b/libs/wire-api/src/Wire/API/OAuth.hs @@ -641,8 +641,8 @@ data OAuthError | OAuthInvalidRefreshToken | OAuthInvalidGrant -instance KnownError (MapError e) => IsSwaggerError (e :: OAuthError) where - addToSwagger = addStaticErrorToSwagger @(MapError e) +instance (Typeable (MapError e), KnownError (MapError e)) => IsSwaggerError (e :: OAuthError) where + addToOpenApi = addStaticErrorToSwagger @(MapError e) type instance MapError 'OAuthClientNotFound = 'StaticError 404 "not-found" "OAuth client not found" diff --git a/libs/wire-api/src/Wire/API/Properties.hs b/libs/wire-api/src/Wire/API/Properties.hs index 186e79d6c90..debcf9016d7 100644 --- a/libs/wire-api/src/Wire/API/Properties.hs +++ b/libs/wire-api/src/Wire/API/Properties.hs @@ -43,7 +43,7 @@ instance S.ToSchema PropertyKeysAndValues where declareNamedSchema _ = pure $ S.NamedSchema (Just "PropertyKeysAndValues") $ - mempty & S.type_ ?~ S.SwaggerObject + mempty & S.type_ ?~ S.OpenApiObject newtype PropertyKey = PropertyKey {propertyKeyName :: AsciiPrintable} @@ -64,7 +64,7 @@ newtype PropertyKey = PropertyKey instance S.ToParamSchema PropertyKey where toParamSchema _ = mempty - & S.type_ ?~ S.SwaggerString + & S.type_ ?~ S.OpenApiString & S.format ?~ "printable" -- | A raw, unparsed property value. diff --git a/libs/wire-api/src/Wire/API/RawJson.hs b/libs/wire-api/src/Wire/API/RawJson.hs index 1e0e8985e8f..08529ded900 100644 --- a/libs/wire-api/src/Wire/API/RawJson.hs +++ b/libs/wire-api/src/Wire/API/RawJson.hs @@ -43,6 +43,6 @@ instance Swagger.ToSchema RawJson where declareNamedSchema _ = pure . Swagger.NamedSchema (Just "RawJson") $ mempty - & Swagger.type_ ?~ Swagger.SwaggerObject + & Swagger.type_ ?~ Swagger.OpenApiObject & Swagger.description ?~ "Any JSON as plain string. The object structure is not specified in this schema." diff --git a/libs/wire-api/src/Wire/API/Routes/API.hs b/libs/wire-api/src/Wire/API/Routes/API.hs index d86f3a3f371..23ac38e6fed 100644 --- a/libs/wire-api/src/Wire/API/Routes/API.hs +++ b/libs/wire-api/src/Wire/API/Routes/API.hs @@ -47,7 +47,7 @@ class ServiceAPI service (v :: Version) where type ServiceAPIRoutes service type SpecialisedAPIRoutes v service :: Type type SpecialisedAPIRoutes v service = SpecialiseToVersion v (ServiceAPIRoutes service) - serviceSwagger :: HasOpenApi (SpecialisedAPIRoutes v service) => S.Swagger + serviceSwagger :: HasOpenApi (SpecialisedAPIRoutes v service) => S.OpenApi serviceSwagger = toOpenApi (Proxy @(SpecialisedAPIRoutes v service)) instance ServiceAPI VersionAPITag v where diff --git a/libs/wire-api/src/Wire/API/Routes/Bearer.hs b/libs/wire-api/src/Wire/API/Routes/Bearer.hs index 7351fc66064..64a1baed79f 100644 --- a/libs/wire-api/src/Wire/API/Routes/Bearer.hs +++ b/libs/wire-api/src/Wire/API/Routes/Bearer.hs @@ -21,7 +21,7 @@ import Control.Lens ((<>~)) import Data.ByteString qualified as BS import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap import Data.Metrics.Servant -import Data.OpenApi hiding (Header) +import Data.OpenApi hiding (HasServer, Header) import Data.Text.Encoding qualified as T import Imports import Servant diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Brig.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Brig.hs index aabe0799692..3a2d6fff216 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Brig.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Brig.hs @@ -46,7 +46,7 @@ import Data.CommaSeparatedList import Data.Domain (Domain) import Data.Handle (Handle) import Data.Id as Id -import Data.OpenApi (HasInfo (info), HasTitle (title), Swagger) +import Data.OpenApi (HasInfo (info), HasTitle (title), OpenApi) import Data.OpenApi qualified as S import Data.Qualified (Qualified) import Data.Schema hiding (swaggerDoc) @@ -798,7 +798,7 @@ type FederationRemotesAPIDeleteDescription = "**WARNING!** If you remove a remote connection, all users from that remote will be removed from local conversations, and all \ \group conversations hosted by that remote will be removed from the local backend. This cannot be reverted! " -swaggerDoc :: Swagger +swaggerDoc :: OpenApi swaggerDoc = - toSwagger (Proxy @API) + toOpenApi (Proxy @API) & info . title .~ "Wire-Server internal brig API" diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Cannon.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Cannon.hs index e6ac2fa4964..b8f1652bc7a 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Cannon.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Cannon.hs @@ -2,7 +2,7 @@ module Wire.API.Routes.Internal.Cannon where import Control.Lens ((.~)) import Data.Id -import Data.OpenApi (HasInfo (info), HasTitle (title), Swagger) +import Data.OpenApi (HasInfo (info), HasTitle (title), OpenApi) import Imports import Servant import Servant.OpenApi (HasOpenApi (toOpenApi)) @@ -59,7 +59,7 @@ type API = ) ) -swaggerDoc :: Swagger +swaggerDoc :: OpenApi swaggerDoc = - toSwagger (Proxy @API) + toOpenApi (Proxy @API) & info . title .~ "Wire-Server internal cannon API" diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Cargohold.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Cargohold.hs index 47d4266b603..cb9599b441e 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Cargohold.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Cargohold.hs @@ -29,7 +29,7 @@ type InternalAPI = :> "status" :> MultiVerb 'GET '() '[RespondEmpty 200 "OK"] () -swaggerDoc :: Swagger +swaggerDoc :: OpenApi swaggerDoc = - toSwagger (Proxy @InternalAPI) + toOpenApi (Proxy @InternalAPI) & info . title .~ "Wire-Server internal cargohold API" diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Galley.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Galley.hs index 5177c34c5ee..ccfcf69a617 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Galley.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Galley.hs @@ -19,7 +19,7 @@ module Wire.API.Routes.Internal.Galley where import Control.Lens ((.~)) import Data.Id as Id -import Data.OpenApi (Swagger, info, title) +import Data.OpenApi (OpenApi, info, title) import Data.Range import GHC.TypeLits (AppendSymbol) import Imports hiding (head) @@ -426,7 +426,7 @@ type IFederationAPI = :> Get '[Servant.JSON] FederationStatus ) -swaggerDoc :: Swagger +swaggerDoc :: OpenApi swaggerDoc = - toSwagger (Proxy @InternalAPI) + toOpenApi (Proxy @InternalAPI) & info . title .~ "Wire-Server internal galley API" diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Spar.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Spar.hs index 265b6e29cff..8cc2207031c 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Spar.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Spar.hs @@ -34,7 +34,7 @@ type InternalAPI = :<|> "scim" :> "userinfos" :> ReqBody '[JSON] UserSet :> Post '[JSON] ScimUserInfos ) -swaggerDoc :: Swagger +swaggerDoc :: OpenApi swaggerDoc = - toSwagger (Proxy @InternalAPI) + toOpenApi (Proxy @InternalAPI) & info . title .~ "Wire-Server internal spar API" diff --git a/libs/wire-api/src/Wire/API/Routes/LowLevelStream.hs b/libs/wire-api/src/Wire/API/Routes/LowLevelStream.hs index 385eb9e5531..f39080b54f7 100644 --- a/libs/wire-api/src/Wire/API/Routes/LowLevelStream.hs +++ b/libs/wire-api/src/Wire/API/Routes/LowLevelStream.hs @@ -17,7 +17,7 @@ module Wire.API.Routes.LowLevelStream where -import Control.Lens (at, (.~), (?~)) +import Control.Lens (at, (.~), (?~), _Just) import Data.ByteString.Char8 as B8 import Data.CaseInsensitive qualified as CI import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap @@ -33,7 +33,6 @@ import Network.Wai import Servant.API import Servant.API.ContentTypes import Servant.API.Status -import Servant.OpenApi (HasOpenApi (toOpenApi)) import Servant.OpenApi as S import Servant.OpenApi.Internal as S import Servant.Server hiding (respond) @@ -91,7 +90,7 @@ type instance LowLevelStream m s h d t instance - (Accept ctype, KnownNat status, KnownSymbol desc, SwaggerMethod method) => + (S.ToSchema ctype, Accept ctype, KnownNat status, KnownSymbol desc, OpenApiMethod method) => HasOpenApi (LowLevelStream method status headers desc ctype) where toOpenApi _ = @@ -101,17 +100,20 @@ instance ?~ ( mempty & method ?~ ( mempty - & S.produces ?~ S.MimeList [contentType (Proxy @ctype)] & S.responses . S.responses .~ fmap S.Inline responses ) ) where - method = S.swaggerMethod (Proxy @method) + method = S.openApiMethod (Proxy @method) responses = InsOrdHashMap.singleton (fromIntegral (natVal (Proxy @status))) $ mempty & S.description .~ Text.pack (symbolVal (Proxy @desc)) + & S.content + .~ InsOrdHashMap.singleton + (contentType $ Proxy @ctype) + (mempty & S.schema . _Just . S._Inline .~ S.toSchema (Proxy @ctype)) instance RoutesToPaths (LowLevelStream method status headers desc ctype) where getRoutes = [] diff --git a/libs/wire-api/src/Wire/API/Routes/MultiTablePaging.hs b/libs/wire-api/src/Wire/API/Routes/MultiTablePaging.hs index 29a00f89cc2..0fc48cdaf06 100644 --- a/libs/wire-api/src/Wire/API/Routes/MultiTablePaging.hs +++ b/libs/wire-api/src/Wire/API/Routes/MultiTablePaging.hs @@ -77,7 +77,10 @@ deriving via deriving via Schema (GetMultiTablePageRequest name tables max def) instance - RequestSchemaConstraint name tables max def => S.ToSchema (GetMultiTablePageRequest name tables max def) + ( Typeable tables, + RequestSchemaConstraint name tables max def + ) => + S.ToSchema (GetMultiTablePageRequest name tables max def) instance RequestSchemaConstraint name tables max def => ToSchema (GetMultiTablePageRequest name tables max def) where schema = @@ -126,7 +129,7 @@ deriving via deriving via (Schema (MultiTablePage name resultsKey tables a)) instance - PageSchemaConstraints name resultsKey tables a => + (Typeable tables, Typeable a, PageSchemaConstraints name resultsKey tables a) => S.ToSchema (MultiTablePage name resultsKey tables a) instance diff --git a/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs b/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs index 30bcfe84bee..459294a8d2d 100644 --- a/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs +++ b/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs @@ -54,16 +54,14 @@ import Control.Lens hiding (Context, (<|)) import Data.ByteString.Builder import Data.ByteString.Lazy qualified as LBS import Data.CaseInsensitive qualified as CI -import Data.Containers.ListUtils import Data.Either.Combinators (leftToMaybe) import Data.HashMap.Strict.InsOrd (InsOrdHashMap) import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap import Data.Kind import Data.Metrics.Servant import Data.OpenApi hiding (HasServer, Response, contentType) -import Data.OpenApi qualified as S hiding (HasServer, Response, contentType) +import Data.OpenApi qualified as S import Data.OpenApi.Declare qualified as S -import Data.OpenApi.Lens qualified as S import Data.Proxy import Data.SOP import Data.Sequence (Seq, (<|), pattern (:<|)) @@ -152,7 +150,7 @@ instance MonadPlus UnrenderResult where mplus m@(UnrenderSuccess _) _ = m class IsSwaggerResponse a where - responseSwagger :: Declare S.Responses + responseSwagger :: Declare S.Response type family ResponseType a :: Type @@ -193,13 +191,13 @@ instance (AllMimeRender cs a, AllMimeUnrender cs a, KnownStatus s) => IsResponse Nothing -> empty Just f -> either UnrenderError UnrenderSuccess (f (responseBody output)) -simpleResponseSwagger :: forall a desc. (S.ToSchema a, KnownSymbol desc) => Declare S.Responses +simpleResponseSwagger :: forall a desc. (S.ToSchema a, KnownSymbol desc) => Declare S.Response simpleResponseSwagger = do ref <- S.declareSchemaRef (Proxy @a) pure $ mempty & S.description .~ Text.pack (symbolVal (Proxy @desc)) - & S.schema ?~ ref + & S.content . traverse . S.schema ?~ ref instance (KnownSymbol desc, S.ToSchema a) => @@ -350,8 +348,8 @@ instance -- FUTUREWORK: should we concatenate all the matching headers instead of just -- taking the first one? extractHeaders hs = do - let name = headerName @name - (hs0, hs1) = Seq.partition (\(h, _) -> h == name) hs + let name' = headerName @name + (hs0, hs1) = Seq.partition (\(h, _) -> h == name') hs x <- case hs0 of Seq.Empty -> empty ((_, h) :<| _) -> either (const empty) pure (parseHeader h) @@ -380,11 +378,11 @@ instance (KnownSymbol name, KnownSymbol desc, S.ToParamSchema a) => ToResponseHeader (DescHeader name desc a) where - toResponseHeader _ = (name, S.Header (Just desc) sch) + toResponseHeader _ = (name', S.Header (Just desc) Nothing Nothing Nothing Nothing Nothing mempty sch) where - name = Text.pack (symbolVal (Proxy @name)) + name' = Text.pack (symbolVal (Proxy @name)) desc = Text.pack (symbolVal (Proxy @desc)) - sch = S.toParamSchema (Proxy @a) + sch = pure $ Inline $ S.toParamSchema (Proxy @a) instance ToResponseHeader h => ToResponseHeader (OptHeader h) where toResponseHeader _ = toResponseHeader (Proxy @h) @@ -421,11 +419,11 @@ instance where responseSwagger = fmap - (S.headers .~ toAllResponseHeaders (Proxy @hs)) + (S.headers .~ fmap S.Inline (toAllResponseHeaders (Proxy @hs))) (responseSwagger @r) class IsSwaggerResponseList as where - responseListSwagger :: Declare (InsOrdHashMap S.HttpStatusCode S.Responses) + responseListSwagger :: Declare (InsOrdHashMap S.HttpStatusCode S.Response) type family ResponseTypes (as :: [Type]) where ResponseTypes '[] = '[] @@ -468,18 +466,26 @@ instance ) => IsSwaggerResponseList (a ': as) where - responseListSwagger = - InsOrdHashMap.insertWith - combineResponseSwagger - (fromIntegral (natVal (Proxy @(ResponseStatus a)))) - <$> responseSwagger @a - <*> responseListSwagger @as - -combineResponseSwagger :: S.Responses -> S.Responses -> S.Responses + responseListSwagger = do + resp <- responseSwagger @a + respList <- responseListSwagger @as + pure $ + InsOrdHashMap.insertWith + combineResponseSwagger + (fromIntegral (natVal (Proxy @(ResponseStatus a)))) + resp + respList + +combineResponseSwagger :: S.Response -> S.Response -> S.Response combineResponseSwagger r1 r2 = r1 & S.description <>~ ("\n\n" <> r2 ^. S.description) - & S.schema . _Just . S._Inline %~ flip combineSwaggerSchema (r2 ^. S.schema . _Just . S._Inline) + & S.content + . traverse + . S.schema + . _Just + . S._Inline + %~ flip combineSwaggerSchema (r2 ^. S.content . traverse . S.schema . _Just . S._Inline) combineSwaggerSchema :: S.Schema -> S.Schema -> S.Schema combineSwaggerSchema s1 s2 @@ -710,13 +716,13 @@ instance . at "/" ?~ ( mempty & method - ?~ ( mempty - & S.responses . S.responses .~ fmap S.Inline resps + ?~ ( mempty & (S.responses @S.Operation @S.Responses) . S.responses .~ refResps ) ) where method = S.openApiMethod (Proxy @method) (defs, resps) = S.runDeclare (responseListSwagger @as) mempty + refResps = S.Inline <$> resps instance (OpenApiMethod method, IsSwaggerResponseList as, AllMime cs) => @@ -730,14 +736,14 @@ instance ?~ ( mempty & method ?~ ( mempty - & S.produces ?~ S.MimeList (nubOrd cs) - & S.responses . S.responses .~ fmap S.Inline resps + & S.responses . S.responses .~ refResps ) ) where method = S.openApiMethod (Proxy @method) - cs = allMime (Proxy @cs) + _cs = allMime (Proxy @cs) (defs, resps) = S.runDeclare (responseListSwagger @as) mempty + refResps = S.Inline <$> resps class Typeable a => IsWaiBody a where responseToWai :: ResponseF a -> Wai.Response diff --git a/libs/wire-api/src/Wire/API/Routes/Public.hs b/libs/wire-api/src/Wire/API/Routes/Public.hs index da1531415c7..68886e65407 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public.hs @@ -44,7 +44,8 @@ import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap import Data.Id as Id import Data.Kind import Data.Metrics.Servant -import Data.OpenApi hiding (Header) +import Data.OpenApi hiding (HasServer, Header, Server) +import Data.OpenApi qualified as S import Data.Qualified import GHC.Base (Symbol) import GHC.TypeLits (KnownSymbol) @@ -228,10 +229,10 @@ instance HasOpenApi api => HasOpenApi (ZHostOpt :> api) where type instance SpecialiseToVersion v (ZHostOpt :> api) = ZHostOpt :> SpecialiseToVersion v api -addZAuthSwagger :: Swagger -> Swagger +addZAuthSwagger :: OpenApi -> OpenApi addZAuthSwagger s = s - & securityDefinitions <>~ SecurityDefinitions (InsOrdHashMap.singleton "ZAuth" secScheme) + & S.components . S.securitySchemes <>~ SecurityDefinitions (InsOrdHashMap.singleton "ZAuth" secScheme) & security <>~ [SecurityRequirement $ InsOrdHashMap.singleton "ZAuth" []] where secScheme = @@ -245,10 +246,10 @@ type instance ZAuthServant t opts :> SpecialiseToVersion v api instance HasOpenApi api => HasOpenApi (ZAuthServant 'ZAuthUser _opts :> api) where - toOpenApi _ = addZAuthSwagger (toSwagger (Proxy @api)) + toOpenApi _ = addZAuthSwagger (toOpenApi (Proxy @api)) instance HasOpenApi api => HasOpenApi (ZAuthServant 'ZLocalAuthUser opts :> api) where - toOpenApi _ = addZAuthSwagger (toSwagger (Proxy @api)) + toOpenApi _ = addZAuthSwagger (toOpenApi (Proxy @api)) instance HasLink endpoint => HasLink (ZAuthServant usr opts :> endpoint) where type MkLink (ZAuthServant _ _ :> endpoint) a = MkLink endpoint a @@ -301,8 +302,8 @@ instance checkType :: Maybe ByteString -> Wai.Request -> DelayedIO () checkType token req = case (token, lookup "Z-Type" (Wai.requestHeaders req)) of - (Just t, value) - | value /= Just t -> + (Just t, v) + | v /= Just t -> delayedFail ServerError { errHTTPCode = 403, @@ -321,7 +322,7 @@ instance RoutesToPaths api => RoutesToPaths (ZHostOpt :> api) where getRoutes = getRoutes @api -- FUTUREWORK: Make a PR to the servant-swagger package with this instance -instance ToSchema a => ToSchema (Headers ls a) where +instance (Typeable ls, ToSchema a) => ToSchema (Headers ls a) where declareNamedSchema _ = declareNamedSchema (Proxy @a) data DescriptionOAuthScope (scope :: OAuth.OAuthScope) @@ -336,7 +337,7 @@ instance where toOpenApi _ = addScopeDescription @scope (toOpenApi (Proxy @api)) -addScopeDescription :: forall scope. OAuth.IsOAuthScope scope => Swagger -> Swagger +addScopeDescription :: forall scope. OAuth.IsOAuthScope scope => OpenApi -> OpenApi addScopeDescription = allOperations . description %~ Just . (<> "\nOAuth scope: `" <> cs (toByteString (OAuth.toOAuthScope @scope)) <> "`") . fold instance (HasServer api ctx) => HasServer (DescriptionOAuthScope scope :> api) ctx where diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs b/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs index bb3144cb32a..930f450fb8a 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs @@ -191,4 +191,4 @@ data SparAPITag instance ServiceAPI SparAPITag v where type ServiceAPIRoutes SparAPITag = SparAPI type SpecialisedAPIRoutes v SparAPITag = SparAPI - serviceSwagger = toSwagger (Proxy @SparAPI) + serviceSwagger = toOpenApi (Proxy @SparAPI) diff --git a/libs/wire-api/src/Wire/API/Routes/QualifiedCapture.hs b/libs/wire-api/src/Wire/API/Routes/QualifiedCapture.hs index 48537e75b0e..9147e008fda 100644 --- a/libs/wire-api/src/Wire/API/Routes/QualifiedCapture.hs +++ b/libs/wire-api/src/Wire/API/Routes/QualifiedCapture.hs @@ -24,7 +24,7 @@ where import Data.Domain import Data.Kind import Data.Metrics.Servant -import Data.OpenApi +import Data.OpenApi hiding (HasServer, value) import Data.Qualified import GHC.TypeLits import Imports @@ -56,8 +56,7 @@ type instance QualifiedCapture' mods capture a :> SpecialiseToVersion v api instance - ( Typeable a, - ToParamSchema a, + ( ToParamSchema a, HasOpenApi api, KnownSymbol capture, KnownSymbol (AppendSymbol capture "_domain"), diff --git a/libs/wire-api/src/Wire/API/Routes/Versioned.hs b/libs/wire-api/src/Wire/API/Routes/Versioned.hs index 1bfb9e3ea92..d461a65523d 100644 --- a/libs/wire-api/src/Wire/API/Routes/Versioned.hs +++ b/libs/wire-api/src/Wire/API/Routes/Versioned.hs @@ -111,7 +111,7 @@ deriving via Schema (Versioned v a) instance ToSchema (Versioned v a) => FromJSO deriving via Schema (Versioned v a) instance ToSchema (Versioned v a) => ToJSON (Versioned v a) -- add version suffix to swagger schema to prevent collisions -instance (SingI v, ToSchema (Versioned v a)) => S.ToSchema (Versioned v a) where +instance (SingI v, ToSchema (Versioned v a), Typeable a, Typeable v) => S.ToSchema (Versioned v a) where declareNamedSchema _ = do S.NamedSchema n s <- schemaToSwagger (Proxy @(Versioned v a)) pure $ S.NamedSchema (fmap (<> toUrlPiece (demote @v)) n) s diff --git a/libs/wire-api/src/Wire/API/Routes/WebSocket.hs b/libs/wire-api/src/Wire/API/Routes/WebSocket.hs index e0f3f658242..0405b58d094 100644 --- a/libs/wire-api/src/Wire/API/Routes/WebSocket.hs +++ b/libs/wire-api/src/Wire/API/Routes/WebSocket.hs @@ -21,7 +21,7 @@ import Control.Lens import Control.Monad.Trans.Resource import Data.HashMap.Strict.InsOrd import Data.Metrics.Servant -import Data.OpenApi +import Data.OpenApi hiding (HasServer) import Data.Proxy import Imports import Network.Wai.Handler.WebSockets @@ -82,7 +82,7 @@ instance HasOpenApi WebSocketPending where ) ) where - resps :: InsOrdHashMap HttpStatusCode (Referenced Data.Swagger.Response) + resps :: InsOrdHashMap HttpStatusCode (Referenced Data.OpenApi.Response) resps = mempty & at 101 ?~ Inline (mempty & description .~ "Connection upgraded.") diff --git a/libs/wire-api/src/Wire/API/SwaggerHelper.hs b/libs/wire-api/src/Wire/API/SwaggerHelper.hs index 43e760cdcb5..915a68bb036 100644 --- a/libs/wire-api/src/Wire/API/SwaggerHelper.hs +++ b/libs/wire-api/src/Wire/API/SwaggerHelper.hs @@ -23,19 +23,21 @@ import Data.OpenApi hiding (Contact, Header, Schema, ToSchema) import Data.OpenApi qualified as S import Imports hiding (head) -cleanupSwagger :: Swagger -> Swagger +cleanupSwagger :: OpenApi -> OpenApi cleanupSwagger = (S.security %~ nub) -- sanitise definitions - . (S.definitions . traverse %~ sanitise) + . (S.components . S.schemas . traverse %~ sanitise) -- sanitise general responses - . (S.responses . traverse . S.schema . _Just . S._Inline %~ sanitise) + . (S.components . S.responses . traverse . S.content . traverse . S.schema . _Just . S._Inline %~ sanitise) -- sanitise all responses of all paths . ( S.allOperations . S.responses . S.responses . traverse . S._Inline + . S.content + . traverse . S.schema . _Just . S._Inline diff --git a/libs/wire-api/src/Wire/API/Team/Feature.hs b/libs/wire-api/src/Wire/API/Team/Feature.hs index 2ccdb709649..899f7491573 100644 --- a/libs/wire-api/src/Wire/API/Team/Feature.hs +++ b/libs/wire-api/src/Wire/API/Team/Feature.hs @@ -266,7 +266,7 @@ deriving via (Schema (WithStatus cfg)) instance (ToSchema (WithStatus cfg)) => T deriving via (Schema (WithStatus cfg)) instance (ToSchema (WithStatus cfg)) => FromJSON (WithStatus cfg) -deriving via (Schema (WithStatus cfg)) instance (ToSchema (WithStatus cfg)) => S.ToSchema (WithStatus cfg) +deriving via (Schema (WithStatus cfg)) instance (ToSchema (WithStatus cfg), Typeable cfg) => S.ToSchema (WithStatus cfg) instance (ToSchema cfg, IsFeatureConfig cfg) => ToSchema (WithStatus cfg) where schema = @@ -296,7 +296,7 @@ deriving via (Schema (WithStatusPatch cfg)) instance (ToSchema (WithStatusPatch deriving via (Schema (WithStatusPatch cfg)) instance (ToSchema (WithStatusPatch cfg)) => FromJSON (WithStatusPatch cfg) -deriving via (Schema (WithStatusPatch cfg)) instance (ToSchema (WithStatusPatch cfg)) => S.ToSchema (WithStatusPatch cfg) +deriving via (Schema (WithStatusPatch cfg)) instance (ToSchema (WithStatusPatch cfg), Typeable cfg) => S.ToSchema (WithStatusPatch cfg) wsPatch :: Maybe FeatureStatus -> Maybe LockStatus -> Maybe cfg -> Maybe FeatureTTL -> WithStatusPatch cfg wsPatch = WithStatusBase @@ -1043,8 +1043,8 @@ data FeatureStatus instance S.ToParamSchema FeatureStatus where toParamSchema _ = mempty - { S._paramSchemaType = Just S.SwaggerString, - S._paramSchemaEnum = Just (A.String . toQueryParam <$> [(minBound :: FeatureStatus) ..]) + { S._schemaType = Just S.OpenApiString, + S._schemaEnum = Just (A.String . toQueryParam <$> [(minBound :: FeatureStatus) ..]) } instance FromHttpApiData FeatureStatus where diff --git a/libs/wire-api/src/Wire/API/Team/Invitation.hs b/libs/wire-api/src/Wire/API/Team/Invitation.hs index 4ef104dc8a4..44cc508ab69 100644 --- a/libs/wire-api/src/Wire/API/Team/Invitation.hs +++ b/libs/wire-api/src/Wire/API/Team/Invitation.hs @@ -130,7 +130,7 @@ newtype InvitationLocation = InvitationLocation instance S.ToParamSchema InvitationLocation where toParamSchema _ = mempty - & S.type_ ?~ S.SwaggerString + & S.type_ ?~ S.OpenApiString & S.format ?~ "url" instance FromHttpApiData InvitationLocation where diff --git a/libs/wire-api/src/Wire/API/Team/LegalHold.hs b/libs/wire-api/src/Wire/API/Team/LegalHold.hs index fe6c88c32f2..40fbb9a7af0 100644 --- a/libs/wire-api/src/Wire/API/Team/LegalHold.hs +++ b/libs/wire-api/src/Wire/API/Team/LegalHold.hs @@ -240,11 +240,11 @@ instance ToSchema LegalholdProtectee where pure $ S.NamedSchema (Just "LegalholdProtectee") $ mempty - & S.type_ ?~ S.SwaggerObject + & S.type_ ?~ S.OpenApiObject & S.properties . at "tag" ?~ S.Inline ( mempty - & S.type_ ?~ S.SwaggerString + & S.type_ ?~ S.OpenApiString & S.enum_ ?~ [ A.toJSON ("ProtectedUser" :: String), A.toJSON ("UnprotectedBot" :: String), diff --git a/libs/wire-api/src/Wire/API/Team/Member.hs b/libs/wire-api/src/Wire/API/Team/Member.hs index c962bcf8c00..91e790aa66e 100644 --- a/libs/wire-api/src/Wire/API/Team/Member.hs +++ b/libs/wire-api/src/Wire/API/Team/Member.hs @@ -132,7 +132,7 @@ deriving via deriving via (Schema (TeamMember' tag)) instance - (ToSchema (TeamMember' tag)) => + (ToSchema (TeamMember' tag), Typeable tag) => S.ToSchema (TeamMember' tag) mkTeamMember :: @@ -256,7 +256,7 @@ deriving via deriving via (Schema (TeamMemberList' tag)) instance - ToSchema (TeamMemberList' tag) => + (ToSchema (TeamMemberList' tag), Typeable tag) => S.ToSchema (TeamMemberList' tag) newTeamMemberList :: [TeamMember] -> ListType -> TeamMemberList @@ -348,7 +348,7 @@ deriving via deriving via (Schema (NewTeamMember' tag)) instance - (ToSchema (NewTeamMember' tag)) => + (ToSchema (NewTeamMember' tag), Typeable tag) => S.ToSchema (NewTeamMember' tag) deriving via (GenericUniform NewTeamMember) instance Arbitrary NewTeamMember diff --git a/libs/wire-api/src/Wire/API/Team/Role.hs b/libs/wire-api/src/Wire/API/Team/Role.hs index 4707d3d9884..d4602394750 100644 --- a/libs/wire-api/src/Wire/API/Team/Role.hs +++ b/libs/wire-api/src/Wire/API/Team/Role.hs @@ -93,7 +93,7 @@ instance ToSchema Role where instance S.ToParamSchema Role where toParamSchema _ = mempty - & S.type_ ?~ S.SwaggerString + & S.type_ ?~ S.OpenApiString & S.enum_ ?~ fmap roleName [minBound .. maxBound] instance FromHttpApiData Role where diff --git a/libs/wire-api/src/Wire/API/User.hs b/libs/wire-api/src/Wire/API/User.hs index 3ea0e88106f..16be7999255 100644 --- a/libs/wire-api/src/Wire/API/User.hs +++ b/libs/wire-api/src/Wire/API/User.hs @@ -1819,7 +1819,7 @@ instance S.ToSchema ListUsersQuery where pure $ S.NamedSchema (Just "ListUsersQuery") $ mempty - & S.type_ ?~ S.SwaggerObject + & S.type_ ?~ S.OpenApiObject & S.description ?~ "exactly one of qualified_ids or qualified_handles must be provided." & S.properties .~ InsOrdHashMap.fromList [("qualified_ids", uids), ("qualified_handles", handles)] & S.example ?~ toJSON (ListUsersByIds [Qualified (Id UUID.nil) (Domain "example.com")]) @@ -1954,8 +1954,8 @@ instance FromByteString VerificationAction where instance S.ToParamSchema VerificationAction where toParamSchema _ = mempty - { S._paramSchemaType = Just S.SwaggerString, - S._paramSchemaEnum = Just (A.String . toQueryParam <$> [(minBound :: VerificationAction) ..]) + { S._schemaType = Just S.OpenApiString, + S._schemaEnum = Just (A.String . toQueryParam <$> [(minBound :: VerificationAction) ..]) } instance FromHttpApiData VerificationAction where diff --git a/libs/wire-api/src/Wire/API/User/Client.hs b/libs/wire-api/src/Wire/API/User/Client.hs index ea69ade56db..198167cde03 100644 --- a/libs/wire-api/src/Wire/API/User/Client.hs +++ b/libs/wire-api/src/Wire/API/User/Client.hs @@ -83,8 +83,8 @@ import Data.Id import Data.Json.Util import Data.Map.Strict qualified as Map import Data.Misc (Latitude (..), Location, Longitude (..), PlainTextPassword6, latitude, location, longitude) -import Data.OpenApi hiding (Schema, ToSchema, schema) -import Data.OpenApi qualified as Swagger +import Data.OpenApi hiding (Schema, ToSchema, nullable, schema) +import Data.OpenApi qualified as Swagger hiding (nullable) import Data.Qualified import Data.Schema import Data.Set qualified as Set @@ -368,7 +368,7 @@ instance Swagger.ToSchema UserClientsFull where pure $ NamedSchema (Just "UserClientsFull") $ mempty - & type_ ?~ SwaggerObject + & type_ ?~ OpenApiObject & description ?~ "Dictionary object of `Client` objects indexed by `UserId`." & example ?~ "{\"1355c55a-0ac8-11ee-97ee-db1a6351f093\": , ...}" diff --git a/libs/wire-api/src/Wire/API/User/Identity.hs b/libs/wire-api/src/Wire/API/User/Identity.hs index 013da379b15..2b88c1d3bd8 100644 --- a/libs/wire-api/src/Wire/API/User/Identity.hs +++ b/libs/wire-api/src/Wire/API/User/Identity.hs @@ -326,7 +326,7 @@ instance S.ToSchema UserSSOId where pure $ S.NamedSchema (Just "UserSSOId") $ mempty - & S.type_ ?~ S.SwaggerObject + & S.type_ ?~ S.OpenApiObject & S.properties .~ [ ("tenant", tenantSchema), ("subject", subjectSchema), diff --git a/libs/wire-api/src/Wire/API/User/IdentityProvider.hs b/libs/wire-api/src/Wire/API/User/IdentityProvider.hs index 6d89141ba47..8486552c42d 100644 --- a/libs/wire-api/src/Wire/API/User/IdentityProvider.hs +++ b/libs/wire-api/src/Wire/API/User/IdentityProvider.hs @@ -107,9 +107,9 @@ instance ToHttpApiData WireIdPAPIVersion where instance ToParamSchema WireIdPAPIVersion where toParamSchema Proxy = mempty - { _paramSchemaDefault = Just "v2", - _paramSchemaType = Just SwaggerString, - _paramSchemaEnum = Just (String . toQueryParam <$> [(minBound :: WireIdPAPIVersion) ..]) + { _schemaDefault = Just "v2", + _schemaType = Just OpenApiString, + _schemaEnum = Just (String . toQueryParam <$> [(minBound :: WireIdPAPIVersion) ..]) } instance Cql.Cql WireIdPAPIVersion where @@ -198,7 +198,7 @@ instance ToSchema IdPMetadataInfo where & properties .~ properties_ & minProperties ?~ 1 & maxProperties ?~ 1 - & type_ ?~ SwaggerObject + & type_ ?~ OpenApiObject where properties_ :: InsOrdHashMap Text (Referenced Schema) properties_ = diff --git a/libs/wire-api/src/Wire/API/User/Orphans.hs b/libs/wire-api/src/Wire/API/User/Orphans.hs index 7331b156410..10ec177a3fe 100644 --- a/libs/wire-api/src/Wire/API/User/Orphans.hs +++ b/libs/wire-api/src/Wire/API/User/Orphans.hs @@ -94,7 +94,7 @@ instance ToSchema (SAML.FormRedirect SAML.AuthnRequest) where pure $ NamedSchema (Just "FormRedirect") $ mempty - & type_ ?~ SwaggerObject + & type_ ?~ OpenApiObject & properties . at "uri" ?~ Inline (toSchema (Proxy @Text)) & properties . at "xml" ?~ authnReqSchema diff --git a/libs/wire-api/src/Wire/API/User/Scim.hs b/libs/wire-api/src/Wire/API/User/Scim.hs index 76c5a3755ae..752c608bd85 100644 --- a/libs/wire-api/src/Wire/API/User/Scim.hs +++ b/libs/wire-api/src/Wire/API/User/Scim.hs @@ -462,7 +462,7 @@ instance ToSchema ScimTokenInfo where pure $ NamedSchema (Just "ScimTokenInfo") $ mempty - & type_ ?~ SwaggerObject + & type_ ?~ OpenApiObject & properties .~ [ ("team", teamSchema), ("id", idSchema), @@ -478,7 +478,7 @@ instance ToSchema CreateScimToken where pure $ NamedSchema (Just "CreateScimToken") $ mempty - & type_ ?~ SwaggerObject + & type_ ?~ OpenApiObject & properties .~ [ ("description", textSchema), ("password", textSchema), @@ -493,7 +493,7 @@ instance ToSchema CreateScimTokenResponse where pure $ NamedSchema (Just "CreateScimTokenResponse") $ mempty - & type_ ?~ SwaggerObject + & type_ ?~ OpenApiObject & properties .~ [ ("token", tokenSchema), ("info", infoSchema) @@ -506,7 +506,7 @@ instance ToSchema ScimTokenList where pure $ NamedSchema (Just "ScimTokenList") $ mempty - & type_ ?~ SwaggerObject + & type_ ?~ OpenApiObject & properties .~ [ ("tokens", infoListSchema) ] diff --git a/libs/wire-api/src/Wire/API/User/Search.hs b/libs/wire-api/src/Wire/API/User/Search.hs index 0ad5dcaa34b..deaf7c08f4d 100644 --- a/libs/wire-api/src/Wire/API/User/Search.hs +++ b/libs/wire-api/src/Wire/API/User/Search.hs @@ -228,7 +228,7 @@ data TeamUserSearchSortBy instance S.ToParamSchema TeamUserSearchSortBy where toParamSchema _ = mempty - & S.type_ ?~ S.SwaggerString + & S.type_ ?~ S.OpenApiString & S.enum_ ?~ fmap teamUserSearchSortByName [minBound .. maxBound] instance ToByteString TeamUserSearchSortBy where @@ -264,7 +264,7 @@ data TeamUserSearchSortOrder instance S.ToParamSchema TeamUserSearchSortOrder where toParamSchema _ = mempty - & S.type_ ?~ S.SwaggerString + & S.type_ ?~ S.OpenApiString & S.enum_ ?~ fmap teamUserSearchSortOrderName [minBound .. maxBound] instance ToByteString TeamUserSearchSortOrder where diff --git a/libs/wire-api/src/Wire/API/UserMap.hs b/libs/wire-api/src/Wire/API/UserMap.hs index 51ed966e0ff..31f81392195 100644 --- a/libs/wire-api/src/Wire/API/UserMap.hs +++ b/libs/wire-api/src/Wire/API/UserMap.hs @@ -56,7 +56,7 @@ instance Functor QualifiedUserMap where instance Arbitrary a => Arbitrary (QualifiedUserMap a) where arbitrary = QualifiedUserMap <$> mapOf' arbitrary arbitrary -instance (Typeable a, ToSchema a, ToJSON a, Arbitrary a) => ToSchema (UserMap (Set a)) where +instance (ToSchema a, ToJSON a, Arbitrary a) => ToSchema (UserMap (Set a)) where declareNamedSchema _ = do mapSch <- declareSchema (Proxy @(Map UserId (Set a))) let valueTypeName = Text.pack $ show $ typeRep $ Proxy @a diff --git a/libs/wire-api/src/Wire/API/Wrapped.hs b/libs/wire-api/src/Wire/API/Wrapped.hs index 0dc9d6edf4f..44c41bbddc2 100644 --- a/libs/wire-api/src/Wire/API/Wrapped.hs +++ b/libs/wire-api/src/Wire/API/Wrapped.hs @@ -48,7 +48,7 @@ instance (ToSchema a, KnownSymbol name) => ToSchema (Wrapped name a) where pure $ NamedSchema Nothing $ mempty - & type_ ?~ SwaggerObject + & type_ ?~ OpenApiObject & properties .~ InsOrdHashMap.singleton (Text.pack (symbolVal (Proxy @name))) wrappedSchema instance (Arbitrary a, KnownSymbol name) => Arbitrary (Wrapped name a) where diff --git a/libs/wire-api/wire-api.cabal b/libs/wire-api/wire-api.cabal index fb49f7fda89..6b55e049407 100644 --- a/libs/wire-api/wire-api.cabal +++ b/libs/wire-api/wire-api.cabal @@ -270,7 +270,7 @@ library , metrics-wai , mime >=0.4 , mtl - , openapi3 >=3.2 && <3.2.3 + , openapi3 , pem >=0.2 , polysemy , proto-lens @@ -748,7 +748,7 @@ test-suite wire-api-tests , imports , memory , metrics-wai - , openapi3 >=3.2 && <3.2.3 + , openapi3 , process , QuickCheck , schema-profunctor diff --git a/nix/manual-overrides.nix b/nix/manual-overrides.nix index f8764ed2c16..ec9d49f4d41 100644 --- a/nix/manual-overrides.nix +++ b/nix/manual-overrides.nix @@ -6,6 +6,7 @@ hself: hsuper: { binary-parsers = hlib.markUnbroken (hlib.doJailbreak hsuper.binary-parsers); bytestring-arbitrary = hlib.markUnbroken (hlib.doJailbreak hsuper.bytestring-arbitrary); cql = hlib.markUnbroken hsuper.cql; + openapi3 = hlib.markUnbroken (hlib.dontCheck hsuper.openapi3); hashtables = hsuper.hashtables_1_3; invertible = hlib.markUnbroken hsuper.invertible; lens-datetime = hlib.markUnbroken (hlib.doJailbreak hsuper.lens-datetime); diff --git a/services/brig/brig.cabal b/services/brig/brig.cabal index ab8dea22ec1..bf2b071b729 100644 --- a/services/brig/brig.cabal +++ b/services/brig/brig.cabal @@ -257,7 +257,7 @@ library , mwc-random , network >=2.4 , network-conduit-tls - , openapi3 >=3.2 && <3.2.3 + , openapi3 , optparse-applicative >=0.11 , polysemy , polysemy-plugin diff --git a/services/spar/spar.cabal b/services/spar/spar.cabal index 5bb672c0d97..124cbb93a99 100644 --- a/services/spar/spar.cabal +++ b/services/spar/spar.cabal @@ -618,7 +618,7 @@ test-suite spec , metrics-wai , mtl , network-uri - , openapi3 >=3.2 && <3.2.3 + , openapi3 , polysemy , polysemy-plugin , polysemy-wire-zoo diff --git a/tools/fedcalls/fedcalls.cabal b/tools/fedcalls/fedcalls.cabal index f01972e0d21..3ed39f04b6b 100644 --- a/tools/fedcalls/fedcalls.cabal +++ b/tools/fedcalls/fedcalls.cabal @@ -69,7 +69,7 @@ executable fedcalls , imports , insert-ordered-containers , language-dot - , openapi3 >=3.2.0 && <3.2.3 + , openapi3 , wire-api default-language: GHC2021 diff --git a/tools/stern/src/Stern/Types.hs b/tools/stern/src/Stern/Types.hs index 08f16b8d80f..f8ed807492a 100644 --- a/tools/stern/src/Stern/Types.hs +++ b/tools/stern/src/Stern/Types.hs @@ -127,7 +127,7 @@ instance Swagger.ToSchema ConsentLog where declareNamedSchema _ = pure . Swagger.NamedSchema (Just "ConsentLog") $ mempty - & Swagger.type_ ?~ Swagger.SwaggerObject + & Swagger.type_ ?~ Swagger.OpenApiObject & Swagger.description ?~ "(object structure is not specified in this schema)" newtype ConsentValue = ConsentValue @@ -152,7 +152,7 @@ instance Swagger.ToSchema ConsentLogAndMarketo where declareNamedSchema _ = pure . Swagger.NamedSchema (Just "ConsentLogAndMarketo") $ mempty - & Swagger.type_ ?~ Swagger.SwaggerObject + & Swagger.type_ ?~ Swagger.OpenApiObject & Swagger.description ?~ "(object structure is not specified in this schema)" newtype UserMetaInfo = UserMetaInfo @@ -164,7 +164,7 @@ instance Swagger.ToSchema UserMetaInfo where declareNamedSchema _ = pure . Swagger.NamedSchema (Just "UserMetaInfo") $ mempty - & Swagger.type_ ?~ Swagger.SwaggerObject + & Swagger.type_ ?~ Swagger.OpenApiObject & Swagger.description ?~ "(object structure is not specified in this schema)" newtype InvoiceId = InvoiceId {unInvoiceId :: Text} diff --git a/tools/stern/stern.cabal b/tools/stern/stern.cabal index efd4b2f08e9..4cb3eff82ea 100644 --- a/tools/stern/stern.cabal +++ b/tools/stern/stern.cabal @@ -91,7 +91,7 @@ library , lens >=4.4 , metrics-wai >=0.3 , mtl >=2.1 - , openapi3 >=3.2 && <3.2.3 + , openapi3 , schema-profunctor , servant , servant-openapi3 @@ -110,7 +110,6 @@ library , wire-api >=0.1 , yaml - -- openapi3 version 3.2.3 is marked as broken in nix default-language: GHC2021 executable stern From db242d78b98cdc16ca189bb16e41418ad90f15fa Mon Sep 17 00:00:00 2001 From: Owen Harvey Date: Fri, 8 Sep 2023 17:10:05 +1000 Subject: [PATCH 04/15] WPB-4240: Fixing up fedcalls and working around limitations in openapi3 openapi3, the library, doesn't support extensions in the schema yet. Thus, we can't use the same method of tracking FedCalls for the routes. I've changed this to work with tags, as we werent' otherwise using them, and updated the code to match. --- .../test/unit/Test/Brig/Roundtrip.hs | 2 +- .../src/Wire/API/MakesFederatedCall.hs | 57 +++++++----- libs/wire-api/src/Wire/API/Routes/CSV.hs | 13 +++ .../unit/Test/Wire/API/Roundtrip/Aeson.hs | 2 +- .../test/unit/Test/Wire/API/Swagger.hs | 2 +- services/brig/src/Brig/API/Public.hs | 2 +- services/brig/src/Brig/API/Public/Swagger.hs | 8 +- tools/fedcalls/default.nix | 6 +- tools/fedcalls/fedcalls.cabal | 5 +- tools/fedcalls/src/Main.hs | 86 +++++++++++-------- tools/stern/src/Stern/API/Routes.hs | 2 +- 11 files changed, 116 insertions(+), 69 deletions(-) diff --git a/libs/brig-types/test/unit/Test/Brig/Roundtrip.hs b/libs/brig-types/test/unit/Test/Brig/Roundtrip.hs index 5e4ada038e8..13cfc3570e6 100644 --- a/libs/brig-types/test/unit/Test/Brig/Roundtrip.hs +++ b/libs/brig-types/test/unit/Test/Brig/Roundtrip.hs @@ -40,7 +40,7 @@ testRoundTrip = testProperty msg trip testRoundTripWithSwagger :: forall a. - (Arbitrary a, Typeable a, ToJSON a, FromJSON a, ToSchema a, Eq a, Show a) => + (Arbitrary a, ToJSON a, FromJSON a, ToSchema a, Eq a, Show a) => TestTree testRoundTripWithSwagger = testProperty msg (trip .&&. scm) where diff --git a/libs/wire-api/src/Wire/API/MakesFederatedCall.hs b/libs/wire-api/src/Wire/API/MakesFederatedCall.hs index 6b5f6f262a3..c3b9bb7b120 100644 --- a/libs/wire-api/src/Wire/API/MakesFederatedCall.hs +++ b/libs/wire-api/src/Wire/API/MakesFederatedCall.hs @@ -31,12 +31,17 @@ module Wire.API.MakesFederatedCall ) where +import Control.Lens ((%~), (<>~), _Just) import Data.Aeson import Data.Constraint +import Data.HashSet.InsOrd (singleton) import Data.Kind import Data.Metrics.Servant +import Data.OpenApi qualified as S +import Data.OpenApi.Lens qualified as S import Data.Proxy import Data.Schema +import Data.Text qualified as T import GHC.TypeLits import Imports import Servant.API @@ -159,26 +164,38 @@ type instance instance (HasOpenApi api, KnownSymbol name, KnownSymbol (ShowComponent comp)) => HasOpenApi (MakesFederatedCall comp name :> api :: Type) where toOpenApi _ = toOpenApi (Proxy @api) - --- TODO & FUTUREWORK: openapi3 doesn't use an underlying aeson Value --- structure to build up the schema. To enable extensions, we will need --- to update the structures in openapi3 to include an extensions field, --- likely holding a Value type. --- & addExtensions --- mergeJSONArray --- [ ( "wire-makes-federated-call-to", --- Array --- [ Array --- [ String $ T.pack $ symbolVal $ Proxy @(ShowComponent comp), --- String $ T.pack $ symbolVal $ Proxy @name --- ] --- ] --- ) --- ] --- --- mergeJSONArray :: Value -> Value -> Value --- mergeJSONArray (Array x) (Array y) = Array $ x <> y --- mergeJSONArray _ _ = error "impossible! bug in construction of federated calls JSON" + -- Since extensions aren't in the openapi3 library yet, + -- and the PRs for their support seem be going no where quickly, I'm using + -- tags instead. https://github.com/biocad/openapi3/pull/43 + -- Basically, this is similar to the old system, except we don't have nested JSON to + -- work with. So I'm using the magic string and sticking the call name on the end + -- and sticking the component in the description. This ordering is important as we + -- can't have duplicate tag names on an object. + + -- Set the tags at the top of OpenApi object + & S.tags + <>~ singleton + ( S.Tag + name + (pure $ T.pack (symbolVal $ Proxy @(ShowComponent comp))) + Nothing + ) + -- Set the tags on the specific path we're looking at + -- This is where the tag is actually registered on the path + -- so it can be picked up by fedcalls. + & S.paths . traverse %~ \pathItem -> + pathItem + & S.get . _Just . S.tags <>~ setName + & S.put . _Just . S.tags <>~ setName + & S.post . _Just . S.tags <>~ setName + & S.delete . _Just . S.tags <>~ setName + & S.options . _Just . S.tags <>~ setName + & S.head_ . _Just . S.tags <>~ setName + & S.patch . _Just . S.tags <>~ setName + & S.trace . _Just . S.tags <>~ setName + where + name = "wire-makes-federated-call-to-" <> T.pack (symbolVal $ Proxy @name) + setName = singleton name instance HasClient m api => HasClient m (MakesFederatedCall comp name :> api :: Type) where type Client m (MakesFederatedCall comp name :> api) = Client m api diff --git a/libs/wire-api/src/Wire/API/Routes/CSV.hs b/libs/wire-api/src/Wire/API/Routes/CSV.hs index 0d09941545c..25a1a88000d 100644 --- a/libs/wire-api/src/Wire/API/Routes/CSV.hs +++ b/libs/wire-api/src/Wire/API/Routes/CSV.hs @@ -17,6 +17,11 @@ module Wire.API.Routes.CSV where +import Control.Lens +import Data.OpenApi qualified as O +import Data.OpenApi.Internal.Schema +import Data.OpenApi.Schema +import Imports import Network.HTTP.Media.MediaType import Servant.API @@ -24,3 +29,11 @@ data CSV instance Accept CSV where contentType _ = "text" // "csv" + +instance ToSchema CSV where + declareNamedSchema _ = + plain $ + mempty + & O.title ?~ "CSV" + & O.type_ ?~ O.OpenApiString + & O.format ?~ "text/csv" diff --git a/libs/wire-api/test/unit/Test/Wire/API/Roundtrip/Aeson.hs b/libs/wire-api/test/unit/Test/Wire/API/Roundtrip/Aeson.hs index ed5c9ed1dc0..aefaa6cb8cd 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Roundtrip/Aeson.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Roundtrip/Aeson.hs @@ -355,7 +355,7 @@ testRoundTrip = testProperty msg trip testRoundTripWithSwagger :: forall a. - (Arbitrary a, Typeable a, ToJSON a, FromJSON a, ToSchema a, Eq a, Show a) => + (Arbitrary a, ToJSON a, FromJSON a, ToSchema a, Eq a, Show a) => T.TestTree testRoundTripWithSwagger = testProperty msg (trip .&&. scm) where diff --git a/libs/wire-api/test/unit/Test/Wire/API/Swagger.hs b/libs/wire-api/test/unit/Test/Wire/API/Swagger.hs index bab30d63e56..bbb37e6e2a4 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Swagger.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Swagger.hs @@ -56,7 +56,7 @@ tests = testToJSON @(Wrapped.Wrapped "some_user" User.User) ] -testToJSON :: forall a. (Arbitrary a, Typeable a, ToJSON a, ToSchema a, Show a) => T.TestTree +testToJSON :: forall a. (Arbitrary a, ToJSON a, ToSchema a, Show a) => T.TestTree testToJSON = testProperty msg trip where msg = show (typeRep @a) diff --git a/services/brig/src/Brig/API/Public.hs b/services/brig/src/Brig/API/Public.hs index 9aed2db83c8..d78bb1ce79a 100644 --- a/services/brig/src/Brig/API/Public.hs +++ b/services/brig/src/Brig/API/Public.hs @@ -236,7 +236,7 @@ versionedSwaggerDocsAPI Nothing = allroutes (throwError listAllVersionsResp) internalEndpointsSwaggerDocsAPI :: String -> PortNumber -> - S.Swagger -> + S.OpenApi -> Servant.Server (VersionedSwaggerDocsAPIBase service) internalEndpointsSwaggerDocsAPI service examplePort swagger (Just (VersionNumber V5)) = swaggerSchemaUIServer $ diff --git a/services/brig/src/Brig/API/Public/Swagger.hs b/services/brig/src/Brig/API/Public/Swagger.hs index 3debaac9ba1..e17607cf8f7 100644 --- a/services/brig/src/Brig/API/Public/Swagger.hs +++ b/services/brig/src/Brig/API/Public/Swagger.hs @@ -68,16 +68,14 @@ swaggerPregenUIServer = . fromMaybe A.Null . A.decode -adjustSwaggerForInternalEndpoint :: String -> PortNumber -> S.Swagger -> S.Swagger +adjustSwaggerForInternalEndpoint :: String -> PortNumber -> S.OpenApi -> S.OpenApi adjustSwaggerForInternalEndpoint service examplePort swagger = swagger & S.info . S.title .~ T.pack ("Wire-Server internal API (" ++ service ++ ")") & S.info . S.description ?~ renderedDescription - & S.host ?~ S.Host "localhost" (Just examplePort) & S.allOperations . S.tags <>~ tag -- Enforce HTTP as the services themselves don't understand HTTPS - & S.schemes ?~ [S.Http] - & S.allOperations . S.schemes ?~ [S.Http] + & S.servers .~ [S.Server ("http://localhost:" <> T.pack (show examplePort)) Nothing mempty] where tag :: InsOrdSet.InsOrdHashSet S.TagName tag = InsOrdSet.singleton @S.TagName (T.pack service) @@ -102,7 +100,7 @@ adjustSwaggerForInternalEndpoint service examplePort swagger = emptySwagger :: Servant.Server (ServiceSwaggerDocsAPIBase a) emptySwagger = swaggerSchemaUIServer $ - mempty @S.Swagger + mempty @S.OpenApi & S.info . S.description ?~ "There is no Swagger documentation for this version. Please refer to v3 or later." diff --git a/tools/fedcalls/default.nix b/tools/fedcalls/default.nix index dd14e7a2859..2d9d10e326d 100644 --- a/tools/fedcalls/default.nix +++ b/tools/fedcalls/default.nix @@ -3,15 +3,16 @@ # must be regenerated whenever local packages are added or removed, or # dependencies are added or removed. { mkDerivation -, aeson , base , containers , gitignoreSource , imports , insert-ordered-containers , language-dot +, lens , lib , openapi3 +, text , wire-api }: mkDerivation { @@ -21,13 +22,14 @@ mkDerivation { isLibrary = false; isExecutable = true; executableHaskellDepends = [ - aeson base containers imports insert-ordered-containers language-dot + lens openapi3 + text wire-api ]; description = "Generate a dot file from swagger docs representing calls to federated instances"; diff --git a/tools/fedcalls/fedcalls.cabal b/tools/fedcalls/fedcalls.cabal index 3ed39f04b6b..615a8bbd151 100644 --- a/tools/fedcalls/fedcalls.cabal +++ b/tools/fedcalls/fedcalls.cabal @@ -63,13 +63,14 @@ executable fedcalls -rtsopts -Wredundant-constraints -Wunused-packages build-depends: - aeson - , base + base , containers , imports , insert-ordered-containers , language-dot + , lens , openapi3 + , text , wire-api default-language: GHC2021 diff --git a/tools/fedcalls/src/Main.hs b/tools/fedcalls/src/Main.hs index 9769a40b074..387424fde9c 100644 --- a/tools/fedcalls/src/Main.hs +++ b/tools/fedcalls/src/Main.hs @@ -23,23 +23,13 @@ module Main where import Control.Exception (assert) -import Data.Aeson as A -import Data.Aeson.Types qualified as A +import Control.Lens import Data.HashMap.Strict.InsOrd qualified as HM +import Data.HashSet.InsOrd (InsOrdHashSet) import Data.Map qualified as M import Data.OpenApi - ( PathItem, - Swagger, - _operationExtensions, - _pathItemDelete, - _pathItemGet, - _pathItemHead, - _pathItemOptions, - _pathItemPatch, - _pathItemPost, - _pathItemPut, - _swaggerPaths, - ) +import Data.OpenApi.Lens qualified as S +import Data.Text qualified as T import Imports import Language.Dot as D import Wire.API.Routes.API @@ -65,7 +55,7 @@ calls = assert (calls' == nub calls') calls' where calls' = mconcat $ parse <$> swaggers -swaggers :: [Swagger] +swaggers :: [OpenApi] swaggers = [ -- TODO: introduce allSwaggerDocs in wire-api that collects these for all -- services, use that in /services/brig/src/Brig/API/Public.hs instead of @@ -101,37 +91,63 @@ data MakesCallTo = MakesCallTo ------------------------------ -parse :: Swagger -> [MakesCallTo] -parse = +parse :: OpenApi -> [MakesCallTo] +parse oapi = mconcat - . fmap parseOperationExtensions + . fmap (parseOperationExtensions allTags) . mconcat . fmap flattenPathItems . HM.toList - . _swaggerPaths + $ oapi ^. S.paths + where + allTags = oapi ^. S.tags + +-- Simple aliases to help track which field is what +type RPC = String + +type Component = String -- | extract path, method, and operation extensions -flattenPathItems :: (FilePath, PathItem) -> [((FilePath, String), HM.InsOrdHashMap Text Value)] +flattenPathItems :: (FilePath, PathItem) -> [((FilePath, String), InsOrdHashSet TagName)] flattenPathItems (path, item) = filter ((/= mempty) . snd) $ catMaybes - [ ((path, "get"),) . _operationExtensions <$> _pathItemGet item, - ((path, "put"),) . _operationExtensions <$> _pathItemPut item, - ((path, "post"),) . _operationExtensions <$> _pathItemPost item, - ((path, "delete"),) . _operationExtensions <$> _pathItemDelete item, - ((path, "options"),) . _operationExtensions <$> _pathItemOptions item, - ((path, "head"),) . _operationExtensions <$> _pathItemHead item, - ((path, "patch"),) . _operationExtensions <$> _pathItemPatch item + [ ((path, "get"),) . view S.tags <$> _pathItemGet item, + ((path, "put"),) . view S.tags <$> _pathItemPut item, + ((path, "post"),) . view S.tags <$> _pathItemPost item, + ((path, "delete"),) . view S.tags <$> _pathItemDelete item, + ((path, "options"),) . view S.tags <$> _pathItemOptions item, + ((path, "head"),) . view S.tags <$> _pathItemHead item, + ((path, "patch"),) . view S.tags <$> _pathItemPatch item ] -parseOperationExtensions :: ((FilePath, String), HM.InsOrdHashMap Text Value) -> [MakesCallTo] -parseOperationExtensions ((path, method), hm) = uncurry (MakesCallTo path method) <$> findCallsFedInfo hm +parseOperationExtensions :: InsOrdHashSet Tag -> ((FilePath, String), InsOrdHashSet TagName) -> [MakesCallTo] +parseOperationExtensions allTags ((path, method), hm) = + uncurry (MakesCallTo path method) <$> findCallsFedInfo allTags hm -findCallsFedInfo :: HM.InsOrdHashMap Text Value -> [(String, String)] -findCallsFedInfo hm = case A.parse parseJSON <$> HM.lookup "wire-makes-federated-call-to" hm of - Just (A.Success (fedcalls :: [(String, String)])) -> fedcalls - Just bad -> error $ "invalid extension `wire-makes-federated-call-to`: expected `[(comp, name), ...]`, got " <> show bad - Nothing -> [] +-- Given a set of tags, and a set of tag names for an operation, +-- parse out the RPC calls and their components +findCallsFedInfo :: InsOrdHashSet Tag -> InsOrdHashSet TagName -> [(Component, RPC)] +findCallsFedInfo allTags = mapMaybe extractStrings . toList + where + magicPrefix :: Text + magicPrefix = "wire-makes-federated-call-to-" + extractStrings :: TagName -> Maybe (Component, RPC) + extractStrings tagName = + tag >>= \t -> + (,) + -- Extract the name and description, and drop everything that is empty + -- This gives us the component name, and as a route may call the same component + -- multiple times, it has to go into the description so it isn't dropped by the set. + <$> fmap T.unpack t._tagDescription + -- Strip off the magic string from the tag names, and drop empty results + -- This also implicitly filters for results that start with the prefix. + -- This gives us the RPC name, as that will be unique for each route, and it + -- doesn't matter if it is set multiple times and dropped in the set, as it + -- still describes that Fed call is made. + <*> fmap T.unpack (T.stripPrefix magicPrefix t._tagName) + where + tag = find (\t -> t._tagName == tagName) allTags ------------------------------ @@ -158,7 +174,7 @@ mkDotGraph inbound = Graph StrictGraph DirectedGraph Nothing (mods <> nodes <> e itemSourceNode (MakesCallTo path method _ _) = method <> " " <> path itemTargetNode :: MakesCallTo -> String - itemTargetNode (MakesCallTo _ _ comp name) = "[" <> comp <> "]:" <> name + itemTargetNode (MakesCallTo _ _ comp rpcName) = "[" <> comp <> "]:" <> rpcName callingNodes :: Map String Integer callingNodes = diff --git a/tools/stern/src/Stern/API/Routes.hs b/tools/stern/src/Stern/API/Routes.hs index 5fd3ec39959..aae30de2805 100644 --- a/tools/stern/src/Stern/API/Routes.hs +++ b/tools/stern/src/Stern/API/Routes.hs @@ -455,7 +455,7 @@ type SwaggerDocsAPI = SwaggerSchemaUI "swagger-ui" "swagger.json" swaggerDocs :: Servant.Server SwaggerDocsAPI swaggerDocs = swaggerSchemaUIServer $ - toSwagger (Proxy @SternAPI) + toOpenApi (Proxy @SternAPI) & S.info . S.title .~ "Stern API" & cleanupSwagger From 1aa191df0ec3f80ba104982bc5707debb4d2e304 Mon Sep 17 00:00:00 2001 From: Owen Harvey Date: Fri, 8 Sep 2023 17:18:32 +1000 Subject: [PATCH 05/15] WPB-4240: Adding changelogs --- changelog.d/4-docs/WPB-4240 | 1 + changelog.d/5-internal/WPB-4240 | 4 ++++ 2 files changed, 5 insertions(+) create mode 100644 changelog.d/4-docs/WPB-4240 create mode 100644 changelog.d/5-internal/WPB-4240 diff --git a/changelog.d/4-docs/WPB-4240 b/changelog.d/4-docs/WPB-4240 new file mode 100644 index 00000000000..d7dd76196ec --- /dev/null +++ b/changelog.d/4-docs/WPB-4240 @@ -0,0 +1 @@ +Updating the route documentation from Swagger 2 to OpenAPI 3. \ No newline at end of file diff --git a/changelog.d/5-internal/WPB-4240 b/changelog.d/5-internal/WPB-4240 new file mode 100644 index 00000000000..bca7dcb1fc6 --- /dev/null +++ b/changelog.d/5-internal/WPB-4240 @@ -0,0 +1,4 @@ +Updating the route documentation library from swagger2 to openapi3. + +This also introduced a breaking change in how we track what federation calls each route makes. +The openapi3 library doesn't support extension fields, and as such tags are being used instead in a similar way. \ No newline at end of file From 853388bec91e8a22f7c93bc68ca41425bee5cd57 Mon Sep 17 00:00:00 2001 From: Owen Harvey Date: Fri, 8 Sep 2023 17:51:30 +1000 Subject: [PATCH 06/15] WPB-4240: Small things picked up while going over the PR diff --- libs/deriving-swagger2/src/Deriving/Swagger.hs | 3 ++- .../src/Wire/API/MakesFederatedCall.hs | 1 - libs/wire-api/src/Wire/API/Routes/CSV.hs | 1 - libs/wire-api/src/Wire/API/Routes/MultiVerb.hs | 18 ++++++++---------- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/libs/deriving-swagger2/src/Deriving/Swagger.hs b/libs/deriving-swagger2/src/Deriving/Swagger.hs index aea688714ee..95a0c121a3e 100644 --- a/libs/deriving-swagger2/src/Deriving/Swagger.hs +++ b/libs/deriving-swagger2/src/Deriving/Swagger.hs @@ -25,6 +25,7 @@ import Data.Char qualified as Char import Data.Kind (Constraint) import Data.List.Extra (stripSuffix) import Data.OpenApi.Internal.Schema (GToSchema) +import Data.OpenApi.Internal.TypeShape import Data.OpenApi.Schema import Data.Proxy (Proxy (..)) import GHC.Generics (Generic (Rep)) @@ -96,7 +97,7 @@ instance (StringModifier f, SwaggerOptions xs) => SwaggerOptions (FieldLabelModi instance (StringModifier f, SwaggerOptions xs) => SwaggerOptions (ConstructorTagModifier f ': xs) where swaggerOptions = (swaggerOptions @xs) {constructorTagModifier = getStringModifier @f} -instance (SwaggerOptions t, Generic a, Typeable a, GToSchema (Rep a), Typeable (CustomSwagger t a)) => ToSchema (CustomSwagger t a) where +instance (SwaggerOptions t, Generic a, Typeable a, GToSchema (Rep a), Typeable (CustomSwagger t a), TypeHasSimpleShape a "genericDeclareNamedSchemaUnrestricted") => ToSchema (CustomSwagger t a) where declareNamedSchema _ = genericDeclareNamedSchema (swaggerOptions @t) (Proxy @a) -- ** Specify __what__ to modify diff --git a/libs/wire-api/src/Wire/API/MakesFederatedCall.hs b/libs/wire-api/src/Wire/API/MakesFederatedCall.hs index c3b9bb7b120..cbbfb3f6925 100644 --- a/libs/wire-api/src/Wire/API/MakesFederatedCall.hs +++ b/libs/wire-api/src/Wire/API/MakesFederatedCall.hs @@ -38,7 +38,6 @@ import Data.HashSet.InsOrd (singleton) import Data.Kind import Data.Metrics.Servant import Data.OpenApi qualified as S -import Data.OpenApi.Lens qualified as S import Data.Proxy import Data.Schema import Data.Text qualified as T diff --git a/libs/wire-api/src/Wire/API/Routes/CSV.hs b/libs/wire-api/src/Wire/API/Routes/CSV.hs index 25a1a88000d..0345336c378 100644 --- a/libs/wire-api/src/Wire/API/Routes/CSV.hs +++ b/libs/wire-api/src/Wire/API/Routes/CSV.hs @@ -20,7 +20,6 @@ module Wire.API.Routes.CSV where import Control.Lens import Data.OpenApi qualified as O import Data.OpenApi.Internal.Schema -import Data.OpenApi.Schema import Imports import Network.HTTP.Media.MediaType import Servant.API diff --git a/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs b/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs index 459294a8d2d..4cdaca1654b 100644 --- a/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs +++ b/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs @@ -466,15 +466,12 @@ instance ) => IsSwaggerResponseList (a ': as) where - responseListSwagger = do - resp <- responseSwagger @a - respList <- responseListSwagger @as - pure $ - InsOrdHashMap.insertWith - combineResponseSwagger - (fromIntegral (natVal (Proxy @(ResponseStatus a)))) - resp - respList + responseListSwagger = + InsOrdHashMap.insertWith + combineResponseSwagger + (fromIntegral (natVal (Proxy @(ResponseStatus a)))) + <$> responseSwagger @a + <*> responseListSwagger @as combineResponseSwagger :: S.Response -> S.Response -> S.Response combineResponseSwagger r1 r2 = @@ -716,7 +713,8 @@ instance . at "/" ?~ ( mempty & method - ?~ ( mempty & (S.responses @S.Operation @S.Responses) . S.responses .~ refResps + ?~ ( mempty + & S.responses . S.responses .~ refResps ) ) where From ea158d0a7d0fcbd375f70c75bdca72906680564e Mon Sep 17 00:00:00 2001 From: Owen Harvey Date: Tue, 12 Sep 2023 18:31:48 +1000 Subject: [PATCH 07/15] A working version, with a few dodgy fixes that need to be removed. --- .../wire-api/src/Wire/API/Routes/MultiVerb.hs | 77 +++++++++++++++---- .../wire-api/src/Wire/API/Routes/Versioned.hs | 2 +- 2 files changed, 62 insertions(+), 17 deletions(-) diff --git a/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs b/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs index 4cdaca1654b..3102141c6b6 100644 --- a/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs +++ b/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs @@ -41,6 +41,7 @@ module Wire.API.Routes.MultiVerb ResponseType, IsResponse (..), IsSwaggerResponse (..), + IsSwaggerResponseList (..), simpleResponseSwagger, combineResponseSwagger, ResponseTypes, @@ -55,7 +56,7 @@ import Data.ByteString.Builder import Data.ByteString.Lazy qualified as LBS import Data.CaseInsensitive qualified as CI import Data.Either.Combinators (leftToMaybe) -import Data.HashMap.Strict.InsOrd (InsOrdHashMap) +import Data.HashMap.Strict.InsOrd (InsOrdHashMap, unionWith) import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap import Data.Kind import Data.Metrics.Servant @@ -69,6 +70,7 @@ import Data.Sequence qualified as Seq import Data.Text qualified as Text import Data.Text.Encoding qualified as Text import Data.Typeable +import Debug.Trace qualified as T import GHC.TypeLits import Generics.SOP as GSOP import Imports hiding (cs) @@ -191,19 +193,25 @@ instance (AllMimeRender cs a, AllMimeUnrender cs a, KnownStatus s) => IsResponse Nothing -> empty Just f -> either UnrenderError UnrenderSuccess (f (responseBody output)) -simpleResponseSwagger :: forall a desc. (S.ToSchema a, KnownSymbol desc) => Declare S.Response +simpleResponseSwagger :: forall a cs desc. (S.ToSchema a, KnownSymbol desc, AllMime cs) => Declare S.Response simpleResponseSwagger = do ref <- S.declareSchemaRef (Proxy @a) + let resps :: InsOrdHashMap M.MediaType MediaTypeObject + resps = InsOrdHashMap.fromList $ (,MediaTypeObject (pure ref) Nothing mempty mempty) <$> cs pure $ mempty & S.description .~ Text.pack (symbolVal (Proxy @desc)) - & S.content . traverse . S.schema ?~ ref + & S.content .~ resps + where + cs :: [M.MediaType] + cs = allMime $ Proxy @cs instance (KnownSymbol desc, S.ToSchema a) => IsSwaggerResponse (Respond s desc a) where - responseSwagger = simpleResponseSwagger @a @desc + -- TODO: Defaulting this to JSON, as openapi3 needs something to map a schema against. + responseSwagger = simpleResponseSwagger @a @'[JSON] @desc type instance ResponseType (RespondAs ct s desc a) = a @@ -248,10 +256,10 @@ instance KnownStatus s => IsResponse cs (RespondAs '() s desc ()) where guard (responseStatusCode output == statusVal (Proxy @s)) instance - (KnownSymbol desc, S.ToSchema a) => + (KnownSymbol desc, S.ToSchema a, Accept ct) => IsSwaggerResponse (RespondAs (ct :: Type) s desc a) where - responseSwagger = simpleResponseSwagger @a @desc + responseSwagger = simpleResponseSwagger @a @'[ct] @desc instance (KnownSymbol desc) => @@ -475,14 +483,33 @@ instance combineResponseSwagger :: S.Response -> S.Response -> S.Response combineResponseSwagger r1 r2 = - r1 - & S.description <>~ ("\n\n" <> r2 ^. S.description) - & S.content - . traverse - . S.schema - . _Just - . S._Inline - %~ flip combineSwaggerSchema (r2 ^. S.content . traverse . S.schema . _Just . S._Inline) + let r = + r1 + & S.description <>~ ("\n\n" <> r2 ^. S.description) + -- & S.content + -- . traverse + -- . S.schema + -- . _Just + -- . S._Inline + -- %~ flip combineSwaggerSchema (r2 ^. S.content . traverse . S.schema . _Just . S._Inline) + + & S.content %~ flip (unionWith combineMediaTypeObject) (r2 ^. S.content) + s = show r + in if isInfixOf "get-user-qualified" s || isInfixOf "UserProfile" s + then T.traceShowId r + else T.trace "bar" r + +combineMediaTypeObject :: S.MediaTypeObject -> S.MediaTypeObject -> S.MediaTypeObject +combineMediaTypeObject m1 m2 = + m1 & S.schema .~ merge (m1 ^. S.schema) (m2 ^. S.schema) + where + -- m1 & S.schema . _Just . S._Inline %~ flip combineSwaggerSchema (m2 ^. S.schema . _Just . S._Inline) + + merge Nothing a = a + merge a Nothing = a + merge (Just (Inline a)) (Just (Inline b)) = pure $ Inline $ combineSwaggerSchema a b + merge a@(Just (Ref _)) _ = a + merge _ a@(Just (Ref _)) = a combineSwaggerSchema :: S.Schema -> S.Schema -> S.Schema combineSwaggerSchema s1 s2 @@ -739,9 +766,27 @@ instance ) where method = S.openApiMethod (Proxy @method) - _cs = allMime (Proxy @cs) + -- This has our content types. + cs = allMime (Proxy @cs) + -- This has our schemas (defs, resps) = S.runDeclare (responseListSwagger @as) mempty - refResps = S.Inline <$> resps + -- We need to zip them together, and stick it all back into the contentMap + -- Since we have a single schema per type, and are only changing the content-types, + -- we should be able to pick a schema out of the resps' map, and then use it in for + -- all of the values out of cs + addMime :: S.Response -> S.Response + addMime resp = + resp + & S.content + %~ + -- pick out an element from the map, if any exist. + -- These will all have the same schemas, and we are reapplying the content types. + foldMap (\c -> InsOrdHashMap.fromList $ (,c) <$> cs) + . listToMaybe + . toList + -- contentMap :: InsOrdHashMap M.MediaType MediaTypeObject + -- contentMap = InsOrdHashMap.fromList $ (, MediaTypeObject (pure $ S.Inline $ _) Nothing mempty mempty) <$> cs + refResps = S.Inline . addMime <$> resps class Typeable a => IsWaiBody a where responseToWai :: ResponseF a -> Wai.Response diff --git a/libs/wire-api/src/Wire/API/Routes/Versioned.hs b/libs/wire-api/src/Wire/API/Routes/Versioned.hs index d461a65523d..7707e3441e6 100644 --- a/libs/wire-api/src/Wire/API/Routes/Versioned.hs +++ b/libs/wire-api/src/Wire/API/Routes/Versioned.hs @@ -92,7 +92,7 @@ instance (KnownSymbol desc, S.ToSchema a) => IsSwaggerResponse (VersionedRespond v s desc a) where - responseSwagger = simpleResponseSwagger @a @desc + responseSwagger = simpleResponseSwagger @a @'[JSON] @desc ------------------------------------------------------------------------------- -- Versioned newtype wrapper From a986ead7bbef3e56be57f161333778a3c1c95691 Mon Sep 17 00:00:00 2001 From: Owen Harvey Date: Wed, 13 Sep 2023 13:47:28 +1000 Subject: [PATCH 08/15] Small code cleanup --- .../wire-api/src/Wire/API/Routes/MultiVerb.hs | 23 ++++--------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs b/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs index 3102141c6b6..40df76bf7c6 100644 --- a/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs +++ b/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs @@ -70,7 +70,6 @@ import Data.Sequence qualified as Seq import Data.Text qualified as Text import Data.Text.Encoding qualified as Text import Data.Typeable -import Debug.Trace qualified as T import GHC.TypeLits import Generics.SOP as GSOP import Imports hiding (cs) @@ -210,7 +209,7 @@ instance (KnownSymbol desc, S.ToSchema a) => IsSwaggerResponse (Respond s desc a) where - -- TODO: Defaulting this to JSON, as openapi3 needs something to map a schema against. + -- Defaulting this to JSON, as openapi3 needs something to map a schema against. responseSwagger = simpleResponseSwagger @a @'[JSON] @desc type instance ResponseType (RespondAs ct s desc a) = a @@ -483,28 +482,14 @@ instance combineResponseSwagger :: S.Response -> S.Response -> S.Response combineResponseSwagger r1 r2 = - let r = - r1 - & S.description <>~ ("\n\n" <> r2 ^. S.description) - -- & S.content - -- . traverse - -- . S.schema - -- . _Just - -- . S._Inline - -- %~ flip combineSwaggerSchema (r2 ^. S.content . traverse . S.schema . _Just . S._Inline) - - & S.content %~ flip (unionWith combineMediaTypeObject) (r2 ^. S.content) - s = show r - in if isInfixOf "get-user-qualified" s || isInfixOf "UserProfile" s - then T.traceShowId r - else T.trace "bar" r + r1 + & S.description <>~ ("\n\n" <> r2 ^. S.description) + & S.content %~ flip (unionWith combineMediaTypeObject) (r2 ^. S.content) combineMediaTypeObject :: S.MediaTypeObject -> S.MediaTypeObject -> S.MediaTypeObject combineMediaTypeObject m1 m2 = m1 & S.schema .~ merge (m1 ^. S.schema) (m2 ^. S.schema) where - -- m1 & S.schema . _Just . S._Inline %~ flip combineSwaggerSchema (m2 ^. S.schema . _Just . S._Inline) - merge Nothing a = a merge a Nothing = a merge (Just (Inline a)) (Just (Inline b)) = pure $ Inline $ combineSwaggerSchema a b From 1890bd99fa60f3640093aa2576e91d9a001e2a1c Mon Sep 17 00:00:00 2001 From: Owen Harvey Date: Wed, 13 Sep 2023 16:41:43 +1000 Subject: [PATCH 09/15] More small fixes, and using a patched version of servant-openapi3 --- libs/wire-api/src/Wire/API/Error.hs | 11 ++++++++++- libs/wire-api/src/Wire/API/Routes/MultiVerb.hs | 4 ++-- nix/haskell-pins.nix | 7 +++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/libs/wire-api/src/Wire/API/Error.hs b/libs/wire-api/src/Wire/API/Error.hs index 424f4c20cf6..8946a785721 100644 --- a/libs/wire-api/src/Wire/API/Error.hs +++ b/libs/wire-api/src/Wire/API/Error.hs @@ -49,6 +49,7 @@ where import Control.Lens (at, (%~), (.~), (?~)) import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.Aeson qualified as A +import Data.HashMap.Strict.InsOrd import Data.Kind import Data.Metrics.Servant import Data.OpenApi qualified as S @@ -215,9 +216,17 @@ errorResponseSwagger :: forall e. (Typeable e, KnownError e) => S.Response errorResponseSwagger = mempty & S.description .~ (eMessage err <> " (label: `" <> eLabel err <> "`)") - & S.content . traverse . S.schema ?~ S.Inline (S.toSchema (Proxy @(SStaticError e))) + -- Defaulting this to JSON, as openapi3 needs something to map a schema against. + -- This _should_ be overridden with the actual media types once we are at the + -- point of rendering out the schemas for MultiVerb. + -- Check the instance of `S.HasOpenApi (MultiVerb method (cs :: [Type]) as r)` + & S.content .~ singleton mediaType mediaTypeObject where err = dynError @e + mediaType = contentType $ Proxy @JSON + mediaTypeObject = + mempty + & S.schema ?~ S.Inline (S.toSchema (Proxy @(SStaticError e))) addErrorResponseToSwagger :: Int -> S.Response -> S.OpenApi -> S.OpenApi addErrorResponseToSwagger code resp = diff --git a/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs b/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs index 40df76bf7c6..338bc985fac 100644 --- a/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs +++ b/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs @@ -757,8 +757,8 @@ instance (defs, resps) = S.runDeclare (responseListSwagger @as) mempty -- We need to zip them together, and stick it all back into the contentMap -- Since we have a single schema per type, and are only changing the content-types, - -- we should be able to pick a schema out of the resps' map, and then use it in for - -- all of the values out of cs + -- we should be able to pick a schema out of the resps' map, and then use it for + -- all of the values of cs addMime :: S.Response -> S.Response addMime resp = resp diff --git a/nix/haskell-pins.nix b/nix/haskell-pins.nix index 3dd60216d1b..00614fc443a 100644 --- a/nix/haskell-pins.nix +++ b/nix/haskell-pins.nix @@ -173,6 +173,13 @@ let sha256 = "sha256-SKEE9ZqhjBxHYUKQaoB4IpN4/Ui3tS4S98FgZqj7WlY="; }; }; + servant-openapi3 = { + src = fetchgit { + url = "https://github.com/lepsa/servant-openapi3"; + rev = "5cdb2783f15058f753c41b800415d4ba1149a78b"; + sha256 = "sha256-8FM3IAA3ewCuv9Mar8aWmzbyfKK9eLXIJPMHzmYb1zE="; + }; + }; # This can be removed once postie 0.6.0.3 (or later) is in nixpkgs postie = { src = fetchgit { From 7678c62e832aa10598591b22c0e7b1f85e1077a3 Mon Sep 17 00:00:00 2001 From: Owen Harvey Date: Wed, 13 Sep 2023 18:58:57 +1000 Subject: [PATCH 10/15] Stripping default responses, 400 and 404, from OpenApi output --- libs/wire-api/src/Wire/API/SwaggerHelper.hs | 54 +++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/libs/wire-api/src/Wire/API/SwaggerHelper.hs b/libs/wire-api/src/Wire/API/SwaggerHelper.hs index 915a68bb036..3e882b8ab5c 100644 --- a/libs/wire-api/src/Wire/API/SwaggerHelper.hs +++ b/libs/wire-api/src/Wire/API/SwaggerHelper.hs @@ -19,8 +19,10 @@ module Wire.API.SwaggerHelper where import Control.Lens import Data.Containers.ListUtils (nubOrd) +import Data.HashMap.Strict.InsOrd import Data.OpenApi hiding (Contact, Header, Schema, ToSchema) import Data.OpenApi qualified as S +import Data.Text qualified as T import Imports hiding (head) cleanupSwagger :: OpenApi -> OpenApi @@ -28,6 +30,12 @@ cleanupSwagger = (S.security %~ nub) -- sanitise definitions . (S.components . S.schemas . traverse %~ sanitise) + -- strip the default errors + . ( S.allOperations + . S.responses + . S.responses + %~ foldrWithKey stripDefaultErrors mempty + ) -- sanitise general responses . (S.components . S.responses . traverse . S.content . traverse . S.schema . _Just . S._Inline %~ sanitise) -- sanitise all responses of all paths @@ -49,3 +57,49 @@ cleanupSwagger = (S.properties . traverse . S._Inline %~ sanitise) . (S.required %~ nubOrd) . (S.enum_ . _Just %~ nub) + -- servant-openapi and servant-swagger both insert default responses with codes 404 and 400. + -- They have a simple structure that we can match against, and remove from the final structure. + stripDefaultErrors :: HttpStatusCode -> Referenced Response -> Responses' -> Responses' + stripDefaultErrors code resp resps = + case code of + 400 -> case resp ^? _Inline . S.description of + (Just desc) -> + if "Invalid " + `T.isPrefixOf` desc + && resp + ^? _Inline + . links + == pure mempty + && resp + ^? _Inline + . content + == pure mempty + && resp + ^? _Inline + . headers + == pure mempty + then resps + else insert code resp resps + Nothing -> insert code resp resps + 404 -> case resp ^? _Inline . S.description of + (Just desc) -> + if " not found" + `T.isSuffixOf` desc + && resp + ^? _Inline + . links + == pure mempty + && resp + ^? _Inline + . content + == pure mempty + && resp + ^? _Inline + . headers + == pure mempty + then resps + else insert code resp resps + Nothing -> insert code resp resps + _ -> insert code resp resps + +type Responses' = InsOrdHashMap HttpStatusCode (Referenced Response) From 732e5874a16762d3dda0ba479f4c5c7b35537cba Mon Sep 17 00:00:00 2001 From: Owen Harvey Date: Thu, 14 Sep 2023 17:51:29 +1000 Subject: [PATCH 11/15] WPB-4240: Fixing remaining issues with the schemas of error types --- libs/wire-api/src/Wire/API/Error/Galley.hs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/libs/wire-api/src/Wire/API/Error/Galley.hs b/libs/wire-api/src/Wire/API/Error/Galley.hs index 9e5962550c1..3e7896b4544 100644 --- a/libs/wire-api/src/Wire/API/Error/Galley.hs +++ b/libs/wire-api/src/Wire/API/Error/Galley.hs @@ -37,6 +37,7 @@ import Control.Lens ((%~), (.~), (?~)) import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.Containers.ListUtils import Data.Domain +import Data.HashMap.Strict.InsOrd (singleton) import Data.OpenApi qualified as S import Data.Proxy import Data.Qualified @@ -51,6 +52,7 @@ import Network.Wai.Utilities.JSONResponse import Polysemy import Polysemy.Error import Prelude.Singletons (Show_) +import Servant.API.ContentTypes (JSON, contentType) import Wire.API.Conversation.Role import Wire.API.Error import Wire.API.Error.Brig qualified as BrigError @@ -453,7 +455,12 @@ instance IsSwaggerError NonFederatingBackends where addErrorResponseToSwagger (HTTP.statusCode nonFederatingBackendsStatus) $ mempty & S.description .~ "Adding members to the conversation is not possible because the backends involved do not form a fully connected graph" - & S.content . traverse . S.schema ?~ S.Inline (S.toSchema (Proxy @NonFederatingBackends)) + & S.content .~ singleton mediaType mediaTypeObject + where + mediaType = contentType $ Proxy @JSON + mediaTypeObject = + mempty + & S.schema ?~ S.Inline (S.toSchema (Proxy @NonFederatingBackends)) type instance ErrorEffect NonFederatingBackends = Error NonFederatingBackends @@ -490,7 +497,14 @@ instance IsSwaggerError UnreachableBackends where addErrorResponseToSwagger (HTTP.statusCode unreachableBackendsStatus) $ mempty & S.description .~ "Some domains are unreachable" - & S.content . traverse . S.schema ?~ S.Inline (S.toSchema (Proxy @UnreachableBackends)) + -- Defaulting this to JSON, as openapi3 needs something to map a schema against. + -- This _should_ be overridden with the actual media types once we are at the + -- point of rendering out the schemas for MultiVerb. + -- Check the instance of `S.HasOpenApi (MultiVerb method (cs :: [Type]) as r)` + & S.content .~ singleton mediaType mediaTypeObject + where + mediaType = contentType $ Proxy @JSON + mediaTypeObject = mempty & S.schema ?~ S.Inline (S.toSchema (Proxy @UnreachableBackends)) type instance ErrorEffect UnreachableBackends = Error UnreachableBackends From 1c1ac850756e6c448286e70b77d643461cee8bd2 Mon Sep 17 00:00:00 2001 From: Owen Harvey Date: Thu, 14 Sep 2023 18:44:29 +1000 Subject: [PATCH 12/15] WPB-4240: Adding comments to nix --- libs/wire-api/src/Wire/API/Routes/MultiVerb.hs | 2 -- nix/haskell-pins.nix | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs b/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs index 338bc985fac..ed24bbfdbe5 100644 --- a/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs +++ b/libs/wire-api/src/Wire/API/Routes/MultiVerb.hs @@ -769,8 +769,6 @@ instance foldMap (\c -> InsOrdHashMap.fromList $ (,c) <$> cs) . listToMaybe . toList - -- contentMap :: InsOrdHashMap M.MediaType MediaTypeObject - -- contentMap = InsOrdHashMap.fromList $ (, MediaTypeObject (pure $ S.Inline $ _) Nothing mempty mempty) <$> cs refResps = S.Inline . addMime <$> resps class Typeable a => IsWaiBody a where diff --git a/nix/haskell-pins.nix b/nix/haskell-pins.nix index 00614fc443a..cd56258ac99 100644 --- a/nix/haskell-pins.nix +++ b/nix/haskell-pins.nix @@ -175,6 +175,8 @@ let }; servant-openapi3 = { src = fetchgit { + # This is a patched version of the library that sets the required flag for HTTP request bodies. + # A PR for these changes has been made for the upstream library. biocad/servant-openapi3#49 url = "https://github.com/lepsa/servant-openapi3"; rev = "5cdb2783f15058f753c41b800415d4ba1149a78b"; sha256 = "sha256-8FM3IAA3ewCuv9Mar8aWmzbyfKK9eLXIJPMHzmYb1zE="; From e376fd2c58399577f4d50060bc603aeb9d23e699 Mon Sep 17 00:00:00 2001 From: Owen Harvey Date: Tue, 19 Sep 2023 16:52:06 +1000 Subject: [PATCH 13/15] WPB-4240: Adding deprecated flags to API routes and types. Updating schema definitions with deprecation flags where needed. Adding a new Servant combinator to set deprecated flags for routes. --- libs/schema-profunctor/src/Data/Schema.hs | 6 ++ libs/types-common/src/Data/Qualified.hs | 10 +++- libs/wire-api/src/Wire/API/Conversation.hs | 22 ++++--- .../src/Wire/API/Conversation/Member.hs | 3 +- libs/wire-api/src/Wire/API/Deprecated.hs | 60 +++++++++++++++++++ .../src/Wire/API/Event/Conversation.hs | 5 +- .../src/Wire/API/MakesFederatedCall.hs | 13 +--- .../src/Wire/API/Routes/Public/Brig.hs | 8 ++- .../API/Routes/Public/Galley/Conversation.hs | 8 +++ .../src/Wire/API/Routes/Public/Spar.hs | 4 +- libs/wire-api/src/Wire/API/Routes/Version.hs | 5 ++ libs/wire-api/src/Wire/API/Team.hs | 13 ++-- libs/wire-api/wire-api.cabal | 1 + 13 files changed, 127 insertions(+), 31 deletions(-) create mode 100644 libs/wire-api/src/Wire/API/Deprecated.hs diff --git a/libs/schema-profunctor/src/Data/Schema.hs b/libs/schema-profunctor/src/Data/Schema.hs index 03e26432c7a..b9f8ef3f96a 100644 --- a/libs/schema-profunctor/src/Data/Schema.hs +++ b/libs/schema-profunctor/src/Data/Schema.hs @@ -939,8 +939,14 @@ instance S.HasSchema d S.Schema => S.HasSchema (SchemaP d v w a b) S.Schema wher instance S.HasDescription NamedSwaggerDoc (Maybe Text) where description = declared . S.schema . S.description +instance S.HasDeprecated NamedSwaggerDoc (Maybe Bool) where + deprecated = declared . S.schema . S.deprecated + instance {-# OVERLAPPABLE #-} S.HasDescription s a => S.HasDescription (WithDeclare s) a where description = declared . S.description +instance {-# OVERLAPPABLE #-} S.HasDeprecated s a => S.HasDeprecated (WithDeclare s) a where + deprecated = declared . S.deprecated + instance {-# OVERLAPPABLE #-} S.HasExample s a => S.HasExample (WithDeclare s) a where example = declared . S.example diff --git a/libs/types-common/src/Data/Qualified.hs b/libs/types-common/src/Data/Qualified.hs index 71870361047..1c1ba088e10 100644 --- a/libs/types-common/src/Data/Qualified.hs +++ b/libs/types-common/src/Data/Qualified.hs @@ -48,13 +48,14 @@ module Data.Qualified ) where -import Control.Lens (Lens, lens, (?~)) +import Control.Lens (Lens, lens, over, (?~)) import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.Bifunctor (first) import Data.Domain (Domain) import Data.Handle (Handle (..)) import Data.Id import Data.Map qualified as Map +import Data.OpenApi (deprecated) import Data.OpenApi qualified as S import Data.Schema import Imports hiding (local) @@ -163,8 +164,11 @@ isLocal loc = foldQualified loc (const True) (const False) ---------------------------------------------------------------------- -deprecatedSchema :: S.HasDescription doc (Maybe Text) => Text -> ValueSchema doc a -> ValueSchema doc a -deprecatedSchema new = doc . description ?~ ("Deprecated, use " <> new) +deprecatedSchema :: (S.HasDeprecated doc (Maybe Bool), S.HasDescription doc (Maybe Text)) => Text -> ValueSchema doc a -> ValueSchema doc a +deprecatedSchema new = + over doc $ + (description ?~ ("Deprecated, use " <> new)) + . (deprecated ?~ True) qualifiedSchema :: HasSchemaRef doc => diff --git a/libs/wire-api/src/Wire/API/Conversation.hs b/libs/wire-api/src/Wire/API/Conversation.hs index 2fb84a10e21..bfe91520ec7 100644 --- a/libs/wire-api/src/Wire/API/Conversation.hs +++ b/libs/wire-api/src/Wire/API/Conversation.hs @@ -96,6 +96,7 @@ import Data.List.NonEmpty (NonEmpty) import Data.List1 import Data.Map qualified as Map import Data.Misc +import Data.OpenApi (deprecated) import Data.OpenApi qualified as S import Data.Qualified import Data.Range (Range, fromRange, rangedSchema) @@ -567,14 +568,15 @@ instance ToSchema AccessRole where instance ToSchema AccessRoleLegacy where schema = - (S.schema . description ?~ desc) $ - enum @Text "AccessRoleLegacy" $ - mconcat - [ element "private" PrivateAccessRole, - element "team" TeamAccessRole, - element "activated" ActivatedAccessRole, - element "non_activated" NonActivatedAccessRole - ] + (S.schema . S.deprecated ?~ True) $ + (S.schema . description ?~ desc) $ + enum @Text "AccessRoleLegacy" $ + mconcat + [ element "private" PrivateAccessRole, + element "team" TeamAccessRole, + element "activated" ActivatedAccessRole, + element "non_activated" NonActivatedAccessRole + ] where desc = "Which users can join conversations (deprecated, use `access_role_v2` instead).\ @@ -670,7 +672,9 @@ newConvSchema sch = <$> newConvUsers .= ( fieldWithDocModifier "users" - (description ?~ usersDesc) + ( (deprecated ?~ True) + . (description ?~ usersDesc) + ) (array schema) <|> pure [] ) diff --git a/libs/wire-api/src/Wire/API/Conversation/Member.hs b/libs/wire-api/src/Wire/API/Conversation/Member.hs index 704edcaf810..bb913a7ef38 100644 --- a/libs/wire-api/src/Wire/API/Conversation/Member.hs +++ b/libs/wire-api/src/Wire/API/Conversation/Member.hs @@ -38,6 +38,7 @@ import Control.Lens ((?~)) import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.Aeson qualified as A import Data.Id +import Data.OpenApi (deprecated) import Data.OpenApi qualified as S import Data.Qualified import Data.Schema @@ -141,7 +142,7 @@ instance ToSchema OtherMember where <* (qUnqualified . omQualifiedId) .= optional (field "id" schema) <*> omService .= maybe_ (optFieldWithDocModifier "service" (description ?~ desc) schema) <*> omConvRoleName .= (field "conversation_role" schema <|> pure roleNameWireAdmin) - <* const (0 :: Int) .= optional (fieldWithDocModifier "status" (description ?~ "deprecated") schema) -- TODO: remove + <* const (0 :: Int) .= optional (fieldWithDocModifier "status" ((deprecated ?~ True) . (description ?~ "deprecated")) schema) -- TODO: remove where desc = "The reference to the owning service, if the member is a 'bot'." diff --git a/libs/wire-api/src/Wire/API/Deprecated.hs b/libs/wire-api/src/Wire/API/Deprecated.hs new file mode 100644 index 00000000000..c68120be996 --- /dev/null +++ b/libs/wire-api/src/Wire/API/Deprecated.hs @@ -0,0 +1,60 @@ +-- This file is part of the Wire Server implementation. +-- +-- Copyright (C) 2022 Wire Swiss GmbH +-- +-- This program is free software: you can redistribute it and/or modify it under +-- the terms of the GNU Affero General Public License as published by the Free +-- Software Foundation, either version 3 of the License, or (at your option) any +-- later version. +-- +-- This program is distributed in the hope that it will be useful, but WITHOUT +-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +-- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Affero General Public License along +-- with this program. If not, see . + +module Wire.API.Deprecated + ( Deprecated, + ) +where + +import Control.Lens +import Data.Kind (Type) +import Data.Metrics.Servant +import Data.OpenApi hiding (HasServer) +import Imports +import Servant +import Servant.Client +import Servant.OpenApi + +-- Annotate that the route is deprecated +data Deprecated deriving (Typeable) + +-- All of these instances are very similar to the instances +-- for Summary. These don't impact the API directly, but are +-- for marking the deprecated flag in the openapi output. +instance HasLink sub => HasLink (Deprecated :> sub :: Type) where + type MkLink (Deprecated :> sub) a = MkLink sub a + toLink = + let simpleToLink toA _ = toLink toA (Proxy :: Proxy sub) + in simpleToLink + +instance HasOpenApi api => HasOpenApi (Deprecated :> api :: Type) where + toOpenApi _ = + toOpenApi (Proxy @api) + & allOperations . deprecated ?~ True + +instance HasServer api ctx => HasServer (Deprecated :> api) ctx where + type ServerT (Deprecated :> api) m = ServerT api m + route _ = route $ Proxy @api + hoistServerWithContext _ pc nt s = hoistServerWithContext (Proxy @api) pc nt s + +instance HasClient m api => HasClient m (Deprecated :> api) where + type Client m (Deprecated :> api) = Client m api + clientWithRoute pm _ = clientWithRoute pm (Proxy :: Proxy api) + hoistClientMonad pm _ f cl = hoistClientMonad pm (Proxy :: Proxy api) f cl + +instance (RoutesToPaths rest) => RoutesToPaths (Deprecated :> rest) where + getRoutes = getRoutes @rest diff --git a/libs/wire-api/src/Wire/API/Event/Conversation.hs b/libs/wire-api/src/Wire/API/Event/Conversation.hs index b83a3221123..265bf5a5d8b 100644 --- a/libs/wire-api/src/Wire/API/Event/Conversation.hs +++ b/libs/wire-api/src/Wire/API/Event/Conversation.hs @@ -71,6 +71,7 @@ import Data.Aeson qualified as A import Data.Aeson.KeyMap qualified as KeyMap import Data.Id import Data.Json.Util +import Data.OpenApi (deprecated) import Data.OpenApi qualified as S import Data.Qualified import Data.SOP @@ -234,7 +235,9 @@ instance ToSchema SimpleMembers where .= optional ( fieldWithDocModifier "user_ids" - (description ?~ "deprecated") + ( (description ?~ "deprecated") + . (deprecated ?~ True) + ) (array schema) ) diff --git a/libs/wire-api/src/Wire/API/MakesFederatedCall.hs b/libs/wire-api/src/Wire/API/MakesFederatedCall.hs index cbbfb3f6925..ba24fd4ee16 100644 --- a/libs/wire-api/src/Wire/API/MakesFederatedCall.hs +++ b/libs/wire-api/src/Wire/API/MakesFederatedCall.hs @@ -31,7 +31,7 @@ module Wire.API.MakesFederatedCall ) where -import Control.Lens ((%~), (<>~), _Just) +import Control.Lens ((<>~)) import Data.Aeson import Data.Constraint import Data.HashSet.InsOrd (singleton) @@ -182,16 +182,7 @@ instance (HasOpenApi api, KnownSymbol name, KnownSymbol (ShowComponent comp)) => -- Set the tags on the specific path we're looking at -- This is where the tag is actually registered on the path -- so it can be picked up by fedcalls. - & S.paths . traverse %~ \pathItem -> - pathItem - & S.get . _Just . S.tags <>~ setName - & S.put . _Just . S.tags <>~ setName - & S.post . _Just . S.tags <>~ setName - & S.delete . _Just . S.tags <>~ setName - & S.options . _Just . S.tags <>~ setName - & S.head_ . _Just . S.tags <>~ setName - & S.patch . _Just . S.tags <>~ setName - & S.trace . _Just . S.tags <>~ setName + & S.allOperations . S.tags <>~ setName where name = "wire-makes-federated-call-to-" <> T.pack (symbolVal $ Proxy @name) setName = singleton name diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs b/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs index 0ea213669f6..46ea48a9cbd 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs @@ -19,6 +19,7 @@ module Wire.API.Routes.Public.Brig where +import Control.Lens ((?~)) import Data.Aeson qualified as A (FromJSON, ToJSON, Value) import Data.ByteString.Conversion import Data.Code (Timeout) @@ -42,6 +43,7 @@ import Servant hiding (Handler, JSON, addHeader, respond) import Servant.OpenApi.Internal.Orphans () import Wire.API.Call.Config (RTCConfiguration) import Wire.API.Connection hiding (MissingLegalholdConsent) +import Wire.API.Deprecated import Wire.API.Error import Wire.API.Error.Brig import Wire.API.Error.Empty @@ -564,6 +566,7 @@ type AccountAPI = :<|> Named "post-password-reset-key-deprecated" ( Summary "Complete a password reset." + :> Deprecated :> CanThrow 'PasswordResetInProgress :> CanThrow 'InvalidPasswordResetKey :> CanThrow 'InvalidPasswordResetCode @@ -577,6 +580,7 @@ type AccountAPI = :<|> Named "onboarding" ( Summary "Upload contacts and invoke matching." + :> Deprecated :> Description "DEPRECATED: the feature has been turned off, the end-point does \ \nothing and always returns '{\"results\":[],\"auto-connects\":[]}'." @@ -598,8 +602,9 @@ data DeprecatedMatchingResult = DeprecatedMatchingResult instance ToSchema DeprecatedMatchingResult where schema = - object + objectWithDocModifier "DeprecatedMatchingResult" + (S.deprecated ?~ True) $ DeprecatedMatchingResult <$ const [] .= field "results" (array (null_ @SwaggerDoc)) @@ -1346,6 +1351,7 @@ type CallingAPI = ( Summary "[deprecated] Retrieve TURN server addresses and credentials for \ \ IP addresses, scheme `turn` and transport `udp` only" + :> Deprecated :> ZUser :> ZConn :> "calls" diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Galley/Conversation.hs b/libs/wire-api/src/Wire/API/Routes/Public/Galley/Conversation.hs index 9d0f2b993b8..79a5db7c59f 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Galley/Conversation.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Galley/Conversation.hs @@ -29,6 +29,7 @@ import Wire.API.Conversation import Wire.API.Conversation.Code import Wire.API.Conversation.Role import Wire.API.Conversation.Typing +import Wire.API.Deprecated import Wire.API.Error import Wire.API.Error.Galley import Wire.API.Event.Conversation @@ -785,6 +786,7 @@ type ConversationAPI = :<|> Named "update-other-member-unqualified" ( Summary "Update membership of the specified user (deprecated)" + :> Deprecated :> Description "Use `PUT /conversations/:cnv_domain/:cnv/members/:usr_domain/:usr` instead" :> MakesFederatedCall 'Galley "on-conversation-updated" :> MakesFederatedCall 'Galley "on-mls-message-sent" @@ -835,6 +837,7 @@ type ConversationAPI = :<|> Named "update-conversation-name-deprecated" ( Summary "Update conversation name (deprecated)" + :> Deprecated :> Description "Use `/conversations/:domain/:conv/name` instead." :> MakesFederatedCall 'Galley "on-conversation-updated" :> MakesFederatedCall 'Galley "on-mls-message-sent" @@ -855,6 +858,7 @@ type ConversationAPI = :<|> Named "update-conversation-name-unqualified" ( Summary "Update conversation name (deprecated)" + :> Deprecated :> Description "Use `/conversations/:domain/:conv/name` instead." :> MakesFederatedCall 'Galley "on-conversation-updated" :> MakesFederatedCall 'Galley "on-mls-message-sent" @@ -898,6 +902,7 @@ type ConversationAPI = :<|> Named "update-conversation-message-timer-unqualified" ( Summary "Update the message timer for a conversation (deprecated)" + :> Deprecated :> Description "Use `/conversations/:domain/:cnv/message-timer` instead." :> MakesFederatedCall 'Galley "on-conversation-updated" :> MakesFederatedCall 'Galley "on-mls-message-sent" @@ -943,6 +948,7 @@ type ConversationAPI = :<|> Named "update-conversation-receipt-mode-unqualified" ( Summary "Update receipt mode for a conversation (deprecated)" + :> Deprecated :> Description "Use `PUT /conversations/:domain/:cnv/receipt-mode` instead." :> MakesFederatedCall 'Galley "on-conversation-updated" :> MakesFederatedCall 'Galley "on-mls-message-sent" @@ -1064,6 +1070,7 @@ type ConversationAPI = :<|> Named "get-conversation-self-unqualified" ( Summary "Get self membership properties (deprecated)" + :> Deprecated :> ZLocalUser :> "conversations" :> Capture' '[Description "Conversation ID"] "cnv" ConvId @@ -1073,6 +1080,7 @@ type ConversationAPI = :<|> Named "update-conversation-self-unqualified" ( Summary "Update self membership properties (deprecated)" + :> Deprecated :> Description "Use `/conversations/:domain/:conv/self` instead." :> CanThrow 'ConvNotFound :> ZLocalUser diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs b/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs index 930f450fb8a..107ed1de9a5 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs @@ -30,6 +30,7 @@ import URI.ByteString qualified as URI import Web.Scim.Capabilities.MetaSchema as Scim.Meta import Web.Scim.Class.Auth as Scim.Auth import Web.Scim.Class.User as Scim.User +import Wire.API.Deprecated (Deprecated) import Wire.API.Error import Wire.API.Error.Brig import Wire.API.Routes.API @@ -57,7 +58,7 @@ type DeprecateSSOAPIV1 = \Details: https://docs.wire.com/understand/single-sign-on/trouble-shooting.html#can-i-use-the-same-sso-login-code-for-multiple-teams" type APISSO = - DeprecateSSOAPIV1 :> "metadata" :> SAML.APIMeta + DeprecateSSOAPIV1 :> Deprecated :> "metadata" :> SAML.APIMeta :<|> "metadata" :> Capture "team" TeamId :> SAML.APIMeta :<|> "initiate-login" :> APIAuthReqPrecheck :<|> "initiate-login" :> APIAuthReq @@ -82,6 +83,7 @@ type APIAuthReq = type APIAuthRespLegacy = DeprecateSSOAPIV1 + :> Deprecated :> "finalize-login" -- (SAML.APIAuthResp from here on, except for response) :> MultipartForm Mem SAML.AuthnResponseBody diff --git a/libs/wire-api/src/Wire/API/Routes/Version.hs b/libs/wire-api/src/Wire/API/Routes/Version.hs index d90540d61c9..a2a337b61df 100644 --- a/libs/wire-api/src/Wire/API/Routes/Version.hs +++ b/libs/wire-api/src/Wire/API/Routes/Version.hs @@ -61,6 +61,7 @@ import GHC.TypeLits import Imports import Servant import Servant.API.Extended.RawM +import Wire.API.Deprecated import Wire.API.Routes.MultiVerb import Wire.API.Routes.Named import Wire.API.VersionInfo @@ -230,6 +231,10 @@ type instance SpecialiseToVersion v (Summary s :> api) = Summary s :> SpecialiseToVersion v api +type instance + SpecialiseToVersion v (Deprecated :> api) = + Deprecated :> SpecialiseToVersion v api + type instance SpecialiseToVersion v (Verb m s t r) = Verb m s t r diff --git a/libs/wire-api/src/Wire/API/Team.hs b/libs/wire-api/src/Wire/API/Team.hs index 87fad624fe5..13c09ab567b 100644 --- a/libs/wire-api/src/Wire/API/Team.hs +++ b/libs/wire-api/src/Wire/API/Team.hs @@ -67,7 +67,7 @@ module Wire.API.Team ) where -import Control.Lens (makeLenses, (?~)) +import Control.Lens (makeLenses, over, (?~)) import Data.Aeson (FromJSON, ToJSON, Value (..)) import Data.Aeson.Types (Parser) import Data.Attoparsec.ByteString qualified as Atto (Parser, string) @@ -76,6 +76,7 @@ import Data.ByteString.Conversion import Data.Code qualified as Code import Data.Id (TeamId, UserId) import Data.Misc (PlainTextPassword6) +import Data.OpenApi (HasDeprecated (deprecated)) import Data.OpenApi qualified as S import Data.Range import Data.Schema @@ -118,7 +119,10 @@ instance ToSchema Team where <*> _teamSplashScreen .= (fromMaybe DefaultIcon <$> optField "splash_screen" schema) where desc = description ?~ "`binding` is deprecated, and should be ignored. The non-binding teams API is not used (and will not be supported from API version V4 onwards), and `binding` will always be `true`." - bindingDesc = description ?~ "Deprecated, please ignore." + bindingDesc v = + v + & description ?~ "Deprecated, please ignore." + & deprecated ?~ True -- | How a team "binds" its members (users) -- @@ -145,8 +149,9 @@ data TeamBinding instance ToSchema TeamBinding where schema = - enum @Bool "TeamBinding" $ - mconcat [element True Binding, element False NonBinding] + over doc (deprecated ?~ True) $ + enum @Bool "TeamBinding" $ + mconcat [element True Binding, element False NonBinding] -------------------------------------------------------------------------------- -- TeamList diff --git a/libs/wire-api/wire-api.cabal b/libs/wire-api/wire-api.cabal index 6b55e049407..b7d3af68205 100644 --- a/libs/wire-api/wire-api.cabal +++ b/libs/wire-api/wire-api.cabal @@ -28,6 +28,7 @@ library Wire.API.Conversation.Role Wire.API.Conversation.Typing Wire.API.CustomBackend + Wire.API.Deprecated Wire.API.Error Wire.API.Error.Brig Wire.API.Error.Cannon From faec8102bbe098e079b87006bedd5f96f22a0600 Mon Sep 17 00:00:00 2001 From: Igor Ranieri Date: Tue, 19 Sep 2023 14:58:35 +0200 Subject: [PATCH 14/15] Removed redundant import --- services/brig/src/Brig/API/Internal.hs | 1 - 1 file changed, 1 deletion(-) diff --git a/services/brig/src/Brig/API/Internal.hs b/services/brig/src/Brig/API/Internal.hs index e9724f6e7fd..75f90bd606c 100644 --- a/services/brig/src/Brig/API/Internal.hs +++ b/services/brig/src/Brig/API/Internal.hs @@ -77,7 +77,6 @@ import Network.Wai.Utilities as Utilities import Polysemy import Servant hiding (Handler, JSON, addHeader, respond) import Servant.OpenApi.Internal.Orphans () -import System.Logger qualified as Lg import System.Logger.Class qualified as Log import System.Random (randomRIO) import UnliftIO.Async From 74fe785554afb79fafae4cf8d5070ce624dac88d Mon Sep 17 00:00:00 2001 From: Igor Ranieri Date: Wed, 20 Sep 2023 11:27:48 +0200 Subject: [PATCH 15/15] Updated API description for consistency --- libs/wire-api/src/Wire/API/Routes/Public/Brig.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs b/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs index 46ea48a9cbd..b8b22b88a33 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs @@ -1349,8 +1349,8 @@ type CallingAPI = Named "get-calls-config" ( Summary - "[deprecated] Retrieve TURN server addresses and credentials for \ - \ IP addresses, scheme `turn` and transport `udp` only" + "Retrieve TURN server addresses and credentials for \ + \ IP addresses, scheme `turn` and transport `udp` only (deprecated)" :> Deprecated :> ZUser :> ZConn