{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TemplateHaskell #-}
-- 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/>.
{-# OPTIONS_GHC -Wno-unused-top-binds #-}

module Wire.API.Routes.Version
  ( -- * API version endpoint
    VersionAPI,
    VersionAPITag,
    VersionInfo (..),
    versionHeader,
    VersionHeader,

    -- * Version
    Version (..),
    versionInt,
    versionText,
    VersionNumber (..),
    VersionExp (..),
    supportedVersions,
    isDevelopmentVersion,
    developmentVersions,
    expandVersionExp,
    maxAvailableVersion,

    -- * Servant combinators
    Until,
    From,

    -- * Swagger instances
    SpecialiseToVersion,
  )
where

import Control.Error (note)
import Control.Lens (makePrisms, (?~))
import Data.Aeson (FromJSON, ToJSON (..))
import Data.Aeson qualified as Aeson
import Data.Bifunctor
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.Set ((\\))
import Data.Set qualified as Set
import Data.Singletons.Base.TH
import Data.Text qualified as Text
import Data.Text.Encoding as Text
import GHC.TypeLits
import Imports hiding ((\\))
import Servant
import Servant.API.Extended.RawM qualified as RawM
import Wire.API.Deprecated
import Wire.API.Routes.MultiVerb
import Wire.API.Routes.Named hiding (unnamed)
import Wire.API.VersionInfo
import Wire.Arbitrary (Arbitrary, GenericUniform (GenericUniform))

-- | Version of the public API.  Serializes to `"v<n>"`.  See 'VersionNumber' below for one
-- that serializes to `<n>`.  See `/libs/wire-api/test/unit/Test/Wire/API/Routes/Version.hs`
-- for serialization rules.
--
-- If you add or remove versions from this type, make sure 'versionInt', 'supportedVersions',
-- and 'developmentVersions' stay in sync; everything else here should keep working without
-- change.  See also documentation in the *docs* directory.
-- https://docs.wire.com/developer/developer/api-versioning.html#version-bump-checklist
data Version = V0 | V1 | V2 | V3 | V4 | V5 | V6 | V7
  deriving stock (Version -> Version -> Bool
(Version -> Version -> Bool)
-> (Version -> Version -> Bool) -> Eq Version
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Version -> Version -> Bool
== :: Version -> Version -> Bool
$c/= :: Version -> Version -> Bool
/= :: Version -> Version -> Bool
Eq, Eq Version
Eq Version =>
(Version -> Version -> Ordering)
-> (Version -> Version -> Bool)
-> (Version -> Version -> Bool)
-> (Version -> Version -> Bool)
-> (Version -> Version -> Bool)
-> (Version -> Version -> Version)
-> (Version -> Version -> Version)
-> Ord Version
Version -> Version -> Bool
Version -> Version -> Ordering
Version -> Version -> Version
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Version -> Version -> Ordering
compare :: Version -> Version -> Ordering
$c< :: Version -> Version -> Bool
< :: Version -> Version -> Bool
$c<= :: Version -> Version -> Bool
<= :: Version -> Version -> Bool
$c> :: Version -> Version -> Bool
> :: Version -> Version -> Bool
$c>= :: Version -> Version -> Bool
>= :: Version -> Version -> Bool
$cmax :: Version -> Version -> Version
max :: Version -> Version -> Version
$cmin :: Version -> Version -> Version
min :: Version -> Version -> Version
Ord, Version
Version -> Version -> Bounded Version
forall a. a -> a -> Bounded a
$cminBound :: Version
minBound :: Version
$cmaxBound :: Version
maxBound :: Version
Bounded, Int -> Version
Version -> Int
Version -> [Version]
Version -> Version
Version -> Version -> [Version]
Version -> Version -> Version -> [Version]
(Version -> Version)
-> (Version -> Version)
-> (Int -> Version)
-> (Version -> Int)
-> (Version -> [Version])
-> (Version -> Version -> [Version])
-> (Version -> Version -> [Version])
-> (Version -> Version -> Version -> [Version])
-> Enum Version
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Version -> Version
succ :: Version -> Version
$cpred :: Version -> Version
pred :: Version -> Version
$ctoEnum :: Int -> Version
toEnum :: Int -> Version
$cfromEnum :: Version -> Int
fromEnum :: Version -> Int
$cenumFrom :: Version -> [Version]
enumFrom :: Version -> [Version]
$cenumFromThen :: Version -> Version -> [Version]
enumFromThen :: Version -> Version -> [Version]
$cenumFromTo :: Version -> Version -> [Version]
enumFromTo :: Version -> Version -> [Version]
$cenumFromThenTo :: Version -> Version -> Version -> [Version]
enumFromThenTo :: Version -> Version -> Version -> [Version]
Enum, Int -> Version -> ShowS
[Version] -> ShowS
Version -> [Char]
(Int -> Version -> ShowS)
-> (Version -> [Char]) -> ([Version] -> ShowS) -> Show Version
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Version -> ShowS
showsPrec :: Int -> Version -> ShowS
$cshow :: Version -> [Char]
show :: Version -> [Char]
$cshowList :: [Version] -> ShowS
showList :: [Version] -> ShowS
Show, (forall x. Version -> Rep Version x)
-> (forall x. Rep Version x -> Version) -> Generic Version
forall x. Rep Version x -> Version
forall x. Version -> Rep Version x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Version -> Rep Version x
from :: forall x. Version -> Rep Version x
$cto :: forall x. Rep Version x -> Version
to :: forall x. Rep Version x -> Version
Generic)
  deriving (Value -> Parser [Version]
Value -> Parser Version
(Value -> Parser Version)
-> (Value -> Parser [Version]) -> FromJSON Version
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
$cparseJSON :: Value -> Parser Version
parseJSON :: Value -> Parser Version
$cparseJSONList :: Value -> Parser [Version]
parseJSONList :: Value -> Parser [Version]
FromJSON, [Version] -> Value
[Version] -> Encoding
Version -> Value
Version -> Encoding
(Version -> Value)
-> (Version -> Encoding)
-> ([Version] -> Value)
-> ([Version] -> Encoding)
-> ToJSON Version
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
$ctoJSON :: Version -> Value
toJSON :: Version -> Value
$ctoEncoding :: Version -> Encoding
toEncoding :: Version -> Encoding
$ctoJSONList :: [Version] -> Value
toJSONList :: [Version] -> Value
$ctoEncodingList :: [Version] -> Encoding
toEncodingList :: [Version] -> Encoding
ToJSON) via (Schema Version)
  deriving (Gen Version
Gen Version -> (Version -> [Version]) -> Arbitrary Version
Version -> [Version]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
$carbitrary :: Gen Version
arbitrary :: Gen Version
$cshrink :: Version -> [Version]
shrink :: Version -> [Version]
Arbitrary) via (GenericUniform Version)

-- | Manual enumeration of version integrals (the `<n>` in the constructor `V<n>`).
--
-- This is not the same as 'fromEnum': we will remove unsupported versions in the future,
-- which will cause `<n>` and `fromEnum V<n>` to diverge.  `Enum` should not be understood as
-- a bijection between meaningful integers and versions, but merely as a convenient way to say
-- `allVersions = [minBound..]`.
versionInt :: (Integral i) => Version -> i
versionInt :: forall i. Integral i => Version -> i
versionInt Version
V0 = i
0
versionInt Version
V1 = i
1
versionInt Version
V2 = i
2
versionInt Version
V3 = i
3
versionInt Version
V4 = i
4
versionInt Version
V5 = i
5
versionInt Version
V6 = i
6
versionInt Version
V7 = i
7

supportedVersions :: [Version]
supportedVersions :: [Version]
supportedVersions = [Version
forall a. Bounded a => a
minBound .. Version
forall a. Bounded a => a
maxBound]

maxAvailableVersion :: Set Version -> Maybe Version
maxAvailableVersion :: Set Version -> Maybe Version
maxAvailableVersion Set Version
disabled = Set Version -> Maybe Version
forall a. Set a -> Maybe a
Set.lookupMax (Set Version -> Maybe Version) -> Set Version -> Maybe Version
forall a b. (a -> b) -> a -> b
$ [Version] -> Set Version
forall a. Ord a => [a] -> Set a
Set.fromList [Version]
supportedVersions Set Version -> Set Version -> Set Version
forall a. Ord a => Set a -> Set a -> Set a
\\ Set Version
disabled

----------------------------------------------------------------------

versionText :: Version -> Text
versionText :: Version -> Text
versionText = (Text
"v" <>) (Text -> Text) -> (Version -> Text) -> Version -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Text
forall a. ToHttpApiData a => a -> Text
toUrlPiece (Int -> Text) -> (Version -> Int) -> Version -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall i. Integral i => Version -> i
versionInt @Int

versionByteString :: Version -> ByteString
versionByteString :: Version -> ByteString
versionByteString = (ByteString
"v" <>) (ByteString -> ByteString)
-> (Version -> ByteString) -> Version -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ByteString
forall a. ToByteString a => a -> ByteString
toByteString' (Int -> ByteString) -> (Version -> Int) -> Version -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall i. Integral i => Version -> i
versionInt @Int

instance ToSchema Version where
  schema :: ValueSchema NamedSwaggerDoc Version
schema = forall v doc a b.
(With v, HasEnum v doc) =>
Text
-> SchemaP [Value] v (Alt Maybe v) a b
-> SchemaP doc Value Value a b
enum @Text Text
"Version" (SchemaP [Value] Text (Alt Maybe Text) Version Version
 -> ValueSchema NamedSwaggerDoc Version)
-> ([SchemaP [Value] Text (Alt Maybe Text) Version Version]
    -> SchemaP [Value] Text (Alt Maybe Text) Version Version)
-> [SchemaP [Value] Text (Alt Maybe Text) Version Version]
-> ValueSchema NamedSwaggerDoc Version
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [SchemaP [Value] Text (Alt Maybe Text) Version Version]
-> SchemaP [Value] Text (Alt Maybe Text) Version Version
forall a. Monoid a => [a] -> a
mconcat ([SchemaP [Value] Text (Alt Maybe Text) Version Version]
 -> ValueSchema NamedSwaggerDoc Version)
-> [SchemaP [Value] Text (Alt Maybe Text) Version Version]
-> ValueSchema NamedSwaggerDoc Version
forall a b. (a -> b) -> a -> b
$ (\Version
v -> Text
-> Version -> SchemaP [Value] Text (Alt Maybe Text) Version Version
forall a b.
(ToJSON a, Eq a, Eq b) =>
a -> b -> SchemaP [Value] a (Alt Maybe a) b b
element (Version -> Text
versionText Version
v) Version
v) (Version -> SchemaP [Value] Text (Alt Maybe Text) Version Version)
-> [Version]
-> [SchemaP [Value] Text (Alt Maybe Text) Version Version]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Version
forall a. Bounded a => a
minBound ..]

instance FromHttpApiData Version where
  parseQueryParam :: Text -> Either Text Version
parseQueryParam Text
v = Text -> Maybe Version -> Either Text Version
forall a b. a -> Maybe b -> Either a b
note (Text
"Unknown version: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
v) (Maybe Version -> Either Text Version)
-> Maybe Version -> Either Text Version
forall a b. (a -> b) -> a -> b
$
    Alt Maybe Version -> Maybe Version
forall {k} (f :: k -> *) (a :: k). Alt f a -> f a
getAlt (Alt Maybe Version -> Maybe Version)
-> Alt Maybe Version -> Maybe Version
forall a b. (a -> b) -> a -> b
$
      ((Version -> Alt Maybe Version) -> [Version] -> Alt Maybe Version)
-> [Version] -> (Version -> Alt Maybe Version) -> Alt Maybe Version
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Version -> Alt Maybe Version) -> [Version] -> Alt Maybe Version
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap [Version
forall a. Bounded a => a
minBound ..] ((Version -> Alt Maybe Version) -> Alt Maybe Version)
-> (Version -> Alt Maybe Version) -> Alt Maybe Version
forall a b. (a -> b) -> a -> b
$
        \Version
