enhance(misskey-js) misskey-jsのストリーミングAPI定義をバックエンドに追従 (#12552)

* (enhance) misskey-jsのストリーミングAPI定義をバックエンドに追従

* fix ci

* fix ci
This commit is contained in:
おさむのひと 2023-12-03 12:45:18 +09:00 committed by GitHub
parent b4a83a22a1
commit e17d741f4b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 414 additions and 56 deletions

View file

@ -36,6 +36,7 @@ import { packedGalleryPostSchema } from '@/models/json-schema/gallery-post.js';
import { packedEmojiDetailedSchema, packedEmojiSimpleSchema } from '@/models/json-schema/emoji.js'; import { packedEmojiDetailedSchema, packedEmojiSimpleSchema } from '@/models/json-schema/emoji.js';
import { packedFlashSchema } from '@/models/json-schema/flash.js'; import { packedFlashSchema } from '@/models/json-schema/flash.js';
import { packedAnnouncementSchema } from '@/models/json-schema/announcement.js'; import { packedAnnouncementSchema } from '@/models/json-schema/announcement.js';
import { packedSigninSchema } from '@/models/json-schema/signin.js';
export const refs = { export const refs = {
UserLite: packedUserLiteSchema, UserLite: packedUserLiteSchema,
@ -71,6 +72,7 @@ export const refs = {
EmojiSimple: packedEmojiSimpleSchema, EmojiSimple: packedEmojiSimpleSchema,
EmojiDetailed: packedEmojiDetailedSchema, EmojiDetailed: packedEmojiDetailedSchema,
Flash: packedFlashSchema, Flash: packedFlashSchema,
Signin: packedSigninSchema,
}; };
export type Packed<x extends keyof typeof refs> = SchemaType<typeof refs[x]>; export type Packed<x extends keyof typeof refs> = SchemaType<typeof refs[x]>;

View file

@ -0,0 +1,26 @@
export const packedSigninSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
ip: {
type: 'string',
optional: false, nullable: false,
},
headers: {
type: 'object',
optional: false, nullable: false,
},
success: {
type: 'boolean',
optional: false, nullable: false,
},
},
} as const;

View file

@ -12,8 +12,17 @@ import { DI } from '@/di-symbols.js';
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
secure: true, secure: true,
res: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
ref: 'Signin',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View file

