Refactor Sync endpoint

pull/1/head
Bram van den Heuvel 2023-02-17 11:07:16 +01:00
parent a0f19a3fdc
commit eaa7bc3444
31 changed files with 131 additions and 4517 deletions

View File

@ -1,9 +1,10 @@
module Internal.Api.Sync.Api exposing (..) module Internal.Api.Sync.Api exposing (..)
import Internal.Api.Request as R import Internal.Api.Request as R
import Internal.Api.Sync.V1.SpecObjects as SO1
import Internal.Api.Sync.V2.SpecObjects as SO2
import Internal.Tools.Exceptions as X import Internal.Tools.Exceptions as X
import Internal.Tools.SpecEnums as Enums import Internal.Tools.SpecEnums as Enums
import Json.Decode as D
import Task exposing (Task) import Task exposing (Task)
@ -18,8 +19,15 @@ type alias SyncInputV1 =
} }
syncV1 : D.Decoder a -> (a -> b) -> SyncInputV1 -> Task X.Error b type alias SyncOutputV1 =
syncV1 decoder mapping data = Task X.Error SO1.Sync
type alias SyncOutputV2 =
Task X.Error SO2.Sync
syncV1 : SyncInputV1 -> SyncOutputV1
syncV1 data =
R.rawApiCall R.rawApiCall
{ headers = R.WithAccessToken data.accessToken { headers = R.WithAccessToken data.accessToken
, method = "GET" , method = "GET"
@ -38,5 +46,29 @@ syncV1 decoder mapping data =
data.timeout data.timeout
|> Maybe.map ((+) 10000) |> Maybe.map ((+) 10000)
|> Maybe.map toFloat |> Maybe.map toFloat
, decoder = \_ -> D.map mapping decoder , decoder = \_ -> SO1.syncDecoder
}
syncV2 : SyncInputV1 -> SyncOutputV2
syncV2 data =
R.rawApiCall
{ headers = R.WithAccessToken data.accessToken
, method = "GET"
, baseUrl = data.baseUrl
, path = "/_matrix/client/v3/sync"
, pathParams = []
, queryParams =
[ R.OpQueryParamString "filter" data.filter
, R.OpQueryParamBool "full_state" data.fullState
, R.OpQueryParamString "set_presence" (Maybe.map Enums.fromUserPresence data.setPresence)
, R.OpQueryParamString "since" data.since
, R.OpQueryParamInt "timeout" data.timeout
]
, bodyParams = []
, timeout =
data.timeout
|> Maybe.map ((+) 10000)
|> Maybe.map toFloat
, decoder = \_ -> SO2.syncDecoder
} }

View File

@ -1,23 +1,26 @@
module Internal.Api.Sync.Main exposing (..) module Internal.Api.Sync.Main exposing (..)
import Internal.Api.Sync.Api as Api import Internal.Api.Sync.Api as Api
import Internal.Api.Sync.V1_2.Api as V1_2 import Internal.Api.Sync.V2.Upcast as U2
import Internal.Api.Sync.V1_3.Api as V1_3 import Internal.Tools.VersionControl as VC
import Internal.Api.Sync.V1_4.Api as V1_4 import Task
import Internal.Api.Sync.V1_5.Api as V1_5
import Internal.Api.Sync.V1_5.Objects as O
import Internal.Api.VersionControl as V
import Internal.Tools.Exceptions as X
import Task exposing (Task)
sync : List String -> SyncInput -> SyncOutput sync : List String -> Maybe (SyncInput -> SyncOutput)
sync = sync versions =
V.firstVersion V1_2.packet VC.withBottomLayer
|> V.updateWith V1_3.packet { current = Api.syncV1
|> V.updateWith V1_4.packet , version = "v1.2"
|> V.updateWith V1_5.packet }
|> V.toFunction |> VC.sameForVersion "v1.3"
|> VC.addMiddleLayer
{ current = Api.syncV2
, downcast = identity
, upcast = Task.map U2.upcastSync
, version = "v1.4"
}
|> VC.sameForVersion "v1.5"
|> VC.mostRecentFromVersionList versions
type alias SyncInput = type alias SyncInput =
@ -25,4 +28,4 @@ type alias SyncInput =
type alias SyncOutput = type alias SyncOutput =
Task X.Error O.Sync Api.SyncOutputV2

View File

@ -1,4 +1,4 @@
module Internal.Api.Sync.V1_2.SpecObjects exposing module Internal.Api.Sync.V1.SpecObjects exposing
( AccountData ( AccountData
, ClientEventWithoutRoomId , ClientEventWithoutRoomId
, Ephemeral , Ephemeral
@ -60,7 +60,7 @@ module Internal.Api.Sync.V1_2.SpecObjects exposing
{-| Automatically generated 'SpecObjects' {-| Automatically generated 'SpecObjects'
Last generated at Unix time 1673279712 Last generated at Unix time 1676625734
-} -}

View File

@ -1,4 +1,4 @@
version: v1.2 version: v1
name: SpecObjects name: SpecObjects
objects: objects:
Sync: Sync:

View File

@ -1,17 +0,0 @@
module Internal.Api.Sync.V1_2.Api exposing (..)
import Internal.Api.Sync.Api as Api
import Internal.Api.Sync.V1_2.Convert as C
import Internal.Api.Sync.V1_2.Objects as O
import Internal.Api.Sync.V1_2.SpecObjects as SO
import Internal.Api.Sync.V1_2.Upcast as U
import Internal.Api.VersionControl as V
packet : V.SingleVersion () () Api.SyncInputV1 O.Sync
packet =
{ version = "v1.2"
, downcast = \_ -> ()
, current = Api.syncV1 SO.syncDecoder C.convert
, upcast = U.upcast
}

View File

@ -1,83 +0,0 @@
module Internal.Api.Sync.V1_2.Convert exposing (..)
import Dict
import Internal.Api.Sync.V1_2.Objects as O
import Internal.Api.Sync.V1_2.SpecObjects as SO
convert : SO.Sync -> O.Sync
convert sync =
{ accountData = convertEventHolder sync.accountData
, nextBatch = sync.nextBatch
, presence = convertEventHolder sync.presence
, rooms = Maybe.map convertRooms sync.rooms
}
convertEventHolder : Maybe { a | events : List b } -> List b
convertEventHolder =
Maybe.map .events >> Maybe.withDefault []
convertRooms : SO.Rooms -> O.Rooms
convertRooms rooms =
{ invite =
Dict.map
(\_ -> .inviteState >> Maybe.map .events >> Maybe.withDefault [])
rooms.invite
, join = Dict.map (\_ -> convertJoinedRoom) rooms.join
, knock =
Dict.map
(\_ -> .knockState >> Maybe.map .events >> Maybe.withDefault [])
rooms.knock
, leave = Dict.map (\_ -> convertLeftRoom) rooms.leave
}
convertJoinedRoom : SO.JoinedRoom -> O.JoinedRoom
convertJoinedRoom room =
{ accountData = convertEventHolder room.accountData
, ephemeral = convertEventHolder room.ephemeral
, state = convertEventHolder room.state |> List.map convertClientEventWithoutRoomId
, summary = room.summary
, timeline = Maybe.map convertTimeline room.timeline
, unreadNotifications = room.unreadNotifications
}
convertClientEventWithoutRoomId : SO.ClientEventWithoutRoomId -> O.ClientEventWithoutRoomId
convertClientEventWithoutRoomId event =
{ content = event.content
, eventId = event.eventId
, originServerTs = event.originServerTs
, sender = event.sender
, stateKey = event.stateKey
, contentType = event.contentType
, unsigned = Maybe.map convertUnsigned event.unsigned
}
convertUnsigned : SO.UnsignedData -> O.UnsignedData
convertUnsigned (SO.UnsignedData data) =
O.UnsignedData
{ age = data.age
, prevContent = data.prevContent
, redactedBecause = Maybe.map convertClientEventWithoutRoomId data.redactedBecause
, transactionId = data.transactionId
}
convertTimeline : SO.Timeline -> O.Timeline
convertTimeline timeline =
{ events = List.map convertClientEventWithoutRoomId timeline.events
, limited = timeline.limited
, prevBatch = timeline.prevBatch
}
convertLeftRoom : SO.LeftRoom -> O.LeftRoom
convertLeftRoom room =
{ accountData = convertEventHolder room.accountData
, state = convertEventHolder room.state |> List.map convertClientEventWithoutRoomId
, timeline = Maybe.map convertTimeline room.timeline
}

View File

@ -1,395 +0,0 @@
module Internal.Api.Sync.V1_2.Objects exposing
( BlindEvent
, ClientEventWithoutRoomId
, JoinedRoom
, LeftRoom
, RoomSummary
, Rooms
, StrippedStateEvent
, Sync
, Timeline
, UnreadNotificationCounts
, UnsignedData(..)
, blindEventDecoder
, clientEventWithoutRoomIdDecoder
, encodeBlindEvent
, encodeClientEventWithoutRoomId
, encodeJoinedRoom
, encodeLeftRoom
, encodeRoomSummary
, encodeRooms
, encodeStrippedStateEvent
, encodeSync
, encodeTimeline
, encodeUnreadNotificationCounts
, encodeUnsignedData
, joinedRoomDecoder
, leftRoomDecoder
, roomSummaryDecoder
, roomsDecoder
, strippedStateEventDecoder
, syncDecoder
, timelineDecoder
, unreadNotificationCountsDecoder
, unsignedDataDecoder
)
{-| Automatically generated 'Objects'
Last generated at Unix time 1673279712
-}
import Dict exposing (Dict)
import Internal.Tools.DecodeExtra exposing (opField, opFieldWithDefault)
import Internal.Tools.EncodeExtra exposing (maybeObject)
import Internal.Tools.Timestamp exposing (Timestamp, encodeTimestamp, timestampDecoder)
import Json.Decode as D
import Json.Encode as E
{-| A blind event that does not give context about itself.
-}
type alias BlindEvent =
{ content : E.Value
, contentType : String
}
encodeBlindEvent : BlindEvent -> E.Value
encodeBlindEvent data =
maybeObject
[ ( "content", Just <| data.content )
, ( "type", Just <| E.string data.contentType )
]
blindEventDecoder : D.Decoder BlindEvent
blindEventDecoder =
D.map2
(\a b ->
{ content = a, contentType = b }
)
(D.field "content" D.value)
(D.field "type" D.string)
{-| Client event that has all data except the room id.
-}
type alias ClientEventWithoutRoomId =
{ content : E.Value
, eventId : String
, originServerTs : Timestamp
, sender : String
, stateKey : Maybe String
, contentType : String
, unsigned : Maybe UnsignedData
}
encodeClientEventWithoutRoomId : ClientEventWithoutRoomId -> E.Value
encodeClientEventWithoutRoomId data =
maybeObject
[ ( "content", Just <| data.content )
, ( "event_id", Just <| E.string data.eventId )
, ( "origin_server_ts", Just <| encodeTimestamp data.originServerTs )
, ( "sender", Just <| E.string data.sender )
, ( "state_key", Maybe.map E.string data.stateKey )
, ( "type", Just <| E.string data.contentType )
, ( "unsigned", Maybe.map encodeUnsignedData data.unsigned )
]
clientEventWithoutRoomIdDecoder : D.Decoder ClientEventWithoutRoomId
clientEventWithoutRoomIdDecoder =
D.map7
(\a b c d e f g ->
{ content = a, eventId = b, originServerTs = c, sender = d, stateKey = e, contentType = f, unsigned = g }
)
(D.field "content" D.value)
(D.field "event_id" D.string)
(D.field "origin_server_ts" timestampDecoder)
(D.field "sender" D.string)
(opField "state_key" D.string)
(D.field "type" D.string)
(opField "unsigned" (D.lazy (\_ -> unsignedDataDecoder)))
{-| Room that the user has joined.
-}
type alias JoinedRoom =
{ accountData : List BlindEvent
, ephemeral : List BlindEvent
, state : List ClientEventWithoutRoomId
, summary : Maybe RoomSummary
, timeline : Maybe Timeline
, unreadNotifications : Maybe UnreadNotificationCounts
}
encodeJoinedRoom : JoinedRoom -> E.Value
encodeJoinedRoom data =
maybeObject
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
, ( "ephemeral", Just <| E.list encodeBlindEvent data.ephemeral )
, ( "state", Just <| E.list encodeClientEventWithoutRoomId data.state )
, ( "summary", Maybe.map encodeRoomSummary data.summary )
, ( "timeline", Maybe.map encodeTimeline data.timeline )
, ( "unread_notifications", Maybe.map encodeUnreadNotificationCounts data.unreadNotifications )
]
joinedRoomDecoder : D.Decoder JoinedRoom
joinedRoomDecoder =
D.map6
(\a b c d e f ->
{ accountData = a, ephemeral = b, state = c, summary = d, timeline = e, unreadNotifications = f }
)
(D.field "account_data" (D.list blindEventDecoder))
(D.field "ephemeral" (D.list blindEventDecoder))
(D.field "state" (D.list clientEventWithoutRoomIdDecoder))
(opField "summary" roomSummaryDecoder)
(opField "timeline" timelineDecoder)
(opField "unread_notifications" unreadNotificationCountsDecoder)
{-| Room that the user has left.
-}
type alias LeftRoom =
{ accountData : List BlindEvent
, state : List ClientEventWithoutRoomId
, timeline : Maybe Timeline
}
encodeLeftRoom : LeftRoom -> E.Value
encodeLeftRoom data =
maybeObject
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
, ( "state", Just <| E.list encodeClientEventWithoutRoomId data.state )
, ( "timeline", Maybe.map encodeTimeline data.timeline )
]
leftRoomDecoder : D.Decoder LeftRoom
leftRoomDecoder =
D.map3
(\a b c ->
{ accountData = a, state = b, timeline = c }
)
(D.field "account_data" (D.list blindEventDecoder))
(D.field "state" (D.list clientEventWithoutRoomIdDecoder))
(opField "timeline" timelineDecoder)
{-| Updates to rooms.
-}
type alias Rooms =
{ invite : Dict String (List StrippedStateEvent)
, join : Dict String JoinedRoom
, knock : Dict String (List StrippedStateEvent)
, leave : Dict String LeftRoom
}
encodeRooms : Rooms -> E.Value
encodeRooms data =
maybeObject
[ ( "invite", Just <| E.dict identity (E.list encodeStrippedStateEvent) data.invite )
, ( "join", Just <| E.dict identity encodeJoinedRoom data.join )
, ( "knock", Just <| E.dict identity (E.list encodeStrippedStateEvent) data.knock )
, ( "leave", Just <| E.dict identity encodeLeftRoom data.leave )
]
roomsDecoder : D.Decoder Rooms
roomsDecoder =
D.map4
(\a b c d ->
{ invite = a, join = b, knock = c, leave = d }
)
(opFieldWithDefault "invite" Dict.empty (D.dict (D.list strippedStateEventDecoder)))
(opFieldWithDefault "join" Dict.empty (D.dict joinedRoomDecoder))
(opFieldWithDefault "knock" Dict.empty (D.dict (D.list strippedStateEventDecoder)))
(opFieldWithDefault "leave" Dict.empty (D.dict leftRoomDecoder))
{-| Information about a room which clients may need to correctly render it to users.
-}
type alias RoomSummary =
{ mHeroes : Maybe (List String)
, mInvitedMemberCount : Maybe Int
, mJoinedMemberCount : Maybe Int
}
encodeRoomSummary : RoomSummary -> E.Value
encodeRoomSummary data =
maybeObject
[ ( "m.heroes", Maybe.map (E.list E.string) data.mHeroes )
, ( "m.invited_member_count", Maybe.map E.int data.mInvitedMemberCount )
, ( "m.joined_member_count", Maybe.map E.int data.mJoinedMemberCount )
]
roomSummaryDecoder : D.Decoder RoomSummary
roomSummaryDecoder =
D.map3
(\a b c ->
{ mHeroes = a, mInvitedMemberCount = b, mJoinedMemberCount = c }
)
(opField "m.heroes" (D.list D.string))
(opField "m.invited_member_count" D.int)
(opField "m.joined_member_count" D.int)
{-| Stripped state events of a room that the user has limited access to.
-}
type alias StrippedStateEvent =
{ content : E.Value
, sender : String
, stateKey : String
, contentType : String
}
encodeStrippedStateEvent : StrippedStateEvent -> E.Value
encodeStrippedStateEvent data =
maybeObject
[ ( "content", Just <| data.content )
, ( "sender", Just <| E.string data.sender )
, ( "state_key", Just <| E.string data.stateKey )
, ( "type", Just <| E.string data.contentType )
]
strippedStateEventDecoder : D.Decoder StrippedStateEvent
strippedStateEventDecoder =
D.map4
(\a b c d ->
{ content = a, sender = b, stateKey = c, contentType = d }
)
(D.field "content" D.value)
(D.field "sender" D.string)
(D.field "state_key" D.string)
(D.field "type" D.string)
{-| The sync response the homeserver sends to the user.
-}
type alias Sync =
{ accountData : List BlindEvent
, nextBatch : String
, presence : List BlindEvent
, rooms : Maybe Rooms
}
encodeSync : Sync -> E.Value
encodeSync data =
maybeObject
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
, ( "next_batch", Just <| E.string data.nextBatch )
, ( "presence", Just <| E.list encodeBlindEvent data.presence )
, ( "rooms", Maybe.map encodeRooms data.rooms )
]
syncDecoder : D.Decoder Sync
syncDecoder =
D.map4
(\a b c d ->
{ accountData = a, nextBatch = b, presence = c, rooms = d }
)
(D.field "account_data" (D.list blindEventDecoder))
(D.field "next_batch" D.string)
(D.field "presence" (D.list blindEventDecoder))
(opField "rooms" roomsDecoder)
{-| The timeline of messages and state changes in a room.
-}
type alias Timeline =
{ events : List ClientEventWithoutRoomId
, limited : Bool
, prevBatch : Maybe String
}
encodeTimeline : Timeline -> E.Value
encodeTimeline data =
maybeObject
[ ( "events", Just <| E.list encodeClientEventWithoutRoomId data.events )
, ( "limited", Just <| E.bool data.limited )
, ( "prev_batch", Maybe.map E.string data.prevBatch )
]
timelineDecoder : D.Decoder Timeline
timelineDecoder =
D.map3
(\a b c ->
{ events = a, limited = b, prevBatch = c }
)
(opFieldWithDefault "events" [] (D.list clientEventWithoutRoomIdDecoder))
(opFieldWithDefault "limited" False D.bool)
(opField "prev_batch" D.string)
{-| Counts of unread notifications for this room.
-}
type alias UnreadNotificationCounts =
{ highlightCount : Maybe Int
, notificationCount : Maybe Int
}
encodeUnreadNotificationCounts : UnreadNotificationCounts -> E.Value
encodeUnreadNotificationCounts data =
maybeObject
[ ( "highlight_count", Maybe.map E.int data.highlightCount )
, ( "notification_count", Maybe.map E.int data.notificationCount )
]
unreadNotificationCountsDecoder : D.Decoder UnreadNotificationCounts
unreadNotificationCountsDecoder =
D.map2
(\a b ->
{ highlightCount = a, notificationCount = b }
)
(opField "highlight_count" D.int)
(opField "notification_count" D.int)
{-| Data that isn't getting signed for Canonical JSON.
-}
type UnsignedData
= UnsignedData
{ age : Maybe Int
, prevContent : Maybe E.Value
, redactedBecause : Maybe ClientEventWithoutRoomId
, transactionId : Maybe String
}
encodeUnsignedData : UnsignedData -> E.Value
encodeUnsignedData (UnsignedData data) =
maybeObject
[ ( "age", Maybe.map E.int data.age )
, ( "prev_content", data.prevContent )
, ( "redacted_because", Maybe.map encodeClientEventWithoutRoomId data.redactedBecause )
, ( "transaction_id", Maybe.map E.string data.transactionId )
]
unsignedDataDecoder : D.Decoder UnsignedData
unsignedDataDecoder =
D.map4
(\a b c d ->
UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d }
)
(opField "age" D.int)
(opField "prev_content" D.value)
(opField "redacted_because" clientEventWithoutRoomIdDecoder)
(opField "transaction_id" D.string)