s ->
          Bool -> Alt Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Version -> Text
versionText Version
s Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
v) Alt Maybe () -> Version -> Alt Maybe Version
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Version
s

instance ToHttpApiData Version where
  toHeader :: Version -> ByteString
toHeader = Version -> ByteString
versionByteString
  toUrlPiece :: Version -> Text
toUrlPiece = Version -> Text
versionText

instance ToByteString Version where
  builder :: Version -> Builder
builder = ByteString -> Builder
Builder.fromByteString (ByteString -> Builder)
-> (Version -> ByteString) -> Version -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Version -> ByteString
versionByteString

-- | Wrapper around 'Version' that serializes to integers `<n>`, as needed in
-- eg. `VersionInfo`.  See `/libs/wire-api/test/unit/Test/Wire/API/Routes/Version.hs` for
-- serialization rules.
newtype VersionNumber = VersionNumber {VersionNumber -> Version
fromVersionNumber :: Version}
  deriving stock (VersionNumber -> VersionNumber -> Bool
(VersionNumber -> VersionNumber -> Bool)
-> (VersionNumber -> VersionNumber -> Bool) -> Eq VersionNumber
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: VersionNumber -> VersionNumber -> Bool
== :: VersionNumber -> VersionNumber -> Bool
$c/= :: VersionNumber -> VersionNumber -> Bool
/= :: VersionNumber -> VersionNumber -> Bool
Eq, Eq VersionNumber
Eq VersionNumber =>
(VersionNumber -> VersionNumber -> Ordering)
-> (VersionNumber -> VersionNumber -> Bool)
-> (VersionNumber -> VersionNumber -> Bool)
-> (VersionNumber -> VersionNumber -> Bool)
-> (VersionNumber -> VersionNumber -> Bool)
-> (VersionNumber -> VersionNumber -> VersionNumber)
-> (VersionNumber -> VersionNumber -> VersionNumber)
-> Ord VersionNumber
VersionNumber -> VersionNumber -> Bool
VersionNumber -> VersionNumber -> Ordering
VersionNumber -> VersionNumber -> VersionNumber
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: VersionNumber -> VersionNumber -> Ordering
compare :: VersionNumber -> VersionNumber -> Ordering
$c< :: VersionNumber -> VersionNumber -> Bool
< :: VersionNumber -> VersionNumber -> Bool
$c<= :: VersionNumber -> VersionNumber -> Bool
<= :: VersionNumber -> VersionNumber -> Bool
$c> :: VersionNumber -> VersionNumber -> Bool
> :: VersionNumber -> VersionNumber -> Bool
$c>= :: VersionNumber -> VersionNumber -> Bool
>= :: VersionNumber -> VersionNumber -> Bool
$cmax :: VersionNumber -> VersionNumber -> VersionNumber
max :: VersionNumber -> VersionNumber -> VersionNumber
$cmin :: VersionNumber -> VersionNumber -> VersionNumber
min :: VersionNumber -> VersionNumber -> VersionNumber
Ord, Int -> VersionNumber -> ShowS
[VersionNumber] -> ShowS
VersionNumber -> [Char]
(Int -> VersionNumber -> ShowS)
-> (VersionNumber -> [Char])
-> ([VersionNumber] -> ShowS)
-> Show VersionNumber
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> VersionNumber -> ShowS
showsPrec :: Int -> VersionNumber -> ShowS
$cshow :: VersionNumber -> [Char]
show :: VersionNumber -> [Char]
$cshowList :: [VersionNumber] -> ShowS
showList :: [VersionNumber] -> ShowS
Show, (forall x. VersionNumber -> Rep VersionNumber x)
-> (forall x. Rep VersionNumber x -> VersionNumber)
-> Generic VersionNumber
forall x. Rep VersionNumber x -> VersionNumber
forall x. VersionNumber -> Rep VersionNumber x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. VersionNumber -> Rep VersionNumber x
from :: forall x. VersionNumber -> Rep VersionNumber x
$cto :: forall x. Rep VersionNumber x -> VersionNumber
to :: forall x. Rep VersionNumber x -> VersionNumber
Generic)
  deriving newtype (VersionNumber
VersionNumber -> VersionNumber -> Bounded VersionNumber
forall a. a -> a -> Bounded a
$cminBound :: VersionNumber
minBound :: VersionNumber
$cmaxBound :: VersionNumber
maxBound :: VersionNumber
Bounded, Int -> VersionNumber
VersionNumber -> Int
VersionNumber -> [VersionNumber]
VersionNumber -> VersionNumber
VersionNumber -> VersionNumber -> [VersionNumber]
VersionNumber -> VersionNumber -> VersionNumber -> [VersionNumber]
(VersionNumber -> VersionNumber)
-> (VersionNumber -> VersionNumber)
-> (Int -> VersionNumber)
-> (VersionNumber -> Int)
-> (VersionNumber -> [VersionNumber])
-> (VersionNumber -> VersionNumber -> [VersionNumber])
-> (VersionNumber -> VersionNumber -> [VersionNumber])
-> (VersionNumber
    -> VersionNumber -> VersionNumber -> [VersionNumber])
-> Enum VersionNumber
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: VersionNumber -> VersionNumber
succ :: VersionNumber -> VersionNumber
$cpred :: VersionNumber -> VersionNumber
pred :: VersionNumber -> VersionNumber
$ctoEnum :: Int -> VersionNumber
toEnum :: Int -> VersionNumber
$cfromEnum :: VersionNumber -> Int
fromEnum :: VersionNumber -> Int
$cenumFrom :: VersionNumber -> [VersionNumber]
enumFrom :: VersionNumber -> [VersionNumber]
$cenumFromThen :: VersionNumber -> VersionNumber -> [VersionNumber]
enumFromThen :: VersionNumber -> VersionNumber -> [VersionNumber]
$cenumFromTo :: VersionNumber -> VersionNumber -> [VersionNumber]
enumFromTo :: VersionNumber -> VersionNumber -> [VersionNumber]
$cenumFromThenTo :: VersionNumber -> VersionNumber -> VersionNumber -> [VersionNumber]
enumFromThenTo :: VersionNumber -> VersionNumber -> VersionNumber -> [VersionNumber]
Enum)
  deriving (Value -> Parser [VersionNumber]
Value -> Parser VersionNumber
(Value -> Parser VersionNumber)
-> (Value -> Parser [VersionNumber]) -> FromJSON VersionNumber
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
$cparseJSON :: Value -> Parser VersionNumber
parseJSON :: Value -> Parser VersionNumber
$cparseJSONList :: Value -> Parser [VersionNumber]
parseJSONList :: Value -> Parser [VersionNumber]
FromJSON, [VersionNumber] -> Value
[VersionNumber] -> Encoding
VersionNumber -> Value
VersionNumber -> Encoding
(VersionNumber -> Value)
-> (VersionNumber -> Encoding)
-> ([VersionNumber] -> Value)
-> ([VersionNumber] -> Encoding)
-> ToJSON VersionNumber
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
$ctoJSON :: VersionNumber -> Value
toJSON :: VersionNumber -> Value
$ctoEncoding :: VersionNumber -> Encoding
toEncoding :: VersionNumber -> Encoding
$ctoJSONList :: [VersionNumber] -> Value
toJSONList :: [VersionNumber] -> Value
$ctoEncodingList :: [VersionNumber] -> Encoding
toEncodingList :: [VersionNumber] -> Encoding
ToJSON) via (Schema VersionNumber)
  deriving (Gen VersionNumber
Gen VersionNumber
-> (VersionNumber -> [VersionNumber]) -> Arbitrary VersionNumber
VersionNumber -> [VersionNumber]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
$carbitrary :: Gen VersionNumber
arbitrary :: Gen VersionNumber
$cshrink :: VersionNumber -> [VersionNumber]
shrink :: VersionNumber -> [VersionNumber]
Arbitrary) via (GenericUniform Version)

