Michcio
dc510c6834
Some checks failed
These imports were breaking in TS error checking and VS Code, because imports need to have an extension to be valid, apparently
261 lines
7.4 KiB
TypeScript
261 lines
7.4 KiB
TypeScript
import { EventEmitter } from 'events';
|
|
import Emitter from 'strict-event-emitter-types';
|
|
import { Channel } from '@/models/entities/channel.js';
|
|
import { User } from '@/models/entities/user.js';
|
|
import { UserProfile } from '@/models/entities/user-profile.js';
|
|
import { Note } from '@/models/entities/note.js';
|
|
import { Antenna } from '@/models/entities/antenna.js';
|
|
import { DriveFile } from '@/models/entities/drive-file.js';
|
|
import { DriveFolder } from '@/models/entities/drive-folder.js';
|
|
import { UserList } from '@/models/entities/user-list.js';
|
|
import { MessagingMessage } from '@/models/entities/messaging-message.js';
|
|
import { UserGroup } from '@/models/entities/user-group.js';
|
|
import { AbuseUserReport } from '@/models/entities/abuse-user-report.js';
|
|
import { Signin } from '@/models/entities/signin.js';
|
|
import { Page } from '@/models/entities/page.js';
|
|
import { Packed } from '@/misc/schema.js';
|
|
import { Webhook } from '@/models/entities/webhook.js';
|
|
|
|
//#region Stream type-body definitions
|
|
export interface InternalStreamTypes {
|
|
userChangeSuspendedState: { id: User['id']; isSuspended: User['isSuspended']; };
|
|
userChangeSilencedState: { id: User['id']; isSilenced: User['isSilenced']; };
|
|
userChangeModeratorState: { id: User['id']; isModerator: User['isModerator']; };
|
|
userTokenRegenerated: { id: User['id']; oldToken: User['token']; newToken: User['token']; };
|
|
remoteUserUpdated: { id: User['id']; };
|
|
webhookCreated: Webhook;
|
|
webhookDeleted: Webhook;
|
|
webhookUpdated: Webhook;
|
|
antennaCreated: Antenna;
|
|
antennaDeleted: Antenna;
|
|
antennaUpdated: Antenna;
|
|
}
|
|
|
|
export interface BroadcastTypes {
|
|
emojiAdded: {
|
|
emoji: Packed<'Emoji'>;
|
|
};
|
|
}
|
|
|
|
export interface UserStreamTypes {
|
|
terminate: Record<string, unknown>;
|
|
followChannel: Channel;
|
|
unfollowChannel: Channel;
|
|
updateUserProfile: UserProfile;
|
|
mute: User;
|
|
unmute: User;
|
|
follow: Packed<'UserDetailedNotMe'>;
|
|
unfollow: Packed<'User'>;
|
|
userAdded: Packed<'User'>;
|
|
}
|
|
|
|
export interface MainStreamTypes {
|
|
notification: Packed<'Notification'>;
|
|
mention: Packed<'Note'>;
|
|
reply: Packed<'Note'>;
|
|
renote: Packed<'Note'>;
|
|
follow: Packed<'UserDetailedNotMe'>;
|
|
followed: Packed<'User'>;
|
|
unfollow: Packed<'User'>;
|
|
meUpdated: Packed<'User'>;
|
|
pageEvent: {
|
|
pageId: Page['id'];
|
|
event: string;
|
|
var: any;
|
|
userId: User['id'];
|
|
user: Packed<'User'>;
|
|
};
|
|
urlUploadFinished: {
|
|
marker?: string | null;
|
|
file: Packed<'DriveFile'>;
|
|
};
|
|
readAllNotifications: undefined;
|
|
unreadNotification: Packed<'Notification'>;
|
|
unreadMention: Note['id'];
|
|
readAllUnreadMentions: undefined;
|
|
unreadSpecifiedNote: Note['id'];
|
|
readAllUnreadSpecifiedNotes: undefined;
|
|
readAllMessagingMessages: undefined;
|
|
messagingMessage: Packed<'MessagingMessage'>;
|
|
unreadMessagingMessage: Packed<'MessagingMessage'>;
|
|
readAllAntennas: undefined;
|
|
unreadAntenna: Antenna;
|
|
readAllAnnouncements: undefined;
|
|
readAllChannels: undefined;
|
|
unreadChannel: Note['id'];
|
|
myTokenRegenerated: undefined;
|
|
signin: Signin;
|
|
registryUpdated: {
|
|
scope?: string[];
|
|
key: string;
|
|
value: any | null;
|
|
};
|
|
driveFileCreated: Packed<'DriveFile'>;
|
|
readAntenna: Antenna;
|
|
receiveFollowRequest: Packed<'User'>;
|
|
}
|
|
|
|
export interface DriveStreamTypes {
|
|
fileCreated: Packed<'DriveFile'>;
|
|
fileDeleted: DriveFile['id'];
|
|
fileUpdated: Packed<'DriveFile'>;
|
|
folderCreated: Packed<'DriveFolder'>;
|
|
folderDeleted: DriveFolder['id'];
|
|
folderUpdated: Packed<'DriveFolder'>;
|
|
}
|
|
|
|
export interface NoteStreamTypes {
|
|
pollVoted: {
|
|
choice: number;
|
|
userId: User['id'];
|
|
};
|
|
deleted: {
|
|
deletedAt: Date;
|
|
};
|
|
reacted: {
|
|
reaction: string;
|
|
emoji?: {
|
|
name: string;
|
|
url: string;
|
|
} | null;
|
|
userId: User['id'];
|
|
};
|
|
unreacted: {
|
|
reaction: string;
|
|
userId: User['id'];
|
|
};
|
|
}
|
|
type NoteStreamEventTypes = {
|
|
[key in keyof NoteStreamTypes]: {
|
|
id: Note['id'];
|
|
body: NoteStreamTypes[key];
|
|
};
|
|
};
|
|
|
|
export interface ChannelStreamTypes {
|
|
typing: User['id'];
|
|
}
|
|
|
|
export interface UserListStreamTypes {
|
|
userAdded: Packed<'User'>;
|
|
userRemoved: Packed<'User'>;
|
|
}
|
|
|
|
export interface AntennaStreamTypes {
|
|
note: Note;
|
|
}
|
|
|
|
export interface MessagingStreamTypes {
|
|
read: MessagingMessage['id'][];
|
|
typing: User['id'];
|
|
message: Packed<'MessagingMessage'>;
|
|
deleted: MessagingMessage['id'];
|
|
}
|
|
|
|
export interface GroupMessagingStreamTypes {
|
|
read: {
|
|
ids: MessagingMessage['id'][];
|
|
userId: User['id'];
|
|
};
|
|
typing: User['id'];
|
|
message: Packed<'MessagingMessage'>;
|
|
deleted: MessagingMessage['id'];
|
|
}
|
|
|
|
export interface MessagingIndexStreamTypes {
|
|
read: MessagingMessage['id'][];
|
|
message: Packed<'MessagingMessage'>;
|
|
}
|
|
|
|
export interface AdminStreamTypes {
|
|
newAbuseUserReport: {
|
|
id: AbuseUserReport['id'];
|
|
targetUserId: User['id'],
|
|
reporterId: User['id'],
|
|
comment: string;
|
|
urls: string[];
|
|
};
|
|
}
|
|
//#endregion
|
|
|
|
// 辞書(interface or type)から{ type, body }ユニオンを定義
|
|
// https://stackoverflow.com/questions/49311989/can-i-infer-the-type-of-a-value-using-extends-keyof-type
|
|
// VS Codeの展開を防止するためにEvents型を定義
|
|
type Events<T extends object> = { [K in keyof T]: { type: K; body: T[K]; } };
|
|
type EventUnionFromDictionary<
|
|
T extends object,
|
|
U = Events<T>
|
|
> = U[keyof U];
|
|
|
|
// name/messages(spec) pairs dictionary
|
|
export type StreamMessages = {
|
|
internal: {
|
|
name: 'internal';
|
|
payload: EventUnionFromDictionary<InternalStreamTypes>;
|
|
};
|
|
broadcast: {
|
|
name: 'broadcast';
|
|
payload: EventUnionFromDictionary<BroadcastTypes>;
|
|
};
|
|
user: {
|
|
name: `user:${User['id']}`;
|
|
payload: EventUnionFromDictionary<UserStreamTypes>;
|
|
};
|
|
main: {
|
|
name: `mainStream:${User['id']}`;
|
|
payload: EventUnionFromDictionary<MainStreamTypes>;
|
|
};
|
|
drive: {
|
|
name: `driveStream:${User['id']}`;
|
|
payload: EventUnionFromDictionary<DriveStreamTypes>;
|
|
};
|
|
note: {
|
|
name: `noteStream:${Note['id']}`;
|
|
payload: EventUnionFromDictionary<NoteStreamEventTypes>;
|
|
};
|
|
channel: {
|
|
name: `channelStream:${Channel['id']}`;
|
|
payload: EventUnionFromDictionary<ChannelStreamTypes>;
|
|
};
|
|
userList: {
|
|
name: `userListStream:${UserList['id']}`;
|
|
payload: EventUnionFromDictionary<UserListStreamTypes>;
|
|
};
|
|
antenna: {
|
|
name: `antennaStream:${Antenna['id']}`;
|
|
payload: EventUnionFromDictionary<AntennaStreamTypes>;
|
|
};
|
|
messaging: {
|
|
name: `messagingStream:${User['id']}-${User['id']}`;
|
|
payload: EventUnionFromDictionary<MessagingStreamTypes>;
|
|
};
|
|
groupMessaging: {
|
|
name: `messagingStream:${UserGroup['id']}`;
|
|
payload: EventUnionFromDictionary<GroupMessagingStreamTypes>;
|
|
};
|
|
messagingIndex: {
|
|
name: `messagingIndexStream:${User['id']}`;
|
|
payload: EventUnionFromDictionary<MessagingIndexStreamTypes>;
|
|
};
|
|
admin: {
|
|
name: `adminStream:${User['id']}`;
|
|
payload: EventUnionFromDictionary<AdminStreamTypes>;
|
|
};
|
|
notes: {
|
|
name: 'notesStream';
|
|
payload: Note;
|
|
};
|
|
};
|
|
|
|
// API event definitions
|
|
// ストリームごとのEmitterの辞書を用意
|
|
type EventEmitterDictionary = { [x in keyof StreamMessages]: Emitter<EventEmitter, { [y in StreamMessages[x]['name']]: (e: StreamMessages[x]['payload']) => void }> };
|
|
// 共用体型を交差型にする型 https://stackoverflow.com/questions/54938141/typescript-convert-union-to-intersection
|
|
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
|
|
// Emitter辞書から共用体型を作り、UnionToIntersectionで交差型にする
|
|
export type StreamEventEmitter = UnionToIntersection<EventEmitterDictionary[keyof StreamMessages]>;
|
|
// { [y in name]: (e: spec) => void }をまとめてその交差型をEmitterにかけるとts(2590)にひっかかる
|
|
|
|
// provide stream channels union
|
|
export type StreamChannels = StreamMessages[keyof StreamMessages]['name'];
|