View File

@ -1,152 +0,0 @@
version: v1.2
name: Objects
objects:
Sync:
description: The sync response the homeserver sends to the user.
fields:
account_data:
type: "[BlindEvent]"
required: true
next_batch:
type: string
required: true
presence:
type: "[BlindEvent]"
required: true
rooms:
type: Rooms
BlindEvent:
description: A blind event that does not give context about itself.
fields:
content:
type: value
required: true
type:
type: string
required: true
Rooms:
description: Updates to rooms.
fields:
invite:
type: "{[StrippedStateEvent]}"
required: false
default: Dict.empty
join:
type: "{JoinedRoom}"
required: false
default: Dict.empty
knock:
type: "{[StrippedStateEvent]}"
required: false
default: Dict.empty
leave:
type: "{LeftRoom}"
required: false
default: Dict.empty
StrippedStateEvent:
description: Stripped state events of a room that the user has limited access to.
fields:
content:
type: value
required: true
sender:
type: string
required: true
state_key:
type: string
required: true
type:
type: string
required: true
JoinedRoom:
description: Room that the user has joined.
fields:
account_data:
type: "[BlindEvent]"
required: true
ephemeral:
type: "[BlindEvent]"
required: true
state:
type: "[ClientEventWithoutRoomId]"
required: true
summary:
type: RoomSummary
timeline:
type: Timeline
unread_notifications:
type: UnreadNotificationCounts
ClientEventWithoutRoomId:
description: Client event that has all data except the room id.
fields:
content:
type: value
required: true
event_id:
type: string
required: true
origin_server_ts:
type: timestamp
required: true
sender:
type: string
required: true
state_key:
type: string
type:
type: string
required: true
unsigned:
type: UnsignedData
UnsignedData:
anti_recursion: true
description: Data that isn't getting signed for Canonical JSON.
fields:
age:
type: int
prev_content:
type: value
redacted_because:
type: ClientEventWithoutRoomId
transaction_id:
type: string
RoomSummary:
description: Information about a room which clients may need to correctly render it to users.
fields:
m.heroes:
type: "[string]"
m.invited_member_count:
type: int
m.joined_member_count:
type: int
Timeline:
description: The timeline of messages and state changes in a room.
fields:
events:
type: "[ClientEventWithoutRoomId]"
required: false
default: "[]"
limited:
type: bool
required: false
default: "False"
prev_batch:
type: string
UnreadNotificationCounts:
description: Counts of unread notifications for this room.
fields:
highlight_count:
type: int
notification_count:
type: int
LeftRoom:
description: Room that the user has left.
fields:
account_data:
type: "[BlindEvent]"
required: true
state:
type: "[ClientEventWithoutRoomId]"
required: true
timeline:
type: Timeline

View File

@ -1,13 +0,0 @@
module Internal.Api.Sync.V1_2.Upcast exposing (..)
import Internal.Api.Sync.V1_2.Objects as O
import Internal.Config.Leaking as L
upcast : () -> O.Sync
upcast _ =
{ accountData = []
, nextBatch = L.nextBatch
, presence = []
, rooms = Nothing
}

View File

@ -1,18 +0,0 @@
module Internal.Api.Sync.V1_3.Api exposing (..)
import Internal.Api.Sync.Api as Api
import Internal.Api.Sync.V1_2.Objects as PO
import Internal.Api.Sync.V1_3.Convert as C
import Internal.Api.Sync.V1_3.Objects as O
import Internal.Api.Sync.V1_3.SpecObjects as SO
import Internal.Api.Sync.V1_3.Upcast as U
import Internal.Api.VersionControl as V
packet : V.SingleVersion Api.SyncInputV1 PO.Sync Api.SyncInputV1 O.Sync
packet =
{ version = "v1.3"
, downcast = identity
, current = Api.syncV1 SO.syncDecoder C.convert
, upcast = U.upcast
}

View File

@ -1,95 +0,0 @@
module Internal.Api.Sync.V1_3.Convert exposing (..)
import Dict
import Internal.Api.Sync.V1_3.Objects as O
import Internal.Api.Sync.V1_3.SpecObjects as SO
convert : SO.Sync -> O.Sync
convert sync =
{ accountData = convertEventHolder sync.accountData
, nextBatch = sync.nextBatch
, presence = convertEventHolder sync.presence
, rooms = Maybe.map convertRooms sync.rooms
}
convertEventHolder : Maybe { a | events : List b } -> List b
convertEventHolder =
Maybe.map .events >> Maybe.withDefault []
convertRooms : SO.Rooms -> O.Rooms
convertRooms rooms =
{ invite =
Dict.map
(\_ -> .inviteState >> Maybe.map .events >> Maybe.withDefault [])
rooms.invite
, join = Dict.map (\_ -> convertJoinedRoom) rooms.join
, knock =
Dict.map
(\_ -> .knockState >> Maybe.map .events >> Maybe.withDefault [])
rooms.knock
, leave = Dict.map (\_ -> convertLeftRoom) rooms.leave
}
convertJoinedRoom : SO.JoinedRoom -> O.JoinedRoom
convertJoinedRoom room =
{ accountData = convertEventHolder room.accountData
, ephemeral = convertEventHolder room.ephemeral
, state = convertEventHolder room.state |> List.map convertClientEventWithoutRoomId
, summary = room.summary
, timeline = Maybe.map convertTimeline room.timeline
, unreadNotifications = room.unreadNotifications
}
convertClientEventWithoutRoomId : SO.ClientEventWithoutRoomId -> O.ClientEventWithoutRoomId
convertClientEventWithoutRoomId event =
{ content = event.content
, eventId = event.eventId
, originServerTs = event.originServerTs
, sender = event.sender
, stateKey = event.stateKey
, contentType = event.contentType
, unsigned = Maybe.map convertUnsigned event.unsigned
}
convertUnsigned : SO.UnsignedData -> O.UnsignedData
convertUnsigned (SO.UnsignedData data) =
O.UnsignedData
{ age = data.age
, prevContent = data.prevContent
, redactedBecause = Maybe.map convertToOldBlindEvent data.redactedBecause
, transactionId = data.transactionId
}
convertToOldBlindEvent : SO.ClientEventWithoutRoomId -> O.ClientEventWithoutRoomId
convertToOldBlindEvent event =
{ content = event.content
, eventId = event.eventId
, originServerTs = event.originServerTs
, sender = event.sender
, stateKey = event.stateKey
, contentType = event.contentType
, unsigned = Maybe.map convertUnsigned event.unsigned
}
convertTimeline : SO.Timeline -> O.Timeline
convertTimeline timeline =
{ events = List.map convertClientEventWithoutRoomId timeline.events
, limited = timeline.limited
, prevBatch = timeline.prevBatch
}
convertLeftRoom : SO.LeftRoom -> O.LeftRoom
convertLeftRoom room =
{ accountData = convertEventHolder room.accountData
, state = convertEventHolder room.state |> List.map convertClientEventWithoutRoomId
, timeline = Maybe.map convertTimeline room.timeline
}

View File

