Skip to content

Commit

Permalink
feat: simplify interaction success type
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim Smart committed Dec 6, 2022
1 parent 46fdba9 commit 683d19d
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 34 deletions.
5 changes: 2 additions & 3 deletions src/Interactions/context.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { InteractionResponse } from "./definitions.js"
import { DefinitionNotFound } from "./handlers.js"
import * as Arr from "@fp-ts/data/ReadonlyArray"
import { optionsMap } from "dfx/Helpers/interactions"
import { EffectTypeId, Effect } from "@effect/io/Effect"
Expand Down Expand Up @@ -57,7 +56,7 @@ export class SubCommandNotFound {
}

export const handleSubCommands = <
NER extends Record<string, Effect<any, any, Maybe<InteractionResponse>>>,
NER extends Record<string, Effect<any, any, InteractionResponse>>,
>(
commands: NER,
): Effect<
Expand All @@ -77,7 +76,7 @@ export const handleSubCommands = <
? E
: never)
| SubCommandNotFound,
Maybe<InteractionResponse>
InteractionResponse
> =>
Effect.service(ApplicationCommandContext).flatMap((data) =>
pipe(
Expand Down
22 changes: 12 additions & 10 deletions src/Interactions/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class GlobalApplicationCommand<R, E> {
readonly _tag = "GlobalApplicationCommand"
constructor(
readonly command: Discord.CreateGlobalApplicationCommandParams,
readonly handle: Effect<R, E, Maybe<InteractionResponse>>,
readonly handle: Effect<R, E, InteractionResponse>,
) {}
}

Expand All @@ -53,7 +53,7 @@ export const global = <
command: A,
handle: DescriptionMissing<A> extends true
? "command description is missing"
: Effect<R, E, Maybe<InteractionResponse>>,
: Effect<R, E, InteractionResponse>,
) =>
new GlobalApplicationCommand<
Exclude<R, Discord.Interaction | Discord.ApplicationCommandDatum>,
Expand All @@ -64,7 +64,7 @@ export class GuildApplicationCommand<R, E> {
readonly _tag = "GuildApplicationCommand"
constructor(
readonly command: Discord.CreateGuildApplicationCommandParams,
readonly handle: Effect<R, E, Maybe<InteractionResponse>>,
readonly handle: Effect<R, E, InteractionResponse>,
) {}
}

Expand All @@ -76,7 +76,7 @@ export const guild = <
command: A,
handle: DescriptionMissing<A> extends true
? "command description is missing"
: Effect<R, E, Maybe<InteractionResponse>>,
: Effect<R, E, InteractionResponse>,
) =>
new GuildApplicationCommand<
Exclude<R, Discord.Interaction | Discord.ApplicationCommandDatum>,
Expand All @@ -87,13 +87,13 @@ export class MessageComponent<R, E> {
readonly _tag = "MessageComponent"
constructor(
readonly predicate: (customId: string) => Effect<R, E, boolean>,
readonly handle: Effect<R, E, Maybe<InteractionResponse>>,
readonly handle: Effect<R, E, InteractionResponse>,
) {}
}

export const messageComponent = <R1, R2, E1, E2>(
pred: (customId: string) => Effect<R1, E1, boolean>,
handle: Effect<R2, E2, Maybe<InteractionResponse>>,
handle: Effect<R2, E2, InteractionResponse>,
) =>
new MessageComponent<
Exclude<R1 | R2, Discord.Interaction | Discord.MessageComponentDatum>,
Expand All @@ -104,13 +104,13 @@ export class ModalSubmit<R, E> {
readonly _tag = "ModalSubmit"
constructor(
readonly predicate: (customId: string) => Effect<R, E, boolean>,
readonly handle: Effect<R, E, Maybe<InteractionResponse>>,
readonly handle: Effect<R, E, InteractionResponse>,
) {}
}

export const modalSubmit = <R1, R2, E1, E2>(
pred: (customId: string) => Effect<R1, E1, boolean>,
handle: Effect<R2, E2, Maybe<InteractionResponse>>,
handle: Effect<R2, E2, InteractionResponse>,
) =>
new ModalSubmit<
Exclude<R1 | R2, Discord.Interaction | Discord.ModalSubmitDatum>,
Expand All @@ -121,17 +121,19 @@ export class Autocomplete<R, E> {
readonly _tag = "Autocomplete"
constructor(
readonly predicate: (
data: Discord.ApplicationCommandDatum,
focusedOption: Discord.ApplicationCommandInteractionDataOption,
) => Effect<R, E, boolean>,
readonly handle: Effect<R, E, Maybe<InteractionResponse>>,
readonly handle: Effect<R, E, InteractionResponse>,
) {}
}

