2015-07-27 16:29:08 +02:00
|
|
|
module Servant.JS.Axios where
|
|
|
|
|
2015-08-17 23:56:29 +02:00
|
|
|
import Control.Lens
|
|
|
|
import Data.Char (toLower)
|
|
|
|
import Data.List
|
|
|
|
import Data.Monoid
|
2015-09-21 12:31:00 +02:00
|
|
|
import Servant.Foreign
|
2015-08-17 23:56:29 +02:00
|
|
|
import Servant.JS.Internal
|
2015-07-27 16:29:08 +02:00
|
|
|
|
2015-07-28 15:06:00 +02:00
|
|
|
-- | Axios 'configuration' type
|
|
|
|
-- Let you customize the generation using Axios capabilities
|
|
|
|
data AxiosOptions = AxiosOptions
|
|
|
|
{ -- | indicates whether or not cross-site Access-Control requests
|
|
|
|
-- should be made using credentials
|
|
|
|
withCredentials :: !Bool
|
|
|
|
-- | the name of the cookie to use as a value for xsrf token
|
2015-08-17 23:56:29 +02:00
|
|
|
, xsrfCookieName :: !(Maybe String)
|
2015-07-28 15:06:00 +02:00
|
|
|
-- | the name of the header to use as a value for xsrf token
|
2015-08-17 23:56:29 +02:00
|
|
|
, xsrfHeaderName :: !(Maybe String)
|
2015-07-28 15:06:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
-- | Default instance of the AxiosOptions
|
|
|
|
-- Defines the settings as they are in the Axios documentation
|
|
|
|
-- by default
|
|
|
|
defAxiosOptions :: AxiosOptions
|
|
|
|
defAxiosOptions = AxiosOptions
|
|
|
|
{ withCredentials = False
|
|
|
|
, xsrfCookieName = Nothing
|
|
|
|
, xsrfHeaderName = Nothing
|
|
|
|
}
|
|
|
|
|
2015-07-27 16:29:08 +02:00
|
|
|
-- | Generate regular javacript functions that use
|
|
|
|
-- the axios library, using default values for 'CommonGeneratorOptions'.
|
2015-07-28 15:06:00 +02:00
|
|
|
axios :: AxiosOptions -> JavaScriptGenerator
|
|
|
|
axios aopts = axiosWith aopts defCommonGeneratorOptions
|
2015-07-27 16:29:08 +02:00
|
|
|
|
|
|
|
-- | Generate regular javascript functions that use the axios library.
|
2015-07-28 15:06:00 +02:00
|
|
|
axiosWith :: AxiosOptions -> CommonGeneratorOptions -> JavaScriptGenerator
|
|
|
|
axiosWith aopts opts = intercalate "\n\n" . map (generateAxiosJSWith aopts opts)
|
2015-07-27 16:29:08 +02:00
|
|
|
|
|
|
|
-- | js codegen using axios library using default options
|
2015-07-28 15:06:00 +02:00
|
|
|
generateAxiosJS :: AxiosOptions -> AjaxReq -> String
|
|
|
|
generateAxiosJS aopts = generateAxiosJSWith aopts defCommonGeneratorOptions
|
2015-08-17 23:56:29 +02:00
|
|
|
|
2015-07-27 16:29:08 +02:00
|
|
|
-- | js codegen using axios library
|
2015-07-28 15:06:00 +02:00
|
|
|
generateAxiosJSWith :: AxiosOptions -> CommonGeneratorOptions -> AjaxReq -> String
|
|
|
|
generateAxiosJSWith aopts opts req = "\n" <>
|
2015-07-27 16:29:08 +02:00
|
|
|
fname <> " = function(" <> argsStr <> ")\n"
|
|
|
|
<> "{\n"
|
2015-07-28 01:25:00 +02:00
|
|
|
<> " return axios({ url: " <> url <> "\n"
|
|
|
|
<> " , method: '" <> method <> "'\n"
|
2015-07-27 16:29:08 +02:00
|
|
|
<> dataBody
|
|
|
|
<> reqheaders
|
2015-07-28 15:06:00 +02:00
|
|
|
<> withCreds
|
|
|
|
<> xsrfCookie
|
|
|
|
<> xsrfHeader
|
2015-07-27 16:29:08 +02:00
|
|
|
<> " });\n"
|
|
|
|
<> "}\n"
|
|
|
|
|
|
|
|
where argsStr = intercalate ", " args
|
|
|
|
args = captures
|
|
|
|
++ map (view argName) queryparams
|
|
|
|
++ body
|
|
|
|
++ map (toValidFunctionName . (<>) "header" . headerArgName) hs
|
2015-08-17 23:56:29 +02:00
|
|
|
|
2015-07-27 16:29:08 +02:00
|
|
|
captures = map captureArg
|
|
|
|
. filter isCapture
|
|
|
|
$ req ^. reqUrl.path
|
|
|
|
|
|
|
|
hs = req ^. reqHeaders
|
|
|
|
|
|
|
|
queryparams = req ^.. reqUrl.queryStr.traverse
|
|
|
|
|
|
|
|
body = if req ^. reqBody
|
|
|
|
then [requestBody opts]
|
|
|
|
else []
|
|
|
|
|
|
|
|
dataBody =
|
|
|
|
if req ^. reqBody
|
2015-07-28 11:33:36 +02:00
|
|
|
then " , data: body\n" <>
|
2015-07-27 16:29:08 +02:00
|
|
|
" , responseType: 'json'\n"
|
|
|
|
else ""
|
|
|
|
|
2015-07-28 15:06:00 +02:00
|
|
|
withCreds =
|
|
|
|
if withCredentials aopts
|
|
|
|
then " , withCredentials: true\n"
|
|
|
|
else ""
|
|
|
|
|
2015-08-17 23:56:29 +02:00
|
|
|
xsrfCookie =
|
2015-07-28 15:06:00 +02:00
|
|
|
case xsrfCookieName aopts of
|
|
|
|
Just name -> " , xsrfCookieName: '" <> name <> "'\n"
|
|
|
|
Nothing -> ""
|
|
|
|
|
|
|
|
xsrfHeader =
|
|
|
|
case xsrfHeaderName aopts of
|
|
|
|
Just name -> " , xsrfHeaderName: '" <> name <> "'\n"
|
|
|
|
Nothing -> ""
|
|
|
|
|
2015-07-27 16:29:08 +02:00
|
|
|
reqheaders =
|
|
|
|
if null hs
|
|
|
|
then ""
|
2015-07-28 15:06:00 +02:00
|
|
|
else " , headers: { " <> headersStr <> " }\n"
|
2015-07-27 16:29:08 +02:00
|
|
|
|
|
|
|
where headersStr = intercalate ", " $ map headerStr hs
|
|
|
|
headerStr header = "\"" ++
|
|
|
|
headerArgName header ++
|
|
|
|
"\": " ++ show header
|
|
|
|
|
|
|
|
namespace =
|
|
|
|
if hasNoModule
|
|
|
|
then "var "
|
|
|
|
else (moduleName opts) <> "."
|
|
|
|
where
|
|
|
|
hasNoModule = null (moduleName opts)
|
2015-08-17 23:56:29 +02:00
|
|
|
|
2015-07-28 16:46:00 +02:00
|
|
|
fname = namespace <> (functionNameBuilder opts $ req ^. funcName)
|
2015-08-17 23:56:29 +02:00
|
|
|
|
2015-07-27 16:29:08 +02:00
|
|
|
method = map toLower $ req ^. reqMethod
|
|
|
|
url = if url' == "'" then "'/'" else url'
|
|
|
|
url' = "'"
|
2015-07-28 16:47:19 +02:00
|
|
|
++ urlPrefix opts
|
2015-07-27 16:29:08 +02:00
|
|
|
++ urlArgs
|
|
|
|
++ queryArgs
|
|
|
|
|
|
|
|
urlArgs = jsSegments
|
|
|
|
$ req ^.. reqUrl.path.traverse
|
|
|
|
|
|
|
|
queryArgs = if null queryparams
|
|
|
|
then ""
|
|
|
|
else " + '?" ++ jsParams queryparams
|