@ -1,395 +0,0 @@
module Internal.Api.Sync.V1_3.Objects exposing
( BlindEvent
, ClientEventWithoutRoomId
, JoinedRoom
, LeftRoom
, RoomSummary
, Rooms
, StrippedStateEvent
, Sync
, Timeline
, UnreadNotificationCounts
, UnsignedData(..)
, blindEventDecoder
, clientEventWithoutRoomIdDecoder
, encodeBlindEvent
, encodeClientEventWithoutRoomId
, encodeJoinedRoom
, encodeLeftRoom
, encodeRoomSummary
, encodeRooms
, encodeStrippedStateEvent
, encodeSync
, encodeTimeline
, encodeUnreadNotificationCounts
, encodeUnsignedData
, joinedRoomDecoder
, leftRoomDecoder
, roomSummaryDecoder
, roomsDecoder
, strippedStateEventDecoder
, syncDecoder
, timelineDecoder
, unreadNotificationCountsDecoder
, unsignedDataDecoder
)
{-| Automatically generated 'Objects'
Last generated at Unix time 1673279712
-}
import Dict exposing (Dict)
import Internal.Tools.DecodeExtra exposing (opField, opFieldWithDefault)
import Internal.Tools.EncodeExtra exposing (maybeObject)
import Internal.Tools.Timestamp exposing (Timestamp, encodeTimestamp, timestampDecoder)
import Json.Decode as D
import Json.Encode as E
{-| A blind event that does not give context about itself.
-}
type alias BlindEvent =
{ content : E.Value
, contentType : String
}
encodeBlindEvent : BlindEvent -> E.Value
encodeBlindEvent data =
maybeObject
[ ( "content", Just <| data.content )
, ( "type", Just <| E.string data.contentType )
]
blindEventDecoder : D.Decoder BlindEvent
blindEventDecoder =
D.map2
(\a b ->
{ content = a, contentType = b }
)
(D.field "content" D.value)
(D.field "type" D.string)
{-| Client event that has all data except the room id.
-}
type alias ClientEventWithoutRoomId =
{ content : E.Value
, eventId : String
, originServerTs : Timestamp
, sender : String
, stateKey : Maybe String
, contentType : String
, unsigned : Maybe UnsignedData
}
encodeClientEventWithoutRoomId : ClientEventWithoutRoomId -> E.Value
encodeClientEventWithoutRoomId data =
maybeObject
[ ( "content", Just <| data.content )
, ( "event_id", Just <| E.string data.eventId )
, ( "origin_server_ts", Just <| encodeTimestamp data.originServerTs )
, ( "sender", Just <| E.string data.sender )
, ( "state_key", Maybe.map E.string data.stateKey )
, ( "type", Just <| E.string data.contentType )
, ( "unsigned", Maybe.map encodeUnsignedData data.unsigned )
]
clientEventWithoutRoomIdDecoder : D.Decoder ClientEventWithoutRoomId
clientEventWithoutRoomIdDecoder =
D.map7
(\a b c d e f g ->
{ content = a, eventId = b, originServerTs = c, sender = d, stateKey = e, contentType = f, unsigned = g }
)
(D.field "content" D.value)
(D.field "event_id" D.string)
(D.field "origin_server_ts" timestampDecoder)
(D.field "sender" D.string)
(opField "state_key" D.string)
(D.field "type" D.string)
(opField "unsigned" (D.lazy (\_ -> unsignedDataDecoder)))
{-| Room that the user has joined.
-}
type alias JoinedRoom =
{ accountData : List BlindEvent
, ephemeral : List BlindEvent
, state : List ClientEventWithoutRoomId
, summary : Maybe RoomSummary
, timeline : Maybe Timeline
, unreadNotifications : Maybe UnreadNotificationCounts
}
encodeJoinedRoom : JoinedRoom -> E.Value
encodeJoinedRoom data =
maybeObject
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
, ( "ephemeral", Just <| E.list encodeBlindEvent data.ephemeral )
, ( "state", Just <| E.list encodeClientEventWithoutRoomId data.state )
, ( "summary", Maybe.map encodeRoomSummary data.summary )
, ( "timeline", Maybe.map encodeTimeline data.timeline )
, ( "unread_notifications", Maybe.map encodeUnreadNotificationCounts data.unreadNotifications )
]
joinedRoomDecoder : D.Decoder JoinedRoom
joinedRoomDecoder =
D.map6
(\a b c d e f ->
{ accountData = a, ephemeral = b, state = c, summary = d, timeline = e, unreadNotifications = f }
)
(D.field "account_data" (D.list blindEventDecoder))
(D.field "ephemeral" (D.list blindEventDecoder))
(D.field "state" (D.list clientEventWithoutRoomIdDecoder))
(opField "summary" roomSummaryDecoder)
(opField "timeline" timelineDecoder)
(opField "unread_notifications" unreadNotificationCountsDecoder)
{-| Room that the user has left.
-}
type alias LeftRoom =
{ accountData : List BlindEvent
, state : List ClientEventWithoutRoomId
, timeline : Maybe Timeline
}
encodeLeftRoom : LeftRoom -> E.Value
encodeLeftRoom data =
maybeObject
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
, ( "state", Just <| E.list encodeClientEventWithoutRoomId data.state )
, ( "timeline", Maybe.map encodeTimeline data.timeline )
]
leftRoomDecoder : D.Decoder LeftRoom
leftRoomDecoder =
D.map3
(\a b c ->
{ accountData = a, state = b, timeline = c }
)
(D.field "account_data" (D.list blindEventDecoder))
(D.field "state" (D.list clientEventWithoutRoomIdDecoder))
(opField "timeline" timelineDecoder)
{-| Updates to rooms.
-}
type alias Rooms =
{ invite : Dict String (List StrippedStateEvent)
, join : Dict String JoinedRoom
, knock : Dict String (List StrippedStateEvent)
, leave : Dict String LeftRoom
}
encodeRooms : Rooms -> E.Value
encodeRooms data =
maybeObject
[ ( "invite", Just <| E.dict identity (E.list encodeStrippedStateEvent) data.invite )
, ( "join", Just <| E.dict identity encodeJoinedRoom data.join )
, ( "knock", Just <| E.dict identity (E.list encodeStrippedStateEvent) data.knock )
, ( "leave", Just <| E.dict identity encodeLeftRoom data.leave )
]
roomsDecoder : D.Decoder Rooms
roomsDecoder =
D.map4
(\a b c d ->
{ invite = a, join = b, knock = c, leave = d }
)
(opFieldWithDefault "invite" Dict.empty (D.dict (D.list strippedStateEventDecoder)))
(opFieldWithDefault "join" Dict.empty (D.dict joinedRoomDecoder))
(opFieldWithDefault "knock" Dict.empty (D.dict (D.list strippedStateEventDecoder)))
(opFieldWithDefault "leave" Dict.empty (D.dict leftRoomDecoder))
{-| Information about a room which clients may need to correctly render it to users.
-}
type alias RoomSummary =
{ mHeroes : Maybe (List String)
, mInvitedMemberCount : Maybe Int
, mJoinedMemberCount : Maybe Int
}
encodeRoomSummary : RoomSummary -> E.Value
encodeRoomSummary data =
maybeObject
[ ( "m.heroes", Maybe.map (E.list E.string) data.mHeroes )
, ( "m.invited_member_count", Maybe.map E.int data.mInvitedMemberCount )
, ( "m.joined_member_count", Maybe.map E.int data.mJoinedMemberCount )
]
roomSummaryDecoder : D.Decoder RoomSummary
roomSummaryDecoder =
D.map3
(\a b c ->
{ mHeroes = a, mInvitedMemberCount = b, mJoinedMemberCount = c }
)
(opField "m.heroes" (D.list D.string))
(opField "m.invited_member_count" D.int)
(opField "m.joined_member_count" D.int)
{-| Stripped state events of a room that the user has limited access to.
-}
type alias StrippedStateEvent =
{ content : E.Value
, sender : String
, stateKey : String
, contentType : String
}
encodeStrippedStateEvent : StrippedStateEvent -> E.Value
encodeStrippedStateEvent data =
maybeObject
[ ( "content", Just <| data.content )
, ( "sender", Just <| E.string data.sender )
, ( "state_key", Just <| E.string data.stateKey )
, ( "type", Just <| E.string data.contentType )
]
strippedStateEventDecoder : D.Decoder StrippedStateEvent
strippedStateEventDecoder =
D.map4
(\a b c d ->
{ content = a, sender = b, stateKey = c, contentType = d }
)
(D.field "content" D.value)
(D.field "sender" D.string)
(D.field "state_key" D.string)
(D.field "type" D.string)
{-| The sync response the homeserver sends to the user.
-}
type alias Sync =
{ accountData : List BlindEvent
, nextBatch : String
, presence : List BlindEvent
, rooms : Maybe Rooms
}
encodeSync : Sync -> E.Value
encodeSync data =
maybeObject
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
, ( "next_batch", Just <| E.string data.nextBatch )
, ( "presence", Just <| E.list encodeBlindEvent data.presence )
, ( "rooms", Maybe.map encodeRooms data.rooms )
]
syncDecoder : D.Decoder Sync
syncDecoder =
D.map4
(\a b c d ->
{ accountData = a, nextBatch = b, presence = c, rooms = d }
)
(D.field "account_data" (D.list blindEventDecoder))
(D.field "next_batch" D.string)
(D.field "presence" (D.list blindEventDecoder))
(opField "rooms" roomsDecoder)
{-| The timeline of messages and state changes in a room.
-}
type alias Timeline =
{ events : List ClientEventWithoutRoomId
, limited : Bool
, prevBatch : Maybe String
}
encodeTimeline : Timeline -> E.Value
encodeTimeline data =
maybeObject
[ ( "events", Just <| E.list encodeClientEventWithoutRoomId data.events )
, ( "limited", Just <| E.bool data.limited )
, ( "prev_batch", Maybe.map E.string data.prevBatch )
]
timelineDecoder : D.Decoder Timeline
timelineDecoder =
D.map3
(\a b c ->
{ events = a, limited = b, prevBatch = c }
)
(opFieldWithDefault "events" [] (D.list clientEventWithoutRoomIdDecoder))
(opFieldWithDefault "limited" False D.bool)
(opField "prev_batch" D.string)
{-| Counts of unread notifications for this room.
-}
type alias UnreadNotificationCounts =
{ highlightCount : Maybe Int
, notificationCount : Maybe Int
}
encodeUnreadNotificationCounts : UnreadNotificationCounts -> E.Value
encodeUnreadNotificationCounts data =
maybeObject
[ ( "highlight_count", Maybe.map E.int data.highlightCount )
, ( "notification_count", Maybe.map E.int data.notificationCount )
]
unreadNotificationCountsDecoder : D.Decoder UnreadNotificationCounts
unreadNotificationCountsDecoder =
D.map2
(\a b ->
{ highlightCount = a, notificationCount = b }
)
(opField "highlight_count" D.int)
(opField "notification_count" D.int)
{-| Data that isn't getting signed for Canonical JSON.
-}
type UnsignedData
= UnsignedData
{ age : Maybe Int
, prevContent : Maybe E.Value
, redactedBecause : Maybe ClientEventWithoutRoomId
, transactionId : Maybe String
}
encodeUnsignedData : UnsignedData -> E.Value
encodeUnsignedData (UnsignedData data) =
maybeObject
[ ( "age", Maybe.map E.int data.age )
, ( "prev_content", data.prevContent )
, ( "redacted_because", Maybe.map encodeClientEventWithoutRoomId data.redactedBecause )
, ( "transaction_id", Maybe.map E.string data.transactionId )
]
unsignedDataDecoder : D.Decoder UnsignedData
unsignedDataDecoder =
D.map4
(\a b c d ->
UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d }
)
(opField "age" D.int)
(opField "prev_content" D.value)
(opField "redacted_because" clientEventWithoutRoomIdDecoder)
(opField "transaction_id" D.string)

View File

@ -1,152 +0,0 @@
version: v1.3
name: Objects
objects:
Sync:
description: The sync response the homeserver sends to the user.
fields:
account_data:
type: "[BlindEvent]"
required: true
next_batch:
type: string
required: true
presence:
type: "[BlindEvent]"
required: true
rooms:
type: Rooms
BlindEvent:
description: A blind event that does not give context about itself.
fields:
content:
type: value
required: true
type:
type: string
required: true
Rooms:
description: Updates to rooms.
fields:
invite:
type: "{[StrippedStateEvent]}"
required: false
default: Dict.empty
join:
type: "{JoinedRoom}"
required: false
default: Dict.empty
knock:
type: "{[StrippedStateEvent]}"
required: false
default: Dict.empty
leave:
type: "{LeftRoom}"
required: false
default: Dict.empty
StrippedStateEvent:
description: Stripped state events of a room that the user has limited access to.
fields:
content:
type: value
required: true
sender:
type: string
required: true
state_key:
type: string
required: true
type:
type: string
required: true
JoinedRoom:
description: Room that the user has joined.
fields:
account_data:
type: "[BlindEvent]"
required: true
ephemeral:
type: "[BlindEvent]"
required: true
state:
type: "[ClientEventWithoutRoomId]"
required: true
summary:
type: RoomSummary
timeline:
type: Timeline
unread_notifications:
type: UnreadNotificationCounts
ClientEventWithoutRoomId:
description: Client event that has all data except the room id.
fields:
content:
type: value
required: true
event_id:
type: string
required: true
origin_server_ts:
type: timestamp
required: true
sender:
type: string
required: true
state_key:
type: string
type:
type: string
required: true
unsigned:
type: UnsignedData
UnsignedData:
anti_recursion: true
description: Data that isn't getting signed for Canonical JSON.
fields:
age:
type: int
prev_content:
type: value
redacted_because:
type: ClientEventWithoutRoomId
transaction_id:
type: string
RoomSummary:
description: Information about a room which clients may need to correctly render it to users.
fields:
m.heroes:
type: "[string]"
m.invited_member_count:
type: int
m.joined_member_count:
type: int
Timeline:
description: The timeline of messages and state changes in a room.
fields:
events:
type: "[ClientEventWithoutRoomId]"
required: false
default: "[]"
limited:
type: bool
required: false
default: "False"
prev_batch:
type: string
UnreadNotificationCounts:
description: Counts of unread notifications for this room.
fields:
highlight_count:
type: int
notification_count:
type: int
LeftRoom:
description: Room that the user has left.
fields:
account_data:
type: "[BlindEvent]"
required: true
state:
type: "[ClientEventWithoutRoomId]"
required: true
timeline:
type: Timeline

View File

