{-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeApplications #-} module Gargantext.API.Routes.Named.Share ( -- * Routes types ShareNode(..) , UnshareNode(..) , ShareURL(..) , ShareLink(..) , renderShareLink -- * API types (which appears in the routes) , ShareNodeParams(..) ) where import Data.Aeson (withText) import Data.Swagger (ToSchema, declareNamedSchema) import Data.Text qualified as T import Gargantext.API.Node.Share.Types ( ShareNodeParams (..) ) import Gargantext.Database.Admin.Types.Node import Gargantext.Prelude import Network.URI (parseURI) import Prelude (fail) import Servant -- | A shareable link. -- N.B. We don't use a 'BareUrl' internally, because parsing something like -- 'http://localhost/#/share/NodeCorpus/16' -- would fail because '#/share/NodeCorpus/16' by the RFC3968 spec is considered -- an uriFragment, but BaseUrl cannot handle that. newtype ShareLink = ShareLink { getShareLink :: URI } deriving (Show, Eq, Ord, Generic) instance NFData ShareLink where renderShareLink :: ShareLink -> T.Text renderShareLink = T.pack . show . getShareLink instance ToJSON ShareLink where toJSON = toJSON . renderShareLink instance FromJSON ShareLink where parseJSON = withText "ShareLink" $ \txt -> let urlStr = T.unpack txt in case parseURI urlStr of Nothing -> fail $ "Invalid URL: " <> urlStr Just u -> pure $ ShareLink u instance ToSchema ShareLink where declareNamedSchema _ = declareNamedSchema (Proxy @T.Text) newtype ShareURL mode = ShareURL { shareUrlEp :: mode :- Summary "Fetch URL for sharing a node" :> QueryParam "type" NodeType :> QueryParam "id" NodeId :> Get '[JSON] ShareLink } deriving Generic newtype ShareNode mode = ShareNode { shareNodeEp :: mode :- Summary " Share Node with username" :> ReqBody '[JSON] ShareNodeParams :> Post '[JSON] Int } deriving Generic newtype UnshareNode mode = UnshareNode { unshareEp :: mode :- Summary " Unshare a Node" :> Capture "node_id" NodeId :> Put '[JSON] Int } deriving Generic