dfx 0.127.0 → 1.0.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/memory.d.ts +1 -1
- package/Cache/memory.d.ts.map +1 -1
- package/Cache/memory.js +4 -4
- package/Cache/memory.js.map +1 -1
- package/Cache/memoryTTL.d.ts +1 -1
- package/Cache/memoryTTL.d.ts.map +1 -1
- package/Cache/memoryTTL.js +6 -6
- package/Cache/memoryTTL.js.map +1 -1
- package/Cache/prelude.d.ts +6 -6
- package/Cache/prelude.d.ts.map +1 -1
- package/Cache/prelude.js +4 -4
- package/Cache/prelude.js.map +1 -1
- package/Cache.d.ts +9 -10
- package/Cache.d.ts.map +1 -1
- package/Cache.js +20 -19
- package/Cache.js.map +1 -1
- package/DiscordConfig.d.ts +8 -8
- package/DiscordConfig.d.ts.map +1 -1
- package/DiscordConfig.js +8 -7
- package/DiscordConfig.js.map +1 -1
- package/DiscordGateway/DiscordWS.d.ts +12 -12
- package/DiscordGateway/DiscordWS.d.ts.map +1 -1
- package/DiscordGateway/DiscordWS.js +30 -17
- package/DiscordGateway/DiscordWS.js.map +1 -1
- package/DiscordGateway/Messaging.d.ts +204 -10
- package/DiscordGateway/Messaging.d.ts.map +1 -1
- package/DiscordGateway/Messaging.js +10 -7
- package/DiscordGateway/Messaging.js.map +1 -1
- package/DiscordGateway/Shard/StateStore.d.ts +4 -4
- package/DiscordGateway/Shard/StateStore.d.ts.map +1 -1
- package/DiscordGateway/Shard/StateStore.js +7 -6
- package/DiscordGateway/Shard/StateStore.js.map +1 -1
- package/DiscordGateway/Shard/heartbeats.d.ts +5 -5
- package/DiscordGateway/Shard/heartbeats.d.ts.map +1 -1
- package/DiscordGateway/Shard/heartbeats.js +15 -10
- package/DiscordGateway/Shard/heartbeats.js.map +1 -1
- package/DiscordGateway/Shard/identify.d.ts +2 -2
- package/DiscordGateway/Shard/identify.d.ts.map +1 -1
- package/DiscordGateway/Shard/identify.js +2 -2
- package/DiscordGateway/Shard/identify.js.map +1 -1
- package/DiscordGateway/Shard/sendEvents.d.ts +1 -1
- package/DiscordGateway/Shard/sendEvents.d.ts.map +1 -1
- package/DiscordGateway/Shard/sendEvents.js +1 -1
- package/DiscordGateway/Shard/sendEvents.js.map +1 -1
- package/DiscordGateway/Shard/utils.d.ts +1 -1
- package/DiscordGateway/Shard/utils.d.ts.map +1 -1
- package/DiscordGateway/Shard.d.ts +16 -15
- package/DiscordGateway/Shard.d.ts.map +1 -1
- package/DiscordGateway/Shard.js +27 -21
- package/DiscordGateway/Shard.js.map +1 -1
- package/DiscordGateway/ShardStore.d.ts +4 -3
- package/DiscordGateway/ShardStore.d.ts.map +1 -1
- package/DiscordGateway/ShardStore.js +3 -2
- package/DiscordGateway/ShardStore.js.map +1 -1
- package/DiscordGateway/Sharder.d.ts +9 -8
- package/DiscordGateway/Sharder.d.ts.map +1 -1
- package/DiscordGateway/Sharder.js +19 -17
- package/DiscordGateway/Sharder.js.map +1 -1
- package/DiscordGateway.d.ts +13 -12
- package/DiscordGateway.d.ts.map +1 -1
- package/DiscordGateway.js +4 -4
- package/DiscordGateway.js.map +1 -1
- package/DiscordREST/Generated.d.ts +402 -240
- package/DiscordREST/Generated.d.ts.map +1 -1
- package/DiscordREST/Generated.js +193 -126
- package/DiscordREST/Generated.js.map +1 -1
- package/DiscordREST/utils.d.ts +1 -1
- 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 +10 -11
- package/DiscordREST.d.ts.map +1 -1
- package/DiscordREST.js +23 -27
- package/DiscordREST.js.map +1 -1
- package/Helpers/flags.d.ts.map +1 -1
- package/Helpers/flags.js +10 -1
- package/Helpers/flags.js.map +1 -1
- package/Helpers/intents.d.ts.map +1 -1
- package/Helpers/intents.js +2 -2
- package/Helpers/intents.js.map +1 -1
- package/Helpers/interactions.d.ts +2 -2
- package/Helpers/interactions.d.ts.map +1 -1
- package/Helpers/interactions.js +12 -12
- package/Helpers/interactions.js.map +1 -1
- package/Helpers/members.d.ts +2 -2
- package/Helpers/members.d.ts.map +1 -1
- package/Helpers/members.js +1 -1
- package/Helpers/members.js.map +1 -1
- package/Helpers/permissions.d.ts +1 -1
- package/Helpers/permissions.d.ts.map +1 -1
- package/Helpers/permissions.js +4 -4
- package/Helpers/permissions.js.map +1 -1
- package/Helpers/ui.d.ts +9 -9
- package/Helpers/ui.d.ts.map +1 -1
- package/Helpers/ui.js +15 -15
- package/Helpers/ui.js.map +1 -1
- package/Interactions/builder.d.ts +6 -6
- package/Interactions/builder.d.ts.map +1 -1
- package/Interactions/builder.js +7 -7
- package/Interactions/builder.js.map +1 -1
- package/Interactions/commandHelper.d.ts +3 -19
- package/Interactions/commandHelper.d.ts.map +1 -1
- package/Interactions/commandHelper.js +11 -7
- package/Interactions/commandHelper.js.map +1 -1
- package/Interactions/context.d.ts +30 -31
- package/Interactions/context.d.ts.map +1 -1
- package/Interactions/context.js +23 -18
- package/Interactions/context.js.map +1 -1
- package/Interactions/definitions.d.ts +7 -8
- package/Interactions/definitions.d.ts.map +1 -1
- package/Interactions/gateway.d.ts +11 -12
- package/Interactions/gateway.d.ts.map +1 -1
- package/Interactions/gateway.js +22 -20
- package/Interactions/gateway.js.map +1 -1
- package/Interactions/handlers.d.ts +3 -3
- package/Interactions/handlers.d.ts.map +1 -1
- package/Interactions/handlers.js +5 -4
- package/Interactions/handlers.js.map +1 -1
- package/Interactions/index.d.ts +5 -4
- package/Interactions/index.d.ts.map +1 -1
- package/Interactions/index.js +4 -4
- package/Interactions/index.js.map +1 -1
- package/Interactions/utils.d.ts +4 -4
- package/Interactions/utils.d.ts.map +1 -1
- package/Interactions/utils.js +1 -1
- package/Interactions/utils.js.map +1 -1
- package/Interactions/webhook.d.ts +9 -11
- package/Interactions/webhook.d.ts.map +1 -1
- package/Interactions/webhook.js +16 -16
- package/Interactions/webhook.js.map +1 -1
- package/RateLimit/memory.d.ts +1 -1
- package/RateLimit/memory.d.ts.map +1 -1
- package/RateLimit/memory.js +2 -2
- package/RateLimit/memory.js.map +1 -1
- package/RateLimit.d.ts +7 -7
- package/RateLimit.d.ts.map +1 -1
- package/RateLimit.js +7 -5
- package/RateLimit.js.map +1 -1
- package/gateway.d.ts +14 -14
- package/gateway.d.ts.map +1 -1
- package/gateway.js +10 -10
- package/gateway.js.map +1 -1
- package/index.d.ts +14 -14
- package/index.d.ts.map +1 -1
- package/index.js +12 -12
- package/index.js.map +1 -1
- package/mjs/Cache/memory.mjs +4 -4
- package/mjs/Cache/memory.mjs.map +1 -1
- package/mjs/Cache/memoryTTL.mjs +6 -6
- package/mjs/Cache/memoryTTL.mjs.map +1 -1
- package/mjs/Cache/prelude.mjs +4 -4
- package/mjs/Cache/prelude.mjs.map +1 -1
- package/mjs/Cache.mjs +20 -19
- package/mjs/Cache.mjs.map +1 -1
- package/mjs/DiscordConfig.mjs +7 -7
- package/mjs/DiscordConfig.mjs.map +1 -1
- package/mjs/DiscordGateway/DiscordWS.mjs +28 -17
- package/mjs/DiscordGateway/DiscordWS.mjs.map +1 -1
- package/mjs/DiscordGateway/Messaging.mjs +9 -7
- package/mjs/DiscordGateway/Messaging.mjs.map +1 -1
- package/mjs/DiscordGateway/Shard/StateStore.mjs +7 -6
- package/mjs/DiscordGateway/Shard/StateStore.mjs.map +1 -1
- package/mjs/DiscordGateway/Shard/heartbeats.mjs +15 -10
- package/mjs/DiscordGateway/Shard/heartbeats.mjs.map +1 -1
- package/mjs/DiscordGateway/Shard/identify.mjs +2 -2
- package/mjs/DiscordGateway/Shard/identify.mjs.map +1 -1
- package/mjs/DiscordGateway/Shard/sendEvents.mjs +1 -1
- package/mjs/DiscordGateway/Shard/sendEvents.mjs.map +1 -1
- package/mjs/DiscordGateway/Shard.mjs +26 -21
- 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 +18 -17
- package/mjs/DiscordGateway/Sharder.mjs.map +1 -1
- package/mjs/DiscordGateway.mjs +4 -4
- package/mjs/DiscordGateway.mjs.map +1 -1
- package/mjs/DiscordREST/Generated.mjs +192 -125
- package/mjs/DiscordREST/Generated.mjs.map +1 -1
- package/mjs/DiscordREST/utils.mjs +4 -3
- package/mjs/DiscordREST/utils.mjs.map +1 -1
- package/mjs/DiscordREST.mjs +22 -27
- package/mjs/DiscordREST.mjs.map +1 -1
- package/mjs/Helpers/flags.mjs +10 -1
- package/mjs/Helpers/flags.mjs.map +1 -1
- package/mjs/Helpers/intents.mjs +2 -2
- package/mjs/Helpers/intents.mjs.map +1 -1
- package/mjs/Helpers/interactions.mjs +12 -12
- package/mjs/Helpers/interactions.mjs.map +1 -1
- package/mjs/Helpers/members.mjs +1 -1
- package/mjs/Helpers/members.mjs.map +1 -1
- package/mjs/Helpers/permissions.mjs +4 -4
- package/mjs/Helpers/permissions.mjs.map +1 -1
- package/mjs/Helpers/ui.mjs +15 -15
- package/mjs/Helpers/ui.mjs.map +1 -1
- package/mjs/Interactions/builder.mjs +7 -7
- package/mjs/Interactions/builder.mjs.map +1 -1
- package/mjs/Interactions/commandHelper.mjs +11 -7
- package/mjs/Interactions/commandHelper.mjs.map +1 -1
- package/mjs/Interactions/context.mjs +17 -18
- package/mjs/Interactions/context.mjs.map +1 -1
- package/mjs/Interactions/gateway.mjs +21 -20
- package/mjs/Interactions/gateway.mjs.map +1 -1
- package/mjs/Interactions/handlers.mjs +5 -4
- package/mjs/Interactions/handlers.mjs.map +1 -1
- package/mjs/Interactions/index.mjs +4 -4
- package/mjs/Interactions/index.mjs.map +1 -1
- package/mjs/Interactions/utils.mjs +1 -1
- package/mjs/Interactions/utils.mjs.map +1 -1
- package/mjs/Interactions/webhook.mjs +15 -16
- package/mjs/Interactions/webhook.mjs.map +1 -1
- package/mjs/RateLimit/memory.mjs +2 -2
- package/mjs/RateLimit/memory.mjs.map +1 -1
- package/mjs/RateLimit.mjs +5 -5
- package/mjs/RateLimit.mjs.map +1 -1
- package/mjs/gateway.mjs +14 -14
- package/mjs/gateway.mjs.map +1 -1
- package/mjs/index.mjs +14 -14
- package/mjs/index.mjs.map +1 -1
- package/mjs/types.mjs +2 -2
- package/mjs/types.mjs.map +1 -1
- package/mjs/utils/Effect.mjs +34 -8
- package/mjs/utils/Effect.mjs.map +1 -1
- package/mjs/version.mjs +1 -1
- package/mjs/version.mjs.map +1 -1
- package/mjs/webhooks.mjs +3 -3
- package/mjs/webhooks.mjs.map +1 -1
- package/package.json +4 -5
- package/src/Cache/memory.ts +5 -5
- package/src/Cache/memoryTTL.ts +7 -7
- package/src/Cache/prelude.ts +10 -8
- package/src/Cache.ts +31 -35
- package/src/DiscordConfig.ts +13 -17
- package/src/DiscordGateway/DiscordWS.ts +58 -32
- package/src/DiscordGateway/Messaging.ts +13 -15
- package/src/DiscordGateway/Shard/StateStore.ts +30 -25
- package/src/DiscordGateway/Shard/heartbeats.ts +25 -28
- package/src/DiscordGateway/Shard/identify.ts +5 -4
- package/src/DiscordGateway/Shard/sendEvents.ts +1 -1
- package/src/DiscordGateway/Shard/utils.ts +1 -1
- package/src/DiscordGateway/Shard.ts +39 -35
- package/src/DiscordGateway/ShardStore.ts +6 -7
- package/src/DiscordGateway/Sharder.ts +31 -29
- package/src/DiscordGateway.ts +15 -14
- package/src/DiscordREST/Generated.ts +683 -378
- package/src/DiscordREST/utils.ts +6 -3
- package/src/DiscordREST.ts +37 -41
- package/src/Helpers/flags.ts +10 -5
- package/src/Helpers/intents.ts +2 -2
- package/src/Helpers/interactions.ts +16 -14
- package/src/Helpers/members.ts +3 -3
- package/src/Helpers/permissions.ts +5 -5
- package/src/Helpers/ui.ts +16 -16
- package/src/Interactions/builder.ts +10 -10
- package/src/Interactions/commandHelper.ts +18 -29
- package/src/Interactions/context.ts +51 -65
- package/src/Interactions/definitions.ts +3 -3
- package/src/Interactions/gateway.ts +33 -45
- package/src/Interactions/handlers.ts +8 -5
- package/src/Interactions/index.ts +5 -5
- package/src/Interactions/utils.ts +6 -6
- package/src/Interactions/webhook.ts +31 -38
- package/src/RateLimit/memory.ts +3 -3
- package/src/RateLimit.ts +18 -15
- package/src/gateway.ts +21 -21
- package/src/index.ts +17 -17
- package/src/types.ts +18 -16
- package/src/utils/Effect.ts +38 -27
- package/src/version.ts +1 -1
- package/src/webhooks.ts +7 -7
- package/tsconfig.base.json +12 -6
- package/tsconfig.examples.json +0 -1
- package/types.d.ts +4 -3
- package/types.d.ts.map +1 -1
- package/types.js +3 -3
- package/types.js.map +1 -1
- package/utils/Effect.d.ts.map +1 -1
- package/utils/Effect.js +33 -7
- package/utils/Effect.js.map +1 -1
- package/version.d.ts +1 -1
- package/version.d.ts.map +1 -1
- package/version.js +1 -1
- package/version.js.map +1 -1
- package/webhooks.d.ts +5 -5
- package/webhooks.d.ts.map +1 -1
- package/webhooks.js +3 -3
- package/webhooks.js.map +1 -1
package/src/DiscordREST/utils.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as Duration from "effect/Duration"
|
|
2
|
+
import { pipe } from "effect/Function"
|
|
2
3
|
import * as Option from "effect/Option"
|
|
3
|
-
import * as Headers from "
|
|
4
|
+
import * as Headers from "effect/unstable/http/Headers"
|
|
4
5
|
|
|
5
6
|
const majorResources = ["channels", "guilds", "webhooks"] as const
|
|
6
7
|
|
|
@@ -18,7 +19,9 @@ export const routeFromConfig = (path: string, method: string) => {
|
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export const numberHeader = (headers: Headers.Headers) => (key: string) =>
|
|
21
|
-
|
|
22
|
+
pipe(
|
|
23
|
+
Headers.get(headers, key),
|
|
24
|
+
Option.fromUndefinedOr,
|
|
22
25
|
Option.map(parseFloat),
|
|
23
26
|
Option.filter(n => !isNaN(n)),
|
|
24
27
|
)
|
|
@@ -31,7 +34,7 @@ export const retryAfter = (headers: Headers.Headers) =>
|
|
|
31
34
|
|
|
32
35
|
export const rateLimitFromHeaders = (headers: Headers.Headers) =>
|
|
33
36
|
Option.all({
|
|
34
|
-
bucket: Headers.get(headers, "x-ratelimit-bucket"),
|
|
37
|
+
bucket: Option.fromUndefinedOr(Headers.get(headers, "x-ratelimit-bucket")),
|
|
35
38
|
retryAfter: retryAfter(headers),
|
|
36
39
|
limit: numberHeader(headers)("x-ratelimit-limit"),
|
|
37
40
|
remaining: numberHeader(headers)("x-ratelimit-remaining"),
|
package/src/DiscordREST.ts
CHANGED
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as HttpClient from "@effect/platform/HttpClient"
|
|
3
|
-
import type { HttpClientError } from "@effect/platform/HttpClientError"
|
|
4
|
-
import * as HttpRequest from "@effect/platform/HttpClientRequest"
|
|
5
|
-
import type * as HttpResponse from "@effect/platform/HttpClientResponse"
|
|
6
|
-
import { DiscordConfig } from "dfx/DiscordConfig"
|
|
1
|
+
import { DiscordConfig } from "./DiscordConfig.ts"
|
|
7
2
|
import {
|
|
8
3
|
rateLimitFromHeaders,
|
|
9
4
|
retryAfter,
|
|
10
5
|
routeFromConfig,
|
|
11
|
-
} from "
|
|
12
|
-
import { RateLimitStore, RateLimiter, RateLimiterLive } from "
|
|
13
|
-
import * as Discord from "
|
|
14
|
-
import { LIB_VERSION } from "
|
|
15
|
-
import * as Context from "effect/Context"
|
|
16
|
-
import { GenericTag } from "effect/Context"
|
|
6
|
+
} from "./DiscordREST/utils.ts"
|
|
7
|
+
import { RateLimitStore, RateLimiter, RateLimiterLive } from "./RateLimit.ts"
|
|
8
|
+
import * as Discord from "./types.ts"
|
|
9
|
+
import { LIB_VERSION } from "./version.ts"
|
|
17
10
|
import * as Duration from "effect/Duration"
|
|
18
11
|
import { millis } from "effect/Duration"
|
|
19
12
|
import * as Effect from "effect/Effect"
|
|
@@ -22,6 +15,12 @@ import { flow } from "effect/Function"
|
|
|
22
15
|
import * as Layer from "effect/Layer"
|
|
23
16
|
import * as Option from "effect/Option"
|
|
24
17
|
import * as Redacted from "effect/Redacted"
|
|
18
|
+
import * as ServiceMap from "effect/ServiceMap"
|
|
19
|
+
import * as HttpBody from "effect/unstable/http/HttpBody"
|
|
20
|
+
import * as HttpClient from "effect/unstable/http/HttpClient"
|
|
21
|
+
import type { HttpClientError } from "effect/unstable/http/HttpClientError"
|
|
22
|
+
import * as HttpRequest from "effect/unstable/http/HttpClientRequest"
|
|
23
|
+
import type * as HttpResponse from "effect/unstable/http/HttpClientResponse"
|
|
25
24
|
|
|
26
25
|
const make = Effect.gen(function* () {
|
|
27
26
|
const { rest, token } = yield* DiscordConfig
|
|
@@ -31,7 +30,7 @@ const make = Effect.gen(function* () {
|
|
|
31
30
|
|
|
32
31
|
const globalRateLimit = maybeWait(
|
|
33
32
|
"dfx.rest.global",
|
|
34
|
-
Duration.
|
|
33
|
+
Duration.fromInputUnsafe(rest.globalRateLimit.window),
|
|
35
34
|
rest.globalRateLimit.limit,
|
|
36
35
|
)
|
|
37
36
|
|
|
@@ -44,7 +43,7 @@ const make = Effect.gen(function* () {
|
|
|
44
43
|
badRoutes.add(route)
|
|
45
44
|
return Effect.log("bad route")
|
|
46
45
|
}).pipe(
|
|
47
|
-
Effect.
|
|
46
|
+
Effect.andThen(
|
|
48
47
|
store.incrementCounter("dfx.rest.invalid", tenMinutesMillis, 10000),
|
|
49
48
|
),
|
|
50
49
|
Effect.annotateLogs("route", route),
|
|
@@ -84,19 +83,19 @@ const make = Effect.gen(function* () {
|
|
|
84
83
|
if (Option.isNone(rateLimitOption)) return
|
|
85
84
|
const rateLimit = rateLimitOption.value
|
|
86
85
|
const hasBucket = yield* store.hasBucket(rateLimit.bucket)
|
|
87
|
-
const fibers: Array<Fiber.
|
|
86
|
+
const fibers: Array<Fiber.Fiber<unknown, unknown>> = []
|
|
88
87
|
|
|
89
88
|
badRoutes.delete(route)
|
|
90
89
|
fibers.push(
|
|
91
|
-
yield* Effect.
|
|
90
|
+
yield* Effect.forkChild(store.putBucketRoute(route, rateLimit.bucket)),
|
|
92
91
|
)
|
|
93
92
|
|
|
94
93
|
if (!hasBucket || rateLimit.limit - 1 === rateLimit.remaining) {
|
|
95
94
|
fibers.push(
|
|
96
|
-
yield* Effect.
|
|
95
|
+
yield* Effect.forkChild(store.removeCounter(`dfx.rest.?.${route}`)),
|
|
97
96
|
)
|
|
98
97
|
fibers.push(
|
|
99
|
-
yield* Effect.
|
|
98
|
+
yield* Effect.forkChild(
|
|
100
99
|
store.putBucket({
|
|
101
100
|
key: rateLimit.bucket,
|
|
102
101
|
resetAfter: Duration.toMillis(rateLimit.retryAfter),
|
|
@@ -109,19 +108,17 @@ const make = Effect.gen(function* () {
|
|
|
109
108
|
)
|
|
110
109
|
}
|
|
111
110
|
|
|
112
|
-
|
|
113
|
-
if (!fiber.unsafePoll()) {
|
|
114
|
-
yield* fiber.await
|
|
115
|
-
}
|
|
116
|
-
}
|
|
111
|
+
yield* Fiber.awaitAll(fibers)
|
|
117
112
|
})
|
|
118
113
|
|
|
119
114
|
const defaultClient = (yield* HttpClient.HttpClient).pipe(
|
|
120
|
-
HttpClient.
|
|
115
|
+
HttpClient.transformResponse(
|
|
116
|
+
Effect.provideService(HttpClient.TracerPropagationEnabled, false),
|
|
117
|
+
),
|
|
121
118
|
)
|
|
122
119
|
const rateLimitedClient: HttpClient.HttpClient = defaultClient.pipe(
|
|
123
120
|
HttpClient.tapRequest(request =>
|
|
124
|
-
Effect.
|
|
121
|
+
Effect.andThen(requestRateLimit(request.url, request), globalRateLimit),
|
|
125
122
|
),
|
|
126
123
|
HttpClient.transformResponse(
|
|
127
124
|
flow(
|
|
@@ -153,18 +150,18 @@ const make = Effect.gen(function* () {
|
|
|
153
150
|
"url",
|
|
154
151
|
request.url,
|
|
155
152
|
).pipe(
|
|
156
|
-
Effect.
|
|
153
|
+
Effect.andThen(
|
|
157
154
|
addBadRoute(routeFromConfig(request.url, request.method)),
|
|
158
155
|
),
|
|
159
|
-
Effect.
|
|
160
|
-
Effect.
|
|
156
|
+
Effect.andThen(updateBuckets(request, response)),
|
|
157
|
+
Effect.andThen(
|
|
161
158
|
Effect.sleep(
|
|
162
159
|
Option.getOrElse(retryAfter(response.headers), () =>
|
|
163
160
|
Duration.seconds(5),
|
|
164
161
|
),
|
|
165
162
|
),
|
|
166
163
|
),
|
|
167
|
-
Effect.
|
|
164
|
+
Effect.andThen(rateLimitedClient.execute(request)),
|
|
168
165
|
)
|
|
169
166
|
}
|
|
170
167
|
|
|
@@ -180,7 +177,7 @@ const make = Effect.gen(function* () {
|
|
|
180
177
|
|
|
181
178
|
const httpClient = HttpClient.mapRequestInputEffect(rateLimitedClient, req =>
|
|
182
179
|
Effect.sync(() => {
|
|
183
|
-
const fiber =
|
|
180
|
+
const fiber = Fiber.getCurrent()!
|
|
184
181
|
let request = req.pipe(
|
|
185
182
|
HttpRequest.prependUrl(rest.baseUrl),
|
|
186
183
|
HttpRequest.setHeaders({
|
|
@@ -188,7 +185,7 @@ const make = Effect.gen(function* () {
|
|
|
188
185
|
"User-Agent": `DiscordBot (https://github.com/tim-smart/dfx, ${LIB_VERSION})`,
|
|
189
186
|
}),
|
|
190
187
|
)
|
|
191
|
-
const formData =
|
|
188
|
+
const formData = ServiceMap.getOption(fiber.services, DiscordFormData)
|
|
192
189
|
if (Option.isSome(formData)) {
|
|
193
190
|
if (request.body._tag === "Uint8Array") {
|
|
194
191
|
formData.value.set(
|
|
@@ -233,13 +230,10 @@ export type DiscordRESTError =
|
|
|
233
230
|
| Discord.DiscordRestError<"RatelimitedResponse", Discord.RatelimitedResponse>
|
|
234
231
|
| Discord.DiscordRestError<"ErrorResponse", Discord.ErrorResponse>
|
|
235
232
|
|
|
236
|
-
export class DiscordFormData extends
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
export interface DiscordREST {
|
|
241
|
-
readonly _: unique symbol
|
|
242
|
-
}
|
|
233
|
+
export class DiscordFormData extends ServiceMap.Service<
|
|
234
|
+
DiscordFormData,
|
|
235
|
+
FormData
|
|
236
|
+
>()("dfx/DiscordREST/DiscordFormData") {}
|
|
243
237
|
|
|
244
238
|
export interface DiscordRestService extends Discord.DiscordRest {
|
|
245
239
|
withFormData(
|
|
@@ -250,9 +244,11 @@ export interface DiscordRestService extends Discord.DiscordRest {
|
|
|
250
244
|
): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>
|
|
251
245
|
}
|
|
252
246
|
|
|
253
|
-
export
|
|
254
|
-
|
|
255
|
-
|
|
247
|
+
export class DiscordREST extends ServiceMap.Service<
|
|
248
|
+
DiscordREST,
|
|
249
|
+
DiscordRestService
|
|
250
|
+
>()("dfx/DiscordREST") {}
|
|
251
|
+
|
|
256
252
|
export const DiscordRESTLive: Layer.Layer<
|
|
257
253
|
DiscordREST,
|
|
258
254
|
never,
|
package/src/Helpers/flags.ts
CHANGED
|
@@ -22,11 +22,16 @@ export function toList<T extends Flags<any>>(
|
|
|
22
22
|
flags: T,
|
|
23
23
|
): (bitfield: any) => Array<keyof T> {
|
|
24
24
|
const entries = Object.entries(flags)
|
|
25
|
-
return val =>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
[]
|
|
29
|
-
|
|
25
|
+
return val => {
|
|
26
|
+
const out = []
|
|
27
|
+
for (let i = 0; i < entries.length; i++) {
|
|
28
|
+
const [key, flag] = entries[i]
|
|
29
|
+
if ((val & flag) === flag) {
|
|
30
|
+
out.push(key)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return out
|
|
34
|
+
}
|
|
30
35
|
}
|
|
31
36
|
|
|
32
37
|
/**
|
package/src/Helpers/intents.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as Discord from "
|
|
1
|
+
import * as Discord from "../types.ts"
|
|
2
2
|
import * as Arr from "effect/Array"
|
|
3
3
|
import { identity, pipe } from "effect/Function"
|
|
4
4
|
import * as HashMap from "effect/HashMap"
|
|
@@ -73,7 +73,7 @@ export const isSubCommand =
|
|
|
73
73
|
*/
|
|
74
74
|
export const subCommandOptions =
|
|
75
75
|
(name: string) => (_: Discord.APIApplicationCommandInteraction["data"]) =>
|
|
76
|
-
Option.
|
|
76
|
+
Option.flatMapNullishOr(findSubCommand(name)(_), o => o.options)
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
79
|
* A lens for accessing nested options in a interaction.
|
|
@@ -86,7 +86,7 @@ export const optionsWithNested = (data: {
|
|
|
86
86
|
const optsFromOption = (opt: {
|
|
87
87
|
readonly options?: ReadonlyArray<Discord.APIApplicationCommandInteractionDataOption>
|
|
88
88
|
}): Array<Discord.APIApplicationCommandInteractionDataOption> =>
|
|
89
|
-
Option.
|
|
89
|
+
Option.fromNullishOr(opt.options).pipe(
|
|
90
90
|
Option.map(opts => [
|
|
91
91
|
...opts,
|
|
92
92
|
...opts.flatMap(_ => optsFromOption(_ as any)),
|
|
@@ -94,7 +94,7 @@ export const optionsWithNested = (data: {
|
|
|
94
94
|
Option.match({ onNone: () => [], onSome: identity }),
|
|
95
95
|
)
|
|
96
96
|
|
|
97
|
-
return Option.
|
|
97
|
+
return Option.fromNullishOr(data.options).pipe(
|
|
98
98
|
Option.map(opts => [
|
|
99
99
|
...opts,
|
|
100
100
|
...opts.flatMap(_ => optsFromOption(_ as any)),
|
|
@@ -158,7 +158,7 @@ export const optionValue =
|
|
|
158
158
|
| ReadonlyArray<Discord.APIApplicationCommandInteractionDataOption>
|
|
159
159
|
| undefined
|
|
160
160
|
}) =>
|
|
161
|
-
Option.
|
|
161
|
+
Option.flatMapNullishOr(getOption(name)(data), o =>
|
|
162
162
|
"value" in o ? o.value : undefined,
|
|
163
163
|
)
|
|
164
164
|
|
|
@@ -166,7 +166,7 @@ export const optionValue =
|
|
|
166
166
|
* Try extract resolved data
|
|
167
167
|
*/
|
|
168
168
|
export const resolved = (data: Discord.APIInteraction) =>
|
|
169
|
-
Option.
|
|
169
|
+
Option.flatMapNullishOr(Option.fromNullishOr(data.data), a =>
|
|
170
170
|
"resolved" in a
|
|
171
171
|
? (a.resolved as Discord.InteractionDataResolved)
|
|
172
172
|
: undefined,
|
|
@@ -185,15 +185,15 @@ export const resolveOptionValue =
|
|
|
185
185
|
) =>
|
|
186
186
|
(a: Discord.APIInteraction): Option.Option<T> =>
|
|
187
187
|
Option.Do.pipe(
|
|
188
|
-
Option.bind("data", () => Option.
|
|
188
|
+
Option.bind("data", () => Option.fromNullishOr(a.data as any)),
|
|
189
189
|
Option.bind("id", ({ data }) =>
|
|
190
|
-
Option.
|
|
190
|
+
Option.flatMapNullishOr(
|
|
191
191
|
getOption(name)(data) as Option.Option<{ value: Discord.Snowflake }>,
|
|
192
192
|
({ value }) => value,
|
|
193
193
|
),
|
|
194
194
|
),
|
|
195
195
|
Option.bind("r", () => resolved(a)),
|
|
196
|
-
Option.
|
|
196
|
+
Option.flatMapNullishOr(({ id, r }) => f(id, r)),
|
|
197
197
|
)
|
|
198
198
|
|
|
199
199
|
/**
|
|
@@ -209,14 +209,16 @@ export const resolveValues =
|
|
|
209
209
|
(a: Discord.APIInteraction): Option.Option<ReadonlyArray<T>> =>
|
|
210
210
|
Option.Do.pipe(
|
|
211
211
|
Option.bind("values", () =>
|
|
212
|
-
Option.
|
|
213
|
-
Option.
|
|
214
|
-
|
|
212
|
+
Option.flatMapNullishOr(
|
|
213
|
+
Option.fromNullishOr(a.data as any),
|
|
214
|
+
data => data.values as unknown as Array<string>,
|
|
215
215
|
),
|
|
216
216
|
),
|
|
217
217
|
Option.bind("r", () => resolved(a)),
|
|
218
218
|
Option.map(({ r, values }) =>
|
|
219
|
-
Arr.getSomes(
|
|
219
|
+
Arr.getSomes(
|
|
220
|
+
values.map(value => Option.fromNullishOr(f(value as any, r))),
|
|
221
|
+
),
|
|
220
222
|
),
|
|
221
223
|
)
|
|
222
224
|
|
|
@@ -276,7 +278,7 @@ export const getComponent =
|
|
|
276
278
|
*/
|
|
277
279
|
export const componentValue =
|
|
278
280
|
(id: string) => (data: Discord.APIModalSubmission) =>
|
|
279
|
-
Option.
|
|
281
|
+
Option.flatMapNullishOr(
|
|
280
282
|
getComponent(id)(data),
|
|
281
283
|
o => (o as Discord.TextInputComponentResponse).value,
|
|
282
284
|
)
|
package/src/Helpers/members.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type * as Discord from "
|
|
1
|
+
import type * as Discord from "../types.ts"
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* From a list of roles, filter out the ones the guild member has.
|
|
5
5
|
*/
|
|
6
6
|
export const roles =
|
|
7
|
-
(
|
|
7
|
+
(guildRoles: Array<Discord.GuildRoleResponse>) =>
|
|
8
8
|
(member: Discord.GuildMemberResponse) =>
|
|
9
|
-
|
|
9
|
+
guildRoles.filter(
|
|
10
10
|
role => member.roles.includes(role.id) || role.name === "@everyone",
|
|
11
11
|
)
|
|
12
12
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { pipe } from "effect/Function"
|
|
2
2
|
import * as Effect from "effect/Effect"
|
|
3
|
-
import * as Flags from "
|
|
4
|
-
import * as Members from "
|
|
5
|
-
import * as Discord from "
|
|
3
|
+
import * as Flags from "./flags.ts"
|
|
4
|
+
import * as Members from "./members.ts"
|
|
5
|
+
import * as Discord from "../types.ts"
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* A constant of all the permissions
|
|
@@ -108,8 +108,8 @@ export const applyOverwrites =
|
|
|
108
108
|
(permissions: bigint) =>
|
|
109
109
|
(overwrites: ReadonlyArray<Discord.ChannelPermissionOverwriteResponse>) =>
|
|
110
110
|
overwrites.reduce(
|
|
111
|
-
(
|
|
112
|
-
(
|
|
111
|
+
(current, overwrite) =>
|
|
112
|
+
(current & ~BigInt(overwrite.deny)) | BigInt(overwrite.allow),
|
|
113
113
|
permissions,
|
|
114
114
|
)
|
|
115
115
|
|
package/src/Helpers/ui.ts
CHANGED
|
@@ -19,13 +19,13 @@ import type {
|
|
|
19
19
|
TextInputComponentForModalRequest,
|
|
20
20
|
ThumbnailComponentForMessageRequest,
|
|
21
21
|
UserSelectComponentForMessageRequest,
|
|
22
|
-
} from "
|
|
22
|
+
} from "../types.ts"
|
|
23
23
|
import {
|
|
24
24
|
TextInputStyleTypes,
|
|
25
25
|
ButtonStyleTypes,
|
|
26
26
|
MessageComponentTypes,
|
|
27
27
|
MessageFlags,
|
|
28
|
-
} from "
|
|
28
|
+
} from "../types.ts"
|
|
29
29
|
|
|
30
30
|
type ActionRowComponents = ReadonlyArray<
|
|
31
31
|
| ActionRowComponentForMessageRequest["components"][number]
|
|
@@ -69,61 +69,61 @@ export const singleColumn = <C extends ActionRowComponents>(
|
|
|
69
69
|
* Helper to create a button component.
|
|
70
70
|
*/
|
|
71
71
|
export const button = (
|
|
72
|
-
|
|
72
|
+
options: Partial<ButtonComponentForMessageRequest>,
|
|
73
73
|
): ButtonComponentForMessageRequest => ({
|
|
74
74
|
type: MessageComponentTypes.BUTTON,
|
|
75
75
|
style: ButtonStyleTypes.PRIMARY,
|
|
76
|
-
...
|
|
76
|
+
...options,
|
|
77
77
|
})
|
|
78
78
|
|
|
79
79
|
/**
|
|
80
80
|
* Helper to create a select component.
|
|
81
81
|
*/
|
|
82
82
|
export const select = (
|
|
83
|
-
|
|
83
|
+
options: Omit<StringSelectComponentForMessageRequest, "type">,
|
|
84
84
|
): StringSelectComponentForMessageRequest => ({
|
|
85
85
|
type: MessageComponentTypes.STRING_SELECT,
|
|
86
|
-
...
|
|
86
|
+
...options,
|
|
87
87
|
})
|
|
88
88
|
|
|
89
89
|
/**
|
|
90
90
|
* Helper to create a select component.
|
|
91
91
|
*/
|
|
92
92
|
export const userSelect = (
|
|
93
|
-
|
|
93
|
+
options: Omit<UserSelectComponentForMessageRequest, "type">,
|
|
94
94
|
): UserSelectComponentForMessageRequest => ({
|
|
95
95
|
type: MessageComponentTypes.USER_SELECT,
|
|
96
|
-
...
|
|
96
|
+
...options,
|
|
97
97
|
})
|
|
98
98
|
|
|
99
99
|
/**
|
|
100
100
|
* Helper to create a select component.
|
|
101
101
|
*/
|
|
102
102
|
export const roleSelect = (
|
|
103
|
-
|
|
103
|
+
options: Omit<RoleSelectComponentForMessageRequest, "type">,
|
|
104
104
|
): RoleSelectComponentForMessageRequest => ({
|
|
105
105
|
type: MessageComponentTypes.ROLE_SELECT,
|
|
106
|
-
...
|
|
106
|
+
...options,
|
|
107
107
|
})
|
|
108
108
|
|
|
109
109
|
/**
|
|
110
110
|
* Helper to create a select component.
|
|
111
111
|
*/
|
|
112
112
|
export const mentionableSelect = (
|
|
113
|
-
|
|
113
|
+
options: Omit<MentionableSelectComponentForMessageRequest, "type">,
|
|
114
114
|
): MentionableSelectComponentForMessageRequest => ({
|
|
115
115
|
type: MessageComponentTypes.MENTIONABLE_SELECT,
|
|
116
|
-
...
|
|
116
|
+
...options,
|
|
117
117
|
})
|
|
118
118
|
|
|
119
119
|
/**
|
|
120
120
|
* Helper to create a select component.
|
|
121
121
|
*/
|
|
122
122
|
export const channelSelect = (
|
|
123
|
-
|
|
123
|
+
options: Omit<ChannelSelectComponentForMessageRequest, "type">,
|
|
124
124
|
): ChannelSelectComponentForMessageRequest => ({
|
|
125
125
|
type: MessageComponentTypes.CHANNEL_SELECT,
|
|
126
|
-
...
|
|
126
|
+
...options,
|
|
127
127
|
})
|
|
128
128
|
|
|
129
129
|
type TextInputOpts = Omit<
|
|
@@ -238,7 +238,7 @@ type MessageComponents = NonNullable<MessageCreateRequest["components"]>[number]
|
|
|
238
238
|
* Create a components v2 message
|
|
239
239
|
*/
|
|
240
240
|
export const components = <const C extends ReadonlyArray<MessageComponents>>(
|
|
241
|
-
|
|
241
|
+
items: C,
|
|
242
242
|
options?: {
|
|
243
243
|
readonly ephemeral?: boolean | undefined
|
|
244
244
|
},
|
|
@@ -249,5 +249,5 @@ export const components = <const C extends ReadonlyArray<MessageComponents>>(
|
|
|
249
249
|
flags: options?.ephemeral
|
|
250
250
|
? MessageFlags.Ephemeral | MessageFlags.IsComponentsV2
|
|
251
251
|
: MessageFlags.IsComponentsV2,
|
|
252
|
-
components,
|
|
252
|
+
components: items,
|
|
253
253
|
})
|
|
@@ -3,10 +3,10 @@ import { identity } from "effect/Function"
|
|
|
3
3
|
import type * as Cause from "effect/Cause"
|
|
4
4
|
import * as Effect from "effect/Effect"
|
|
5
5
|
import { catchTag } from "effect/Effect"
|
|
6
|
-
import type { DiscordRESTError } from "
|
|
7
|
-
import { DiscordREST } from "
|
|
8
|
-
import type * as D from "
|
|
9
|
-
import type * as Discord from "
|
|
6
|
+
import type { DiscordRESTError } from "../DiscordREST.ts"
|
|
7
|
+
import { DiscordREST } from "../DiscordREST.ts"
|
|
8
|
+
import type * as D from "./definitions.ts"
|
|
9
|
+
import type * as Discord from "../types.ts"
|
|
10
10
|
|
|
11
11
|
type ExtractTag<A> = A extends { _tag: infer Tag }
|
|
12
12
|
? Tag extends string
|
|
@@ -78,7 +78,7 @@ export class InteractionBuilder<R, E, TE> {
|
|
|
78
78
|
catchAllCause<R1, E1>(
|
|
79
79
|
f: (cause: Cause.Cause<TE>) => Effect.Effect<void, E1, R1>,
|
|
80
80
|
) {
|
|
81
|
-
return this.transformTransform<R | R1, E1>(Effect.
|
|
81
|
+
return this.transformTransform<R | R1, E1>(Effect.catchCause(f))
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
catchAllCauseRespond<R1, E1>(
|
|
@@ -86,11 +86,11 @@ export class InteractionBuilder<R, E, TE> {
|
|
|
86
86
|
cause: Cause.Cause<E>,
|
|
87
87
|
) => Effect.Effect<Discord.CreateInteractionResponseRequest, E1, R1>,
|
|
88
88
|
) {
|
|
89
|
-
return this.transformHandlers<R | R1, E1>(Effect.
|
|
89
|
+
return this.transformHandlers<R | R1, E1>(Effect.catchCause(f))
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
catchAll<R1, E1>(f: (error: TE) => Effect.Effect<void, E1, R1>) {
|
|
93
|
-
return this.transformTransform<R | R1, E1>(Effect.
|
|
93
|
+
return this.transformTransform<R | R1, E1>(Effect.catch(f))
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
catchAllRespond<R1, E1>(
|
|
@@ -98,7 +98,7 @@ export class InteractionBuilder<R, E, TE> {
|
|
|
98
98
|
error: E,
|
|
99
99
|
) => Effect.Effect<Discord.CreateInteractionResponseRequest, E1, R1>,
|
|
100
100
|
) {
|
|
101
|
-
return this.transformHandlers<R | R1, E1>(Effect.
|
|
101
|
+
return this.transformHandlers<R | R1, E1>(Effect.catch(f))
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
catchTag<T extends ExtractTag<E>, R1, E1>(
|
|
@@ -131,7 +131,7 @@ export class InteractionBuilder<R, E, TE> {
|
|
|
131
131
|
Chunk.map(c => c.command),
|
|
132
132
|
)
|
|
133
133
|
|
|
134
|
-
return
|
|
134
|
+
return DiscordREST.use(rest =>
|
|
135
135
|
rest
|
|
136
136
|
.getMyApplication()
|
|
137
137
|
.pipe(
|
|
@@ -155,7 +155,7 @@ export class InteractionBuilder<R, E, TE> {
|
|
|
155
155
|
Chunk.map(c => c.command),
|
|
156
156
|
)
|
|
157
157
|
|
|
158
|
-
return
|
|
158
|
+
return DiscordREST.use(rest =>
|
|
159
159
|
rest.bulkSetGuildApplicationCommands(
|
|
160
160
|
appId,
|
|
161
161
|
guildId,
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import * as Option from "effect/Option"
|
|
2
2
|
import * as Effect from "effect/Effect"
|
|
3
3
|
import {
|
|
4
|
+
type DiscordSubCommand,
|
|
4
5
|
SubCommandContext,
|
|
5
6
|
SubCommandNotFound,
|
|
6
7
|
type DiscordApplicationCommand,
|
|
7
8
|
type DiscordInteraction,
|
|
8
|
-
} from "
|
|
9
|
-
import type * as Discord from "
|
|
10
|
-
import * as Helpers from "
|
|
9
|
+
} from "./context.ts"
|
|
10
|
+
import type * as Discord from "../types.ts"
|
|
11
|
+
import * as Helpers from "../Helpers/interactions.ts"
|
|
11
12
|
import * as Arr from "effect/Array"
|
|
12
13
|
import type { HashMap } from "effect/HashMap"
|
|
13
14
|
|
|
@@ -82,37 +83,25 @@ export class CommandHelper<A> {
|
|
|
82
83
|
>(
|
|
83
84
|
commands: NER,
|
|
84
85
|
): Effect.Effect<
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
]
|
|
89
|
-
? E
|
|
90
|
-
: never,
|
|
91
|
-
| Exclude<
|
|
92
|
-
[NER[keyof NER]] extends [
|
|
93
|
-
{ [Effect.EffectTypeId]: { _R: (_: never) => infer R } },
|
|
94
|
-
]
|
|
95
|
-
? R
|
|
96
|
-
: never,
|
|
97
|
-
SubCommandContext
|
|
98
|
-
>
|
|
86
|
+
Effect.Success<NER[keyof NER]>,
|
|
87
|
+
Effect.Error<NER[keyof NER]>,
|
|
88
|
+
| Exclude<Effect.Services<NER[keyof NER]>, DiscordSubCommand>
|
|
99
89
|
| DiscordInteraction
|
|
100
90
|
| DiscordApplicationCommand
|
|
101
91
|
> {
|
|
102
92
|
const commands_ = commands as Record<string, any>
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
Effect.provideService(commands_[
|
|
112
|
-
command,
|
|
93
|
+
const matchedCommand = Arr.findFirst(
|
|
94
|
+
Helpers.allSubCommands(this.data),
|
|
95
|
+
_ => !!commands_[_.name],
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
return Option.match(matchedCommand, {
|
|
99
|
+
onNone: () => Effect.fail(new SubCommandNotFound({ data: this.data })),
|
|
100
|
+
onSome: subCommand =>
|
|
101
|
+
Effect.provideService(commands_[subCommand.name], SubCommandContext, {
|
|
102
|
+
command: subCommand,
|
|
113
103
|
}),
|
|
114
|
-
|
|
115
|
-
) as any
|
|
104
|
+
}) as any
|
|
116
105
|
}
|
|
117
106
|
|
|
118
107
|
get optionsMap(): HashMap<string, string | undefined> {
|