-
Notifications
You must be signed in to change notification settings - Fork 50
/
Copy pathAPI.purs
109 lines (95 loc) · 2.92 KB
/
API.purs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
module Try.API
( ErrorPosition(..)
, CompilerError(..)
, CompileError(..)
, CompileWarning(..)
, Suggestion(..)
, SuccessResult(..)
, FailedResult(..)
, CompileResult(..)
, get
, compile
) where
import Prelude
import Affjax (URL, printError)
import Affjax as AX
import Affjax.RequestBody as AXRB
import Affjax.ResponseFormat as AXRF
import Affjax.StatusCode (StatusCode(..))
import Control.Alt ((<|>))
import Control.Monad.Except (ExceptT(..))
import Data.Argonaut.Decode (class DecodeJson, decodeJson, (.:))
import Data.Either (Either(..))
import Data.Maybe (Maybe(..))
import Data.Traversable (traverse)
import Effect.Aff (Aff)
-- | The range of text associated with an error
type ErrorPosition =
{ startLine :: Int
, endLine :: Int
, startColumn :: Int
, endColumn :: Int
}
type CompilerError =
{ message :: String
, position :: Maybe ErrorPosition
}
-- | An error reported from the compile API.
data CompileError
= CompilerErrors (Array CompilerError)
| OtherError String
instance decodeJsonCompileError :: DecodeJson CompileError where
decodeJson = decodeJson >=> \obj -> do
contents <- obj .: "contents"
obj .: "tag" >>= case _ of
"OtherError" ->
map OtherError $ decodeJson contents
"CompilerErrors" ->
map CompilerErrors $ traverse decodeJson =<< decodeJson contents
_ ->
Left "Tag must be one of: OtherError, CompilerErrors"
type Suggestion =
{ replacement :: String
, replaceRange :: Maybe ErrorPosition
}
type CompileWarning =
{ errorCode :: String
, message :: String
, position :: Maybe ErrorPosition
, suggestion :: Maybe Suggestion
}
type SuccessResult =
{ js :: String
, warnings :: Maybe (Array CompileWarning)
}
type FailedResult =
{ error :: CompileError
}
-- | The result of calling the compile API.
data CompileResult
= CompileSuccess SuccessResult
| CompileFailed FailedResult
-- | Parse the result from the compile API and verify it
instance decodeJsonCompileResult :: DecodeJson CompileResult where
decodeJson json =
map CompileSuccess (decodeJson json)
<|> map CompileFailed (decodeJson json)
get :: URL -> ExceptT String Aff String
get url = ExceptT $ AX.get AXRF.string url >>= case _ of
Left e ->
pure $ Left $ printError e
Right { status } | status >= StatusCode 400 ->
pure $ Left $ "Received error status code: " <> show status
Right { body } ->
pure $ Right body
-- | POST the specified code to the Try PureScript API, and wait for a response.
compile :: String -> String -> ExceptT String Aff (Either String CompileResult)
compile endpoint code = ExceptT $ AX.post AXRF.json (endpoint <> "/compile") requestBody >>= case _ of
Left e ->
pure $ Left $ printError e
Right { status } | status >= StatusCode 400 ->
pure $ Left $ "Received error status code: " <> show status
Right { body } ->
pure $ Right $ decodeJson body
where
requestBody = Just $ AXRB.string code