Add PreApi for getting unavailable values
parent
c844c94564
commit
68d93180c1
|
@ -1,12 +1,18 @@
|
|||
module Internal.Api.All exposing (..)
|
||||
|
||||
import Hash
|
||||
import Internal.Api.GetEvent.Main as GetEvent
|
||||
import Internal.Api.JoinedMembers.Main as JoinedMembers
|
||||
import Internal.Api.PreApi.Main as PreApi
|
||||
import Internal.Api.PreApi.Objects.Versions as V
|
||||
import Internal.Api.SendMessageEvent.Main as SendMessageEvent
|
||||
import Internal.Api.SendStateKey.Main as SendStateKey
|
||||
import Internal.Api.Sync.Main as Sync
|
||||
import Internal.Api.Versions.Main as Versions
|
||||
import Internal.Tools.Exceptions as X
|
||||
import Internal.Tools.LoginValues exposing (AccessToken)
|
||||
import Internal.Tools.SpecEnums as Enums
|
||||
import Internal.Tools.ValueGetter as VG
|
||||
import Json.Encode as E
|
||||
import Task exposing (Task)
|
||||
|
||||
|
||||
|
@ -14,43 +20,161 @@ type alias Future a =
|
|||
Task X.Error a
|
||||
|
||||
|
||||
type alias GetEventInput =
|
||||
{ accessToken : AccessToken
|
||||
, baseUrl : String
|
||||
, eventId : String
|
||||
, roomId : String
|
||||
, versions : Maybe V.Versions
|
||||
}
|
||||
|
||||
|
||||
{-| Get a specific event from the Matrix API.
|
||||
-}
|
||||
getEvent : List String -> Maybe (GetEvent.EventInput -> Future GetEvent.EventOutput)
|
||||
getEvent =
|
||||
getEvent : GetEventInput -> Future GetEvent.EventOutput
|
||||
getEvent data =
|
||||
VG.withInfo2
|
||||
(\accessToken versions ->
|
||||
GetEvent.getEvent
|
||||
versions.versions
|
||||
{ accessToken = accessToken
|
||||
, baseUrl = data.baseUrl
|
||||
, eventId = data.eventId
|
||||
, roomId = data.roomId
|
||||
}
|
||||
)
|
||||
(PreApi.accessToken data.baseUrl data.accessToken)
|
||||
(PreApi.versions data.baseUrl data.versions)
|
||||
|
||||
|
||||
type alias JoinedMembersInput =
|
||||
{ accessToken : AccessToken
|
||||
, baseUrl : String
|
||||
, roomId : String
|
||||
, versions : Maybe V.Versions
|
||||
}
|
||||
|
||||
|
||||
{-| Get a list of members who are part of a Matrix room.
|
||||
-}
|
||||
joinedMembers : List String -> Maybe (JoinedMembers.JoinedMembersInput -> Future JoinedMembers.JoinedMembersOutput)
|
||||
joinedMembers =
|
||||
joinedMembers : JoinedMembersInput -> Future JoinedMembers.JoinedMembersOutput
|
||||
joinedMembers data =
|
||||
VG.withInfo2
|
||||
(\accessToken versions ->
|
||||
JoinedMembers.joinedMembers
|
||||
versions.versions
|
||||
{ accessToken = accessToken
|
||||
, baseUrl = data.baseUrl
|
||||
, roomId = data.roomId
|
||||
}
|
||||
)
|
||||
(PreApi.accessToken data.baseUrl data.accessToken)
|
||||
(PreApi.versions data.baseUrl data.versions)
|
||||
|
||||
|
||||
type alias SendMessageEventInput =
|
||||
{ accessToken : AccessToken
|
||||
, baseUrl : String
|
||||
, content : E.Value
|
||||
, eventType : String
|
||||
, roomId : String
|
||||
, versions : Maybe V.Versions
|
||||
, extraTransactionNoise : String
|
||||
}
|
||||
|
||||
|
||||
{-| Send a message event into a Matrix room.
|
||||
-}
|
||||
sendMessageEvent : List String -> Maybe (SendMessageEvent.SendMessageEventInput -> Future SendMessageEvent.SendMessageEventOutput)
|
||||
sendMessageEvent =
|
||||
sendMessageEvent : SendMessageEventInput -> Future SendMessageEvent.SendMessageEventOutput
|
||||
sendMessageEvent data =
|
||||
VG.withInfo3
|
||||
(\accessToken versions transactionId ->
|
||||
SendMessageEvent.sendMessageEvent
|
||||
versions.versions
|
||||
{ accessToken = accessToken
|
||||
, baseUrl = data.baseUrl
|
||||
, content = data.content
|
||||
, eventType = data.eventType
|
||||
, roomId = data.roomId
|
||||
, transactionId = transactionId
|
||||
}
|
||||
)
|
||||
(PreApi.accessToken data.baseUrl data.accessToken)
|
||||
(PreApi.versions data.baseUrl data.versions)
|
||||
(PreApi.transactionId
|
||||
(\timestamp ->
|
||||
[ Hash.fromInt timestamp
|
||||
, Hash.fromString data.baseUrl
|
||||
, Hash.fromString data.eventType
|
||||
, Hash.fromString data.roomId
|
||||
, Hash.fromString data.extraTransactionNoise
|
||||
]
|
||||
|> List.foldl Hash.dependent (Hash.fromInt 0)
|
||||
|> Hash.toString
|
||||
|> (++) "elm"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
type alias SendStateKeyInput =
|
||||
{ accessToken : AccessToken
|
||||
, baseUrl : String
|
||||
, content : E.Value
|
||||
, eventType : String
|
||||
, roomId : String
|
||||
, stateKey : String
|
||||
, versions : Maybe V.Versions
|
||||
}
|
||||
|
||||
|
||||
{-| Send a state event into a Matrix room.
|
||||
-}
|
||||
sendStateEvent : List String -> Maybe (SendStateKey.SendStateKeyInput -> Future SendStateKey.SendStateKeyOutput)
|
||||
sendStateEvent =
|
||||
sendStateEvent : SendStateKeyInput -> Future SendStateKey.SendStateKeyOutput
|
||||
sendStateEvent data =
|
||||
VG.withInfo2
|
||||
(\accessToken versions ->
|
||||
SendStateKey.sendStateKey
|
||||
versions.versions
|
||||
{ accessToken = accessToken
|
||||
, baseUrl = data.baseUrl
|
||||
, content = data.content
|
||||
, eventType = data.eventType
|
||||
, roomId = data.roomId
|
||||
, stateKey = data.stateKey
|
||||
}
|
||||
)
|
||||
(PreApi.accessToken data.baseUrl data.accessToken)
|
||||
(PreApi.versions data.baseUrl data.versions)
|
||||
|
||||
|
||||
type alias SyncInput =
|
||||
{ accessToken : AccessToken
|
||||
, baseUrl : String
|
||||
, filter : Maybe String
|
||||
, fullState : Maybe Bool
|
||||
, setPresence : Maybe Enums.UserPresence
|
||||
, since : Maybe String
|
||||
, timeout : Maybe Int
|
||||
, versions : Maybe V.Versions
|
||||
}
|
||||
|
||||
|
||||
{-| Get the latest sync from the Matrix API.
|
||||
-}
|
||||
syncCredentials : List String -> Maybe (Sync.SyncInput -> Future Sync.SyncOutput)
|
||||
syncCredentials =
|
||||
syncCredentials : SyncInput -> Future Sync.SyncOutput
|
||||
syncCredentials data =
|
||||
VG.withInfo2
|
||||
(\accessToken versions ->
|
||||
Sync.sync
|
||||
|
||||
|
||||
{-| Get all supported versions on the Matrix homeserver.
|
||||
-}
|
||||
versions : Versions.VersionsInput -> Versions.VersionsOutput
|
||||
versions =
|
||||
Versions.getVersions
|
||||
versions.versions
|
||||
{ accessToken = accessToken
|
||||
, baseUrl = data.baseUrl
|
||||
, filter = data.filter
|
||||
, fullState = data.fullState
|
||||
, setPresence = data.setPresence
|
||||
, since = data.since
|
||||
, timeout = data.timeout
|
||||
}
|
||||
)
|
||||
(PreApi.accessToken data.baseUrl data.accessToken)
|
||||
(PreApi.versions data.baseUrl data.versions)
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
module Internal.Api.CredUpdate exposing (getEvent, joinedMembers, sendMessage, sendState, sync)
|
||||
{-| Sometimes, the `Credentials` type needs to refresh its tokens, log in again,
|
||||
change some state or adjust its values to be able to keep talking to the server.
|
||||
|
||||
That's what the `CredUpdate` type is for. It is a list of changes that the
|
||||
`Credentials` type needs to make.
|
||||
-}
|
||||
|
||||
import Internal.Api.GetEvent.Main as GetEvent
|
||||
import Internal.Api.Helpers as H
|
||||
import Internal.Api.JoinedMembers.Main as JoinedMembers
|
||||
import Internal.Api.SendMessageEvent.Main as SendMessageEvent
|
||||
import Internal.Api.SendStateKey.Main as SendStateKey
|
||||
import Internal.Api.Sync.Main as Sync
|
||||
import Internal.Api.Versions.Main as Versions
|
||||
import Internal.Tools.Exceptions as X
|
||||
import Task exposing (Task)
|
||||
|
||||
type CredUpdate
|
||||
= MultipleChanges (List CredUpdate)
|
||||
| EventDetails GetEvent.EventOutput
|
||||
| RoomMemberList JoinedMembers.JoinedMembersOutput
|
||||
| MessageEventSent SendMessageEvent.SendMessageEventOutput
|
||||
| StateEventSent SendStateKey.SendStateKeyOutput
|
||||
| SyncReceived Sync.SyncOutput
|
||||
| VersionReceived Versions.VersionsOutput
|
||||
|
||||
type alias Updater = Task X.Error CredUpdate
|
||||
|
||||
getEvent : Maybe (List String) -> GetEvent.EventInput -> Updater
|
||||
getEvent versions =
|
||||
maybeWithVersions
|
||||
{ maybeVersions = versions
|
||||
, f = GetEvent.getEvent
|
||||
, toUpdate = EventDetails
|
||||
}
|
||||
>> H.retryTask 2
|
||||
|
||||
joinedMembers : Maybe (List String) -> JoinedMembers.JoinedMembersInput -> Updater
|
||||
joinedMembers versions =
|
||||
maybeWithVersions
|
||||
{ maybeVersions = versions
|
||||
, f = JoinedMembers.joinedMembers
|
||||
, toUpdate = RoomMemberList
|
||||
}
|
||||
|
||||
sendMessage : Maybe (List String) -> SendMessageEvent.SendMessageEventInput -> Updater
|
||||
sendMessage versions =
|
||||
maybeWithVersions
|
||||
{ maybeVersions = versions
|
||||
, f = SendMessageEvent.sendMessageEvent
|
||||
, toUpdate = MessageEventSent
|
||||
}
|
||||
>> H.retryTask 5
|
||||
|
||||
sendState : Maybe (List String) -> SendStateKey.SendStateKeyInput -> Updater
|
||||
sendState versions =
|
||||
maybeWithVersions
|
||||
{ maybeVersions = versions
|
||||
, f = SendStateKey.sendStateKey
|
||||
, toUpdate = StateEventSent
|
||||
}
|
||||
>> H.retryTask 5
|
||||
|
||||
sync : Maybe (List String) -> Sync.SyncInput -> Updater
|
||||
sync versions =
|
||||
maybeWithVersions
|
||||
{ maybeVersions = versions
|
||||
, f = Sync.sync
|
||||
, toUpdate = SyncReceived
|
||||
}
|
||||
>> H.retryTask 1
|
||||
|
||||
|
||||
maybeWithVersions :
|
||||
{ maybeVersions : Maybe (List String)
|
||||
, f : (List String -> Maybe ({ in | baseUrl : String } -> Task X.Error out))
|
||||
, toUpdate : (out -> CredUpdate)
|
||||
} ->
|
||||
{ in | baseUrl : String } -> Updater
|
||||
maybeWithVersions {maybeVersions, f, toUpdate} params =
|
||||
case maybeVersions of
|
||||
Just versions ->
|
||||
case f versions of
|
||||
Just task ->
|
||||
task params
|
||||
|> Task.map toUpdate
|
||||
Nothing ->
|
||||
Task.fail X.UnsupportedSpecVersion
|
||||
|
||||
Nothing ->
|
||||
Versions.getVersions params.baseUrl
|
||||
|> Task.andThen
|
||||
(\versions ->
|
||||
maybeWithVersions (Just versions.supportedVersions) f toUpdate params
|
||||
|> Task.map
|
||||
(\update ->
|
||||
MultipleChanges
|
||||
[ update
|
||||
, VersionReceived versions
|
||||
]
|
||||
)
|
||||
)
|
||||
|
|
@ -6,7 +6,7 @@ import Internal.Tools.VersionControl as VC
|
|||
import Task exposing (Task)
|
||||
|
||||
|
||||
getEvent : List String -> Maybe (EventInput -> Task X.Error EventOutput)
|
||||
getEvent : List String -> EventInput -> Task X.Error EventOutput
|
||||
getEvent versions =
|
||||
VC.withBottomLayer
|
||||
{ current = Api.getEventInputV1
|
||||
|
@ -20,6 +20,7 @@ getEvent versions =
|
|||
|> VC.sameForVersion "v1.4"
|
||||
|> VC.sameForVersion "v1.5"
|
||||
|> VC.mostRecentFromVersionList versions
|
||||
|> Maybe.withDefault (always <| Task.fail X.UnsupportedSpecVersion)
|
||||
|
||||
|
||||
type alias EventOutput =
|
||||
|
|
|
@ -6,7 +6,7 @@ import Internal.Tools.VersionControl as VC
|
|||
import Task exposing (Task)
|
||||
|
||||
|
||||
joinedMembers : List String -> Maybe (JoinedMembersInput -> Task X.Error JoinedMembersOutput)
|
||||
joinedMembers : List String -> JoinedMembersInput -> Task X.Error JoinedMembersOutput
|
||||
joinedMembers versions =
|
||||
VC.withBottomLayer
|
||||
{ current = Api.joinedMembersV1
|
||||
|
@ -31,6 +31,7 @@ joinedMembers versions =
|
|||
|> VC.sameForVersion "v1.4"
|
||||
|> VC.sameForVersion "v1.5"
|
||||
|> VC.mostRecentFromVersionList versions
|
||||
|> Maybe.withDefault (always <| Task.fail X.UnsupportedSpecVersion)
|
||||
|
||||
|
||||
type alias JoinedMembersInput =
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
module Internal.Api.PreApi.Main exposing (..)
|
||||
|
||||
{-| Certain values are required knowledge for (almost) every endpoint.
|
||||
Some values aren't known right away, however.
|
||||
|
||||
This module takes care of values like access tokens, transaction ids and spec version lists
|
||||
that the credentials type needs to know about before it can make a request.
|
||||
|
||||
-}
|
||||
|
||||
import Internal.Api.PreApi.Objects.Versions as V
|
||||
import Internal.Api.Request as R
|
||||
import Internal.Tools.Exceptions as X
|
||||
import Internal.Tools.LoginValues exposing (AccessToken(..))
|
||||
import Internal.Tools.ValueGetter exposing (ValueGetter)
|
||||
import Task
|
||||
import Time
|
||||
|
||||
|
||||
accessToken : String -> AccessToken -> ValueGetter String
|
||||
accessToken baseUrl t =
|
||||
{ value =
|
||||
case t of
|
||||
NoAccess ->
|
||||
Nothing
|
||||
|
||||
AccessToken token ->
|
||||
Just token
|
||||
|
||||
UsernameAndPassword { token } ->
|
||||
token
|
||||
, getValue =
|
||||
"Automated login yet needs to be implemented."
|
||||
|> X.NotSupportedYet
|
||||
|> X.SDKException
|
||||
|> Task.fail
|
||||
}
|
||||
|
||||
|
||||
transactionId : (Int -> String) -> ValueGetter String
|
||||
transactionId seeder =
|
||||
{ value = Nothing
|
||||
, getValue =
|
||||
Time.now
|
||||
|> Task.map Time.posixToMillis
|
||||
|> Task.map seeder
|
||||
}
|
||||
|
||||
|
||||
versions : String -> Maybe V.Versions -> ValueGetter V.Versions
|
||||
versions baseUrl mVersions =
|
||||
{ value = mVersions
|
||||
, getValue =
|
||||
R.rawApiCall
|
||||
{ headers = R.NoHeaders
|
||||
, method = "GET"
|
||||
, baseUrl = baseUrl
|
||||
, path = "/_matrix/client/versions"
|
||||
, pathParams = []
|
||||
, queryParams = []
|
||||
, bodyParams = []
|
||||
, timeout = Nothing
|
||||
, decoder = \_ -> V.versionsDecoder
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
module Internal.Api.PreApi.Objects.Versions exposing
|
||||
( Versions
|
||||
, encodeVersions
|
||||
, versionsDecoder
|
||||
)
|
||||
|
||||
{-| Automatically generated 'Versions'
|
||||
|
||||
Last generated at Unix time 1677064309
|
||||
|
||||
-}
|
||||
|
||||
import Dict exposing (Dict)
|
||||
import Internal.Tools.DecodeExtra exposing (opField, opFieldWithDefault)
|
||||
import Internal.Tools.EncodeExtra exposing (maybeObject)
|
||||
import Json.Decode as D
|
||||
import Json.Encode as E
|
||||
|
||||
|
||||
{-| Information on what the homeserver supports.
|
||||
-}
|
||||
type alias Versions =
|
||||
{ unstableFeatures : Dict String Bool
|
||||
, versions : List String
|
||||
}
|
||||
|
||||
|
||||
encodeVersions : Versions -> E.Value
|
||||
encodeVersions data =
|
||||
maybeObject
|
||||
[ ( "unstable_features", Just <| E.dict identity E.bool data.unstableFeatures )
|
||||
, ( "versions", Just <| E.list E.string data.versions )
|
||||
]
|
||||
|
||||
|
||||
versionsDecoder : D.Decoder Versions
|
||||
versionsDecoder =
|
||||
D.map2
|
||||
(\a b ->
|
||||
{ unstableFeatures = a, versions = b }
|
||||
)
|
||||
(opFieldWithDefault "unstable_features" Dict.empty (D.dict D.bool))
|
||||
(D.field "versions" (D.list D.string))
|
|
@ -0,0 +1,12 @@
|
|||
version: V_all
|
||||
name: Versions
|
||||
objects:
|
||||
Versions:
|
||||
description: Information on what the homeserver supports.
|
||||
fields:
|
||||
unstable_features:
|
||||
type: "{bool}"
|
||||
default: Dict.empty
|
||||
versions:
|
||||
type: "[string]"
|
||||
required: true
|
|
@ -6,7 +6,7 @@ import Internal.Tools.VersionControl as VC
|
|||
import Task exposing (Task)
|
||||
|
||||
|
||||
sendMessageEvent : List String -> Maybe (SendMessageEventInput -> Task X.Error SendMessageEventOutput)
|
||||
sendMessageEvent : List String -> SendMessageEventInput -> Task X.Error SendMessageEventOutput
|
||||
sendMessageEvent versions =
|
||||
VC.withBottomLayer
|
||||
{ current = Api.sendMessageEventV1
|
||||
|
@ -31,6 +31,7 @@ sendMessageEvent versions =
|
|||
|> VC.sameForVersion "v1.4"
|
||||
|> VC.sameForVersion "v1.5"
|
||||
|> VC.mostRecentFromVersionList versions
|
||||
|> Maybe.withDefault (always <| Task.fail X.UnsupportedSpecVersion)
|
||||
|
||||
|
||||
type alias SendMessageEventInput =
|
||||
|
|
|
@ -6,7 +6,7 @@ import Internal.Tools.VersionControl as VC
|
|||
import Task exposing (Task)
|
||||
|
||||
|
||||
sendStateKey : List String -> Maybe (SendStateKeyInput -> Task X.Error SendStateKeyOutput)
|
||||
sendStateKey : List String -> SendStateKeyInput -> Task X.Error SendStateKeyOutput
|
||||
sendStateKey versions =
|
||||
VC.withBottomLayer
|
||||
{ current = Api.sendStateKeyV1
|
||||
|
@ -31,6 +31,7 @@ sendStateKey versions =
|
|||
|> VC.sameForVersion "v1.4"
|
||||
|> VC.sameForVersion "v1.5"
|
||||
|> VC.mostRecentFromVersionList versions
|
||||
|> Maybe.withDefault (always <| Task.fail X.UnsupportedSpecVersion)
|
||||
|
||||
|
||||
type alias SendStateKeyInput =
|
||||
|
|
|
@ -45,7 +45,7 @@ syncV1 data =
|
|||
, bodyParams = []
|
||||
, timeout =
|
||||
data.timeout
|
||||
|> Maybe.map ((+) 10000)
|
||||
|> Maybe.map ((*) 1000)
|
||||
|> Maybe.map toFloat
|
||||
, decoder = \_ -> SO1.syncDecoder
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ syncV2 data =
|
|||
, bodyParams = []
|
||||
, timeout =
|
||||
data.timeout
|
||||
|> Maybe.map ((+) 10000)
|
||||
|> Maybe.map ((*) 1000)
|
||||
|> Maybe.map toFloat
|
||||
, decoder = \_ -> SO2.syncDecoder
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import Internal.Tools.VersionControl as VC
|
|||
import Task exposing (Task)
|
||||
|
||||
|
||||
sync : List String -> Maybe (SyncInput -> Task X.Error SyncOutput)
|
||||
sync : List String -> SyncInput -> Task X.Error SyncOutput
|
||||
sync versions =
|
||||
VC.withBottomLayer
|
||||
{ current = Api.syncV1
|
||||
|
@ -22,6 +22,7 @@ sync versions =
|
|||
}
|
||||
|> VC.sameForVersion "v1.5"
|
||||
|> VC.mostRecentFromVersionList versions
|
||||
|> Maybe.withDefault (always <| Task.fail X.UnsupportedSpecVersion)
|
||||
|
||||
|
||||
type alias SyncInput =
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
module Internal.Tools.LoginValues exposing (..)
|
||||
|
||||
|
||||
type AccessToken
|
||||
= NoAccess
|
||||
| AccessToken String
|
||||
| UsernameAndPassword { username : String, password : String, token : Maybe String }
|
||||
|
||||
|
||||
defaultAccessToken : AccessToken
|
||||
defaultAccessToken =
|
||||
NoAccess
|
||||
|
||||
|
||||
fromAccessToken : String -> AccessToken
|
||||
fromAccessToken =
|
||||
AccessToken
|
||||
|
||||
|
||||
fromUsernameAndPassword : String -> String -> AccessToken
|
||||
fromUsernameAndPassword username password =
|
||||
UsernameAndPassword
|
||||
{ username = username
|
||||
, password = password
|
||||
, token = Nothing
|
||||
}
|
||||
|
||||
|
||||
getToken : AccessToken -> Maybe String
|
||||
getToken t =
|
||||
case t of
|
||||
NoAccess ->
|
||||
Nothing
|
||||
|
||||
AccessToken token ->
|
||||
Just token
|
||||
|
||||
UsernameAndPassword { token } ->
|
||||
token
|
||||
|
||||
|
||||
addToken : String -> AccessToken -> AccessToken
|
||||
addToken s t =
|
||||
case t of
|
||||
NoAccess ->
|
||||
AccessToken s
|
||||
|
||||
AccessToken _ ->
|
||||
AccessToken s
|
||||
|
||||
UsernameAndPassword { username, password } ->
|
||||
UsernameAndPassword
|
||||
{ username = username
|
||||
, password = password
|
||||
, token = Just s
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
module Internal.Tools.Timestamp exposing (Timestamp, encodeTimestamp, generateTransactionId, timestampDecoder)
|
||||
module Internal.Tools.Timestamp exposing (Timestamp, encodeTimestamp, timestampDecoder)
|
||||
|
||||
import Json.Decode as D
|
||||
import Json.Encode as E
|
||||
import Task exposing (Task)
|
||||
import Time
|
||||
|
||||
|
||||
|
@ -22,13 +21,3 @@ encodeTimestamp =
|
|||
timestampDecoder : D.Decoder Timestamp
|
||||
timestampDecoder =
|
||||
D.map Time.millisToPosix D.int
|
||||
|
||||
|
||||
{-| Generate a transaction id from the current Unix timestamp
|
||||
-}
|
||||
generateTransactionId : Task x String
|
||||
generateTransactionId =
|
||||
Time.now
|
||||
|> Task.map Time.posixToMillis
|
||||
|> Task.map String.fromInt
|
||||
|> Task.map ((++) "elm")
|
||||
|
|
|
@ -0,0 +1,271 @@
|
|||
module Internal.Tools.ValueGetter exposing (..)
|
||||
|
||||
{-| This module creates task pipelines that help gather information
|
||||
in the Matrix API.
|
||||
|
||||
For example, it might happen that you need to make multiple API calls:
|
||||
|
||||
- Authenticate
|
||||
- Log in
|
||||
- Get a list of channels
|
||||
- Send a message in every room
|
||||
|
||||
For each of these API requests, you might need certain information like
|
||||
which spec version the homeserver supports.
|
||||
|
||||
This module takes care of this. That way, functions can be written simply by
|
||||
saying "I need THESE values" and you will then be able to assign them to each
|
||||
HTTP call that needs that value.
|
||||
|
||||
-}
|
||||
|
||||
import Task exposing (Task)
|
||||
|
||||
|
||||
{-| A ValueGetter type takes care of values that MIGHT be available.
|
||||
If a value is not available, then the task can be used to get a new value.
|
||||
-}
|
||||
type alias ValueGetter a =
|
||||
{ value : Maybe a, getValue : Task x a }
|
||||
|
||||
|
||||
{-| Convert a `ValueGetter` type to a task. If a previous value has already been given,
|
||||
then use that value. Otherwise, use the `getValue` task to get a new value.
|
||||
-}
|
||||
toTask : ValueGetter a -> Task x a
|
||||
toTask { value, getValue } =
|
||||
Maybe.map Task.succeed value
|
||||
|> Maybe.withDefault getValue
|
||||
|
||||
|
||||
withInfo : (a -> Task x result) -> ValueGetter a -> Task x result
|
||||
withInfo task info1 =
|
||||
Task.andThen
|
||||
(\a ->
|
||||
task a
|
||||
)
|
||||
(toTask info1)
|
||||
|
||||
|
||||
withInfo2 :
|
||||
(a -> b -> Task x result)
|
||||
-> ValueGetter a
|
||||
-> ValueGetter b
|
||||
-> Task x result
|
||||
withInfo2 task info1 info2 =
|
||||
Task.andThen
|
||||
(\a ->
|
||||
Task.andThen
|
||||
(\b ->
|
||||
task a b
|
||||
)
|
||||
(toTask info2)
|
||||
)
|
||||
(toTask info1)
|
||||
|
||||
|
||||
withInfo3 :
|
||||
(a -> b -> c -> Task x result)
|
||||
-> ValueGetter a
|
||||
-> ValueGetter b
|
||||
-> ValueGetter c
|
||||
-> Task x result
|
||||
withInfo3 task info1 info2 info3 =
|
||||
Task.andThen
|
||||
(\a ->
|
||||
Task.andThen
|
||||
(\b ->
|
||||
Task.andThen
|
||||
(\c ->
|
||||
task a b c
|
||||
)
|
||||
(toTask info3)
|
||||
)
|
||||
(toTask info2)
|
||||
)
|
||||
(toTask info1)
|
||||
|
||||
|
||||
withInfo4 :
|
||||
(a -> b -> c -> d -> Task x result)
|
||||
-> ValueGetter a
|
||||
-> ValueGetter b
|
||||
-> ValueGetter c
|
||||
-> ValueGetter d
|
||||
-> Task x result
|
||||
withInfo4 task info1 info2 info3 info4 =
|
||||
Task.andThen
|
||||
(\a ->
|
||||
Task.andThen
|
||||
(\b ->
|
||||
Task.andThen
|
||||
(\c ->
|
||||
Task.andThen
|
||||
(\d ->
|
||||
task a b c d
|
||||
)
|
||||
(toTask info4)
|
||||
)
|
||||
(toTask info3)
|
||||
)
|
||||
(toTask info2)
|
||||
)
|
||||
(toTask info1)
|
||||
|
||||
|
||||
withInfo5 :
|
||||
(a -> b -> c -> d -> e -> Task x result)
|
||||
-> ValueGetter a
|
||||
-> ValueGetter b
|
||||
-> ValueGetter c
|
||||
-> ValueGetter d
|
||||
-> ValueGetter e
|
||||
-> Task x result
|
||||
withInfo5 task info1 info2 info3 info4 info5 =
|
||||
Task.andThen
|
||||
(\a ->
|
||||
Task.andThen
|
||||
(\b ->
|
||||
Task.andThen
|
||||
(\c ->
|
||||
Task.andThen
|
||||
(\d ->
|
||||
Task.andThen
|
||||
(\e ->
|
||||
task a b c d e
|
||||
)
|
||||
(toTask info5)
|
||||
)
|
||||
(toTask info4)
|
||||
)
|
||||
(toTask info3)
|
||||
)
|
||||
(toTask info2)
|
||||
)
|
||||
(toTask info1)
|
||||
|
||||
|
||||
withInfo6 :
|
||||
(a -> b -> c -> d -> e -> f -> Task x result)
|
||||
-> ValueGetter a
|
||||
-> ValueGetter b
|
||||
-> ValueGetter c
|
||||
-> ValueGetter d
|
||||
-> ValueGetter e
|
||||
-> ValueGetter f
|
||||
-> Task x result
|
||||
withInfo6 task info1 info2 info3 info4 info5 info6 =
|
||||
Task.andThen
|
||||
(\a ->
|
||||
Task.andThen
|
||||
(\b ->
|
||||
Task.andThen
|
||||
(\c ->
|
||||
Task.andThen
|
||||
(\d ->
|
||||
Task.andThen
|
||||
(\e ->
|
||||
Task.andThen
|
||||
(\f ->
|
||||
task a b c d e f
|
||||
)
|
||||
(toTask info6)
|
||||
)
|
||||
(toTask info5)
|
||||
)
|
||||
(toTask info4)
|
||||
)
|
||||
(toTask info3)
|
||||
)
|
||||
(toTask info2)
|
||||
)
|
||||
(toTask info1)
|
||||
|
||||
|
||||
withInfo7 :
|
||||
(a -> b -> c -> d -> e -> f -> g -> Task x result)
|
||||
-> ValueGetter a
|
||||
-> ValueGetter b
|
||||
-> ValueGetter c
|
||||
-> ValueGetter d
|
||||
-> ValueGetter e
|
||||
-> ValueGetter f
|
||||
-> ValueGetter g
|
||||
-> Task x result
|
||||
withInfo7 task info1 info2 info3 info4 info5 info6 info7 =
|
||||
Task.andThen
|
||||
(\a ->
|
||||
Task.andThen
|
||||
(\b ->
|
||||
Task.andThen
|
||||
(\c ->
|
||||
Task.andThen
|
||||
(\d ->
|
||||
Task.andThen
|
||||
(\e ->
|
||||
Task.andThen
|
||||
(\f ->
|
||||
Task.andThen
|
||||
(\g ->
|
||||
task a b c d e f g
|
||||
)
|
||||
(toTask info7)
|
||||
)
|
||||
(toTask info6)
|
||||
)
|
||||
(toTask info5)
|
||||
)
|
||||
(toTask info4)
|
||||
)
|
||||
(toTask info3)
|
||||
)
|
||||
(toTask info2)
|
||||
)
|
||||
(toTask info1)
|
||||
|
||||
|
||||
withInfo8 :
|
||||
(a -> b -> c -> d -> e -> f -> g -> h -> Task x result)
|
||||
-> ValueGetter a
|
||||
-> ValueGetter b
|
||||
-> ValueGetter c
|
||||
-> ValueGetter d
|
||||
-> ValueGetter e
|
||||
-> ValueGetter f
|
||||
-> ValueGetter g
|
||||
-> ValueGetter h
|
||||
-> Task x result
|
||||
withInfo8 task info1 info2 info3 info4 info5 info6 info7 info8 =
|
||||
Task.andThen
|
||||
(\a ->
|
||||
Task.andThen
|
||||
(\b ->
|
||||
Task.andThen
|
||||
(\c ->
|
||||
Task.andThen
|
||||
(\d ->
|
||||
Task.andThen
|
||||
(\e ->
|
||||
Task.andThen
|
||||
(\f ->
|
||||
Task.andThen
|
||||
(\g ->
|
||||
Task.andThen
|
||||
(\h ->
|
||||
task a b c d e f g h
|
||||
)
|
||||
(toTask info8)
|
||||
)
|
||||
(toTask info7)
|
||||
)
|
||||
(toTask info6)
|
||||
)
|
||||
(toTask info5)
|
||||
)
|
||||
(toTask info4)
|
||||
)
|
||||
(toTask info3)
|
||||
)
|
||||
(toTask info2)
|
||||
)
|
||||
(toTask info1)
|
Loading…
Reference in New Issue