dfx 0.43.1 → 0.45.0
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 +8 -2
- package/Interactions/gateway.js +21 -9
- 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 +2 -17
- package/Interactions/index.js +1 -40
- 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 +5 -4
- package/Interactions/webhook.js.map +1 -1
- package/gateway.d.ts +1 -1
- package/gateway.js +1 -1
- package/gateway.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 +65 -16
- package/src/Interactions/handlers.ts +59 -80
- package/src/Interactions/index.ts +2 -65
- package/src/Interactions/utils.ts +72 -29
- package/src/Interactions/webhook.ts +27 -6
- package/src/gateway.ts +5 -1
- package/src/package.json +2 -2
package/Interactions/webhook.js
CHANGED
|
@@ -5,6 +5,7 @@ import * as tsplus_module_4 from "dfx/_common";
|
|
|
5
5
|
import * as tsplus_module_5 from "@effect/io/Layer";
|
|
6
6
|
import * as tsplus_module_6 from "@effect/data/Function";
|
|
7
7
|
import * as tsplus_module_7 from "@effect/io/Effect";
|
|
8
|
+
import * as tsplus_module_8 from "@effect/data/Chunk";
|
|
8
9
|
import Nacl from "tweetnacl";
|
|
9
10
|
import { handlers } from "./handlers.js";
|
|
10
11
|
import { Interaction } from "./index.js";
|
|
@@ -34,22 +35,22 @@ export class WebhookParseError {
|
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
const fromHeadersAndBody = (headers, body) => tsplus_module_7.flatMap(WebhookConfig, ({ publicKey }) => tsplus_module_7.flatMap(checkSignature(publicKey, headers, body), () => tsplus_module_7.tryCatch(() => JSON.parse(body), reason => new WebhookParseError(reason))));
|
|
37
|
-
const run = (definitions) => {
|
|
38
|
-
const handler = handlers(definitions);
|
|
38
|
+
const run = (definitions, handleResponse) => {
|
|
39
|
+
const handler = handlers(definitions, handleResponse);
|
|
39
40
|
return (headers, body) => tsplus_module_7.flatMap(fromHeadersAndBody(headers, body), interaction => tsplus_module_7.provideService(handler[interaction.type](interaction), Interaction, interaction));
|
|
40
41
|
};
|
|
41
42
|
/**
|
|
42
43
|
* @tsplus getter dfx/InteractionBuilder webhookHandler
|
|
43
44
|
*/
|
|
44
45
|
export const makeHandler = (ix) => {
|
|
45
|
-
const handle = run(ix.definitions);
|
|
46
|
+
const handle = run(tsplus_module_8.map(ix.definitions, ([d]) => [d, tsplus_module_6.identity]), (_i, r) => tsplus_module_7.succeed(r));
|
|
46
47
|
return ({ headers, body, success, error, }) => tsplus_module_7.catchAllCause(tsplus_module_7.flatMap(handle(headers, body), success), error);
|
|
47
48
|
};
|
|
48
49
|
/**
|
|
49
50
|
* @tsplus getter dfx/InteractionBuilder simpleWebhookHandler
|
|
50
51
|
*/
|
|
51
52
|
export const makeSimpleHandler = (ix) => {
|
|
52
|
-
const handle = run(ix.definitions);
|
|
53
|
+
const handle = run(tsplus_module_8.map(ix.definitions, ([d]) => [d, tsplus_module_6.identity]), (_i, r) => tsplus_module_7.succeed(r));
|
|
53
54
|
return ({ headers, body }) => handle(headers, body);
|
|
54
55
|
};
|
|
55
56
|
//# sourceMappingURL=webhook.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhook.js","sourceRoot":"","sources":["../src/Interactions/webhook.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"webhook.js","sourceRoot":"","sources":["../src/Interactions/webhook.ts"],"names":[],"mappings":"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"}
|
package/gateway.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export * as DiscordWS from "./DiscordGateway/DiscordWS.js";
|
|
|
6
6
|
export * as Shard from "./DiscordGateway/Shard.js";
|
|
7
7
|
export * as ShardStore from "./DiscordGateway/ShardStore.js";
|
|
8
8
|
export * as WS from "./DiscordGateway/WS.js";
|
|
9
|
-
export { run as runIx } from "./Interactions/gateway.js";
|
|
9
|
+
export { InteractionsRegistry, InteractionsRegistryLive, run as runIx, } from "./Interactions/gateway.js";
|
|
10
10
|
export declare const MemoryRateLimit: import("@effect-http/client/_common").Layer<Log.Log, never, import("dfx").RateLimiter>;
|
|
11
11
|
export declare const MemoryBot: import("@effect-http/client/_common").Layer<DiscordConfig.DiscordConfig | Log.Log | import("@effect-http/client").HttpRequestExecutor, never, import("dfx").DiscordREST | import("dfx").RateLimiter | import("./DiscordGateway.js").DiscordGateway>;
|
|
12
12
|
export declare const makeLiveWithoutFetch: (config: Config.Wrap<DiscordConfig.MakeOpts>) => import("@effect-http/client/_common").Layer<import("@effect-http/client").HttpRequestExecutor, import("./_common.js").ConfigError, import("dfx").DiscordREST | DiscordConfig.DiscordConfig | Log.Log | import("dfx").RateLimiter | import("./DiscordGateway.js").DiscordGateway>;
|
package/gateway.js
CHANGED
|
@@ -13,7 +13,7 @@ export * as DiscordWS from "./DiscordGateway/DiscordWS.js";
|
|
|
13
13
|
export * as Shard from "./DiscordGateway/Shard.js";
|
|
14
14
|
export * as ShardStore from "./DiscordGateway/ShardStore.js";
|
|
15
15
|
export * as WS from "./DiscordGateway/WS.js";
|
|
16
|
-
export { run as runIx } from "./Interactions/gateway.js";
|
|
16
|
+
export { InteractionsRegistry, InteractionsRegistryLive, run as runIx, } from "./Interactions/gateway.js";
|
|
17
17
|
export const MemoryRateLimit = tsplus_module_1.provide(LiveRateLimiter)(LiveMemoryRateLimitStore);
|
|
18
18
|
export const MemoryBot = tsplus_module_1.provide((tsplus_module_1.merge(MemoryRateLimit)((tsplus_module_1.provideMerge(LiveDiscordGateway)(LiveDiscordREST)))))((tsplus_module_1.merge(LiveJsonDiscordWSCodec)(tsplus_module_1.merge(LiveMemoryRateLimitStore)(LiveMemoryShardStore))));
|
|
19
19
|
export const makeLiveWithoutFetch = (config) => tsplus_module_1.unwrapEffect(tsplus_module_3.map(tsplus_module_3.map(tsplus_module_3.config(tsplus_module_2.unwrap(config)), DiscordConfig.make), config => {
|
package/gateway.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway.js","sourceRoot":"","sources":["src/gateway.ts"],"names":[],"mappings":";;;AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAA;AACrE,OAAO,EAAE,wBAAwB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAE1E,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxE,OAAO,KAAK,SAAS,MAAM,+BAA+B,CAAA;AAC1D,OAAO,KAAK,KAAK,MAAM,2BAA2B,CAAA;AAClD,OAAO,KAAK,UAAU,MAAM,gCAAgC,CAAA;AAC5D,OAAO,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAC5C,OAAO,
|
|
1
|
+
{"version":3,"file":"gateway.js","sourceRoot":"","sources":["src/gateway.ts"],"names":[],"mappings":";;;AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAA;AACrE,OAAO,EAAE,wBAAwB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAE1E,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxE,OAAO,KAAK,SAAS,MAAM,+BAA+B,CAAA;AAC1D,OAAO,KAAK,KAAK,MAAM,2BAA2B,CAAA;AAClD,OAAO,KAAK,UAAU,MAAM,gCAAgC,CAAA;AAC5D,OAAO,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAC5C,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,GAAG,IAAI,KAAK,GACb,MAAM,2BAA2B,CAAA;AAElC,MAAM,CAAC,MAAM,eAAe,2BAA+B,eAAe,EAA3C,wBAAwB,CAAmB,CAAA;AAE1E,MAAM,CAAC,MAAM,SAAS,2BAEpB,uBAA0C,eAAe,EAAxD,8BAAmB,kBAAkB,EAApC,eAAe,EAAsB,EAAmB,EAD1D,uBAAmD,sBAAsB,wBAAjD,wBAAwB,EAA/C,oBAAoB,GAAqD,CAChB,CAAA;AAE5D,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,MAA2C,EAC3C,EAAE,CACF,6BACE,oBAAA,2CAAA,uBAAc,MAAM,CAAC,GACP,aAAa,CAAC,IAAI,CAAC,EAC1B,MAAM,CAAC,EAAE;IACZ,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAA;IAC7D,MAAM,UAAU,GAAG,wBAAc,aAAa,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;IACrE,oCAA8B,SAAS,wBAAtB,UAAU,EAApB,OAAO,GAAyB;AACzC,CAAC,CAAC,CACL,CAAA;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,MAA2C,EAAE,EAAE,yBAC1C,oBAAoB,CAAC,MAAM,CAAC,EAAxD,wBAAwB,CAAgC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dfx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.45.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
"ws": "^8.13.0"
|
|
49
49
|
},
|
|
50
50
|
"sideEffects": false,
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "1120664f76fc34a00312d277c22007b37d623a30"
|
|
52
52
|
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import * as Http from "@effect-http/client"
|
|
2
|
+
import { catchTag } from "@effect/io/Effect"
|
|
3
|
+
import { DiscordREST } from "dfx"
|
|
4
|
+
import { Discord, Effect } from "dfx/_common"
|
|
5
|
+
import * as D from "./definitions.js"
|
|
6
|
+
|
|
7
|
+
type ExtractTag<A> = A extends { _tag: infer Tag }
|
|
8
|
+
? Tag extends string
|
|
9
|
+
? Tag
|
|
10
|
+
: never
|
|
11
|
+
: never
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @tsplus type dfx/InteractionBuilder
|
|
15
|
+
*/
|
|
16
|
+
export class InteractionBuilder<R, E, TE> {
|
|
17
|
+
constructor(
|
|
18
|
+
readonly definitions: Chunk<
|
|
19
|
+
readonly [
|
|
20
|
+
handler: D.InteractionDefinition<R, E>,
|
|
21
|
+
transform: (self: Effect<any, any, any>) => Effect<R, TE, void>,
|
|
22
|
+
]
|
|
23
|
+
>,
|
|
24
|
+
readonly transform: (self: Effect<any, any, any>) => Effect<R, TE, void>,
|
|
25
|
+
) {}
|
|
26
|
+
|
|
27
|
+
add<R1, E1>(definition: D.InteractionDefinition<R1, E1>) {
|
|
28
|
+
return new InteractionBuilder<R | R1, E | E1, TE | E1>(
|
|
29
|
+
this.definitions.append([definition, this.transform] as const),
|
|
30
|
+
this.transform,
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
concat<R1, E1, TE1>(builder: InteractionBuilder<R1, E1, TE1>) {
|
|
35
|
+
return new InteractionBuilder<R | R1, E | E1, TE | TE1>(
|
|
36
|
+
this.definitions.concat(builder.definitions),
|
|
37
|
+
this.transform,
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private transformTransform<R1, E1>(
|
|
42
|
+
f: (selr: Effect<R, TE, void>) => Effect<R1, E1, void>,
|
|
43
|
+
) {
|
|
44
|
+
return new InteractionBuilder<R1, E, E1>(
|
|
45
|
+
this.definitions.map(([d, t]) => [d as any, _ => f(t(_)) as any]),
|
|
46
|
+
_ => f(this.transform(_)) as any,
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private transformHandlers<R1, E1>(
|
|
51
|
+
f: (
|
|
52
|
+
selr: Effect<R, E, Discord.InteractionResponse>,
|
|
53
|
+
) => Effect<R1, E1, Discord.InteractionResponse>,
|
|
54
|
+
) {
|
|
55
|
+
return new InteractionBuilder<
|
|
56
|
+
R1,
|
|
57
|
+
E1,
|
|
58
|
+
Exclude<TE, Exclude<E, E1>> | Exclude<E1, E>
|
|
59
|
+
>(
|
|
60
|
+
this.definitions.map(([d, t]) => [
|
|
61
|
+
{
|
|
62
|
+
...d,
|
|
63
|
+
handle: Effect.isEffect(d.handle)
|
|
64
|
+
? f(d.handle)
|
|
65
|
+
: (_: any) => f((d.handle as any)(_)),
|
|
66
|
+
} as any,
|
|
67
|
+
t as any,
|
|
68
|
+
]),
|
|
69
|
+
this.transform as any,
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
catchAllCause<R1, E1>(f: (cause: Cause<TE>) => Effect<R1, E1, void>) {
|
|
74
|
+
return this.transformTransform<R | R1, E1>(_ => _.catchAllCause(f))
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
catchAllCauseRespond<R1, E1>(
|
|
78
|
+
f: (cause: Cause<E>) => Effect<R1, E1, Discord.InteractionResponse>,
|
|
79
|
+
) {
|
|
80
|
+
return this.transformHandlers<R | R1, E1>(_ => _.catchAllCause(f))
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
catchAll<R1, E1>(f: (error: TE) => Effect<R1, E1, void>) {
|
|
84
|
+
return this.transformTransform<R | R1, E1>(_ => _.catchAll(f))
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
catchAllRespond<R1, E1>(
|
|
88
|
+
f: (error: E) => Effect<R1, E1, Discord.InteractionResponse>,
|
|
89
|
+
) {
|
|
90
|
+
return this.transformHandlers<R | R1, E1>(_ => _.catchAll(f))
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
catchTag<T extends ExtractTag<E>, R1, E1>(
|
|
94
|
+
tag: T,
|
|
95
|
+
f: (error: Extract<TE, { _tag: T }>) => Effect<R1, E1, void>,
|
|
96
|
+
) {
|
|
97
|
+
return this.transformTransform<R | R1, Exclude<TE, { _tag: T }> | E1>(
|
|
98
|
+
_ => catchTag(_ as any, tag, f as any) as any,
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
catchTagRespond<T extends ExtractTag<E>, R1, E1>(
|
|
103
|
+
tag: T,
|
|
104
|
+
f: (
|
|
105
|
+
error: Extract<E, { _tag: T }>,
|
|
106
|
+
) => Effect<R1, E1, Discord.InteractionResponse>,
|
|
107
|
+
) {
|
|
108
|
+
return this.transformHandlers<R | R1, Exclude<E, { _tag: T }> | E1>(
|
|
109
|
+
_ => catchTag(_ as any, tag, f as any) as any,
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
get syncGlobal() {
|
|
114
|
+
const commands = this.definitions
|
|
115
|
+
.map(([d, _]) => d)
|
|
116
|
+
.filter(
|
|
117
|
+
(c): c is D.GlobalApplicationCommand<R, E> =>
|
|
118
|
+
c._tag === "GlobalApplicationCommand",
|
|
119
|
+
)
|
|
120
|
+
.map(c => c.command)
|
|
121
|
+
|
|
122
|
+
return DiscordREST.flatMap(rest =>
|
|
123
|
+
rest
|
|
124
|
+
.getCurrentBotApplicationInformation()
|
|
125
|
+
.flatMap(r => r.json)
|
|
126
|
+
.flatMap(app =>
|
|
127
|
+
rest.bulkOverwriteGlobalApplicationCommands(app.id, {
|
|
128
|
+
body: Http.body.json(commands),
|
|
129
|
+
}),
|
|
130
|
+
),
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
syncGuild(appId: Discord.Snowflake, guildId: Discord.Snowflake) {
|
|
135
|
+
const commands = this.definitions
|
|
136
|
+
.map(([d, _]) => d)
|
|
137
|
+
.filter(
|
|
138
|
+
(c): c is D.GuildApplicationCommand<R, E> =>
|
|
139
|
+
c._tag === "GuildApplicationCommand",
|
|
140
|
+
)
|
|
141
|
+
.map(c => c.command)
|
|
142
|
+
|
|
143
|
+
return DiscordREST.flatMap(rest =>
|
|
144
|
+
rest.bulkOverwriteGuildApplicationCommands(
|
|
145
|
+
appId,
|
|
146
|
+
guildId,
|
|
147
|
+
commands as any,
|
|
148
|
+
),
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export const builder = new InteractionBuilder<never, never, never>(
|
|
154
|
+
Chunk.empty(),
|
|
155
|
+
identity as any,
|
|
156
|
+
)
|
|
@@ -143,7 +143,7 @@ type DeepReadonlyObject<T> = {
|
|
|
143
143
|
readonly [P in keyof T]: DeepReadonly<T[P]>
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
type CommandHandler<R, E, A = any> =
|
|
146
|
+
export type CommandHandler<R, E, A = any> =
|
|
147
147
|
| Effect<R, E, Discord.InteractionResponse>
|
|
148
148
|
| CommandHandlerFn<R, E, A>
|
|
149
149
|
|
|
@@ -196,7 +196,7 @@ export interface CommandHelper<A> {
|
|
|
196
196
|
>
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
type CommandHandlerFn<R, E, A> = (
|
|
199
|
+
export type CommandHandlerFn<R, E, A> = (
|
|
200
200
|
i: CommandHelper<A>,
|
|
201
201
|
) => Effect<R, E, Discord.InteractionResponse>
|
|
202
202
|
|
|
@@ -2,8 +2,11 @@ import * as Http from "@effect-http/client"
|
|
|
2
2
|
import { DiscordGateway } from "dfx/DiscordGateway"
|
|
3
3
|
import { DiscordREST, DiscordRESTError } from "dfx/DiscordREST"
|
|
4
4
|
import { DefinitionNotFound, handlers } from "./handlers.js"
|
|
5
|
-
import { Interaction, InteractionBuilder } from "./index.js"
|
|
6
|
-
import {
|
|
5
|
+
import { Interaction, InteractionBuilder, builder } from "./index.js"
|
|
6
|
+
import type {
|
|
7
|
+
GlobalApplicationCommand,
|
|
8
|
+
GuildApplicationCommand,
|
|
9
|
+
} from "./definitions.js"
|
|
7
10
|
|
|
8
11
|
export interface RunOpts {
|
|
9
12
|
sync?: boolean
|
|
@@ -13,26 +16,36 @@ export interface RunOpts {
|
|
|
13
16
|
* @tsplus pipeable dfx/InteractionBuilder runGateway
|
|
14
17
|
*/
|
|
15
18
|
export const run =
|
|
16
|
-
<R, R2, E, E2>(
|
|
19
|
+
<R, R2, E, TE, E2>(
|
|
17
20
|
postHandler: (
|
|
18
21
|
effect: Effect<
|
|
19
22
|
R | DiscordREST | Discord.Interaction,
|
|
20
|
-
|
|
23
|
+
TE | DiscordRESTError | DefinitionNotFound,
|
|
21
24
|
void
|
|
22
25
|
>,
|
|
23
26
|
) => Effect<R2, E2, void>,
|
|
24
27
|
{ sync = true }: RunOpts = {},
|
|
25
28
|
) =>
|
|
26
29
|
(
|
|
27
|
-
ix: InteractionBuilder<R, E>,
|
|
30
|
+
ix: InteractionBuilder<R, E, TE>,
|
|
28
31
|
): Effect<
|
|
29
32
|
DiscordREST | DiscordGateway | Exclude<R2, Discord.Interaction>,
|
|
30
33
|
E2 | DiscordRESTError | Http.ResponseDecodeError,
|
|
31
34
|
never
|
|
32
35
|
> =>
|
|
33
36
|
Do($ => {
|
|
34
|
-
const
|
|
35
|
-
|
|
37
|
+
const GlobalApplicationCommand = ix.definitions
|
|
38
|
+
.map(_ => _[0])
|
|
39
|
+
.filter(
|
|
40
|
+
(_): _ is GlobalApplicationCommand<R, E> =>
|
|
41
|
+
_._tag === "GlobalApplicationCommand",
|
|
42
|
+
).toReadonlyArray
|
|
43
|
+
const GuildApplicationCommand = ix.definitions
|
|
44
|
+
.map(_ => _[0])
|
|
45
|
+
.filter(
|
|
46
|
+
(_): _ is GuildApplicationCommand<R, E> =>
|
|
47
|
+
_._tag === "GuildApplicationCommand",
|
|
48
|
+
).toReadonlyArray
|
|
36
49
|
|
|
37
50
|
const gateway = $(DiscordGateway)
|
|
38
51
|
const rest = $(DiscordREST)
|
|
@@ -43,7 +56,9 @@ export const run =
|
|
|
43
56
|
|
|
44
57
|
const globalSync = rest.bulkOverwriteGlobalApplicationCommands(
|
|
45
58
|
application.id,
|
|
46
|
-
{
|
|
59
|
+
{
|
|
60
|
+
body: Http.body.json(GlobalApplicationCommand.map(_ => _.command)),
|
|
61
|
+
},
|
|
47
62
|
)
|
|
48
63
|
|
|
49
64
|
const guildSync = GuildApplicationCommand.length
|
|
@@ -51,21 +66,55 @@ export const run =
|
|
|
51
66
|
rest.bulkOverwriteGuildApplicationCommands(
|
|
52
67
|
application.id,
|
|
53
68
|
a.id,
|
|
54
|
-
GuildApplicationCommand.map(
|
|
69
|
+
GuildApplicationCommand.map(_ => _.command) as any,
|
|
55
70
|
),
|
|
56
71
|
)
|
|
57
72
|
: Effect.never()
|
|
58
73
|
|
|
59
|
-
const handle = handlers(ix.definitions)
|
|
74
|
+
const handle = handlers(ix.definitions, (i, r) =>
|
|
75
|
+
rest.createInteractionResponse(i.id, i.token, r),
|
|
76
|
+
)
|
|
60
77
|
|
|
61
78
|
const run = gateway.handleDispatch("INTERACTION_CREATE", i =>
|
|
62
|
-
|
|
63
|
-
handle[i.type](i).tap(r =>
|
|
64
|
-
rest.createInteractionResponse(i.id, i.token, r),
|
|
65
|
-
),
|
|
66
|
-
postHandler,
|
|
67
|
-
).provideService(Interaction, i),
|
|
79
|
+
postHandler(handle[i.type](i)).provideService(Interaction, i),
|
|
68
80
|
)
|
|
69
81
|
|
|
70
82
|
return $(sync ? run.zipParRight(globalSync).zipParRight(guildSync) : run)
|
|
71
83
|
})
|
|
84
|
+
|
|
85
|
+
const makeRegistry = Do($ => {
|
|
86
|
+
const ref = $(Ref.make(builder))
|
|
87
|
+
|
|
88
|
+
const register = <E>(ix: InteractionBuilder<never, E, never>) =>
|
|
89
|
+
ref.update(_ => _.concat(ix as any))
|
|
90
|
+
|
|
91
|
+
const run = <R, E>(
|
|
92
|
+
onError: (
|
|
93
|
+
_: Cause<DiscordRESTError | DefinitionNotFound>,
|
|
94
|
+
) => Effect<R, E, void>,
|
|
95
|
+
opts?: RunOpts,
|
|
96
|
+
) => ref.get.flatMap(_ => _.runGateway(_ => _.catchAllCause(onError), opts))
|
|
97
|
+
|
|
98
|
+
return { register, run } as const
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
export interface InteractionsRegistry {
|
|
102
|
+
readonly register: <E>(
|
|
103
|
+
ix: InteractionBuilder<never, E, never>,
|
|
104
|
+
) => Effect<never, never, void>
|
|
105
|
+
|
|
106
|
+
readonly run: <R, E>(
|
|
107
|
+
onError: (
|
|
108
|
+
_: Cause<DiscordRESTError | DefinitionNotFound>,
|
|
109
|
+
) => Effect<R, E, void>,
|
|
110
|
+
opts?: RunOpts,
|
|
111
|
+
) => Effect<
|
|
112
|
+
DiscordREST | DiscordGateway | Exclude<R, Discord.Interaction>,
|
|
113
|
+
DiscordRESTError | Http.ResponseDecodeError | E,
|
|
114
|
+
never
|
|
115
|
+
>
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export const InteractionsRegistry = Tag<InteractionsRegistry>()
|
|
119
|
+
export const InteractionsRegistryLive =
|
|
120
|
+
makeRegistry.toLayer(InteractionsRegistry)
|
|
@@ -1,36 +1,38 @@
|
|
|
1
|
-
import * as Arr from "@effect/data/ReadonlyArray"
|
|
2
1
|
import * as IxHelpers from "dfx/Helpers/interactions"
|
|
3
2
|
import * as Ctx from "./context.js"
|
|
4
3
|
import * as D from "./definitions.js"
|
|
5
|
-
import { splitDefinitions } from "./utils.js"
|
|
4
|
+
import { flattenDefinitions, splitDefinitions } from "./utils.js"
|
|
6
5
|
|
|
7
6
|
export class DefinitionNotFound {
|
|
8
7
|
readonly _tag = "DefinitionNotFound"
|
|
9
8
|
constructor(readonly interaction: Discord.Interaction) {}
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
type Handler<R, E> = Effect<
|
|
11
|
+
type Handler<R, E, A> = Effect<
|
|
13
12
|
R | Discord.Interaction,
|
|
14
13
|
E | DefinitionNotFound,
|
|
15
|
-
|
|
14
|
+
A
|
|
16
15
|
>
|
|
17
16
|
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
17
|
+
export const handlers = <R, E, TE, A, B>(
|
|
18
|
+
definitions: Chunk<
|
|
19
|
+
readonly [
|
|
20
|
+
handler: D.InteractionDefinition<R, E>,
|
|
21
|
+
transform: (self: Effect<R, E, A>) => Effect<R, TE, B>,
|
|
22
|
+
]
|
|
23
|
+
>,
|
|
24
|
+
handleResponse: (
|
|
25
|
+
ix: Discord.Interaction,
|
|
26
|
+
_: Discord.InteractionResponse,
|
|
27
|
+
) => Effect<R, E, A>,
|
|
28
28
|
): Record<
|
|
29
29
|
Discord.InteractionType,
|
|
30
|
-
(i: Discord.Interaction) => Handler<R, E>
|
|
30
|
+
(i: Discord.Interaction) => Handler<R, E, B>
|
|
31
31
|
> => {
|
|
32
|
+
const flattened = flattenDefinitions(definitions, handleResponse)
|
|
33
|
+
|
|
32
34
|
const { Commands, Autocomplete, MessageComponent, ModalSubmit } =
|
|
33
|
-
splitDefinitions(
|
|
35
|
+
splitDefinitions(flattened)
|
|
34
36
|
|
|
35
37
|
return {
|
|
36
38
|
[Discord.InteractionType.PING]: () =>
|
|
@@ -41,90 +43,67 @@ export const handlers = <R, E>(
|
|
|
41
43
|
[Discord.InteractionType.APPLICATION_COMMAND]: i => {
|
|
42
44
|
const data = i.data as Discord.ApplicationCommandDatum
|
|
43
45
|
|
|
44
|
-
return Maybe.fromNullable(Commands[data.name])
|
|
45
|
-
.
|
|
46
|
-
|
|
47
|
-
command
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
)
|
|
52
|
-
.provideService(Ctx.ApplicationCommand, data)
|
|
46
|
+
return Maybe.fromNullable(Commands[data.name]).match(
|
|
47
|
+
() => Effect.fail(new DefinitionNotFound(i)),
|
|
48
|
+
command =>
|
|
49
|
+
command
|
|
50
|
+
.handle(i)
|
|
51
|
+
.provideService(Ctx.ApplicationCommand, data) as Handler<R, E, B>,
|
|
52
|
+
)
|
|
53
53
|
},
|
|
54
54
|
|
|
55
|
-
[Discord.InteractionType.MODAL_SUBMIT]:
|
|
55
|
+
[Discord.InteractionType.MODAL_SUBMIT]: i => {
|
|
56
56
|
const data = i.data as Discord.ModalSubmitDatum
|
|
57
57
|
|
|
58
|
-
return
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
58
|
+
return ModalSubmit.find(_ => _.predicate(data.custom_id)).flatMap(_ =>
|
|
59
|
+
_.match(
|
|
60
|
+
() => Effect.fail(new DefinitionNotFound(i)),
|
|
61
|
+
match =>
|
|
62
|
+
match
|
|
63
|
+
.handle(i)
|
|
64
|
+
.provideService(Ctx.ModalSubmitData, data) as Handler<R, E, B>,
|
|
65
65
|
),
|
|
66
|
-
_ =>
|
|
67
|
-
Effect.allPar(_)
|
|
68
|
-
.flatMap(_ =>
|
|
69
|
-
Arr.findFirst(_, _ => _.match).match(
|
|
70
|
-
() => Effect.fail(new DefinitionNotFound(i)) as Handler<R, E>,
|
|
71
|
-
a => a.command.handle,
|
|
72
|
-
),
|
|
73
|
-
)
|
|
74
|
-
.provideService(Ctx.ModalSubmitData, data),
|
|
75
66
|
)
|
|
76
67
|
},
|
|
77
68
|
|
|
78
69
|
[Discord.InteractionType.MESSAGE_COMPONENT]: i => {
|
|
79
70
|
const data = i.data as Discord.MessageComponentDatum
|
|
80
71
|
|
|
81
|
-
return
|
|
82
|
-
MessageComponent,
|
|
83
|
-
Arr.map(a =>
|
|
84
|
-
Effect.all({
|
|
85
|
-
command: Effect.succeed(a),
|
|
86
|
-
match: a.predicate(data.custom_id),
|
|
87
|
-
}),
|
|
88
|
-
),
|
|
72
|
+
return MessageComponent.find(_ => _.predicate(data.custom_id)).flatMap(
|
|
89
73
|
_ =>
|
|
90
|
-
|
|
91
|
-
.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
74
|
+
_.match(
|
|
75
|
+
() => Effect.fail(new DefinitionNotFound(i)),
|
|
76
|
+
match =>
|
|
77
|
+
match
|
|
78
|
+
.handle(i)
|
|
79
|
+
.provideService(Ctx.MessageComponentData, data) as Handler<
|
|
80
|
+
R,
|
|
81
|
+
E,
|
|
82
|
+
B
|
|
83
|
+
>,
|
|
84
|
+
),
|
|
98
85
|
)
|
|
99
86
|
},
|
|
100
87
|
|
|
101
88
|
[Discord.InteractionType.APPLICATION_COMMAND_AUTOCOMPLETE]: i => {
|
|
102
89
|
const data = i.data as Discord.ApplicationCommandDatum
|
|
103
90
|
|
|
104
|
-
return IxHelpers.focusedOption(data)
|
|
105
|
-
.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
Effect.
|
|
110
|
-
|
|
111
|
-
match
|
|
112
|
-
|
|
91
|
+
return IxHelpers.focusedOption(data).match(
|
|
92
|
+
() => Effect.fail(new DefinitionNotFound(i)),
|
|
93
|
+
focusedOption =>
|
|
94
|
+
Autocomplete.find(_ => _.predicate(data, focusedOption)).flatMap(_ =>
|
|
95
|
+
_.match(
|
|
96
|
+
() => Effect.fail(new DefinitionNotFound(i)),
|
|
97
|
+
match =>
|
|
98
|
+
match
|
|
99
|
+
.handle(i)
|
|
100
|
+
.provideService(Ctx.ApplicationCommand, data)
|
|
101
|
+
.provideService(Ctx.FocusedOptionContext, {
|
|
102
|
+
focusedOption,
|
|
103
|
+
}) as Handler<R, E, B>,
|
|
113
104
|
),
|
|
114
|
-
_ =>
|
|
115
|
-
Effect.allPar(_)
|
|
116
|
-
.flatMap(_ =>
|
|
117
|
-
Arr.findFirst(_, _ => _.match).match(
|
|
118
|
-
() =>
|
|
119
|
-
Effect.fail(new DefinitionNotFound(i)) as Handler<R, E>,
|
|
120
|
-
_ => _.command.handle,
|
|
121
|
-
),
|
|
122
|
-
)
|
|
123
|
-
.provideService(Ctx.ApplicationCommand, data)
|
|
124
|
-
.provideService(Ctx.FocusedOptionContext, { focusedOption }),
|
|
125
105
|
),
|
|
126
|
-
|
|
127
|
-
.getOrElse(() => Effect.fail(new DefinitionNotFound(i)))
|
|
106
|
+
)
|
|
128
107
|
},
|
|
129
108
|
}
|
|
130
109
|
}
|
|
@@ -1,80 +1,17 @@
|
|
|
1
|
-
import { DiscordREST } from "dfx"
|
|
2
1
|
import { Discord, Effect } from "dfx/_common"
|
|
3
|
-
import * as D from "./definitions.js"
|
|
4
|
-
import * as Http from "@effect-http/client"
|
|
5
2
|
|
|
6
3
|
export { response } from "../Helpers/interactions.js"
|
|
7
|
-
export *
|
|
4
|
+
export * from "./builder.js"
|
|
8
5
|
export * from "./context.js"
|
|
9
6
|
export {
|
|
7
|
+
InteractionDefinition,
|
|
10
8
|
autocomplete,
|
|
11
9
|
global,
|
|
12
10
|
guild,
|
|
13
|
-
InteractionDefinition,
|
|
14
11
|
messageComponent,
|
|
15
12
|
modalSubmit,
|
|
16
13
|
} from "./definitions.js"
|
|
17
14
|
|
|
18
|
-
/**
|
|
19
|
-
* @tsplus type dfx/InteractionBuilder
|
|
20
|
-
*/
|
|
21
|
-
export class InteractionBuilder<R, E> {
|
|
22
|
-
constructor(readonly definitions: D.InteractionDefinition<R, E>[]) {}
|
|
23
|
-
|
|
24
|
-
add<R1, E1>(definition: D.InteractionDefinition<R1, E1>) {
|
|
25
|
-
return new InteractionBuilder<R | R1, E | E1>([
|
|
26
|
-
...this.definitions,
|
|
27
|
-
definition,
|
|
28
|
-
])
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
concat<R1, E1>(builder: InteractionBuilder<R1, E1>) {
|
|
32
|
-
return new InteractionBuilder<R | R1, E | E1>([
|
|
33
|
-
...this.definitions,
|
|
34
|
-
...builder.definitions,
|
|
35
|
-
])
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
get syncGlobal() {
|
|
39
|
-
const commands = this.definitions
|
|
40
|
-
.filter(
|
|
41
|
-
(c): c is D.GlobalApplicationCommand<R, E> =>
|
|
42
|
-
c._tag === "GlobalApplicationCommand",
|
|
43
|
-
)
|
|
44
|
-
.map(c => c.command)
|
|
45
|
-
|
|
46
|
-
return DiscordREST.flatMap(rest =>
|
|
47
|
-
rest
|
|
48
|
-
.getCurrentBotApplicationInformation()
|
|
49
|
-
.flatMap(r => r.json)
|
|
50
|
-
.flatMap(app =>
|
|
51
|
-
rest.bulkOverwriteGlobalApplicationCommands(app.id, {
|
|
52
|
-
body: Http.body.json(commands),
|
|
53
|
-
}),
|
|
54
|
-
),
|
|
55
|
-
)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
syncGuild(appId: Discord.Snowflake, guildId: Discord.Snowflake) {
|
|
59
|
-
const commands = this.definitions
|
|
60
|
-
.filter(
|
|
61
|
-
(c): c is D.GuildApplicationCommand<R, E> =>
|
|
62
|
-
c._tag === "GuildApplicationCommand",
|
|
63
|
-
)
|
|
64
|
-
.map(c => c.command)
|
|
65
|
-
|
|
66
|
-
return DiscordREST.flatMap(rest =>
|
|
67
|
-
rest.bulkOverwriteGuildApplicationCommands(
|
|
68
|
-
appId,
|
|
69
|
-
guildId,
|
|
70
|
-
commands as any,
|
|
71
|
-
),
|
|
72
|
-
)
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export const builder = new InteractionBuilder<never, never>([])
|
|
77
|
-
|
|
78
15
|
// Filters
|
|
79
16
|
export const id = (query: string) => (customId: string) =>
|
|
80
17
|
Effect.succeed(query === customId)
|