Add PreApi for getting unavailable values
parent
c844c94564
commit
68d93180c1
|
@ -1,12 +1,18 @@
|
||||||
module Internal.Api.All exposing (..)
|
module Internal.Api.All exposing (..)
|
||||||
|
|
||||||
|
import Hash
|
||||||
import Internal.Api.GetEvent.Main as GetEvent
|
import Internal.Api.GetEvent.Main as GetEvent
|
||||||
import Internal.Api.JoinedMembers.Main as JoinedMembers
|
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.SendMessageEvent.Main as SendMessageEvent
|
||||||
import Internal.Api.SendStateKey.Main as SendStateKey
|
import Internal.Api.SendStateKey.Main as SendStateKey
|
||||||
import Internal.Api.Sync.Main as Sync
|
import Internal.Api.Sync.Main as Sync
|
||||||
import Internal.Api.Versions.Main as Versions
|
|
||||||
import Internal.Tools.Exceptions as X
|
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)
|
import Task exposing (Task)
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,43 +20,161 @@ type alias Future a =
|
||||||
Task X.Error 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.
|
{-| Get a specific event from the Matrix API.
|
||||||
-}
|
-}
|
||||||
getEvent : List String -> Maybe (GetEvent.EventInput -> Future GetEvent.EventOutput)
|
getEvent : GetEventInput -> Future GetEvent.EventOutput
|
||||||
getEvent =
|
getEvent data =
|
||||||
GetEvent.getEvent
|
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.
|
{-| Get a list of members who are part of a Matrix room.
|
||||||
-}
|
-}
|
||||||
joinedMembers : List String -> Maybe (JoinedMembers.JoinedMembersInput -> Future JoinedMembers.JoinedMembersOutput)
|
joinedMembers : JoinedMembersInput -> Future JoinedMembers.JoinedMembersOutput
|
||||||
joinedMembers =
|
joinedMembers data =
|
||||||
JoinedMembers.joinedMembers
|
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.
|
{-| Send a message event into a Matrix room.
|
||||||
-}
|
-}
|
||||||
sendMessageEvent : List String -> Maybe (SendMessageEvent.SendMessageEventInput -> Future SendMessageEvent.SendMessageEventOutput)
|
sendMessageEvent : SendMessageEventInput -> Future SendMessageEvent.SendMessageEventOutput
|
||||||
sendMessageEvent =
|
sendMessageEvent data =
|
||||||
SendMessageEvent.sendMessageEvent
|
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.
|
{-| Send a state event into a Matrix room.
|
||||||
-}
|
-}
|
||||||
sendStateEvent : List String -> Maybe (SendStateKey.SendStateKeyInput -> Future SendStateKey.SendStateKeyOutput)
|
sendStateEvent : SendStateKeyInput -> Future SendStateKey.SendStateKeyOutput
|
||||||
sendStateEvent =
|
sendStateEvent data =
|
||||||
SendStateKey.sendStateKey
|
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.
|
{-| Get the latest sync from the Matrix API.
|
||||||
-}
|
-}
|
||||||
syncCredentials : List String -> Maybe (Sync.SyncInput -> Future Sync.SyncOutput)
|
syncCredentials : SyncInput -> Future Sync.SyncOutput
|
||||||
syncCredentials =
|
syncCredentials data =
|
||||||
Sync.sync
|
VG.withInfo2
|
||||||
|
(\accessToken versions ->
|
||||||
|
Sync.sync
|
||||||
{-| Get all supported versions on the Matrix homeserver.
|
versions.versions
|
||||||
-}
|
{ accessToken = accessToken
|
||||||
versions : Versions.VersionsInput -> Versions.VersionsOutput
|
, baseUrl = data.baseUrl
|
||||||
versions =
|
, filter = data.filter
|
||||||
Versions.getVersions
|
, 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)
|
import Task exposing (Task)
|
||||||
|
|
||||||
|
|
||||||
getEvent : List String -> Maybe (EventInput -> Task X.Error EventOutput)
|
getEvent : List String -> EventInput -> Task X.Error EventOutput
|
||||||
getEvent versions =
|
getEvent versions =
|
||||||
VC.withBottomLayer
|
VC.withBottomLayer
|
||||||
{ current = Api.getEventInputV1
|
{ current = Api.getEventInputV1
|
||||||
|
@ -20,6 +20,7 @@ getEvent versions =
|
||||||
|> VC.sameForVersion "v1.4"
|
|> VC.sameForVersion "v1.4"
|
||||||
|> VC.sameForVersion "v1.5"
|
|> VC.sameForVersion "v1.5"
|
||||||
|> VC.mostRecentFromVersionList versions
|
|> VC.mostRecentFromVersionList versions
|
||||||
|
|> Maybe.withDefault (always <| Task.fail X.UnsupportedSpecVersion)
|
||||||
|
|
||||||
|
|
||||||
type alias EventOutput =
|
type alias EventOutput =
|
||||||
|
|
|
@ -6,7 +6,7 @@ import Internal.Tools.VersionControl as VC
|
||||||
import Task exposing (Task)
|
import Task exposing (Task)
|
||||||
|
|
||||||
|
|
||||||
joinedMembers : List String -> Maybe (JoinedMembersInput -> Task X.Error JoinedMembersOutput)
|
joinedMembers : List String -> JoinedMembersInput -> Task X.Error JoinedMembersOutput
|
||||||
joinedMembers versions =
|
joinedMembers versions =
|
||||||
VC.withBottomLayer
|
VC.withBottomLayer
|
||||||
{ current = Api.joinedMembersV1
|
{ current = Api.joinedMembersV1
|
||||||
|
@ -31,6 +31,7 @@ joinedMembers versions =
|
||||||
|> VC.sameForVersion "v1.4"
|
|> VC.sameForVersion "v1.4"
|
||||||
|> VC.sameForVersion "v1.5"
|
|> VC.sameForVersion "v1.5"
|
||||||
|> VC.mostRecentFromVersionList versions
|
|> VC.mostRecentFromVersionList versions
|
||||||
|
|> Maybe.withDefault (always <| Task.fail X.UnsupportedSpecVersion)
|
||||||
|
|
||||||
|
|
||||||
type alias JoinedMembersInput =
|
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)
|
import Task exposing (Task)
|
||||||
|
|
||||||
|
|
||||||
sendMessageEvent : List String -> Maybe (SendMessageEventInput -> Task X.Error SendMessageEventOutput)
|
sendMessageEvent : List String -> SendMessageEventInput -> Task X.Error SendMessageEventOutput
|
||||||
sendMessageEvent versions =
|
sendMessageEvent versions =
|
||||||
VC.withBottomLayer
|
VC.withBottomLayer
|
||||||
{ current = Api.sendMessageEventV1
|
{ current = Api.sendMessageEventV1
|
||||||
|
@ -31,6 +31,7 @@ sendMessageEvent versions =
|
||||||
|> VC.sameForVersion "v1.4"
|
|> VC.sameForVersion "v1.4"
|
||||||
|> VC.sameForVersion "v1.5"
|
|> VC.sameForVersion "v1.5"
|
||||||
|> VC.mostRecentFromVersionList versions
|
|> VC.mostRecentFromVersionList versions
|
||||||
|
|> Maybe.withDefault (always <| Task.fail X.UnsupportedSpecVersion)
|
||||||
|
|
||||||
|
|
||||||
type alias SendMessageEventInput =
|
type alias SendMessageEventInput =
|
||||||
|
|
|
@ -6,7 +6,7 @@ import Internal.Tools.VersionControl as VC
|
||||||
import Task exposing (Task)
|
import Task exposing (Task)
|
||||||
|
|
||||||
|
|
||||||
sendStateKey : List String -> Maybe (SendStateKeyInput -> Task X.Error SendStateKeyOutput)
|
sendStateKey : List String -> SendStateKeyInput -> Task X.Error SendStateKeyOutput
|
||||||
sendStateKey versions =
|
sendStateKey versions =
|
||||||
VC.withBottomLayer
|
VC.withBottomLayer
|
||||||
{ current = Api.sendStateKeyV1
|
{ current = Api.sendStateKeyV1
|
||||||
|
@ -31,6 +31,7 @@ sendStateKey versions =
|
||||||
|> VC.sameForVersion "v1.4"
|
|> VC.sameForVersion "v1.4"
|
||||||
|> VC.sameForVersion "v1.5"
|
|> VC.sameForVersion "v1.5"
|
||||||
|> VC.mostRecentFromVersionList versions
|
|> VC.mostRecentFromVersionList versions
|
||||||
|
|> Maybe.withDefault (always <| Task.fail X.UnsupportedSpecVersion)
|
||||||
|
|
||||||
|
|
||||||
type alias SendStateKeyInput =
|
type alias SendStateKeyInput =
|
||||||
|
|
|
@ -45,7 +45,7 @@ syncV1 data =
|
||||||
, bodyParams = []
|
, bodyParams = []
|
||||||
, timeout =
|
, timeout =
|
||||||
data.timeout
|
data.timeout
|
||||||
|> Maybe.map ((+) 10000)
|
|> Maybe.map ((*) 1000)
|
||||||
|> Maybe.map toFloat
|
|> Maybe.map toFloat
|
||||||
, decoder = \_ -> SO1.syncDecoder
|
, decoder = \_ -> SO1.syncDecoder
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ syncV2 data =
|
||||||
, bodyParams = []
|
, bodyParams = []
|
||||||
, timeout =
|
, timeout =
|
||||||
data.timeout
|
data.timeout
|
||||||
|> Maybe.map ((+) 10000)
|
|> Maybe.map ((*) 1000)
|
||||||
|> Maybe.map toFloat
|
|> Maybe.map toFloat
|
||||||
, decoder = \_ -> SO2.syncDecoder
|
, decoder = \_ -> SO2.syncDecoder
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import Internal.Tools.VersionControl as VC
|
||||||
import Task exposing (Task)
|
import Task exposing (Task)
|
||||||
|
|
||||||
|
|
||||||
sync : List String -> Maybe (SyncInput -> Task X.Error SyncOutput)
|
sync : List String -> SyncInput -> Task X.Error SyncOutput
|
||||||
sync versions =
|
sync versions =
|
||||||
VC.withBottomLayer
|
VC.withBottomLayer
|
||||||
{ current = Api.syncV1
|
{ current = Api.syncV1
|
||||||
|
@ -22,6 +22,7 @@ sync versions =
|
||||||
}
|
}
|
||||||
|> VC.sameForVersion "v1.5"
|
|> VC.sameForVersion "v1.5"
|
||||||
|> VC.mostRecentFromVersionList versions
|
|> VC.mostRecentFromVersionList versions
|
||||||
|
|> Maybe.withDefault (always <| Task.fail X.UnsupportedSpecVersion)
|
||||||
|
|
||||||
|
|
||||||
type alias SyncInput =
|
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.Decode as D
|
||||||
import Json.Encode as E
|
import Json.Encode as E
|
||||||
import Task exposing (Task)
|
|
||||||
import Time
|
import Time
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,13 +21,3 @@ encodeTimestamp =
|
||||||
timestampDecoder : D.Decoder Timestamp
|
timestampDecoder : D.Decoder Timestamp
|
||||||
timestampDecoder =
|
timestampDecoder =
|
||||||
D.map Time.millisToPosix D.int
|
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