dfx 0.44.0 → 0.45.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Interactions/builder.d.ts +48 -0
- package/Interactions/builder.js +68 -0
- package/Interactions/builder.js.map +1 -0
- package/Interactions/definitions.d.ts +2 -2
- package/Interactions/gateway.d.ts +4 -4
- package/Interactions/gateway.js +19 -15
- package/Interactions/gateway.js.map +1 -1
- package/Interactions/handlers.d.ts +3 -3
- package/Interactions/handlers.js +15 -28
- package/Interactions/handlers.js.map +1 -1
- package/Interactions/index.d.ts +1 -35
- package/Interactions/index.js +1 -57
- package/Interactions/index.js.map +1 -1
- package/Interactions/utils.d.ts +75 -7
- package/Interactions/utils.js +28 -15
- package/Interactions/utils.js.map +1 -1
- package/Interactions/webhook.d.ts +4 -4
- package/Interactions/webhook.js +6 -6
- package/Interactions/webhook.js.map +1 -1
- package/package.json +2 -2
- package/src/Interactions/builder.ts +156 -0
- package/src/Interactions/definitions.ts +2 -2
- package/src/Interactions/gateway.ts +49 -26
- package/src/Interactions/handlers.ts +59 -80
- package/src/Interactions/index.ts +1 -142
- package/src/Interactions/utils.ts +72 -29
- package/src/Interactions/webhook.ts +28 -10
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import * as Http from "@effect-http/client"
|
|
2
|
-
import { catchTag } from "@effect/io/Effect"
|
|
3
|
-
import { DiscordREST } from "dfx"
|
|
4
1
|
import { Discord, Effect } from "dfx/_common"
|
|
5
|
-
import * as D from "./definitions.js"
|
|
6
2
|
|
|
7
3
|
export { response } from "../Helpers/interactions.js"
|
|
4
|
+
export * from "./builder.js"
|
|
8
5
|
export * from "./context.js"
|
|
9
6
|
export {
|
|
10
7
|
InteractionDefinition,
|
|
@@ -15,144 +12,6 @@ export {
|
|
|
15
12
|
modalSubmit,
|
|
16
13
|
} from "./definitions.js"
|
|
17
14
|
|
|
18
|
-
type ExtractTag<A> = A extends { _tag: infer Tag }
|
|
19
|
-
? Tag extends string
|
|
20
|
-
? Tag
|
|
21
|
-
: never
|
|
22
|
-
: never
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @tsplus type dfx/InteractionBuilder
|
|
26
|
-
*/
|
|
27
|
-
export class InteractionBuilder<R, E> {
|
|
28
|
-
constructor(
|
|
29
|
-
readonly definitions: D.InteractionDefinition<R, E>[],
|
|
30
|
-
readonly transform: (self: Effect<any, any, any>) => Effect<R, E, void>,
|
|
31
|
-
readonly transformRespond: (
|
|
32
|
-
self: Effect<any, any, Discord.InteractionResponse>,
|
|
33
|
-
) => Effect<R, E, Discord.InteractionResponse>,
|
|
34
|
-
) {}
|
|
35
|
-
|
|
36
|
-
add<R1, E1>(definition: D.InteractionDefinition<R1, E1>) {
|
|
37
|
-
return new InteractionBuilder<R | R1, E | E1>(
|
|
38
|
-
[...this.definitions, definition],
|
|
39
|
-
this.transform,
|
|
40
|
-
this.transformRespond,
|
|
41
|
-
)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
concat<R1, E1>(builder: InteractionBuilder<R1, E1>) {
|
|
45
|
-
return new InteractionBuilder<R | R1, E | E1>(
|
|
46
|
-
[...this.definitions, ...builder.definitions],
|
|
47
|
-
this.transform,
|
|
48
|
-
this.transformRespond,
|
|
49
|
-
)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
catchAllCause<R1, E1>(f: (cause: Cause<E>) => Effect<R1, E1, void>) {
|
|
53
|
-
return new InteractionBuilder<R | R1, E1>(
|
|
54
|
-
this.definitions as any,
|
|
55
|
-
_ => this.transform(_).catchAllCause(f),
|
|
56
|
-
this.transformRespond as any,
|
|
57
|
-
)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
catchAllCauseRespond<R1, E1>(
|
|
61
|
-
f: (cause: Cause<E>) => Effect<R1, E1, Discord.InteractionResponse>,
|
|
62
|
-
) {
|
|
63
|
-
return new InteractionBuilder<R | R1, E1>(
|
|
64
|
-
this.definitions as any,
|
|
65
|
-
this.transform as any,
|
|
66
|
-
_ => this.transformRespond(_).catchAllCause(f),
|
|
67
|
-
)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
catchAll<R1, E1>(f: (error: E) => Effect<R1, E1, void>) {
|
|
71
|
-
return new InteractionBuilder<R | R1, E1>(
|
|
72
|
-
this.definitions as any,
|
|
73
|
-
_ => this.transform(_).catchAll(f),
|
|
74
|
-
this.transformRespond as any,
|
|
75
|
-
)
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
catchAllRespond<R1, E1>(
|
|
79
|
-
f: (error: E) => Effect<R1, E1, Discord.InteractionResponse>,
|
|
80
|
-
) {
|
|
81
|
-
return new InteractionBuilder<R | R1, E1>(
|
|
82
|
-
this.definitions as any,
|
|
83
|
-
this.transform as any,
|
|
84
|
-
_ => this.transformRespond(_).catchAll(f),
|
|
85
|
-
)
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
catchTag<T extends ExtractTag<E>, R1, E1>(
|
|
89
|
-
tag: T,
|
|
90
|
-
f: (error: Extract<E, { _tag: T }>) => Effect<R1, E1, void>,
|
|
91
|
-
) {
|
|
92
|
-
return new InteractionBuilder<R | R1, Exclude<E, { _tag: T }> | E1>(
|
|
93
|
-
this.definitions as any,
|
|
94
|
-
_ => catchTag(this.transform(_) as any, tag, f as any) as any,
|
|
95
|
-
this.transformRespond as any,
|
|
96
|
-
)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
catchTagRespond<T extends ExtractTag<E>, R1, E1>(
|
|
100
|
-
tag: T,
|
|
101
|
-
f: (
|
|
102
|
-
error: Extract<E, { _tag: T }>,
|
|
103
|
-
) => Effect<R1, E1, Discord.InteractionResponse>,
|
|
104
|
-
) {
|
|
105
|
-
return new InteractionBuilder<R | R1, Exclude<E, { _tag: T }> | E1>(
|
|
106
|
-
this.definitions as any,
|
|
107
|
-
this.transform as any,
|
|
108
|
-
_ => catchTag(this.transformRespond(_) as any, tag, f as any) as any,
|
|
109
|
-
)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
get syncGlobal() {
|
|
113
|
-
const commands = this.definitions
|
|
114
|
-
.filter(
|
|
115
|
-
(c): c is D.GlobalApplicationCommand<R, E> =>
|
|
116
|
-
c._tag === "GlobalApplicationCommand",
|
|
117
|
-
)
|
|
118
|
-
.map(c => c.command)
|
|
119
|
-
|
|
120
|
-
return DiscordREST.flatMap(rest =>
|
|
121
|
-
rest
|
|
122
|
-
.getCurrentBotApplicationInformation()
|
|
123
|
-
.flatMap(r => r.json)
|
|
124
|
-
.flatMap(app =>
|
|
125
|
-
rest.bulkOverwriteGlobalApplicationCommands(app.id, {
|
|
126
|
-
body: Http.body.json(commands),
|
|
127
|
-
}),
|
|
128
|
-
),
|
|
129
|
-
)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
syncGuild(appId: Discord.Snowflake, guildId: Discord.Snowflake) {
|
|
133
|
-
const commands = this.definitions
|
|
134
|
-
.filter(
|
|
135
|
-
(c): c is D.GuildApplicationCommand<R, E> =>
|
|
136
|
-
c._tag === "GuildApplicationCommand",
|
|
137
|
-
)
|
|
138
|
-
.map(c => c.command)
|
|
139
|
-
|
|
140
|
-
return DiscordREST.flatMap(rest =>
|
|
141
|
-
rest.bulkOverwriteGuildApplicationCommands(
|
|
142
|
-
appId,
|
|
143
|
-
guildId,
|
|
144
|
-
commands as any,
|
|
145
|
-
),
|
|
146
|
-
)
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export const builder = new InteractionBuilder<never, never>(
|
|
151
|
-
[],
|
|
152
|
-
identity as any,
|
|
153
|
-
identity as any,
|
|
154
|
-
)
|
|
155
|
-
|
|
156
15
|
// Filters
|
|
157
16
|
export const id = (query: string) => (customId: string) =>
|
|
158
17
|
Effect.succeed(query === customId)
|
|
@@ -1,39 +1,82 @@
|
|
|
1
1
|
import * as D from "./definitions.js"
|
|
2
|
+
import * as Ctx from "./context.js"
|
|
2
3
|
|
|
3
|
-
export
|
|
4
|
-
|
|
4
|
+
export type DefinitionFlattened<R, E, TE, A> = D.InteractionDefinition<
|
|
5
|
+
R,
|
|
6
|
+
E
|
|
7
|
+
> extends infer D
|
|
8
|
+
? {
|
|
9
|
+
[K in keyof D]: K extends "handle"
|
|
10
|
+
? (_: Discord.Interaction) => Effect<R, TE, A>
|
|
11
|
+
: D[K]
|
|
12
|
+
}
|
|
13
|
+
: never
|
|
14
|
+
|
|
15
|
+
export type DefinitionFlattenedCommand<R, E, TE, A> = Extract<
|
|
16
|
+
DefinitionFlattened<R, E, TE, A>,
|
|
17
|
+
{ _tag: "GlobalApplicationCommand" | "GuildApplicationCommand" }
|
|
18
|
+
>
|
|
19
|
+
|
|
20
|
+
const context: D.CommandHelper<any> = {
|
|
21
|
+
resolve: Ctx.resolved,
|
|
22
|
+
option: Ctx.option,
|
|
23
|
+
optionValue: Ctx.optionValue,
|
|
24
|
+
optionValueOptional: Ctx.optionValueOptional,
|
|
25
|
+
subCommands: Ctx.handleSubCommands,
|
|
26
|
+
} as any
|
|
27
|
+
|
|
28
|
+
export const flattenDefinitions = <R, E, TE, A, B>(
|
|
29
|
+
definitions: Chunk<
|
|
30
|
+
readonly [
|
|
31
|
+
handler: D.InteractionDefinition<R, E>,
|
|
32
|
+
transform: (self: Effect<R, E, A>) => Effect<R, TE, B>,
|
|
33
|
+
]
|
|
34
|
+
>,
|
|
35
|
+
handleResponse: (
|
|
36
|
+
ix: Discord.Interaction,
|
|
37
|
+
_: Discord.InteractionResponse,
|
|
38
|
+
) => Effect<R, E, A>,
|
|
39
|
+
) =>
|
|
40
|
+
definitions.map(([definition, transform]) => ({
|
|
41
|
+
...definition,
|
|
42
|
+
handle: (i: Discord.Interaction) =>
|
|
43
|
+
Effect.isEffect(definition.handle)
|
|
44
|
+
? transform(definition.handle.flatMap(_ => handleResponse(i, _)))
|
|
45
|
+
: transform(
|
|
46
|
+
definition.handle(context).flatMap(_ => handleResponse(i, _)),
|
|
47
|
+
),
|
|
48
|
+
}))
|
|
49
|
+
|
|
50
|
+
export const splitDefinitions = <R, E, TE, A>(
|
|
51
|
+
definitions: Chunk<DefinitionFlattened<R, E, TE, A>>,
|
|
5
52
|
) => {
|
|
6
|
-
const grouped = definitions.reduce
|
|
7
|
-
[K in D.InteractionDefinition<R, E>["_tag"]]: Extract<
|
|
8
|
-
D.InteractionDefinition<R, E>,
|
|
9
|
-
{ _tag: K }
|
|
10
|
-
>[]
|
|
11
|
-
}>(
|
|
12
|
-
(acc, a) => ({
|
|
13
|
-
...acc,
|
|
14
|
-
[a._tag]: [...(acc[a._tag] ?? []), a],
|
|
15
|
-
}),
|
|
53
|
+
const grouped = definitions.reduce(
|
|
16
54
|
{
|
|
17
|
-
Autocomplete:
|
|
18
|
-
GlobalApplicationCommand:
|
|
19
|
-
GuildApplicationCommand:
|
|
20
|
-
MessageComponent:
|
|
21
|
-
ModalSubmit:
|
|
55
|
+
Autocomplete: Chunk.empty(),
|
|
56
|
+
GlobalApplicationCommand: Chunk.empty(),
|
|
57
|
+
GuildApplicationCommand: Chunk.empty(),
|
|
58
|
+
MessageComponent: Chunk.empty(),
|
|
59
|
+
ModalSubmit: Chunk.empty(),
|
|
60
|
+
} as {
|
|
61
|
+
[K in D.InteractionDefinition<R, E>["_tag"]]: Chunk<
|
|
62
|
+
Extract<DefinitionFlattened<R, E, TE, A>, { _tag: K }>
|
|
63
|
+
>
|
|
22
64
|
},
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const Commands = [
|
|
26
|
-
...grouped.GlobalApplicationCommand,
|
|
27
|
-
...grouped.GuildApplicationCommand,
|
|
28
|
-
].reduce(
|
|
29
|
-
(acc, a) => ({
|
|
65
|
+
(acc, d) => ({
|
|
30
66
|
...acc,
|
|
31
|
-
[
|
|
67
|
+
[d._tag]: (acc[d._tag] as Chunk<any>).append(d),
|
|
32
68
|
}),
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
const Commands = grouped.GlobalApplicationCommand.concat(
|
|
72
|
+
grouped.GuildApplicationCommand,
|
|
73
|
+
).reduce(
|
|
74
|
+
{} as Record<string, DefinitionFlattenedCommand<R, E, TE, A>>,
|
|
75
|
+
(acc, d) =>
|
|
76
|
+
({
|
|
77
|
+
...acc,
|
|
78
|
+
[d.command.name]: d,
|
|
79
|
+
} as any),
|
|
37
80
|
)
|
|
38
81
|
|
|
39
82
|
return {
|
|
@@ -62,8 +62,21 @@ const fromHeadersAndBody = (headers: Headers, body: string) =>
|
|
|
62
62
|
)
|
|
63
63
|
})
|
|
64
64
|
|
|
65
|
-
const run = <R, E>(
|
|
66
|
-
|
|
65
|
+
const run = <R, E>(
|
|
66
|
+
definitions: Chunk<
|
|
67
|
+
readonly [
|
|
68
|
+
handler: D.InteractionDefinition<R, E>,
|
|
69
|
+
transform: (
|
|
70
|
+
self: Effect<R, E, Discord.InteractionResponse>,
|
|
71
|
+
) => Effect<R, E, Discord.InteractionResponse>,
|
|
72
|
+
]
|
|
73
|
+
>,
|
|
74
|
+
handleResponse: (
|
|
75
|
+
ix: Discord.Interaction,
|
|
76
|
+
_: Discord.InteractionResponse,
|
|
77
|
+
) => Effect<R, E, Discord.InteractionResponse>,
|
|
78
|
+
) => {
|
|
79
|
+
const handler = handlers(definitions, handleResponse)
|
|
67
80
|
return (headers: Headers, body: string) =>
|
|
68
81
|
Do($ => {
|
|
69
82
|
const interaction = $(fromHeadersAndBody(headers, body))
|
|
@@ -86,8 +99,11 @@ export interface HandleWebhookOpts<E> {
|
|
|
86
99
|
/**
|
|
87
100
|
* @tsplus getter dfx/InteractionBuilder webhookHandler
|
|
88
101
|
*/
|
|
89
|
-
export const makeHandler = <R, E>(ix: InteractionBuilder<R, E>) => {
|
|
90
|
-
const handle = run(
|
|
102
|
+
export const makeHandler = <R, E, TE>(ix: InteractionBuilder<R, E, TE>) => {
|
|
103
|
+
const handle = run(
|
|
104
|
+
ix.definitions.map(([d]) => [d, identity] as any),
|
|
105
|
+
(_i, r) => Effect.succeed(r),
|
|
106
|
+
)
|
|
91
107
|
|
|
92
108
|
return ({
|
|
93
109
|
headers,
|
|
@@ -96,17 +112,19 @@ export const makeHandler = <R, E>(ix: InteractionBuilder<R, E>) => {
|
|
|
96
112
|
error,
|
|
97
113
|
}: HandleWebhookOpts<
|
|
98
114
|
E | WebhookParseError | BadWebhookSignature | DefinitionNotFound
|
|
99
|
-
>) =>
|
|
100
|
-
ix
|
|
101
|
-
.transform(ix.transformRespond(handle(headers, body)).flatMap(success))
|
|
102
|
-
.catchAllCause(error)
|
|
115
|
+
>) => handle(headers, body).flatMap(success).catchAllCause(error)
|
|
103
116
|
}
|
|
104
117
|
|
|
105
118
|
/**
|
|
106
119
|
* @tsplus getter dfx/InteractionBuilder simpleWebhookHandler
|
|
107
120
|
*/
|
|
108
|
-
export const makeSimpleHandler = <R, E
|
|
109
|
-
|
|
121
|
+
export const makeSimpleHandler = <R, E, TE>(
|
|
122
|
+
ix: InteractionBuilder<R, E, TE>,
|
|
123
|
+
) => {
|
|
124
|
+
const handle = run(
|
|
125
|
+
ix.definitions.map(([d]) => [d, identity] as any),
|
|
126
|
+
(_i, r) => Effect.succeed(r),
|
|
127
|
+
)
|
|
110
128
|
|
|
111
129
|
return ({ headers, body }: { headers: Headers; body: string }) =>
|
|
112
130
|
handle(headers, body)
|