@ -1,603 +0,0 @@
module Internal.Api.Sync.V1_3.SpecObjects exposing
( AccountData
, ClientEventWithoutRoomId
, Ephemeral
, Event
, InviteState
, InvitedRoom
, JoinedRoom
, KnockState
, KnockedRoom
, LeftRoom
, Presence
, RoomSummary
, Rooms
, State
, StrippedStateEvent
, Sync
, Timeline
, UnreadNotificationCounts
, UnsignedData(..)
, accountDataDecoder
, clientEventWithoutRoomIdDecoder
, encodeAccountData
, encodeClientEventWithoutRoomId
, encodeEphemeral
, encodeEvent
, encodeInviteState
, encodeInvitedRoom
, encodeJoinedRoom
, encodeKnockState
, encodeKnockedRoom
, encodeLeftRoom
, encodePresence
, encodeRoomSummary
, encodeRooms
, encodeState
, encodeStrippedStateEvent
, encodeSync
, encodeTimeline
, encodeUnreadNotificationCounts
, encodeUnsignedData
, ephemeralDecoder
, eventDecoder
, inviteStateDecoder
, invitedRoomDecoder
, joinedRoomDecoder
, knockStateDecoder
, knockedRoomDecoder
, leftRoomDecoder
, presenceDecoder
, roomSummaryDecoder
, roomsDecoder
, stateDecoder
, strippedStateEventDecoder
, syncDecoder
, timelineDecoder
, unreadNotificationCountsDecoder
, unsignedDataDecoder
)
{-| Automatically generated 'SpecObjects'
Last generated at Unix time 1673279712
-}
import Dict exposing (Dict)
import Internal.Tools.DecodeExtra exposing (opField, opFieldWithDefault)
import Internal.Tools.EncodeExtra exposing (maybeObject)
import Internal.Tools.Timestamp exposing (Timestamp, encodeTimestamp, timestampDecoder)
import Json.Decode as D
import Json.Encode as E
{-| The private data created by this user in a given context.
-}
type alias AccountData =
{ events : List Event
}
encodeAccountData : AccountData -> E.Value
encodeAccountData data =
maybeObject
[ ( "events", Just <| E.list encodeEvent data.events )
]
accountDataDecoder : D.Decoder AccountData
accountDataDecoder =
D.map
(\a ->
{ events = a }
)
(opFieldWithDefault "events" [] (D.list eventDecoder))
{-| Client event that has all data except the room id.
-}
type alias ClientEventWithoutRoomId =
{ content : E.Value
, eventId : String
, originServerTs : Timestamp
, sender : String
, stateKey : Maybe String
, contentType : String
, unsigned : Maybe UnsignedData
}
encodeClientEventWithoutRoomId : ClientEventWithoutRoomId -> E.Value
encodeClientEventWithoutRoomId data =
maybeObject
[ ( "content", Just <| data.content )
, ( "event_id", Just <| E.string data.eventId )
, ( "origin_server_ts", Just <| encodeTimestamp data.originServerTs )
, ( "sender", Just <| E.string data.sender )
, ( "state_key", Maybe.map E.string data.stateKey )
, ( "type", Just <| E.string data.contentType )
, ( "unsigned", Maybe.map encodeUnsignedData data.unsigned )
]
clientEventWithoutRoomIdDecoder : D.Decoder ClientEventWithoutRoomId
clientEventWithoutRoomIdDecoder =
D.map7
(\a b c d e f g ->
{ content = a, eventId = b, originServerTs = c, sender = d, stateKey = e, contentType = f, unsigned = g }
)
(D.field "content" D.value)
(D.field "event_id" D.string)
(D.field "origin_server_ts" timestampDecoder)
(D.field "sender" D.string)
(opField "state_key" D.string)
(D.field "type" D.string)
(opField "unsigned" (D.lazy (\_ -> unsignedDataDecoder)))
{-| Ephemeral events in a room that aren't recorded in the timeline or the room state.
-}
type alias Ephemeral =
{ events : List Event
}
encodeEphemeral : Ephemeral -> E.Value
encodeEphemeral data =
maybeObject
[ ( "events", Just <| E.list encodeEvent data.events )
]
ephemeralDecoder : D.Decoder Ephemeral
ephemeralDecoder =
D.map
(\a ->
{ events = a }
)
(opFieldWithDefault "events" [] (D.list eventDecoder))
{-| A blind event that does not give context about itself.
-}
type alias Event =
{ content : E.Value
, contentType : String
}
encodeEvent : Event -> E.Value
encodeEvent data =
maybeObject
[ ( "content", Just <| data.content )
, ( "type", Just <| E.string data.contentType )
]
eventDecoder : D.Decoder Event
eventDecoder =
D.map2
(\a b ->
{ content = a, contentType = b }
)
(D.field "content" D.value)
(D.field "type" D.string)
{-| Room that the user has been invited to.
-}
type alias InvitedRoom =
{ inviteState : Maybe InviteState
}
encodeInvitedRoom : InvitedRoom -> E.Value
encodeInvitedRoom data =
maybeObject
[ ( "invite_state", Maybe.map encodeInviteState data.inviteState )
]
invitedRoomDecoder : D.Decoder InvitedRoom
invitedRoomDecoder =
D.map
(\a ->
{ inviteState = a }
)
(opField "invite_state" inviteStateDecoder)
{-| The state of a room that the user has been invited to.
-}
type alias InviteState =
{ events : List StrippedStateEvent
}
encodeInviteState : InviteState -> E.Value
encodeInviteState data =
maybeObject
[ ( "events", Just <| E.list encodeStrippedStateEvent data.events )
]
inviteStateDecoder : D.Decoder InviteState
inviteStateDecoder =
D.map
(\a ->
{ events = a }
)
(opFieldWithDefault "events" [] (D.list strippedStateEventDecoder))
{-| Room that the user has joined.
-}
type alias JoinedRoom =
{ accountData : Maybe AccountData
, ephemeral : Maybe Ephemeral
, state : Maybe State
, summary : Maybe RoomSummary
, timeline : Maybe Timeline
, unreadNotifications : Maybe UnreadNotificationCounts
}
encodeJoinedRoom : JoinedRoom -> E.Value
encodeJoinedRoom data =
maybeObject
[ ( "account_data", Maybe.map encodeAccountData data.accountData )
, ( "ephemeral", Maybe.map encodeEphemeral data.ephemeral )
, ( "state", Maybe.map encodeState data.state )
, ( "summary", Maybe.map encodeRoomSummary data.summary )
, ( "timeline", Maybe.map encodeTimeline data.timeline )
, ( "unread_notifications", Maybe.map encodeUnreadNotificationCounts data.unreadNotifications )
]
joinedRoomDecoder : D.Decoder JoinedRoom
joinedRoomDecoder =
D.map6
(\a b c d e f ->
{ accountData = a, ephemeral = b, state = c, summary = d, timeline = e, unreadNotifications = f }
)
(opField "account_data" accountDataDecoder)
(opField "ephemeral" ephemeralDecoder)
(opField "state" stateDecoder)
(opField "summary" roomSummaryDecoder)
(opField "timeline" timelineDecoder)
(opField "unread_notifications" unreadNotificationCountsDecoder)
{-| Room that the user has knocked upon.
-}
type alias KnockedRoom =
{ knockState : Maybe KnockState
}
encodeKnockedRoom : KnockedRoom -> E.Value
encodeKnockedRoom data =
maybeObject
[ ( "knock_state", Maybe.map encodeKnockState data.knockState )
]
knockedRoomDecoder : D.Decoder KnockedRoom
knockedRoomDecoder =
D.map
(\a ->
{ knockState = a }
)
(opField "knock_state" knockStateDecoder)
{-| The state of a room that the user has knocked upon.
-}
type alias KnockState =
{ events : List StrippedStateEvent
}
encodeKnockState : KnockState -> E.Value
encodeKnockState data =
maybeObject
[ ( "events", Just <| E.list encodeStrippedStateEvent data.events )
]
knockStateDecoder : D.Decoder KnockState
knockStateDecoder =
D.map
(\a ->
{ events = a }
)
(opFieldWithDefault "events" [] (D.list strippedStateEventDecoder))
{-| Room that the user has left.
-}
type alias LeftRoom =
{ accountData : Maybe AccountData
, state : Maybe State
, timeline : Maybe Timeline
}
encodeLeftRoom : LeftRoom -> E.Value
encodeLeftRoom data =
maybeObject
[ ( "account_data", Maybe.map encodeAccountData data.accountData )
, ( "state", Maybe.map encodeState data.state )
, ( "timeline", Maybe.map encodeTimeline data.timeline )
]
leftRoomDecoder : D.Decoder LeftRoom
leftRoomDecoder =
D.map3
(\a b c ->
{ accountData = a, state = b, timeline = c }
)
(opField "account_data" accountDataDecoder)
(opField "state" stateDecoder)
(opField "timeline" timelineDecoder)
{-| The updates to the presence status of other users.
-}
type alias Presence =
{ events : List Event
}
encodePresence : Presence -> E.Value
encodePresence data =
maybeObject
[ ( "events", Just <| E.list encodeEvent data.events )
]
presenceDecoder : D.Decoder Presence
presenceDecoder =
D.map
(\a ->
{ events = a }
)
(opFieldWithDefault "events" [] (D.list eventDecoder))
{-| Updates to rooms.
-}
type alias Rooms =
{ invite : Dict String InvitedRoom
, join : Dict String JoinedRoom
, knock : Dict String KnockedRoom
, leave : Dict String LeftRoom
}
encodeRooms : Rooms -> E.Value
encodeRooms data =
maybeObject
[ ( "invite", Just <| E.dict identity encodeInvitedRoom data.invite )
, ( "join", Just <| E.dict identity encodeJoinedRoom data.join )
, ( "knock", Just <| E.dict identity encodeKnockedRoom data.knock )
, ( "leave", Just <| E.dict identity encodeLeftRoom data.leave )
]
roomsDecoder : D.Decoder Rooms
roomsDecoder =
D.map4
(\a b c d ->
{ invite = a, join = b, knock = c, leave = d }
)
(opFieldWithDefault "invite" Dict.empty (D.dict invitedRoomDecoder))
(opFieldWithDefault "join" Dict.empty (D.dict joinedRoomDecoder))
(opFieldWithDefault "knock" Dict.empty (D.dict knockedRoomDecoder))
(opFieldWithDefault "leave" Dict.empty (D.dict leftRoomDecoder))
{-| Information about a room which clients may need to correctly render it to users.
-}
type alias RoomSummary =
{ mHeroes : Maybe (List String)
, mInvitedMemberCount : Maybe Int
, mJoinedMemberCount : Maybe Int
}
encodeRoomSummary : RoomSummary -> E.Value
encodeRoomSummary data =
maybeObject
[ ( "m.heroes", Maybe.map (E.list E.string) data.mHeroes )
, ( "m.invited_member_count", Maybe.map E.int data.mInvitedMemberCount )
, ( "m.joined_member_count", Maybe.map E.int data.mJoinedMemberCount )
]
roomSummaryDecoder : D.Decoder RoomSummary
roomSummaryDecoder =
D.map3
(\a b c ->
{ mHeroes = a, mInvitedMemberCount = b, mJoinedMemberCount = c }
)
(opField "m.heroes" (D.list D.string))
(opField "m.invited_member_count" D.int)
(opField "m.joined_member_count" D.int)
{-| Updates to the state of a room.
-}
type alias State =
{ events : List ClientEventWithoutRoomId
}
encodeState : State -> E.Value
encodeState data =
maybeObject
[ ( "events", Just <| E.list encodeClientEventWithoutRoomId data.events )
]
stateDecoder : D.Decoder State
stateDecoder =
D.map
(\a ->
{ events = a }
)
(opFieldWithDefault "events" [] (D.list clientEventWithoutRoomIdDecoder))
{-| Stripped state events of a room that the user has limited access to.
-}
type alias StrippedStateEvent =
{ content : E.Value
, sender : String
, stateKey : String
, contentType : String
}
encodeStrippedStateEvent : StrippedStateEvent -> E.Value
encodeStrippedStateEvent data =
maybeObject
[ ( "content", Just <| data.content )
, ( "sender", Just <| E.string data.sender )
, ( "state_key", Just <| E.string data.stateKey )
, ( "type", Just <| E.string data.contentType )
]
strippedStateEventDecoder : D.Decoder StrippedStateEvent
strippedStateEventDecoder =
D.map4
(\a b c d ->
{ content = a, sender = b, stateKey = c, contentType = d }
)
(D.field "content" D.value)
(D.field "sender" D.string)
(D.field "state_key" D.string)
(D.field "type" D.string)
{-| The sync response the homeserver sends to the user.
-}
type alias Sync =
{ accountData : Maybe AccountData
, nextBatch : String
, presence : Maybe Presence
, rooms : Maybe Rooms
}
encodeSync : Sync -> E.Value
encodeSync data =
maybeObject
[ ( "account_data", Maybe.map encodeAccountData data.accountData )
, ( "next_batch", Just <| E.string data.nextBatch )
, ( "presence", Maybe.map encodePresence data.presence )
, ( "rooms", Maybe.map encodeRooms data.rooms )
]
syncDecoder : D.Decoder Sync
syncDecoder =
D.map4
(\a b c d ->
{ accountData = a, nextBatch = b, presence = c, rooms = d }
)
(opField "account_data" accountDataDecoder)
(D.field "next_batch" D.string)
(opField "presence" presenceDecoder)
(opField "rooms" roomsDecoder)
{-| The timeline of messages and state changes in a room.
-}
type alias Timeline =
{ events : List ClientEventWithoutRoomId
, limited : Bool
, prevBatch : Maybe String
}
encodeTimeline : Timeline -> E.Value
encodeTimeline data =
maybeObject
[ ( "events", Just <| E.list encodeClientEventWithoutRoomId data.events )
, ( "limited", Just <| E.bool data.limited )
, ( "prev_batch", Maybe.map E.string data.prevBatch )
]
timelineDecoder : D.Decoder Timeline
timelineDecoder =
D.map3
(\a b c ->
{ events = a, limited = b, prevBatch = c }
)
(opFieldWithDefault "events" [] (D.list clientEventWithoutRoomIdDecoder))
(opFieldWithDefault "limited" False D.bool)
(opField "prev_batch" D.string)
{-| Counts of unread notifications for this room.
-}
type alias UnreadNotificationCounts =
{ highlightCount : Maybe Int
, notificationCount : Maybe Int
}
encodeUnreadNotificationCounts : UnreadNotificationCounts -> E.Value
encodeUnreadNotificationCounts data =
maybeObject
[ ( "highlight_count", Maybe.map E.int data.highlightCount )
, ( "notification_count", Maybe.map E.int data.notificationCount )
]
unreadNotificationCountsDecoder : D.Decoder UnreadNotificationCounts
unreadNotificationCountsDecoder =
D.map2
(\a b ->
{ highlightCount = a, notificationCount = b }
)
(opField "highlight_count" D.int)
(opField "notification_count" D.int)
{-| Data that isn't getting signed for Canonical JSON.
-}
type UnsignedData
= UnsignedData
{ age : Maybe Int
, prevContent : Maybe E.Value
, redactedBecause : Maybe ClientEventWithoutRoomId
, transactionId : Maybe String
}
encodeUnsignedData : UnsignedData -> E.Value
encodeUnsignedData (UnsignedData data) =
maybeObject
[ ( "age", Maybe.map E.int data.age )
, ( "prev_content", data.prevContent )
, ( "redacted_because", Maybe.map encodeClientEventWithoutRoomId data.redactedBecause )
, ( "transaction_id", Maybe.map E.string data.transactionId )
]
unsignedDataDecoder : D.Decoder UnsignedData
unsignedDataDecoder =
D.map4
(\a b c d ->
UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d }
)
(opField "age" D.int)
(opField "prev_content" D.value)
(opField "redacted_because" clientEventWithoutRoomIdDecoder)
(opField "transaction_id" D.string)

View File

@ -1,197 +0,0 @@
version: v1.3
name: SpecObjects
objects:
Sync:
description: The sync response the homeserver sends to the user.
fields:
account_data:
type: AccountData
next_batch:
type: string
required: true
presence:
type: Presence
rooms:
type: Rooms
AccountData:
description: The private data created by this user in a given context.
fields:
events:
type: "[Event]"
required: false
default: "[]"
Event:
description: A blind event that does not give context about itself.
fields:
content:
type: value
required: true
type:
type: string
required: true
Presence:
description: The updates to the presence status of other users.
fields:
events:
type: "[Event]"
required: false
default: "[]"
Rooms:
description: Updates to rooms.
fields:
invite:
type: "{InvitedRoom}"
required: false
default: Dict.empty
join:
type: "{JoinedRoom}"
required: false
default: Dict.empty
knock:
type: "{KnockedRoom}"
required: false
default: Dict.empty
leave:
type: "{LeftRoom}"
required: false
default: Dict.empty
InvitedRoom:
description: Room that the user has been invited to.
fields:
invite_state:
type: InviteState
InviteState:
description: The state of a room that the user has been invited to.
fields:
events:
type: "[StrippedStateEvent]"
required: false
default: "[]"
StrippedStateEvent:
description: Stripped state events of a room that the user has limited access to.
fields:
content:
type: value
required: true
sender:
type: string
required: true
state_key:
type: string
required: true
type:
type: string
required: true
JoinedRoom:
description: Room that the user has joined.
fields:
account_data:
type: AccountData
ephemeral:
type: Ephemeral
state:
type: State
summary:
type: RoomSummary
timeline:
type: Timeline
unread_notifications:
type: UnreadNotificationCounts
Ephemeral:
description: Ephemeral events in a room that aren't recorded in the timeline or the room state.
fields:
events:
type: "[Event]"
required: false
default: "[]"
State:
description: Updates to the state of a room.
fields:
events:
type: "[ClientEventWithoutRoomId]"
required: false
default: "[]"
ClientEventWithoutRoomId:
description: Client event that has all data except the room id.
fields:
content:
type: value
required: true
event_id:
type: string
required: true
origin_server_ts:
type: timestamp
required: true
sender:
type: string
required: true
state_key:
type: string
type:
type: string
required: true
unsigned:
type: UnsignedData
UnsignedData:
anti_recursion: true
description: Data that isn't getting signed for Canonical JSON.
fields:
age:
type: int
prev_content:
type: value
redacted_because:
type: ClientEventWithoutRoomId
transaction_id:
type: string
RoomSummary:
description: Information about a room which clients may need to correctly render it to users.
fields:
m.heroes:
type: "[string]"
m.invited_member_count:
type: int
m.joined_member_count:
type: int
Timeline:
description: The timeline of messages and state changes in a room.
fields:
events:
type: "[ClientEventWithoutRoomId]"
required: false
default: "[]"
limited:
type: bool
required: false
default: "False"
prev_batch:
type: string
UnreadNotificationCounts:
description: Counts of unread notifications for this room.
fields:
highlight_count:
type: int
notification_count:
type: int
KnockedRoom:
description: Room that the user has knocked upon.
fields:
knock_state:
type: KnockState
KnockState:
description: The state of a room that the user has knocked upon.
fields:
events:
type: "[StrippedStateEvent]"
required: false
default: "[]"
LeftRoom:
description: Room that the user has left.
fields:
account_data:
type: AccountData
state:
type: State
timeline:
type: Timeline

View File

@ -1,72 +0,0 @@
module Internal.Api.Sync.V1_3.Upcast exposing (..)
import Dict
import Internal.Api.Sync.V1_2.Objects as PO
import Internal.Api.Sync.V1_3.Objects as O
upcast : PO.Sync -> O.Sync
upcast sync =
{ accountData = sync.accountData
, nextBatch = sync.nextBatch
, presence = sync.presence
, rooms = Maybe.map upcastRooms sync.rooms
}
upcastRooms : PO.Rooms -> O.Rooms
upcastRooms rooms =
{ invite = rooms.invite
, join = Dict.map (\_ -> upcastJoinedRoom) rooms.join
, knock = rooms.knock
, leave = Dict.map (\_ -> upcastLeftRoom) rooms.leave
}
upcastJoinedRoom : PO.JoinedRoom -> O.JoinedRoom
upcastJoinedRoom room =
{ accountData = room.accountData
, ephemeral = room.ephemeral
, state = List.map upcastClientEventWithoutRoomId room.state
, summary = room.summary
, timeline = Maybe.map upcastTimeline room.timeline
, unreadNotifications = room.unreadNotifications
}
upcastClientEventWithoutRoomId : PO.ClientEventWithoutRoomId -> O.ClientEventWithoutRoomId
upcastClientEventWithoutRoomId event =
{ content = event.content
, eventId = event.eventId
, originServerTs = event.originServerTs
, sender = event.sender
, stateKey = event.stateKey
, contentType = event.contentType
, unsigned = Maybe.map upcastUnsigned event.unsigned
}
upcastUnsigned : PO.UnsignedData -> O.UnsignedData
upcastUnsigned (PO.UnsignedData data) =
O.UnsignedData
{ age = data.age
, prevContent = data.prevContent
, redactedBecause = Maybe.map upcastClientEventWithoutRoomId data.redactedBecause
, transactionId = data.transactionId
}
upcastTimeline : PO.Timeline -> O.Timeline
upcastTimeline timeline =
{ events = List.map upcastClientEventWithoutRoomId timeline.events
, limited = timeline.limited
, prevBatch = timeline.prevBatch
}
upcastLeftRoom : PO.LeftRoom -> O.LeftRoom
upcastLeftRoom room =
{ accountData = room.accountData
, state = List.map upcastClientEventWithoutRoomId room.state
, timeline = Maybe.map upcastTimeline room.timeline
}

View File

@ -1,18 +0,0 @@
module Internal.Api.Sync.V1_4.Api exposing (..)
import Internal.Api.Sync.Api as Api
import Internal.Api.Sync.V1_3.Objects as PO
import Internal.Api.Sync.V1_4.Convert as C
import Internal.Api.Sync.V1_4.Objects as O
import Internal.Api.Sync.V1_4.SpecObjects as SO
import Internal.Api.Sync.V1_4.Upcast as U
import Internal.Api.VersionControl as V
packet : V.SingleVersion Api.SyncInputV1 PO.Sync Api.SyncInputV1 O.Sync
packet =
{ version = "v1.4"
, downcast = identity
, current = Api.syncV1 SO.syncDecoder C.convert
, upcast = U.upcast
}

View File