instance ToSchema VersionNumber where
  schema :: ValueSchema NamedSwaggerDoc VersionNumber
schema =
    forall v doc a b.
(With v, HasEnum v doc) =>
Text
-> SchemaP [Value] v (Alt Maybe v) a b
-> SchemaP doc Value Value a b
enum @Integer Text
"VersionNumber" (SchemaP
   [Value] Integer (Alt Maybe Integer) VersionNumber VersionNumber
 -> ValueSchema NamedSwaggerDoc VersionNumber)
-> ([SchemaP
       [Value] Integer (Alt Maybe Integer) VersionNumber VersionNumber]
    -> SchemaP
         [Value] Integer (Alt Maybe Integer) VersionNumber VersionNumber)
-> [SchemaP
      [Value] Integer (Alt Maybe Integer) VersionNumber VersionNumber]
-> ValueSchema NamedSwaggerDoc VersionNumber
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [SchemaP
   [Value] Integer (Alt Maybe Integer) VersionNumber VersionNumber]
-> SchemaP
     [Value] Integer (Alt Maybe Integer) VersionNumber VersionNumber
forall a. Monoid a => [a] -> a
mconcat ([SchemaP
    [Value] Integer (Alt Maybe Integer) VersionNumber VersionNumber]
 -> ValueSchema NamedSwaggerDoc VersionNumber)
