-- This file is part of the Wire Server implementation.
--
-- Copyright (C) 2022 Wire Swiss GmbH <opensource@wire.com>
--
-- 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 <https://www.gnu.org/licenses/>.

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
cleanupSwagger :: OpenApi -> OpenApi
cleanupSwagger =
  (([SecurityRequirement] -> Identity [SecurityRequirement])
-> OpenApi -> Identity OpenApi
forall s a. HasSecurity s a => Lens' s a
Lens' OpenApi [SecurityRequirement]
S.security (([SecurityRequirement] -> Identity [SecurityRequirement])
 -> OpenApi -> Identity OpenApi)
-> ([SecurityRequirement] -> [SecurityRequirement])
-> OpenApi
-> OpenApi
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ [SecurityRequirement] -> [SecurityRequirement]
forall a. Eq a => [a] -> [a]
nub)
    -- sanitise definitions
    (OpenApi -> OpenApi) -> (OpenApi -> OpenApi) -> OpenApi -> OpenApi
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Components -> Identity Components) -> OpenApi -> Identity OpenApi
forall s a. HasComponents s a => Lens' s a
Lens' OpenApi Components
S.components ((Components -> Identity Components)
 -> OpenApi -> Identity OpenApi)
-> ((Schema -> Identity Schema)
    -> Components -> Identity Components)
-> (Schema -> Identity Schema)
-> OpenApi
-> Identity OpenApi
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InsOrdHashMap Text Schema -> Identity (InsOrdHashMap Text Schema))
-> Components -> Identity Components
forall s a. HasSchemas s a => Lens' s a
Lens' Components (InsOrdHashMap Text Schema)
S.schemas ((InsOrdHashMap Text Schema
  -> Identity (InsOrdHashMap Text Schema))
 -> Components -> Identity Components)
-> ((Schema -> Identity Schema)
    -> InsOrdHashMap Text Schema
    -> Identity (InsOrdHashMap Text Schema))
-> (Schema -> Identity Schema)
-> Components
-> Identity Components
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Schema -> Identity Schema)
-> InsOrdHashMap Text Schema
-> Identity (InsOrdHashMap Text Schema)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> InsOrdHashMap Text a -> f (InsOrdHashMap Text b)
traverse ((Schema -> Identity Schema) -> OpenApi -> Identity OpenApi)
-> (Schema -> Schema) -> OpenApi -> OpenApi
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Schema -> Schema
sanitise)
    -- strip the default errors
    (OpenApi -> OpenApi) -> (OpenApi -> OpenApi) -> OpenApi -> OpenApi
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ( (Operation -> Identity Operation) -> OpenApi -> Identity OpenApi
Traversal' OpenApi Operation
S.allOperations
          ((Operation -> Identity Operation) -> OpenApi -> Identity OpenApi)
-> ((InsOrdHashMap HttpStatusCode (Referenced Response)
     -> Identity (InsOrdHashMap HttpStatusCode (Referenced Response)))
    -> Operation -> Identity Operation)
-> (InsOrdHashMap HttpStatusCode (Referenced Response)
    -> Identity (InsOrdHashMap HttpStatusCode (Referenced Response)))
-> OpenApi
-> Identity OpenApi
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Responses -> Identity Responses)
-> Operation -> Identity Operation
forall s a. HasResponses s a => Lens' s a
Lens' Operation Responses
S.responses
          ((Responses -> Identity Responses)
 -> Operation -> Identity Operation)
-> ((InsOrdHashMap HttpStatusCode (Referenced Response)
     -> Identity (InsOrdHashMap HttpStatusCode (Referenced Response)))
    -> Responses -> Identity Responses)
-> (InsOrdHashMap HttpStatusCode (Referenced Response)
    -> Identity (InsOrdHashMap HttpStatusCode (Referenced Response)))
-> Operation
-> Identity Operation
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InsOrdHashMap HttpStatusCode (Referenced Response)
 -> Identity (InsOrdHashMap HttpStatusCode (Referenced Response)))
-> Responses -> Identity Responses
forall s a. HasResponses s a => Lens' s a
Lens'
  Responses (InsOrdHashMap HttpStatusCode (Referenced Response))
S.responses
          ((InsOrdHashMap HttpStatusCode (Referenced Response)
  -> Identity (InsOrdHashMap HttpStatusCode (Referenced Response)))
 -> OpenApi -> Identity OpenApi)
-> (InsOrdHashMap HttpStatusCode (Referenced Response)
    -> InsOrdHashMap HttpStatusCode (Referenced Response))
-> OpenApi
-> OpenApi
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (HttpStatusCode
 -> Referenced Response
 -> InsOrdHashMap HttpStatusCode (Referenced Response)
 -> InsOrdHashMap HttpStatusCode (Referenced Response))