@ -1,84 +0,0 @@
module Internal.Api.Sync.V1_4.Convert exposing (..)
import Dict
import Internal.Api.Sync.V1_4.Objects as O
import Internal.Api.Sync.V1_4.SpecObjects as SO
convert : SO.Sync -> O.Sync
convert sync =
{ accountData = convertEventHolder sync.accountData
, nextBatch = sync.nextBatch
, presence = convertEventHolder sync.presence
, rooms = Maybe.map convertRooms sync.rooms
}
convertEventHolder : Maybe { a | events : List b } -> List b
convertEventHolder =
Maybe.map .events >> Maybe.withDefault []
convertRooms : SO.Rooms -> O.Rooms
convertRooms rooms =
{ invite =
Dict.map
(\_ -> .inviteState >> Maybe.map .events >> Maybe.withDefault [])
rooms.invite
, join = Dict.map (\_ -> convertJoinedRoom) rooms.join
, knock =
Dict.map
(\_ -> .knockState >> Maybe.map .events >> Maybe.withDefault [])
rooms.knock
, leave = Dict.map (\_ -> convertLeftRoom) rooms.leave
}
convertJoinedRoom : SO.JoinedRoom -> O.JoinedRoom
convertJoinedRoom room =
{ accountData = convertEventHolder room.accountData
, ephemeral = convertEventHolder room.ephemeral
, state = convertEventHolder room.state |> List.map convertClientEventWithoutRoomId
, summary = room.summary
, timeline = Maybe.map convertTimeline room.timeline
, unreadNotifications = room.unreadNotifications
, unreadThreadNotifications = room.unreadThreadNotifications
}
convertClientEventWithoutRoomId : SO.ClientEventWithoutRoomId -> O.ClientEventWithoutRoomId
convertClientEventWithoutRoomId event =
{ content = event.content
, eventId = event.eventId
, originServerTs = event.originServerTs
, sender = event.sender
, stateKey = event.stateKey
, contentType = event.contentType
, unsigned = Maybe.map convertUnsigned event.unsigned
}
convertUnsigned : SO.UnsignedData -> O.UnsignedData
convertUnsigned (SO.UnsignedData data) =
O.UnsignedData
{ age = data.age
, prevContent = data.prevContent
, redactedBecause = Maybe.map convertClientEventWithoutRoomId data.redactedBecause
, transactionId = data.transactionId
}
convertTimeline : SO.Timeline -> O.Timeline
convertTimeline timeline =
{ events = List.map convertClientEventWithoutRoomId timeline.events
, limited = timeline.limited
, prevBatch = timeline.prevBatch
}
convertLeftRoom : SO.LeftRoom -> O.LeftRoom
convertLeftRoom room =
{ accountData = convertEventHolder room.accountData
, state = convertEventHolder room.state |> List.map convertClientEventWithoutRoomId
, timeline = Maybe.map convertTimeline room.timeline
}

View File

@ -1,398 +0,0 @@
module Internal.Api.Sync.V1_4.Objects exposing
( BlindEvent
, ClientEventWithoutRoomId
, JoinedRoom
, LeftRoom
, RoomSummary
, Rooms
, StrippedStateEvent
, Sync
, Timeline
, UnreadNotificationCounts
, UnsignedData(..)
, blindEventDecoder
, clientEventWithoutRoomIdDecoder
, encodeBlindEvent
, encodeClientEventWithoutRoomId
, encodeJoinedRoom
, encodeLeftRoom
, encodeRoomSummary
, encodeRooms
, encodeStrippedStateEvent
, encodeSync
, encodeTimeline
, encodeUnreadNotificationCounts
, encodeUnsignedData
, joinedRoomDecoder
, leftRoomDecoder
, roomSummaryDecoder
, roomsDecoder
, strippedStateEventDecoder
, syncDecoder
, timelineDecoder
, unreadNotificationCountsDecoder
, unsignedDataDecoder
)
{-| Automatically generated 'Objects'
Last generated at Unix time 1673279712
-}
import Dict exposing (Dict)
import Internal.Tools.DecodeExtra exposing (opField, opFieldWithDefault)
import Internal.Tools.EncodeExtra exposing (maybeObject)
import Internal.Tools.Timestamp exposing (Timestamp, encodeTimestamp, timestampDecoder)
import Json.Decode as D
import Json.Encode as E
{-| A blind event that does not give context about itself.
-}
type alias BlindEvent =
{ content : E.Value
, contentType : String
}
encodeBlindEvent : BlindEvent -> E.Value
encodeBlindEvent data =
maybeObject
[ ( "content", Just <| data.content )
, ( "type", Just <| E.string data.contentType )
]
blindEventDecoder : D.Decoder BlindEvent
blindEventDecoder =
D.map2
(\a b ->
{ content = a, contentType = b }
)
(D.field "content" D.value)
(D.field "type" D.string)
{-| Client event that has all data except the room id.
-}
type alias ClientEventWithoutRoomId =
{ content : E.Value
, eventId : String
, originServerTs : Timestamp
, sender : String
, stateKey : Maybe String
, contentType : String
, unsigned : Maybe UnsignedData
}
encodeClientEventWithoutRoomId : ClientEventWithoutRoomId -> E.Value
encodeClientEventWithoutRoomId data =
maybeObject
[ ( "content", Just <| data.content )
, ( "event_id", Just <| E.string data.eventId )
, ( "origin_server_ts", Just <| encodeTimestamp data.originServerTs )
, ( "sender", Just <| E.string data.sender )
, ( "state_key", Maybe.map E.string data.stateKey )
, ( "type", Just <| E.string data.contentType )
, ( "unsigned", Maybe.map encodeUnsignedData data.unsigned )
]
clientEventWithoutRoomIdDecoder : D.Decoder ClientEventWithoutRoomId
clientEventWithoutRoomIdDecoder =
D.map7
(\a b c d e f g ->
{ content = a, eventId = b, originServerTs = c, sender = d, stateKey = e, contentType = f, unsigned = g }
)
(D.field "content" D.value)
(D.field "event_id" D.string)
(D.field "origin_server_ts" timestampDecoder)
(D.field "sender" D.string)
(opField "state_key" D.string)
(D.field "type" D.string)
(opField "unsigned" (D.lazy (\_ -> unsignedDataDecoder)))
{-| Room that the user has joined.
-}
type alias JoinedRoom =
{ accountData : List BlindEvent
, ephemeral : List BlindEvent
, state : List ClientEventWithoutRoomId
, summary : Maybe RoomSummary
, timeline : Maybe Timeline
, unreadNotifications : Maybe UnreadNotificationCounts
, unreadThreadNotifications : Dict String UnreadNotificationCounts
}
encodeJoinedRoom : JoinedRoom -> E.Value
encodeJoinedRoom data =
maybeObject
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
, ( "ephemeral", Just <| E.list encodeBlindEvent data.ephemeral )
, ( "state", Just <| E.list encodeClientEventWithoutRoomId data.state )
, ( "summary", Maybe.map encodeRoomSummary data.summary )
, ( "timeline", Maybe.map encodeTimeline data.timeline )
, ( "unread_notifications", Maybe.map encodeUnreadNotificationCounts data.unreadNotifications )
, ( "unread_thread_notifications", Just <| E.dict identity encodeUnreadNotificationCounts data.unreadThreadNotifications )
]
joinedRoomDecoder : D.Decoder JoinedRoom
joinedRoomDecoder =
D.map7
(\a b c d e f g ->
{ accountData = a, ephemeral = b, state = c, summary = d, timeline = e, unreadNotifications = f, unreadThreadNotifications = g }
)
(D.field "account_data" (D.list blindEventDecoder))
(D.field "ephemeral" (D.list blindEventDecoder))
(D.field "state" (D.list clientEventWithoutRoomIdDecoder))
(opField "summary" roomSummaryDecoder)
(opField "timeline" timelineDecoder)
(opField "unread_notifications" unreadNotificationCountsDecoder)
(D.field "unread_thread_notifications" (D.dict unreadNotificationCountsDecoder))
{-| Room that the user has left.
-}
type alias LeftRoom =
{ accountData : List BlindEvent
, state : List ClientEventWithoutRoomId
, timeline : Maybe Timeline
}
encodeLeftRoom : LeftRoom -> E.Value
encodeLeftRoom data =
maybeObject
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
, ( "state", Just <| E.list encodeClientEventWithoutRoomId data.state )
, ( "timeline", Maybe.map encodeTimeline data.timeline )
]
leftRoomDecoder : D.Decoder LeftRoom
leftRoomDecoder =
D.map3
(\a b c ->
{ accountData = a, state = b, timeline = c }
)
(D.field "account_data" (D.list blindEventDecoder))
(D.field "state" (D.list clientEventWithoutRoomIdDecoder))
(opField "timeline" timelineDecoder)
{-| Updates to rooms.
-}
type alias Rooms =
{ invite : Dict String (List StrippedStateEvent)
, join : Dict String JoinedRoom
, knock : Dict String (List StrippedStateEvent)
, leave : Dict String LeftRoom
}
encodeRooms : Rooms -> E.Value
encodeRooms data =
maybeObject
[ ( "invite", Just <| E.dict identity (E.list encodeStrippedStateEvent) data.invite )
, ( "join", Just <| E.dict identity encodeJoinedRoom data.join )
, ( "knock", Just <| E.dict identity (E.list encodeStrippedStateEvent) data.knock )
, ( "leave", Just <| E.dict identity encodeLeftRoom data.leave )
]
roomsDecoder : D.Decoder Rooms
roomsDecoder =
D.map4
(\a b c d ->
{ invite = a, join = b, knock = c, leave = d }
)
(opFieldWithDefault "invite" Dict.empty (D.dict (D.list strippedStateEventDecoder)))
(opFieldWithDefault "join" Dict.empty (D.dict joinedRoomDecoder))
(opFieldWithDefault "knock" Dict.empty (D.dict (D.list strippedStateEventDecoder)))
(opFieldWithDefault "leave" Dict.empty (D.dict leftRoomDecoder))
{-| Information about a room which clients may need to correctly render it to users.
-}
type alias RoomSummary =
{ mHeroes : Maybe (List String)
, mInvitedMemberCount : Maybe Int
, mJoinedMemberCount : Maybe Int
}
encodeRoomSummary : RoomSummary -> E.Value
encodeRoomSummary data =
maybeObject
[ ( "m.heroes", Maybe.map (E.list E.string) data.mHeroes )
, ( "m.invited_member_count", Maybe.map E.int data.mInvitedMemberCount )
, ( "m.joined_member_count", Maybe.map E.int data.mJoinedMemberCount )
]
roomSummaryDecoder : D.Decoder RoomSummary
roomSummaryDecoder =
D.map3
(\a b c ->
{ mHeroes = a, mInvitedMemberCount = b, mJoinedMemberCount = c }
)
(opField "m.heroes" (D.list D.string))
(opField "m.invited_member_count" D.int)
(opField "m.joined_member_count" D.int)
{-| Stripped state events of a room that the user has limited access to.
-}
type alias StrippedStateEvent =
{ content : E.Value
, sender : String
, stateKey : String
, contentType : String
}
encodeStrippedStateEvent : StrippedStateEvent -> E.Value
encodeStrippedStateEvent data =
maybeObject
[ ( "content", Just <| data.content )
, ( "sender", Just <| E.string data.sender )
, ( "state_key", Just <| E.string data.stateKey )
, ( "type", Just <| E.string data.contentType )
]
strippedStateEventDecoder : D.Decoder StrippedStateEvent
strippedStateEventDecoder =
D.map4
(\a b c d ->
{ content = a, sender = b, stateKey = c, contentType = d }
)
(D.field "content" D.value)
(D.field "sender" D.string)
(D.field "state_key" D.string)
(D.field "type" D.string)
{-| The sync response the homeserver sends to the user.
-}
type alias Sync =
{ accountData : List BlindEvent
, nextBatch : String
, presence : List BlindEvent
, rooms : Maybe Rooms
}
encodeSync : Sync -> E.Value
encodeSync data =
maybeObject
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
, ( "next_batch", Just <| E.string data.nextBatch )
, ( "presence", Just <| E.list encodeBlindEvent data.presence )
, ( "rooms", Maybe.map encodeRooms data.rooms )
]
syncDecoder : D.Decoder Sync
syncDecoder =
D.map4
(\a b c d ->
{ accountData = a, nextBatch = b, presence = c, rooms = d }
)
(D.field "account_data" (D.list blindEventDecoder))
(D.field "next_batch" D.string)
(D.field "presence" (D.list blindEventDecoder))
(opField "rooms" roomsDecoder)
{-| The timeline of messages and state changes in a room.
-}
type alias Timeline =
{ events : List ClientEventWithoutRoomId
, limited : Bool
, prevBatch : Maybe String
}
encodeTimeline : Timeline -> E.Value
encodeTimeline data =
maybeObject
[ ( "events", Just <| E.list encodeClientEventWithoutRoomId data.events )
, ( "limited", Just <| E.bool data.limited )
, ( "prev_batch", Maybe.map E.string data.prevBatch )
]
timelineDecoder : D.Decoder Timeline
timelineDecoder =
D.map3
(\a b c ->
{ events = a, limited = b, prevBatch = c }
)
(opFieldWithDefault "events" [] (D.list clientEventWithoutRoomIdDecoder))
(opFieldWithDefault "limited" False D.bool)
(opField "prev_batch" D.string)
{-| Counts of unread notifications for this room.
-}
type alias UnreadNotificationCounts =
{ highlightCount : Maybe Int
, notificationCount : Maybe Int
}
encodeUnreadNotificationCounts : UnreadNotificationCounts -> E.Value
encodeUnreadNotificationCounts data =
maybeObject
[ ( "highlight_count", Maybe.map E.int data.highlightCount )
, ( "notification_count", Maybe.map E.int data.notificationCount )
]
unreadNotificationCountsDecoder : D.Decoder UnreadNotificationCounts
unreadNotificationCountsDecoder =
D.map2
(\a b ->
{ highlightCount = a, notificationCount = b }
)
(opField "highlight_count" D.int)
(opField "notification_count" D.int)
{-| Data that isn't getting signed for Canonical JSON.
-}
type UnsignedData
= UnsignedData
{ age : Maybe Int
, prevContent : Maybe E.Value
, redactedBecause : Maybe ClientEventWithoutRoomId
, transactionId : Maybe String
}
encodeUnsignedData : UnsignedData -> E.Value
encodeUnsignedData (UnsignedData data) =
maybeObject
[ ( "age", Maybe.map E.int data.age )
, ( "prev_content", data.prevContent )
, ( "redacted_because", Maybe.map encodeClientEventWithoutRoomId data.redactedBecause )
, ( "transaction_id", Maybe.map E.string data.transactionId )
]
unsignedDataDecoder : D.Decoder UnsignedData
unsignedDataDecoder =
D.map4
(\a b c d ->
UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d }
)
(opField "age" D.int)
(opField "prev_content" D.value)
(opField "redacted_because" clientEventWithoutRoomIdDecoder)
(opField "transaction_id" D.string)

View File

@ -1,155 +0,0 @@
version: v1.4
name: Objects
objects:
Sync:
description: The sync response the homeserver sends to the user.
fields:
account_data:
type: "[BlindEvent]"
required: true
next_batch:
type: string
required: true
presence:
type: "[BlindEvent]"
required: true
rooms:
type: Rooms
BlindEvent:
description: A blind event that does not give context about itself.
fields:
content:
type: value
required: true
type:
type: string
required: true
Rooms:
description: Updates to rooms.
fields:
invite:
type: "{[StrippedStateEvent]}"
required: false
default: Dict.empty
join:
type: "{JoinedRoom}"
required: false
default: Dict.empty
knock:
type: "{[StrippedStateEvent]}"
required: false
default: Dict.empty
leave:
type: "{LeftRoom}"
required: false
default: Dict.empty
StrippedStateEvent:
description: Stripped state events of a room that the user has limited access to.
fields:
content:
type: value
required: true
sender:
type: string
required: true
state_key:
type: string
required: true
type:
type: string
required: true
JoinedRoom:
description: Room that the user has joined.
fields:
account_data:
type: "[BlindEvent]"
required: true
ephemeral:
type: "[BlindEvent]"
required: true
state:
type: "[ClientEventWithoutRoomId]"
required: true
summary:
type: RoomSummary
timeline:
type: Timeline
unread_notifications:
type: UnreadNotificationCounts
unread_thread_notifications:
type: "{UnreadNotificationCounts}"
required: true
ClientEventWithoutRoomId:
description: Client event that has all data except the room id.
fields:
content:
type: value
required: true
event_id:
type: string
required: true
origin_server_ts:
type: timestamp
required: true
sender:
type: string
required: true
state_key:
type: string
type:
type: string
required: true
unsigned:
type: UnsignedData
UnsignedData:
anti_recursion: true
description: Data that isn't getting signed for Canonical JSON.
fields:
age:
type: int
prev_content:
type: value
redacted_because:
type: ClientEventWithoutRoomId
transaction_id:
type: string
RoomSummary:
description: Information about a room which clients may need to correctly render it to users.
fields:
m.heroes:
type: "[string]"
m.invited_member_count:
type: int
m.joined_member_count:
type: int
Timeline:
description: The timeline of messages and state changes in a room.
fields:
events:
type: "[ClientEventWithoutRoomId]"
required: false
default: "[]"
limited:
type: bool
required: false
default: "False"
prev_batch:
type: string
UnreadNotificationCounts:
description: Counts of unread notifications for this room.
fields:
highlight_count:
type: int
notification_count:
type: int
LeftRoom:
description: Room that the user has left.
fields:
account_data:
type: "[BlindEvent]"
required: true
state:
type: "[ClientEventWithoutRoomId]"
required: true
timeline:
type: Timeline

