forked from loafle/openapi-generator-original
203 lines
5.7 KiB
Elm
203 lines
5.7 KiB
Elm
module Api exposing
|
|
( Request
|
|
, request
|
|
, send
|
|
, sendWithCustomError
|
|
, sendWithCustomExpect
|
|
, task
|
|
, map
|
|
, withBasePath
|
|
, withTimeout
|
|
, withTracker
|
|
, withBearerToken
|
|
, withHeader
|
|
, withHeaders
|
|
)
|
|
|
|
import Http
|
|
import Json.Decode
|
|
import Json.Encode
|
|
import Task
|
|
import Url.Builder
|
|
|
|
|
|
type Request a =
|
|
Request
|
|
{ method : String
|
|
, headers : List Http.Header
|
|
, basePath : String
|
|
, pathParams : List String
|
|
, queryParams : List Url.Builder.QueryParameter
|
|
, body : Http.Body
|
|
, decoder : Json.Decode.Decoder a
|
|
, timeout : Maybe Float
|
|
, tracker : Maybe String
|
|
}
|
|
|
|
|
|
request : String -> String -> List ( String, String ) -> List (String, Maybe String) -> List (String, Maybe String) -> Maybe Json.Encode.Value -> Json.Decode.Decoder a -> Request a
|
|
request method path pathParams queryParams headerParams body decoder =
|
|
Request
|
|
{ method = method
|
|
, headers = headers headerParams
|
|
, basePath = "http://localhost:9000"
|
|
, pathParams = interpolatePath path pathParams
|
|
, queryParams = queries queryParams
|
|
, body = Maybe.withDefault Http.emptyBody (Maybe.map Http.jsonBody body)
|
|
, decoder = decoder
|
|
, timeout = Nothing
|
|
, tracker = Nothing
|
|
}
|
|
|
|
|
|
send : (Result Http.Error a -> msg) -> Request a -> Cmd msg
|
|
send toMsg req =
|
|
sendWithCustomError identity toMsg req
|
|
|
|
|
|
sendWithCustomError : (Http.Error -> e) -> (Result e a -> msg) -> Request a -> Cmd msg
|
|
sendWithCustomError mapError toMsg req =
|
|
sendWithCustomExpect (expectJson mapError toMsg) req
|
|
|
|
|
|
sendWithCustomExpect : (Json.Decode.Decoder a -> Http.Expect msg) -> Request a -> Cmd msg
|
|
sendWithCustomExpect expect (Request req) =
|
|
Http.request
|
|
{ method = req.method
|
|
, headers = req.headers
|
|
, url = Url.Builder.crossOrigin req.basePath req.pathParams req.queryParams
|
|
, body = req.body
|
|
, expect = expect req.decoder
|
|
, timeout = req.timeout
|
|
, tracker = req.tracker
|
|
}
|
|
|
|
|
|
task : Request a -> Task.Task Http.Error a
|
|
task (Request req) =
|
|
Http.task
|
|
{ method = req.method
|
|
, headers = req.headers
|
|
, url = Url.Builder.crossOrigin req.basePath req.pathParams req.queryParams
|
|
, body = req.body
|
|
, resolver = jsonResolver req.decoder
|
|
, timeout = req.timeout
|
|
}
|
|
|
|
|
|
map : (a -> b) -> Request a -> Request b
|
|
map fn (Request req) =
|
|
Request
|
|
{ method = req.method
|
|
, headers = req.headers
|
|
, basePath = req.basePath
|
|
, pathParams = req.pathParams
|
|
, queryParams = req.queryParams
|
|
, body = req.body
|
|
, decoder = Json.Decode.map fn req.decoder
|
|
, timeout = req.timeout
|
|
, tracker = req.tracker
|
|
}
|
|
|
|
withBasePath : String -> Request a -> Request a
|
|
withBasePath basePath (Request req) =
|
|
Request { req | basePath = basePath }
|
|
|
|
|
|
withTimeout : Float -> Request a -> Request a
|
|
withTimeout timeout (Request req) =
|
|
Request { req | timeout = Just timeout }
|
|
|
|
|
|
withTracker : String -> Request a -> Request a
|
|
withTracker tracker (Request req) =
|
|
Request { req | tracker = Just tracker }
|
|
|
|
|
|
withBearerToken : String -> Request a -> Request a
|
|
withBearerToken token (Request req) =
|
|
Request { req | headers = Http.header "Authorization" ("Bearer " ++ token) :: req.headers }
|
|
|
|
|
|
withHeader : String -> String -> Request a -> Request a
|
|
withHeader key value (Request req) =
|
|
Request { req | headers = req.headers ++ [ Http.header key value ] }
|
|
|
|
|
|
withHeaders : List ( String, String ) -> Request a -> Request a
|
|
withHeaders headers_ (Request req) =
|
|
Request { req | headers = req.headers ++ headers (List.map (Tuple.mapSecond Just) headers_) }
|
|
|
|
|
|
-- HELPER
|
|
|
|
|
|
headers : List (String, Maybe String) -> List Http.Header
|
|
headers =
|
|
List.filterMap (\(key, value) -> Maybe.map (Http.header key) value)
|
|
|
|
|
|
interpolatePath : String -> List ( String, String ) -> List String
|
|
interpolatePath rawPath pathParams =
|
|
let
|
|
interpolate =
|
|
(\(name, value) path -> String.replace ("{" ++ name ++ "}") value path)
|
|
in
|
|
List.foldl interpolate rawPath pathParams
|
|
|> String.split "/"
|
|
|> List.drop 1
|
|
|
|
|
|
queries : List (String, Maybe String) -> List Url.Builder.QueryParameter
|
|
queries =
|
|
List.filterMap (\(key, value) -> Maybe.map (Url.Builder.string key) value)
|
|
|
|
|
|
expectJson : (Http.Error -> e) -> (Result e a -> msg) -> Json.Decode.Decoder a -> Http.Expect msg
|
|
expectJson mapError toMsg decoder =
|
|
Http.expectStringResponse toMsg (Result.mapError mapError << decodeResponse decoder)
|
|
|
|
|
|
jsonResolver : Json.Decode.Decoder a -> Http.Resolver Http.Error a
|
|
jsonResolver decoder =
|
|
Http.stringResolver (decodeResponse decoder)
|
|
|
|
|
|
decodeResponse : Json.Decode.Decoder a -> Http.Response String -> Result Http.Error a
|
|
decodeResponse decoder response =
|
|
case response of
|
|
Http.BadUrl_ url ->
|
|
Err (Http.BadUrl url)
|
|
|
|
Http.Timeout_ ->
|
|
Err Http.Timeout
|
|
|
|
Http.NetworkError_ ->
|
|
Err Http.NetworkError
|
|
|
|
Http.BadStatus_ metadata _ ->
|
|
Err (Http.BadStatus metadata.statusCode)
|
|
|
|
Http.GoodStatus_ _ body ->
|
|
if String.isEmpty body then
|
|
-- we might 'expect' no body if the return type is `()`
|
|
case Json.Decode.decodeString decoder "{}" of
|
|
Ok value ->
|
|
Ok value
|
|
|
|
Err _ ->
|
|
decodeBody decoder body
|
|
|
|
else
|
|
decodeBody decoder body
|
|
|
|
|
|
decodeBody : Json.Decode.Decoder a -> String -> Result Http.Error a
|
|
decodeBody decoder body =
|
|
case Json.Decode.decodeString decoder body of
|
|
Ok value ->
|
|
Ok value
|
|
|
|
Err err ->
|
|
Err (Http.BadBody (Json.Decode.errorToString err))
|