-> InsOrdHashMap HttpStatusCode (Referenced Response)
-> InsOrdHashMap HttpStatusCode (Referenced Response)
-> InsOrdHashMap HttpStatusCode (Referenced Response)
forall k v a. (k -> v -> a -> a) -> a -> InsOrdHashMap k v -> a
foldrWithKey HttpStatusCode
-> Referenced Response
-> InsOrdHashMap HttpStatusCode (Referenced Response)
-> InsOrdHashMap HttpStatusCode (Referenced Response)
stripDefaultErrors InsOrdHashMap HttpStatusCode (Referenced Response)
forall a. Monoid a => a
mempty
      )
    -- sanitise general responses
    (OpenApi -> OpenApi) -> (OpenApi -> OpenApi) -> OpenApi -> OpenApi
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Components -> Identity Components) -> OpenApi -> Identity OpenApi
forall s a. HasComponents s a => Lens' s a
Lens' OpenApi Components
S.components ((Components -> Identity Components)
 -> OpenApi -> Identity OpenApi)
-> ((Schema -> Identity Schema)
    -> Components -> Identity Components)
-> (Schema -> Identity Schema)
-> OpenApi
-> Identity OpenApi
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InsOrdHashMap Text Response
 -> Identity (InsOrdHashMap Text Response))
-> Components -> Identity Components
forall s a. HasResponses s a => Lens' s a
Lens' Components (InsOrdHashMap Text Response)
S.responses ((InsOrdHashMap Text Response
  -> Identity (InsOrdHashMap Text Response))
 -> Components -> Identity Components)
-> ((Schema -> Identity Schema)
    -> InsOrdHashMap Text Response
    -> Identity (InsOrdHashMap Text Response))
-> (Schema -> Identity Schema)
-> Components
-> Identity Components
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Response -> Identity Response)
-> InsOrdHashMap Text Response
-> Identity (InsOrdHashMap Text Response)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> InsOrdHashMap Text a -> f (InsOrdHashMap Text b)
traverse ((Response -> Identity Response)
 -> InsOrdHashMap Text Response
 -> Identity (InsOrdHashMap Text Response))
-> ((Schema -> Identity Schema) -> Response -> Identity Response)
-> (Schema -> Identity Schema)
-> InsOrdHashMap Text Response
-> Identity (InsOrdHashMap Text Response)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InsOrdHashMap MediaType MediaTypeObject
 -> Identity (InsOrdHashMap MediaType MediaTypeObject))
-> Response -> Identity Response
forall s a. HasContent s a => Lens' s a
Lens' Response (InsOrdHashMap MediaType MediaTypeObject)
S.content ((InsOrdHashMap MediaType MediaTypeObject
  -> Identity (InsOrdHashMap MediaType MediaTypeObject))
 -> Response -> Identity Response)
-> ((Schema -> Identity Schema)
    -> InsOrdHashMap MediaType MediaTypeObject
    -> Identity (InsOrdHashMap MediaType MediaTypeObject))
-> (Schema -> Identity Schema)
-> Response
-> Identity Response
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MediaTypeObject -> Identity MediaTypeObject)
-> InsOrdHashMap MediaType MediaTypeObject
-> Identity (InsOrdHashMap MediaType MediaTypeObject)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b)
-> InsOrdHashMap MediaType a -> f (InsOrdHashMap MediaType b)
traverse ((MediaTypeObject -> Identity MediaTypeObject)
 -> InsOrdHashMap MediaType MediaTypeObject
 -> Identity (InsOrdHashMap MediaType MediaTypeObject))
-> ((Schema -> Identity Schema)
    -> MediaTypeObject -> Identity MediaTypeObject)
-> (Schema -> Identity Schema)
-> InsOrdHashMap MediaType MediaTypeObject
-> Identity (InsOrdHashMap MediaType MediaTypeObject)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe (Referenced Schema) -> Identity (Maybe (Referenced Schema)))
-> MediaTypeObject -> Identity MediaTypeObject
forall s a. HasSchema s a => Lens' s a
Lens' MediaTypeObject (Maybe (Referenced Schema))
S.schema ((Maybe (Referenced Schema)
  -> Identity (Maybe (Referenced Schema)))
 -> MediaTypeObject -> Identity MediaTypeObject)
-> ((Schema -> Identity Schema)
    -> Maybe (Referenced Schema)
    -> Identity (Maybe (Referenced Schema)))