View File

@ -1,635 +0,0 @@
module Internal.Api.Sync.V1_4.SpecObjects exposing
( AccountData
, ClientEventWithoutRoomId
, Ephemeral
, Event
, InviteState
, InvitedRoom
, JoinedRoom
, KnockState
, KnockedRoom
, LeftRoom
, Presence
, RoomSummary
, Rooms
, State
, StrippedStateEvent
, Sync
, ThreadNotificationCounts
, Timeline
, UnreadNotificationCounts
, UnsignedData(..)
, accountDataDecoder
, clientEventWithoutRoomIdDecoder
, encodeAccountData
, encodeClientEventWithoutRoomId
, encodeEphemeral
, encodeEvent
, encodeInviteState
, encodeInvitedRoom
, encodeJoinedRoom
, encodeKnockState
, encodeKnockedRoom
, encodeLeftRoom
, encodePresence
, encodeRoomSummary
, encodeRooms
, encodeState
, encodeStrippedStateEvent
, encodeSync
, encodeThreadNotificationCounts
, encodeTimeline
, encodeUnreadNotificationCounts
, encodeUnsignedData
, ephemeralDecoder
, eventDecoder
, inviteStateDecoder
, invitedRoomDecoder
, joinedRoomDecoder
, knockStateDecoder
, knockedRoomDecoder
, leftRoomDecoder
, presenceDecoder
, roomSummaryDecoder
, roomsDecoder
, stateDecoder
, strippedStateEventDecoder
, syncDecoder
, threadNotificationCountsDecoder
, timelineDecoder
, unreadNotificationCountsDecoder
, unsignedDataDecoder
)
{-| Automatically generated 'SpecObjects'
Last generated at Unix time 1673279712
-}
import Dict exposing (Dict)
import Internal.Tools.DecodeExtra exposing (opField, opFieldWithDefault)
import Internal.Tools.EncodeExtra exposing (maybeObject)
import Internal.Tools.Timestamp exposing (Timestamp, encodeTimestamp, timestampDecoder)
import Json.Decode as D
import Json.Encode as E
{-| The private data created by this user in a given context.
-}
type alias AccountData =
{ events : List Event
}
encodeAccountData : AccountData -> E.Value
encodeAccountData data =
maybeObject
[ ( "events", Just <| E.list encodeEvent data.events )
]
accountDataDecoder : D.Decoder AccountData
accountDataDecoder =
D.map
(\a ->
{ events = a }
)
(opFieldWithDefault "events" [] (D.list eventDecoder))
{-| Client event that has all data except the room id.
-}
type alias ClientEventWithoutRoomId =
{ content : E.Value
, eventId : String
, originServerTs : Timestamp
, sender : String
, stateKey : Maybe String
, contentType : String
, unsigned : Maybe UnsignedData
}
encodeClientEventWithoutRoomId : ClientEventWithoutRoomId -> E.Value
encodeClientEventWithoutRoomId data =
maybeObject
[ ( "content", Just <| data.content )
, ( "event_id", Just <| E.string data.eventId )
, ( "origin_server_ts", Just <| encodeTimestamp data.originServerTs )
, ( "sender", Just <| E.string data.sender )
, ( "state_key", Maybe.map E.string data.stateKey )
, ( "type", Just <| E.string data.contentType )
, ( "unsigned", Maybe.map encodeUnsignedData data.unsigned )
]
clientEventWithoutRoomIdDecoder : D.Decoder ClientEventWithoutRoomId
clientEventWithoutRoomIdDecoder =
D.map7
(\a b c d e f g ->
{ content = a, eventId = b, originServerTs = c, sender = d, stateKey = e, contentType = f, unsigned = g }
)
(D.field "content" D.value)
(D.field "event_id" D.string)
(D.field "origin_server_ts" timestampDecoder)
(D.field "sender" D.string)
(opField "state_key" D.string)
(D.field "type" D.string)
(opField "unsigned" (D.lazy (\_ -> unsignedDataDecoder)))
{-| Ephemeral events in a room that aren't recorded in the timeline or the room state.
-}
type alias Ephemeral =
{ events : List Event
}
encodeEphemeral : Ephemeral -> E.Value
encodeEphemeral data =
maybeObject
[ ( "events", Just <| E.list encodeEvent data.events )
]
ephemeralDecoder : D.Decoder Ephemeral
ephemeralDecoder =
D.map
(\a ->
{ events = a }
)
(opFieldWithDefault "events" [] (D.list eventDecoder))
{-| A blind event that does not give context about itself.
-}
type alias Event =
{ content : E.Value
, contentType : String
}
encodeEvent : Event -> E.Value
encodeEvent data =
maybeObject
[ ( "content", Just <| data.content )
, ( "type", Just <| E.string data.contentType )
]
eventDecoder : D.Decoder Event
eventDecoder =
D.map2
(\a b ->
{ content = a, contentType = b }
)
(D.field "content" D.value)
(D.field "type" D.string)
{-| Room that the user has been invited to.
-}
type alias InvitedRoom =
{ inviteState : Maybe InviteState
}
encodeInvitedRoom : InvitedRoom -> E.Value
encodeInvitedRoom data =
maybeObject
[ ( "invite_state", Maybe.map encodeInviteState data.inviteState )
]
invitedRoomDecoder : D.Decoder InvitedRoom
invitedRoomDecoder =
D.map
(\a ->
{ inviteState = a }
)
(opField "invite_state" inviteStateDecoder)
{-| The state of a room that the user has been invited to.
-}
type alias InviteState =
{ events : List StrippedStateEvent
}
encodeInviteState : InviteState -> E.Value
encodeInviteState data =
maybeObject
[ ( "events", Just <| E.list encodeStrippedStateEvent data.events )
]
inviteStateDecoder : D.Decoder InviteState
inviteStateDecoder =
D.map
(\a ->
{ events = a }
)
(opFieldWithDefault "events" [] (D.list strippedStateEventDecoder))
{-| Room that the user has joined.
-}
type alias JoinedRoom =
{ accountData : Maybe AccountData
, ephemeral : Maybe Ephemeral
, state : Maybe State
, summary : Maybe RoomSummary
, timeline : Maybe Timeline
, unreadNotifications : Maybe UnreadNotificationCounts
, unreadThreadNotifications : Dict String ThreadNotificationCounts
}
encodeJoinedRoom : JoinedRoom -> E.Value
encodeJoinedRoom data =
maybeObject
[ ( "account_data", Maybe.map encodeAccountData data.accountData )
, ( "ephemeral", Maybe.map encodeEphemeral data.ephemeral )
, ( "state", Maybe.map encodeState data.state )
, ( "summary", Maybe.map encodeRoomSummary data.summary )
, ( "timeline", Maybe.map encodeTimeline data.timeline )
, ( "unread_notifications", Maybe.map encodeUnreadNotificationCounts data.unreadNotifications )
, ( "unread_thread_notifications", Just <| E.dict identity encodeThreadNotificationCounts data.unreadThreadNotifications )
]
joinedRoomDecoder : D.Decoder JoinedRoom
joinedRoomDecoder =
D.map7
(\a b c d e f g ->
{ accountData = a, ephemeral = b, state = c, summary = d, timeline = e, unreadNotifications = f, unreadThreadNotifications = g }
)
(opField "account_data" accountDataDecoder)
(opField "ephemeral" ephemeralDecoder)
(opField "state" stateDecoder)
(opField "summary" roomSummaryDecoder)
(opField "timeline" timelineDecoder)
(opField "unread_notifications" unreadNotificationCountsDecoder)
(opFieldWithDefault "unread_thread_notifications" Dict.empty (D.dict threadNotificationCountsDecoder))
{-| Room that the user has knocked upon.
-}
type alias KnockedRoom =
{ knockState : Maybe KnockState
}
encodeKnockedRoom : KnockedRoom -> E.Value
encodeKnockedRoom data =
maybeObject
[ ( "knock_state", Maybe.map encodeKnockState data.knockState )
]
knockedRoomDecoder : D.Decoder KnockedRoom
knockedRoomDecoder =
D.map
(\a ->
{ knockState = a }
)
(opField "knock_state" knockStateDecoder)
{-| The state of a room that the user has knocked upon.
-}
type alias KnockState =
{ events : List StrippedStateEvent
}
encodeKnockState : KnockState -> E.Value
encodeKnockState data =
maybeObject
[ ( "events", Just <| E.list encodeStrippedStateEvent data.events )
]
knockStateDecoder : D.Decoder KnockState
knockStateDecoder =
D.map
(\a ->
{ events = a }
)
(opFieldWithDefault "events" [] (D.list strippedStateEventDecoder))
{-| Room that the user has left.
-}
type alias LeftRoom =
{ accountData : Maybe AccountData
, state : Maybe State
, timeline : Maybe Timeline
}
encodeLeftRoom : LeftRoom -> E.Value
encodeLeftRoom data =
maybeObject
[ ( "account_data", Maybe.map encodeAccountData data.accountData )
, ( "state", Maybe.map encodeState data.state )
, ( "timeline", Maybe.map encodeTimeline data.timeline )
]
leftRoomDecoder : D.Decoder LeftRoom
leftRoomDecoder =
D.map3
(\a b c ->
{ accountData = a, state = b, timeline = c }
)
(opField "account_data" accountDataDecoder)
(opField "state" stateDecoder)
(opField "timeline" timelineDecoder)
{-| The updates to the presence status of other users.
-}
type alias Presence =
{ events : List Event
}
encodePresence : Presence -> E.Value
encodePresence data =
maybeObject
[ ( "events", Just <| E.list encodeEvent data.events )
]
presenceDecoder : D.Decoder Presence
presenceDecoder =
D.map
(\a ->
{ events = a }
)
(opFieldWithDefault "events" [] (D.list eventDecoder))
{-| Updates to rooms.
-}
type alias Rooms =
{ invite : Dict String InvitedRoom
, join : Dict String JoinedRoom
, knock : Dict String KnockedRoom
, leave : Dict String LeftRoom
}
encodeRooms : Rooms -> E.Value
encodeRooms data =
maybeObject
[ ( "invite", Just <| E.dict identity encodeInvitedRoom data.invite )
, ( "join", Just <| E.dict identity encodeJoinedRoom data.join )
, ( "knock", Just <| E.dict identity encodeKnockedRoom data.knock )
, ( "leave", Just <| E.dict identity encodeLeftRoom data.leave )
]
roomsDecoder : D.Decoder Rooms
roomsDecoder =
D.map4
(\a b c d ->
{ invite = a, join = b, knock = c, leave = d }
)
(opFieldWithDefault "invite" Dict.empty (D.dict invitedRoomDecoder))
(opFieldWithDefault "join" Dict.empty (D.dict joinedRoomDecoder))
(opFieldWithDefault "knock" Dict.empty (D.dict knockedRoomDecoder))
(opFieldWithDefault "leave" Dict.empty (D.dict leftRoomDecoder))
{-| Information about a room which clients may need to correctly render it to users.
-}
type alias RoomSummary =
{ mHeroes : Maybe (List String)
, mInvitedMemberCount : Maybe Int
, mJoinedMemberCount : Maybe Int
}
encodeRoomSummary : RoomSummary -> E.Value
encodeRoomSummary data =
maybeObject
[ ( "m.heroes", Maybe.map (E.list E.string) data.mHeroes )
, ( "m.invited_member_count", Maybe.map E.int data.mInvitedMemberCount )
, ( "m.joined_member_count", Maybe.map E.int data.mJoinedMemberCount )
]
roomSummaryDecoder : D.Decoder RoomSummary
roomSummaryDecoder =
D.map3
(\a b c ->
{ mHeroes = a, mInvitedMemberCount = b, mJoinedMemberCount = c }
)
(opField "m.heroes" (D.list D.string))
(opField "m.invited_member_count" D.int)
(opField "m.joined_member_count" D.int)
{-| Updates to the state of a room.
-}
type alias State =
{ events : List ClientEventWithoutRoomId
}
encodeState : State -> E.Value
encodeState data =
maybeObject
[ ( "events", Just <| E.list encodeClientEventWithoutRoomId data.events )
]
stateDecoder : D.Decoder State
stateDecoder =
D.map
(\a ->
{ events = a }
)
(opFieldWithDefault "events" [] (D.list clientEventWithoutRoomIdDecoder))
{-| Stripped state events of a room that the user has limited access to.
-}
type alias StrippedStateEvent =
{ content : E.Value
, sender : String
, stateKey : String
, contentType : String
}
encodeStrippedStateEvent : StrippedStateEvent -> E.Value
encodeStrippedStateEvent data =
maybeObject
[ ( "content", Just <| data.content )
, ( "sender", Just <| E.string data.sender )
, ( "state_key", Just <| E.string data.stateKey )
, ( "type", Just <| E.string data.contentType )
]
strippedStateEventDecoder : D.Decoder StrippedStateEvent
strippedStateEventDecoder =
D.map4
(\a b c d ->
{ content = a, sender = b, stateKey = c, contentType = d }
)
(D.field "content" D.value)
(D.field "sender" D.string)
(D.field "state_key" D.string)
(D.field "type" D.string)
{-| The sync response the homeserver sends to the user.
-}
type alias Sync =
{ accountData : Maybe AccountData
, nextBatch : String
, presence : Maybe Presence
, rooms : Maybe Rooms
}
encodeSync : Sync -> E.Value
encodeSync data =
maybeObject
[ ( "account_data", Maybe.map encodeAccountData data.accountData )
, ( "next_batch", Just <| E.string data.nextBatch )
, ( "presence", Maybe.map encodePresence data.presence )
, ( "rooms", Maybe.map encodeRooms data.rooms )
]
syncDecoder : D.Decoder Sync
syncDecoder =
D.map4
(\a b c d ->
{ accountData = a, nextBatch = b, presence = c, rooms = d }
)
(opField "account_data" accountDataDecoder)
(D.field "next_batch" D.string)
(opField "presence" presenceDecoder)
(opField "rooms" roomsDecoder)
{-| Counts of unread notifications for a given thread.
-}
type alias ThreadNotificationCounts =
{ highlightCount : Maybe Int
, notificationCount : Maybe Int
}
encodeThreadNotificationCounts : ThreadNotificationCounts -> E.Value
encodeThreadNotificationCounts data =
maybeObject
[ ( "highlight_count", Maybe.map E.int data.highlightCount )
, ( "notification_count", Maybe.map E.int data.notificationCount )
]
threadNotificationCountsDecoder : D.Decoder ThreadNotificationCounts
threadNotificationCountsDecoder =
D.map2
(\a b ->
{ highlightCount = a, notificationCount = b }
)
(opField "highlight_count" D.int)
(opField "notification_count" D.int)
{-| The timeline of messages and state changes in a room.
-}
type alias Timeline =
{ events : List ClientEventWithoutRoomId
, limited : Bool
, prevBatch : Maybe String
}
encodeTimeline : Timeline -> E.Value
encodeTimeline data =
maybeObject
[ ( "events", Just <| E.list encodeClientEventWithoutRoomId data.events )
, ( "limited", Just <| E.bool data.limited )
, ( "prev_batch", Maybe.map E.string data.prevBatch )
]
timelineDecoder : D.Decoder Timeline
timelineDecoder =
D.map3
(\a b c ->
{ events = a, limited = b, prevBatch = c }
)
(opFieldWithDefault "events" [] (D.list clientEventWithoutRoomIdDecoder))
(opFieldWithDefault "limited" False D.bool)
(opField "prev_batch" D.string)
{-| Counts of unread notifications for this room.
-}
type alias UnreadNotificationCounts =
{ highlightCount : Maybe Int
, notificationCount : Maybe Int
}
encodeUnreadNotificationCounts : UnreadNotificationCounts -> E.Value
encodeUnreadNotificationCounts data =
maybeObject
[ ( "highlight_count", Maybe.map E.int data.highlightCount )
, ( "notification_count", Maybe.map E.int data.notificationCount )
]
unreadNotificationCountsDecoder : D.Decoder UnreadNotificationCounts
unreadNotificationCountsDecoder =
D.map2
(\a b ->
{ highlightCount = a, notificationCount = b }
)
(opField "highlight_count" D.int)
(opField "notification_count" D.int)
{-| Data that isn't getting signed for Canonical JSON.
-}
type UnsignedData
= UnsignedData
{ age : Maybe Int
, prevContent : Maybe E.Value
, redactedBecause : Maybe ClientEventWithoutRoomId
, transactionId : Maybe String
}
encodeUnsignedData : UnsignedData -> E.Value
encodeUnsignedData (UnsignedData data) =
maybeObject
[ ( "age", Maybe.map E.int data.age )
, ( "prev_content", data.prevContent )
, ( "redacted_because", Maybe.map encodeClientEventWithoutRoomId data.redactedBecause )
, ( "transaction_id", Maybe.map E.string data.transactionId )
]
unsignedDataDecoder : D.Decoder UnsignedData
unsignedDataDecoder =
D.map4
(\a b c d ->
UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d }
)
(opField "age" D.int)
(opField "prev_content" D.value)
(opField "redacted_because" clientEventWithoutRoomIdDecoder)
(opField "transaction_id" D.string)