@ -292,6 +292,11 @@ type AdminUpdateUserNoteRequest = operations['admin/update-user-note']['requestB
// @public (undocumented) // @public (undocumented)
type Announcement = components['schemas']['Announcement']; type Announcement = components['schemas']['Announcement'];
// @public (undocumented)
type AnnouncementCreated = {
announcement: Announcement;
};
// @public (undocumented) // @public (undocumented)
type AnnouncementsRequest = operations['announcements']['requestBody']['content']['application/json']; type AnnouncementsRequest = operations['announcements']['requestBody']['content']['application/json'];
@ -488,9 +493,7 @@ export type Channels = {
unreadAntenna: (payload: Antenna) => void; unreadAntenna: (payload: Antenna) => void;
readAllAnnouncements: () => void; readAllAnnouncements: () => void;
myTokenRegenerated: () => void; myTokenRegenerated: () => void;
reversiNoInvites: () => void; signin: (payload: Signin) => void;
reversiInvited: (payload: FIXME) => void;
signin: (payload: FIXME) => void;
registryUpdated: (payload: { registryUpdated: (payload: {
scope?: string[]; scope?: string[];
key: string; key: string;
@ -498,41 +501,116 @@ export type Channels = {
}) => void; }) => void;
driveFileCreated: (payload: DriveFile) => void; driveFileCreated: (payload: DriveFile) => void;
readAntenna: (payload: Antenna) => void; readAntenna: (payload: Antenna) => void;
receiveFollowRequest: (payload: User) => void;
announcementCreated: (payload: AnnouncementCreated) => void;
}; };
receives: null; receives: null;
}; };
homeTimeline: { homeTimeline: {
params: null; params: {
withRenotes?: boolean;
withFiles?: boolean;
};
events: { events: {
note: (payload: Note) => void; note: (payload: Note) => void;
}; };
receives: null; receives: null;
}; };
localTimeline: { localTimeline: {
params: null; params: {
withRenotes?: boolean;
withReplies?: boolean;
withFiles?: boolean;
};
events: { events: {
note: (payload: Note) => void; note: (payload: Note) => void;
}; };
receives: null; receives: null;
}; };
hybridTimeline: { hybridTimeline: {
params: null; params: {
withRenotes?: boolean;
withReplies?: boolean;
withFiles?: boolean;
};
events: { events: {
note: (payload: Note) => void; note: (payload: Note) => void;
}; };
receives: null; receives: null;
}; };
globalTimeline: { globalTimeline: {
params: null; params: {
withRenotes?: boolean;
withFiles?: boolean;
};
events: { events: {
note: (payload: Note) => void; note: (payload: Note) => void;
}; };
receives: null; receives: null;
}; };
userList: {
params: {
listId: string;
withFiles?: boolean;
};
events: {
note: (payload: Note) => void;
};
receives: null;
};
hashtag: {
params: {
q?: string;
};
events: {
note: (payload: Note) => void;
};
receives: null;
};
roleTimeline: {
params: {
roleId: string;
};
events: {
note: (payload: Note) => void;
};
receives: null;
};
antenna: {
params: {
antennaId: string;
};
events: {
note: (payload: Note) => void;
};
receives: null;
};
channel: {
params: {
channelId: string;
};
events: {
note: (payload: Note) => void;
};
receives: null;
};
drive: {
params: null;
events: {
fileCreated: (payload: DriveFile) => void;
fileDeleted: (payload: DriveFile['id']) => void;
fileUpdated: (payload: DriveFile) => void;
folderCreated: (payload: DriveFolder) => void;
folderDeleted: (payload: DriveFolder['id']) => void;
folderUpdated: (payload: DriveFile) => void;
};
receives: null;
};
serverStats: { serverStats: {
params: null; params: null;
events: { events: {
stats: (payload: FIXME) => void; stats: (payload: ServerStats) => void;
statsLog: (payload: ServerStatsLog) => void;
}; };
receives: { receives: {
requestLog: { requestLog: {
@ -544,7 +622,8 @@ export type Channels = {
queueStats: { queueStats: {
params: null; params: null;
events: { events: {
stats: (payload: FIXME) => void; stats: (payload: QueueStats) => void;
statsLog: (payload: QueueStatsLog) => void;
}; };
receives: { receives: {
requestLog: { requestLog: {
@ -553,6 +632,18 @@ export type Channels = {
}; };
}; };
}; };
admin: {
params: null;
events: {
newAbuseUserReport: {
id: string;
targetUserId: string;
reporterId: string;
comment: string;
};
};
receives: null;
};
}; };
// @public (undocumented) // @public (undocumented)
@ -846,6 +937,16 @@ type EmailAddressAvailableRequest = operations['email-address/available']['reque
// @public (undocumented) // @public (undocumented)
type EmailAddressAvailableResponse = operations['email-address/available']['responses']['200']['content']['application/json']; type EmailAddressAvailableResponse = operations['email-address/available']['responses']['200']['content']['application/json'];
// @public (undocumented)
type EmojiAdded = {
emoji: EmojiDetailed;
};
// @public (undocumented)
type EmojiDeleted = {
emojis: EmojiDetailed[];
};
// @public (undocumented) // @public (undocumented)
type EmojiDetailed = components['schemas']['EmojiDetailed']; type EmojiDetailed = components['schemas']['EmojiDetailed'];
@ -861,6 +962,11 @@ type EmojiSimple = components['schemas']['EmojiSimple'];
// @public (undocumented) // @public (undocumented)
type EmojisResponse = operations['emojis']['responses']['200']['content']['application/json']; type EmojisResponse = operations['emojis']['responses']['200']['content']['application/json'];
// @public (undocumented)
type EmojiUpdated = {
emojis: EmojiDetailed[];
};
// @public (undocumented) // @public (undocumented)
type EmptyRequest = Record<string, unknown> | undefined; type EmptyRequest = Record<string, unknown> | undefined;
@ -902,6 +1008,14 @@ declare namespace entities {
DateString, DateString,
PageEvent, PageEvent,
ModerationLog, ModerationLog,
ServerStats,
ServerStatsLog,
QueueStats,
QueueStatsLog,
EmojiAdded,
EmojiUpdated,
EmojiDeleted,
AnnouncementCreated,
EmptyRequest, EmptyRequest,
EmptyResponse, EmptyResponse,
AdminMetaResponse, AdminMetaResponse,
@ -1404,7 +1518,8 @@ declare namespace entities {
GalleryPost, GalleryPost,
EmojiSimple, EmojiSimple,
EmojiDetailed, EmojiDetailed,
Flash Flash,
Signin
} }
} }
export { entities } export { entities }
@ -2154,6 +2269,25 @@ type PromoReadRequest = operations['promo/read']['requestBody']['content']['appl
// @public (undocumented) // @public (undocumented)
type QueueCount = components['schemas']['QueueCount']; type QueueCount = components['schemas']['QueueCount'];
// @public (undocumented)
type QueueStats = {
deliver: {
activeSincePrevTick: number;
active: number;
waiting: number;
delayed: number;
};
inbox: {
activeSincePrevTick: number;
active: number;
waiting: number;
delayed: number;
};
};
// @public (undocumented)
type QueueStatsLog = string[];
// @public (undocumented) // @public (undocumented)
type RenoteMuteCreateRequest = operations['renote-mute/create']['requestBody']['content']['application/json']; type RenoteMuteCreateRequest = operations['renote-mute/create']['requestBody']['content']['application/json'];
@ -2190,6 +2324,29 @@ type RolesShowRequest = operations['roles/show']['requestBody']['content']['appl
// @public (undocumented) // @public (undocumented)
type RolesUsersRequest = operations['roles/users']['requestBody']['content']['application/json']; type RolesUsersRequest = operations['roles/users']['requestBody']['content']['application/json'];
// @public (undocumented)
type ServerStats = {
cpu: number;
mem: {
used: number;
active: number;
};
net: {
rx: number;
tx: number;
};
fs: {
r: number;
w: number;
};
};
// @public (undocumented)
type ServerStatsLog = string[];
// @public (undocumented)
type Signin = components['schemas']['Signin'];
// @public (undocumented) // @public (undocumented)
type StatsResponse = operations['stats']['responses']['200']['content']['application/json']; type StatsResponse = operations['stats']['responses']['200']['content']['application/json'];
@ -2448,8 +2605,7 @@ type UsersUpdateMemoRequest = operations['users/update-memo']['requestBody']['co
// Warnings were encountered during analysis: // Warnings were encountered during analysis:
// //
// src/entities.ts:24:2 - (ae-forgotten-export) The symbol "ModerationLogPayloads" needs to be exported by the entry point index.d.ts // src/entities.ts:25:2 - (ae-forgotten-export) The symbol "ModerationLogPayloads" needs to be exported by the entry point index.d.ts
// src/streaming.types.ts:31:4 - (ae-forgotten-export) The symbol "FIXME" needs to be exported by the entry point index.d.ts
// (No @packageDocumentation comment for this package) // (No @packageDocumentation comment for this package)

View file

@ -1,6 +1,6 @@
/* /*
* version: 2023.11.1 * version: 2023.12.0-beta.1
* generatedAt: 2023-11-27T02:24:45.113Z * generatedAt: 2023-12-03T02:04:45.058Z
*/ */
import type { import type {

View file

@ -1,6 +1,6 @@
/* /*
* version: 2023.11.1 * version: 2023.12.0-beta.1
* generatedAt: 2023-11-27T02:24:45.111Z * generatedAt: 2023-12-03T02:04:45.053Z
*/ */
import { operations } from './types.js'; import { operations } from './types.js';

View file

@ -1,6 +1,6 @@
/* /*
* version: 2023.11.1 * version: 2023.12.0-beta.1
* generatedAt: 2023-11-27T02:24:45.109Z * generatedAt: 2023-12-03T02:04:45.051Z
*/ */
import { components } from './types.js'; import { components } from './types.js';
@ -37,3 +37,4 @@ export type GalleryPost = components['schemas']['GalleryPost'];
export type EmojiSimple = components['schemas']['EmojiSimple']; export type EmojiSimple = components['schemas']['EmojiSimple'];
export type EmojiDetailed = components['schemas']['EmojiDetailed']; export type EmojiDetailed = components['schemas']['EmojiDetailed'];
export type Flash = components['schemas']['Flash']; export type Flash = components['schemas']['Flash'];
export type Signin = components['schemas']['Signin'];

View file

@ -2,8 +2,8 @@
/* eslint @typescript-eslint/no-explicit-any: 0 */ /* eslint @typescript-eslint/no-explicit-any: 0 */
/* /*
* version: 2023.11.1 * version: 2023.12.0-beta.1
* generatedAt: 2023-11-27T02:24:44.994Z * generatedAt: 2023-12-03T02:04:44.864Z
*/ */
/** /**
@ -3388,6 +3388,7 @@ export type components = {
uri?: string; uri?: string;
url?: string; url?: string;
reactionAndUserPairCache?: string[]; reactionAndUserPairCache?: string[];
clippedCount?: number;
myReaction?: Record<string, unknown> | null; myReaction?: Record<string, unknown> | null;
}; };
NoteReaction: { NoteReaction: {
@ -3786,6 +3787,14 @@ export type components = {
likedCount: number | null; likedCount: number | null;
isLiked?: boolean; isLiked?: boolean;
}; };
Signin: {
id: string;
/** Format: date-time */
createdAt: string;
ip: string;
headers: Record<string, never>;
success: boolean;
};
}; };
responses: never; responses: never;
parameters: never; parameters: never;
@ -6405,10 +6414,7 @@ export type operations = {
/** @description OK (with results) */ /** @description OK (with results) */
200: { 200: {
content: { content: {
'application/json': { 'application/json': components['schemas']['InviteCode'][];
/** @example GR6S02ERUA5VR */
code: string;
}[];
}; };
}; };
/** @description Client error */ /** @description Client error */
@ -6471,7 +6477,7 @@ export type operations = {
/** @description OK (with results) */ /** @description OK (with results) */
200: { 200: {
content: { content: {
'application/json': Record<string, never>[]; 'application/json': components['schemas']['InviteCode'][];
}; };
}; };
/** @description Client error */ /** @description Client error */
@ -9600,6 +9606,8 @@ export type operations = {
untilId?: string; untilId?: string;
sinceDate?: number; sinceDate?: number;
untilDate?: number; untilDate?: number;
/** @default false */
allowPartial?: boolean;
}; };
}; };
}; };
@ -15893,10 +15901,7 @@ export type operations = {
/** @description OK (with results) */ /** @description OK (with results) */
200: { 200: {
content: { content: {
'application/json': { 'application/json': components['schemas']['InviteCode'];
/** @example GR6S02ERUA5VR */
code: string;
};
}; };
}; };
/** @description Client error */ /** @description Client error */
@ -17349,6 +17354,8 @@ export type operations = {
untilId?: string; untilId?: string;
sinceDate?: number; sinceDate?: number;
untilDate?: number; untilDate?: number;
/** @default false */
allowPartial?: boolean;
/** @default true */ /** @default true */
includeMyRenotes?: boolean; includeMyRenotes?: boolean;
/** @default true */ /** @default true */
@ -17419,14 +17426,14 @@ export type operations = {
withRenotes?: boolean; withRenotes?: boolean;
/** @default false */ /** @default false */
withReplies?: boolean; withReplies?: boolean;
/** @default false */
excludeNsfw?: boolean;
/** @default 10 */ /** @default 10 */
limit?: number; limit?: number;
/** Format: misskey:id */ /** Format: misskey:id */
sinceId?: string; sinceId?: string;
/** Format: misskey:id */ /** Format: misskey:id */
untilId?: string; untilId?: string;
/** @default false */
allowPartial?: boolean;
sinceDate?: number; sinceDate?: number;
untilDate?: number; untilDate?: number;
}; };
@ -18317,6 +18324,8 @@ export type operations = {
untilId?: string; untilId?: string;
sinceDate?: number; sinceDate?: number;
untilDate?: number; untilDate?: number;
/** @default false */
allowPartial?: boolean;
/** @default true */ /** @default true */
includeMyRenotes?: boolean; includeMyRenotes?: boolean;
/** @default true */ /** @default true */
@ -18502,6 +18511,8 @@ export type operations = {
untilId?: string; untilId?: string;
sinceDate?: number; sinceDate?: number;
untilDate?: number; untilDate?: number;
/** @default false */
allowPartial?: boolean;
/** @default true */ /** @default true */
includeMyRenotes?: boolean; includeMyRenotes?: boolean;
/** @default true */ /** @default true */
@ -20799,6 +20810,7 @@ export type operations = {
username?: string; username?: string;
/** @description The local host is represented with `null`. */ /** @description The local host is represented with `null`. */
host?: string | null; host?: string | null;
birthday?: string | null;
}; };
}; };
}; };
@ -21704,9 +21716,9 @@ export type operations = {
sinceDate?: number; sinceDate?: number;
untilDate?: number; untilDate?: number;
/** @default false */ /** @default false */
withFiles?: boolean; allowPartial?: boolean;
/** @default false */ /** @default false */
excludeNsfw?: boolean; withFiles?: boolean;
}; };
}; };
}; };

