Added default NoTypes parameter for dynamic languages.

This commit is contained in:
Maksymilian Owsianny 2015-12-02 15:56:56 +00:00
parent 83600d5326
commit 721151a32d
4 changed files with 22 additions and 21 deletions

View file

@ -30,6 +30,7 @@ module Servant.Foreign
, queryStr , queryStr
, listFromAPI , listFromAPI
, GenerateList(..) , GenerateList(..)
, NoTypes
-- re-exports -- re-exports
, module Servant.API , module Servant.API
) where ) where

View file

@ -130,11 +130,6 @@ type family Elem (a :: *) (ls::[*]) :: Constraint where
-- > -- instances. -- > -- instances.
-- > data LangX -- > data LangX
-- > -- >
-- > -- If the language __X__ is dynamically typed then you only need
-- > -- a catch all instance of a form
-- > instance HasForeignType LangX a where
-- > typeFor _ _ = empty
-- >
-- > -- Otherwise you define instances for the types you need -- > -- Otherwise you define instances for the types you need
-- > instance HasForeignType LangX Int where -- > instance HasForeignType LangX Int where
-- > typeFor _ _ = "intX" -- > typeFor _ _ = "intX"
@ -150,9 +145,21 @@ type family Elem (a :: *) (ls::[*]) :: Constraint where
-- > => Proxy api -> [Req] -- > => Proxy api -> [Req]
-- > getEndpoints api = listFromAPI (Proxy :: Proxy LangX) api -- > getEndpoints api = listFromAPI (Proxy :: Proxy LangX) api
-- --
-- > -- If language __X__ is dynamically typed then you can use
-- > -- a predefined NoTypes parameter
-- > getEndpoints :: (HasForeign NoTypes api, GenerateList (Foreign api))
-- > => Proxy api -> [Req]
-- > getEndpoints api = listFromAPI (Proxy :: Proxy NoTypes) api
-- >
--
class HasForeignType lang a where class HasForeignType lang a where
typeFor :: Proxy lang -> Proxy a -> ForeignType typeFor :: Proxy lang -> Proxy a -> ForeignType
data NoTypes
instance HasForeignType NoTypes a where
typeFor _ _ = empty
class HasForeign lang (layout :: *) where class HasForeign lang (layout :: *) where
type Foreign layout :: * type Foreign layout :: *
foreignFor :: Proxy lang -> Proxy layout -> Req -> Foreign layout foreignFor :: Proxy lang -> Proxy layout -> Req -> Foreign layout

View file

@ -110,7 +110,7 @@ module Servant.JS
, -- * Misc. , -- * Misc.
listFromAPI listFromAPI
, javascript , javascript
, LangJS , NoTypes
, GenerateList(..) , GenerateList(..)
) where ) where
@ -123,37 +123,30 @@ import Servant.JS.Axios
import Servant.JS.Internal import Servant.JS.Internal
import Servant.JS.JQuery import Servant.JS.JQuery
import Servant.JS.Vanilla import Servant.JS.Vanilla
import Servant.Foreign (GenerateList(..), listFromAPI) import Servant.Foreign (GenerateList(..), listFromAPI, NoTypes)
-- Dummy type specifying target language
data LangJS
-- | Generate the data necessary to generate javascript code -- | Generate the data necessary to generate javascript code
-- for all the endpoints of an API, as ':<|>'-separated values -- for all the endpoints of an API, as ':<|>'-separated values
-- of type 'AjaxReq'. -- of type 'AjaxReq'.
javascript :: HasForeign LangJS layout => Proxy layout -> Foreign layout javascript :: HasForeign NoTypes layout => Proxy layout -> Foreign layout
javascript p = foreignFor (Proxy :: Proxy LangJS) p defReq javascript p = foreignFor (Proxy :: Proxy NoTypes) p defReq
-- | Directly generate all the javascript functions for your API -- | Directly generate all the javascript functions for your API
-- from a 'Proxy' for your API type. You can then write it to -- from a 'Proxy' for your API type. You can then write it to
-- a file or integrate it in a page, for example. -- a file or integrate it in a page, for example.
jsForAPI :: (HasForeign LangJS api, GenerateList (Foreign api)) jsForAPI :: (HasForeign NoTypes api, GenerateList (Foreign api))
=> Proxy api -- ^ proxy for your API type => Proxy api -- ^ proxy for your API type
-> JavaScriptGenerator -- ^ js code generator to use (angular, vanilla js, jquery, others) -> JavaScriptGenerator -- ^ js code generator to use (angular, vanilla js, jquery, others)
-> Text -- ^ a text that you can embed in your pages or write to a file -> Text -- ^ a text that you can embed in your pages or write to a file
jsForAPI p gen = gen (listFromAPI (Proxy :: Proxy LangJS) p) jsForAPI p gen = gen (listFromAPI (Proxy :: Proxy NoTypes) p)
-- | Directly generate all the javascript functions for your API -- | Directly generate all the javascript functions for your API
-- from a 'Proxy' for your API type using the given generator -- from a 'Proxy' for your API type using the given generator
-- and write the resulting code to a file at the given path. -- and write the resulting code to a file at the given path.
writeJSForAPI :: (HasForeign LangJS api, GenerateList (Foreign api)) writeJSForAPI :: (HasForeign NoTypes api, GenerateList (Foreign api))
=> Proxy api -- ^ proxy for your API type => Proxy api -- ^ proxy for your API type
-> JavaScriptGenerator -- ^ js code generator to use (angular, vanilla js, jquery, others) -> JavaScriptGenerator -- ^ js code generator to use (angular, vanilla js, jquery, others)
-> FilePath -- ^ path to the file you want to write the resulting javascript code into -> FilePath -- ^ path to the file you want to write the resulting javascript code into
-> IO () -> IO ()
writeJSForAPI p gen fp = writeFile fp (jsForAPI p gen) writeJSForAPI p gen fp = writeFile fp (jsForAPI p gen)
-- A catch all instance since JavaScript has no types.
instance HasForeignType LangJS a where
typeFor _ _ = empty

View file

@ -98,7 +98,7 @@ a `shouldNotContain` b = shouldNotSatisfy a (T.isInfixOf b)
axiosSpec :: Spec axiosSpec :: Spec
axiosSpec = describe specLabel $ do axiosSpec = describe specLabel $ do
let reqList = listFromAPI (Proxy :: Proxy LangJS) (Proxy :: Proxy TestAPI) let reqList = listFromAPI (Proxy :: Proxy NoTypes) (Proxy :: Proxy TestAPI)
it "should add withCredentials when needed" $ do it "should add withCredentials when needed" $ do
let jsText = genJS withCredOpts $ reqList let jsText = genJS withCredOpts $ reqList
output jsText output jsText
@ -122,7 +122,7 @@ axiosSpec = describe specLabel $ do
angularSpec :: TestNames -> Spec angularSpec :: TestNames -> Spec
angularSpec test = describe specLabel $ do angularSpec test = describe specLabel $ do
let reqList = listFromAPI (Proxy :: Proxy LangJS) (Proxy :: Proxy TestAPI) let reqList = listFromAPI (Proxy :: Proxy NoTypes) (Proxy :: Proxy TestAPI)
it "should implement a service globally" $ do it "should implement a service globally" $ do
let jsText = genJS reqList let jsText = genJS reqList
output jsText output jsText