View File

@ -1,208 +0,0 @@
version: v1.4
name: SpecObjects
objects:
Sync:
description: The sync response the homeserver sends to the user.
fields:
account_data:
type: AccountData
next_batch:
type: string
required: true
presence:
type: Presence
rooms:
type: Rooms
AccountData:
description: The private data created by this user in a given context.
fields:
events:
type: "[Event]"
required: false
default: "[]"
Event:
description: A blind event that does not give context about itself.
fields:
content:
type: value
required: true
type:
type: string
required: true
Presence:
description: The updates to the presence status of other users.
fields:
events:
type: "[Event]"
required: false
default: "[]"
Rooms:
description: Updates to rooms.
fields:
invite:
type: "{InvitedRoom}"
required: false
default: Dict.empty
join:
type: "{JoinedRoom}"
required: false
default: Dict.empty
knock:
type: "{KnockedRoom}"
required: false
default: Dict.empty
leave:
type: "{LeftRoom}"
required: false
default: Dict.empty
InvitedRoom:
description: Room that the user has been invited to.
fields:
invite_state:
type: InviteState
InviteState:
description: The state of a room that the user has been invited to.
fields:
events:
type: "[StrippedStateEvent]"
required: false
default: "[]"
StrippedStateEvent:
description: Stripped state events of a room that the user has limited access to.
fields:
content:
type: value
required: true
sender:
type: string
required: true
state_key:
type: string
required: true
type:
type: string
required: true
JoinedRoom:
description: Room that the user has joined.
fields:
account_data:
type: AccountData
ephemeral:
type: Ephemeral
state:
type: State
summary:
type: RoomSummary
timeline:
type: Timeline
unread_notifications:
type: UnreadNotificationCounts
unread_thread_notifications:
type: "{ThreadNotificationCounts}"
required: false
default: Dict.empty
Ephemeral:
description: Ephemeral events in a room that aren't recorded in the timeline or the room state.
fields:
events:
type: "[Event]"
required: false
default: "[]"
State:
description: Updates to the state of a room.
fields:
events:
type: "[ClientEventWithoutRoomId]"
required: false
default: "[]"
ClientEventWithoutRoomId:
description: Client event that has all data except the room id.
fields:
content:
type: value
required: true
event_id:
type: string
required: true
origin_server_ts:
type: timestamp
required: true
sender:
type: string
required: true
state_key:
type: string
type:
type: string
required: true
unsigned:
type: UnsignedData
UnsignedData:
anti_recursion: true
description: Data that isn't getting signed for Canonical JSON.
fields:
age:
type: int
prev_content:
type: value
redacted_because:
type: ClientEventWithoutRoomId
transaction_id:
type: string
RoomSummary:
description: Information about a room which clients may need to correctly render it to users.
fields:
m.heroes:
type: "[string]"
m.invited_member_count:
type: int
m.joined_member_count:
type: int
Timeline:
description: The timeline of messages and state changes in a room.
fields:
events:
type: "[ClientEventWithoutRoomId]"
required: false
default: "[]"
limited:
type: bool
required: false
default: "False"
prev_batch:
type: string
UnreadNotificationCounts:
description: Counts of unread notifications for this room.
fields:
highlight_count:
type: int
notification_count:
type: int
ThreadNotificationCounts:
description: Counts of unread notifications for a given thread.
fields:
highlight_count:
type: int
notification_count:
type: int
KnockedRoom:
description: Room that the user has knocked upon.
fields:
knock_state:
type: KnockState
KnockState:
description: The state of a room that the user has knocked upon.
fields:
events:
type: "[StrippedStateEvent]"
required: false
default: "[]"
LeftRoom:
description: Room that the user has left.
fields:
account_data:
type: AccountData
state:
type: State
timeline:
type: Timeline

View File

@ -1,73 +0,0 @@
module Internal.Api.Sync.V1_4.Upcast exposing (..)
import Dict
import Internal.Api.Sync.V1_3.Objects as PO
import Internal.Api.Sync.V1_4.Objects as O
upcast : PO.Sync -> O.Sync
upcast sync =
{ accountData = sync.accountData
, nextBatch = sync.nextBatch
, presence = sync.presence
, rooms = Maybe.map upcastRooms sync.rooms
}
upcastRooms : PO.Rooms -> O.Rooms
upcastRooms rooms =
{ invite = rooms.invite
, join = Dict.map (\_ -> upcastJoinedRoom) rooms.join
, knock = rooms.knock
, leave = Dict.map (\_ -> upcastLeftRoom) rooms.leave
}
upcastJoinedRoom : PO.JoinedRoom -> O.JoinedRoom
upcastJoinedRoom room =
{ accountData = room.accountData
, ephemeral = room.ephemeral
, state = List.map upcastClientEventWithoutRoomId room.state
, summary = room.summary
, timeline = Maybe.map upcastTimeline room.timeline
, unreadNotifications = room.unreadNotifications
, unreadThreadNotifications = Dict.empty
}
upcastClientEventWithoutRoomId : PO.ClientEventWithoutRoomId -> O.ClientEventWithoutRoomId
upcastClientEventWithoutRoomId event =
{ content = event.content
, eventId = event.eventId
, originServerTs = event.originServerTs
, sender = event.sender
, stateKey = event.stateKey
, contentType = event.contentType
, unsigned = Maybe.map upcastUnsigned event.unsigned
}
upcastUnsigned : PO.UnsignedData -> O.UnsignedData
upcastUnsigned (PO.UnsignedData data) =
O.UnsignedData
{ age = data.age
, prevContent = data.prevContent
, redactedBecause = Maybe.map upcastClientEventWithoutRoomId data.redactedBecause
, transactionId = data.transactionId
}
upcastTimeline : PO.Timeline -> O.Timeline
upcastTimeline timeline =
{ events = List.map upcastClientEventWithoutRoomId timeline.events
, limited = timeline.limited
, prevBatch = timeline.prevBatch
}
upcastLeftRoom : PO.LeftRoom -> O.LeftRoom
upcastLeftRoom room =
{ accountData = room.accountData
, state = List.map upcastClientEventWithoutRoomId room.state
, timeline = Maybe.map upcastTimeline room.timeline
}

View File

@ -1,18 +0,0 @@
module Internal.Api.Sync.V1_5.Api exposing (..)
import Internal.Api.Sync.Api as Api
import Internal.Api.Sync.V1_4.Objects as PO
import Internal.Api.Sync.V1_5.Convert as C
import Internal.Api.Sync.V1_5.Objects as O
import Internal.Api.Sync.V1_5.SpecObjects as SO
import Internal.Api.Sync.V1_5.Upcast as U
import Internal.Api.VersionControl as V
packet : V.SingleVersion Api.SyncInputV1 PO.Sync Api.SyncInputV1 O.Sync
packet =
{ version = "v1.5"
, downcast = identity
, current = Api.syncV1 SO.syncDecoder C.convert
, upcast = U.upcast
}

View File

@ -1,84 +0,0 @@
module Internal.Api.Sync.V1_5.Convert exposing (..)
import Dict
import Internal.Api.Sync.V1_5.Objects as O
import Internal.Api.Sync.V1_5.SpecObjects as SO
convert : SO.Sync -> O.Sync
convert sync =
{ accountData = convertEventHolder sync.accountData
, nextBatch = sync.nextBatch
, presence = convertEventHolder sync.presence
, rooms = Maybe.map convertRooms sync.rooms
}
convertEventHolder : Maybe { a | events : List b } -> List b
convertEventHolder =
Maybe.map .events >> Maybe.withDefault []
convertRooms : SO.Rooms -> O.Rooms
convertRooms rooms =
{ invite =
Dict.map
(\_ -> .inviteState >> Maybe.map .events >> Maybe.withDefault [])
rooms.invite
, join = Dict.map (\_ -> convertJoinedRoom) rooms.join
, knock =
Dict.map
(\_ -> .knockState >> Maybe.map .events >> Maybe.withDefault [])
rooms.knock
, leave = Dict.map (\_ -> convertLeftRoom) rooms.leave
}
convertJoinedRoom : SO.JoinedRoom -> O.JoinedRoom
convertJoinedRoom room =
{ accountData = convertEventHolder room.accountData
, ephemeral = convertEventHolder room.ephemeral
, state = convertEventHolder room.state |> List.map convertClientEventWithoutRoomId
, summary = room.summary
, timeline = Maybe.map convertTimeline room.timeline
, unreadNotifications = room.unreadNotifications
, unreadThreadNotifications = room.unreadThreadNotifications
}
convertClientEventWithoutRoomId : SO.ClientEventWithoutRoomId -> O.ClientEventWithoutRoomId
convertClientEventWithoutRoomId event =
{ content = event.content
, eventId = event.eventId
, originServerTs = event.originServerTs
, sender = event.sender
, stateKey = event.stateKey
, contentType = event.contentType
, unsigned = Maybe.map convertUnsigned event.unsigned
}
convertUnsigned : SO.UnsignedData -> O.UnsignedData
convertUnsigned (SO.UnsignedData data) =
O.UnsignedData
{ age = data.age
, prevContent = data.prevContent
, redactedBecause = Maybe.map convertClientEventWithoutRoomId data.redactedBecause
, transactionId = data.transactionId
}
convertTimeline : SO.Timeline -> O.Timeline
convertTimeline timeline =
{ events = List.map convertClientEventWithoutRoomId timeline.events
, limited = timeline.limited
, prevBatch = timeline.prevBatch
}
convertLeftRoom : SO.LeftRoom -> O.LeftRoom
convertLeftRoom room =
{ accountData = convertEventHolder room.accountData
, state = convertEventHolder room.state |> List.map convertClientEventWithoutRoomId
, timeline = Maybe.map convertTimeline room.timeline
}

View File