-> [SchemaP
      [Value] Integer (Alt Maybe Integer) VersionNumber VersionNumber]
-> ValueSchema NamedSwaggerDoc VersionNumber
forall a b. (a -> b) -> a -> b
$ (\Version
v -> Integer
-> VersionNumber
-> SchemaP
     [Value] Integer (Alt Maybe Integer) VersionNumber VersionNumber
forall a b.
(ToJSON a, Eq a, Eq b) =>
a -> b -> SchemaP [Value] a (Alt Maybe a) b b
element (Version -> Integer
forall i. Integral i => Version -> i
versionInt Version
v) (Version -> VersionNumber
VersionNumber Version
v)) (Version
 -> SchemaP
      [Value] Integer (Alt Maybe Integer) VersionNumber VersionNumber)
-> [Version]
-> [SchemaP
      [Value] Integer (Alt Maybe Integer) VersionNumber VersionNumber]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Version
forall a. Bounded a => a
minBound ..]

instance FromHttpApiData VersionNumber where
  parseHeader :: ByteString -> Either Text VersionNumber
parseHeader = ([Char] -> Text)
-> Either [Char] VersionNumber -> Either Text VersionNumber
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first [Char] -> Text
Text.pack (Either [Char] VersionNumber -> Either Text VersionNumber)
-> (ByteString -> Either [Char] VersionNumber)
-> ByteString
-> Either Text VersionNumber
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either [Char] VersionNumber
forall a. FromJSON a => ByteString -> Either [Char] a
Aeson.eitherDecode (ByteString -> Either [Char] VersionNumber)
-> (ByteString -> ByteString)
-> ByteString
-> Either [Char] VersionNumber
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
LBS.fromStrict
  parseUrlPiece :: Text -> Either Text VersionNumber
