"use strict"; // FIXME: own package const required = require("@validatem/required"); const anyProperty = require("@validatem/any-property"); const arrayOf = require("@validatem/array-of"); const isString = require("@validatem/is-string"); const isInteger = require("@validatem/is-integer"); const isBoolean = require("@validatem/is-boolean"); const anything = require("@validatem/anything"); const isEvent = require("../is-event"); const isPresenceEvent = require("../is-presence-event"); const isStateEvent = require("../is-state-event"); const isDeviceEvent = require("../is-device-event"); const isStrippedEvent = require("../is-stripped-event"); const isTimelineEvent = require("../is-timeline-event"); const isRoomID = require("../is-room-id"); const isMatrixID = require("../is-matrix-id"); const optionalObject = require("../optional-object"); const optionalArray = require("../optional-array"); let isStateList = arrayOf([ required, isStateEvent ]); let isEventList = arrayOf([ required, isEvent ]); let isPresenceEventList = arrayOf([ required, isPresenceEvent ]); let isStrippedEventList = arrayOf([ required, isStrippedEvent ]); let isDeviceEventList = arrayOf([ required, isDeviceEvent ]); let isTimelineList = arrayOf([ required, isTimelineEvent ]); module.exports = { next_batch: [ required, isString ], // FIXME: also optionalObject for `rooms` rooms: { join: optionalObject(anyProperty({ key: [ required, isRoomID ], value: { summary: optionalObject({ "m.heroes": arrayOf([ required, isString ]), "m.joined_member_count": isInteger, "m.invited_member_count": isInteger, }), // NOTE: Despite what the spec currently says, state.events *can* contain membership events when the timeline isn't limited, when lazy-loading is enabled state: optionalObject({ events: optionalArray(isStateList) }), timeline: optionalObject({ events: optionalArray(isTimelineList), limited: isBoolean, prev_batch: isString }), ephemeral: optionalObject({ events: optionalArray(isEventList) }), account_data: optionalObject({ events: optionalArray(isEventList) }), unread_notifications: { highlight_count: isInteger, notification_count: isInteger }, // FIXME: expose the below "org.matrix.msc2654.unread_count": [ isInteger ], // NOTE: https://github.com/matrix-org/matrix-doc/pull/2654 } })), invite: optionalObject(anyProperty({ key: [ required, isRoomID ], value: { // NOTE: This state needs to be maintained separately from known room state (see spec). FIXME: Represent this in the event list output? invite_state: optionalObject({ events: optionalArray(isStrippedEventList) }) } })), leave: optionalObject(anyProperty({ key: [ required, isRoomID ], value: { state: optionalObject({ events: optionalArray(isStateList) }), timeline: optionalObject({ events: optionalArray(isTimelineList), limited: isBoolean, prev_batch: isString }), account_data: optionalObject({ events: optionalArray(isEventList) }), } })) }, presence: optionalObject({ events: optionalArray(isPresenceEventList) }), account_data: optionalObject({ events: optionalArray(isEventList) }), to_device: optionalObject({ events: optionalArray(isDeviceEventList) }), device_lists: optionalObject({ changed: arrayOf([ required, isMatrixID ]), left: arrayOf([ required, isMatrixID ]) }), device_one_time_keys_count: optionalObject(anyProperty({ key: [ required, isString ], // algorithm name value: [ required, isInteger ] // key count })), groups: anything, // NOTE: Non-standard // TODO: Validate algorithm names below? "org.matrix.msc2732.device_unused_fallback_key_types": optionalArray(arrayOf([ required, isString ])), // NOTE: https://github.com/matrix-org/matrix-doc/pull/2732 };