Skip to content

Commit 2dc57d3

Browse files
committed
refactor: adds edit support to reply utility function, and refactors implementation to use Object.defineProperties
1 parent a025196 commit 2dc57d3

File tree

1 file changed

+52
-19
lines changed

1 file changed

+52
-19
lines changed

src/runtime/server/utils/reply.ts

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,47 @@
1-
import type { InteractionReplyOptions } from 'discord.js'
1+
import type { InteractionEditReplyOptions, InteractionReplyOptions } from 'discord.js'
22
import type { SlashCommandCustomReturnHandler } from '~/src/types'
33
import { MessageFlags } from 'discord.js'
44

5+
type OmitPreservingCallSignature<T, K extends keyof T = keyof T>
6+
= Omit<T, K> & (T extends (...args: infer R) => infer S ? (...args: R) => S : unknown)
57
interface ReplyFunction {
68
(text: string, options?: InteractionReplyOptions): SlashCommandCustomReturnHandler
7-
ephemeral: this
8-
flags: (flags: InteractionReplyOptions['flags']) => this
9+
edit: EditReplyFunction
10+
ephemeral: OmitPreservingCallSignature<ReplyFunction, 'edit' | 'ephemeral'>
11+
flags: (flags: InteractionReplyOptions['flags']) => OmitPreservingCallSignature<ReplyFunction, 'edit'>
912
}
1013

11-
function createReplyFunction(defaultOptions: Partial<InteractionReplyOptions> = {}): ReplyFunction {
12-
const reply = (text: string, options?: InteractionReplyOptions): SlashCommandCustomReturnHandler => (interaction) => {
13-
interaction.reply({
14-
content: text,
15-
...defaultOptions,
16-
...options,
17-
})
14+
interface EditReplyFunction {
15+
(text: string, options?: InteractionEditReplyOptions): SlashCommandCustomReturnHandler
16+
flags: (flags: InteractionEditReplyOptions['flags']) => EditReplyFunction
17+
}
18+
19+
function createReplyFunction(
20+
{ editReply, ...defaultOptions }: (
21+
| InteractionReplyOptions
22+
| InteractionEditReplyOptions
23+
) & { editReply?: boolean } = {},
24+
): ReplyFunction {
25+
const reply = (text: string, options?: InteractionReplyOptions | InteractionEditReplyOptions): SlashCommandCustomReturnHandler => async (interaction) => {
26+
if (editReply) {
27+
await interaction.editReply({
28+
content: text,
29+
...(defaultOptions as InteractionEditReplyOptions),
30+
...(options as InteractionEditReplyOptions),
31+
})
32+
}
33+
else {
34+
await interaction.reply({
35+
content: text,
36+
...(defaultOptions as InteractionReplyOptions),
37+
...(options as InteractionReplyOptions),
38+
})
39+
}
1840
}
1941

20-
return new Proxy(reply, {
21-
get(target, prop, receiver) {
22-
if (prop === 'ephemeral') {
42+
Object.defineProperties(reply, {
43+
ephemeral: {
44+
get() {
2345
return createReplyFunction({
2446
...defaultOptions,
2547
flags: defaultOptions.flags == null
@@ -33,16 +55,27 @@ function createReplyFunction(defaultOptions: Partial<InteractionReplyOptions> =
3355
// I give up refining this type...
3456
: MessageFlags.Ephemeral,
3557
})
36-
}
37-
else if (prop === 'flags') {
38-
return (flags: InteractionReplyOptions['flags']) => createReplyFunction({
58+
},
59+
},
60+
flags: {
61+
get() {
62+
return (flags: InteractionReplyOptions['flags'] & InteractionEditReplyOptions['flags']) => createReplyFunction({
3963
...defaultOptions,
4064
flags,
4165
})
42-
}
43-
return Reflect.get(target, prop, receiver)
66+
},
67+
},
68+
edit: {
69+
get() {
70+
return createReplyFunction({
71+
...defaultOptions,
72+
editReply: true,
73+
})
74+
},
4475
},
45-
}) as ReplyFunction
76+
})
77+
78+
return reply as ReplyFunction
4679
}
4780

4881
export const reply: ReplyFunction = createReplyFunction()

0 commit comments

Comments
 (0)