packages feed

fb 0.12.9 → 0.13

raw patch · 12 files changed

+96/−78 lines, 12 filesdep −bytestring-lexingPVP ok

version bump matches the API change (PVP)

Dependencies removed: bytestring-lexing

API changes (from Hackage documentation)

- Facebook: Credentials :: ByteString -> ByteString -> ByteString -> Credentials
+ Facebook: Credentials :: Text -> Text -> Text -> Credentials
- Facebook: Id :: ByteString -> Id
+ Facebook: Id :: Text -> Id
- Facebook: Page :: ByteString -> Maybe Text -> Maybe ByteString -> Maybe Text -> Maybe Bool -> Maybe Bool -> Maybe Integer -> Maybe Location -> Maybe Text -> Maybe Integer -> Maybe ByteString -> Maybe ByteString -> Maybe Integer -> Page
+ Facebook: Page :: Id -> Maybe Text -> Maybe Text -> Maybe Text -> Maybe Bool -> Maybe Bool -> Maybe Integer -> Maybe Location -> Maybe Text -> Maybe Integer -> Maybe Text -> Maybe Text -> Maybe Integer -> Page
- Facebook: appId :: Credentials -> ByteString
+ Facebook: appId :: Credentials -> Text
- Facebook: appName :: Credentials -> ByteString
+ Facebook: appName :: Credentials -> Text
- Facebook: appSecret :: Credentials -> ByteString
+ Facebook: appSecret :: Credentials -> Text
- Facebook: getObject :: (MonadResource m, MonadBaseControl IO m, FromJSON a) => ByteString -> [Argument] -> Maybe (AccessToken anyKind) -> FacebookT anyAuth m a
+ Facebook: getObject :: (MonadResource m, MonadBaseControl IO m, FromJSON a) => Text -> [Argument] -> Maybe (AccessToken anyKind) -> FacebookT anyAuth m a
- Facebook: getPage :: (MonadResource m, MonadBaseControl IO m) => ByteString -> [Argument] -> Maybe UserAccessToken -> FacebookT anyAuth m Page
+ Facebook: getPage :: (MonadResource m, MonadBaseControl IO m) => Id -> [Argument] -> Maybe UserAccessToken -> FacebookT anyAuth m Page
- Facebook: idCode :: Id -> ByteString
+ Facebook: idCode :: Id -> Text
- Facebook: pageId :: Page -> ByteString
+ Facebook: pageId :: Page -> Id
- Facebook: pageLink :: Page -> Maybe ByteString
+ Facebook: pageLink :: Page -> Maybe Text
- Facebook: pagePicture :: Page -> Maybe ByteString
+ Facebook: pagePicture :: Page -> Maybe Text
- Facebook: pageWebsite :: Page -> Maybe ByteString
+ Facebook: pageWebsite :: Page -> Maybe Text
- Facebook: postObject :: (MonadResource m, MonadBaseControl IO m, FromJSON a) => ByteString -> [Argument] -> AccessToken anyKind -> FacebookT Auth m a
+ Facebook: postObject :: (MonadResource m, MonadBaseControl IO m, FromJSON a) => Text -> [Argument] -> AccessToken anyKind -> FacebookT Auth m a
- Facebook: searchObjects :: (MonadResource m, MonadBaseControl IO m, FromJSON a) => ByteString -> ByteString -> [Argument] -> Maybe UserAccessToken -> FacebookT anyAuth m (Pager a)
+ Facebook: searchObjects :: (MonadResource m, MonadBaseControl IO m, FromJSON a) => Text -> Text -> [Argument] -> Maybe UserAccessToken -> FacebookT anyAuth m (Pager a)
- Facebook: searchPages :: (MonadResource m, MonadBaseControl IO m) => ByteString -> [Argument] -> Maybe UserAccessToken -> FacebookT anyAuth m (Pager Page)
+ Facebook: searchPages :: (MonadResource m, MonadBaseControl IO m) => Text -> [Argument] -> Maybe UserAccessToken -> FacebookT anyAuth m (Pager Page)
- Facebook: searchUsers :: (MonadResource m, MonadBaseControl IO m) => ByteString -> [Argument] -> Maybe UserAccessToken -> FacebookT anyAuth m (Pager User)
+ Facebook: searchUsers :: (MonadResource m, MonadBaseControl IO m) => Text -> [Argument] -> Maybe UserAccessToken -> FacebookT anyAuth m (Pager User)
- Facebook: type AccessTokenData = ByteString
+ Facebook: type AccessTokenData = Text
- Facebook: type UserId = ByteString
+ Facebook: type UserId = Id