-> (Schema -> Identity Schema)
-> MediaTypeObject
-> Identity MediaTypeObject
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Referenced Schema -> Identity (Referenced Schema))
-> Maybe (Referenced Schema)
-> Identity (Maybe (Referenced Schema))
forall a b (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a (f b) -> p (Maybe a) (f (Maybe b))
_Just ((Referenced Schema -> Identity (Referenced Schema))
 -> Maybe (Referenced Schema)
 -> Identity (Maybe (Referenced Schema)))
-> ((Schema -> Identity Schema)
    -> Referenced Schema -> Identity (Referenced Schema))
-> (Schema -> Identity Schema)
-> Maybe (Referenced Schema)
-> Identity (Maybe (Referenced Schema))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Schema -> Identity Schema)
-> Referenced Schema -> Identity (Referenced Schema)
forall a1 a2 (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a1 (f a2) -> p (Referenced a1) (f (Referenced a2))
S._Inline ((Schema -> Identity Schema) -> OpenApi -> Identity OpenApi)
-> (Schema -> Schema) -> OpenApi -> OpenApi
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Schema -> Schema
sanitise)
    -- sanitise all responses of all paths
    (OpenApi -> OpenApi) -> (OpenApi -> OpenApi) -> OpenApi -> OpenApi
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ( (Operation -> Identity Operation) -> OpenApi -> Identity OpenApi
Traversal' OpenApi Operation
S.allOperations
          ((Operation -> Identity Operation) -> OpenApi -> Identity OpenApi)
-> ((Schema -> Identity Schema) -> Operation -> Identity Operation)
-> (Schema -> Identity Schema)
-> OpenApi
-> Identity OpenApi
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Responses -> Identity Responses)
-> Operation -> Identity Operation
forall s a. HasResponses s a => Lens' s a
Lens' Operation Responses
S.responses
          ((Responses -> Identity Responses)
 -> Operation -> Identity Operation)
-> ((Schema -> Identity Schema) -> Responses -> Identity Responses)
-> (Schema -> Identity Schema)
-> Operation
-> Identity Operation
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InsOrdHashMap HttpStatusCode (Referenced Response)
 -> Identity (InsOrdHashMap HttpStatusCode (Referenced Response)))
-> Responses -> Identity Responses
forall s a. HasResponses s a => Lens' s a
Lens'
  Responses (InsOrdHashMap HttpStatusCode (Referenced Response))
S.responses
          ((InsOrdHashMap HttpStatusCode (Referenced Response)
  -> Identity (InsOrdHashMap HttpStatusCode (Referenced Response)))
 -> Responses -> Identity Responses)
-> ((Schema -> Identity Schema)
    -> InsOrdHashMap HttpStatusCode (Referenced Response)
    -> Identity (InsOrdHashMap HttpStatusCode (Referenced Response)))
-> (Schema -> Identity Schema)
-> Responses
-> Identity Responses
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Referenced Response -> Identity (Referenced Response))
-> InsOrdHashMap HttpStatusCode (Referenced Response)
-> Identity (InsOrdHashMap HttpStatusCode (Referenced Response))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b)
-> InsOrdHashMap HttpStatusCode a
-> f (InsOrdHashMap HttpStatusCode b)
traverse
          ((Referenced Response -> Identity (Referenced Response))
 -> InsOrdHashMap HttpStatusCode (Referenced Response)
 -> Identity (InsOrdHashMap HttpStatusCode (Referenced Response)))
-> ((Schema -> Identity Schema)
    -> Referenced Response -> Identity (Referenced Response))
-> (Schema -> Identity Schema)
-> InsOrdHashMap HttpStatusCode (Referenced Response)
-> Identity (InsOrdHashMap HttpStatusCode (Referenced Response))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Response -> Identity Response)
-> Referenced Response -> Identity (Referenced Response)
forall a1 a2 (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a1 (f a2) -> p (Referenced a1) (f (Referenced a2))
S._Inline
          ((Response -> Identity Response)
 -> Referenced Response -> Identity (Referenced Response))
-> ((Schema -> Identity Schema) -> Response -> Identity Response)
-> (Schema -> Identity Schema)
-> Referenced Response
-> Identity (Referenced Response)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InsOrdHashMap MediaType MediaTypeObject
 -> Identity (InsOrdHashMap MediaType MediaTypeObject))
-> Response -> Identity Response
forall s a. HasContent s a => Lens' s a
Lens' Response (InsOrdHashMap MediaType MediaTypeObject)
S.content
          ((InsOrdHashMap MediaType MediaTypeObject
  -> Identity (InsOrdHashMap MediaType MediaTypeObject))
 -> Response -> Identity Response)
-> ((Schema -> Identity Schema)
    -> InsOrdHashMap MediaType MediaTypeObject
    -> Identity (InsOrdHashMap MediaType MediaTypeObject))
-> (Schema -> Identity Schema)
-> Response
-> Identity Response
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MediaTypeObject -> Identity MediaTypeObject)
-> InsOrdHashMap MediaType MediaTypeObject
-> Identity (InsOrdHashMap MediaType MediaTypeObject)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b)
-> InsOrdHashMap MediaType a -> f (InsOrdHashMap MediaType b)
traverse
          ((MediaTypeObject -> Identity MediaTypeObject)
 -> InsOrdHashMap MediaType MediaTypeObject
 -> Identity (InsOrdHashMap MediaType MediaTypeObject))