@ -1,398 +0,0 @@
module Internal.Api.Sync.V1_5.Objects exposing
( BlindEvent
, ClientEventWithoutRoomId
, JoinedRoom
, LeftRoom
, RoomSummary
, Rooms
, StrippedStateEvent
, Sync
, Timeline
, UnreadNotificationCounts
, UnsignedData(..)
, blindEventDecoder
, clientEventWithoutRoomIdDecoder
, encodeBlindEvent
, encodeClientEventWithoutRoomId
, encodeJoinedRoom
, encodeLeftRoom
, encodeRoomSummary
, encodeRooms
, encodeStrippedStateEvent
, encodeSync
, encodeTimeline
, encodeUnreadNotificationCounts
, encodeUnsignedData
, joinedRoomDecoder
, leftRoomDecoder
, roomSummaryDecoder
, roomsDecoder
, strippedStateEventDecoder
, syncDecoder
, timelineDecoder
, unreadNotificationCountsDecoder
, unsignedDataDecoder
)
{-| Automatically generated 'Objects'
Last generated at Unix time 1673279712
-}
import Dict exposing (Dict)
import Internal.Tools.DecodeExtra exposing (opField, opFieldWithDefault)
import Internal.Tools.EncodeExtra exposing (maybeObject)
import Internal.Tools.Timestamp exposing (Timestamp, encodeTimestamp, timestampDecoder)
import Json.Decode as D
import Json.Encode as E
{-| A blind event that does not give context about itself.
-}
type alias BlindEvent =
{ content : E.Value
, contentType : String
}
encodeBlindEvent : BlindEvent -> E.Value
encodeBlindEvent data =
maybeObject
[ ( "content", Just <| data.content )
, ( "type", Just <| E.string data.contentType )
]
blindEventDecoder : D.Decoder BlindEvent
blindEventDecoder =
D.map2
(\a b ->
{ content = a, contentType = b }
)
(D.field "content" D.value)
(D.field "type" D.string)
{-| Client event that has all data except the room id.
-}
type alias ClientEventWithoutRoomId =
{ content : E.Value
, eventId : String
, originServerTs : Timestamp
, sender : String
, stateKey : Maybe String
, contentType : String
, unsigned : Maybe UnsignedData
}
encodeClientEventWithoutRoomId : ClientEventWithoutRoomId -> E.Value
encodeClientEventWithoutRoomId data =
maybeObject
[ ( "content", Just <| data.content )
, ( "event_id", Just <| E.string data.eventId )
, ( "origin_server_ts", Just <| encodeTimestamp data.originServerTs )
, ( "sender", Just <| E.string data.sender )
, ( "state_key", Maybe.map E.string data.stateKey )
, ( "type", Just <| E.string data.contentType )
, ( "unsigned", Maybe.map encodeUnsignedData data.unsigned )
]
clientEventWithoutRoomIdDecoder : D.Decoder ClientEventWithoutRoomId
clientEventWithoutRoomIdDecoder =
D.map7
(\a b c d e f g ->
{ content = a, eventId = b, originServerTs = c, sender = d, stateKey = e, contentType = f, unsigned = g }
)
(D.field "content" D.value)
(D.field "event_id" D.string)
(D.field "origin_server_ts" timestampDecoder)
(D.field "sender" D.string)
(opField "state_key" D.string)
(D.field "type" D.string)
(opField "unsigned" (D.lazy (\_ -> unsignedDataDecoder)))
{-| Room that the user has joined.
-}
type alias JoinedRoom =
{ accountData : List BlindEvent
, ephemeral : List BlindEvent
, state : List ClientEventWithoutRoomId
, summary : Maybe RoomSummary
, timeline : Maybe Timeline
, unreadNotifications : Maybe UnreadNotificationCounts
, unreadThreadNotifications : Dict String UnreadNotificationCounts
}
encodeJoinedRoom : JoinedRoom -> E.Value
encodeJoinedRoom data =
maybeObject
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
, ( "ephemeral", Just <| E.list encodeBlindEvent data.ephemeral )
, ( "state", Just <| E.list encodeClientEventWithoutRoomId data.state )
, ( "summary", Maybe.map encodeRoomSummary data.summary )
, ( "timeline", Maybe.map encodeTimeline data.timeline )
, ( "unread_notifications", Maybe.map encodeUnreadNotificationCounts data.unreadNotifications )
, ( "unread_thread_notifications", Just <| E.dict identity encodeUnreadNotificationCounts data.unreadThreadNotifications )
]
joinedRoomDecoder : D.Decoder JoinedRoom
joinedRoomDecoder =
D.map7
(\a b c d e f g ->
{ accountData = a, ephemeral = b, state = c, summary = d, timeline = e, unreadNotifications = f, unreadThreadNotifications = g }
)
(D.field "account_data" (D.list blindEventDecoder))
(D.field "ephemeral" (D.list blindEventDecoder))
(D.field "state" (D.list clientEventWithoutRoomIdDecoder))
(opField "summary" roomSummaryDecoder)
(opField "timeline" timelineDecoder)
(opField "unread_notifications" unreadNotificationCountsDecoder)
(D.field "unread_thread_notifications" (D.dict unreadNotificationCountsDecoder))
{-| Room that the user has left.
-}
type alias LeftRoom =
{ accountData : List BlindEvent
, state : List ClientEventWithoutRoomId
, timeline : Maybe Timeline
}
encodeLeftRoom : LeftRoom -> E.Value
encodeLeftRoom data =
maybeObject
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
, ( "state", Just <| E.list encodeClientEventWithoutRoomId data.state )
, ( "timeline", Maybe.map encodeTimeline data.timeline )
]
leftRoomDecoder : D.Decoder LeftRoom
leftRoomDecoder =
D.map3
(\a b c ->
{ accountData = a, state = b, timeline = c }
)
(D.field "account_data" (D.list blindEventDecoder))
(D.field "state" (D.list clientEventWithoutRoomIdDecoder))
(opField "timeline" timelineDecoder)
{-| Updates to rooms.
-}
type alias Rooms =
{ invite : Dict String (List StrippedStateEvent)
, join : Dict String JoinedRoom
, knock : Dict String (List StrippedStateEvent)
, leave : Dict String LeftRoom
}
encodeRooms : Rooms -> E.Value
encodeRooms data =
maybeObject
[ ( "invite", Just <| E.dict identity (E.list encodeStrippedStateEvent) data.invite )
, ( "join", Just <| E.dict identity encodeJoinedRoom data.join )
, ( "knock", Just <| E.dict identity (E.list encodeStrippedStateEvent) data.knock )
, ( "leave", Just <| E.dict identity encodeLeftRoom data.leave )
]
roomsDecoder : D.Decoder Rooms
roomsDecoder =
D.map4
(\a b c d ->
{ invite = a, join = b, knock = c, leave = d }
)
(opFieldWithDefault "invite" Dict.empty (D.dict (D.list strippedStateEventDecoder)))
(opFieldWithDefault "join" Dict.empty (D.dict joinedRoomDecoder))
(opFieldWithDefault "knock" Dict.empty (D.dict (D.list strippedStateEventDecoder)))
(opFieldWithDefault "leave" Dict.empty (D.dict leftRoomDecoder))
{-| Information about a room which clients may need to correctly render it to users.
-}
type alias RoomSummary =
{ mHeroes : Maybe (List String)
, mInvitedMemberCount : Maybe Int
, mJoinedMemberCount : Maybe Int
}
encodeRoomSummary : RoomSummary -> E.Value
encodeRoomSummary data =
maybeObject
[ ( "m.heroes", Maybe.map (E.list E.string) data.mHeroes )
, ( "m.invited_member_count", Maybe.map E.int data.mInvitedMemberCount )
, ( "m.joined_member_count", Maybe.map E.int data.mJoinedMemberCount )
]
roomSummaryDecoder : D.Decoder RoomSummary
roomSummaryDecoder =
D.map3
(\a b c ->
{ mHeroes = a, mInvitedMemberCount = b, mJoinedMemberCount = c }
)
(opField "m.heroes" (D.list D.string))
(opField "m.invited_member_count" D.int)
(opField "m.joined_member_count" D.int)
{-| Stripped state events of a room that the user has limited access to.
-}
type alias StrippedStateEvent =
{ content : E.Value
, sender : String
, stateKey : String
, contentType : String
}
encodeStrippedStateEvent : StrippedStateEvent -> E.Value
encodeStrippedStateEvent data =
maybeObject
[ ( "content", Just <| data.content )
, ( "sender", Just <| E.string data.sender )
, ( "state_key", Just <| E.string data.stateKey )
, ( "type", Just <| E.string data.contentType )
]
strippedStateEventDecoder : D.Decoder StrippedStateEvent
strippedStateEventDecoder =
D.map4
(\a b c d ->
{ content = a, sender = b, stateKey = c, contentType = d }
)
(D.field "content" D.value)
(D.field "sender" D.string)
(D.field "state_key" D.string)
(D.field "type" D.string)
{-| The sync response the homeserver sends to the user.
-}
type alias Sync =
{ accountData : List BlindEvent
, nextBatch : String
, presence : List BlindEvent
, rooms : Maybe Rooms
}
encodeSync : Sync -> E.Value
encodeSync data =
maybeObject
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
, ( "next_batch", Just <| E.string data.nextBatch )
, ( "presence", Just <| E.list encodeBlindEvent data.presence )
, ( "rooms", Maybe.map encodeRooms data.rooms )
]
syncDecoder : D.Decoder Sync
syncDecoder =
D.map4
(\a b c d ->
{ accountData = a, nextBatch = b, presence = c, rooms = d }
)
(D.field "account_data" (D.list blindEventDecoder))
(D.field "next_batch" D.string)
(D.field "presence" (D.list blindEventDecoder))
(opField "rooms" roomsDecoder)
{-| The timeline of messages and state changes in a room.
-}
type alias Timeline =
{ events : List ClientEventWithoutRoomId
, limited : Bool
, prevBatch : Maybe String
}
encodeTimeline : Timeline -> E.Value
encodeTimeline data =
maybeObject
[ ( "events", Just <| E.list encodeClientEventWithoutRoomId data.events )
, ( "limited", Just <| E.bool data.limited )
, ( "prev_batch", Maybe.map E.string data.prevBatch )
]
timelineDecoder : D.Decoder Timeline
timelineDecoder =
D.map3
(\a b c ->
{ events = a, limited = b, prevBatch = c }
)
(opFieldWithDefault "events" [] (D.list clientEventWithoutRoomIdDecoder))
(opFieldWithDefault "limited" False D.bool)
(opField "prev_batch" D.string)
{-| Counts of unread notifications for this room.
-}
type alias UnreadNotificationCounts =
{ highlightCount : Maybe Int
, notificationCount : Maybe Int
}
encodeUnreadNotificationCounts : UnreadNotificationCounts -> E.Value
encodeUnreadNotificationCounts data =
maybeObject
[ ( "highlight_count", Maybe.map E.int data.highlightCount )
, ( "notification_count", Maybe.map E.int data.notificationCount )
]
unreadNotificationCountsDecoder : D.Decoder UnreadNotificationCounts
unreadNotificationCountsDecoder =
D.map2
(\a b ->
{ highlightCount = a, notificationCount = b }
)
(opField "highlight_count" D.int)
(opField "notification_count" D.int)
{-| Data that isn't getting signed for Canonical JSON.
-}
type UnsignedData
= UnsignedData
{ age : Maybe Int
, prevContent : Maybe E.Value
, redactedBecause : Maybe ClientEventWithoutRoomId
, transactionId : Maybe String
}
encodeUnsignedData : UnsignedData -> E.Value
encodeUnsignedData (UnsignedData data) =
maybeObject
[ ( "age", Maybe.map E.int data.age )
, ( "prev_content", data.prevContent )
, ( "redacted_because", Maybe.map encodeClientEventWithoutRoomId data.redactedBecause )
, ( "transaction_id", Maybe.map E.string data.transactionId )
]
unsignedDataDecoder : D.Decoder UnsignedData
unsignedDataDecoder =
D.map4
(\a b c d ->
UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d }
)
(opField "age" D.int)
(opField "prev_content" D.value)
(opField "redacted_because" clientEventWithoutRoomIdDecoder)
(opField "transaction_id" D.string)

View File

@ -1,155 +0,0 @@
version: v1.5
name: Objects
objects:
Sync:
description: The sync response the homeserver sends to the user.
fields:
account_data:
type: "[BlindEvent]"
required: true
next_batch:
type: string
required: true
presence:
type: "[BlindEvent]"
required: true
rooms:
type: Rooms
BlindEvent:
description: A blind event that does not give context about itself.
fields:
content:
type: value
required: true
type:
type: string
required: true
Rooms:
description: Updates to rooms.
fields:
invite:
type: "{[StrippedStateEvent]}"
required: false
default: Dict.empty
join:
type: "{JoinedRoom}"
required: false
default: Dict.empty
knock:
type: "{[StrippedStateEvent]}"
required: false
default: Dict.empty
leave:
type: "{LeftRoom}"
required: false
default: Dict.empty
StrippedStateEvent:
description: Stripped state events of a room that the user has limited access to.
fields:
content:
type: value
required: true
sender:
type: string
required: true
state_key:
type: string
required: true
type:
type: string
required: true
JoinedRoom:
description: Room that the user has joined.
fields:
account_data:
type: "[BlindEvent]"
required: true
ephemeral:
type: "[BlindEvent]"
required: true
state:
type: "[ClientEventWithoutRoomId]"
required: true
summary:
type: RoomSummary
timeline:
type: Timeline
unread_notifications:
type: UnreadNotificationCounts
unread_thread_notifications:
type: "{UnreadNotificationCounts}"
required: true
ClientEventWithoutRoomId:
description: Client event that has all data except the room id.
fields:
content:
type: value
required: true
event_id:
type: string
required: true
origin_server_ts:
type: timestamp
required: true
sender:
type: string
required: true
state_key:
type: string
type:
type: string
required: true
unsigned:
type: UnsignedData
UnsignedData:
anti_recursion: true
description: Data that isn't getting signed for Canonical JSON.
fields:
age:
type: int
prev_content:
type: value
redacted_because:
type: ClientEventWithoutRoomId
transaction_id:
type: string
RoomSummary:
description: Information about a room which clients may need to correctly render it to users.
fields:
m.heroes:
type: "[string]"
m.invited_member_count:
type: int
m.joined_member_count:
type: int
Timeline:
description: The timeline of messages and state changes in a room.
fields:
events:
type: "[ClientEventWithoutRoomId]"
required: false
default: "[]"
limited:
type: bool
required: false
default: "False"
prev_batch:
type: string
UnreadNotificationCounts:
description: Counts of unread notifications for this room.
fields:
highlight_count:
type: int
notification_count:
type: int
LeftRoom:
description: Room that the user has left.
fields:
account_data:
type: "[BlindEvent]"
required: true
state:
type: "[ClientEventWithoutRoomId]"
required: true
timeline:
type: Timeline

View File

@ -1,73 +0,0 @@
module Internal.Api.Sync.V1_5.Upcast exposing (..)
import Dict
import Internal.Api.Sync.V1_4.Objects as PO
import Internal.Api.Sync.V1_5.Objects as O
upcast : PO.Sync -> O.Sync
upcast sync =
{ accountData = sync.accountData
, nextBatch = sync.nextBatch
, presence = sync.presence
, rooms = Maybe.map upcastRooms sync.rooms
}
upcastRooms : PO.Rooms -> O.Rooms
upcastRooms rooms =
{ invite = rooms.invite
, join = Dict.map (\_ -> upcastJoinedRoom) rooms.join
, knock = rooms.knock
, leave = Dict.map (\_ -> upcastLeftRoom) rooms.leave
}
upcastJoinedRoom : PO.JoinedRoom -> O.JoinedRoom
upcastJoinedRoom room =
{ accountData = room.accountData
, ephemeral = room.ephemeral
, state = List.map upcastClientEventWithoutRoomId room.state
, summary = room.summary
, timeline = Maybe.map upcastTimeline room.timeline
, unreadNotifications = room.unreadNotifications
, unreadThreadNotifications = room.unreadThreadNotifications
}
upcastClientEventWithoutRoomId : PO.ClientEventWithoutRoomId -> O.ClientEventWithoutRoomId
upcastClientEventWithoutRoomId event =
{ content = event.content
, eventId = event.eventId
, originServerTs = event.originServerTs
, sender = event.sender
, stateKey = event.stateKey
, contentType = event.contentType
, unsigned = Maybe.map upcastUnsigned event.unsigned
}
upcastUnsigned : PO.UnsignedData -> O.UnsignedData
upcastUnsigned (PO.UnsignedData data) =
O.UnsignedData
{ age = data.age
, prevContent = data.prevContent
, redactedBecause = Maybe.map upcastClientEventWithoutRoomId data.redactedBecause
, transactionId = data.transactionId
}
upcastTimeline : PO.Timeline -> O.Timeline
upcastTimeline timeline =
{ events = List.map upcastClientEventWithoutRoomId timeline.events
, limited = timeline.limited
, prevBatch = timeline.prevBatch
}
upcastLeftRoom : PO.LeftRoom -> O.LeftRoom
upcastLeftRoom room =
{ accountData = room.accountData
, state = List.map upcastClientEventWithoutRoomId room.state
, timeline = Maybe.map upcastTimeline room.timeline
}

View File

@ -1,4 +1,4 @@
module Internal.Api.Sync.V1_5.SpecObjects exposing module Internal.Api.Sync.V2.SpecObjects exposing
( AccountData ( AccountData
, ClientEventWithoutRoomId , ClientEventWithoutRoomId
, Ephemeral , Ephemeral
@ -63,7 +63,7 @@ module Internal.Api.Sync.V1_5.SpecObjects exposing
{-| Automatically generated 'SpecObjects' {-| Automatically generated 'SpecObjects'
Last generated at Unix time 1673279712 Last generated at Unix time 1676625735
-} -}

View File

@ -1,4 +1,4 @@
version: v1.5 version: v2
name: SpecObjects name: SpecObjects
objects: objects:
Sync: Sync:

View File

@ -0,0 +1,70 @@
module Internal.Api.Sync.V2.Upcast exposing (..)
import Dict
import Internal.Api.Sync.V1.SpecObjects as PO
import Internal.Api.Sync.V2.SpecObjects as SO
upcastSync : PO.Sync -> SO.Sync
upcastSync old =
{ accountData = old.accountData
, nextBatch = old.nextBatch
, presence = old.presence
, rooms = Maybe.map upcastRooms old.rooms
}
upcastRooms : PO.Rooms -> SO.Rooms
upcastRooms old =
{ invite = old.invite
, join = Dict.map (\_ -> upcastJoinedRoom) old.join
, knock = old.knock
, leave = Dict.map (\_ -> upcastLeftRoom) old.leave
}
upcastJoinedRoom : PO.JoinedRoom -> SO.JoinedRoom
upcastJoinedRoom old =
{ accountData = old.accountData
, ephemeral = old.ephemeral
, state = Maybe.map upcastState old.state
, summary = old.summary
, timeline = Maybe.map upcastTimeline old.timeline
, unreadNotifications = old.unreadNotifications
, unreadThreadNotifications = Dict.empty
}
upcastState : PO.State -> SO.State
upcastState old =
{ events = List.map upcastClientEventWithoutRoomId old.events }
upcastClientEventWithoutRoomId : PO.ClientEventWithoutRoomId -> SO.ClientEventWithoutRoomId
upcastClientEventWithoutRoomId old =
{ content = old.content
, eventId = old.eventId
, originServerTs = old.originServerTs
, sender = old.sender
, stateKey = old.stateKey
, contentType = old.contentType
, unsigned = Maybe.map upcastUnsigned old.unsigned
}
upcastUnsigned : PO.UnsignedData -> SO.UnsignedData
upcastUnsigned (PO.UnsignedData old) =
SO.UnsignedData
{ age = old.age
, prevContent = old.prevContent
, redactedBecause = Maybe.map upcastClientEventWithoutRoomId old.redactedBecause
, transactionId = old.transactionId
}
upcastTimeline : PO.Timeline -> SO.Timeline
upcastTimeline old =
{ events = List.map upcastClientEventWithoutRoomId old.events
, limited = old.limited
, prevBatch = old.prevBatch
}
upcastLeftRoom : PO.LeftRoom -> SO.LeftRoom
upcastLeftRoom old =
{ accountData = old.accountData
, state = Maybe.map upcastState old.state
, timeline = Maybe.map upcastTimeline old.timeline
}