Files

fb.cabal view
@@ -1,5 +1,5 @@ name:              fb-version:           0.12.9+version:           0.13 license:           BSD3 license-file:      LICENSE author:            Felipe Lessa@@ -63,7 +63,6 @@       base               >= 4       && < 5     , lifted-base        >= 0.1     && < 0.2     , bytestring         >= 0.9     && < 0.11-    , bytestring-lexing  == 0.4.*     , text               >= 0.11    && < 0.12     , transformers       >= 0.2     && < 0.4     , transformers-base
src/Facebook/Auth.hs view
@@ -31,12 +31,14 @@ import qualified Control.Exception.Lifted as E import qualified Data.Aeson as AE import qualified Data.Aeson.Types as AE-import qualified Data.Attoparsec.Char8 as A+import qualified Data.Attoparsec.Char8 as AB+import qualified Data.Attoparsec.Text as A import qualified Data.ByteString as B import qualified Data.ByteString.Base64.URL as Base64URL import qualified Data.ByteString.Char8 as B8 import qualified Data.Conduit as C import qualified Data.Conduit.Attoparsec as C+import qualified Data.Conduit.Text as CT import qualified Data.List as L import qualified Data.Serialize as Cereal import qualified Data.Text as T@@ -63,8 +65,9 @@     response <- fbhttp req     lift $       H.responseBody response C.$$+-+      CT.decode CT.utf8 C.=$       C.sinkParser (AppAccessToken <$  A.string "access_token="-                                   <*> A.takeByteString)+                                   <*> A.takeText)   -- | The first step to get an user access token.  Returns the@@ -82,7 +85,7 @@                     Production -> "https://www.facebook.com/dialog/oauth?client_id="                     Beta ->  "https://www.beta.facebook.com/dialog/oauth?client_id="     in T.concat $ urlBase-                : TE.decodeUtf8 (appId creds)+                : appId creds                 : "&redirect_uri="                 : redirectUrl                 : (case perms of@@ -140,11 +143,12 @@ userAccessTokenParser now bs =     let q = HT.parseQuery bs; lookup' a = join (lookup a q)     in case (,) <$> lookup' "access_token" <*> lookup' "expires" of-         (Just (tok, expt)) -> UserAccessToken userId tok (toExpire expt)+         (Just (tok, expt)) -> UserAccessToken userId (dec tok) (toExpire expt)          _ -> error $ "userAccessTokenParser: failed to parse " ++ show bs        where toExpire expt = let i = read (B8.unpack expt) :: Int                              in addUTCTime (fromIntegral i) now              userId = error "userAccessTokenParser: never here"+             dec = TE.decodeUtf8With TE.lenientDecode   -- | The URL an user should be redirected to in order to log them@@ -178,7 +182,7 @@     in TE.decodeUtf8 $          urlBase <>          HT.renderQuery False [ ("next", Just (TE.encodeUtf8 next))-                              , ("access_token", Just data_) ]+                              , ("access_token", Just (TE.encodeUtf8 data_)) ]   -- | URL where the user is redirected to after Facebook@@ -274,7 +278,7 @@         creds <- getCreds         req   <- fbreq "/oauth/access_token" Nothing $                  tsq creds [ ("grant_type", "fb_exchange_token")-                           , ("fb_exchange_token", data_) ]+                           , ("fb_exchange_token", TE.encodeUtf8 data_) ]         eresponse <- E.try (asBS =<< fbhttp req)         case eresponse of           Right response -> do@@ -304,7 +308,7 @@     ('.', encodedUnparsedPayload) <- MaybeT $ return (B8.uncons encodedUnparsedPayloadWithDot)     signature       <- eitherToMaybeT $ Base64URL.decode $ addBase64Padding encodedSignature     unparsedPayload <- eitherToMaybeT $ Base64URL.decode $ addBase64Padding encodedUnparsedPayload-    payload         <- eitherToMaybeT $ A.parseOnly json' unparsedPayload+    payload         <- eitherToMaybeT $ AB.parseOnly json' unparsedPayload      -- Verify signature     SignedRequestAlgorithm algo <- fromJson payload@@ -321,7 +325,7 @@        fromJson :: (AE.FromJSON a, Monad m) => AE.Value -> MaybeT m a        fromJson = eitherToMaybeT . AE.parseEither AE.parseJSON        credsToHmacKey :: Credentials -> MacKey ctx SHA256-       credsToHmacKey = MacKey . appSecret+       credsToHmacKey = MacKey . appSecretBS  newtype SignedRequestAlgorithm = SignedRequestAlgorithm Text instance AE.FromJSON SignedRequestAlgorithm where
src/Facebook/Base.hs view
@@ -27,6 +27,7 @@ import qualified Data.Conduit.Attoparsec as C import qualified Data.Conduit.List as CL import qualified Data.Text as T+import qualified Data.Text.Encoding as TE import qualified Network.HTTP.Conduit as H import qualified Network.HTTP.Types as HT @@ -43,7 +44,7 @@ -- | A plain 'H.Request' to a Facebook API.  Use this instead of -- 'H.def' when creating new 'H.Request'@s@ for Facebook. fbreq :: Monad m =>-         ByteString                  -- ^ Path.+         Text                        -- ^ Path.       -> Maybe (AccessToken anyKind) -- ^ Access token.       -> HT.SimpleQuery              -- ^ Parameters.       -> FacebookT anyAuth m (H.Request n)@@ -55,11 +56,12 @@       in H.def { H.secure        = True                , H.host          = host                , H.port          = 443-               , H.path          = path+               , H.path          = TE.encodeUtf8 path                , H.redirectCount = 3                , H.queryString   =                    HT.renderSimpleQuery False $                    maybe id tsq mtoken query+               , H.responseTimeout = Just 120000000 -- 2 minutes                }  @@ -72,11 +74,11 @@     tsq _ = id  instance ToSimpleQuery Credentials where-    tsq creds = (:) ("client_id",     appId     creds) .-                (:) ("client_secret", appSecret creds)+    tsq creds = (:) ("client_id",     appIdBS     creds) .+                (:) ("client_secret", appSecretBS creds)  instance ToSimpleQuery (AccessToken anyKind) where-    tsq token = (:) ("access_token", accessTokenData token)+    tsq token = (:) ("access_token", TE.encodeUtf8 $ accessTokenData token)   -- | Converts a plain 'H.Response' coming from 'H.http' into a
src/Facebook/Graph.hs view
@@ -1,7 +1,6 @@ {-# LANGUAGE ConstraintKinds, DeriveDataTypeable, FlexibleContexts, OverloadedStrings #-} module Facebook.Graph-    ( Id(..)-    , getObject+    ( getObject     , postObject     , searchObjects     , Pager(..)@@ -24,10 +23,8 @@ import Control.Monad.Trans.Control (MonadBaseControl) import Control.Monad.Trans.Resource (MonadResourceBase) import Data.ByteString.Char8 (ByteString)-import Data.ByteString.Lex.Integral (packDecimal) import Data.Int (Int8, Int16, Int32, Int64) import Data.List (intersperse)-import Data.Maybe (fromMaybe) import Data.Text (Text) import Data.Typeable (Typeable) import Data.Word (Word, Word8, Word16, Word32, Word64)@@ -51,21 +48,9 @@ import Facebook.Types  --- | The identification code of an object.-newtype Id = Id { idCode :: ByteString }-    deriving (Eq, Ord, Show, Read, Typeable)--instance A.FromJSON Id where-    parseJSON (A.Object v) = v A..: "id"-    parseJSON (A.String s) = pure $ Id $ TE.encodeUtf8 s-    parseJSON (A.Number d) = pure $ Id $ from $ floor d-      where from i = fromMaybe (B.pack $ show i) (packDecimal (i :: Int64))-    parseJSON o = fail $ "Can't parse Facebook.Id from " ++ show o-- -- | Make a raw @GET@ request to Facebook's Graph API. getObject :: (C.MonadResource m, MonadBaseControl IO m, A.FromJSON a) =>-             ByteString     -- ^ Path (should begin with a slash @\/@)+             Text           -- ^ Path (should begin with a slash @\/@)           -> [Argument]     -- ^ Arguments to be passed to Facebook           -> Maybe (AccessToken anyKind) -- ^ Optional access token           -> FacebookT anyAuth m a@@ -76,7 +61,7 @@  -- | Make a raw @POST@ request to Facebook's Graph API. postObject :: (C.MonadResource m, MonadBaseControl IO m, A.FromJSON a) =>-              ByteString          -- ^ Path (should begin with a slash @\/@)+              Text                -- ^ Path (should begin with a slash @\/@)            -> [Argument]          -- ^ Arguments to be passed to Facebook            -> AccessToken anyKind -- ^ Access token            -> FacebookT Auth m a@@ -89,13 +74,13 @@ -- | Make a raw @GET@ request to the /search endpoint of Facebook’s -- Graph API.  Returns a raw JSON 'A.Value'. searchObjects :: (C.MonadResource m, MonadBaseControl IO m, A.FromJSON a)-              => ByteString            -- ^ A Facebook object type to search for-              -> ByteString            -- ^ The keyword to search for+              => Text                  -- ^ A Facebook object type to search for+              -> Text                  -- ^ The keyword to search for               -> [Argument]            -- ^ Additional arguments to pass               -> Maybe UserAccessToken -- ^ Optional access token               -> FacebookT anyAuth m (Pager a) searchObjects objectType keyword query = getObject "/search" query'-  where query' = ("q", keyword) : ("type", objectType) : query+  where query' = ("q" #= keyword) : ("type" #= objectType) : query   ----------------------------------------------------------------------@@ -281,7 +266,7 @@  -- | An object's 'Id' code. instance SimpleType Id where-    encodeFbParam = idCode+    encodeFbParam = TE.encodeUtf8 . idCode  -- | 'Permission' is a @newtype@ of 'Text' instance SimpleType Permission where
src/Facebook/Object/Action.hs view
@@ -6,9 +6,9 @@  import Control.Arrow (first) import Control.Monad.Trans.Control (MonadBaseControl)-import Data.ByteString.Char8 (ByteString) import Data.Function (on) import Data.String (IsString(..))+import Data.Text (Text)  import qualified Data.Conduit as C @@ -37,11 +37,11 @@              -> FacebookT Auth m Id createAction (Action action) query mapptoken usertoken = do   creds <- getCreds-  let post :: (C.MonadResource m, MonadBaseControl IO m)  => ByteString -> AccessToken anyKind -> FacebookT Auth m Id+  let post :: (C.MonadResource m, MonadBaseControl IO m)  => Text -> AccessToken anyKind -> FacebookT Auth m Id       post prepath = postObject (prepath <> appName creds <> ":" <> action) query   case mapptoken of     Nothing       -> post "/me/" usertoken-    Just apptoken -> post ("/" <> accessTokenUserId usertoken <> "/") apptoken+    Just apptoken -> post ("/" <> idCode (accessTokenUserId usertoken) <> "/") apptoken   -- | An action of your app.  Please refer to Facebook's@@ -49,7 +49,7 @@ -- <https://developers.facebook.com/docs/opengraph/keyconcepts/#actions-objects> -- to see how you can create actions. ----- This is a @newtype@ of 'ByteString' that supports only 'IsString'.+-- This is a @newtype@ of 'Text' that supports only 'IsString'. -- This means that to create an 'Action' you should use the -- @OverloadedStrings@ language extension.  For example, --@@ -58,7 +58,7 @@ -- > foo token = do -- >   ... -- >   createAction "cook" [...] token-newtype Action = Action { unAction :: ByteString }+newtype Action = Action { unAction :: Text }  instance Show Action where     show = show . unAction
src/Facebook/Object/Checkin.hs view
@@ -72,7 +72,7 @@            -> [Argument]            -- ^ Arguments to be passed to Facebook.            -> Maybe UserAccessToken -- ^ Optional user access token.            -> FacebookT anyAuth m Checkin-getCheckin (Id id_) query mtoken = getObject ("/" <> id_) query mtoken+getCheckin id_ query mtoken = getObject ("/" <> idCode id_) query mtoken   -- | Creates a 'check-in' and returns its ID. Place and
src/Facebook/Object/Page.hs view
@@ -12,7 +12,6 @@ import Control.Monad (mzero) import Control.Monad.Trans.Control (MonadBaseControl) import Data.Aeson ((.:), (.:?))-import Data.ByteString.Char8 (ByteString) import qualified Data.Aeson as A import qualified Data.Conduit as C import Data.Text (Text)@@ -27,9 +26,9 @@ -- -- /NOTE:/ Does not yet support all fields. Please file an issue if -- you need any other fields.-data Page = Page { pageId                :: ByteString+data Page = Page { pageId                :: Id                  , pageName              :: Maybe Text-                 , pageLink              :: Maybe ByteString+                 , pageLink              :: Maybe Text                  , pageCategory          :: Maybe Text                  , pageIsPublished       :: Maybe Bool                  , pageCanPost           :: Maybe Bool@@ -37,8 +36,8 @@                  , pageLocation          :: Maybe Location                  , pagePhone             :: Maybe Text                  , pageCheckins          :: Maybe Integer-                 , pagePicture           :: Maybe ByteString-                 , pageWebsite           :: Maybe ByteString+                 , pagePicture           :: Maybe Text+                 , pageWebsite           :: Maybe Text                  , pageTalkingAboutCount :: Maybe Integer                  } deriving (Eq, Ord, Show, Read, Typeable) @@ -62,16 +61,16 @@  -- | Get a page using its ID. The user access token is optional. getPage :: (C.MonadResource m, MonadBaseControl IO m)-        => ByteString            -- ^ Page ID+        => Id                    -- ^ Page ID         -> [Argument]            -- ^ Arguments to be passed to Facebook         -> Maybe UserAccessToken -- ^ Optional user access token         -> FacebookT anyAuth m Page-getPage id_ = getObject $ "/" <> id_+getPage id_ = getObject $ "/" <> idCode id_   -- | Search pages by keyword. The user access token is optional. searchPages :: (C.MonadResource m, MonadBaseControl IO m)-            => ByteString            -- ^ Keyword to search for+            => Text                  -- ^ Keyword to search for             -> [Argument]            -- ^ Arguments to pass to Facebook             -> Maybe UserAccessToken -- ^ Optional user access token             -> FacebookT anyAuth m (Pager Page)
src/Facebook/Object/User.hs view
@@ -11,14 +11,12 @@ import Control.Monad (mzero) import Control.Monad.Trans.Control (MonadBaseControl) import Data.Aeson ((.:), (.:?))-import Data.ByteString.Char8 (ByteString) import Data.Text (Text) import Data.Typeable (Typeable)  -- import qualified Control.Exception.Lifted as E import qualified Data.Aeson as A import qualified Data.Conduit as C--- import qualified Data.Text as T   import Facebook.Types@@ -90,12 +88,12 @@         -> [Argument]     -- ^ Arguments to be passed to Facebook.         -> Maybe UserAccessToken -- ^ Optional user access token.         -> FacebookT anyAuth m User-getUser id_ query mtoken = getObject ("/" <> id_) query mtoken+getUser id_ query mtoken = getObject ("/" <> idCode id_) query mtoken   -- | Search users by keyword. searchUsers :: (C.MonadResource m, MonadBaseControl IO m)-            => ByteString+            => Text             -> [Argument]             -> Maybe UserAccessToken             -> FacebookT anyAuth m (Pager User)@@ -110,4 +108,4 @@   -> UserAccessToken -- ^ User access token.   -> FacebookT anyAuth m (Pager Checkin) getUserCheckins id_ query token =-  getObject ("/" <> id_ <> "/checkins") query (Just token)+  getObject ("/" <> idCode id_ <> "/checkins") query (Just token)
src/Facebook/RealTime.hs view
@@ -25,10 +25,10 @@ import qualified Crypto.Hash.SHA1 as SHA1 import qualified Data.Aeson as A import qualified Data.ByteString.Base16 as Base16-import qualified Data.ByteString.Char8 as B import qualified Data.ByteString.Lazy.Char8 as L import qualified Data.Conduit as C import qualified Data.Conduit.List as CL+import qualified Data.Text as T import qualified Data.Text.Encoding as TE import qualified Network.HTTP.Conduit as H import qualified Network.HTTP.Types as HT@@ -118,10 +118,10 @@   -- | (Internal)  Get the subscription's path.-getSubscriptionsPath :: Monad m => FacebookT Auth m ByteString+getSubscriptionsPath :: Monad m => FacebookT Auth m Text getSubscriptionsPath = do   creds <- getCreds-  return $ B.concat ["/", appId creds, "/subscriptions"]+  return $ T.concat ["/", appId creds, "/subscriptions"]   -- | Information returned by Facebook about a real-time update@@ -172,7 +172,7 @@ verifyRealTimeUpdateNotifications sig body = do   creds <- getCreds   let key :: Crypto.MacKey SHA1.Ctx SHA1.SHA1-      key = Crypto.MacKey (appSecret creds)+      key = Crypto.MacKey (appSecretBS creds)       hash = Crypto.hmac key body       expected = "sha1=" <> Base16.encode (Crypto.encode hash)   return $! if sig `Crypto.constTimeEq` expected then Just body else Nothing
src/Facebook/TestUsers.hs view
@@ -123,7 +123,7 @@                   -> AppAccessToken -- ^ Access token for your app.                   -> FacebookT Auth m Bool removeTestUser testUser token =-  getObjectBool ("/" <> tuId testUser) [("method","delete")] (Just token)+  getObjectBool ("/" <> idCode (tuId testUser)) [("method","delete")] (Just token)   -- | Make a friend connection between two test users.@@ -146,7 +146,7 @@                      \ a token. Both users must have a token." makeFriendConn (TestUser {tuId = id1, tuAccessToken = (Just token1)}) (TestUser {tuId = id2, tuAccessToken = (Just token2)}) = do   let friendReq userId1 userId2 token =-          getObjectBool ("/" <> userId1 <> "/friends/" <> userId2)+          getObjectBool ("/" <> idCode userId1 <> "/friends/" <> idCode userId2)                         [ "method" #= ("post" :: B.ByteString),                           "access_token" #= token ]                         Nothing@@ -170,7 +170,7 @@ -- as a JSON, it tries to parse either as "true" or "false". -- Used only by the Test User API bindings. getObjectBool :: (C.MonadResource m, MonadBaseControl IO m)-                 => B.ByteString+                 => Text                  -- ^ Path (should begin with a slash @\/@).                  -> [Argument]                  -- ^ Arguments to be passed to Facebook.
src/Facebook/Types.hs view
@@ -1,10 +1,13 @@ {-# LANGUAGE DeriveDataTypeable, GADTs, StandaloneDeriving #-} module Facebook.Types     ( Credentials(..)+    , appIdBS+    , appSecretBS     , AccessToken(..)     , UserAccessToken     , AppAccessToken     , AccessTokenData+    , Id(..)     , UserId     , accessTokenData     , accessTokenExpires@@ -16,26 +19,41 @@     , FbUTCTime(..)     ) where +import Control.Applicative (pure) import Data.ByteString (ByteString)+import Data.Int (Int64) import Data.Monoid (Monoid, mappend)+import Data.Text (Text) import Data.Time (UTCTime, parseTime) import Data.Typeable (Typeable, Typeable1) import System.Locale (defaultTimeLocale)  import qualified Data.Aeson as A import qualified Data.Text as T+import qualified Data.Text.Encoding as TE+import qualified Data.Text.Lazy as TL+import qualified Data.Text.Lazy.Builder as TLB+import qualified Data.Text.Lazy.Builder.Int as TLBI   -- | Credentials that you get for your app when you register on -- Facebook. data Credentials =-    Credentials { appName   :: ByteString -- ^ Your application name (e.g. for Open Graph calls).-                , appId     :: ByteString -- ^ Your application ID.-                , appSecret :: ByteString -- ^ Your application secret key.+    Credentials { appName   :: Text -- ^ Your application name (e.g. for Open Graph calls).+                , appId     :: Text -- ^ Your application ID.+                , appSecret :: Text -- ^ Your application secret key.                 }     deriving (Eq, Ord, Show, Read, Typeable) +-- | 'appId' for 'ByteString'.+appIdBS :: Credentials -> ByteString+appIdBS = TE.encodeUtf8 . appId +-- | 'appSecret' for 'ByteString'.+appSecretBS :: Credentials -> ByteString+appSecretBS = TE.encodeUtf8 . appSecret++ -- | An access token.  While you can make some API calls without -- an access token, many require an access token and some will -- give you more information with an appropriate access token.@@ -69,12 +87,26 @@ deriving instance Show (AccessToken kind) deriving instance Typeable1 AccessToken + -- | The access token data that is passed to Facebook's API -- calls.-type AccessTokenData = ByteString+type AccessTokenData = Text --- | A Facebook user id such as @1008905713901@.-type UserId = ByteString+-- | The identification code of an object.+newtype Id = Id { idCode :: Text }+    deriving (Eq, Ord, Show, Read, Typeable)++instance A.FromJSON Id where+    parseJSON (A.Object v) = v A..: "id"+    parseJSON (A.String s) = pure $ Id s+    parseJSON (A.Number d) = pure $ Id $ from $ floor d+      where from i = TL.toStrict $ TLB.toLazyText $ TLBI.decimal (i :: Int64)+    parseJSON o = fail $ "Can't parse Facebook.Id from " ++ show o+++-- | A Facebook user ID such as @1008905713901@.+type UserId = Id+  -- | Get the access token data. accessTokenData :: AccessToken anyKind -> AccessTokenData
tests/Main.hs view
@@ -50,7 +50,7 @@     where       tryToGet = do         [appName, appId, appSecret] <- mapM getEnv ["APP_NAME", "APP_ID", "APP_SECRET"]-        return $ FB.Credentials (B.pack appName) (B.pack appId) (B.pack appSecret)+        return $ FB.Credentials (T.pack appName) (T.pack appId) (T.pack appSecret)        showHelp exc | not (isDoesNotExistError exc) = E.throw exc       showHelp _ = do@@ -80,7 +80,7 @@ invalidCredentials = FB.Credentials "this" "isn't" "valid"  invalidUserAccessToken :: FB.UserAccessToken-invalidUserAccessToken = FB.UserAccessToken "invalid" "user" farInTheFuture+invalidUserAccessToken = FB.UserAccessToken (FB.Id "invalid") "user" farInTheFuture     where       Just farInTheFuture = parseTime (error "farInTheFuture") "%Y" "3000"       -- It's actually important to use 'farInTheFuture' since we@@ -95,7 +95,6 @@ main = H.withManager $ \manager -> liftIO $ do   creds <- getCredentials   hspec $ do-{-     -- Run the tests twice, once in Facebook's production tier...     facebookTests "Production tier: "                   manager@@ -106,7 +105,7 @@                   manager                   (C.runResourceT . FB.beta_runFacebookT creds manager)                   (C.runResourceT . FB.beta_runNoAuthFacebookT manager)--}+     -- Tests that don't depend on which tier is chosen.     libraryTests manager @@ -153,8 +152,8 @@   describe' "getUser" $ do     it "works for Zuckerberg" $ do       runNoAuth $ do-        user <- FB.getUser "zuck" [] Nothing-        FB.userId user         &?= "4"+        user <- FB.getUser (FB.Id "zuck") [] Nothing+        FB.userId user         &?= FB.Id "4"         FB.userName user       &?= Just "Mark Zuckerberg"         FB.userFirstName user  &?= Just "Mark"         FB.userMiddleName user &?= Nothing@@ -164,8 +163,8 @@   describe' "getPage" $ do     it "works for FB Developers" $ do       runNoAuth $ do-        page <- FB.getPage "19292868552" [] Nothing-        FB.pageId page &?= "19292868552"+        page <- FB.getPage (FB.Id "19292868552") [] Nothing+        FB.pageId page &?= (FB.Id "19292868552")         FB.pageName page &?= Just "Facebook Developers"         FB.pageCategory page &?= Just "Product/service"         FB.pageIsPublished page &?= Just True@@ -347,7 +346,7 @@      prop "works for Id" $ \i ->       let toId :: Int -> FB.Id-          toId = FB.Id . B.pack . show+          toId = FB.Id . T.pack . show           j = abs i       in FB.encodeFbParam (toId j) == FB.encodeFbParam j