View file

@ -1,5 +1,6 @@
import { ModerationLogPayloads, notificationTypes } from './consts.js'; import { ModerationLogPayloads } from './consts.js';
import { Page, User, UserDetailed } from './autogen/models'; import { Announcement, EmojiDetailed, Page, User, UserDetailed } from './autogen/models';
export * from './autogen/entities'; export * from './autogen/entities';
export * from './autogen/models'; export * from './autogen/models';
@ -131,3 +132,54 @@ export type ModerationLog = {
type: 'unsetUserBanner'; type: 'unsetUserBanner';
info: ModerationLogPayloads['unsetUserBanner']; info: ModerationLogPayloads['unsetUserBanner'];
}); });
export type ServerStats = {
cpu: number;
mem: {
used: number;
active: number;
};
net: {
rx: number;
tx: number;
};
fs: {
r: number;
w: number;
}
};
export type ServerStatsLog = string[];
export type QueueStats = {
deliver: {
activeSincePrevTick: number;
active: number;
waiting: number;
delayed: number;
};
inbox: {
activeSincePrevTick: number;
active: number;
waiting: number;
delayed: number;
};
};
export type QueueStatsLog = string[];
export type EmojiAdded = {
emoji: EmojiDetailed
};
export type EmojiUpdated = {
emojis: EmojiDetailed[]
};
export type EmojiDeleted = {
emojis: EmojiDetailed[]
};
export type AnnouncementCreated = {
announcement: Announcement;
};