-> ((Schema -> Identity Schema)
    -> MediaTypeObject -> Identity MediaTypeObject)
-> (Schema -> Identity Schema)
-> InsOrdHashMap MediaType MediaTypeObject
-> Identity (InsOrdHashMap MediaType MediaTypeObject)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe (Referenced Schema) -> Identity (Maybe (Referenced Schema)))
-> MediaTypeObject -> Identity MediaTypeObject
forall s a. HasSchema s a => Lens' s a
Lens' MediaTypeObject (Maybe (Referenced Schema))
S.schema
          ((Maybe (Referenced Schema)
  -> Identity (Maybe (Referenced Schema)))
 -> MediaTypeObject -> Identity MediaTypeObject)
-> ((Schema -> Identity Schema)
    -> Maybe (Referenced Schema)
    -> Identity (Maybe (Referenced Schema)))
-> (Schema -> Identity Schema)
-> MediaTypeObject
-> Identity MediaTypeObject
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Referenced Schema -> Identity (Referenced Schema))
-> Maybe (Referenced Schema)
-> Identity (Maybe (Referenced Schema))
forall a b (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a (f b) -> p (Maybe a) (f (Maybe b))
_Just
          ((Referenced Schema -> Identity (Referenced Schema))
 -> Maybe (Referenced Schema)
 -> Identity (Maybe (Referenced Schema)))
-> ((Schema -> Identity Schema)
    -> Referenced Schema -> Identity (Referenced Schema))
-> (Schema -> Identity Schema)
-> Maybe (Referenced Schema)
-> Identity (Maybe (Referenced Schema))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Schema -> Identity Schema)
-> Referenced Schema -> Identity (Referenced Schema)
forall a1 a2 (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a1 (f a2) -> p (Referenced a1) (f (Referenced a2))
S._Inline
          ((Schema -> Identity Schema) -> OpenApi -> Identity OpenApi)
-> (Schema -> Schema) -> OpenApi -> OpenApi
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Schema -> Schema
sanitise
      )
  where
    sanitise :: S.Schema -> S.Schema
    sanitise :: Schema -> Schema
sanitise =
      ((InsOrdHashMap Text (Referenced Schema)
 -> Identity (InsOrdHashMap Text (Referenced Schema)))
-> Schema -> Identity Schema
forall s a. HasProperties s a => Lens' s a
Lens' Schema (InsOrdHashMap Text (Referenced Schema))
S.properties ((InsOrdHashMap Text (Referenced Schema)
  -> Identity (InsOrdHashMap Text (Referenced Schema)))
 -> Schema -> Identity Schema)
-> ((Schema -> Identity Schema)
    -> InsOrdHashMap Text (Referenced Schema)
    -> Identity (InsOrdHashMap Text (Referenced Schema)))
-> (Schema -> Identity Schema)
-> Schema
-> Identity Schema
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Referenced Schema -> Identity (Referenced Schema))
-> InsOrdHashMap Text (Referenced Schema)
-> Identity (InsOrdHashMap Text (Referenced Schema))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> InsOrdHashMap Text a -> f (InsOrdHashMap Text b)
traverse ((Referenced Schema -> Identity (Referenced Schema))
 -> InsOrdHashMap Text (Referenced Schema)
 -> Identity (InsOrdHashMap Text (Referenced Schema)))
-> ((Schema -> Identity Schema)
    -> Referenced Schema -> Identity (Referenced Schema))
-> (Schema -> Identity Schema)
-> InsOrdHashMap Text (Referenced Schema)
-> Identity (InsOrdHashMap Text (Referenced Schema))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Schema -> Identity Schema)
-> Referenced Schema -> Identity (Referenced Schema)
forall a1 a2 (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a1 (f a2) -> p (Referenced a1) (f (Referenced a2))
S._Inline ((Schema -> Identity Schema) -> Schema -> Identity Schema)
-> (Schema -> Schema) -> Schema -> Schema
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Schema -> Schema
sanitise)
        (Schema -> Schema) -> (Schema -> Schema) -> Schema -> Schema
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (([Text] -> Identity [Text]) -> Schema -> Identity Schema
forall s a. HasRequired s a => Lens' s a
Lens' Schema [Text]
S.required (([Text] -> Identity [Text]) -> Schema -> Identity Schema)
-> ([Text] -> [Text]) -> Schema -> Schema
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ [Text] -> [Text]
forall a. Ord a => [a] -> [a]
nubOrd)
        (Schema -> Schema) -> (Schema -> Schema) -> Schema -> Schema
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Maybe [Value] -> Identity (Maybe [Value]))
-> Schema -> Identity Schema
forall s a. HasEnum s a => Lens' s a
Lens' Schema (Maybe [Value])
S.enum_ ((Maybe [Value] -> Identity (Maybe [Value]))
 -> Schema -> Identity Schema)
