dfx 0.9.7 → 0.9.8

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.
Files changed (208) hide show
  1. package/package.json +7 -6
  2. package/README.md +0 -41
  3. package/dist/DiscordConfig/index.d.ts +0 -40
  4. package/dist/DiscordConfig/index.d.ts.map +0 -1
  5. package/dist/DiscordConfig/index.js +0 -29
  6. package/dist/DiscordConfig/index.js.map +0 -1
  7. package/dist/DiscordGateway/DiscordWS/index.d.ts +0 -24
  8. package/dist/DiscordGateway/DiscordWS/index.d.ts.map +0 -1
  9. package/dist/DiscordGateway/DiscordWS/index.js +0 -26
  10. package/dist/DiscordGateway/DiscordWS/index.js.map +0 -1
  11. package/dist/DiscordGateway/Shard/heartbeats.d.ts +0 -4
  12. package/dist/DiscordGateway/Shard/heartbeats.d.ts.map +0 -1
  13. package/dist/DiscordGateway/Shard/heartbeats.js +0 -24
  14. package/dist/DiscordGateway/Shard/heartbeats.js.map +0 -1
  15. package/dist/DiscordGateway/Shard/identify.d.ts +0 -13
  16. package/dist/DiscordGateway/Shard/identify.d.ts.map +0 -1
  17. package/dist/DiscordGateway/Shard/identify.js +0 -30
  18. package/dist/DiscordGateway/Shard/identify.js.map +0 -1
  19. package/dist/DiscordGateway/Shard/index.d.ts +0 -10
  20. package/dist/DiscordGateway/Shard/index.d.ts.map +0 -1
  21. package/dist/DiscordGateway/Shard/index.js +0 -52
  22. package/dist/DiscordGateway/Shard/index.js.map +0 -1
  23. package/dist/DiscordGateway/Shard/invalidSession.d.ts +0 -4
  24. package/dist/DiscordGateway/Shard/invalidSession.d.ts.map +0 -1
  25. package/dist/DiscordGateway/Shard/invalidSession.js +0 -10
  26. package/dist/DiscordGateway/Shard/invalidSession.js.map +0 -1
  27. package/dist/DiscordGateway/Shard/sendEvents.d.ts +0 -8
  28. package/dist/DiscordGateway/Shard/sendEvents.d.ts.map +0 -1
  29. package/dist/DiscordGateway/Shard/sendEvents.js +0 -26
  30. package/dist/DiscordGateway/Shard/sendEvents.js.map +0 -1
  31. package/dist/DiscordGateway/Shard/utils.d.ts +0 -4
  32. package/dist/DiscordGateway/Shard/utils.d.ts.map +0 -1
  33. package/dist/DiscordGateway/Shard/utils.js +0 -9
  34. package/dist/DiscordGateway/Shard/utils.js.map +0 -1
  35. package/dist/DiscordGateway/ShardStore/index.d.ts +0 -13
  36. package/dist/DiscordGateway/ShardStore/index.d.ts.map +0 -1
  37. package/dist/DiscordGateway/ShardStore/index.js +0 -22
  38. package/dist/DiscordGateway/ShardStore/index.js.map +0 -1
  39. package/dist/DiscordGateway/Sharder/index.d.ts +0 -10
  40. package/dist/DiscordGateway/Sharder/index.d.ts.map +0 -1
  41. package/dist/DiscordGateway/Sharder/index.js +0 -61
  42. package/dist/DiscordGateway/Sharder/index.js.map +0 -1
  43. package/dist/DiscordGateway/WS/index.d.ts +0 -28
  44. package/dist/DiscordGateway/WS/index.d.ts.map +0 -1
  45. package/dist/DiscordGateway/WS/index.js +0 -82
  46. package/dist/DiscordGateway/WS/index.js.map +0 -1
  47. package/dist/DiscordGateway/index.d.ts +0 -21
  48. package/dist/DiscordGateway/index.d.ts.map +0 -1
  49. package/dist/DiscordGateway/index.js +0 -27
  50. package/dist/DiscordGateway/index.js.map +0 -1
  51. package/dist/DiscordREST/index.d.ts +0 -13
  52. package/dist/DiscordREST/index.d.ts.map +0 -1
  53. package/dist/DiscordREST/index.js +0 -85
  54. package/dist/DiscordREST/index.js.map +0 -1
  55. package/dist/DiscordREST/types.d.ts +0 -10
  56. package/dist/DiscordREST/types.d.ts.map +0 -1
  57. package/dist/DiscordREST/types.js +0 -2
  58. package/dist/DiscordREST/types.js.map +0 -1
  59. package/dist/DiscordREST/utils.d.ts +0 -11
  60. package/dist/DiscordREST/utils.d.ts.map +0 -1
  61. package/dist/DiscordREST/utils.js +0 -22
  62. package/dist/DiscordREST/utils.js.map +0 -1
  63. package/dist/Helpers/flags.d.ts +0 -28
  64. package/dist/Helpers/flags.d.ts.map +0 -1
  65. package/dist/Helpers/flags.js +0 -36
  66. package/dist/Helpers/flags.js.map +0 -1
  67. package/dist/Helpers/intents.d.ts +0 -25
  68. package/dist/Helpers/intents.d.ts.map +0 -1
  69. package/dist/Helpers/intents.js +0 -28
  70. package/dist/Helpers/intents.js.map +0 -1
  71. package/dist/Helpers/interactions.d.ts +0 -74
  72. package/dist/Helpers/interactions.d.ts.map +0 -1
  73. package/dist/Helpers/interactions.js +0 -93
  74. package/dist/Helpers/interactions.js.map +0 -1
  75. package/dist/Helpers/members.d.ts +0 -10
  76. package/dist/Helpers/members.d.ts.map +0 -1
  77. package/dist/Helpers/members.js +0 -10
  78. package/dist/Helpers/members.js.map +0 -1
  79. package/dist/Helpers/permissions.d.ts +0 -35
  80. package/dist/Helpers/permissions.d.ts.map +0 -1
  81. package/dist/Helpers/permissions.js +0 -69
  82. package/dist/Helpers/permissions.js.map +0 -1
  83. package/dist/Helpers/ui.d.ts +0 -48
  84. package/dist/Helpers/ui.d.ts.map +0 -1
  85. package/dist/Helpers/ui.js +0 -67
  86. package/dist/Helpers/ui.js.map +0 -1
  87. package/dist/Http/index.d.ts +0 -31
  88. package/dist/Http/index.d.ts.map +0 -1
  89. package/dist/Http/index.js +0 -53
  90. package/dist/Http/index.js.map +0 -1
  91. package/dist/Interactions/context.d.ts +0 -37
  92. package/dist/Interactions/context.d.ts.map +0 -1
  93. package/dist/Interactions/context.js +0 -34
  94. package/dist/Interactions/context.js.map +0 -1
  95. package/dist/Interactions/definitions.d.ts +0 -61
  96. package/dist/Interactions/definitions.d.ts.map +0 -1
  97. package/dist/Interactions/definitions.js +0 -52
  98. package/dist/Interactions/definitions.js.map +0 -1
  99. package/dist/Interactions/gateway.d.ts +0 -7
  100. package/dist/Interactions/gateway.d.ts.map +0 -1
  101. package/dist/Interactions/gateway.js +0 -21
  102. package/dist/Interactions/gateway.js.map +0 -1
  103. package/dist/Interactions/handlers.d.ts +0 -9
  104. package/dist/Interactions/handlers.d.ts.map +0 -1
  105. package/dist/Interactions/handlers.js +0 -49
  106. package/dist/Interactions/handlers.js.map +0 -1
  107. package/dist/Interactions/index.d.ts +0 -18
  108. package/dist/Interactions/index.d.ts.map +0 -1
  109. package/dist/Interactions/index.js +0 -39
  110. package/dist/Interactions/index.js.map +0 -1
  111. package/dist/Interactions/utils.d.ts +0 -11
  112. package/dist/Interactions/utils.d.ts.map +0 -1
  113. package/dist/Interactions/utils.js +0 -61
  114. package/dist/Interactions/utils.js.map +0 -1
  115. package/dist/Interactions/webhook.d.ts +0 -33
  116. package/dist/Interactions/webhook.d.ts.map +0 -1
  117. package/dist/Interactions/webhook.js +0 -42
  118. package/dist/Interactions/webhook.js.map +0 -1
  119. package/dist/Log/index.d.ts +0 -13
  120. package/dist/Log/index.d.ts.map +0 -1
  121. package/dist/Log/index.js +0 -19
  122. package/dist/Log/index.js.map +0 -1
  123. package/dist/RateLimitStore/index.d.ts +0 -25
  124. package/dist/RateLimitStore/index.d.ts.map +0 -1
  125. package/dist/RateLimitStore/index.js +0 -24
  126. package/dist/RateLimitStore/index.js.map +0 -1
  127. package/dist/RateLimitStore/memory.d.ts +0 -3
  128. package/dist/RateLimitStore/memory.d.ts.map +0 -1
  129. package/dist/RateLimitStore/memory.js +0 -31
  130. package/dist/RateLimitStore/memory.js.map +0 -1
  131. package/dist/RateLimitStore/utils.d.ts +0 -3
  132. package/dist/RateLimitStore/utils.d.ts.map +0 -1
  133. package/dist/RateLimitStore/utils.js +0 -18
  134. package/dist/RateLimitStore/utils.js.map +0 -1
  135. package/dist/common-gateway.d.ts +0 -6
  136. package/dist/common-gateway.d.ts.map +0 -1
  137. package/dist/common-gateway.js +0 -6
  138. package/dist/common-gateway.js.map +0 -1
  139. package/dist/common.d.ts +0 -29
  140. package/dist/common.d.ts.map +0 -1
  141. package/dist/common.js +0 -16
  142. package/dist/common.js.map +0 -1
  143. package/dist/global.d.ts +0 -18
  144. package/dist/global.d.ts.map +0 -1
  145. package/dist/global.js +0 -2
  146. package/dist/global.js.map +0 -1
  147. package/dist/index.d.ts +0 -22
  148. package/dist/index.d.ts.map +0 -1
  149. package/dist/index.js +0 -29
  150. package/dist/index.js.map +0 -1
  151. package/dist/types.d.ts +0 -4229
  152. package/dist/types.d.ts.map +0 -1
  153. package/dist/types.js +0 -1796
  154. package/dist/types.js.map +0 -1
  155. package/dist/utils/effect.d.ts +0 -3
  156. package/dist/utils/effect.d.ts.map +0 -1
  157. package/dist/utils/effect.js +0 -2
  158. package/dist/utils/effect.js.map +0 -1
  159. package/dist/utils/tsplus.d.ts +0 -14
  160. package/dist/utils/tsplus.d.ts.map +0 -1
  161. package/dist/utils/tsplus.js +0 -2
  162. package/dist/utils/tsplus.js.map +0 -1
  163. package/dist/webhooks.d.ts +0 -16
  164. package/dist/webhooks.d.ts.map +0 -1
  165. package/dist/webhooks.js +0 -23
  166. package/dist/webhooks.js.map +0 -1
  167. package/src/DiscordConfig/index.ts +0 -52
  168. package/src/DiscordGateway/DiscordWS/index.ts +0 -50
  169. package/src/DiscordGateway/Shard/heartbeats.ts +0 -39
  170. package/src/DiscordGateway/Shard/identify.ts +0 -61
  171. package/src/DiscordGateway/Shard/index.ts +0 -90
  172. package/src/DiscordGateway/Shard/invalidSession.ts +0 -11
  173. package/src/DiscordGateway/Shard/sendEvents.ts +0 -35
  174. package/src/DiscordGateway/Shard/utils.ts +0 -14
  175. package/src/DiscordGateway/ShardStore/index.ts +0 -33
  176. package/src/DiscordGateway/Sharder/index.ts +0 -95
  177. package/src/DiscordGateway/WS/index.ts +0 -99
  178. package/src/DiscordGateway/index.ts +0 -55
  179. package/src/DiscordREST/index.ts +0 -132
  180. package/src/DiscordREST/types.ts +0 -14
  181. package/src/DiscordREST/utils.ts +0 -35
  182. package/src/Helpers/flags.ts +0 -68
  183. package/src/Helpers/intents.ts +0 -32
  184. package/src/Helpers/interactions.ts +0 -180
  185. package/src/Helpers/members.ts +0 -14
  186. package/src/Helpers/permissions.ts +0 -102
  187. package/src/Helpers/ui.ts +0 -103
  188. package/src/Http/index.ts +0 -65
  189. package/src/Interactions/context.ts +0 -100
  190. package/src/Interactions/definitions.ts +0 -144
  191. package/src/Interactions/gateway.ts +0 -55
  192. package/src/Interactions/handlers.ts +0 -139
  193. package/src/Interactions/index.ts +0 -83
  194. package/src/Interactions/utils.ts +0 -81
  195. package/src/Interactions/webhook.ts +0 -96
  196. package/src/Log/index.ts +0 -23
  197. package/src/RateLimitStore/index.ts +0 -65
  198. package/src/RateLimitStore/memory.ts +0 -48
  199. package/src/RateLimitStore/utils.ts +0 -27
  200. package/src/common-gateway.ts +0 -5
  201. package/src/common.ts +0 -30
  202. package/src/global.ts +0 -50
  203. package/src/index.ts +0 -36
  204. package/src/json.d.ts +0 -1
  205. package/src/types.ts +0 -6095
  206. package/src/utils/effect.ts +0 -7
  207. package/src/utils/tsplus.ts +0 -11
  208. package/src/webhooks.ts +0 -30
