dfx 0.60.0 → 0.61.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/Cache/driver.d.ts +1 -1
- package/Cache/driver.d.ts.map +1 -1
- package/Cache/memory.js +2 -2
- package/Cache/memory.js.map +1 -1
- package/Cache/memoryTTL.d.ts.map +1 -1
- package/Cache/memoryTTL.js.map +1 -1
- package/Cache/prelude.d.ts +7 -7
- package/Cache/prelude.d.ts.map +1 -1
- package/Cache/prelude.js.map +1 -1
- package/Cache.d.ts +1 -1
- package/Cache.d.ts.map +1 -1
- package/Cache.js +1 -1
- package/Cache.js.map +1 -1
- package/DiscordGateway/DiscordWS.d.ts +5 -5
- package/DiscordGateway/DiscordWS.d.ts.map +1 -1
- package/DiscordGateway/DiscordWS.js +2 -2
- package/DiscordGateway/DiscordWS.js.map +1 -1
- package/DiscordGateway/Shard/heartbeats.js.map +1 -1
- package/DiscordGateway/Shard/utils.d.ts +1 -1
- package/DiscordGateway/Shard/utils.d.ts.map +1 -1
- package/DiscordGateway/Shard/utils.js.map +1 -1
- package/DiscordGateway/Shard.d.ts +8 -8
- package/DiscordGateway/Shard.d.ts.map +1 -1
- package/DiscordGateway/Shard.js +11 -11
- package/DiscordGateway/Shard.js.map +1 -1
- package/DiscordGateway/ShardStore.d.ts +2 -2
- package/DiscordGateway/ShardStore.d.ts.map +1 -1
- package/DiscordGateway/ShardStore.js +2 -2
- package/DiscordGateway/ShardStore.js.map +1 -1
- package/DiscordGateway/Sharder.d.ts +2 -2
- package/DiscordGateway/Sharder.js.map +1 -1
- package/DiscordGateway/WS.d.ts +4 -4
- package/DiscordGateway/WS.d.ts.map +1 -1
- package/DiscordGateway/WS.js +6 -6
- package/DiscordGateway/WS.js.map +1 -1
- package/DiscordGateway.d.ts +1 -1
- package/DiscordGateway.d.ts.map +1 -1
- package/DiscordGateway.js.map +1 -1
- package/DiscordREST/types.d.ts +4 -4
- package/DiscordREST/types.d.ts.map +1 -1
- package/DiscordREST/utils.d.ts +5 -4
- package/DiscordREST/utils.d.ts.map +1 -1
- package/DiscordREST/utils.js +4 -3
- package/DiscordREST/utils.js.map +1 -1
- package/DiscordREST.d.ts +6 -7
- package/DiscordREST.d.ts.map +1 -1
- package/DiscordREST.js +12 -18
- package/DiscordREST.js.map +1 -1
- package/Helpers/flags.d.ts.map +1 -1
- package/Helpers/flags.js.map +1 -1
- package/Helpers/intents.d.ts.map +1 -1
- package/Helpers/intents.js.map +1 -1
- package/Helpers/interactions.d.ts +1 -1
- package/Helpers/interactions.d.ts.map +1 -1
- package/Helpers/interactions.js +2 -2
- package/Helpers/interactions.js.map +1 -1
- package/Helpers/members.d.ts.map +1 -1
- package/Helpers/members.js.map +1 -1
- package/Helpers/permissions.js.map +1 -1
- package/Interactions/builder.d.ts +3 -3
- package/Interactions/builder.d.ts.map +1 -1
- package/Interactions/builder.js +1 -1
- package/Interactions/builder.js.map +1 -1
- package/Interactions/context.d.ts +1 -1
- package/Interactions/context.d.ts.map +1 -1
- package/Interactions/context.js.map +1 -1
- package/Interactions/definitions.d.ts +3 -3
- package/Interactions/definitions.d.ts.map +1 -1
- package/Interactions/definitions.js.map +1 -1
- package/Interactions/gateway.d.ts +3 -3
- 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.map +1 -1
- package/Interactions/handlers.js.map +1 -1
- package/Interactions/index.d.ts +1 -1
- package/Interactions/index.d.ts.map +1 -1
- package/Interactions/index.js.map +1 -1
- package/Interactions/utils.d.ts.map +1 -1
- package/Interactions/utils.js.map +1 -1
- package/Interactions/webhook.d.ts.map +1 -1
- package/Interactions/webhook.js.map +1 -1
- package/LICENSE +21 -0
- package/Log.d.ts +1 -1
- package/Log.d.ts.map +1 -1
- package/Log.js +1 -1
- package/Log.js.map +1 -1
- package/RateLimit.d.ts +2 -2
- package/RateLimit.d.ts.map +1 -1
- package/RateLimit.js.map +1 -1
- package/gateway.d.ts +2 -4
- package/gateway.d.ts.map +1 -1
- package/gateway.js +3 -6
- package/gateway.js.map +1 -1
- package/index.d.ts +2 -3
- package/index.d.ts.map +1 -1
- package/index.js +1 -3
- package/index.js.map +1 -1
- package/mjs/Cache/memory.mjs +2 -2
- package/mjs/Cache/memory.mjs.map +1 -1
- package/mjs/Cache/memoryTTL.mjs.map +1 -1
- package/mjs/Cache/prelude.mjs.map +1 -1
- package/mjs/Cache.mjs +1 -1
- package/mjs/Cache.mjs.map +1 -1
- package/mjs/DiscordGateway/DiscordWS.mjs +2 -2
- package/mjs/DiscordGateway/DiscordWS.mjs.map +1 -1
- package/mjs/DiscordGateway/Shard/heartbeats.mjs.map +1 -1
- package/mjs/DiscordGateway/Shard/utils.mjs.map +1 -1
- package/mjs/DiscordGateway/Shard.mjs +11 -11
- package/mjs/DiscordGateway/Shard.mjs.map +1 -1
- package/mjs/DiscordGateway/ShardStore.mjs +2 -2
- package/mjs/DiscordGateway/ShardStore.mjs.map +1 -1
- package/mjs/DiscordGateway/Sharder.mjs.map +1 -1
- package/mjs/DiscordGateway/WS.mjs +5 -5
- package/mjs/DiscordGateway/WS.mjs.map +1 -1
- package/mjs/DiscordGateway.mjs.map +1 -1
- package/mjs/DiscordREST/utils.mjs +4 -3
- package/mjs/DiscordREST/utils.mjs.map +1 -1
- package/mjs/DiscordREST.mjs +13 -14
- package/mjs/DiscordREST.mjs.map +1 -1
- package/mjs/Helpers/flags.mjs.map +1 -1
- package/mjs/Helpers/intents.mjs.map +1 -1
- package/mjs/Helpers/interactions.mjs +2 -2
- package/mjs/Helpers/interactions.mjs.map +1 -1
- package/mjs/Helpers/members.mjs.map +1 -1
- package/mjs/Helpers/permissions.mjs.map +1 -1
- package/mjs/Interactions/builder.mjs +1 -1
- package/mjs/Interactions/builder.mjs.map +1 -1
- package/mjs/Interactions/context.mjs.map +1 -1
- package/mjs/Interactions/definitions.mjs.map +1 -1
- package/mjs/Interactions/gateway.mjs +2 -2
- package/mjs/Interactions/gateway.mjs.map +1 -1
- package/mjs/Interactions/handlers.mjs.map +1 -1
- package/mjs/Interactions/index.mjs.map +1 -1
- package/mjs/Interactions/utils.mjs.map +1 -1
- package/mjs/Interactions/webhook.mjs.map +1 -1
- package/mjs/Log.mjs +1 -1
- package/mjs/Log.mjs.map +1 -1
- package/mjs/RateLimit.mjs.map +1 -1
- package/mjs/gateway.mjs +2 -4
- package/mjs/gateway.mjs.map +1 -1
- package/mjs/index.mjs +2 -3
- package/mjs/index.mjs.map +1 -1
- package/mjs/types.mjs.map +1 -1
- package/mjs/utils/Effect.mjs +4 -4
- package/mjs/utils/Effect.mjs.map +1 -1
- package/mjs/version.mjs +1 -1
- package/mjs/webhooks.mjs +3 -12
- package/mjs/webhooks.mjs.map +1 -1
- package/package.json +32 -26
- package/src/Cache/driver.ts +1 -1
- package/src/Cache/memory.ts +2 -2
- package/src/Cache/memoryTTL.ts +6 -4
- package/src/Cache/prelude.ts +15 -13
- package/src/Cache.ts +3 -3
- package/src/DiscordGateway/DiscordWS.ts +9 -10
- package/src/DiscordGateway/Shard/heartbeats.ts +1 -1
- package/src/DiscordGateway/Shard/utils.ts +10 -12
- package/src/DiscordGateway/Shard.ts +23 -24
- package/src/DiscordGateway/ShardStore.ts +2 -2
- package/src/DiscordGateway/Sharder.ts +7 -7
- package/src/DiscordGateway/WS.ts +10 -10
- package/src/DiscordGateway.ts +8 -9
- package/src/DiscordREST/types.ts +4 -4
- package/src/DiscordREST/utils.ts +12 -8
- package/src/DiscordREST.ts +60 -53
- package/src/Helpers/flags.ts +2 -4
- package/src/Helpers/intents.ts +3 -4
- package/src/Helpers/interactions.ts +53 -56
- package/src/Helpers/members.ts +2 -2
- package/src/Helpers/permissions.ts +2 -2
- package/src/Interactions/builder.ts +22 -20
- package/src/Interactions/context.ts +16 -23
- package/src/Interactions/definitions.ts +27 -34
- package/src/Interactions/gateway.ts +82 -85
- package/src/Interactions/handlers.ts +34 -35
- package/src/Interactions/index.ts +17 -21
- package/src/Interactions/utils.ts +13 -17
- package/src/Interactions/webhook.ts +19 -15
- package/src/Log.ts +3 -3
- package/src/RateLimit.ts +5 -4
- package/src/gateway.ts +4 -19
- package/src/index.ts +1 -3
- package/src/types.ts +50 -26
- package/src/utils/Effect.ts +16 -17
- package/src/version.ts +1 -1
- package/src/webhooks.ts +21 -34
- package/tsconfig.tsbuildinfo +1 -0
- package/types.d.ts.map +1 -1
- package/types.js.map +1 -1
- package/utils/Effect.d.ts.map +1 -1
- package/utils/Effect.js +4 -4
- package/utils/Effect.js.map +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/webhooks.d.ts +3 -5
- package/webhooks.d.ts.map +1 -1
- package/webhooks.js +4 -14
- package/webhooks.js.map +1 -1
package/src/DiscordREST.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as Http from "@effect-http/client"
|
|
2
1
|
import { Tag } from "@effect/data/Context"
|
|
3
2
|
import * as Duration from "@effect/data/Duration"
|
|
4
3
|
import { millis } from "@effect/data/Duration"
|
|
@@ -9,6 +8,7 @@ import * as ConfigSecret from "@effect/io/Config/Secret"
|
|
|
9
8
|
import * as Effect from "@effect/io/Effect"
|
|
10
9
|
import * as Layer from "@effect/io/Layer"
|
|
11
10
|
import * as Ref from "@effect/io/Ref"
|
|
11
|
+
import * as Http from "@effect/platform/HttpClient"
|
|
12
12
|
import { DiscordConfig } from "dfx/DiscordConfig"
|
|
13
13
|
import type { ResponseWithData, RestResponse } from "dfx/DiscordREST/types"
|
|
14
14
|
import {
|
|
@@ -17,21 +17,22 @@ import {
|
|
|
17
17
|
routeFromConfig,
|
|
18
18
|
} from "dfx/DiscordREST/utils"
|
|
19
19
|
import { Log } from "dfx/Log"
|
|
20
|
-
import { LiveRateLimiter,
|
|
20
|
+
import { LiveRateLimiter, RateLimiter, RateLimitStore } from "dfx/RateLimit"
|
|
21
21
|
import * as Discord from "dfx/types"
|
|
22
22
|
import { LIB_VERSION } from "dfx/version"
|
|
23
23
|
|
|
24
24
|
export class DiscordRESTError {
|
|
25
25
|
readonly _tag = "DiscordRESTError"
|
|
26
|
-
constructor(
|
|
26
|
+
constructor(
|
|
27
|
+
readonly error: Http.error.HttpClientError,
|
|
28
|
+
readonly body?: unknown,
|
|
29
|
+
) {}
|
|
27
30
|
}
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const make = Effect.gen(function* (_) {
|
|
32
|
+
const make = Effect.gen(function*(_) {
|
|
32
33
|
const { rest, token } = yield* _(DiscordConfig)
|
|
33
34
|
|
|
34
|
-
const http = yield* _(Http.
|
|
35
|
+
const http = yield* _(Http.client.Client)
|
|
35
36
|
const log = yield* _(Log)
|
|
36
37
|
const store = yield* _(RateLimitStore)
|
|
37
38
|
const { maybeWait } = yield* _(RateLimiter)
|
|
@@ -64,13 +65,16 @@ const make = Effect.gen(function* (_) {
|
|
|
64
65
|
Effect.tap(invalid =>
|
|
65
66
|
invalid
|
|
66
67
|
? maybeWait("dfx.rest.invalid", Duration.minutes(10), 10000)
|
|
67
|
-
: Effect.unit
|
|
68
|
+
: Effect.unit
|
|
68
69
|
),
|
|
69
70
|
Effect.asUnit,
|
|
70
71
|
)
|
|
71
72
|
|
|
72
73
|
// Request rate limiting
|
|
73
|
-
const requestRateLimit = (
|
|
74
|
+
const requestRateLimit = (
|
|
75
|
+
path: string,
|
|
76
|
+
request: Http.request.ClientRequest,
|
|
77
|
+
) =>
|
|
74
78
|
Effect.Do.pipe(
|
|
75
79
|
Effect.let("route", () => routeFromConfig(path, request.method)),
|
|
76
80
|
Effect.bind("maybeBucket", ({ route }) => store.getBucketForRoute(route)),
|
|
@@ -86,17 +90,21 @@ const make = Effect.gen(function* (_) {
|
|
|
86
90
|
bucket.limit,
|
|
87
91
|
),
|
|
88
92
|
),
|
|
89
|
-
})
|
|
93
|
+
})
|
|
90
94
|
),
|
|
91
95
|
)
|
|
92
96
|
|
|
93
97
|
// Update rate limit buckets
|
|
94
|
-
const updateBuckets = (
|
|
98
|
+
const updateBuckets = (
|
|
99
|
+
request: Http.request.ClientRequest,
|
|
100
|
+
response: Http.response.ClientResponse,
|
|
101
|
+
) =>
|
|
95
102
|
Effect.Do.pipe(
|
|
96
103
|
Effect.let("route", () => routeFromConfig(request.url, request.method)),
|
|
97
104
|
Effect.bind("rateLimit", () => rateLimitFromHeaders(response.headers)),
|
|
98
|
-
Effect.bind(
|
|
99
|
-
|
|
105
|
+
Effect.bind(
|
|
106
|
+
"hasBucket",
|
|
107
|
+
({ rateLimit }) => store.hasBucket(rateLimit.bucket),
|
|
100
108
|
),
|
|
101
109
|
Effect.flatMap(({ hasBucket, rateLimit, route }) => {
|
|
102
110
|
const effectsToRun = [
|
|
@@ -110,10 +118,9 @@ const make = Effect.gen(function* (_) {
|
|
|
110
118
|
store.putBucket({
|
|
111
119
|
key: rateLimit.bucket,
|
|
112
120
|
resetAfter: Duration.toMillis(rateLimit.retryAfter),
|
|
113
|
-
limit:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
: rateLimit.limit,
|
|
121
|
+
limit: !hasBucket && rateLimit.remaining > 0
|
|
122
|
+
? rateLimit.remaining
|
|
123
|
+
: rateLimit.limit,
|
|
117
124
|
}),
|
|
118
125
|
)
|
|
119
126
|
}
|
|
@@ -127,31 +134,31 @@ const make = Effect.gen(function* (_) {
|
|
|
127
134
|
)
|
|
128
135
|
|
|
129
136
|
const httpExecutor = pipe(
|
|
130
|
-
http
|
|
131
|
-
Http.
|
|
132
|
-
Http.executor.contramap(req =>
|
|
137
|
+
Http.client.filterStatusOk(http),
|
|
138
|
+
Http.client.mapRequest(req =>
|
|
133
139
|
pipe(
|
|
134
|
-
Http.
|
|
135
|
-
Http.setHeaders({
|
|
140
|
+
Http.request.prependUrl(req, rest.baseUrl),
|
|
141
|
+
Http.request.setHeaders({
|
|
136
142
|
Authorization: `Bot ${ConfigSecret.value(token)}`,
|
|
137
|
-
"User-Agent":
|
|
143
|
+
"User-Agent":
|
|
144
|
+
`DiscordBot (https://github.com/tim-smart/dfx, ${LIB_VERSION})`,
|
|
138
145
|
}),
|
|
139
|
-
)
|
|
146
|
+
)
|
|
140
147
|
),
|
|
141
|
-
Http.
|
|
142
|
-
error.
|
|
148
|
+
Http.client.catchAll(error =>
|
|
149
|
+
error.reason === "StatusCode"
|
|
143
150
|
? error.response.json.pipe(
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
: Effect.fail(new DiscordRESTError(error))
|
|
151
|
+
Effect.mapError(_ => new DiscordRESTError(_)),
|
|
152
|
+
Effect.flatMap(body =>
|
|
153
|
+
Effect.fail(new DiscordRESTError(error, body))
|
|
154
|
+
),
|
|
155
|
+
)
|
|
156
|
+
: Effect.fail(new DiscordRESTError(error))
|
|
150
157
|
),
|
|
151
158
|
)
|
|
152
159
|
|
|
153
160
|
const executor = <A = unknown>(
|
|
154
|
-
request: Http.
|
|
161
|
+
request: Http.request.ClientRequest,
|
|
155
162
|
): Effect.Effect<never, DiscordRESTError, ResponseWithData<A>> =>
|
|
156
163
|
requestRateLimit(request.url, request).pipe(
|
|
157
164
|
Effect.zipLeft(globalRateLimit),
|
|
@@ -164,13 +171,13 @@ const make = Effect.gen(function* (_) {
|
|
|
164
171
|
),
|
|
165
172
|
Effect.tap(response => updateBuckets(request, response)),
|
|
166
173
|
Effect.catchTag("DiscordRESTError", e => {
|
|
167
|
-
if (e.error.
|
|
174
|
+
if (e.error.reason !== "StatusCode") {
|
|
168
175
|
return Effect.fail(e)
|
|
169
176
|
}
|
|
170
177
|
|
|
171
178
|
const response = e.error.response
|
|
172
179
|
|
|
173
|
-
switch (
|
|
180
|
+
switch (response.status) {
|
|
174
181
|
case 403:
|
|
175
182
|
return Effect.zipRight(
|
|
176
183
|
Effect.all(
|
|
@@ -194,8 +201,9 @@ const make = Effect.gen(function* (_) {
|
|
|
194
201
|
Effect.zipRight(updateBuckets(request, response)),
|
|
195
202
|
Effect.zipRight(
|
|
196
203
|
Effect.sleep(
|
|
197
|
-
Option.getOrElse(
|
|
198
|
-
|
|
204
|
+
Option.getOrElse(
|
|
205
|
+
retryAfter(response.headers),
|
|
206
|
+
() => Duration.seconds(5),
|
|
199
207
|
),
|
|
200
208
|
),
|
|
201
209
|
),
|
|
@@ -207,28 +215,26 @@ const make = Effect.gen(function* (_) {
|
|
|
207
215
|
}),
|
|
208
216
|
)
|
|
209
217
|
|
|
210
|
-
const routes = Discord.createRoutes<Partial<Http.
|
|
218
|
+
const routes = Discord.createRoutes<Partial<Http.request.Options.NoUrl>>(
|
|
211
219
|
<R, P>({
|
|
212
220
|
method,
|
|
213
221
|
options = {},
|
|
214
222
|
params,
|
|
215
223
|
url,
|
|
216
|
-
}: Discord.Route<P, Partial<Http.
|
|
224
|
+
}: Discord.Route<P, Partial<Http.request.Options.NoUrl>>): RestResponse<
|
|
225
|
+
R
|
|
226
|
+
> => {
|
|
217
227
|
const hasBody = method !== "GET" && method !== "DELETE"
|
|
218
|
-
let request = Http.make(method as any)(url, options)
|
|
228
|
+
let request = Http.request.make(method as any)(url, options)
|
|
219
229
|
|
|
220
230
|
if (!hasBody) {
|
|
221
231
|
if (params) {
|
|
222
|
-
request = Http.
|
|
232
|
+
request = Http.request.appendUrlParams(request, params as any)
|
|
223
233
|
}
|
|
224
|
-
} else if (
|
|
225
|
-
params
|
|
226
|
-
request.body._tag === "Some" &&
|
|
227
|
-
request.body.value._tag === "FormDataBody"
|
|
228
|
-
) {
|
|
229
|
-
request.body.value.value.append("payload_json", JSON.stringify(params))
|
|
234
|
+
} else if (params && request.body._tag === "FormData") {
|
|
235
|
+
request.body.formData.append("payload_json", JSON.stringify(params))
|
|
230
236
|
} else if (params) {
|
|
231
|
-
request = Http.jsonBody(request, params)
|
|
237
|
+
request = Http.request.jsonBody(request, params)
|
|
232
238
|
}
|
|
233
239
|
|
|
234
240
|
return executor(request)
|
|
@@ -242,14 +248,15 @@ const make = Effect.gen(function* (_) {
|
|
|
242
248
|
})
|
|
243
249
|
|
|
244
250
|
export interface DiscordREST
|
|
245
|
-
extends Discord.Endpoints<Partial<Http.
|
|
251
|
+
extends Discord.Endpoints<Partial<Http.request.Options.NoUrl>>
|
|
252
|
+
{
|
|
246
253
|
readonly executor: <A = unknown>(
|
|
247
|
-
request: Http.
|
|
254
|
+
request: Http.request.ClientRequest,
|
|
248
255
|
) => Effect.Effect<never, DiscordRESTError, ResponseWithData<A>>
|
|
249
256
|
}
|
|
250
257
|
|
|
251
258
|
export const DiscordREST = Tag<DiscordREST>()
|
|
252
|
-
export const LiveDiscordREST = Layer.
|
|
253
|
-
LiveRateLimiter,
|
|
254
|
-
Layer.
|
|
259
|
+
export const LiveDiscordREST = Layer.effect(DiscordREST, make).pipe(
|
|
260
|
+
Layer.use(LiveRateLimiter),
|
|
261
|
+
Layer.use(Http.client.fetchLayer),
|
|
255
262
|
)
|
package/src/Helpers/flags.ts
CHANGED
|
@@ -33,16 +33,14 @@ export function toList<T extends Flags<any>>(
|
|
|
33
33
|
* Returns a function that converts a list of flags names to a bigint bitfield.
|
|
34
34
|
*/
|
|
35
35
|
export const fromListBigint =
|
|
36
|
-
<T extends Flags<bigint>>(flags: T) =>
|
|
37
|
-
(list: Array<keyof T>) =>
|
|
36
|
+
<T extends Flags<bigint>>(flags: T) => (list: Array<keyof T>) =>
|
|
38
37
|
list.reduce((acc, key) => acc | flags[key], BigInt(0))
|
|
39
38
|
|
|
40
39
|
/**
|
|
41
40
|
* Returns a function that converts a list of flags names to a bitfield.
|
|
42
41
|
*/
|
|
43
42
|
export const fromList =
|
|
44
|
-
<T extends Flags<number>>(flags: T) =>
|
|
45
|
-
(list: Array<keyof T>) =>
|
|
43
|
+
<T extends Flags<number>>(flags: T) => (list: Array<keyof T>) =>
|
|
46
44
|
list.reduce((acc, key) => acc | flags[key], 0)
|
|
47
45
|
|
|
48
46
|
/**
|
package/src/Helpers/intents.ts
CHANGED
|
@@ -9,10 +9,9 @@ export const ALL = Flags.all(Discord.GatewayIntents)
|
|
|
9
9
|
/**
|
|
10
10
|
* Privileged intents
|
|
11
11
|
*/
|
|
12
|
-
export const PRIVILEGED =
|
|
13
|
-
Discord.GatewayIntents.
|
|
14
|
-
Discord.GatewayIntents.
|
|
15
|
-
Discord.GatewayIntents.MESSAGE_CONTENT
|
|
12
|
+
export const PRIVILEGED = Discord.GatewayIntents.GUILD_PRESENCES
|
|
13
|
+
| Discord.GatewayIntents.GUILD_MEMBERS
|
|
14
|
+
| Discord.GatewayIntents.MESSAGE_CONTENT
|
|
16
15
|
|
|
17
16
|
/**
|
|
18
17
|
* Un-privileged intents
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { identity, pipe } from "@effect/data/Function"
|
|
2
|
+
import * as HashMap from "@effect/data/HashMap"
|
|
1
3
|
import * as Option from "@effect/data/Option"
|
|
2
4
|
import * as Arr from "@effect/data/ReadonlyArray"
|
|
3
5
|
import * as Discord from "dfx/types"
|
|
4
|
-
import { identity, pipe } from "@effect/data/Function"
|
|
5
|
-
import * as HashMap from "@effect/data/HashMap"
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Option find a sub-command within the interaction options.
|
|
@@ -24,8 +24,8 @@ export const findSubCommand =
|
|
|
24
24
|
optionsWithNested(interaction),
|
|
25
25
|
Arr.findFirst(
|
|
26
26
|
o =>
|
|
27
|
-
o.type === Discord.ApplicationCommandOptionType.SUB_COMMAND
|
|
28
|
-
o.name === name,
|
|
27
|
+
o.type === Discord.ApplicationCommandOptionType.SUB_COMMAND
|
|
28
|
+
&& o.name === name,
|
|
29
29
|
),
|
|
30
30
|
)
|
|
31
31
|
|
|
@@ -114,46 +114,42 @@ export const resolved = (data: Discord.Interaction) =>
|
|
|
114
114
|
/**
|
|
115
115
|
* Try find a matching option value from the interaction.
|
|
116
116
|
*/
|
|
117
|
-
export const resolveOptionValue =
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
Option.
|
|
124
|
-
Option.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
Option.flatMapNullable(({ id, r }) => f(id, r)),
|
|
135
|
-
)
|
|
117
|
+
export const resolveOptionValue = <T>(
|
|
118
|
+
name: string,
|
|
119
|
+
f: (id: Discord.Snowflake, data: Discord.ResolvedDatum) => T | undefined,
|
|
120
|
+
) =>
|
|
121
|
+
(a: Discord.Interaction): Option.Option<T> =>
|
|
122
|
+
Option.Do.pipe(
|
|
123
|
+
Option.bind("data", () =>
|
|
124
|
+
Option.fromNullable(a.data as Discord.ApplicationCommandDatum)),
|
|
125
|
+
Option.bind("id", ({ data }) =>
|
|
126
|
+
Option.flatMapNullable(
|
|
127
|
+
getOption(name)(data),
|
|
128
|
+
({ value }) =>
|
|
129
|
+
value as Discord.Snowflake,
|
|
130
|
+
)),
|
|
131
|
+
Option.bind("r", () => resolved(a)),
|
|
132
|
+
Option.flatMapNullable(({ id, r }) => f(id, r)),
|
|
133
|
+
)
|
|
136
134
|
|
|
137
135
|
/**
|
|
138
136
|
* Try find matching option values from the interaction.
|
|
139
137
|
*/
|
|
140
|
-
export const resolveValues =
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
Option.
|
|
146
|
-
Option.
|
|
147
|
-
Option.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
),
|
|
156
|
-
)
|
|
138
|
+
export const resolveValues = <T>(
|
|
139
|
+
f: (id: Discord.Snowflake, data: Discord.ResolvedDatum) => T | undefined,
|
|
140
|
+
) =>
|
|
141
|
+
(a: Discord.Interaction): Option.Option<ReadonlyArray<T>> =>
|
|
142
|
+
Option.Do.pipe(
|
|
143
|
+
Option.bind("values", () =>
|
|
144
|
+
Option.flatMapNullable(
|
|
145
|
+
Option.fromNullable(a.data as Discord.MessageComponentDatum),
|
|
146
|
+
a => a.values as unknown as Array<string>,
|
|
147
|
+
)),
|
|
148
|
+
Option.bind("r", () => resolved(a)),
|
|
149
|
+
Option.map(({ r, values }) =>
|
|
150
|
+
Arr.compact(values.map(a => Option.fromNullable(f(a as any, r))))
|
|
151
|
+
),
|
|
152
|
+
)
|
|
157
153
|
|
|
158
154
|
const extractComponents = (c: Discord.Component): Array<Discord.Component> => {
|
|
159
155
|
if ("components" in c) {
|
|
@@ -215,26 +211,27 @@ export const componentValue =
|
|
|
215
211
|
|
|
216
212
|
export type InteractionResponse =
|
|
217
213
|
| {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
214
|
+
type: Discord.InteractionCallbackType.CHANNEL_MESSAGE_WITH_SOURCE
|
|
215
|
+
data: Discord.InteractionCallbackMessage
|
|
216
|
+
}
|
|
221
217
|
| {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
218
|
+
type: Discord.InteractionCallbackType.UPDATE_MESSAGE
|
|
219
|
+
data: Discord.InteractionCallbackMessage
|
|
220
|
+
}
|
|
225
221
|
| {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
222
|
+
type: Discord.InteractionCallbackType.MODAL
|
|
223
|
+
data: Discord.InteractionCallbackModal
|
|
224
|
+
}
|
|
229
225
|
| {
|
|
230
|
-
|
|
231
|
-
|
|
226
|
+
type: Discord.InteractionCallbackType.DEFERRED_UPDATE_MESSAGE
|
|
227
|
+
}
|
|
232
228
|
| {
|
|
233
|
-
|
|
234
|
-
|
|
229
|
+
type: Discord.InteractionCallbackType.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE
|
|
230
|
+
}
|
|
235
231
|
| {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
232
|
+
type:
|
|
233
|
+
Discord.InteractionCallbackType.APPLICATION_COMMAND_AUTOCOMPLETE_RESULT
|
|
234
|
+
data: Discord.InteractionCallbackAutocomplete
|
|
235
|
+
}
|
|
239
236
|
|
|
240
237
|
export const response = (r: InteractionResponse) => r
|
package/src/Helpers/members.ts
CHANGED
|
@@ -13,5 +13,5 @@ export const roles =
|
|
|
13
13
|
* Type-guard function for checking if the object is a guild member
|
|
14
14
|
*/
|
|
15
15
|
export const is = (thing: unknown): thing is Discord.GuildMember =>
|
|
16
|
-
Object.prototype.hasOwnProperty.call(thing, "roles")
|
|
17
|
-
Object.prototype.hasOwnProperty.call(thing, "joined_at")
|
|
16
|
+
Object.prototype.hasOwnProperty.call(thing, "roles")
|
|
17
|
+
&& Object.prototype.hasOwnProperty.call(thing, "joined_at")
|
|
@@ -84,8 +84,8 @@ export const forChannel =
|
|
|
84
84
|
} else {
|
|
85
85
|
const everyone = roles.find(role => role.name === "@everyone")
|
|
86
86
|
|
|
87
|
-
basePermissions =
|
|
88
|
-
|
|
87
|
+
basePermissions = BigInt(everyone?.permissions || "0")
|
|
88
|
+
| BigInt(memberOrRole.permissions)
|
|
89
89
|
filteredOverwrites = overwrites.filter(
|
|
90
90
|
overwriteIsForRole(guild_id)(memberOrRole),
|
|
91
91
|
)
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import * as Http from "@effect-http/client"
|
|
2
1
|
import * as Chunk from "@effect/data/Chunk"
|
|
3
2
|
import { identity } from "@effect/data/Function"
|
|
4
3
|
import type * as Cause from "@effect/io/Cause"
|
|
5
4
|
import * as Effect from "@effect/io/Effect"
|
|
6
5
|
import { catchTag } from "@effect/io/Effect"
|
|
6
|
+
import * as Http from "@effect/platform/HttpClient"
|
|
7
7
|
import { DiscordREST, type DiscordRESTError } from "dfx/DiscordREST"
|
|
8
|
-
import type * as Discord from "dfx/types"
|
|
9
8
|
import type * as D from "dfx/Interactions/definitions"
|
|
9
|
+
import type * as Discord from "dfx/types"
|
|
10
10
|
|
|
11
|
-
type ExtractTag<A> = A extends { _tag: infer Tag }
|
|
12
|
-
|
|
13
|
-
? Tag
|
|
14
|
-
: never
|
|
11
|
+
type ExtractTag<A> = A extends { _tag: infer Tag } ? Tag extends string ? Tag
|
|
12
|
+
: never
|
|
15
13
|
: never
|
|
16
14
|
|
|
17
15
|
/**
|
|
@@ -132,15 +130,17 @@ export class InteractionBuilder<R, E, TE> {
|
|
|
132
130
|
Chunk.map(c => c.command),
|
|
133
131
|
)
|
|
134
132
|
|
|
135
|
-
return Effect.flatMap(
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
133
|
+
return Effect.flatMap(
|
|
134
|
+
DiscordREST,
|
|
135
|
+
rest =>
|
|
136
|
+
rest.getCurrentBotApplicationInformation().pipe(
|
|
137
|
+
Effect.flatMap(r => r.json),
|
|
138
|
+
Effect.flatMap(app =>
|
|
139
|
+
rest.bulkOverwriteGlobalApplicationCommands(app.id, {
|
|
140
|
+
body: Http.body.json(Chunk.toReadonlyArray(commands)),
|
|
141
|
+
})
|
|
142
|
+
),
|
|
142
143
|
),
|
|
143
|
-
),
|
|
144
144
|
)
|
|
145
145
|
}
|
|
146
146
|
|
|
@@ -154,12 +154,14 @@ export class InteractionBuilder<R, E, TE> {
|
|
|
154
154
|
Chunk.map(c => c.command),
|
|
155
155
|
)
|
|
156
156
|
|
|
157
|
-
return Effect.flatMap(
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
157
|
+
return Effect.flatMap(
|
|
158
|
+
DiscordREST,
|
|
159
|
+
rest =>
|
|
160
|
+
rest.bulkOverwriteGuildApplicationCommands(
|
|
161
|
+
appId,
|
|
162
|
+
guildId,
|
|
163
|
+
Chunk.toReadonlyArray(commands) as any,
|
|
164
|
+
),
|
|
163
165
|
)
|
|
164
166
|
}
|
|
165
167
|
}
|
|
@@ -33,8 +33,7 @@ export const resolvedValues = <A>(
|
|
|
33
33
|
Effect.mapError(
|
|
34
34
|
IxHelpers.resolveValues(f)(ix),
|
|
35
35
|
() => new ResolvedDataNotFound(ix),
|
|
36
|
-
)
|
|
37
|
-
)
|
|
36
|
+
))
|
|
38
37
|
|
|
39
38
|
export const resolved = <A>(
|
|
40
39
|
name: string,
|
|
@@ -44,8 +43,7 @@ export const resolved = <A>(
|
|
|
44
43
|
Effect.mapError(
|
|
45
44
|
IxHelpers.resolveOptionValue(name, f)(ix),
|
|
46
45
|
() => new ResolvedDataNotFound(ix, name),
|
|
47
|
-
)
|
|
48
|
-
)
|
|
46
|
+
))
|
|
49
47
|
|
|
50
48
|
export const focusedOptionValue = Effect.map(
|
|
51
49
|
FocusedOptionContext,
|
|
@@ -66,20 +64,18 @@ export const handleSubCommands = <
|
|
|
66
64
|
commands: NER,
|
|
67
65
|
): Effect.Effect<
|
|
68
66
|
| Exclude<
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
>
|
|
67
|
+
[NER[keyof NER]] extends [
|
|
68
|
+
{ [Effect.EffectTypeId]: { _R: (_: never) => infer R } },
|
|
69
|
+
] ? R
|
|
70
|
+
: never,
|
|
71
|
+
SubCommandContext
|
|
72
|
+
>
|
|
76
73
|
| Discord.Interaction
|
|
77
74
|
| Discord.ApplicationCommandDatum,
|
|
78
75
|
| ([NER[keyof NER]] extends [
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
: never)
|
|
76
|
+
{ [Effect.EffectTypeId]: { _E: (_: never) => infer E } },
|
|
77
|
+
] ? E
|
|
78
|
+
: never)
|
|
83
79
|
| SubCommandNotFound,
|
|
84
80
|
Discord.InteractionResponse
|
|
85
81
|
> =>
|
|
@@ -88,12 +84,12 @@ export const handleSubCommands = <
|
|
|
88
84
|
Effect.mapError(
|
|
89
85
|
Arr.findFirst(IxHelpers.allSubCommands(data), _ => !!commands[_.name]),
|
|
90
86
|
() => new SubCommandNotFound(data),
|
|
91
|
-
)
|
|
87
|
+
)
|
|
92
88
|
),
|
|
93
89
|
Effect.flatMap(command =>
|
|
94
90
|
Effect.provideService(commands[command.name], SubCommandContext, {
|
|
95
91
|
command,
|
|
96
|
-
})
|
|
92
|
+
})
|
|
97
93
|
),
|
|
98
94
|
)
|
|
99
95
|
|
|
@@ -129,12 +125,10 @@ export const optionValue = (name: string) =>
|
|
|
129
125
|
{
|
|
130
126
|
onNone: () =>
|
|
131
127
|
Effect.flatMap(ApplicationCommand, data =>
|
|
132
|
-
Effect.fail(new RequiredOptionNotFound(data, name)),
|
|
133
|
-
),
|
|
128
|
+
Effect.fail(new RequiredOptionNotFound(data, name))),
|
|
134
129
|
onSome: Effect.succeed,
|
|
135
130
|
},
|
|
136
|
-
)
|
|
137
|
-
)
|
|
131
|
+
))
|
|
138
132
|
|
|
139
133
|
export const optionValueOptional = (name: string) =>
|
|
140
134
|
Effect.map(
|
|
@@ -157,5 +151,4 @@ export const modalValue = (name: string) =>
|
|
|
157
151
|
Effect.mapError(
|
|
158
152
|
IxHelpers.componentValue(name)(data),
|
|
159
153
|
() => new ModalValueNotFound(data, name),
|
|
160
|
-
)
|
|
161
|
-
)
|
|
154
|
+
))
|