export const autocomplete = <R1, R2, E1, E2>(
pred: (
data: Discord.ApplicationCommandDatum,
focusedOption: Discord.ApplicationCommandInteractionDataOption,
) => Effect<R1, E1, boolean>,
handle: Effect<R2, E2, Maybe<InteractionResponse>>,
handle: Effect<R2, E2, InteractionResponse>,
) =>
new Autocomplete<
Exclude<
Expand Down
4 changes: 1 addition & 3 deletions src/Interactions/gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@ export const run =
const run = Gateway.handleDispatch("INTERACTION_CREATE", (i) =>
pipe(
handle[i.type](i).tap((r) =>
r.match(Effect.unit, (r) =>
Rest.rest.createInteractionResponse(i.id, i.token, r),
),
Rest.rest.createInteractionResponse(i.id, i.token, r),
),
postHandler,
Effect.provideService(InteractionContext)(i),
Expand Down
8 changes: 4 additions & 4 deletions src/Interactions/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class DefinitionNotFound {
type Handler<R, E> = Effect<
R | Discord.Interaction,
E | DefinitionNotFound,
Maybe<Discord.InteractionResponse>
Discord.InteractionResponse
>

export const handlers = <R, E>(
Expand All @@ -27,7 +27,7 @@ export const handlers = <R, E>(
[Discord.InteractionType.PING]: () =>
Effect.succeed({
type: Discord.InteractionCallbackType.PONG,
}).asSome,
}),

[Discord.InteractionType.APPLICATION_COMMAND]: (i) => {
const data = i.data as Discord.ApplicationCommandDatum
Expand Down Expand Up @@ -100,7 +100,7 @@ export const handlers = <R, E>(
Arr.map((a) =>
Effect.struct({
command: Effect.succeed(a),
match: a.predicate(focusedOption),
match: a.predicate(data, focusedOption),
}),
),
(a) =>
Expand All @@ -117,7 +117,7 @@ export const handlers = <R, E>(
Effect.provideService(Ctx.FocusedOptionContext)({ focusedOption }),
),
)
.getOrElse(() => Effect.fail(new DefinitionNotFound(i)) as any)
.getOrElse(() => Effect.fail(new DefinitionNotFound(i)))
},
}
}
15 changes: 12 additions & 3 deletions src/Interactions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,21 @@ export const idRegex = (query: RegExp) => (customId: string) =>
export const option =
(command: string, optionName: string) =>
(
data: Discord.ApplicationCommandDatum,
focusedOption: Discord.ApplicationCommandInteractionDataOption,
data: Pick<Discord.ApplicationCommandDatum, "name">,
focusedOption: Pick<
Discord.ApplicationCommandInteractionDataOption,
"name"
>,
) =>
Effect.succeed(data.name === command && focusedOption.name === optionName)

export const optionOnly =
(optionName: string) =>
(focusedOption: Discord.ApplicationCommandInteractionDataOption) =>
(
_: unknown,
focusedOption: Pick<
Discord.ApplicationCommandInteractionDataOption,
"name"
>,
) =>
Effect.succeed(focusedOption.name === optionName)
12 changes: 1 addition & 11 deletions src/Interactions/webhook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ export interface HandleWebhookOpts<E> {
body: string
success: (a: Discord.InteractionResponse) => Effect<never, never, void>
error: (e: Cause<E>) => Effect<never, never, void>
empty: Effect<never, never, void>
}

export const makeHandler = <R, E>(ix: InteractionBuilder<R, E>) => {
Expand All @@ -83,17 +82,8 @@ export const makeHandler = <R, E>(ix: InteractionBuilder<R, E>) => {
headers,
body,
success,
empty,
error,
}: HandleWebhookOpts<
E | WebhookParseError | BadWebhookSignature | DefinitionNotFound
>) =>
handle(headers, body)
.flatMap((o) =>
o.match(
() => empty,
(a) => success(a),
),
)
.catchAllCause(error)
>) => handle(headers, body).flatMap(success).catchAllCause(error)
}

0 comments on commit 683d19d

Please sign in to comment.