@@ -1,95 +0,0 @@
1
- import { millis } from "@fp-ts/data/Duration"
2
- import { overridePull } from "callbag-effect-ts/Source"
3
- import { ShardStore } from "../ShardStore/index.js"
4
-
5
- const configs = (totalCount: number) =>
6
- Do(($) => {
7
- const store = $(Effect.service(ShardStore))
8
- const claimId = (sharderCount: number) =>
9
- store
10
- .claimId({
11
- totalCount,
12
- sharderCount,
13
- })
14
- .flatMap(
15
- (
16
- a,
17
- ): Effect<
18
- never,
19
- never,
20
- readonly [Maybe<number>, EffectSource<never, never, number>]
21
- > =>
22
- a.match(
23
- () =>
24
- Effect.succeed([
25
- Maybe.some(sharderCount),
26
- EffectSource.empty,
27
- ] as const).delay(Duration.minutes(3)),
28
- (id) =>
29
- Effect.succeed([
30
- Maybe.some(sharderCount + 1),
31
- EffectSource.of(id),
32
- ]),
33
- ),
34
- )
35
-
36
- return EffectSource.resource(0, (sharderCount) =>
37
- EffectSource.fromEffect(claimId(sharderCount)),
38
- ).map((id) => ({
39
- id,
40
- totalCount,
41
- }))
42
- })
43
-
44
- const spawnEffect = Effect.structPar({
45
- gateway: Rest.rest
46
- .getGatewayBot()
47
- .flatMap((r) => r.json)
48
- .catchAll(() =>
49
- Effect.succeed<Discord.GetGatewayBotResponse>({
50
- url: "wss://gateway.discord.gg/",
51
- shards: 1,
52
- session_start_limit: {
53
- total: 0,
54
- remaining: 0,
55
- reset_after: 0,
56
- max_concurrency: 1,
57
- },
58
- }),
59
- ),
60
- config: Config.gateway,
61
- limiter: Effect.service(RateLimitStore.RateLimiter),
62
- })
63
- .bind("configs", ({ gateway, config }) =>
64
- configs(config.shardCount ?? gateway.shards),
65
- )
66
- .map(({ gateway, config, configs, limiter }) => {
67
- const [source, pull] = overridePull(
68
- configs,
69
- gateway.session_start_limit.max_concurrency,
70
- )
71
-
72
- return source
73
- .map((config) => ({
74
- ...config,
75
- url: gateway.url,
76
- concurrency: gateway.session_start_limit.max_concurrency,
77
- }))
78
- .groupBy((c) => c.id % c.concurrency)
79
- .chainPar(([shardConfig, key]) =>
80
- shardConfig
81
- .tap(() =>
82
- limiter.maybeWait(
83
- `gateway.sharder.${key}`,
84
- millis(config.identifyRateLimit[0]),
85
- config.identifyRateLimit[1],
86
- ),
87
- )
88
- .mapEffect((c) => Shard.make([c.id, c.totalCount])),
89
- )
90
- .tap(() => Effect.sync(pull))
91
- })
92
-
93
- export const spawn = spawnEffect.unwrap.chainPar((shard) =>
94
- EffectSource.of(shard).merge(EffectSource.fromEffect(shard.run).drain),
95
- )
@@ -1,99 +0,0 @@
1
- import WebSocket from "isomorphic-ws"
2
-
3
- export const Reconnect = Symbol()
4
- export type Reconnect = typeof Reconnect
5
- export type Message = string | Buffer | ArrayBuffer | Reconnect
6
-
7
- const socket = (urlRef: Ref<string>, options?: WebSocket.ClientOptions) =>
8
- Do(($) => {
9
- const url = $(urlRef.get)
10
- return new WebSocket(url, options)
11
- }).acquireRelease((ws) =>
12
- Effect.sync(() => {
13
- ws.close()
14
- ws.removeAllListeners()
15
- }),
16
- )
17
-
18
- export class WebSocketError {
19
- readonly _tag = "WebSocketError"
20
- constructor(readonly reason: unknown) {}
21
- }
22
-
23
- export class WebSocketCloseError {
24
- readonly _tag = "WebSocketCloseError"
25
- constructor(readonly code: number, readonly reason: string) {}
26
- }
27
-
28
- const recv = (ws: WebSocket) =>
29
- EffectSource.async<WebSocketError | WebSocketCloseError, WebSocket.RawData>(
30
- (emit) => {
31
- ws.on("message", (message) => {
32
- emit.data(message)
33
- })
34
-
35
- ws.on("error", (cause) => {
36
- emit.fail(new WebSocketError(cause))
37
- })
38
-
39
- ws.on("close", (code, reason) => {
40
- emit.fail(new WebSocketCloseError(code, reason.toString("utf8")))
41
- })
42
- },
43
- )
44
-
45
- export class WebSocketWriteError {
46
- readonly _tag = "WebSocketWriteError"
47
- constructor(readonly reason: Error) {}
48
- }
49
-
50
- const send = (ws: WebSocket, out: EffectSource<never, never, Message>) =>
51
- Do(($) => {
52
- const log = $(Effect.service(Log.Log))
53
- return Effect.async<never, never, void>((resume) => {
54
- if (ws.readyState & ws.OPEN) {
55
- resume(Effect.unit())
56
- } else {
57
- ws.once("open", () => {
58
- resume(Effect.unit())
59
- })
60
- }
61
- })
62
- .map(() => out)
63
- .unwrap.tap((p) => log.debug("WS", "send", p))
64
- .tap((data) =>
65
- Effect.async<never, WebSocketWriteError, void>((resume) => {
66
- if (data === Reconnect) {
67
- ws.close(1012, "reconnecting")
68
- resume(Effect.unit())
69
- } else {
70
- ws.send(data, (err) => {
71
- resume(
72
- err
73
- ? Effect.fail(new WebSocketWriteError(err!))
74
- : Effect.unit(),
75
- )
76
- })
77
- }
78
- }),
79
- ).drain
80
- })
81
-
82
- export const make = (url: Ref<string>, options?: WebSocket.ClientOptions) =>
83
- Do(($) => {
84
- const [sink, outbound] = EffectSource.asyncSink<never, Message>()
85
- const log = $(Effect.service(Log.Log))
86
- const withLog = Effect.provideService(Log.Log)(log)
87
-
88
- const source = Do(($) => {
89
- const ws = $(socket(url, options))
90
- const sendEffect = $(withLog(send(ws, outbound)))
91
- return recv(ws).merge(sendEffect)
92
- }).unwrapScope.retry(
93
- Schedule.recurWhile(
94
- (e) => e._tag === "WebSocketCloseError" && e.code === 1012,
95
- ),
96
- )
97
-
98
- return { source, sink }
99
- })
@@ -1,55 +0,0 @@
1
- import { spawn } from "./Sharder/index.js"
2
-
3
- const fromDispatchFactory =
4
- <R, E>(
5
- source: EffectSource<R, E, Discord.GatewayPayload<Discord.ReceiveEvent>>,
6
- ) =>
7
- <K extends keyof Discord.ReceiveEvents>(
8
- event: K,
9
- ): EffectSource<R, E, Discord.ReceiveEvents[K]> =>
10
- source.filter((p) => p.t === event).map((p) => p.d! as any)
11
-
12
- const handleDispatchFactory =
13
- <R, E>(
14
- source: EffectSource<R, E, Discord.GatewayPayload<Discord.ReceiveEvent>>,
15
- ) =>
16
- <K extends keyof Discord.ReceiveEvents, R1, E1, A>(
17
- event: K,
18
- handle: (event: Discord.ReceiveEvents[K]) => Effect<R1, E1, A>,
19
- ): Effect<R | R1, E | E1, void> =>
20
- source
21
- .filter((p) => p.t === event)
22
- .chainPar((a) => EffectSource.fromEffect(handle(a.d as any))).runDrain
23
-
24
- export const make = Do(($) => {
25
- const shards = $(spawn.share)
26
- const raw = $(shards.chainPar((s) => s.raw).share)
27
- const dispatch = $(shards.chainPar((s) => s.dispatch).share)
28
- const fromDispatch = fromDispatchFactory(dispatch)
29
- const handleDispatch = handleDispatchFactory(dispatch)
30
-
31
- return {
32
- shards,
33
- raw,
34
- dispatch,
35
- fromDispatch,
36
- handleDispatch,
37
- }
38
- })
39
-
40
- export interface DiscordGateway extends Success<typeof make> {}
41
- export const DiscordGateway = Tag<DiscordGateway>()
42
- export const LiveDiscordGateway = Layer.fromEffect(DiscordGateway)(make)
43
-
44
- export const handleDispatch = <
45
- K extends keyof Discord.ReceiveEvents,
46
- R1,
47
- E1,
48
- A,
49
- >(
50
- event: K,
51
- handle: (event: Discord.ReceiveEvents[K]) => Effect<R1, E1, A>,
52
- ) =>
53
- Effect.serviceWithEffect(DiscordGateway)((a) =>
54
- a.handleDispatch(event, handle),
55
- )
@@ -1,132 +0,0 @@
1
- import { millis } from "@fp-ts/data/Duration"
2
- import { BucketDetails } from "dfx/RateLimitStore/index"
3
- import { ResponseWithData } from "./types.js"
4
- import { rateLimitFromHeaders, routeFromConfig } from "./utils.js"
5
- import Pkg from "../../package.json" assert { type: "json" }
6
-
7
- const make = Do(($) => {
8
- const { token, rest } = $(Effect.service(Config.DiscordConfig))
9
-
10
- const log = $(Effect.service(Log.Log))
11
- const store = $(Effect.service(RateLimitStore.RateLimitStore))
12
- const { maybeWait } = $(Effect.service(RateLimitStore.RateLimiter))
13
-
14
- const globalRateLimit = maybeWait(
15
- "rest.global",
16
- rest.globalRateLimit.window,
17
- rest.globalRateLimit.limit,
18
- )
19
-
20
- const requestRateLimit = (path: string, init: RequestInit) =>
21
- Do(($) => {
22
- const route = routeFromConfig(path, init)
23
- const maybeBucket = $(store.getBucketForRoute(route))
24
- const bucket = maybeBucket.getOrElse(
25
- (): BucketDetails => ({
26
- key: `?.${Equal.hash(route)}`,
27
- resetAfter: 5000,
28
- limit: 1,
29
- }),
30
- )
31
- const resetAfter = millis(bucket.resetAfter)
32
- $(maybeWait(`rest.bucket.${bucket.key}`, resetAfter, bucket.limit))
33
- })
34
-
35
- const updateBuckets = (path: string, init: RequestInit, response: Response) =>
36
- Do(($) => {
37
- const route = routeFromConfig(path, init)
38
- const { bucket, retryAfter, limit, remaining } = $(
39
- Effect.fromOption(rateLimitFromHeaders(response.headers)),
40
- )
41
-
42
- const effectsToRun = [store.putBucketRoute(route, bucket)]
43
-
44
- const hasBucket = $(store.hasBucket(bucket))
45
- if (!hasBucket || limit - 1 === remaining) {
46
- effectsToRun.push(
47
- store.putBucket({
48
- key: bucket,
49
- resetAfter: retryAfter.millis,
50
- limit: !hasBucket && remaining > 0 ? remaining : limit,
51
- }),
52
- )
53
- }
54
-
55
- $(effectsToRun.collectAllParDiscard)
56
- }).ignore
57
-
58
- const request = <A = unknown>(
59
- path: string,
60
- init: RequestInit = {},
61
- ): Effect<
62
- never,
63
- Http.FetchError | Http.StatusCodeError | Http.JsonParseError,
64
- ResponseWithData<A>
65
- > =>
66
- requestRateLimit(path, init)
67
- .tap(() => globalRateLimit)
68
- .flatMap(() =>
69
- Http.requestWithJson<A>(`${rest.baseUrl}${path}`, {
70
- ...init,
71
- headers: {
72
- ...(init?.headers ?? {}),
73
- Authorization: `Bot ${token}`,
74
- "User-Agent": `DiscordBot (https://github.com/tim-smart/dfx, ${Pkg.version})`,
75
- },
76
- }),
77
- )
78
- .catchTag("StatusCodeError", (e) =>
79
- e.code === 429
80
- ? Do(($) => {
81
- $(log.debug("DiscordREST", "429", path))
82
- $(updateBuckets(path, init, e.response))
83
- return $(request<A>(path, init))
84
- })
85
- : Effect.fail(e),
86
- )
87
- .tap(({ response }) => updateBuckets(path, init, response))
88
-
89
- return { request }
90
- })
91
-
92
- export interface DiscordREST extends Success<typeof make> {}
93
- export const DiscordREST = Tag<DiscordREST>()
94
- export const LiveDiscordREST = Layer.fromEffect(DiscordREST)(make)
95
-
96
- export const rest = Discord.createRoutes<RequestInit>(
97
- ({ method, url, params, options = {} }) =>
98
- Effect.serviceWithEffect(DiscordREST)(({ request }) => {
99
- const hasBody = method !== "GET" && method !== "DELETE"
100
- let hasFormData = typeof (options?.body as any)?.append === "function"
101
- let body: BodyInit | undefined = undefined
102
-
103
- const headers: Record<string, string> = {}
104
- if (hasBody && !hasFormData) {
105
- headers["content-type"] = "application/json"
106
- }
107
-
108
- const qs = new URLSearchParams()
109
- if (!hasBody) {
110
- Object.entries((params ?? {}) as Record<string, string>).forEach(
111
- ([key, value]) => {
112
- qs.append(key, value)
113
- },
114
- )
115
- } else if (hasFormData) {
116
- body = options.body!
117
- if (params) {
118
- ;(body as FormData).append("payload_json", JSON.stringify(params))
119
- }
120
- } else if (params) {
121
- body = JSON.stringify(params)
122
- } else {
123
- body = options.body!
124
- }
125
-
126
- return request(`${url}?${qs.toString()}`, {
127
- method,
128
- headers,
129
- body,
130
- })
131
- }),
132
- )
@@ -1,14 +0,0 @@
1
- import { DiscordREST } from "./index.js"
2
-
3
- export interface ResponseWithData<A> {
4
- response: Response
5
- json: Effect<never, Http.JsonParseError, A>
6
- text: Effect<never, never, string>
7
- blob: Effect<never, Http.BlobError, Blob>
8
- }
9
-
10
- export type RestResponse<T> = Effect<
11
- DiscordREST,
12
- Http.FetchError | Http.StatusCodeError | Http.JsonParseError,
13
- ResponseWithData<T>
14
- >
@@ -1,35 +0,0 @@
1
- const majorResources = ["channels", "guilds", "webhooks"] as const
2
-
3
- export const routeFromConfig = (path: string, init: RequestInit) => {
4
- const method = (init?.method ?? "get").toLowerCase()
5
-
6
- // Only keep major ID's
7
- const routeURL = path
8
- .split("?")[0]
9
- .replace(/\/([A-Za-z]+)\/(\d{16,21}|@me)/g, (match, resource) =>
10
- majorResources.includes(resource) ? match : `/${resource}`,
11
- )
12
- // Strip reactions
13
- .replace(/\/reactions\/(.*)/, "/reactions")
14
-
15
- return `${method}-${routeURL}`
16
- }
17
-
18
- export const numberHeader = (headers: Headers) => (key: string) =>
19
- Maybe.fromNullable(headers.get(key))
20
- .map(parseFloat)
21
- .filter((n) => !isNaN(n))
22
-
23
- export const retryAfter = (headers: Headers) =>
24
- numberHeader(headers)("x-ratelimit-reset-after")
25
- .catchAll(() => numberHeader(headers)("retry-after"))
26
- .map(Duration.seconds)
27
-
28
- export const rateLimitFromHeaders = (headers: Headers) =>
29
- Maybe.struct({
30
- bucket: Maybe.fromNullable(headers.get("x-ratelimit-bucket")),
31
- retryAfter: retryAfter(headers),
32
- limit: numberHeader(headers)("x-ratelimit-limit"),
33
- remaining: numberHeader(headers)("x-ratelimit-remaining"),
34
- })
35
- export type RateLimitDetails = ReturnType<typeof rateLimitFromHeaders>
@@ -1,68 +0,0 @@
1
- export type Flags<T extends number | bigint> = Record<string, T>
2
-
3
- /**
4
- * Returns all the flags OR'ed together.
5
- */
6
- export function all(flags: Flags<number>): number
7
- export function all(flags: Flags<bigint>): bigint
8
- export function all(flags: Flags<any>): any {
9
- return Object.values(flags).reduce((acc, flag) => acc | flag)
10
- }
11
-
12
- /**
13
- * Returns a function that converts a bitfield to a list of flag names.
14
- */
15
- export function toList<T extends Flags<number>>(
16
- flags: T,
17
- ): (bitfield: number) => (keyof T)[]
18
- export function toList<T extends Flags<bigint>>(
19
- flags: T,
20
- ): (bitfield: bigint) => (keyof T)[]
21
- export function toList<T extends Flags<any>>(
22
- flags: T,
23
- ): (bitfield: any) => (keyof T)[] {
24
- const entries = Object.entries(flags)
25
- return (val) =>
26
- entries.reduce(
27
- (acc, [key, flag]) => ((val & flag) === flag ? [...acc, key] : acc),
28
- [] as (keyof T)[],
29
- )
30
- }
31
-
32
- /**
33
- * Returns a function that converts a list of flags names to a bigint bitfield.
34
- */
35
- export const fromListBigint =
36
- <T extends Flags<bigint>>(flags: T) =>
37
- (list: (keyof T)[]) =>
38
- list.reduce((acc, key) => acc | flags[key], BigInt(0))
39
-
40
- /**
41
- * Returns a function that converts a list of flags names to a bitfield.
42
- */
43
- export const fromList =
44
- <T extends Flags<number>>(flags: T) =>
45
- (list: (keyof T)[]) =>
46
- list.reduce((acc, key) => acc | flags[key], 0)
47
-
48
- /**
49
- * Checks if a bigint bitfield contains and a flag value.
50
- */
51
- export const hasBigInt = (flag: bigint | string) => {
52
- const flagBigInt = BigInt(flag)
53
- return (bits: bigint | string) => {
54
- const bitsBigInt = BigInt(bits)
55
- return (bitsBigInt & flagBigInt) === flagBigInt
56
- }
57
- }
58
-
59
- /**
60
- * Checks if a bitfield contains and a flag value.
61
- */
62
- export const has = (flag: number | string) => {
63
- const flagNumber = +flag
64
- return (bits: number | string) => {
65
- const bitsNumber = +bits
66
- return (bitsNumber & flagNumber) === flagNumber
67
- }
68
- }
@@ -1,32 +0,0 @@
1
- /**
2
- * All the intents
3
- */
4
- export const ALL = Flags.all(Discord.GatewayIntents)
5
-
6
- /**
7
- * Privileged intents
8
- */
9
- export const PRIVILEGED =
10
- Discord.GatewayIntents.GUILD_PRESENCES |
11
- Discord.GatewayIntents.GUILD_MEMBERS |
12
- Discord.GatewayIntents.MESSAGE_CONTENT
13
-
14
- /**
15
- * Un-privileged intents
16
- */
17
- export const UNPRIVILEGED = ALL ^ PRIVILEGED
18
-
19
- /**
20
- * Function that converts a intents bitfield value to a list of intent names.
21
- */
22
- export const toList = Flags.toList(Discord.GatewayIntents)
23
-
24
- /**
25
- * Function that converts a list of intent names to a bitfield value.
26
- */
27
- export const fromList = Flags.fromList(Discord.GatewayIntents)
28
-
29
- /**
30
- * Check if an intent flag exists in the permissions.
31
- */
32
- export const has = Flags.has