Skip to content

Commit 22eebe3

Browse files
authored
Merge pull request #9 from Coder-soft/Testingbranch
Testingbranch
2 parents 3c7512c + d34f319 commit 22eebe3

7 files changed

Lines changed: 57 additions & 18 deletions

File tree

src/api/routes/messages.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,22 @@ import { Router, type Request } from 'express';
22
import { messageService } from '../../discord/services/index.js';
33
import { SendMessageSchema, EditMessageSchema, GetMessagesSchema } from '../../types/api.types.js';
44

5+
/** Route params for message endpoints (merged from parent router) */
6+
interface MessageParams {
7+
channelId?: string;
8+
messageId?: string;
9+
emoji?: string;
10+
}
11+
512
const router = Router({ mergeParams: true });
613

7-
// Helper to get merged params
14+
/**
15+
* Helper to get merged params with type safety.
16+
* Express mergeParams merges parent route params, so channelId comes from the parent router.
17+
*/
818
function getParams(req: Request): { channelId: string; messageId?: string; emoji?: string } {
9-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
10-
const params = req.params as any;
19+
// Params are merged from parent router via mergeParams: true
20+
const params = req.params as MessageParams;
1121
return { channelId: params.channelId ?? '', messageId: params.messageId, emoji: params.emoji };
1222
}
1323

src/discord/events/index.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Server as SocketIOServer } from 'socket.io';
2+
import type { User, GuildScheduledEvent } from 'discord.js';
23
import { discordClient } from '../client.js';
34
import {
45
serializeMessage,
@@ -267,7 +268,8 @@ export function registerDiscordEvents(): void {
267268

268269
discordClient.on('userUpdate', (oldUser, newUser) => {
269270
// oldUser may be partial, so we only serialize if not partial
270-
const oldSerialized = oldUser.partial ? null : serializeUser(oldUser as any);
271+
// Type assertion is safe here because we've checked partial === false
272+
const oldSerialized = oldUser.partial ? null : serializeUser(oldUser as User);
271273
broadcastEvent({
272274
event: 'userUpdate',
273275
guildId: null,
@@ -605,25 +607,40 @@ export function registerDiscordEvents(): void {
605607

606608
discordClient.on('guildScheduledEventUpdate', (oldEvent, newEvent) => {
607609
// oldEvent may be partial
610+
// Type assertions are safe here because we've checked partial === false
608611
const oldSerialized = oldEvent && !oldEvent.partial
609-
? serializeScheduledEvent(oldEvent as any)
612+
? serializeScheduledEvent(oldEvent as GuildScheduledEvent)
610613
: null;
611614
broadcastEvent({
612615
event: 'guildScheduledEventUpdate',
613616
guildId: newEvent.guildId,
614617
data: {
615618
old: oldSerialized,
616-
new: serializeScheduledEvent(newEvent as any),
619+
new: serializeScheduledEvent(newEvent as GuildScheduledEvent),
617620
},
618621
});
619622
});
620623

621624
discordClient.on('guildScheduledEventDelete', (event) => {
622-
// event may be partial, but we still want to broadcast the deletion
625+
// For partial events, only broadcast minimal deletion info
626+
// Full serialization would fail as many properties are undefined
627+
if (event.partial) {
628+
broadcastEvent({
629+
event: 'guildScheduledEventDelete',
630+
guildId: event.guildId,
631+
data: {
632+
id: event.id,
633+
guildId: event.guildId,
634+
partial: true,
635+
},
636+
});
637+
return;
638+
}
639+
623640
broadcastEvent({
624641
event: 'guildScheduledEventDelete',
625642
guildId: event.guildId,
626-
data: serializeScheduledEvent(event as any),
643+
data: serializeScheduledEvent(event as GuildScheduledEvent),
627644
});
628645
});
629646

src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { loginDiscord, waitForReady, discordClient } from './discord/client.js';
22
import { registerDiscordEvents } from './discord/events/index.js';
33
import { createApiServer, startApiServer } from './api/server.js';
44
import { pluginManager } from './plugins/manager.js';
5+
import { shutdownRateLimiter } from './api/middleware/rateLimit.js';
56
import { config } from './config/index.js';
67

78
async function main(): Promise<void> {
@@ -44,6 +45,9 @@ async function main(): Promise<void> {
4445
async function shutdown(): Promise<void> {
4546
console.log('\n🛑 Shutting down...');
4647

48+
// Clean up rate limiter intervals
49+
shutdownRateLimiter();
50+
4751
// Unload plugins gracefully
4852
if (pluginManager.count > 0) {
4953
console.log('🔌 Unloading plugins...');

src/plugins/manager.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,9 @@ export class PluginManager {
214214
normalizedArgs = args.map(wrapHandler);
215215
}
216216

217-
pluginSubRouter!.use(...normalizedArgs as Parameters<typeof pluginSubRouter.use>);
217+
// pluginSubRouter is guaranteed non-null here since we just created it
218+
const router = pluginSubRouter as Router;
219+
router.use(...normalizedArgs as Parameters<typeof router.use>);
218220
},
219221
};
220222

src/plugins/sdk.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ export function createEventHelpers(eventBus: PluginEventBus) {
167167
};
168168
}
169169

170+
/**
171+
* Type for the event helpers object returned by createEventHelpers
172+
*/
173+
export type EventHelpers = ReturnType<typeof createEventHelpers>;
174+
170175
/**
171176
* Plugin definition options for definePlugin helper
172177
*/

src/types/events.types.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,14 @@ export interface GuildScheduledEventUpdateEvent {
563563
export interface GuildScheduledEventDeleteEvent {
564564
event: 'guildScheduledEventDelete';
565565
guildId: string;
566-
data: SerializedScheduledEvent;
566+
data: SerializedScheduledEvent | {
567+
/** Event ID (always available even for partial events) */
568+
id: string;
569+
/** Guild ID (always available even for partial events) */
570+
guildId: string;
571+
/** Indicates this is a partial event with limited data */
572+
partial: true;
573+
};
567574
}
568575

569576
export interface GuildScheduledEventUserAddEvent {

src/types/plugin.types.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type {
99
SocketData,
1010
} from './events.types.js';
1111
import type { PluginEventBus, EventSubscription } from '../plugins/event-bus.js';
12-
import type { PluginRouter, PluginLogger } from '../plugins/sdk.js';
12+
import type { PluginRouter, PluginLogger, EventHelpers } from '../plugins/sdk.js';
1313

1414
/**
1515
* The context passed to plugins on load.
@@ -92,13 +92,7 @@ export interface HoloPlugin {
9292
* ```
9393
*/
9494
events?: (
95-
helpers: {
96-
onDiscord: <T = unknown>(event: string, handler: (data: T) => void | Promise<void>) => EventSubscription;
97-
onCustom: <T = Record<string, unknown>>(event: string, handler: (data: T) => void | Promise<void>) => EventSubscription;
98-
emit: <T extends Record<string, unknown>>(event: string, data: T) => void;
99-
onPluginLoaded: (handler: (data: { name: string; version: string }) => void) => EventSubscription;
100-
onPluginUnloaded: (handler: (data: { name: string }) => void) => EventSubscription;
101-
},
95+
helpers: EventHelpers,
10296
ctx: PluginContext
10397
) => EventSubscription[];
10498

0 commit comments

Comments
 (0)