-> (([Value] -> Identity [Value])
    -> Maybe [Value] -> Identity (Maybe [Value]))
-> ([Value] -> Identity [Value])
-> Schema
-> Identity Schema
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Value] -> Identity [Value])
-> Maybe [Value] -> Identity (Maybe [Value])
forall a b (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a (f b) -> p (Maybe a) (f (Maybe b))
_Just (([Value] -> Identity [Value]) -> Schema -> Identity Schema)
-> ([Value] -> [Value]) -> Schema -> Schema
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ [Value] -> [Value]
forall a. Eq a => [a] -> [a]
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 :: HttpStatusCode
-> Referenced Response
-> InsOrdHashMap HttpStatusCode (Referenced Response)
-> InsOrdHashMap HttpStatusCode (Referenced Response)
stripDefaultErrors HttpStatusCode
code Referenced Response
resp InsOrdHashMap HttpStatusCode (Referenced Response)
resps =
      case HttpStatusCode
code of
        HttpStatusCode
400 -> case Referenced Response
resp Referenced Response
-> Getting (First Text) (Referenced Response) Text -> Maybe Text
forall s a. s -> Getting (First a) s a -> Maybe a
^? (Response -> Const (First Text) Response)
-> Referenced Response -> Const (First Text) (Referenced Response)
forall a1 a2 (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a1 (f a2) -> p (Referenced a1) (f (Referenced a2))
_Inline ((Response -> Const (First Text) Response)
 -> Referenced Response -> Const (First Text) (Referenced Response))
-> ((Text -> Const (First Text) Text)
    -> Response -> Const (First Text) Response)
-> Getting (First Text) (Referenced Response) Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Const (First Text) Text)
-> Response -> Const (First Text) Response
forall s a. HasDescription s a => Lens' s a
Lens' Response Text
S.description of
          (Just Text
desc) ->
            if Text
"Invalid "
              Text -> Text -> Bool
`T.isPrefixOf` Text
desc
              Bool -> Bool -> Bool
&& Referenced Response
resp
                Referenced Response
-> Getting
     (First (InsOrdHashMap Text (Referenced Link)))
     (Referenced Response)
     (InsOrdHashMap Text (Referenced Link))
-> Maybe (InsOrdHashMap Text (Referenced Link))
forall s a. s -> Getting (First a) s a -> Maybe a
^? (Response
 -> Const (First (InsOrdHashMap Text (Referenced Link))) Response)
-> Referenced Response
-> Const
     (First (InsOrdHashMap Text (Referenced Link)))
     (Referenced Response)
forall a1 a2 (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a1 (f a2) -> p (Referenced a1) (f (Referenced a2))
_Inline
                  ((Response
  -> Const (First (InsOrdHashMap Text (Referenced Link))) Response)
 -> Referenced Response
 -> Const
      (First (InsOrdHashMap Text (Referenced Link)))
      (Referenced Response))
-> ((InsOrdHashMap Text (Referenced Link)
     -> Const
          (First (InsOrdHashMap Text (Referenced Link)))
          (InsOrdHashMap Text (Referenced Link)))
    -> Response
    -> Const (First (InsOrdHashMap Text (Referenced Link))) Response)
-> Getting
     (First (InsOrdHashMap Text (Referenced Link)))
     (Referenced Response)
     (InsOrdHashMap Text (Referenced Link))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InsOrdHashMap Text (Referenced Link)
 -> Const
      (First (InsOrdHashMap Text (Referenced Link)))
      (InsOrdHashMap Text (Referenced Link)))
-> Response
-> Const (First (InsOrdHashMap Text (Referenced Link))) Response
forall s a. HasLinks s a => Lens' s a
Lens' Response (InsOrdHashMap Text (Referenced Link))
links
                Maybe (InsOrdHashMap Text (Referenced Link))
-> Maybe (InsOrdHashMap Text (Referenced Link)) -> Bool
forall a. Eq a => a -> a -> Bool
== InsOrdHashMap Text (Referenced Link)
-> Maybe (InsOrdHashMap Text (Referenced Link))
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure InsOrdHashMap Text (Referenced Link)
forall a. Monoid a => a
mempty
              Bool -> Bool -> Bool
&& Referenced Response
resp
                Referenced Response
-> Getting
     (First (InsOrdHashMap MediaType MediaTypeObject))
     (Referenced Response)
     (InsOrdHashMap MediaType MediaTypeObject)
-> Maybe (InsOrdHashMap MediaType MediaTypeObject)
forall s a. s -> Getting (First a) s a -> Maybe a
^? (Response
 -> Const
      (First (InsOrdHashMap MediaType MediaTypeObject)) Response)
-> Referenced Response
-> Const
     (First (InsOrdHashMap MediaType MediaTypeObject))
     (Referenced Response)
forall a1 a2 (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a1 (f a2) -> p (Referenced a1) (f (Referenced a2))
_Inline
                  ((Response
  -> Const
       (First (InsOrdHashMap MediaType MediaTypeObject)) Response)
 -> Referenced Response
 -> Const
      (First (InsOrdHashMap MediaType MediaTypeObject))
      (Referenced Response))
-> ((InsOrdHashMap MediaType MediaTypeObject
     -> Const
          (First (InsOrdHashMap MediaType MediaTypeObject))
          (InsOrdHashMap MediaType MediaTypeObject))
    -> Response
    -> Const
         (First (InsOrdHashMap MediaType MediaTypeObject)) Response)
-> Getting
     (First (InsOrdHashMap MediaType MediaTypeObject))
     (Referenced Response)
     (InsOrdHashMap MediaType MediaTypeObject)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InsOrdHashMap MediaType MediaTypeObject
 -> Const
      (First (InsOrdHashMap MediaType MediaTypeObject))
      (InsOrdHashMap MediaType MediaTypeObject))
-> Response
-> Const (First (InsOrdHashMap MediaType MediaTypeObject)) Response
forall s a. HasContent s a => Lens' s a
Lens' Response (InsOrdHashMap MediaType MediaTypeObject)
content
                Maybe (InsOrdHashMap MediaType MediaTypeObject)
-> Maybe (InsOrdHashMap MediaType MediaTypeObject) -> Bool
forall a. Eq a => a -> a -> Bool
== InsOrdHashMap MediaType MediaTypeObject
-> Maybe (InsOrdHashMap MediaType MediaTypeObject)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure InsOrdHashMap MediaType MediaTypeObject
forall a. Monoid a => a
mempty
              Bool -> Bool -> Bool
&& Referenced Response
resp
                Referenced Response
-> Getting
     (First (InsOrdHashMap Text (Referenced Header)))
     (Referenced Response)
     (InsOrdHashMap Text (Referenced Header))
-> Maybe (InsOrdHashMap Text (Referenced Header))
forall s a. s -> Getting (First a) s a -> Maybe a
^? (Response
 -> Const (First (InsOrdHashMap Text (Referenced Header))) Response)
-> Referenced Response
-> Const
     (First (InsOrdHashMap Text (Referenced Header)))
     (Referenced Response)
forall a1 a2 (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a1 (f a2) -> p (Referenced a1) (f (Referenced a2))
_Inline
                  ((Response
  -> Const (First (InsOrdHashMap Text (Referenced Header))) Response)
 -> Referenced Response
 -> Const
      (First (InsOrdHashMap Text (Referenced Header)))
      (Referenced Response))
-> ((InsOrdHashMap Text (Referenced Header)
     -> Const
          (First (InsOrdHashMap Text (Referenced Header)))
          (InsOrdHashMap Text (Referenced Header)))
    -> Response
    -> Const (First (InsOrdHashMap Text (Referenced Header))) Response)
-> Getting
     (First (InsOrdHashMap Text (Referenced Header)))
     (Referenced Response)
     (InsOrdHashMap Text (Referenced Header))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InsOrdHashMap Text (Referenced Header)
 -> Const
      (First (InsOrdHashMap Text (Referenced Header)))
      (InsOrdHashMap Text (Referenced Header)))
-> Response
-> Const (First (InsOrdHashMap Text (Referenced Header))) Response
forall s a. HasHeaders s a => Lens' s a
Lens' Response (InsOrdHashMap Text (Referenced Header))
headers
                Maybe (InsOrdHashMap Text (Referenced Header))
-> Maybe (InsOrdHashMap Text (Referenced Header)) -> Bool
forall a. Eq a => a -> a -> Bool
== InsOrdHashMap Text (Referenced Header)
-> Maybe (InsOrdHashMap Text (Referenced Header))
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure InsOrdHashMap Text (Referenced Header)
forall a. Monoid a => a
mempty
              then InsOrdHashMap HttpStatusCode (Referenced Response)
resps
              else HttpStatusCode
-> Referenced Response
-> InsOrdHashMap HttpStatusCode (Referenced Response)
-> InsOrdHashMap HttpStatusCode (Referenced Response)
forall k v.
(Eq k, Hashable k) =>
k -> v -> InsOrdHashMap k v -> InsOrdHashMap k v
insert HttpStatusCode
code Referenced Response
resp InsOrdHashMap HttpStatusCode (Referenced Response)
resps
          Maybe Text
Nothing -> HttpStatusCode
-> Referenced Response
-> InsOrdHashMap HttpStatusCode (Referenced Response)
-> InsOrdHashMap HttpStatusCode (Referenced Response)
forall k v.
(Eq k, Hashable k) =>
k -> v -> InsOrdHashMap k v -> InsOrdHashMap k v
insert HttpStatusCode
code Referenced Response
resp InsOrdHashMap HttpStatusCode (Referenced Response)
resps
        HttpStatusCode
404 -> case Referenced Response
resp Referenced Response
-> Getting (First Text) (Referenced Response) Text -> Maybe Text
forall s a. s -> Getting (First a) s a -> Maybe a
^? (Response -> Const (First Text) Response)
-> Referenced Response -> Const (First Text) (Referenced Response)
forall a1 a2 (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a1 (f a2) -> p (Referenced a1) (f (Referenced a2))
_Inline ((Response -> Const (First Text) Response)
 -> Referenced Response -> Const (First Text) (Referenced Response))
-> ((Text -> Const (First Text) Text)
    -> Response -> Const (First Text) Response)
-> Getting (First Text) (Referenced Response) Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Const (First Text) Text)
-> Response -> Const (First Text) Response
forall s a. HasDescription s a => Lens' s a
Lens' Response Text
S.description of
          (Just Text
desc) ->
            if Text
" not found"
              Text -> Text -> Bool
`T.isSuffixOf` Text
desc
              Bool -> Bool -> Bool
&& Referenced Response
resp
                Referenced Response
-> Getting
     (First (InsOrdHashMap Text (Referenced Link)))
     (Referenced Response)
     (InsOrdHashMap Text (Referenced Link))
-> Maybe (InsOrdHashMap Text (Referenced Link))
forall s a. s -> Getting (First a) s a -> Maybe a
^? (Response
 -> Const (First (InsOrdHashMap Text (Referenced Link))) Response)
-> Referenced Response
-> Const
     (First (InsOrdHashMap Text (Referenced Link)))
     (Referenced Response)
forall a1 a2 (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a1 (f a2) -> p (Referenced a1) (f (Referenced a2))
_Inline
                  ((Response
  -> Const (First (InsOrdHashMap Text (Referenced Link))) Response)
 -> Referenced Response
 -> Const
      (First (InsOrdHashMap Text (Referenced Link)))
      (Referenced Response))
-> ((InsOrdHashMap Text (Referenced Link)
     -> Const
          (First (InsOrdHashMap Text (Referenced Link)))
          (InsOrdHashMap Text (Referenced Link)))
    -> Response
    -> Const (First (InsOrdHashMap Text (Referenced Link))) Response)
-> Getting
     (First (InsOrdHashMap Text (Referenced Link)))
     (Referenced Response)
     (InsOrdHashMap Text (Referenced Link))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InsOrdHashMap Text (Referenced Link)
 -> Const
      (First (InsOrdHashMap Text (Referenced Link)))
      (InsOrdHashMap Text (Referenced Link)))
-> Response
-> Const (First (InsOrdHashMap Text (Referenced Link))) Response
forall s a. HasLinks s a => Lens' s a
Lens' Response (InsOrdHashMap Text (Referenced Link))
links
                Maybe (InsOrdHashMap Text (Referenced Link))
-> Maybe (InsOrdHashMap Text (Referenced Link)) -> Bool
forall a. Eq a => a -> a -> Bool
== InsOrdHashMap Text (Referenced Link)
-> Maybe (InsOrdHashMap Text (Referenced Link))
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure InsOrdHashMap Text (Referenced Link)
forall a. Monoid a => a
mempty
              Bool -> Bool -> Bool
&& Referenced Response
resp
                Referenced Response
-> Getting
     (First (InsOrdHashMap MediaType MediaTypeObject))
     (Referenced Response)
     (InsOrdHashMap MediaType MediaTypeObject)
-> Maybe (InsOrdHashMap MediaType MediaTypeObject)
forall s a. s -> Getting (First a) s a -> Maybe a
^? (Response
 -> Const
      (First (InsOrdHashMap MediaType MediaTypeObject)) Response)
-> Referenced Response
-> Const
     (First (InsOrdHashMap MediaType MediaTypeObject))
     (Referenced Response)
forall a1 a2 (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a1 (f a2) -> p (Referenced a1) (f (Referenced a2))
_Inline
                  ((Response
  -> Const
       (First (InsOrdHashMap MediaType MediaTypeObject)) Response)
 -> Referenced Response
 -> Const
      (First (InsOrdHashMap MediaType MediaTypeObject))
      (Referenced Response))
-> ((InsOrdHashMap MediaType MediaTypeObject
     -> Const
          (First (InsOrdHashMap MediaType MediaTypeObject))
          (InsOrdHashMap MediaType MediaTypeObject))
    -> Response
    -> Const
         (First (InsOrdHashMap MediaType MediaTypeObject)) Response)
-> Getting
     (First (InsOrdHashMap MediaType MediaTypeObject))
     (Referenced Response)
     (InsOrdHashMap MediaType MediaTypeObject)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InsOrdHashMap MediaType MediaTypeObject
 -> Const
      (First (InsOrdHashMap MediaType MediaTypeObject))
      (InsOrdHashMap MediaType MediaTypeObject))
-> Response
-> Const (First (InsOrdHashMap MediaType MediaTypeObject)) Response
forall s a. HasContent s a => Lens' s a
Lens' Response (InsOrdHashMap MediaType MediaTypeObject)
content
                Maybe (InsOrdHashMap MediaType MediaTypeObject)
-> Maybe (InsOrdHashMap MediaType MediaTypeObject) -> Bool
forall a. Eq a => a -> a -> Bool
== InsOrdHashMap MediaType MediaTypeObject
-> Maybe (InsOrdHashMap MediaType MediaTypeObject)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure InsOrdHashMap MediaType MediaTypeObject
forall a. Monoid a => a
mempty
              Bool -> Bool -> Bool
&& Referenced Response
resp
                Referenced Response
-> Getting
     (First (InsOrdHashMap Text (Referenced Header)))
     (Referenced Response)
     (InsOrdHashMap Text (Referenced Header))
-> Maybe (InsOrdHashMap Text (Referenced Header))
forall s a. s -> Getting (First a) s a -> Maybe a
^? (Response
 -> Const (First (InsOrdHashMap Text (Referenced Header))) Response)
-> Referenced Response
-> Const
     (First (InsOrdHashMap Text (Referenced Header)))
     (Referenced Response)
forall a1 a2 (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a1 (f a2) -> p (Referenced a1) (f (Referenced a2))
_Inline
                  ((Response
  -> Const (First (InsOrdHashMap Text (Referenced Header))) Response)
 -> Referenced Response
 -> Const
      (First (InsOrdHashMap Text (Referenced Header)))
      (Referenced Response))
-> ((InsOrdHashMap Text (Referenced Header)
     -> Const
          (First (InsOrdHashMap Text (Referenced Header)))
          (InsOrdHashMap Text (Referenced Header)))
    -> Response
    -> Const (First (InsOrdHashMap Text (Referenced Header))) Response)
-> Getting
     (First (InsOrdHashMap Text (Referenced Header)))
     (Referenced Response)
     (InsOrdHashMap Text (Referenced Header))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InsOrdHashMap Text (Referenced Header)
 -> Const
      (First (InsOrdHashMap Text (Referenced Header)))
      (InsOrdHashMap Text (Referenced Header)))
-> Response
-> Const (First (InsOrdHashMap Text (Referenced Header))) Response
forall s a. HasHeaders s a => Lens' s a
Lens' Response (InsOrdHashMap Text (Referenced Header))
headers
                Maybe (InsOrdHashMap Text (Referenced Header))
-> Maybe (InsOrdHashMap Text (Referenced Header)) -> Bool
forall a. Eq a => a -> a -> Bool
== InsOrdHashMap Text (Referenced Header)
-> Maybe (InsOrdHashMap Text (Referenced Header))
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure InsOrdHashMap Text (Referenced Header)
forall a. Monoid a => a
mempty
              then InsOrdHashMap HttpStatusCode (Referenced Response)
resps
              else HttpStatusCode
-> Referenced Response
-> InsOrdHashMap HttpStatusCode (Referenced Response)
-> InsOrdHashMap HttpStatusCode (Referenced Response)
forall k v.
(Eq k, Hashable k) =>
k -> v -> InsOrdHashMap k v -> InsOrdHashMap k v
insert HttpStatusCode
code Referenced Response
resp InsOrdHashMap HttpStatusCode (Referenced Response)
resps
          Maybe Text
Nothing -> HttpStatusCode
-> Referenced Response
-> InsOrdHashMap HttpStatusCode (Referenced Response)
-> InsOrdHashMap HttpStatusCode (Referenced Response)
forall k v.
(Eq k, Hashable k) =>
k -> v -> InsOrdHashMap k v -> InsOrdHashMap k v
insert HttpStatusCode
code Referenced Response
resp InsOrdHashMap HttpStatusCode (Referenced Response)
resps
        HttpStatusCode
_ -> HttpStatusCode
-> Referenced Response
-> InsOrdHashMap HttpStatusCode (Referenced Response)
-> InsOrdHashMap HttpStatusCode (Referenced Response)
forall k v.
(Eq k, Hashable k) =>
k -> v -> InsOrdHashMap k v -> InsOrdHashMap k v
insert HttpStatusCode
code Referenced Response
resp InsOrdHashMap HttpStatusCode (Referenced Response)
resps

type Responses' = InsOrdHashMap HttpStatusCode (Referenced Response)