parseUrlPiece = ByteString -> Either Text VersionNumber
forall a. FromHttpApiData a => ByteString -> Either Text a
parseHeader (ByteString -> Either Text VersionNumber)
-> (Text -> ByteString) -> Text -> Either Text VersionNumber
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
Text.encodeUtf8

instance ToHttpApiData VersionNumber where
  toHeader :: VersionNumber -> ByteString
toHeader = ByteString -> ByteString
LBS.toStrict (ByteString -> ByteString)
-> (VersionNumber -> ByteString) -> VersionNumber -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VersionNumber -> ByteString
forall a. ToJSON a => a -> ByteString
Aeson.encode
  toUrlPiece :: VersionNumber -> Text
toUrlPiece = ByteString -> Text
Text.decodeUtf8 (ByteString -> Text)
-> (VersionNumber -> ByteString) -> VersionNumber -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VersionNumber -> ByteString
forall a. ToHttpApiData a => a -> ByteString
toHeader

instance ToByteString VersionNumber where
  builder :: VersionNumber -> Builder
builder = VersionNumber -> Builder
forall a. ToHttpApiData a => a -> Builder
toEncodedUrlPiece

-- | Information related to the public API version.
--
-- This record also contains whether federation is enabled and the federation
-- domain. Clients should fetch this information early when connecting to a
-- backend, in order to decide how to form request paths, and how to deal with
-- federated backends and qualified user IDs.
data VersionInfo = VersionInfo
  { VersionInfo -> [VersionNumber]
vinfoSupported :: [VersionNumber],
    VersionInfo -> [VersionNumber]
vinfoDevelopment :: [VersionNumber],
    VersionInfo -> Bool
vinfoFederation :: Bool,
    VersionInfo -> Domain
vinfoDomain :: Domain
  }
  deriving (Value -> Parser [VersionInfo]
Value -> Parser VersionInfo
(Value -> Parser VersionInfo)
-> (Value -> Parser [VersionInfo]) -> FromJSON VersionInfo
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
$cparseJSON :: Value -> Parser VersionInfo
parseJSON :: Value -> Parser VersionInfo
$cparseJSONList :: Value -> Parser [VersionInfo]
parseJSONList :: Value -> Parser [VersionInfo]
FromJSON, [VersionInfo] -> Value
[VersionInfo] -> Encoding
VersionInfo -> Value
VersionInfo -> Encoding
(VersionInfo -> Value)
-> (VersionInfo -> Encoding)
-> ([VersionInfo] -> Value)
-> ([VersionInfo] -> Encoding)
-> ToJSON VersionInfo
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
$ctoJSON :: VersionInfo -> Value
toJSON :: VersionInfo -> Value
$ctoEncoding :: VersionInfo -> Encoding
toEncoding :: VersionInfo -> Encoding
$ctoJSONList :: [VersionInfo] -> Value
toJSONList :: [VersionInfo] -> Value
$ctoEncodingList :: [VersionInfo] -> Encoding
toEncodingList :: [VersionInfo] -> Encoding
ToJSON, Typeable VersionInfo
Typeable VersionInfo =>
(Proxy VersionInfo -> Declare (Definitions Schema) NamedSchema)
-> ToSchema VersionInfo
Proxy VersionInfo -> Declare (Definitions Schema) NamedSchema
forall a.
Typeable a =>
(Proxy a -> Declare (Definitions Schema) NamedSchema) -> ToSchema a
$cdeclareNamedSchema :: Proxy VersionInfo -> Declare (Definitions Schema) NamedSchema
declareNamedSchema :: Proxy VersionInfo -> Declare (Definitions Schema) NamedSchema
S.ToSchema) via (Schema VersionInfo)

instance ToSchema VersionInfo where
  schema :: ValueSchema NamedSwaggerDoc VersionInfo
schema =
    Text
-> (NamedSwaggerDoc -> NamedSwaggerDoc)
-> ObjectSchema SwaggerDoc VersionInfo
-> ValueSchema NamedSwaggerDoc VersionInfo
forall doc doc' a.
HasObject doc doc' =>
Text -> (doc' -> doc') -> ObjectSchema doc a -> ValueSchema doc' a
objectWithDocModifier Text
"VersionInfo" ((Schema -> Identity Schema)
-> NamedSwaggerDoc -> Identity NamedSwaggerDoc
forall s a. HasSchema s a => Lens' s a
Lens' NamedSwaggerDoc Schema
S.schema ((Schema -> Identity Schema)
 -> NamedSwaggerDoc -> Identity NamedSwaggerDoc)
-> ((Maybe Value -> Identity (Maybe Value))
    -> Schema -> Identity Schema)
-> (Maybe Value -> Identity (Maybe Value))
-> NamedSwaggerDoc
-> Identity NamedSwaggerDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Value -> Identity (Maybe Value))
-> Schema -> Identity Schema
forall s a. HasExample s a => Lens' s a
Lens' Schema (Maybe Value)
S.example ((Maybe Value -> Identity (Maybe Value))
 -> NamedSwaggerDoc -> Identity NamedSwaggerDoc)
