forked from loafle/openapi-generator-original
[elm] Add bearer, task, and sendWithCustomError (#5146)
* [elm] Add bearer support * [elm] Allow mapping request errors By either using `sendWithCustomError` or `task`.
This commit is contained in:
@@ -64,7 +64,7 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
featureSet = getFeatureSet().modify()
|
||||
.includeDocumentationFeatures(DocumentationFeature.Readme)
|
||||
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON))
|
||||
.securityFeatures(EnumSet.noneOf(SecurityFeature.class))
|
||||
.securityFeatures(EnumSet.of(SecurityFeature.BearerToken))
|
||||
.excludeGlobalFeatures(
|
||||
GlobalFeature.XMLStructureDefinitions,
|
||||
GlobalFeature.Callbacks,
|
||||
|
||||
@@ -2,10 +2,13 @@ module Api exposing
|
||||
( Request
|
||||
, request
|
||||
, send
|
||||
, sendWithCustomError
|
||||
, task
|
||||
, map
|
||||
, withBasePath
|
||||
, withTimeout
|
||||
, withTracker
|
||||
, withBearerToken
|
||||
, withHeader
|
||||
, withHeaders
|
||||
)
|
||||
@@ -13,6 +16,7 @@ module Api exposing
|
||||
import Http
|
||||
import Json.Decode
|
||||
import Json.Encode
|
||||
import Task
|
||||
import Url.Builder
|
||||
|
||||
|
||||
@@ -46,18 +50,35 @@ request method path pathParams queryParams headerParams body decoder =
|
||||
|
||||
|
||||
send : (Result Http.Error a -> msg) -> Request a -> Cmd msg
|
||||
send toMsg (Request req) =
|
||||
send toMsg req =
|
||||
sendWithCustomError identity toMsg req
|
||||
|
||||
|
||||
sendWithCustomError : (Http.Error -> e) -> (Result e a -> msg) -> Request a -> Cmd msg
|
||||
sendWithCustomError mapError toMsg (Request req) =
|
||||
Http.request
|
||||
{ method = req.method
|
||||
, headers = req.headers
|
||||
, url = Url.Builder.crossOrigin req.basePath req.pathParams req.queryParams
|
||||
, body = req.body
|
||||
, expect = expectJson toMsg req.decoder
|
||||
, expect = expectJson mapError toMsg 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
|
||||
@@ -87,6 +108,11 @@ 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 ] }
|
||||
@@ -121,36 +147,44 @@ queries =
|
||||
List.filterMap (\(key, value) -> Maybe.map (Url.Builder.string key) value)
|
||||
|
||||
|
||||
expectJson : (Result Http.Error a -> msg) -> Json.Decode.Decoder a -> Http.Expect msg
|
||||
expectJson toMsg decoder =
|
||||
Http.expectStringResponse toMsg <|
|
||||
\response ->
|
||||
case response of
|
||||
Http.BadUrl_ url ->
|
||||
Err (Http.BadUrl url)
|
||||
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)
|
||||
|
||||
Http.Timeout_ ->
|
||||
Err Http.Timeout
|
||||
|
||||
Http.NetworkError_ ->
|
||||
Err Http.NetworkError
|
||||
jsonResolver : Json.Decode.Decoder a -> Http.Resolver Http.Error a
|
||||
jsonResolver decoder =
|
||||
Http.stringResolver (decodeResponse decoder)
|
||||
|
||||
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
|
||||
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)
|
||||
|
||||
Err _ ->
|
||||
decodeBody decoder body
|
||||
Http.Timeout_ ->
|
||||
Err Http.Timeout
|
||||
|
||||
else
|
||||
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 =
|
||||
|
||||
@@ -33,8 +33,8 @@ import Uuid exposing (Uuid){{/includeUuid}}
|
||||
{-| {{{notes}}}
|
||||
-}
|
||||
{{/notes}}
|
||||
{{operationId}} : {{#allParams}}{{^required}}Maybe {{/required}}{{#isListContainer}}List {{/isListContainer}}{{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{#isModel}}Api.Data.{{/isModel}}{{dataType}}{{/datatypeWithEnum}} -> {{/allParams}}Api.Request {{^responses}}(){{/responses}}{{#responses}}{{#-first}}{{^dataType}}(){{/dataType}}{{#isMapContainer}}(Dict.Dict String {{/isMapContainer}}{{#isListContainer}}(List {{/isListContainer}}{{^primitiveType}}{{^isUuid}}Api.Data.{{/isUuid}}{{/primitiveType}}{{#items}}{{#isModel}}Api.Data.{{/isModel}}{{/items}}{{dataType}}{{#isListContainer}}){{/isListContainer}}{{#isMapContainer}}){{/isMapContainer}}{{/-first}}{{/responses}}
|
||||
{{operationId}}{{#allParams}} {{>paramName}}{{/allParams}} =
|
||||
{{operationId}} : {{#allParams}}{{^required}}Maybe {{/required}}{{#isListContainer}}List {{/isListContainer}}{{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{#isModel}}Api.Data.{{/isModel}}{{dataType}}{{/datatypeWithEnum}} -> {{/allParams}}{{#authMethods}}{{#isBasicBearer}}String -> {{/isBasicBearer}}{{/authMethods}}Api.Request {{^responses}}(){{/responses}}{{#responses}}{{#isDefault}}{{^dataType}}(){{/dataType}}{{#isMapContainer}}(Dict.Dict String {{/isMapContainer}}{{#isListContainer}}(List {{/isListContainer}}{{^primitiveType}}{{^isUuid}}Api.Data.{{/isUuid}}{{/primitiveType}}{{#items}}{{#isModel}}Api.Data.{{/isModel}}{{/items}}{{dataType}}{{#isListContainer}}){{/isListContainer}}{{#isMapContainer}}){{/isMapContainer}}{{/isDefault}}{{/responses}}
|
||||
{{operationId}}{{#allParams}} {{>paramName}}{{/allParams}}{{#authMethods}}{{#isBasicBearer}} auth_token{{/isBasicBearer}}{{/authMethods}} =
|
||||
Api.request
|
||||
"{{httpMethod}}"
|
||||
"{{path}}"
|
||||
@@ -42,5 +42,6 @@ import Uuid exposing (Uuid){{/includeUuid}}
|
||||
[{{#queryParams}} ( "{{baseName}}", {{#required}}Just <| {{/required}}{{^required}}Maybe.map {{/required}}{{>paramToString}} {{>paramName}} ){{#-last}} {{/-last}}{{^-last}},{{/-last}}{{/queryParams}}]
|
||||
[{{#headerParams}} ( "{{baseName}}", {{#required}}Just <| {{/required}}{{^required}}Maybe.map {{/required}}{{>paramToString}} {{>paramName}} ){{#-last}} {{/-last}}{{^-last}},{{/-last}}{{/headerParams}}]
|
||||
{{#bodyParam}}({{#required}}Just ({{/required}}{{^required}}Maybe.map {{/required}}{{#isModel}}Api.Data.{{/isModel}}{{>recordFieldValueEncoder}} {{>paramName}}{{#required}}){{/required}}){{/bodyParam}}{{^bodyParam}}Nothing{{/bodyParam}}
|
||||
{{^responses}}(Json.Decode.succeed ()){{/responses}}{{#responses}}{{#isDefault}}{{^dataType}}(Json.Decode.succeed ()){{/dataType}}{{#dataType}}{{>recordFieldValueDecoder}}{{/dataType}}{{/isDefault}}{{/responses}}
|
||||
{{^responses}}(Json.Decode.succeed ()){{/responses}}{{#responses}}{{#isDefault}}{{^dataType}}(Json.Decode.succeed ()){{/dataType}}{{#dataType}}{{>recordFieldValueDecoder}}{{/dataType}}{{/isDefault}}{{/responses}}{{#authMethods}}{{#isBasicBearer}}
|
||||
|> Api.withBearerToken auth_token{{/isBasicBearer}}{{/authMethods}}
|
||||
{{/operation}}{{/operations}}
|
||||
@@ -97,6 +97,16 @@ paths:
|
||||
responses:
|
||||
"200":
|
||||
description: Default response
|
||||
/secured:
|
||||
post:
|
||||
summary: Secured endpoint
|
||||
security:
|
||||
- BearerAuth: []
|
||||
responses:
|
||||
"200":
|
||||
description: Authenticated
|
||||
"401":
|
||||
description: Unauthenticated
|
||||
/uuid:
|
||||
get:
|
||||
parameters:
|
||||
@@ -278,3 +288,8 @@ components:
|
||||
type: string
|
||||
in_the_middle:
|
||||
type: string
|
||||
securitySchemes:
|
||||
BearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
|
||||
@@ -2,10 +2,13 @@ module Api exposing
|
||||
( Request
|
||||
, request
|
||||
, send
|
||||
, sendWithCustomError
|
||||
, task
|
||||
, map
|
||||
, withBasePath
|
||||
, withTimeout
|
||||
, withTracker
|
||||
, withBearerToken
|
||||
, withHeader
|
||||
, withHeaders
|
||||
)
|
||||
@@ -13,6 +16,7 @@ module Api exposing
|
||||
import Http
|
||||
import Json.Decode
|
||||
import Json.Encode
|
||||
import Task
|
||||
import Url.Builder
|
||||
|
||||
|
||||
@@ -46,18 +50,35 @@ request method path pathParams queryParams headerParams body decoder =
|
||||
|
||||
|
||||
send : (Result Http.Error a -> msg) -> Request a -> Cmd msg
|
||||
send toMsg (Request req) =
|
||||
send toMsg req =
|
||||
sendWithCustomError identity toMsg req
|
||||
|
||||
|
||||
sendWithCustomError : (Http.Error -> e) -> (Result e a -> msg) -> Request a -> Cmd msg
|
||||
sendWithCustomError mapError toMsg (Request req) =
|
||||
Http.request
|
||||
{ method = req.method
|
||||
, headers = req.headers
|
||||
, url = Url.Builder.crossOrigin req.basePath req.pathParams req.queryParams
|
||||
, body = req.body
|
||||
, expect = expectJson toMsg req.decoder
|
||||
, expect = expectJson mapError toMsg 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
|
||||
@@ -87,6 +108,11 @@ 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 ] }
|
||||
@@ -121,36 +147,44 @@ queries =
|
||||
List.filterMap (\(key, value) -> Maybe.map (Url.Builder.string key) value)
|
||||
|
||||
|
||||
expectJson : (Result Http.Error a -> msg) -> Json.Decode.Decoder a -> Http.Expect msg
|
||||
expectJson toMsg decoder =
|
||||
Http.expectStringResponse toMsg <|
|
||||
\response ->
|
||||
case response of
|
||||
Http.BadUrl_ url ->
|
||||
Err (Http.BadUrl url)
|
||||
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)
|
||||
|
||||
Http.Timeout_ ->
|
||||
Err Http.Timeout
|
||||
|
||||
Http.NetworkError_ ->
|
||||
Err Http.NetworkError
|
||||
jsonResolver : Json.Decode.Decoder a -> Http.Resolver Http.Error a
|
||||
jsonResolver decoder =
|
||||
Http.stringResolver (decodeResponse decoder)
|
||||
|
||||
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
|
||||
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)
|
||||
|
||||
Err _ ->
|
||||
decodeBody decoder body
|
||||
Http.Timeout_ ->
|
||||
Err Http.Timeout
|
||||
|
||||
else
|
||||
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 =
|
||||
|
||||
@@ -18,6 +18,7 @@ module Api.Request.Default exposing
|
||||
, maybeGet
|
||||
, pathStringIntegerEnumerationGet, Enumeration(..), enumerationVariants
|
||||
, queryGet, Enum(..), enumVariants
|
||||
, securedPost
|
||||
, uuidGet
|
||||
)
|
||||
|
||||
@@ -165,6 +166,20 @@ queryGet string_query int_query enum_query =
|
||||
|
||||
|
||||
|
||||
securedPost : String -> Api.Request ()
|
||||
securedPost auth_token =
|
||||
Api.request
|
||||
"POST"
|
||||
"/secured"
|
||||
[]
|
||||
[]
|
||||
[]
|
||||
Nothing
|
||||
(Json.Decode.succeed ())
|
||||
|> Api.withBearerToken auth_token
|
||||
|
||||
|
||||
|
||||
uuidGet : Maybe Uuid -> Api.Request Uuid
|
||||
uuidGet value_query =
|
||||
Api.request
|
||||
|
||||
Reference in New Issue
Block a user