View file

@ -1,7 +1,23 @@
import { Antenna, DriveFile, EmojiDetailed, MeDetailed, Note, User, Notification } from './autogen/models.js'; import {
import { PageEvent } from './entities.js'; Antenna,
DriveFile,
type FIXME = any; DriveFolder,
MeDetailed,
Note,
Notification,
Signin,
User,
} from './autogen/models.js';
import {
AnnouncementCreated,
EmojiAdded, EmojiDeleted,
EmojiUpdated,
PageEvent,
QueueStats,
QueueStatsLog,
ServerStats,
ServerStatsLog,
} from './entities.js';
export type Channels = { export type Channels = {
main: { main: {
@ -27,9 +43,7 @@ export type Channels = {
unreadAntenna: (payload: Antenna) => void; unreadAntenna: (payload: Antenna) => void;
readAllAnnouncements: () => void; readAllAnnouncements: () => void;
myTokenRegenerated: () => void; myTokenRegenerated: () => void;
reversiNoInvites: () => void; signin: (payload: Signin) => void;
reversiInvited: (payload: FIXME) => void;
signin: (payload: FIXME) => void;
registryUpdated: (payload: { registryUpdated: (payload: {
scope?: string[]; scope?: string[];
key: string; key: string;
@ -37,41 +51,116 @@ export type Channels = {
}) => void; }) => void;
driveFileCreated: (payload: DriveFile) => void; driveFileCreated: (payload: DriveFile) => void;
readAntenna: (payload: Antenna) => void; readAntenna: (payload: Antenna) => void;
receiveFollowRequest: (payload: User) => void;
announcementCreated: (payload: AnnouncementCreated) => void;
}; };
receives: null; receives: null;
}; };
homeTimeline: { homeTimeline: {
params: null; params: {
withRenotes?: boolean;
withFiles?: boolean;
};
events: { events: {
note: (payload: Note) => void; note: (payload: Note) => void;
}; };
receives: null; receives: null;
}; };
localTimeline: { localTimeline: {
params: null; params: {
withRenotes?: boolean;
withReplies?: boolean;
withFiles?: boolean;
};
events: { events: {
note: (payload: Note) => void; note: (payload: Note) => void;
}; };
receives: null; receives: null;
}; };
hybridTimeline: { hybridTimeline: {
params: null; params: {
withRenotes?: boolean;
withReplies?: boolean;
withFiles?: boolean;
};
events: { events: {
note: (payload: Note) => void; note: (payload: Note) => void;
}; };
receives: null; receives: null;
}; };
globalTimeline: { globalTimeline: {
params: null; params: {
withRenotes?: boolean;
withFiles?: boolean;
};
events: { events: {
note: (payload: Note) => void; note: (payload: Note) => void;
}; };
receives: null; receives: null;
}; };
userList: {
params: {
listId: string;
withFiles?: boolean;
};
events: {
note: (payload: Note) => void;
};
receives: null;
};
hashtag: {
params: {
q?: string;
};
events: {
note: (payload: Note) => void;
};
receives: null;
};
roleTimeline: {
params: {
roleId: string;
};
events: {
note: (payload: Note) => void;
};
receives: null;
};
antenna: {
params: {
antennaId: string;
};
events: {
note: (payload: Note) => void;
};
receives: null;
};
channel: {
params: {
channelId: string;
};
events: {
note: (payload: Note) => void;
};
receives: null;
};
drive: {
params: null;
events: {
fileCreated: (payload: DriveFile) => void;
fileDeleted: (payload: DriveFile['id']) => void;
fileUpdated: (payload: DriveFile) => void;
folderCreated: (payload: DriveFolder) => void;
folderDeleted: (payload: DriveFolder['id']) => void;
folderUpdated: (payload: DriveFile) => void;
};
receives: null;
};
serverStats: { serverStats: {
params: null; params: null;
events: { events: {
stats: (payload: FIXME) => void; stats: (payload: ServerStats) => void;
statsLog: (payload: ServerStatsLog) => void;
}; };
receives: { receives: {
requestLog: { requestLog: {
@ -83,7 +172,8 @@ export type Channels = {
queueStats: { queueStats: {
params: null; params: null;
events: { events: {
stats: (payload: FIXME) => void; stats: (payload: QueueStats) => void;
statsLog: (payload: QueueStatsLog) => void;
}; };
receives: { receives: {
requestLog: { requestLog: {
@ -92,30 +182,39 @@ export type Channels = {
}; };
}; };
}; };
admin: {
params: null;
events: {
newAbuseUserReport: {
id: string;
targetUserId: string;
reporterId: string;
comment: string;
}
};
receives: null;
}
}; };
export type NoteUpdatedEvent = { export type NoteUpdatedEvent = {
id: Note['id'];
type: 'reacted'; type: 'reacted';
body: { body: {
reaction: string; reaction: string;
emoji: string | null;
userId: User['id']; userId: User['id'];
}; };
} | { } | {
id: Note['id'];
type: 'unreacted'; type: 'unreacted';
body: { body: {
reaction: string; reaction: string;
userId: User['id']; userId: User['id'];
}; };
} | { } | {
id: Note['id'];
type: 'deleted'; type: 'deleted';
body: { body: {
deletedAt: string; deletedAt: string;
}; };
} | { } | {
id: Note['id'];
type: 'pollVoted'; type: 'pollVoted';
body: { body: {
choice: number; choice: number;
@ -125,7 +224,8 @@ export type NoteUpdatedEvent = {
export type BroadcastEvents = { export type BroadcastEvents = {
noteUpdated: (payload: NoteUpdatedEvent) => void; noteUpdated: (payload: NoteUpdatedEvent) => void;
emojiAdded: (payload: { emojiAdded: (payload: EmojiAdded) => void;
emoji: EmojiDetailed; emojiUpdated: (payload: EmojiUpdated) => void;
}) => void; emojiDeleted: (payload: EmojiDeleted) => void;
announcementCreated: (payload: AnnouncementCreated) => void;
}; };