You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
4.1 KiB
JavaScript

"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");
module.exports = function isSyncResponse(strict = false) {
// FIXME: Expand validation rules affected by 'strict' setting? eg. allowing extra properties in the sync response itself
let isStateList = arrayOf([ required, isStateEvent(strict) ]);
let isEventList = arrayOf([ required, isEvent(strict) ]);
let isPresenceEventList = arrayOf([ required, isPresenceEvent(strict) ]);
let isStrippedEventList = arrayOf([ required, isStrippedEvent(strict) ]);
let isDeviceEventList = arrayOf([ required, isDeviceEvent(strict) ]);
let isTimelineList = arrayOf([ required, isTimelineEvent(strict) ]);
return {
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
};
};