-> Value -> NamedSwaggerDoc -> NamedSwaggerDoc
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ VersionInfo -> Value
forall a. ToJSON a => a -> Value
toJSON VersionInfo
example) (ObjectSchema SwaggerDoc VersionInfo
 -> ValueSchema NamedSwaggerDoc VersionInfo)
-> ObjectSchema SwaggerDoc VersionInfo
-> ValueSchema NamedSwaggerDoc VersionInfo
forall a b. (a -> b) -> a -> b
$
      [VersionNumber] -> [VersionNumber] -> Bool -> Domain -> VersionInfo
VersionInfo
        ([VersionNumber]
 -> [VersionNumber] -> Bool -> Domain -> VersionInfo)
-> SchemaP SwaggerDoc Object [Pair] VersionInfo [VersionNumber]
-> SchemaP
     SwaggerDoc
     Object
     [Pair]
     VersionInfo
     ([VersionNumber] -> Bool -> Domain -> VersionInfo)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VersionInfo -> [VersionNumber]
vinfoSupported
          (VersionInfo -> [VersionNumber])
-> SchemaP SwaggerDoc Object [Pair] [VersionNumber] [VersionNumber]
-> SchemaP SwaggerDoc Object [Pair] VersionInfo [VersionNumber]
forall (p :: * -> * -> *) a a' b.
Profunctor p =>
(a -> a') -> p a' b -> p a b
.= ValueSchema NamedSwaggerDoc VersionNumber
-> SchemaP SwaggerDoc Object [Pair] [VersionNumber] [VersionNumber]
forall v.
ValueSchema NamedSwaggerDoc v -> ObjectSchema SwaggerDoc [v]
vinfoObjectSchema ValueSchema NamedSwaggerDoc VersionNumber
forall a. ToSchema a => ValueSchema NamedSwaggerDoc a
schema
        SchemaP
  SwaggerDoc
  Object
  [Pair]
  VersionInfo
  ([VersionNumber] -> Bool -> Domain -> VersionInfo)
-> SchemaP SwaggerDoc Object [Pair] VersionInfo [VersionNumber]
-> SchemaP
     SwaggerDoc
     Object
     [Pair]
     VersionInfo
     (Bool -> Domain -> VersionInfo)
forall a b.
SchemaP SwaggerDoc Object [Pair] VersionInfo (a -> b)
-> SchemaP SwaggerDoc Object [Pair] VersionInfo a
-> SchemaP SwaggerDoc Object [Pair] VersionInfo b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> VersionInfo -> [VersionNumber]
vinfoDevelopment (VersionInfo -> [VersionNumber])
-> SchemaP SwaggerDoc Object [Pair] [VersionNumber] [VersionNumber]
-> SchemaP SwaggerDoc Object [Pair] VersionInfo [VersionNumber]
forall (p :: * -> * -> *) a a' b.
Profunctor p =>
(a -> a') -> p a' b -> p a b
.= Text
-> SchemaP SwaggerDoc Value Value [VersionNumber] [VersionNumber]
-> SchemaP SwaggerDoc Object [Pair] [VersionNumber] [VersionNumber]
forall doc' doc a b.
HasField doc' doc =>
Text
-> SchemaP doc' Value Value a b -> SchemaP doc Object [Pair] a b
field Text
"development" (ValueSchema NamedSwaggerDoc VersionNumber
-> SchemaP SwaggerDoc Value Value [VersionNumber] [VersionNumber]
forall ndoc doc a.
(HasArray ndoc doc, HasName ndoc) =>
ValueSchema ndoc a -> ValueSchema doc [a]
array ValueSchema NamedSwaggerDoc VersionNumber
forall a. ToSchema a => ValueSchema NamedSwaggerDoc a
schema)
        SchemaP
  SwaggerDoc
  Object
  [Pair]
  VersionInfo
  (Bool -> Domain -> VersionInfo)
-> SchemaP SwaggerDoc Object [Pair] VersionInfo Bool
-> SchemaP
     SwaggerDoc Object [Pair] VersionInfo (Domain -> VersionInfo)
forall a b.
SchemaP SwaggerDoc Object [Pair] VersionInfo (a -> b)
-> SchemaP SwaggerDoc Object [Pair] VersionInfo a
-> SchemaP SwaggerDoc Object [Pair] VersionInfo b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> VersionInfo -> Bool
vinfoFederation (VersionInfo -> Bool)
-> SchemaP SwaggerDoc Object [Pair] Bool Bool
-> SchemaP SwaggerDoc Object [Pair] VersionInfo Bool
forall (p :: * -> * -> *) a a' b.
Profunctor p =>
(a -> a') -> p a' b -> p a b
.= Text
-> SchemaP NamedSwaggerDoc Value Value Bool Bool
-> SchemaP SwaggerDoc Object [Pair] Bool Bool
forall doc' doc a b.
HasField doc' doc =>
Text
-> SchemaP doc' Value Value a b -> SchemaP doc Object [Pair] a b
field Text
"federation" SchemaP NamedSwaggerDoc Value Value Bool Bool
forall a. ToSchema a => ValueSchema NamedSwaggerDoc a
schema
        SchemaP
  SwaggerDoc Object [Pair] VersionInfo (Domain -> VersionInfo)
-> SchemaP SwaggerDoc Object [Pair] VersionInfo Domain
-> ObjectSchema SwaggerDoc VersionInfo
forall a b.
SchemaP SwaggerDoc Object [Pair] VersionInfo (a -> b)
-> SchemaP SwaggerDoc Object [Pair] VersionInfo a
-> SchemaP SwaggerDoc Object [Pair] VersionInfo b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> VersionInfo -> Domain
vinfoDomain (VersionInfo -> Domain)
-> SchemaP SwaggerDoc Object [Pair] Domain Domain
-> SchemaP SwaggerDoc Object [Pair] VersionInfo Domain
forall (p :: * -> * -> *) a a' b.
Profunctor p =>
(a -> a') -> p a' b -> p a b
.= Text
-> SchemaP NamedSwaggerDoc Value Value Domain Domain
-> SchemaP SwaggerDoc Object [Pair] Domain Domain
forall doc' doc a b.
HasField doc' doc =>
Text
-> SchemaP doc' Value Value a b -> SchemaP doc Object [Pair] a b
field Text
"domain" SchemaP NamedSwaggerDoc Value Value Domain Domain
forall a. ToSchema a => ValueSchema NamedSwaggerDoc a
schema
    where
      example :: VersionInfo
      example :: VersionInfo
example =
        VersionInfo
          { $sel:vinfoSupported:VersionInfo :: [VersionNumber]
vinfoSupported = Version -> VersionNumber
VersionNumber (Version -> VersionNumber) -> [Version] -> [VersionNumber]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Version]
supportedVersions,
            $sel:vinfoDevelopment:VersionInfo :: [VersionNumber]
vinfoDevelopment = [VersionNumber
forall a. Bounded a => a
maxBound],
            $sel:vinfoFederation:VersionInfo :: Bool
vinfoFederation = Bool
False,
            $sel:vinfoDomain:VersionInfo :: Domain
vinfoDomain = Text -> Domain
Domain Text
"example.com"
          }

type VersionAPI =
  Named
    "get-version"
    ( "api-version"
        :> Get '[JSON] VersionInfo
    )

data VersionAPITag

-- Development versions

$(genSingletons [''Version])

isDevelopmentVersion :: Version -> Bool
isDevelopmentVersion :: Version -> Bool
isDevelopmentVersion Version
V0 = Bool
False
isDevelopmentVersion Version
V1 = Bool
False
isDevelopmentVersion Version
V2 = Bool
False
isDevelopmentVersion Version
V3 = Bool
False
isDevelopmentVersion Version
V4 = Bool
False
isDevelopmentVersion Version
V5 = Bool
False
isDevelopmentVersion Version
V6 = Bool
False
isDevelopmentVersion Version
_ = Bool
True

developmentVersions :: [Version]
developmentVersions :: [Version]
developmentVersions = (Version -> Bool) -> [Version] -> [Version]
forall a. (a -> Bool) -> [a] -> [a]
filter Version -> Bool
isDevelopmentVersion [Version]
supportedVersions

-- Version keywords

-- | A version "expression" which can be used when disabling versions in a
-- configuration file.
data VersionExp
  = -- | A fixed version.
    VersionExpConst Version
  | -- | All development versions.
    VersionExpDevelopment
  deriving (Int -> VersionExp -> ShowS
[VersionExp] -> ShowS
VersionExp -> [Char]
(Int -> VersionExp -> ShowS)
-> (VersionExp -> [Char])
-> ([VersionExp] -> ShowS)
-> Show VersionExp
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> VersionExp -> ShowS
showsPrec :: Int -> VersionExp -> ShowS
$cshow :: VersionExp -> [Char]
show :: VersionExp -> [Char]
$cshowList :: [VersionExp] -> ShowS
showList :: [VersionExp] -> ShowS
Show, VersionExp -> VersionExp -> Bool
(VersionExp -> VersionExp -> Bool)
-> (VersionExp -> VersionExp -> Bool) -> Eq VersionExp
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: VersionExp -> VersionExp -> Bool
== :: VersionExp -> VersionExp -> Bool
$c/= :: VersionExp -> VersionExp -> Bool
/= :: VersionExp -> VersionExp -> Bool
Eq, Eq VersionExp
Eq VersionExp =>
(VersionExp -> VersionExp -> Ordering)
-> (VersionExp -> VersionExp -> Bool)
-> (VersionExp -> VersionExp -> Bool)
-> (VersionExp -> VersionExp -> Bool)
-> (VersionExp -> VersionExp -> Bool)
-> (VersionExp -> VersionExp -> VersionExp)
-> (VersionExp -> VersionExp -> VersionExp)
-> Ord VersionExp
VersionExp -> VersionExp -> Bool
VersionExp -> VersionExp -> Ordering
VersionExp -> VersionExp -> VersionExp
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: VersionExp -> VersionExp -> Ordering
compare :: VersionExp -> VersionExp -> Ordering
$c< :: VersionExp -> VersionExp -> Bool
< :: VersionExp -> VersionExp -> Bool
$c<= :: VersionExp -> VersionExp -> Bool
<= :: VersionExp -> VersionExp -> Bool
$c> :: VersionExp -> VersionExp -> Bool
> :: VersionExp -> VersionExp -> Bool
$c>= :: VersionExp -> VersionExp -> Bool
>= :: VersionExp -> VersionExp -> Bool
$cmax :: VersionExp -> VersionExp -> VersionExp
max :: VersionExp -> VersionExp -> VersionExp
$cmin :: VersionExp -> VersionExp -> VersionExp
min :: VersionExp -> VersionExp -> VersionExp
Ord, (forall x. VersionExp -> Rep VersionExp x)
-> (forall x. Rep VersionExp x -> VersionExp) -> Generic VersionExp
forall x. Rep VersionExp x -> VersionExp
forall x. VersionExp -> Rep VersionExp x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. VersionExp -> Rep VersionExp x
from :: forall x. VersionExp -> Rep VersionExp x
$cto :: forall x. Rep VersionExp x -> VersionExp
to :: forall x. Rep VersionExp x -> VersionExp
Generic)

$(makePrisms ''VersionExp)

instance ToSchema VersionExp where
  schema :: ValueSchema NamedSwaggerDoc VersionExp
schema =
    Text
-> SchemaP SwaggerDoc Value Value VersionExp VersionExp
-> ValueSchema NamedSwaggerDoc VersionExp
forall doc doc' v m a b.
HasObject doc doc' =>
Text -> SchemaP doc v m a b -> SchemaP doc' v m a b
named Text
"VersionExp" (SchemaP SwaggerDoc Value Value VersionExp VersionExp
 -> ValueSchema NamedSwaggerDoc VersionExp)
-> SchemaP SwaggerDoc Value Value VersionExp VersionExp
-> ValueSchema NamedSwaggerDoc VersionExp
forall a b. (a -> b) -> a -> b
$
      Prism' VersionExp Version
-> SchemaP SwaggerDoc Value Value Version Version
-> SchemaP SwaggerDoc Value Value VersionExp VersionExp
forall b b' a a' ss v m.
Prism b b' a a' -> SchemaP ss v m a a' -> SchemaP ss v m b b'
tag p Version (f Version) -> p VersionExp (f VersionExp)
Prism' VersionExp Version
_VersionExpConst (ValueSchema NamedSwaggerDoc Version
-> SchemaP SwaggerDoc Value Value Version Version
forall doc doc' v m a b.
HasObject doc doc' =>
SchemaP doc' v m a b -> SchemaP doc v m a b
unnamed ValueSchema NamedSwaggerDoc Version
forall a. ToSchema a => ValueSchema NamedSwaggerDoc a
schema)
        SchemaP SwaggerDoc Value Value VersionExp VersionExp
-> SchemaP SwaggerDoc Value Value VersionExp VersionExp
-> SchemaP SwaggerDoc Value Value VersionExp VersionExp
forall a. Semigroup a => a -> a -> a
<> Prism' VersionExp ()
-> SchemaP SwaggerDoc Value Value () ()
-> SchemaP SwaggerDoc Value Value VersionExp VersionExp
forall b b' a a' ss v m.
Prism b b' a a' -> SchemaP ss v m a a' -> SchemaP ss v m b b'
tag
          p () (f ()) -> p VersionExp (f VersionExp)
Prism' VersionExp ()
_VersionExpDevelopment
          ( SchemaP NamedSwaggerDoc Value Value () ()
-> SchemaP SwaggerDoc Value Value () ()
forall doc doc' v m a b.
HasObject doc doc' =>
SchemaP doc' v m a b -> SchemaP doc v m a b
unnamed
              ( forall v doc a b.
(With v, HasEnum v doc) =>
Text
-> SchemaP [Value] v (Alt Maybe v) a b
-> SchemaP doc Value Value a b
enum @Text Text
"VersionExpDevelopment" (Text -> () -> SchemaP [Value] Text (Alt Maybe Text) () ()
forall a b.
(ToJSON a, Eq a, Eq b) =>
a -> b -> SchemaP [Value] a (Alt Maybe a) b b
element Text
"development" ())
              )
          )

deriving via Schema VersionExp instance (FromJSON VersionExp)

deriving via Schema VersionExp instance (ToJSON VersionExp)

-- | Expand a version expression into a set of versions.
expandVersionExp :: VersionExp -> Set Version
expandVersionExp :: VersionExp -> Set Version
expandVersionExp (VersionExpConst Version
v) = Version -> Set Version
forall a. a -> Set a
Set.singleton Version
v
expandVersionExp VersionExp
VersionExpDevelopment = [Version] -> Set Version
forall a. Ord a => [a] -> Set a
Set.fromList [Version]
developmentVersions

-- Version-aware swagger generation

$(promoteOrdInstances [''Version])

type family SpecialiseToVersion (v :: Version) api

type instance
  SpecialiseToVersion v (From w :> api) =
    If (v < w) EmptyAPI (SpecialiseToVersion v api)

type instance
  SpecialiseToVersion v (Until w :> api) =
    If (v < w) (SpecialiseToVersion v api) EmptyAPI

type instance
  SpecialiseToVersion v ((s :: Symbol) :> api) =
    s :> SpecialiseToVersion v api

type instance
  SpecialiseToVersion v (Named n api) =
    Named n (SpecialiseToVersion v api)

type instance
  SpecialiseToVersion v (Capture' mod sym a :> api) =
    Capture' mod sym a :> SpecialiseToVersion v api

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

type instance
  SpecialiseToVersion v (MultiVerb m t r x) =
    MultiVerb m t r x

type instance SpecialiseToVersion v RawM.RawM = RawM.RawM

type instance
  SpecialiseToVersion v (ReqBody t x :> api) =
    ReqBody t x :> SpecialiseToVersion v api

type instance
  SpecialiseToVersion v (QueryParam' mods l x :> api) =
    QueryParam' mods l x :> SpecialiseToVersion v api

type instance
  SpecialiseToVersion v (Header' opts l x :> api) =
    Header' opts l x :> SpecialiseToVersion v api

type instance
  SpecialiseToVersion v (Description desc :> api) =
    Description desc :> SpecialiseToVersion v api

type instance
  SpecialiseToVersion v (StreamBody' opts f t x :> api) =
    StreamBody' opts f t x :> SpecialiseToVersion v api

type instance SpecialiseToVersion v EmptyAPI = EmptyAPI

type instance
  SpecialiseToVersion v (api1 :<|> api2) =
    SpecialiseToVersion v api1 :<|> SpecialiseToVersion v api2