twitchapi 0.0.2 → 0.0.3
raw patch · 6 files changed
+215/−127 lines, 6 files
Files
- CHANGELOG.md +8/−0
- src/Web/TwitchAPI/Helix/Bits.hs +13/−15
- src/Web/TwitchAPI/Helix/ChannelPoints.hs +59/−36
- src/Web/TwitchAPI/Helix/Request.hs +0/−2
- src/Web/TwitchAPI/Helix/Users.hs +134/−73
- twitchapi.cabal +1/−1
CHANGELOG.md view
@@ -1,5 +1,13 @@ # Revision history for twitchapi +## 0.0.3 -- 2022-11-09++* Restructured Helix API to remove DuplicateRecordFields dependency++## 0.0.2 -- 2022-10-10++* Implemented support for Helix (User - partial)+ ## 0.0.1 -- 2022-09-27 * Implemented support for Helix (Bits, Channel Points)
src/Web/TwitchAPI/Helix/Bits.hs view
@@ -1,7 +1,6 @@-{-# LANGUAGE DuplicateRecordFields #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-} module Web.TwitchAPI.Helix.Bits where @@ -14,17 +13,16 @@ import qualified Data.Text.Encoding as Text ( encodeUtf8 ) import qualified Network.HTTP.Client as HTTP -import Data.Maybe ( fromMaybe ) import Data.Aeson ( FromJSON(..), (.:), withObject , Object ) import qualified Web.TwitchAPI.Helix.Request as Req -data Leaderboard = Leaderboard { count :: Maybe Integer- , period :: Maybe Period- , startedAt :: Maybe Time.UTCTime- , userId :: Maybe Integer+data Leaderboard = Leaderboard { count :: Maybe Integer+ , period :: Maybe Period+ , start :: Maybe Time.UTCTime+ , searchId :: Maybe Integer } deriving ( Show, Eq ) data Period = Day | Week | Month | Year | All deriving ( Eq )@@ -37,11 +35,11 @@ instance Req.HelixRequest Leaderboard where toRequest leaderboard =- let count' :: [(BS.ByteString, Maybe BS.ByteString)] = fromMaybe [] $ (\c -> ("count", Just . BS.pack . show $ c):[]) <$> (count leaderboard)- period' :: [(BS.ByteString, Maybe BS.ByteString)] = fromMaybe [] $ (\p -> ("period", Just . BS.pack . show $ p):[]) <$> (period leaderboard)- startedAt' :: [(BS.ByteString, Maybe BS.ByteString)] = fromMaybe [] $ (\s -> ("started_at", Just . Text.encodeUtf8 $ (Time.formatTimeRFC3339 $ Time.utcToZonedTime Time.utc s :: Text.Text)):[]) <$> ((startedAt :: Leaderboard -> Maybe Time.UTCTime) leaderboard)- userId' :: [(BS.ByteString, Maybe BS.ByteString)] = fromMaybe [] $ (\u -> ("user_id", Just . Text.encodeUtf8 . Text.pack . show $ u):[]) <$> ((userId :: Leaderboard -> Maybe Integer) leaderboard)- setQuery = HTTP.setQueryString $ foldl (++) [] [count', period', startedAt', userId']+ let count' :: [(BS.ByteString, Maybe BS.ByteString)] = maybe [] (\c -> [("count", Just . BS.pack . show $ c)]) (count leaderboard)+ period' :: [(BS.ByteString, Maybe BS.ByteString)] = maybe [] (\p -> [("period", Just . BS.pack . show $ p)]) (period leaderboard)+ start' :: [(BS.ByteString, Maybe BS.ByteString)] = maybe [] (\s -> [("started_at", Just . Text.encodeUtf8 $ (Time.formatTimeRFC3339 $ Time.utcToZonedTime Time.utc s :: Text.Text))]) (start leaderboard)+ searchId' :: [(BS.ByteString, Maybe BS.ByteString)] = maybe [] (\u -> [("user_id", Just . Text.encodeUtf8 . Text.pack . show $ u)]) (searchId leaderboard)+ setQuery = HTTP.setQueryString $ concat [count', period', start', searchId'] in setQuery $ HTTP.parseRequest_ "GET https://api.twitch.tv/helix/bits/leaderboard" scope Leaderboard{} = Just "bits:read" @@ -79,7 +77,7 @@ startedAt = Time.zonedTimeToUTC <$> Time.parseTimeRFC3339 started return LeaderboardResponse{..} -data Cheermotes = Cheermotes { broadcasterId :: Integer } deriving ( Show, Eq )+newtype Cheermotes = Cheermotes { broadcasterId :: Integer } deriving ( Show, Eq ) instance Req.HelixRequest Cheermotes where toRequest c =
src/Web/TwitchAPI/Helix/ChannelPoints.hs view
@@ -1,7 +1,6 @@-{-# LANGUAGE DuplicateRecordFields #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-} module Web.TwitchAPI.Helix.ChannelPoints where @@ -21,33 +20,41 @@ import qualified Web.TwitchAPI.Helix.Request as Req -data Create = Create { broadcasterId :: Integer+class RewardDetails a where+ broadcasterId :: a -> Integer+ prompt :: a -> Maybe String+ backgroundColor :: a -> String+ maxPerStream :: a -> Maybe Integer+ maxPerUser :: a -> Maybe Integer+ autoFulfilled :: a -> Bool++data Create = Create { forBroadcasterId :: Integer , title :: String- , prompt :: Maybe String+ , setPrompt :: Maybe String , cost :: Integer , enabled :: Maybe Bool- , backgroundColor :: Maybe String- , maxPerStream :: Maybe Integer- , maxPerUser :: Maybe Integer+ , setBackgroundColor :: Maybe String+ , setMaxPerStream :: Maybe Integer+ , setMaxPerUser :: Maybe Integer , cooldownSeconds :: Maybe Integer- , autoFulfilled :: Maybe Bool+ , setAutoFulfilled :: Maybe Bool } deriving ( Show, Eq ) instance ToJSON Create where toJSON Create{..} =- object [ "title" .= (Text.pack title)- , "prompt" .= (Text.pack <$> prompt)+ object [ "title" .= Text.pack title+ , "prompt" .= (Text.pack <$> setPrompt) , "cost" .= cost- , "is_enabled" .= (fromMaybe True enabled)- , "background_color" .= (Text.pack <$> backgroundColor)- , "is_user_input_required" .= (fmap (const True) prompt)- , "is_max_per_stream_enabled" .= (fmap (const True) maxPerStream)- , "max_per_stream" .= maxPerStream- , "is_max_per_user_per_stream_enabled" .= (fmap (const True) maxPerUser)- , "max_per_user_per_stream" .= maxPerUser- , "is_global_cooldown_enabled" .= (fmap (const True) cooldownSeconds)+ , "is_enabled" .= fromMaybe True enabled+ , "background_color" .= (Text.pack <$> setBackgroundColor)+ , "is_user_input_required" .= fmap (const True) setPrompt+ , "is_max_per_stream_enabled" .= fmap (const True) setMaxPerStream+ , "max_per_stream" .= setMaxPerStream+ , "is_max_per_user_per_stream_enabled" .= fmap (const True) setMaxPerUser+ , "max_per_user_per_stream" .= setMaxPerUser+ , "is_global_cooldown_enabled" .= fmap (const True) cooldownSeconds , "global_cooldown_seconds" .= cooldownSeconds- , "should_redemptions_skip_request_queue" .= autoFulfilled+ , "should_redemptions_skip_request_queue" .= setAutoFulfilled ] instance Req.HelixRequest Create where@@ -57,6 +64,14 @@ in setBody . setQuery $ HTTP.parseRequest_ "POST https://api.twitch.tv/helix/channel_points/custom_rewards" scope Create{} = Just "channel:manage:redemptions" +instance RewardDetails Create where+ broadcasterId = forBroadcasterId+ prompt = setPrompt+ backgroundColor = fromMaybe "" . setBackgroundColor+ maxPerStream = setMaxPerStream+ maxPerUser = setMaxPerUser+ autoFulfilled = fromMaybe False . setAutoFulfilled+ data RewardImages = RewardImages { tiny :: Maybe String , large :: Maybe String , huge :: Maybe String@@ -69,22 +84,22 @@ huge <- o .: "url_4x" return RewardImages{..} -data CreateResponse = CreateResponse { broadcasterId :: Integer+data CreateResponse = CreateResponse { broadcaster :: Integer , broadcasterLogin :: String , broadcasterName :: String , rewardId :: String , rewardTitle :: String- , prompt :: Maybe String+ , rewardPrompt :: Maybe String , rewardCost :: Integer , rewardImage :: Maybe RewardImages , defaultImage :: RewardImages- , backgroundColor :: String- , maxPerStream :: Maybe Integer- , maxPerUser :: Maybe Integer- , cooldownSeconds :: Maybe Integer+ , rewardBackgroundColor :: String+ , rewardMaxPerStream :: Maybe Integer+ , rewardMaxPerUser :: Maybe Integer+ , cooldown :: Maybe Integer , paused :: Bool , inStock :: Bool- , autoFulfilled :: Bool+ , rewardAutoFulfilled :: Bool , redemptionCount :: Integer , cooldownExpires :: Maybe Time.UTCTime } deriving ( Show, Eq )@@ -92,7 +107,7 @@ instance FromJSON CreateResponse where parseJSON = withObject "CreateResponse" $ \o -> do bid <- o .: "broadcaster_id"- let broadcasterId = read bid :: Integer+ let broadcaster = read bid :: Integer broadcasterLogin <- o .: "broadcaster_login" broadcasterName <- o .: "broadcaster_name" rewardId <- o .: "id"@@ -100,32 +115,40 @@ promptText <- o .: "prompt" promptEnabled :: Bool <- o .: "is_user_input_required"- let prompt = if promptEnabled then Just promptText else Nothing+ let rewardPrompt = if promptEnabled then Just promptText else Nothing rewardCost <- o .: "cost" rewardImage <- o .: "image" defaultImage <- o .: "default_image"- backgroundColor <- o .: "background_color"+ rewardBackgroundColor <- o .: "background_color" maxObject :: Object <- o .: "max_per_stream_setting" maxEnabled <- maxObject .: "is_enabled" streamMax <- maxObject .: "max_per_stream"- let maxPerStream = if maxEnabled then Just streamMax else Nothing+ let rewardMaxPerStream = if maxEnabled then Just streamMax else Nothing userMaxObject :: Object <- o .: "max_per_user_per_stream_setting" userMaxEnabled <- userMaxObject .: "is_enabled" userMax <- userMaxObject .: "max_per_user_per_stream"- let maxPerUser = if userMaxEnabled then Just userMax else Nothing+ let rewardMaxPerUser = if userMaxEnabled then Just userMax else Nothing cooldownObject :: Object <- o .: "global_cooldown_setting" cooldownEnabled <- cooldownObject .: "is_enabled"- cooldown <- cooldownObject .: "global_cooldown_seconds"- let cooldownSeconds = if cooldownEnabled then Just cooldown else Nothing+ cooldownSeconds <- cooldownObject .: "global_cooldown_seconds"+ let cooldown = if cooldownEnabled then Just cooldownSeconds else Nothing paused <- o .: "is_paused" inStock <- o .: "is_in_stock"- autoFulfilled <- o .: "should_redemptions_skip_request_queue"+ rewardAutoFulfilled <- o .: "should_redemptions_skip_request_queue" redemptionCount <- o .: "redemptions_redeemed_current_stream" cooldownExpiry :: Maybe String <- o .: "cooldown_expires_at" let cooldownExpires = Time.zonedTimeToUTC <$> (Time.parseTimeRFC3339 =<< cooldownExpiry) return CreateResponse{..}++instance RewardDetails CreateResponse where+ broadcasterId = broadcaster+ prompt = rewardPrompt+ backgroundColor = rewardBackgroundColor+ maxPerStream = rewardMaxPerStream+ maxPerUser = rewardMaxPerUser+ autoFulfilled = rewardAutoFulfilled
src/Web/TwitchAPI/Helix/Request.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE DuplicateRecordFields #-}- module Web.TwitchAPI.Helix.Request where import Prelude
src/Web/TwitchAPI/Helix/Users.hs view
@@ -1,7 +1,6 @@-{-# LANGUAGE DuplicateRecordFields #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-} module Web.TwitchAPI.Helix.Users where @@ -24,15 +23,33 @@ -- - Block/Unblock User -- - Update User Extensions -data User = User { lookupID :: Maybe String+class DisplayName a where+ displayName :: a -> String++class ExtensionId a where+ extensionId :: a -> String++class IsActive a where+ active :: a -> Bool++class Named a where+ name :: a -> String++class UserId a where+ userId :: a -> Integer++class Versioned a where+ version :: a -> String++data User = User { lookupId :: Maybe String , username :: Maybe String } deriving ( Show ) instance Req.HelixRequest User where toRequest user =- let lookupID' :: [(BS.ByteString, Maybe BS.ByteString)] = maybe [] (\i -> [("id", Just . BS.pack . show $ i)]) (lookupID user)+ let lookupId' :: [(BS.ByteString, Maybe BS.ByteString)] = maybe [] (\i -> [("id", Just . BS.pack . show $ i)]) (lookupId user) username' :: [(BS.ByteString, Maybe BS.ByteString)] = maybe [] (\u -> [("login", Just . BS.pack $ u)]) (username user)- setQuery = HTTP.setQueryString $ lookupID' ++ username'+ setQuery = HTTP.setQueryString $ lookupId' ++ username' in setQuery $ HTTP.parseRequest_ "GET https://api.twitch.tv/helix/users" scope User{} = Just "user:read:email" @@ -53,8 +70,8 @@ data UserEntry = UserEntry { broadcasterType :: BroadcasterType , description :: String- , displayName :: String- , userId :: Integer+ , userDisplayName :: String+ , userEntryId :: Integer , login :: String , offlineImageURL :: String , profileImageURL :: String@@ -69,28 +86,34 @@ created :: String <- o .: "created_at" userType' :: String <- o .: "type" broadcasterType' :: String <- o .: "broadcaster_type"- let userId = read userId' :: Integer+ let userEntryId = read userId' :: Integer createdAt = Time.zonedTimeToUTC <$> Time.parseTimeRFC3339 created userType = read userType' :: UserType broadcasterType = read broadcasterType' :: BroadcasterType description <- o .: "description"- displayName <- o .: "display_name"+ userDisplayName <- o .: "display_name" login <- o .: "login" offlineImageURL <- o .: "offline_image_url" profileImageURL <- o .: "profile_image_url" email <- o .: "email" return UserEntry{..} -data Users = Users { lookupIDs :: [Integer]+instance DisplayName UserEntry where+ displayName = userDisplayName++instance UserId UserEntry where+ userId = userEntryId++data Users = Users { lookupIds :: [Integer] , usernames :: [String] } deriving ( Show, Eq ) instance Req.HelixRequest Users where toRequest users =- let lookupID' :: [(BS.ByteString, Maybe BS.ByteString)] = (\i -> ("id", Just . BS.pack . show $ i)) <$> lookupIDs users+ let lookupId' :: [(BS.ByteString, Maybe BS.ByteString)] = (\i -> ("id", Just . BS.pack . show $ i)) <$> lookupIds users username' :: [(BS.ByteString, Maybe BS.ByteString)] = (\u -> ("login", Just . BS.pack $ u)) <$> usernames users- setQuery = HTTP.setQueryString $ lookupID' ++ username'+ setQuery = HTTP.setQueryString $ lookupId' ++ username' in setQuery $ HTTP.parseRequest_ "GET https://api.twitch.tv/helix/users" scope Users{} = Nothing @@ -111,27 +134,27 @@ toRequest user = let after' :: [(BS.ByteString, Maybe BS.ByteString)] = maybe [] (\a -> [("after", Just . BS.pack $ a)]) (after user) max' :: [(BS.ByteString, Maybe BS.ByteString)] = maybe [] (\u -> [("first", Just . BS.pack . show $ u)]) (from user)- fromID' :: [(BS.ByteString, Maybe BS.ByteString)] = maybe [] (\u -> [("after", Just . BS.pack . show $ u)]) (from user)- toID' :: [(BS.ByteString, Maybe BS.ByteString)] = maybe [] (\u -> [("after", Just . BS.pack . show $ u)]) (to user)- setQuery = HTTP.setQueryString $ concat [after', max', fromID', toID']+ fromId' :: [(BS.ByteString, Maybe BS.ByteString)] = maybe [] (\u -> [("after", Just . BS.pack . show $ u)]) (from user)+ toId' :: [(BS.ByteString, Maybe BS.ByteString)] = maybe [] (\u -> [("after", Just . BS.pack . show $ u)]) (to user)+ setQuery = HTTP.setQueryString $ concat [after', max', fromId', toId'] in setQuery $ HTTP.parseRequest_ "GET https://api.twitch.tv/helix/users/follows" scope Follows{} = Nothing -data FollowEntry = FollowEntry { fromID :: Integer+data FollowEntry = FollowEntry { fromId :: Integer , fromLogin :: String , fromName :: String- , toID :: Integer+ , toId :: Integer , toName :: String , followedAt :: Maybe Time.UTCTime } deriving ( Show, Eq ) instance FromJSON FollowEntry where parseJSON = withObject "FollowEntry" $ \o -> do- fromID' :: String <- o .: "from_id"- toID' :: String <- o .: "to_id"+ fromId' :: String <- o .: "from_id"+ toId' :: String <- o .: "to_id" followedAt' :: String <- o .: "followed_at"- let fromID = read fromID' :: Integer- toID = read toID' :: Integer+ let fromId = read fromId' :: Integer+ toId = read toId' :: Integer followedAt = Time.zonedTimeToUTC <$> Time.parseTimeRFC3339 followedAt' fromLogin <- o .: "from_login" fromName <- o .: "from_name"@@ -139,7 +162,7 @@ return FollowEntry{..} data FollowsResponse = FollowsResponse { total :: Integer- , users :: [FollowEntry]+ , follows :: [FollowEntry] , paginationCursor :: String } deriving ( Show, Eq ) @@ -147,30 +170,36 @@ parseJSON = withObject "FollowsResponse" $ \o -> do total <- o .: "total" paginationCursor <- (o .: "pagination") >>= (.: "cursor")- users <- o .: "data"+ follows <- o .: "data" return FollowsResponse{..} -newtype BlockList = BlockList { broadcasterID :: Integer } deriving ( Show, Eq )+newtype BlockList = BlockList { broadcasterId :: Integer } deriving ( Show, Eq ) instance Req.HelixRequest BlockList where toRequest user =- HTTP.setQueryString [("login", Just . BS.pack . show . broadcasterID $ user)] $+ HTTP.setQueryString [("login", Just . BS.pack . show . broadcasterId $ user)] $ HTTP.parseRequest_ "https://api.twitch.tv/helix/users/blocks" scope BlockList{} = Just "user:read:blocked_users" -data BlockListEntry = BlockListEntry { userId :: Integer+data BlockListEntry = BlockListEntry { blockedUserId :: Integer , userLogin :: String- , displayName :: String+ , blockedDisplayName :: String } deriving ( Show, Eq ) instance FromJSON BlockListEntry where parseJSON = withObject "BlockListEntry" $ \o -> do userId' :: String <- o .: "user_id"- let userId = read userId' :: Integer+ let blockedUserId = read userId' :: Integer userLogin <- o .: "user_login"- displayName <- o .: "display_name"+ blockedDisplayName <- o .: "display_name" return BlockListEntry{..} +instance DisplayName BlockListEntry where+ displayName = blockedDisplayName++instance UserId BlockListEntry where+ userId = blockedUserId+ newtype BlockListResponse = BlockListResponse { blocks :: [BlockListEntry] } deriving ( Show, Eq ) instance FromJSON BlockListResponse where@@ -194,20 +223,26 @@ readsPrec _ _ = mempty data ExtensionsEntry = ExtensionsEntry { canActivate :: Bool- , extensionId :: String- , name :: String+ , extensionEntryId :: String+ , extensionName :: String , extensionTypes :: [ExtensionType]- , version :: String+ , extensionVersion :: String } deriving ( Show, Eq ) +instance ExtensionId ExtensionsEntry where+ extensionId = extensionEntryId++instance Versioned ExtensionsEntry where+ version = extensionVersion+ instance FromJSON ExtensionsEntry where parseJSON = withObject "ExtensionsEntry" $ \o -> do extensionTypes' :: [String] <- o .: "type" let extensionTypes :: [ExtensionType] = read <$> extensionTypes' canActivate <- o .: "can_activate"- extensionId <- o .: "id"- name <- o .: "name"- version <- o .: "version"+ extensionEntryId <- o .: "id"+ extensionName <- o .: "name"+ extensionVersion <- o .: "version" return ExtensionsEntry{..} newtype ExtensionsResponse = ExtensionsResponse { extensions :: [ExtensionsEntry] } deriving ( Show, Eq )@@ -217,44 +252,58 @@ extensions <- o .: "data" return ExtensionsResponse{..} -newtype ActiveExtensions = ActiveExtensions { userID :: Maybe Integer } deriving ( Show, Eq )+data ActiveExtensions = ActiveExtensions+ | ActiveExtensionsFor Integer deriving ( Show, Eq ) instance Req.HelixRequest ActiveExtensions where- toRequest user =- let userID' :: [(BS.ByteString, Maybe BS.ByteString)] = maybe [] (\i -> [("user_id", Just . BS.pack . show $ i)]) (userID user)- setQuery = HTTP.setQueryString userID'+ toRequest (ActiveExtensionsFor i) =+ let setQuery = HTTP.setQueryString [("user_id", Just . BS.pack . show $ i)] in setQuery $ HTTP.parseRequest_ "GET https://api.twitch.tv/helix/users/extensions"- scope ActiveExtensions{} = Nothing+ toRequest ActiveExtensions = HTTP.parseRequest_ "GET https://api.twitch.tv/helix/users/extensions"+ scope ActiveExtensions = Nothing+ scope (ActiveExtensionsFor _) = Nothing -data ActiveComponentExtensionEntry' = ActiveComponentExtensionEntry' { active :: Bool- , extensionId :: String- , version :: String- , name :: String- , x :: Integer- , y :: Integer+data ActiveComponentExtensionEntry' = ActiveComponentExtensionEntry' { activeComponentActive' :: Bool+ , activeComponentExtensionId' :: String+ , activeComponentVersion' :: String+ , activeComponentName' :: String+ , activeComponentX :: Integer+ , activeComponentY :: Integer } | InactiveComponentExtension deriving ( Show, Eq ) instance FromJSON ActiveComponentExtensionEntry' where parseJSON = withObject "ActiveExtensionEntry" $ \o -> do- active <- o .: "active"- if active then do- extensionId <- o .: "id"- version <- o .: "version"- name <- o .: "name"- x <- o .: "x"- y <- o .: "y"+ activeComponentActive' <- o .: "active"+ if activeComponentActive' then do+ activeComponentExtensionId' <- o .: "id"+ activeComponentVersion' <- o .: "version"+ activeComponentName' <- o .: "name"+ activeComponentX <- o .: "x"+ activeComponentY <- o .: "y" return ActiveComponentExtensionEntry'{..} else return InactiveComponentExtension -data ActiveComponentExtensionEntry = ActiveComponentExtensionEntry { active :: Bool- , extensionId :: String- , version :: String- , name :: String+data ActiveComponentExtensionEntry = ActiveComponentExtensionEntry { activeComponentExtensionActive :: Bool+ , activeComponentExtensionId :: String+ , activeComponentExtensionVersion :: String+ , activeComponentExtensionName :: String , x :: Integer , y :: Integer } deriving ( Show, Eq ) +instance ExtensionId ActiveComponentExtensionEntry where+ extensionId = activeComponentExtensionId++instance IsActive ActiveComponentExtensionEntry where+ active = activeComponentExtensionActive++instance Named ActiveComponentExtensionEntry where+ name = activeComponentExtensionName++instance Versioned ActiveComponentExtensionEntry where+ version = activeComponentExtensionVersion+ filterActiveComponentExtensions :: [ActiveComponentExtensionEntry'] -> [ActiveComponentExtensionEntry] filterActiveComponentExtensions = reverse . foldl filterActiveComponentExtensions' [] @@ -262,28 +311,40 @@ filterActiveComponentExtensions' as InactiveComponentExtension = as filterActiveComponentExtensions' as (ActiveComponentExtensionEntry' _ i v n x y) = ActiveComponentExtensionEntry True i v n x y : as -data ActiveExtensionEntry' = ActiveExtensionEntry' { active :: Bool- , extensionId :: String- , version :: String- , name :: String- } +data ActiveExtensionEntry' = ActiveExtensionEntry' { activeExtensionActive' :: Bool+ , activeExtensionExtensionId' :: String+ , activeExtensionVersion' :: String+ , activeExtensionName' :: String+ } | InactiveExtension deriving ( Show, Eq ) instance FromJSON ActiveExtensionEntry' where parseJSON = withObject "ActiveExtensionEntry" $ \o -> do- active <- o .: "active"- if active then do- extensionId <- o .: "id"- version <- o .: "version"- name <- o .: "name"+ activeExtensionActive' <- o .: "active"+ if activeExtensionActive' then do+ activeExtensionExtensionId' <- o .: "id"+ activeExtensionVersion' <- o .: "version"+ activeExtensionName' <- o .: "name" return ActiveExtensionEntry'{..} else return InactiveExtension -data ActiveExtensionEntry = ActiveExtensionEntry { active :: Bool- , extensionId :: String- , version :: String- , name :: String+data ActiveExtensionEntry = ActiveExtensionEntry { activeExtensionActive :: Bool+ , activeExtensionId :: String+ , activeExtensionVersion :: String+ , activeExtensionName :: String } deriving ( Show, Eq )++instance IsActive ActiveExtensionEntry where+ active = activeExtensionActive++instance ExtensionId ActiveExtensionEntry where+ extensionId = activeExtensionId++instance Versioned ActiveExtensionEntry where+ version = activeExtensionVersion++instance Named ActiveExtensionEntry where+ name = activeExtensionName filterActiveExtensions :: [ActiveExtensionEntry'] -> [ActiveExtensionEntry] filterActiveExtensions = reverse . foldl filterActiveExtensions' []
twitchapi.cabal view
@@ -1,5 +1,5 @@ name: twitchapi-version: 0.0.2+version: 0.0.3 synopsis: Client access to Twitch.tv API endpoints description: Twitch.tv API client supporting Helix and PubSub homepage: https://github.com/wuest/haskell-twitchapi