diff --git a/lib/types/message-types.js b/lib/types/message-types.js index 67ab54258..e64a6428f 100644 --- a/lib/types/message-types.js +++ b/lib/types/message-types.js @@ -1,696 +1,696 @@ // @flow import invariant from 'invariant'; import t, { type TDict, type TEnums, type TInterface, type TUnion, } from 'tcomb'; import { type ClientDBMediaInfo } from './media-types.js'; import { type MessageType, messageTypes } from './message-types-enum.js'; import { type AddMembersMessageData, type AddMembersMessageInfo, type RawAddMembersMessageInfo, rawAddMembersMessageInfoValidator, } from './messages/add-members.js'; import { type ChangeRoleMessageData, type ChangeRoleMessageInfo, type RawChangeRoleMessageInfo, rawChangeRoleMessageInfoValidator, } from './messages/change-role.js'; import { type ChangeSettingsMessageData, type ChangeSettingsMessageInfo, type RawChangeSettingsMessageInfo, rawChangeSettingsMessageInfoValidator, } from './messages/change-settings.js'; import { type CreateEntryMessageData, type CreateEntryMessageInfo, type RawCreateEntryMessageInfo, rawCreateEntryMessageInfoValidator, } from './messages/create-entry.js'; import { type CreateSidebarMessageData, type CreateSidebarMessageInfo, type RawCreateSidebarMessageInfo, rawCreateSidebarMessageInfoValidator, } from './messages/create-sidebar.js'; import { type CreateSubthreadMessageData, type CreateSubthreadMessageInfo, type RawCreateSubthreadMessageInfo, rawCreateSubthreadMessageInfoValidator, } from './messages/create-subthread.js'; import { type CreateThreadMessageData, type CreateThreadMessageInfo, type RawCreateThreadMessageInfo, rawCreateThreadMessageInfoValidator, } from './messages/create-thread.js'; import { type DeleteEntryMessageData, type DeleteEntryMessageInfo, type RawDeleteEntryMessageInfo, rawDeleteEntryMessageInfoValidator, } from './messages/delete-entry.js'; import { type EditEntryMessageData, type EditEntryMessageInfo, type RawEditEntryMessageInfo, rawEditEntryMessageInfoValidator, } from './messages/edit-entry.js'; import { type EditMessageData, type EditMessageInfo, type RawEditMessageInfo, rawEditMessageInfoValidator, } from './messages/edit.js'; import { type ImagesMessageData, type ImagesMessageInfo, type RawImagesMessageInfo, rawImagesMessageInfoValidator, } from './messages/images.js'; import { type JoinThreadMessageData, type JoinThreadMessageInfo, type RawJoinThreadMessageInfo, rawJoinThreadMessageInfoValidator, } from './messages/join-thread.js'; import { type LeaveThreadMessageData, type LeaveThreadMessageInfo, type RawLeaveThreadMessageInfo, rawLeaveThreadMessageInfoValidator, } from './messages/leave-thread.js'; import { type RawLegacyUpdateRelationshipMessageInfo, rawLegacyUpdateRelationshipMessageInfoValidator, type LegacyUpdateRelationshipMessageData, type LegacyUpdateRelationshipMessageInfo, } from './messages/legacy-update-relationship.js'; import { type MediaMessageData, type MediaMessageInfo, type MediaMessageServerDBContent, type RawMediaMessageInfo, rawMediaMessageInfoValidator, } from './messages/media.js'; import { type RawReactionMessageInfo, rawReactionMessageInfoValidator, type ReactionMessageData, type ReactionMessageInfo, } from './messages/reaction.js'; import { type RawRemoveMembersMessageInfo, rawRemoveMembersMessageInfoValidator, type RemoveMembersMessageData, type RemoveMembersMessageInfo, } from './messages/remove-members.js'; import { type RawRestoreEntryMessageInfo, rawRestoreEntryMessageInfoValidator, type RestoreEntryMessageData, type RestoreEntryMessageInfo, } from './messages/restore-entry.js'; import { type RawTextMessageInfo, rawTextMessageInfoValidator, type TextMessageData, type TextMessageInfo, } from './messages/text.js'; import { type RawTogglePinMessageInfo, rawTogglePinMessageInfoValidator, type TogglePinMessageData, type TogglePinMessageInfo, } from './messages/toggle-pin.js'; import { type RawUnsupportedMessageInfo, rawUnsupportedMessageInfoValidator, type UnsupportedMessageInfo, } from './messages/unsupported.js'; import type { RawUpdateRelationshipMessageInfo, UpdateRelationshipMessageData, UpdateRelationshipMessageInfo, } from './messages/update-relationship.js'; import { rawUpdateRelationshipMessageInfoValidator } from './messages/update-relationship.js'; import { type RelativeUserInfo, type UserInfos } from './user-types.js'; import type { CallSingleKeyserverEndpointResultInfoInterface } from '../keyserver-conn/call-single-keyserver-endpoint.js'; import { values } from '../utils/objects.js'; -import { tID, tNumber, tShape } from '../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../utils/validation-utils.js'; const composableMessageTypes = new Set([ messageTypes.TEXT, messageTypes.IMAGES, messageTypes.MULTIMEDIA, ]); export function isComposableMessageType(ourMessageType: MessageType): boolean { return composableMessageTypes.has(ourMessageType); } export function assertComposableMessageType( ourMessageType: MessageType, ): MessageType { invariant( isComposableMessageType(ourMessageType), 'MessageType is not composed', ); return ourMessageType; } export function assertComposableRawMessage( message: RawMessageInfo, ): RawComposableMessageInfo { invariant( message.type === messageTypes.TEXT || message.type === messageTypes.IMAGES || message.type === messageTypes.MULTIMEDIA, 'Message is not composable', ); return message; } export function messageDataLocalID(messageData: MessageData): ?string { if ( messageData.type !== messageTypes.TEXT && messageData.type !== messageTypes.IMAGES && messageData.type !== messageTypes.MULTIMEDIA && messageData.type !== messageTypes.REACTION ) { return null; } return messageData.localID; } const mediaMessageTypes = new Set([ messageTypes.IMAGES, messageTypes.MULTIMEDIA, ]); export function isMediaMessageType(ourMessageType: MessageType): boolean { return mediaMessageTypes.has(ourMessageType); } export function assertMediaMessageType( ourMessageType: MessageType, ): MessageType { invariant(isMediaMessageType(ourMessageType), 'MessageType is not media'); return ourMessageType; } // *MessageData = passed to createMessages function to insert into database // Raw*MessageInfo = used by server, and contained in client's local store // *MessageInfo = used by client in UI code export type ValidRawSidebarSourceMessageInfo = | RawTextMessageInfo | RawCreateThreadMessageInfo | RawAddMembersMessageInfo | RawCreateSubthreadMessageInfo | RawChangeSettingsMessageInfo | RawRemoveMembersMessageInfo | RawChangeRoleMessageInfo | RawLeaveThreadMessageInfo | RawJoinThreadMessageInfo | RawCreateEntryMessageInfo | RawEditEntryMessageInfo | RawDeleteEntryMessageInfo | RawRestoreEntryMessageInfo | RawImagesMessageInfo | RawMediaMessageInfo | RawLegacyUpdateRelationshipMessageInfo | RawCreateSidebarMessageInfo | RawUnsupportedMessageInfo | RawUpdateRelationshipMessageInfo; export type SidebarSourceMessageData = { +type: 17, +threadID: string, +creatorID: string, +time: number, +sourceMessage?: ValidRawSidebarSourceMessageInfo, }; export type MessageData = | TextMessageData | CreateThreadMessageData | AddMembersMessageData | CreateSubthreadMessageData | ChangeSettingsMessageData | RemoveMembersMessageData | ChangeRoleMessageData | LeaveThreadMessageData | JoinThreadMessageData | CreateEntryMessageData | EditEntryMessageData | DeleteEntryMessageData | RestoreEntryMessageData | ImagesMessageData | MediaMessageData | LegacyUpdateRelationshipMessageData | SidebarSourceMessageData | CreateSidebarMessageData | ReactionMessageData | EditMessageData | TogglePinMessageData | UpdateRelationshipMessageData; export type MultimediaMessageData = ImagesMessageData | MediaMessageData; export type RawMultimediaMessageInfo = | RawImagesMessageInfo | RawMediaMessageInfo; export const rawMultimediaMessageInfoValidator: TUnion = t.union([rawImagesMessageInfoValidator, rawMediaMessageInfoValidator]); export type RawComposableMessageInfo = | RawTextMessageInfo | RawMultimediaMessageInfo; const rawComposableMessageInfoValidator = t.union([ rawTextMessageInfoValidator, rawMultimediaMessageInfoValidator, ]); export type RawRobotextMessageInfo = | RawCreateThreadMessageInfo | RawAddMembersMessageInfo | RawCreateSubthreadMessageInfo | RawChangeSettingsMessageInfo | RawRemoveMembersMessageInfo | RawChangeRoleMessageInfo | RawLeaveThreadMessageInfo | RawJoinThreadMessageInfo | RawCreateEntryMessageInfo | RawEditEntryMessageInfo | RawDeleteEntryMessageInfo | RawRestoreEntryMessageInfo | RawLegacyUpdateRelationshipMessageInfo | RawCreateSidebarMessageInfo | RawUnsupportedMessageInfo | RawTogglePinMessageInfo | RawUpdateRelationshipMessageInfo; const rawRobotextMessageInfoValidator = t.union([ rawCreateThreadMessageInfoValidator, rawAddMembersMessageInfoValidator, rawCreateSubthreadMessageInfoValidator, rawChangeSettingsMessageInfoValidator, rawRemoveMembersMessageInfoValidator, rawChangeRoleMessageInfoValidator, rawLeaveThreadMessageInfoValidator, rawJoinThreadMessageInfoValidator, rawCreateEntryMessageInfoValidator, rawEditEntryMessageInfoValidator, rawDeleteEntryMessageInfoValidator, rawRestoreEntryMessageInfoValidator, rawLegacyUpdateRelationshipMessageInfoValidator, rawCreateSidebarMessageInfoValidator, rawUnsupportedMessageInfoValidator, rawTogglePinMessageInfoValidator, rawUpdateRelationshipMessageInfoValidator, ]); export type RawSidebarSourceMessageInfo = { ...SidebarSourceMessageData, id: string, }; export const rawSidebarSourceMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.SIDEBAR_SOURCE), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, sourceMessage: t.maybe( t.union([ rawComposableMessageInfoValidator, rawRobotextMessageInfoValidator, ]), ), id: tID, }); export type RawMessageInfo = | RawComposableMessageInfo | RawRobotextMessageInfo | RawSidebarSourceMessageInfo | RawReactionMessageInfo | RawEditMessageInfo; export const rawMessageInfoValidator: TUnion = t.union([ rawComposableMessageInfoValidator, rawRobotextMessageInfoValidator, rawSidebarSourceMessageInfoValidator, rawReactionMessageInfoValidator, rawEditMessageInfoValidator, ]); export type LocallyComposedMessageInfo = | ({ ...RawImagesMessageInfo, +localID: string, } & RawImagesMessageInfo) | ({ ...RawMediaMessageInfo, +localID: string, } & RawMediaMessageInfo) | ({ ...RawTextMessageInfo, +localID: string, } & RawTextMessageInfo) | ({ ...RawReactionMessageInfo, +localID: string, } & RawReactionMessageInfo); export type MultimediaMessageInfo = ImagesMessageInfo | MediaMessageInfo; export type ComposableMessageInfo = TextMessageInfo | MultimediaMessageInfo; export type RobotextMessageInfo = | CreateThreadMessageInfo | AddMembersMessageInfo | CreateSubthreadMessageInfo | ChangeSettingsMessageInfo | RemoveMembersMessageInfo | ChangeRoleMessageInfo | LeaveThreadMessageInfo | JoinThreadMessageInfo | CreateEntryMessageInfo | EditEntryMessageInfo | DeleteEntryMessageInfo | RestoreEntryMessageInfo | UnsupportedMessageInfo | LegacyUpdateRelationshipMessageInfo | CreateSidebarMessageInfo | TogglePinMessageInfo | UpdateRelationshipMessageInfo; export type PreviewableMessageInfo = | RobotextMessageInfo | MultimediaMessageInfo | ReactionMessageInfo; export type ValidSidebarSourceMessageInfo = | TextMessageInfo | CreateThreadMessageInfo | AddMembersMessageInfo | CreateSubthreadMessageInfo | ChangeSettingsMessageInfo | RemoveMembersMessageInfo | ChangeRoleMessageInfo | LeaveThreadMessageInfo | JoinThreadMessageInfo | CreateEntryMessageInfo | EditEntryMessageInfo | DeleteEntryMessageInfo | RestoreEntryMessageInfo | ImagesMessageInfo | MediaMessageInfo | LegacyUpdateRelationshipMessageInfo | CreateSidebarMessageInfo | UnsupportedMessageInfo | UpdateRelationshipMessageInfo; export type SidebarSourceMessageInfo = { +type: 17, +id: string, +threadID: string, +creator: RelativeUserInfo, +time: number, +sourceMessage: ValidSidebarSourceMessageInfo, }; export type MessageInfo = | ComposableMessageInfo | RobotextMessageInfo | SidebarSourceMessageInfo | ReactionMessageInfo | EditMessageInfo; export type ThreadMessageInfo = { messageIDs: string[], startReached: boolean, }; const threadMessageInfoValidator: TInterface = tShape({ messageIDs: t.list(tID), startReached: t.Boolean, }); // Tracks client-local information about a message that hasn't been assigned an // ID by the server yet. As soon as the client gets an ack from the server for // this message, it will clear the LocalMessageInfo. export type LocalMessageInfo = { +sendFailed?: boolean, }; const localMessageInfoValidator: TInterface = tShape({ sendFailed: t.maybe(t.Boolean), }); export type MessageStoreThreads = { +[threadID: string]: ThreadMessageInfo, }; const messageStoreThreadsValidator: TDict = t.dict( tID, threadMessageInfoValidator, ); export type MessageStore = { +messages: { +[id: string]: RawMessageInfo }, +threads: MessageStoreThreads, +local: { +[id: string]: LocalMessageInfo }, +currentAsOf: { +[keyserverID: string]: number }, }; export const messageStoreValidator: TInterface = tShape({ messages: t.dict(tID, rawMessageInfoValidator), threads: messageStoreThreadsValidator, local: t.dict(t.String, localMessageInfoValidator), currentAsOf: t.dict(t.String, t.Number), }); // We were initially using `number`s` for `thread`, `type`, `future_type`, etc. // However, we ended up changing `thread` to `string` to account for thread IDs // including information about the keyserver (eg 'GENESIS|123') in the future. // // At that point we discussed whether we should switch the remaining `number` // fields to `string`s for consistency and flexibility. We researched whether // there was any performance cost to using `string`s instead of `number`s and // found the differences to be negligible. We also concluded using `string`s // may be safer after considering `jsi::Number` and the various C++ number // representations on the CommCoreModule side. export type ClientDBMessageInfo = { +id: string, +local_id: ?string, +thread: string, +user: string, +type: string, +future_type: ?string, +content: ?string, +time: string, +media_infos: ?$ReadOnlyArray, }; export type ClientDBThreadMessageInfo = { +id: string, +start_reached: string, }; export const messageTruncationStatus = Object.freeze({ // EXHAUSTIVE means we've reached the start of the thread. Either the result // set includes the very first message for that thread, or there is nothing // behind the cursor you queried for. Given that the client only ever issues // ranged queries whose range, when unioned with what is in state, represent // the set of all messages for a given thread, we can guarantee that getting // EXHAUSTIVE means the start has been reached. EXHAUSTIVE: 'exhaustive', // TRUNCATED is rare, and means that the server can't guarantee that the // result set for a given thread is contiguous with what the client has in its // state. If the client can't verify the contiguousness itself, it needs to // replace its Redux store's contents with what it is in this payload. // 1) getMessageInfosSince: Result set for thread is equal to max, and the // truncation status isn't EXHAUSTIVE (ie. doesn't include the very first // message). // 2) getMessageInfos: MessageSelectionCriteria does not specify cursors, the // result set for thread is equal to max, and the truncation status isn't // EXHAUSTIVE. If cursors are specified, we never return truncated, since // the cursor given us guarantees the contiguousness of the result set. // Note that in the reducer, we can guarantee contiguousness if there is any // intersection between messageIDs in the result set and the set currently in // the Redux store. TRUNCATED: 'truncated', // UNCHANGED means the result set is guaranteed to be contiguous with what the // client has in its state, but is not EXHAUSTIVE. Basically, it's anything // that isn't either EXHAUSTIVE or TRUNCATED. UNCHANGED: 'unchanged', }); export type MessageTruncationStatus = $Values; export function assertMessageTruncationStatus( ourMessageTruncationStatus: string, ): MessageTruncationStatus { invariant( ourMessageTruncationStatus === 'truncated' || ourMessageTruncationStatus === 'unchanged' || ourMessageTruncationStatus === 'exhaustive', 'string is not ourMessageTruncationStatus enum', ); return ourMessageTruncationStatus; } export const messageTruncationStatusValidator: TEnums = t.enums.of( values(messageTruncationStatus), ); export type MessageTruncationStatuses = { [threadID: string]: MessageTruncationStatus, }; export const messageTruncationStatusesValidator: TDict = t.dict(tID, messageTruncationStatusValidator); export type ThreadCursors = { +[threadID: string]: ?string }; export type MessageSelectionCriteria = { +threadCursors?: ?ThreadCursors, +joinedThreads?: ?boolean, +newerThan?: ?number, }; export type FetchMessageInfosRequest = { +cursors: ThreadCursors, +numberPerThread?: ?number, }; export type FetchMessageInfosResponse = { +rawMessageInfos: $ReadOnlyArray, +truncationStatuses: MessageTruncationStatuses, +userInfos: UserInfos, }; export type FetchMessageInfosResult = { +rawMessageInfos: $ReadOnlyArray, +truncationStatuses: MessageTruncationStatuses, }; export type FetchMessageInfosPayload = { +threadID: string, +rawMessageInfos: $ReadOnlyArray, +truncationStatus: MessageTruncationStatus, }; export type MessagesResponse = { +rawMessageInfos: $ReadOnlyArray, +truncationStatuses: MessageTruncationStatuses, +currentAsOf: number, }; export const messagesResponseValidator: TInterface = tShape({ rawMessageInfos: t.list(rawMessageInfoValidator), truncationStatuses: messageTruncationStatusesValidator, currentAsOf: t.Number, }); export type SimpleMessagesPayload = { +rawMessageInfos: $ReadOnlyArray, +truncationStatuses: MessageTruncationStatuses, }; export const defaultNumberPerThread = 20; export const defaultMaxMessageAge = 14 * 24 * 60 * 60 * 1000; // 2 weeks export type SendMessageResponse = { +newMessageInfo: RawMessageInfo, }; export type SendMessageResult = { +id: string, +time: number, +interface: CallSingleKeyserverEndpointResultInfoInterface, }; export type SendMessagePayload = { +localID: string, +serverID: string, +threadID: string, +time: number, +interface: CallSingleKeyserverEndpointResultInfoInterface, }; export type SendTextMessageRequest = { +threadID: string, +localID?: string, +text: string, +sidebarCreation?: boolean, }; export type SendMultimediaMessageRequest = // This option is only used for messageTypes.IMAGES | { +threadID: string, +localID: string, +sidebarCreation?: boolean, +mediaIDs: $ReadOnlyArray, } | { +threadID: string, +localID: string, +sidebarCreation?: boolean, +mediaMessageContents: $ReadOnlyArray, }; export type SendReactionMessageRequest = { +threadID: string, +localID?: string, +targetMessageID: string, +reaction: string, +action: 'add_reaction' | 'remove_reaction', }; export type SendEditMessageRequest = { +targetMessageID: string, +text: string, }; export type SendEditMessageResponse = { +newMessageInfos: $ReadOnlyArray, }; export type EditMessagePayload = SendEditMessageResponse; export type SendEditMessageResult = SendEditMessageResponse; export type EditMessageContent = { +text: string, }; // Used for the message info included in log-in type actions export type GenericMessagesResult = { +messageInfos: RawMessageInfo[], +truncationStatus: MessageTruncationStatuses, +watchedIDsAtRequestTime: $ReadOnlyArray, +currentAsOf: { +[keyserverID: string]: number }, }; export type SaveMessagesPayload = { +rawMessageInfos: $ReadOnlyArray, +updatesCurrentAsOf: number, }; export type NewMessagesPayload = { +messagesResult: MessagesResponse, }; export const newMessagesPayloadValidator: TInterface = tShape({ messagesResult: messagesResponseValidator, }); export type MessageStorePrunePayload = { +threadIDs: $ReadOnlyArray, }; export type FetchPinnedMessagesRequest = { +threadID: string, }; export type FetchPinnedMessagesResult = { +pinnedMessages: $ReadOnlyArray, }; export type SearchMessagesRequest = { +query: string, +threadID: string, +cursor?: ?string, }; export type SearchMessagesResponse = { +messages: $ReadOnlyArray, +endReached: boolean, }; diff --git a/lib/types/messages/add-members.js b/lib/types/messages/add-members.js index ab2e1d6f8..d35c5a629 100644 --- a/lib/types/messages/add-members.js +++ b/lib/types/messages/add-members.js @@ -1,39 +1,39 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tShape, tID, tNumber } from '../../utils/validation-utils.js'; +import { tShape, tID, tNumber, tUserID } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; export type AddMembersMessageData = { type: 2, threadID: string, creatorID: string, time: number, addedUserIDs: string[], }; export type RawAddMembersMessageInfo = { ...AddMembersMessageData, id: string, }; export const rawAddMembersMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.ADD_MEMBERS), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, - addedUserIDs: t.list(t.String), + addedUserIDs: t.list(tUserID), id: tID, }); export type AddMembersMessageInfo = { type: 2, id: string, threadID: string, creator: RelativeUserInfo, time: number, addedMembers: RelativeUserInfo[], }; diff --git a/lib/types/messages/change-role.js b/lib/types/messages/change-role.js index 13972b4fa..f03522638 100644 --- a/lib/types/messages/change-role.js +++ b/lib/types/messages/change-role.js @@ -1,45 +1,45 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tID, tNumber, tShape } from '../../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; export type ChangeRoleMessageData = { +type: 6, +threadID: string, +creatorID: string, +time: number, +userIDs: string[], +newRole: string, +roleName?: string, // Older clients will not have this field }; export type RawChangeRoleMessageInfo = $ReadOnly<{ ...ChangeRoleMessageData, +id: string, }>; export const rawChangeRoleMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.CHANGE_ROLE), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, - userIDs: t.list(t.String), + userIDs: t.list(tUserID), newRole: tID, id: tID, roleName: t.maybe(t.String), }); export type ChangeRoleMessageInfo = { +type: 6, +id: string, +threadID: string, +creator: RelativeUserInfo, +time: number, +members: RelativeUserInfo[], +newRole: string, +roleName?: string, // Older clients will not have this field }; diff --git a/lib/types/messages/change-settings.js b/lib/types/messages/change-settings.js index 03bd1e954..88db129a1 100644 --- a/lib/types/messages/change-settings.js +++ b/lib/types/messages/change-settings.js @@ -1,42 +1,42 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tID, tNumber, tShape } from '../../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; export type ChangeSettingsMessageData = { type: 4, threadID: string, creatorID: string, time: number, field: string, value: string | number, }; export type RawChangeSettingsMessageInfo = { ...ChangeSettingsMessageData, id: string, }; export const rawChangeSettingsMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.CHANGE_SETTINGS), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, field: t.String, value: t.union([t.String, t.Number]), id: tID, }); export type ChangeSettingsMessageInfo = { type: 4, id: string, threadID: string, creator: RelativeUserInfo, time: number, field: string, value: string | number, }; diff --git a/lib/types/messages/create-entry.js b/lib/types/messages/create-entry.js index fc0d42319..e12511b85 100644 --- a/lib/types/messages/create-entry.js +++ b/lib/types/messages/create-entry.js @@ -1,45 +1,45 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tID, tNumber, tShape } from '../../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; export type CreateEntryMessageData = { type: 9, threadID: string, creatorID: string, time: number, entryID: string, date: string, text: string, }; export type RawCreateEntryMessageInfo = { ...CreateEntryMessageData, id: string, }; export const rawCreateEntryMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.CREATE_ENTRY), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, entryID: tID, date: t.String, text: t.String, id: tID, }); export type CreateEntryMessageInfo = { type: 9, id: string, threadID: string, creator: RelativeUserInfo, time: number, entryID: string, date: string, text: string, }; diff --git a/lib/types/messages/create-sidebar.js b/lib/types/messages/create-sidebar.js index bdd70111e..05e3545e5 100644 --- a/lib/types/messages/create-sidebar.js +++ b/lib/types/messages/create-sidebar.js @@ -1,58 +1,58 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tID, tNumber, tShape } from '../../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { ThreadInfo } from '../minimally-encoded-thread-permissions-types.js'; import type { RelativeUserInfo } from '../user-types.js'; export type CreateSidebarMessageData = { +type: 18, +threadID: string, +creatorID: string, +time: number, +sourceMessageAuthorID: string, +initialThreadState: { +name: ?string, +parentThreadID: string, +color: string, +memberIDs: string[], }, }; export type RawCreateSidebarMessageInfo = { ...CreateSidebarMessageData, id: string, }; export const rawCreateSidebarMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.CREATE_SIDEBAR), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, - sourceMessageAuthorID: t.String, + sourceMessageAuthorID: tUserID, initialThreadState: tShape({ name: t.maybe(t.String), parentThreadID: tID, color: t.String, - memberIDs: t.list(t.String), + memberIDs: t.list(tUserID), }), id: tID, }); export type CreateSidebarMessageInfo = { +type: 18, +id: string, +threadID: string, +creator: RelativeUserInfo, +time: number, +sourceMessageAuthor: RelativeUserInfo, +initialThreadState: { +name: ?string, +parentThreadInfo: ThreadInfo, +color: string, +otherMembers: RelativeUserInfo[], }, }; diff --git a/lib/types/messages/create-subthread.js b/lib/types/messages/create-subthread.js index 07ebf2a61..1338761fa 100644 --- a/lib/types/messages/create-subthread.js +++ b/lib/types/messages/create-subthread.js @@ -1,40 +1,40 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tID, tNumber, tShape } from '../../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { ThreadInfo } from '../minimally-encoded-thread-permissions-types.js'; import type { RelativeUserInfo } from '../user-types.js'; export type CreateSubthreadMessageData = { type: 3, threadID: string, creatorID: string, time: number, childThreadID: string, }; export type RawCreateSubthreadMessageInfo = { ...CreateSubthreadMessageData, id: string, }; export const rawCreateSubthreadMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.CREATE_SUB_THREAD), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, childThreadID: tID, id: tID, }); export type CreateSubthreadMessageInfo = { type: 3, id: string, threadID: string, creator: RelativeUserInfo, time: number, childThreadInfo: ThreadInfo, }; diff --git a/lib/types/messages/create-thread.js b/lib/types/messages/create-thread.js index 8e1d7f1d0..1d2907c9a 100644 --- a/lib/types/messages/create-thread.js +++ b/lib/types/messages/create-thread.js @@ -1,65 +1,66 @@ // @flow import t, { type TInterface } from 'tcomb'; import { values } from '../../utils/objects.js'; import { tID, tNumber, tNumEnum, tShape, + tUserID, } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { ThreadInfo } from '../minimally-encoded-thread-permissions-types.js'; import { type ThreadType, threadTypes } from '../thread-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; export type CreateThreadMessageData = { type: 1, threadID: string, creatorID: string, time: number, initialThreadState: { type: ThreadType, name: ?string, parentThreadID: ?string, color: string, memberIDs: string[], }, }; export type RawCreateThreadMessageInfo = { ...CreateThreadMessageData, id: string, }; export const rawCreateThreadMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.CREATE_THREAD), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, initialThreadState: tShape({ type: tNumEnum(values(threadTypes)), name: t.maybe(t.String), parentThreadID: t.maybe(tID), color: t.String, - memberIDs: t.list(t.String), + memberIDs: t.list(tUserID), }), id: tID, }); export type CreateThreadMessageInfo = { type: 1, id: string, threadID: string, creator: RelativeUserInfo, time: number, initialThreadState: { type: ThreadType, name: ?string, parentThreadInfo: ?ThreadInfo, color: string, otherMembers: RelativeUserInfo[], }, }; diff --git a/lib/types/messages/delete-entry.js b/lib/types/messages/delete-entry.js index c4664a2e7..d6e4f2fbf 100644 --- a/lib/types/messages/delete-entry.js +++ b/lib/types/messages/delete-entry.js @@ -1,45 +1,45 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tID, tNumber, tShape } from '../../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; export type DeleteEntryMessageData = { type: 11, threadID: string, creatorID: string, time: number, entryID: string, date: string, text: string, }; export type RawDeleteEntryMessageInfo = { ...DeleteEntryMessageData, id: string, }; export const rawDeleteEntryMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.DELETE_ENTRY), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, entryID: tID, date: t.String, text: t.String, id: tID, }); export type DeleteEntryMessageInfo = { type: 11, id: string, threadID: string, creator: RelativeUserInfo, time: number, entryID: string, date: string, text: string, }; diff --git a/lib/types/messages/edit-entry.js b/lib/types/messages/edit-entry.js index 889b2b19e..6b3974f53 100644 --- a/lib/types/messages/edit-entry.js +++ b/lib/types/messages/edit-entry.js @@ -1,45 +1,45 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tID, tNumber, tShape } from '../../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; export type EditEntryMessageData = { type: 10, threadID: string, creatorID: string, time: number, entryID: string, date: string, text: string, }; export type RawEditEntryMessageInfo = { ...EditEntryMessageData, id: string, }; export const rawEditEntryMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.EDIT_ENTRY), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, entryID: tID, date: t.String, text: t.String, id: tID, }); export type EditEntryMessageInfo = { type: 10, id: string, threadID: string, creator: RelativeUserInfo, time: number, entryID: string, date: string, text: string, }; diff --git a/lib/types/messages/edit.js b/lib/types/messages/edit.js index 5f21565bb..e3089eeea 100644 --- a/lib/types/messages/edit.js +++ b/lib/types/messages/edit.js @@ -1,42 +1,42 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tID, tNumber, tShape } from '../../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; export type EditMessageData = { +type: 20, +threadID: string, +creatorID: string, +time: number, +targetMessageID: string, +text: string, }; export type RawEditMessageInfo = $ReadOnly<{ ...EditMessageData, +id: string, }>; export const rawEditMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.EDIT_MESSAGE), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, targetMessageID: tID, text: t.String, id: tID, }); export type EditMessageInfo = { +type: 20, +id: string, +threadID: string, +creator: RelativeUserInfo, +time: number, // millisecond timestamp +targetMessageID: string, +text: string, }; diff --git a/lib/types/messages/images.js b/lib/types/messages/images.js index 9492084cf..902037421 100644 --- a/lib/types/messages/images.js +++ b/lib/types/messages/images.js @@ -1,48 +1,48 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tID, tNumber, tShape } from '../../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../../utils/validation-utils.js'; import { imageValidator, type Image } from '../media-types.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; type ImagesSharedBase = { +type: 14, +localID?: string, // for optimistic creations. included by new clients +threadID: string, +creatorID: string, +time: number, +media: $ReadOnlyArray, }; export type ImagesMessageData = { ...ImagesSharedBase, +sidebarCreation?: boolean, }; export type RawImagesMessageInfo = { ...ImagesSharedBase, +id?: string, // null if local copy without ID yet }; export const rawImagesMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.IMAGES), localID: t.maybe(t.String), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, media: t.list(imageValidator), id: t.maybe(tID), }); export type ImagesMessageInfo = { +type: 14, +id?: string, // null if local copy without ID yet +localID?: string, // for optimistic creations +threadID: string, +creator: RelativeUserInfo, +time: number, // millisecond timestamp +media: $ReadOnlyArray, }; diff --git a/lib/types/messages/join-thread.js b/lib/types/messages/join-thread.js index 6ab83153a..073ddee41 100644 --- a/lib/types/messages/join-thread.js +++ b/lib/types/messages/join-thread.js @@ -1,36 +1,36 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tID, tNumber, tShape } from '../../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; export type JoinThreadMessageData = { type: 8, threadID: string, creatorID: string, time: number, }; export type RawJoinThreadMessageInfo = { ...JoinThreadMessageData, id: string, }; export const rawJoinThreadMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.JOIN_THREAD), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, id: tID, }); export type JoinThreadMessageInfo = { type: 8, id: string, threadID: string, creator: RelativeUserInfo, time: number, }; diff --git a/lib/types/messages/leave-thread.js b/lib/types/messages/leave-thread.js index 7e4145cfc..72df490ed 100644 --- a/lib/types/messages/leave-thread.js +++ b/lib/types/messages/leave-thread.js @@ -1,36 +1,36 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tID, tNumber, tShape } from '../../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; export type LeaveThreadMessageData = { type: 7, threadID: string, creatorID: string, time: number, }; export type RawLeaveThreadMessageInfo = { ...LeaveThreadMessageData, id: string, }; export const rawLeaveThreadMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.LEAVE_THREAD), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, id: tID, }); export type LeaveThreadMessageInfo = { type: 7, id: string, threadID: string, creator: RelativeUserInfo, time: number, }; diff --git a/lib/types/messages/legacy-update-relationship.js b/lib/types/messages/legacy-update-relationship.js index 22c0e2ad7..71cdb9915 100644 --- a/lib/types/messages/legacy-update-relationship.js +++ b/lib/types/messages/legacy-update-relationship.js @@ -1,42 +1,42 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tID, tNumber, tShape } from '../../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; export type LegacyUpdateRelationshipMessageData = { +type: 16, +threadID: string, +creatorID: string, +targetID: string, +time: number, +operation: 'request_sent' | 'request_accepted', }; export type RawLegacyUpdateRelationshipMessageInfo = { ...LegacyUpdateRelationshipMessageData, id: string, }; export const rawLegacyUpdateRelationshipMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.LEGACY_UPDATE_RELATIONSHIP), threadID: tID, - creatorID: t.String, - targetID: t.String, + creatorID: tUserID, + targetID: tUserID, time: t.Number, operation: t.enums.of(['request_sent', 'request_accepted']), id: tID, }); export type LegacyUpdateRelationshipMessageInfo = { +type: 16, +id: string, +threadID: string, +creator: RelativeUserInfo, +target: RelativeUserInfo, +time: number, +operation: 'request_sent' | 'request_accepted', }; diff --git a/lib/types/messages/media.js b/lib/types/messages/media.js index 6df679c23..9e44bc11c 100644 --- a/lib/types/messages/media.js +++ b/lib/types/messages/media.js @@ -1,96 +1,96 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tShape, tNumber, tID } from '../../utils/validation-utils.js'; +import { tShape, tNumber, tID, tUserID } from '../../utils/validation-utils.js'; import { type Media, mediaValidator } from '../media-types.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; type MediaSharedBase = { +type: 15, +localID?: string, // for optimistic creations. included by new clients +threadID: string, +creatorID: string, +time: number, +media: $ReadOnlyArray, }; export type MediaMessageData = $ReadOnly<{ ...MediaSharedBase, +sidebarCreation?: boolean, }>; export type RawMediaMessageInfo = $ReadOnly<{ ...MediaSharedBase, +id?: string, // null if local copy without ID yet }>; export const rawMediaMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.MULTIMEDIA), localID: t.maybe(t.String), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, media: t.list(mediaValidator), id: t.maybe(tID), }); export type MediaMessageInfo = { +type: 15, +id?: string, // null if local copy without ID yet +localID?: string, // for optimistic creations +threadID: string, +creator: RelativeUserInfo, +time: number, // millisecond timestamp +media: $ReadOnlyArray, }; export type PhotoMessageServerDBContent = { +type: 'photo', +uploadID: string, }; export type VideoMessageServerDBContent = { +type: 'video', +uploadID: string, +thumbnailUploadID: string, }; export type MediaMessageServerDBContent = | PhotoMessageServerDBContent | VideoMessageServerDBContent; function getUploadIDsFromMediaMessageServerDBContents( mediaMessageContents: $ReadOnlyArray, ): $ReadOnlyArray { const uploadIDs: string[] = []; for (const mediaContent of mediaMessageContents) { uploadIDs.push(mediaContent.uploadID); if (mediaContent.type === 'video') { uploadIDs.push(mediaContent.thumbnailUploadID); } } return uploadIDs; } function getMediaMessageServerDBContentsFromMedia( media: $ReadOnlyArray, ): $ReadOnlyArray { return media.map(m => { if (m.type === 'photo' || m.type === 'encrypted_photo') { return { type: 'photo', uploadID: m.id }; } else if (m.type === 'video' || m.type === 'encrypted_video') { return { type: 'video', uploadID: m.id, thumbnailUploadID: m.thumbnailID, }; } throw new Error(`Unexpected media type: ${m.type}`); }); } export { getUploadIDsFromMediaMessageServerDBContents, getMediaMessageServerDBContentsFromMedia, }; diff --git a/lib/types/messages/reaction.js b/lib/types/messages/reaction.js index 7950f0528..bd104e089 100644 --- a/lib/types/messages/reaction.js +++ b/lib/types/messages/reaction.js @@ -1,48 +1,48 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tID, tNumber, tShape } from '../../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; export type ReactionMessageData = { +type: 19, +localID?: string, // for optimistic creations. included by new clients +threadID: string, +creatorID: string, +time: number, +targetMessageID: string, +reaction: string, +action: 'add_reaction' | 'remove_reaction', }; export type RawReactionMessageInfo = $ReadOnly<{ ...ReactionMessageData, +id?: string, // null if local copy without ID yet }>; export const rawReactionMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.REACTION), localID: t.maybe(t.String), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, targetMessageID: tID, reaction: t.String, action: t.enums.of(['add_reaction', 'remove_reaction']), id: t.maybe(tID), }); export type ReactionMessageInfo = { +type: 19, +id?: string, // null if local copy without ID yet +localID?: string, // for optimistic creations +threadID: string, +creator: RelativeUserInfo, +time: number, +targetMessageID: string, +reaction: string, +action: 'add_reaction' | 'remove_reaction', }; diff --git a/lib/types/messages/remove-members.js b/lib/types/messages/remove-members.js index c87962cf3..050e2132d 100644 --- a/lib/types/messages/remove-members.js +++ b/lib/types/messages/remove-members.js @@ -1,39 +1,39 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tID, tNumber, tShape } from '../../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; export type RemoveMembersMessageData = { type: 5, threadID: string, creatorID: string, time: number, removedUserIDs: string[], }; export type RawRemoveMembersMessageInfo = { ...RemoveMembersMessageData, id: string, }; export const rawRemoveMembersMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.REMOVE_MEMBERS), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, - removedUserIDs: t.list(t.String), + removedUserIDs: t.list(tUserID), id: tID, }); export type RemoveMembersMessageInfo = { type: 5, id: string, threadID: string, creator: RelativeUserInfo, time: number, removedMembers: RelativeUserInfo[], }; diff --git a/lib/types/messages/restore-entry.js b/lib/types/messages/restore-entry.js index b4479a941..d1125ad4b 100644 --- a/lib/types/messages/restore-entry.js +++ b/lib/types/messages/restore-entry.js @@ -1,45 +1,45 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tID, tNumber, tShape } from '../../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; export type RestoreEntryMessageData = { type: 12, threadID: string, creatorID: string, time: number, entryID: string, date: string, text: string, }; export type RawRestoreEntryMessageInfo = { ...RestoreEntryMessageData, id: string, }; export const rawRestoreEntryMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.RESTORE_ENTRY), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, entryID: tID, date: t.String, text: t.String, id: tID, }); export type RestoreEntryMessageInfo = { type: 12, id: string, threadID: string, creator: RelativeUserInfo, time: number, entryID: string, date: string, text: string, }; diff --git a/lib/types/messages/text.js b/lib/types/messages/text.js index 43ddc6574..73e829eb3 100644 --- a/lib/types/messages/text.js +++ b/lib/types/messages/text.js @@ -1,47 +1,47 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tID, tNumber, tShape } from '../../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; type TextSharedBase = { +type: 0, +localID?: string, // for optimistic creations. included by new clients +threadID: string, +creatorID: string, +time: number, +text: string, }; export type TextMessageData = { ...TextSharedBase, +sidebarCreation?: boolean, }; export type RawTextMessageInfo = { ...TextSharedBase, +id?: string, // null if local copy without ID yet }; export const rawTextMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.TEXT), localID: t.maybe(t.String), threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, text: t.String, id: t.maybe(tID), }); export type TextMessageInfo = { +type: 0, +id?: string, // null if local copy without ID yet +localID?: string, // for optimistic creations +threadID: string, +creator: RelativeUserInfo, +time: number, // millisecond timestamp +text: string, }; diff --git a/lib/types/messages/toggle-pin.js b/lib/types/messages/toggle-pin.js index 100c2118b..af48a4615 100644 --- a/lib/types/messages/toggle-pin.js +++ b/lib/types/messages/toggle-pin.js @@ -1,45 +1,45 @@ // @flow import t, { type TInterface } from 'tcomb'; -import { tID, tNumber, tShape } from '../../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; export type TogglePinMessageData = { +type: 21, +threadID: string, +targetMessageID: string, +action: 'pin' | 'unpin', +pinnedContent: string, +creatorID: string, +time: number, }; export type RawTogglePinMessageInfo = $ReadOnly<{ ...TogglePinMessageData, +id: string, }>; export const rawTogglePinMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.TOGGLE_PIN), threadID: tID, targetMessageID: tID, action: t.enums.of(['pin', 'unpin']), pinnedContent: t.String, - creatorID: t.String, + creatorID: tUserID, time: t.Number, id: tID, }); export type TogglePinMessageInfo = { +type: 21, +id: string, +threadID: string, +targetMessageID: string, +action: 'pin' | 'unpin', +pinnedContent: string, +creator: RelativeUserInfo, +time: number, }; diff --git a/lib/types/messages/unsupported.js b/lib/types/messages/unsupported.js index 86069acf0..3997ada4e 100644 --- a/lib/types/messages/unsupported.js +++ b/lib/types/messages/unsupported.js @@ -1,87 +1,87 @@ // @flow import t, { type TInterface } from 'tcomb'; import { rawChangeRoleMessageInfoValidator, type RawChangeRoleMessageInfo, } from './change-role.js'; import { rawEditMessageInfoValidator, type RawEditMessageInfo, } from './edit.js'; import { rawMediaMessageInfoValidator, type RawMediaMessageInfo, } from './media.js'; import { rawReactionMessageInfoValidator, type RawReactionMessageInfo, } from './reaction.js'; import { rawTogglePinMessageInfoValidator, type RawTogglePinMessageInfo, } from './toggle-pin.js'; import { rawUpdateFarcasterRelationshipMessageInfoValidator, type RawUpdateFarcasterRelationshipMessageInfo, } from './update-relationship.js'; -import { tID, tNumber, tShape } from '../../utils/validation-utils.js'; +import { tID, tNumber, tShape, tUserID } from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; export type RawUnsupportedMessageInfo = { type: 13, id: string, threadID: string, creatorID: string, time: number, robotext: string, dontPrefixCreator?: boolean, unsupportedMessageInfo: | RawUpdateFarcasterRelationshipMessageInfo | RawChangeRoleMessageInfo | RawEditMessageInfo | RawMediaMessageInfo | RawReactionMessageInfo | RawTogglePinMessageInfo, }; export const rawUnsupportedMessageInfoValidator: TInterface = tShape({ type: tNumber(messageTypes.UNSUPPORTED), id: tID, threadID: tID, - creatorID: t.String, + creatorID: tUserID, time: t.Number, robotext: t.String, dontPrefixCreator: t.maybe(t.Boolean), unsupportedMessageInfo: t.union([ // We include these validators here to make sure that the keyserver does // ID conversion on unsupportedMessageInfo when it's one of these types rawUpdateFarcasterRelationshipMessageInfoValidator, rawChangeRoleMessageInfoValidator, rawEditMessageInfoValidator, rawMediaMessageInfoValidator, rawReactionMessageInfoValidator, rawTogglePinMessageInfoValidator, t.Object, ]), }); export type UnsupportedMessageInfo = { type: 13, id: string, threadID: string, creator: RelativeUserInfo, time: number, robotext: string, dontPrefixCreator?: boolean, unsupportedMessageInfo: | RawUpdateFarcasterRelationshipMessageInfo | RawChangeRoleMessageInfo | RawEditMessageInfo | RawMediaMessageInfo | RawReactionMessageInfo | RawTogglePinMessageInfo, }; diff --git a/lib/types/messages/update-relationship.js b/lib/types/messages/update-relationship.js index c48d1efd3..a75b69353 100644 --- a/lib/types/messages/update-relationship.js +++ b/lib/types/messages/update-relationship.js @@ -1,107 +1,113 @@ // @flow import t, { type TInterface, type TUnion } from 'tcomb'; -import { tID, tNumber, tShape, tString } from '../../utils/validation-utils.js'; +import { + tID, + tNumber, + tShape, + tString, + tUserID, +} from '../../utils/validation-utils.js'; import { messageTypes } from '../message-types-enum.js'; import type { RelativeUserInfo } from '../user-types.js'; export type TraditionalRelationshipOperation = | 'request_sent' | 'request_accepted'; export type FarcasterRelationshipOperation = 'farcaster_mutual'; export type UpdateTraditionalRelationshipMessageData = { +type: 22, +threadID: string, +creatorID: string, +targetID: string, +time: number, +operation: TraditionalRelationshipOperation, }; export type UpdateFarcasterRelationshipMessageData = { +type: 22, +threadID: string, +creatorID: string, +creatorFID: string, +targetID: string, +targetFID: string, +time: number, +operation: FarcasterRelationshipOperation, }; export type UpdateRelationshipMessageData = | UpdateTraditionalRelationshipMessageData | UpdateFarcasterRelationshipMessageData; export type RawUpdateTraditionalRelationshipMessageInfo = $ReadOnly<{ ...UpdateTraditionalRelationshipMessageData, +id: string, }>; export type RawUpdateFarcasterRelationshipMessageInfo = $ReadOnly<{ ...UpdateFarcasterRelationshipMessageData, +id: string, }>; export type RawUpdateRelationshipMessageInfo = | RawUpdateTraditionalRelationshipMessageInfo | RawUpdateFarcasterRelationshipMessageInfo; export const rawUpdateTraditionalRelationshipMessageInfoValidator: TInterface = tShape({ id: tID, type: tNumber(messageTypes.UPDATE_RELATIONSHIP), threadID: tID, - creatorID: t.String, - targetID: t.String, + creatorID: tUserID, + targetID: tUserID, time: t.Number, operation: t.enums.of(['request_sent', 'request_accepted']), }); export const rawUpdateFarcasterRelationshipMessageInfoValidator: TInterface = tShape({ id: tID, type: tNumber(messageTypes.UPDATE_RELATIONSHIP), threadID: tID, - creatorID: t.String, + creatorID: tUserID, creatorFID: t.String, - targetID: t.String, + targetID: tUserID, targetFID: t.String, time: t.Number, operation: tString('farcaster_mutual'), }); export const rawUpdateRelationshipMessageInfoValidator: TUnion = t.union([ rawUpdateTraditionalRelationshipMessageInfoValidator, rawUpdateFarcasterRelationshipMessageInfoValidator, ]); export type UpdateTraditionalRelationshipMessageInfo = { +type: 22, +id: string, +threadID: string, +creator: RelativeUserInfo, +target: RelativeUserInfo, +time: number, +operation: TraditionalRelationshipOperation, }; export type UpdateFarcasterRelationshipMessageInfo = { +type: 22, +id: string, +threadID: string, +creator: RelativeUserInfo, +creatorFID: string, +target: RelativeUserInfo, +targetFID: string, +time: number, +operation: FarcasterRelationshipOperation, }; export type UpdateRelationshipMessageInfo = | UpdateTraditionalRelationshipMessageInfo | UpdateFarcasterRelationshipMessageInfo;