dfx 0.77.3 → 0.79.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/Cache/prelude.d.ts +3 -3
- package/DiscordConfig.d.ts +8 -10
- package/DiscordConfig.d.ts.map +1 -1
- package/DiscordConfig.js +1 -3
- package/DiscordConfig.js.map +1 -1
- package/DiscordGateway/DiscordWS.d.ts +12 -11
- package/DiscordGateway/DiscordWS.d.ts.map +1 -1
- package/DiscordGateway/DiscordWS.js +8 -5
- package/DiscordGateway/DiscordWS.js.map +1 -1
- package/DiscordGateway/Messaging.d.ts +28 -0
- package/DiscordGateway/Messaging.d.ts.map +1 -0
- package/DiscordGateway/Messaging.js +41 -0
- package/DiscordGateway/Messaging.js.map +1 -0
- package/DiscordGateway/Shard.d.ts +14 -11
- package/DiscordGateway/Shard.d.ts.map +1 -1
- package/DiscordGateway/Shard.js +22 -19
- package/DiscordGateway/Shard.js.map +1 -1
- package/DiscordGateway/ShardStore.d.ts +5 -2
- package/DiscordGateway/ShardStore.d.ts.map +1 -1
- package/DiscordGateway/ShardStore.js +1 -1
- package/DiscordGateway/ShardStore.js.map +1 -1
- package/DiscordGateway/Sharder.d.ts +9 -18
- package/DiscordGateway/Sharder.d.ts.map +1 -1
- package/DiscordGateway/Sharder.js +36 -45
- package/DiscordGateway/Sharder.js.map +1 -1
- package/DiscordGateway/WS.d.ts +14 -10
- package/DiscordGateway/WS.d.ts.map +1 -1
- package/DiscordGateway/WS.js +31 -21
- package/DiscordGateway/WS.js.map +1 -1
- package/DiscordGateway.d.ts +10 -7
- package/DiscordGateway.d.ts.map +1 -1
- package/DiscordGateway.js +13 -31
- package/DiscordGateway.js.map +1 -1
- package/DiscordREST.d.ts +6 -4
- package/DiscordREST.d.ts.map +1 -1
- package/DiscordREST.js +9 -8
- package/DiscordREST.js.map +1 -1
- package/Interactions/context.d.ts +36 -18
- package/Interactions/context.d.ts.map +1 -1
- package/Interactions/context.js +6 -6
- package/Interactions/context.js.map +1 -1
- package/Interactions/definitions.d.ts +11 -11
- package/Interactions/definitions.d.ts.map +1 -1
- package/Interactions/definitions.js.map +1 -1
- package/Interactions/gateway.d.ts +7 -6
- package/Interactions/gateway.d.ts.map +1 -1
- package/Interactions/gateway.js +1 -1
- package/Interactions/gateway.js.map +1 -1
- package/Interactions/handlers.d.ts +2 -1
- package/Interactions/handlers.d.ts.map +1 -1
- package/Interactions/webhook.d.ts +7 -8
- package/Interactions/webhook.d.ts.map +1 -1
- package/Interactions/webhook.js +3 -3
- package/Interactions/webhook.js.map +1 -1
- package/README.md +37 -29
- package/RateLimit/memory.d.ts +2 -2
- package/RateLimit/memory.d.ts.map +1 -1
- package/RateLimit/memory.js.map +1 -1
- package/RateLimit.d.ts +10 -9
- package/RateLimit.d.ts.map +1 -1
- package/RateLimit.js +4 -5
- package/RateLimit.js.map +1 -1
- package/gateway.d.ts +2 -2
- package/gateway.d.ts.map +1 -1
- package/gateway.js +1 -2
- package/gateway.js.map +1 -1
- package/index.d.ts +1 -2
- package/index.d.ts.map +1 -1
- package/index.js +1 -3
- package/index.js.map +1 -1
- package/mjs/DiscordConfig.mjs +1 -3
- package/mjs/DiscordConfig.mjs.map +1 -1
- package/mjs/DiscordGateway/DiscordWS.mjs +8 -5
- package/mjs/DiscordGateway/DiscordWS.mjs.map +1 -1
- package/mjs/DiscordGateway/Messaging.mjs +33 -0
- package/mjs/DiscordGateway/Messaging.mjs.map +1 -0
- package/mjs/DiscordGateway/Shard.mjs +22 -19
- package/mjs/DiscordGateway/Shard.mjs.map +1 -1
- package/mjs/DiscordGateway/ShardStore.mjs +1 -1
- package/mjs/DiscordGateway/ShardStore.mjs.map +1 -1
- package/mjs/DiscordGateway/Sharder.mjs +35 -44
- package/mjs/DiscordGateway/Sharder.mjs.map +1 -1
- package/mjs/DiscordGateway/WS.mjs +32 -22
- package/mjs/DiscordGateway/WS.mjs.map +1 -1
- package/mjs/DiscordGateway.mjs +12 -30
- package/mjs/DiscordGateway.mjs.map +1 -1
- package/mjs/DiscordREST.mjs +9 -8
- package/mjs/DiscordREST.mjs.map +1 -1
- package/mjs/Interactions/context.mjs +6 -6
- package/mjs/Interactions/context.mjs.map +1 -1
- package/mjs/Interactions/definitions.mjs.map +1 -1
- package/mjs/Interactions/gateway.mjs +1 -1
- package/mjs/Interactions/gateway.mjs.map +1 -1
- package/mjs/Interactions/webhook.mjs +3 -3
- package/mjs/Interactions/webhook.mjs.map +1 -1
- package/mjs/RateLimit/memory.mjs.map +1 -1
- package/mjs/RateLimit.mjs +4 -5
- package/mjs/RateLimit.mjs.map +1 -1
- package/mjs/gateway.mjs +1 -2
- package/mjs/gateway.mjs.map +1 -1
- package/mjs/index.mjs +1 -2
- package/mjs/index.mjs.map +1 -1
- package/mjs/version.mjs +1 -1
- package/mjs/webhooks.mjs +1 -2
- package/mjs/webhooks.mjs.map +1 -1
- package/package.json +4 -4
- package/src/DiscordConfig.ts +10 -12
- package/src/DiscordGateway/DiscordWS.ts +23 -13
- package/src/DiscordGateway/Messaging.ts +72 -0
- package/src/DiscordGateway/Shard.ts +53 -35
- package/src/DiscordGateway/ShardStore.ts +8 -3
- package/src/DiscordGateway/Sharder.ts +72 -97
- package/src/DiscordGateway/WS.ts +64 -32
- package/src/DiscordGateway.ts +22 -71
- package/src/DiscordREST.ts +42 -29
- package/src/Interactions/context.ts +47 -10
- package/src/Interactions/definitions.ts +22 -20
- package/src/Interactions/gateway.ts +14 -6
- package/src/Interactions/handlers.ts +1 -1
- package/src/Interactions/webhook.ts +21 -7
- package/src/RateLimit/memory.ts +2 -2
- package/src/RateLimit.ts +17 -8
- package/src/gateway.ts +0 -2
- package/src/index.ts +0 -2
- package/src/version.ts +1 -1
- package/src/webhooks.ts +1 -2
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/webhooks.d.ts +1 -2
- package/webhooks.d.ts.map +1 -1
- package/webhooks.js +1 -2
- package/webhooks.js.map +1 -1
- package/Log.d.ts +0 -14
- package/Log.d.ts.map +0 -1
- package/Log.js +0 -23
- package/Log.js.map +0 -1
- package/mjs/Log.mjs +0 -15
- package/mjs/Log.mjs.map +0 -1
- package/src/Log.ts +0 -24
package/src/DiscordREST.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { millis } from "effect/Duration"
|
|
|
4
4
|
import { pipe } from "effect/Function"
|
|
5
5
|
import * as HashSet from "effect/HashSet"
|
|
6
6
|
import * as Option from "effect/Option"
|
|
7
|
-
import * as
|
|
7
|
+
import * as Secret from "effect/Secret"
|
|
8
8
|
import * as Effect from "effect/Effect"
|
|
9
9
|
import * as Layer from "effect/Layer"
|
|
10
10
|
import * as Ref from "effect/Ref"
|
|
@@ -16,7 +16,6 @@ import {
|
|
|
16
16
|
retryAfter,
|
|
17
17
|
routeFromConfig,
|
|
18
18
|
} from "dfx/DiscordREST/utils"
|
|
19
|
-
import { Log } from "dfx/Log"
|
|
20
19
|
import { RateLimiterLive, RateLimiter, RateLimitStore } from "dfx/RateLimit"
|
|
21
20
|
import * as Discord from "dfx/types"
|
|
22
21
|
import { LIB_VERSION } from "dfx/version"
|
|
@@ -33,7 +32,6 @@ const make = Effect.gen(function* (_) {
|
|
|
33
32
|
const { rest, token } = yield* _(DiscordConfig)
|
|
34
33
|
|
|
35
34
|
const http = yield* _(Http.client.Client)
|
|
36
|
-
const log = yield* _(Log)
|
|
37
35
|
const store = yield* _(RateLimitStore)
|
|
38
36
|
const { maybeWait } = yield* _(RateLimiter)
|
|
39
37
|
|
|
@@ -47,14 +45,13 @@ const make = Effect.gen(function* (_) {
|
|
|
47
45
|
const badRoutesRef = yield* _(Ref.make(HashSet.empty<string>()))
|
|
48
46
|
const tenMinutes = Duration.toMillis(Duration.minutes(10))
|
|
49
47
|
const addBadRoute = (route: string) =>
|
|
50
|
-
|
|
51
|
-
.
|
|
52
|
-
.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
)
|
|
48
|
+
Effect.logDebug("bad route").pipe(
|
|
49
|
+
Effect.zipRight(Ref.update(badRoutesRef, HashSet.add(route))),
|
|
50
|
+
Effect.zipRight(
|
|
51
|
+
store.incrementCounter("dfx.rest.invalid", tenMinutes, 10000),
|
|
52
|
+
),
|
|
53
|
+
Effect.annotateLogs("route", route),
|
|
54
|
+
)
|
|
58
55
|
const isBadRoute = (route: string) =>
|
|
59
56
|
Effect.map(Ref.get(badRoutesRef), HashSet.has(route))
|
|
60
57
|
const removeBadRoute = (route: string) =>
|
|
@@ -139,7 +136,7 @@ const make = Effect.gen(function* (_) {
|
|
|
139
136
|
pipe(
|
|
140
137
|
Http.request.prependUrl(req, rest.baseUrl),
|
|
141
138
|
Http.request.setHeaders({
|
|
142
|
-
Authorization: `Bot ${
|
|
139
|
+
Authorization: `Bot ${Secret.value(token)}`,
|
|
143
140
|
"User-Agent": `DiscordBot (https://github.com/tim-smart/dfx, ${LIB_VERSION})`,
|
|
144
141
|
}),
|
|
145
142
|
),
|
|
@@ -181,7 +178,11 @@ const make = Effect.gen(function* (_) {
|
|
|
181
178
|
return Effect.zipRight(
|
|
182
179
|
Effect.all(
|
|
183
180
|
[
|
|
184
|
-
|
|
181
|
+
Effect.annotateLogs(
|
|
182
|
+
Effect.logDebug("403"),
|
|
183
|
+
"url",
|
|
184
|
+
request.url,
|
|
185
|
+
),
|
|
185
186
|
addBadRoute(routeFromConfig(request.url, request.method)),
|
|
186
187
|
updateBuckets(request, response),
|
|
187
188
|
],
|
|
@@ -191,26 +192,32 @@ const make = Effect.gen(function* (_) {
|
|
|
191
192
|
)
|
|
192
193
|
|
|
193
194
|
case 429:
|
|
194
|
-
return
|
|
195
|
-
.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
195
|
+
return Effect.annotateLogs(
|
|
196
|
+
Effect.logDebug("429"),
|
|
197
|
+
"url",
|
|
198
|
+
request.url,
|
|
199
|
+
).pipe(
|
|
200
|
+
Effect.zipRight(
|
|
201
|
+
addBadRoute(routeFromConfig(request.url, request.method)),
|
|
202
|
+
),
|
|
203
|
+
Effect.zipRight(updateBuckets(request, response)),
|
|
204
|
+
Effect.zipRight(
|
|
205
|
+
Effect.sleep(
|
|
206
|
+
Option.getOrElse(retryAfter(response.headers), () =>
|
|
207
|
+
Duration.seconds(5),
|
|
206
208
|
),
|
|
207
209
|
),
|
|
208
|
-
|
|
209
|
-
)
|
|
210
|
+
),
|
|
211
|
+
Effect.zipRight(executor<A>(request)),
|
|
212
|
+
)
|
|
210
213
|
}
|
|
211
214
|
|
|
212
215
|
return Effect.fail(e)
|
|
213
216
|
}),
|
|
217
|
+
Effect.annotateLogs({
|
|
218
|
+
package: "dfx",
|
|
219
|
+
module: "DiscordREST",
|
|
220
|
+
}),
|
|
214
221
|
)
|
|
215
222
|
|
|
216
223
|
const routes = Discord.createRoutes<Partial<Http.request.Options.NoUrl>>(
|
|
@@ -246,14 +253,20 @@ const make = Effect.gen(function* (_) {
|
|
|
246
253
|
}
|
|
247
254
|
})
|
|
248
255
|
|
|
249
|
-
export interface DiscordREST
|
|
256
|
+
export interface DiscordREST {
|
|
257
|
+
readonly _: unique symbol
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export interface DiscordRESTService
|
|
250
261
|
extends Discord.Endpoints<Partial<Http.request.Options.NoUrl>> {
|
|
251
262
|
readonly executor: <A = unknown>(
|
|
252
263
|
request: Http.request.ClientRequest,
|
|
253
264
|
) => Effect.Effect<never, DiscordRESTError, ResponseWithData<A>>
|
|
254
265
|
}
|
|
255
266
|
|
|
256
|
-
export const DiscordREST = Tag<DiscordREST>(
|
|
267
|
+
export const DiscordREST = Tag<DiscordREST, DiscordRESTService>(
|
|
268
|
+
"dfx/DiscordREST",
|
|
269
|
+
)
|
|
257
270
|
export const DiscordRESTLive = Layer.effect(DiscordREST, make).pipe(
|
|
258
271
|
Layer.provide(RateLimiterLive),
|
|
259
272
|
Layer.provide(Http.client.layer),
|
|
@@ -6,20 +6,57 @@ import * as Effect from "effect/Effect"
|
|
|
6
6
|
import * as IxHelpers from "dfx/Helpers/interactions"
|
|
7
7
|
import type * as Discord from "dfx/types"
|
|
8
8
|
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
export const
|
|
9
|
+
export interface DiscordInteraction {
|
|
10
|
+
readonly _: unique symbol
|
|
11
|
+
}
|
|
12
|
+
export const Interaction = Tag<DiscordInteraction, Discord.Interaction>(
|
|
13
|
+
"dfx/Interactions/Interaction",
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
export interface DiscordApplicationCommand {
|
|
17
|
+
readonly _: unique symbol
|
|
18
|
+
}
|
|
19
|
+
export const ApplicationCommand = Tag<
|
|
20
|
+
DiscordApplicationCommand,
|
|
21
|
+
Discord.ApplicationCommandDatum
|
|
22
|
+
>("dfx/Interactions/ApplicationCommand")
|
|
23
|
+
|
|
24
|
+
export interface DiscordMessageComponent {
|
|
25
|
+
readonly _: unique symbol
|
|
26
|
+
}
|
|
27
|
+
export const MessageComponentData = Tag<
|
|
28
|
+
DiscordMessageComponent,
|
|
29
|
+
Discord.MessageComponentDatum
|
|
30
|
+
>("dfx/Interactions/MessageComponentData")
|
|
13
31
|
|
|
32
|
+
export interface DiscordModalSubmit {
|
|
33
|
+
readonly _: unique symbol
|
|
34
|
+
}
|
|
35
|
+
export const ModalSubmitData = Tag<
|
|
36
|
+
DiscordModalSubmit,
|
|
37
|
+
Discord.ModalSubmitDatum
|
|
38
|
+
>("dfx/Interactions/ModalSubmitData")
|
|
39
|
+
|
|
40
|
+
export interface DiscordFocusedOption {
|
|
41
|
+
readonly _: unique symbol
|
|
42
|
+
}
|
|
14
43
|
export interface FocusedOptionContext {
|
|
15
44
|
readonly focusedOption: Discord.ApplicationCommandInteractionDataOption
|
|
16
45
|
}
|
|
17
|
-
export const FocusedOptionContext = Tag<
|
|
46
|
+
export const FocusedOptionContext = Tag<
|
|
47
|
+
DiscordFocusedOption,
|
|
48
|
+
FocusedOptionContext
|
|
49
|
+
>("dfx/Interactions/FocusedOptionContext")
|
|
18
50
|
|
|
51
|
+
export interface DiscordSubCommand {
|
|
52
|
+
readonly _: unique symbol
|
|
53
|
+
}
|
|
19
54
|
export interface SubCommandContext {
|
|
20
55
|
readonly command: Discord.ApplicationCommandInteractionDataOption
|
|
21
56
|
}
|
|
22
|
-
export const SubCommandContext = Tag<SubCommandContext>(
|
|
57
|
+
export const SubCommandContext = Tag<DiscordSubCommand, SubCommandContext>(
|
|
58
|
+
"dfx/Interactions/SubCommandContext",
|
|
59
|
+
)
|
|
23
60
|
|
|
24
61
|
export class ResolvedDataNotFound {
|
|
25
62
|
readonly _tag = "ResolvedDataNotFound"
|
|
@@ -31,7 +68,7 @@ export class ResolvedDataNotFound {
|
|
|
31
68
|
|
|
32
69
|
export const resolvedValues = <A>(
|
|
33
70
|
f: (id: Discord.Snowflake, data: Discord.ResolvedDatum) => A | undefined,
|
|
34
|
-
): Effect.Effect<
|
|
71
|
+
): Effect.Effect<DiscordInteraction, ResolvedDataNotFound, ReadonlyArray<A>> =>
|
|
35
72
|
Effect.flatMap(Interaction, ix =>
|
|
36
73
|
Effect.mapError(
|
|
37
74
|
IxHelpers.resolveValues(f)(ix),
|
|
@@ -42,7 +79,7 @@ export const resolvedValues = <A>(
|
|
|
42
79
|
export const resolved = <A>(
|
|
43
80
|
name: string,
|
|
44
81
|
f: (id: Discord.Snowflake, data: Discord.ResolvedDatum) => A | undefined,
|
|
45
|
-
): Effect.Effect<
|
|
82
|
+
): Effect.Effect<DiscordInteraction, ResolvedDataNotFound, A> =>
|
|
46
83
|
Effect.flatMap(Interaction, ix =>
|
|
47
84
|
Effect.mapError(
|
|
48
85
|
IxHelpers.resolveOptionValue(name, f)(ix),
|
|
@@ -101,13 +138,13 @@ export const handleSubCommands = <
|
|
|
101
138
|
)
|
|
102
139
|
|
|
103
140
|
export const currentSubCommand: Effect.Effect<
|
|
104
|
-
|
|
141
|
+
DiscordSubCommand,
|
|
105
142
|
never,
|
|
106
143
|
Discord.ApplicationCommandInteractionDataOption
|
|
107
144
|
> = Effect.map(SubCommandContext, _ => _.command)
|
|
108
145
|
|
|
109
146
|
export const optionsMap: Effect.Effect<
|
|
110
|
-
|
|
147
|
+
DiscordApplicationCommand,
|
|
111
148
|
never,
|
|
112
149
|
HashMap.HashMap<string, string | undefined>
|
|
113
150
|
> = Effect.map(ApplicationCommand, IxHelpers.optionsMap)
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type * as Option from "effect/Option"
|
|
2
2
|
import type * as Effect from "effect/Effect"
|
|
3
3
|
import type {
|
|
4
|
-
|
|
4
|
+
DiscordApplicationCommand,
|
|
5
|
+
DiscordFocusedOption,
|
|
6
|
+
DiscordInteraction,
|
|
7
|
+
DiscordMessageComponent,
|
|
8
|
+
DiscordModalSubmit,
|
|
5
9
|
ResolvedDataNotFound,
|
|
6
10
|
SubCommandContext,
|
|
7
11
|
} from "dfx/Interactions/context"
|
|
@@ -32,7 +36,7 @@ export const global = <
|
|
|
32
36
|
handle: CommandHandler<R, E, A>,
|
|
33
37
|
) =>
|
|
34
38
|
new GlobalApplicationCommand<
|
|
35
|
-
Exclude<R,
|
|
39
|
+
Exclude<R, DiscordInteraction | DiscordApplicationCommand>,
|
|
36
40
|
E
|
|
37
41
|
>(command as any, handle as any)
|
|
38
42
|
|
|
@@ -54,7 +58,7 @@ export const guild = <
|
|
|
54
58
|
handle: CommandHandler<R, E, A>,
|
|
55
59
|
) =>
|
|
56
60
|
new GuildApplicationCommand<
|
|
57
|
-
Exclude<R,
|
|
61
|
+
Exclude<R, DiscordInteraction | DiscordApplicationCommand>,
|
|
58
62
|
E
|
|
59
63
|
>(command as any, handle as any)
|
|
60
64
|
|
|
@@ -71,7 +75,7 @@ export const messageComponent = <R1, R2, E1, E2>(
|
|
|
71
75
|
handle: CommandHandler<R2, E2, Discord.InteractionResponse>,
|
|
72
76
|
) =>
|
|
73
77
|
new MessageComponent<
|
|
74
|
-
Exclude<R1 | R2,
|
|
78
|
+
Exclude<R1 | R2, DiscordInteraction | DiscordMessageComponent>,
|
|
75
79
|
E1 | E2
|
|
76
80
|
>(pred as any, handle as any)
|
|
77
81
|
|
|
@@ -88,7 +92,7 @@ export const modalSubmit = <R1, R2, E1, E2>(
|
|
|
88
92
|
handle: Effect.Effect<R2, E2, Discord.InteractionResponse>,
|
|
89
93
|
) =>
|
|
90
94
|
new ModalSubmit<
|
|
91
|
-
Exclude<R1 | R2,
|
|
95
|
+
Exclude<R1 | R2, DiscordInteraction | DiscordModalSubmit>,
|
|
92
96
|
E1 | E2
|
|
93
97
|
>(pred as any, handle as any)
|
|
94
98
|
|
|
@@ -113,9 +117,7 @@ export const autocomplete = <R1, R2, E1, E2>(
|
|
|
113
117
|
new Autocomplete<
|
|
114
118
|
Exclude<
|
|
115
119
|
R1 | R2,
|
|
116
|
-
|
|
|
117
|
-
| Discord.ApplicationCommandDatum
|
|
118
|
-
| FocusedOptionContext
|
|
120
|
+
DiscordInteraction | DiscordApplicationCommand | DiscordFocusedOption
|
|
119
121
|
>,
|
|
120
122
|
E1 | E2
|
|
121
123
|
>(pred as any, handle as any)
|
|
@@ -124,10 +126,10 @@ export const autocomplete = <R1, R2, E1, E2>(
|
|
|
124
126
|
type DeepReadonly<T> = T extends Array<infer R>
|
|
125
127
|
? ReadonlyArray<DeepReadonly<R>>
|
|
126
128
|
: T extends Function
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
? T
|
|
130
|
+
: T extends object
|
|
131
|
+
? DeepReadonlyObject<T>
|
|
132
|
+
: T
|
|
131
133
|
type DeepReadonlyObject<T> = {
|
|
132
134
|
readonly [P in keyof T]: DeepReadonly<T[P]>
|
|
133
135
|
}
|
|
@@ -140,24 +142,24 @@ export interface CommandHelper<A> {
|
|
|
140
142
|
resolve: <T>(
|
|
141
143
|
name: AllResolvables<A>["name"],
|
|
142
144
|
f: (id: Discord.Snowflake, data: Discord.ResolvedDatum) => T | undefined,
|
|
143
|
-
) => Effect.Effect<
|
|
145
|
+
) => Effect.Effect<DiscordInteraction, ResolvedDataNotFound, T>
|
|
144
146
|
|
|
145
147
|
option: (
|
|
146
148
|
name: AllCommandOptions<A>["name"],
|
|
147
149
|
) => Effect.Effect<
|
|
148
|
-
|
|
150
|
+
DiscordApplicationCommand,
|
|
149
151
|
never,
|
|
150
152
|
Option.Option<Discord.ApplicationCommandInteractionDataOption>
|
|
151
153
|
>
|
|
152
154
|
|
|
153
155
|
optionValue: <N extends AllRequiredCommandOptions<A>["name"]>(
|
|
154
156
|
name: N,
|
|
155
|
-
) => Effect.Effect<
|
|
157
|
+
) => Effect.Effect<DiscordApplicationCommand, never, CommandValue<A, N>>
|
|
156
158
|
|
|
157
159
|
optionValueOptional: <N extends AllCommandOptions<A>["name"]>(
|
|
158
160
|
name: N,
|
|
159
161
|
) => Effect.Effect<
|
|
160
|
-
|
|
162
|
+
DiscordApplicationCommand,
|
|
161
163
|
never,
|
|
162
164
|
Option.Option<CommandValue<A, N>>
|
|
163
165
|
>
|
|
@@ -180,8 +182,8 @@ export interface CommandHelper<A> {
|
|
|
180
182
|
: never,
|
|
181
183
|
SubCommandContext
|
|
182
184
|
>
|
|
183
|
-
|
|
|
184
|
-
|
|
|
185
|
+
| DiscordInteraction
|
|
186
|
+
| DiscordApplicationCommand,
|
|
185
187
|
[NER[keyof NER]] extends [
|
|
186
188
|
{ [Effect.EffectTypeId]: { _E: (_: never) => infer E } },
|
|
187
189
|
]
|
|
@@ -208,8 +210,8 @@ type SubCommands<A> = A extends {
|
|
|
208
210
|
}
|
|
209
211
|
? A
|
|
210
212
|
: A extends { readonly options: ReadonlyArray<CommandOption> }
|
|
211
|
-
|
|
212
|
-
|
|
213
|
+
? SubCommands<A["options"][number]>
|
|
214
|
+
: never
|
|
213
215
|
|
|
214
216
|
type SubCommandNames<A> = Option<SubCommands<A>>["name"]
|
|
215
217
|
|
|
@@ -16,9 +16,11 @@ import type {
|
|
|
16
16
|
} from "dfx/Interactions/definitions"
|
|
17
17
|
import type { DefinitionNotFound } from "dfx/Interactions/handlers"
|
|
18
18
|
import { handlers } from "dfx/Interactions/handlers"
|
|
19
|
-
import type {
|
|
19
|
+
import type {
|
|
20
|
+
DiscordInteraction,
|
|
21
|
+
InteractionBuilder,
|
|
22
|
+
} from "dfx/Interactions/index"
|
|
20
23
|
import { builder, Interaction } from "dfx/Interactions/index"
|
|
21
|
-
import type * as Discord from "dfx/types"
|
|
22
24
|
import * as EffectUtils from "dfx/utils/Effect"
|
|
23
25
|
import * as Schedule from "effect/Schedule"
|
|
24
26
|
import { globalValue } from "effect/GlobalValue"
|
|
@@ -36,7 +38,7 @@ export const run =
|
|
|
36
38
|
<R, R2, E, TE, E2>(
|
|
37
39
|
postHandler: (
|
|
38
40
|
effect: Effect.Effect<
|
|
39
|
-
R | DiscordREST |
|
|
41
|
+
R | DiscordREST | DiscordInteraction,
|
|
40
42
|
TE | DiscordRESTError | DefinitionNotFound,
|
|
41
43
|
void
|
|
42
44
|
>,
|
|
@@ -45,7 +47,7 @@ export const run =
|
|
|
45
47
|
(
|
|
46
48
|
ix: InteractionBuilder<R, E, TE>,
|
|
47
49
|
): Effect.Effect<
|
|
48
|
-
DiscordREST | DiscordGateway | Exclude<R2,
|
|
50
|
+
DiscordREST | DiscordGateway | Exclude<R2, DiscordInteraction>,
|
|
49
51
|
E2 | DiscordRESTError | Http.error.ResponseError,
|
|
50
52
|
never
|
|
51
53
|
> =>
|
|
@@ -155,13 +157,19 @@ const makeRegistry = Effect.gen(function* (_) {
|
|
|
155
157
|
}),
|
|
156
158
|
)
|
|
157
159
|
|
|
158
|
-
export interface
|
|
160
|
+
export interface InteractionsRegistryService {
|
|
159
161
|
readonly register: <E>(
|
|
160
162
|
ix: InteractionBuilder<never, E, never>,
|
|
161
163
|
) => Effect.Effect<never, never, void>
|
|
162
164
|
}
|
|
165
|
+
export interface InteractionsRegistry {
|
|
166
|
+
readonly _: unique symbol
|
|
167
|
+
}
|
|
163
168
|
|
|
164
|
-
export const InteractionsRegistry = Tag<
|
|
169
|
+
export const InteractionsRegistry = Tag<
|
|
170
|
+
InteractionsRegistry,
|
|
171
|
+
InteractionsRegistryService
|
|
172
|
+
>("dfx/Interactions/InteractionsRegistry")
|
|
165
173
|
export const InteractionsRegistryLive = Layer.scoped(
|
|
166
174
|
InteractionsRegistry,
|
|
167
175
|
makeRegistry,
|
|
@@ -5,13 +5,16 @@ import * as Option from "effect/Option"
|
|
|
5
5
|
import type * as Cause from "effect/Cause"
|
|
6
6
|
import type * as Config from "effect/Config"
|
|
7
7
|
import type * as ConfigError from "effect/ConfigError"
|
|
8
|
-
import * as
|
|
8
|
+
import * as Secret from "effect/Secret"
|
|
9
9
|
import * as Effect from "effect/Effect"
|
|
10
10
|
import * as Layer from "effect/Layer"
|
|
11
11
|
import type * as D from "dfx/Interactions/definitions"
|
|
12
12
|
import type { DefinitionNotFound } from "dfx/Interactions/handlers"
|
|
13
13
|
import { handlers } from "dfx/Interactions/handlers"
|
|
14
|
-
import type {
|
|
14
|
+
import type {
|
|
15
|
+
DiscordInteraction,
|
|
16
|
+
InteractionBuilder,
|
|
17
|
+
} from "dfx/Interactions/index"
|
|
15
18
|
import { Interaction } from "dfx/Interactions/index"
|
|
16
19
|
import type * as Discord from "dfx/types"
|
|
17
20
|
import * as Verify from "discord-verify"
|
|
@@ -52,7 +55,7 @@ const checkSignature = (
|
|
|
52
55
|
|
|
53
56
|
export interface MakeConfigOpts {
|
|
54
57
|
readonly applicationId: string
|
|
55
|
-
readonly publicKey:
|
|
58
|
+
readonly publicKey: Secret.Secret
|
|
56
59
|
readonly crypto: SubtleCrypto
|
|
57
60
|
readonly algorithm: keyof typeof Verify.PlatformAlgorithm
|
|
58
61
|
}
|
|
@@ -63,13 +66,17 @@ const makeConfig = ({
|
|
|
63
66
|
publicKey,
|
|
64
67
|
}: MakeConfigOpts) => ({
|
|
65
68
|
applicationId,
|
|
66
|
-
publicKey:
|
|
69
|
+
publicKey: Secret.value(publicKey),
|
|
67
70
|
crypto,
|
|
68
71
|
algorithm: Verify.PlatformAlgorithm[algorithm],
|
|
69
72
|
})
|
|
70
73
|
|
|
71
|
-
export interface WebhookConfig
|
|
72
|
-
|
|
74
|
+
export interface WebhookConfig {
|
|
75
|
+
readonly _: unique symbol
|
|
76
|
+
}
|
|
77
|
+
export const WebhookConfig = Tag<WebhookConfig, ReturnType<typeof makeConfig>>(
|
|
78
|
+
"dfx/Interactions/WebhookConfig",
|
|
79
|
+
)
|
|
73
80
|
|
|
74
81
|
export const layer = (opts: MakeConfigOpts) =>
|
|
75
82
|
Layer.succeed(WebhookConfig, makeConfig(opts))
|
|
@@ -112,7 +119,14 @@ const run = <R, E>(
|
|
|
112
119
|
) => Effect.Effect<R, E, Discord.InteractionResponse>,
|
|
113
120
|
) => {
|
|
114
121
|
const handler = handlers(definitions, handleResponse)
|
|
115
|
-
return (
|
|
122
|
+
return (
|
|
123
|
+
headers: Headers,
|
|
124
|
+
body: string,
|
|
125
|
+
): Effect.Effect<
|
|
126
|
+
WebhookConfig | Exclude<R, DiscordInteraction>,
|
|
127
|
+
BadWebhookSignature | WebhookParseError | E | DefinitionNotFound,
|
|
128
|
+
Discord.InteractionResponse
|
|
129
|
+
> =>
|
|
116
130
|
Effect.flatMap(fromHeadersAndBody(headers, body), interaction =>
|
|
117
131
|
Effect.provideService(
|
|
118
132
|
handler[interaction.type](interaction),
|
package/src/RateLimit/memory.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import * as Option from "effect/Option"
|
|
2
2
|
import * as Effect from "effect/Effect"
|
|
3
|
-
import type { BucketDetails,
|
|
3
|
+
import type { BucketDetails, RateLimitStoreService } from "dfx/RateLimit"
|
|
4
4
|
|
|
5
5
|
interface Counter {
|
|
6
6
|
count: number
|
|
7
7
|
expires: number
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export const make = ():
|
|
10
|
+
export const make = (): RateLimitStoreService => {
|
|
11
11
|
const buckets = new Map<string, BucketDetails>()
|
|
12
12
|
const routes = new Map<string, string>()
|
|
13
13
|
const counters = new Map<string, Counter>()
|
package/src/RateLimit.ts
CHANGED
|
@@ -3,7 +3,6 @@ import * as Duration from "effect/Duration"
|
|
|
3
3
|
import type * as Option from "effect/Option"
|
|
4
4
|
import * as Effect from "effect/Effect"
|
|
5
5
|
import * as Layer from "effect/Layer"
|
|
6
|
-
import { Log } from "dfx/Log"
|
|
7
6
|
import * as Memory from "dfx/RateLimit/memory"
|
|
8
7
|
import { delayFrom } from "dfx/RateLimit/utils"
|
|
9
8
|
|
|
@@ -13,7 +12,7 @@ export type BucketDetails = {
|
|
|
13
12
|
limit: number
|
|
14
13
|
}
|
|
15
14
|
|
|
16
|
-
export interface
|
|
15
|
+
export interface RateLimitStoreService {
|
|
17
16
|
readonly hasBucket: (
|
|
18
17
|
bucketKey: string,
|
|
19
18
|
) => Effect.Effect<never, never, boolean>
|
|
@@ -40,12 +39,17 @@ export interface RateLimitStore {
|
|
|
40
39
|
readonly removeCounter: (key: string) => Effect.Effect<never, never, void>
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
export
|
|
42
|
+
export interface RateLimitStore {
|
|
43
|
+
readonly _: unique symbol
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const RateLimitStore = Tag<RateLimitStore, RateLimitStoreService>(
|
|
47
|
+
"dfx/RateLimit/RateLimitStore",
|
|
48
|
+
)
|
|
44
49
|
export const MemoryRateLimitStoreLive = Layer.sync(RateLimitStore, Memory.make)
|
|
45
50
|
|
|
46
51
|
const makeLimiter = Effect.gen(function* (_) {
|
|
47
52
|
const store = yield* _(RateLimitStore)
|
|
48
|
-
const log = yield* _(Log)
|
|
49
53
|
|
|
50
54
|
const maybeWait = (
|
|
51
55
|
key: string,
|
|
@@ -58,7 +62,8 @@ const makeLimiter = Effect.gen(function* (_) {
|
|
|
58
62
|
return store.incrementCounter(key, windowMs, limit).pipe(
|
|
59
63
|
Effect.map(([count, ttl]) => delayFrom(windowMs, limit, count, ttl)),
|
|
60
64
|
Effect.tap(d =>
|
|
61
|
-
|
|
65
|
+
Effect.annotateLogs(Effect.logTrace("maybeWait"), {
|
|
66
|
+
service: "RateLimit",
|
|
62
67
|
key,
|
|
63
68
|
window: Duration.toMillis(window),
|
|
64
69
|
windowMs,
|
|
@@ -76,7 +81,11 @@ const makeLimiter = Effect.gen(function* (_) {
|
|
|
76
81
|
return { maybeWait }
|
|
77
82
|
})
|
|
78
83
|
|
|
79
|
-
export interface RateLimiter
|
|
80
|
-
|
|
81
|
-
|
|
84
|
+
export interface RateLimiter {
|
|
85
|
+
readonly _: unique symbol
|
|
86
|
+
}
|
|
87
|
+
export const RateLimiter = Tag<
|
|
88
|
+
RateLimiter,
|
|
89
|
+
Effect.Effect.Success<typeof makeLimiter>
|
|
90
|
+
>("dfx/RateLimit/RateLimiter")
|
|
82
91
|
export const RateLimiterLive = Layer.effect(RateLimiter, makeLimiter)
|
package/src/gateway.ts
CHANGED
|
@@ -9,7 +9,6 @@ import { MemoryShardStoreLive } from "dfx/DiscordGateway/ShardStore"
|
|
|
9
9
|
import * as WS from "dfx/DiscordGateway/WS"
|
|
10
10
|
import { DiscordRESTLive } from "dfx/DiscordREST"
|
|
11
11
|
import { InteractionsRegistryLive } from "dfx/Interactions/gateway"
|
|
12
|
-
import { LogLive } from "dfx/Log"
|
|
13
12
|
import { MemoryRateLimitStoreLive, RateLimiterLive } from "dfx/RateLimit"
|
|
14
13
|
import * as Layer from "effect/Layer"
|
|
15
14
|
|
|
@@ -33,7 +32,6 @@ export const DiscordLive = Layer.mergeAll(
|
|
|
33
32
|
Layer.provide(JsonDiscordWSCodecLive),
|
|
34
33
|
Layer.provide(MemoryRateLimitStoreLive),
|
|
35
34
|
Layer.provide(MemoryShardStoreLive),
|
|
36
|
-
Layer.provideMerge(LogLive),
|
|
37
35
|
)
|
|
38
36
|
|
|
39
37
|
export const DiscordIxLive = InteractionsRegistryLive.pipe(
|
package/src/index.ts
CHANGED
|
@@ -7,7 +7,6 @@ import * as Members from "dfx/Helpers/members"
|
|
|
7
7
|
import * as Perms from "dfx/Helpers/permissions"
|
|
8
8
|
import * as UI from "dfx/Helpers/ui"
|
|
9
9
|
import * as Ix from "dfx/Interactions/index"
|
|
10
|
-
import * as Log from "dfx/Log"
|
|
11
10
|
import * as Discord from "dfx/types"
|
|
12
11
|
|
|
13
12
|
export { DiscordREST, DiscordRESTLive } from "dfx/DiscordREST"
|
|
@@ -28,7 +27,6 @@ export {
|
|
|
28
27
|
Intents,
|
|
29
28
|
Ix,
|
|
30
29
|
IxHelpers,
|
|
31
|
-
Log,
|
|
32
30
|
Members,
|
|
33
31
|
Perms,
|
|
34
32
|
UI,
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const LIB_VERSION = "0.
|
|
1
|
+
export const LIB_VERSION = "0.79.0";
|
package/src/webhooks.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { DiscordRESTLive } from "dfx/DiscordREST"
|
|
2
|
-
import * as Log from "dfx/Log"
|
|
3
2
|
import {
|
|
4
3
|
MemoryRateLimitStoreLive as MemoryRateLimitStoreLive,
|
|
5
4
|
RateLimiterLive as RateLimiterLive,
|
|
@@ -19,4 +18,4 @@ export {
|
|
|
19
18
|
export const DiscordLive = Layer.mergeAll(
|
|
20
19
|
DiscordRESTLive,
|
|
21
20
|
RateLimiterLive,
|
|
22
|
-
).pipe(Layer.provide(MemoryRateLimitStoreLive)
|
|
21
|
+
).pipe(Layer.provide(MemoryRateLimitStoreLive))
|
package/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "0.
|
|
1
|
+
export declare const LIB_VERSION = "0.79.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/version.js
CHANGED
package/webhooks.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import * as Log from "dfx/Log";
|
|
2
1
|
import * as Layer from "effect/Layer";
|
|
3
2
|
export { BadWebhookSignature, WebhookConfig, WebhookParseError, makeHandler, makeSimpleHandler, layer as webhookLayer, layerConfig as webhookLayerConfig, } from "dfx/Interactions/webhook";
|
|
4
|
-
export declare const DiscordLive: Layer.Layer<import("./DiscordConfig").DiscordConfig, never,
|
|
3
|
+
export declare const DiscordLive: Layer.Layer<import("./DiscordConfig").DiscordConfig, never, import("dfx/RateLimit").RateLimiter | import("dfx/DiscordREST").DiscordREST>;
|
|
5
4
|
//# sourceMappingURL=webhooks.d.ts.map
|
package/webhooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["./src/webhooks.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["./src/webhooks.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,KAAK,IAAI,YAAY,EACrB,WAAW,IAAI,kBAAkB,GAClC,MAAM,0BAA0B,CAAA;AAEjC,eAAO,MAAM,WAAW,0IAGuB,CAAA"}
|
package/webhooks.js
CHANGED
|
@@ -47,11 +47,10 @@ Object.defineProperty(exports, "webhookLayerConfig", {
|
|
|
47
47
|
}
|
|
48
48
|
});
|
|
49
49
|
var _DiscordREST = /*#__PURE__*/require("dfx/DiscordREST");
|
|
50
|
-
var Log = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("dfx/Log"));
|
|
51
50
|
var _RateLimit = /*#__PURE__*/require("dfx/RateLimit");
|
|
52
51
|
var Layer = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("effect/Layer"));
|
|
53
52
|
var _webhook = /*#__PURE__*/require("dfx/Interactions/webhook");
|
|
54
53
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
55
54
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
56
|
-
const DiscordLive = exports.DiscordLive = /*#__PURE__*/Layer.mergeAll(_DiscordREST.DiscordRESTLive, _RateLimit.RateLimiterLive).pipe( /*#__PURE__*/Layer.provide(_RateLimit.MemoryRateLimitStoreLive)
|
|
55
|
+
const DiscordLive = exports.DiscordLive = /*#__PURE__*/Layer.mergeAll(_DiscordREST.DiscordRESTLive, _RateLimit.RateLimiterLive).pipe( /*#__PURE__*/Layer.provide(_RateLimit.MemoryRateLimitStoreLive));
|
|
57
56
|
//# sourceMappingURL=webhooks.js.map
|