dfx 0.9.5 → 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 +8 -7
  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,55 +0,0 @@
1
- import { handlers } from "./handlers.js"
2
- import { InteractionBuilder } from "./index.js"
3
- import { splitDefinitions } from "./utils.js"
4
-
5
- export interface RunOpts {
6
- sync?: boolean
7
- }
8
-
9
- export const run =
10
- <R2, E, E2>(
11
- catchAll: (
12
- e: Http.FetchError | Http.StatusCodeError | Http.JsonParseError | E,
13
- ) => Effect<R2, E2, any>,
14
- { sync = true }: RunOpts = {},
15
- ) =>
16
- <R>(ix: InteractionBuilder<R, E>) =>
17
- Do(($) => {
18
- const { GlobalApplicationCommand, GuildApplicationCommand } =
19
- splitDefinitions(ix.definitions)
20
-
21
- const application = $(
22
- Rest.rest.getCurrentBotApplicationInformation().flatMap((a) => a.json),
23
- )
24
-
25
- const globalSync = Rest.rest.bulkOverwriteGlobalApplicationCommands(
26
- application.id,
27
- {
28
- body: JSON.stringify(GlobalApplicationCommand.map((a) => a.command)),
29
- },
30
- )
31
-
32
- const guildSync = GuildApplicationCommand.length
33
- ? Gateway.handleDispatch("GUILD_CREATE", (a) =>
34
- Rest.rest.bulkOverwriteGuildApplicationCommands(
35
- application.id,
36
- a.id,
37
- GuildApplicationCommand.map((a) => a.command) as any,
38
- ),
39
- )
40
- : Effect.unit()
41
-
42
- const handle = handlers(ix.definitions)
43
-
44
- const run = Gateway.handleDispatch("INTERACTION_CREATE", (i) =>
45
- handle[i.type](i)
46
- .tap((r) =>
47
- r.match(Effect.unit, (r) =>
48
- Rest.rest.createInteractionResponse(i.id, i.token, r),
49
- ),
50
- )
51
- .catchAll(catchAll),
52
- )
53
-
54
- $(sync ? run.zipPar(globalSync).zipPar(guildSync) : run)
55
- })
@@ -1,139 +0,0 @@
1
- import * as Ctx from "./context.js"
2
- import * as D from "./definitions.js"
3
- import * as Arr from "@fp-ts/data/ReadonlyArray"
4
- import { splitDefinitions } from "./utils.js"
5
-
6
- export class InteractionNotFound {
7
- readonly _tag = "InteractionNotFound"
8
- constructor(readonly interaction: Discord.Interaction) {}
9
- }
10
-
11
- export const handlers = <R, E>(
12
- definitions: D.InteractionDefinition<R, E>[],
13
- ): Record<
14
- Discord.InteractionType,
15
- (i: Discord.Interaction) => Effect<R, E, Maybe<Discord.InteractionResponse>>
16
- > => {
17
- const { Commands, Autocomplete, MessageComponent, ModalSubmit } =
18
- splitDefinitions(definitions)
19
-
20
- return {
21
- [Discord.InteractionType.PING]: () =>
22
- Effect.succeed({
23
- type: Discord.InteractionCallbackType.PONG,
24
- }).asSome,
25
-
26
- [Discord.InteractionType.APPLICATION_COMMAND]: (i) => {
27
- const data = i.data as Discord.ApplicationCommandDatum
28
-
29
- return pipe(
30
- Maybe.fromNullable(Commands[data.name]).match(
31
- () =>
32
- Effect.fail(new InteractionNotFound(i)) as any as Effect<
33
- R,
34
- E,
35
- Maybe<Discord.InteractionResponse>
36
- >,
37
- (command) => command.handle,
38
- ),
39
- Effect.provideService(Ctx.InteractionContext)(i),
40
- Effect.provideService(Ctx.ApplicationCommandContext)(data),
41
- )
42
- },
43
-
44
- [Discord.InteractionType.MODAL_SUBMIT]: (i: Discord.Interaction) => {
45
- const data = i.data as Discord.ModalSubmitDatum
46
-
47
- return pipe(
48
- ModalSubmit,
49
- Arr.map((a) =>
50
- Effect.struct({
51
- command: Effect.succeed(a),
52
- match: a.predicate(data.custom_id),
53
- }),
54
- ),
55
- (a) =>
56
- a.collectAllPar.flatMap((a) =>
57
- a
58
- .findFirst((a) => a.match)
59
- .match(
60
- () =>
61
- Effect.fail(new InteractionNotFound(i)) as any as Effect<
62
- R,
63
- E,
64
- Maybe<Discord.InteractionResponse>
65
- >,
66
- (a) => a.command.handle,
67
- ),
68
- ),
69
- Effect.provideService(Ctx.InteractionContext)(i),
70
- Effect.provideService(Ctx.ModalSubmitContext)(data),
71
- )
72
- },
73
-
74
- [Discord.InteractionType.MESSAGE_COMPONENT]: (i) => {
75
- const data = i.data as Discord.MessageComponentDatum
76
-
77
- return pipe(
78
- MessageComponent,
79
- Arr.map((a) =>
80
- Effect.struct({
81
- command: Effect.succeed(a),
82
- match: a.predicate(data.custom_id),
83
- }),
84
- ),
85
- (a) =>
86
- a.collectAllPar.flatMap((a) =>
87
- a
88
- .findFirst((a) => a.match)
89
- .match(
90
- () =>
91
- Effect.fail(new InteractionNotFound(i)) as any as Effect<
92
- R,
93
- E,
94
- Maybe<Discord.InteractionResponse>
95
- >,
96
- (a) => a.command.handle,
97
- ),
98
- ),
99
- Effect.provideService(Ctx.InteractionContext)(i),
100
- Effect.provideService(Ctx.MessageComponentContext)(data),
101
- )
102
- },
103
-
104
- [Discord.InteractionType.APPLICATION_COMMAND_AUTOCOMPLETE]: (i) => {
105
- const data = i.data as Discord.ApplicationCommandDatum
106
-
107
- return IxHelpers.focusedOption(data)
108
- .map((focusedOption) =>
109
- pipe(
110
- Autocomplete,
111
- Arr.map((a) =>
112
- Effect.struct({
113
- command: Effect.succeed(a),
114
- match: a.predicate(focusedOption),
115
- }),
116
- ),
117
- (a) =>
118
- a.collectAllPar.flatMap((a) =>
119
- a
120
- .findFirst((a) => a.match)
121
- .match(
122
- () =>
123
- Effect.fail(new InteractionNotFound(i)) as any as Effect<
124
- R,
125
- E,
126
- Maybe<Discord.InteractionResponse>
127
- >,
128
- (a) => a.command.handle,
129
- ),
130
- ),
131
- Effect.provideService(Ctx.InteractionContext)(i),
132
- Effect.provideService(Ctx.ApplicationCommandContext)(data),
133
- Effect.provideService(Ctx.FocusedOptionContext)({ focusedOption }),
134
- ),
135
- )
136
- .getOrElse(() => Effect.fail(new InteractionNotFound(i)) as any)
137
- },
138
- }
139
- }
@@ -1,83 +0,0 @@
1
- import * as D from "./definitions.js"
2
-
3
- export * from "./context.js"
4
-
5
- export {
6
- global,
7
- guild,
8
- messageComponent,
9
- modalSubmit,
10
- autocomplete,
11
- InteractionDefinition,
12
- InteractionResponse,
13
- } from "./definitions.js"
14
-
15
- export {
16
- makeConfigLayer as makeWebhookConfig,
17
- makeHandler as makeWebhookHandler,
18
- MakeConfigOpts as MakeWebhookConfigOpts,
19
- WebhookConfig,
20
- WebhookParseError,
21
- BadWebhookSignature,
22
- } from "./webhook.js"
23
-
24
- export class InteractionBuilder<R, E> {
25
- constructor(readonly definitions: D.InteractionDefinition<R, E>[]) {}
26
-
27
- add<R1, E1>(definition: D.InteractionDefinition<R1, E1>) {
28
- return new InteractionBuilder<R | R1, E | E1>([
29
- ...this.definitions,
30
- definition,
31
- ])
32
- }
33
-
34
- get syncGlobal() {
35
- const commands = this.definitions
36
- .filter(
37
- (c): c is D.GlobalApplicationCommand<R, E> =>
38
- c._tag === "GlobalApplicationCommand",
39
- )
40
- .map((c) => c.command)
41
-
42
- return Rest.rest
43
- .getCurrentBotApplicationInformation()
44
- .flatMap((r) => r.json)
45
- .flatMap((app) =>
46
- Rest.rest.bulkOverwriteGlobalApplicationCommands(app.id, {
47
- body: JSON.stringify(commands),
48
- }),
49
- )
50
- }
51
-
52
- syncGuild(appId: Discord.Snowflake, guildId: Discord.Snowflake) {
53
- const commands = this.definitions
54
- .filter(
55
- (c): c is D.GuildApplicationCommand<R, E> =>
56
- c._tag === "GuildApplicationCommand",
57
- )
58
- .map((c) => c.command)
59
-
60
- return Rest.rest.bulkOverwriteGuildApplicationCommands(
61
- appId,
62
- guildId,
63
- commands as any,
64
- )
65
- }
66
- }
67
-
68
- export const builder = new InteractionBuilder<never, never>([])
69
-
70
- // Filters
71
- export const id = (query: string) => (customId: string) =>
72
- Effect.succeed(query === customId)
73
-
74
- export const idStartsWith = (query: string) => (customId: string) =>
75
- Effect.succeed(customId.startsWith(query))
76
-
77
- export const regex = (query: RegExp) => (customId: string) =>
78
- Effect.succeed(query.test(customId))
79
-
80
- export const option =
81
- (name: string) =>
82
- (focusedOption: Discord.ApplicationCommandInteractionDataOption) =>
83
- Effect.succeed(focusedOption.name === name)
@@ -1,81 +0,0 @@
1
- import * as D from "./definitions.js"
2
-
3
- export const splitDefinitions = <R, E>(
4
- definitions: D.InteractionDefinition<R, E>[],
5
- ) => {
6
- const grouped = definitions.reduce<{
7
- [K in D.InteractionDefinition<R, E>["_tag"]]: Extract<
8
- D.InteractionDefinition<R, E>,
9
- { _tag: K }
10
- >[]
11
- }>(
12
- (acc, a) => ({
13
- ...acc,
14
- [a._tag]: [...(acc[a._tag] ?? []), a],
15
- }),
16
- {
17
- Autocomplete: [],
18
- GlobalApplicationCommand: [],
19
- GuildApplicationCommand: [],
20
- MessageComponent: [],
21
- ModalSubmit: [],
22
- },
23
- )
24
-
25
- const Commands = [
26
- ...grouped.GlobalApplicationCommand,
27
- ...grouped.GuildApplicationCommand,
28
- ].reduce(
29
- (acc, a) => ({
30
- ...acc,
31
- [a.command.name]: a,
32
- }),
33
- {} as Record<
34
- string,
35
- D.GlobalApplicationCommand<R, E> | D.GuildApplicationCommand<R, E>
36
- >,
37
- )
38
-
39
- return {
40
- ...grouped,
41
- Commands,
42
- }
43
- }
44
- const MAP_HEX: Record<string, number> = {
45
- 0: 0,
46
- 1: 1,
47
- 2: 2,
48
- 3: 3,
49
- 4: 4,
50
- 5: 5,
51
- 6: 6,
52
- 7: 7,
53
- 8: 8,
54
- 9: 9,
55
- a: 10,
56
- b: 11,
57
- c: 12,
58
- d: 13,
59
- e: 14,
60
- f: 15,
61
- A: 10,
62
- B: 11,
63
- C: 12,
64
- D: 13,
65
- E: 14,
66
- F: 15,
67
- }
68
-
69
- export function fromHex(hexString: string) {
70
- const bytes = new Uint8Array(Math.floor((hexString || "").length / 2))
71
- let i
72
- for (i = 0; i < bytes.length; i++) {
73
- const a = MAP_HEX[hexString[i * 2]]
74
- const b = MAP_HEX[hexString[i * 2 + 1]]
75
- if (a === undefined || b === undefined) {
76
- break
77
- }
78
- bytes[i] = (a << 4) | b
79
- }
80
- return i === bytes.length ? bytes : bytes.slice(0, i)
81
- }
@@ -1,96 +0,0 @@
1
- import Nacl from "tweetnacl"
2
- import * as D from "./definitions.js"
3
- import { handlers } from "./handlers.js"
4
- import { InteractionBuilder } from "./index.js"
5
- import { fromHex } from "./utils.js"
6
-
7
- export class BadWebhookSignature {
8
- readonly _tag = "BadWebhookSignature"
9
- }
10
-
11
- export type Headers = Record<string, string | string[] | undefined>
12
-
13
- const checkSignature = (
14
- publicKey: Uint8Array,
15
- headers: Headers,
16
- body: string,
17
- ) =>
18
- Maybe.struct({
19
- signature: Maybe.fromNullable(headers["x-signature-ed25519"]),
20
- timestamp: Maybe.fromNullable(headers["x-signature-timestamp"]),
21
- })
22
- .filter((a) => {
23
- const enc = new TextEncoder()
24
- return Nacl.sign.detached.verify(
25
- enc.encode(a.timestamp + body),
26
- fromHex(`${a.signature}`),
27
- publicKey,
28
- )
29
- })
30
- .toEither(() => new BadWebhookSignature()).asUnit
31
-
32
- export interface MakeConfigOpts {
33
- applicationId: string
34
- publicKey: string
35
- }
36
- const makeConfig = ({ applicationId, publicKey }: MakeConfigOpts) => ({
37
- applicationId,
38
- publicKey: fromHex(publicKey),
39
- })
40
- export interface WebhookConfig extends ReturnType<typeof makeConfig> {}
41
- export const WebhookConfig = Tag<WebhookConfig>()
42
- export const makeConfigLayer = flow(makeConfig, Layer.succeed(WebhookConfig))
43
-
44
- export class WebhookParseError {
45
- readonly _tag = "WebhookParseError"
46
- constructor(readonly reason: unknown) {}
47
- }
48
-
49
- const fromHeadersAndBody = (headers: Headers, body: string) =>
50
- Do(($) => {
51
- const { publicKey } = $(Effect.service(WebhookConfig))
52
- $(Effect.fromEither(checkSignature(publicKey, headers, body)))
53
- return $(
54
- Effect.tryCatch(
55
- () => JSON.parse(body) as Discord.Interaction,
56
- (reason) => new WebhookParseError(reason),
57
- ),
58
- )
59
- })
60
-
61
- const run = <R, E>(definitions: D.InteractionDefinition<R, E>[]) => {
62
- const handler = handlers(definitions)
63
- return (headers: Headers, body: string) =>
64
- Do(($) => {
65
- const interaction = $(fromHeadersAndBody(headers, body))
66
- return $(handler[interaction.type](interaction))
67
- })
68
- }
69
-
70
- export interface HandleWebhookOpts<E> {
71
- headers: Headers
72
- body: string
73
- success: (a: Discord.InteractionResponse) => Effect<never, never, void>
74
- error: (e: Cause<E>) => Effect<never, never, void>
75
- empty: Effect<never, never, void>
76
- }
77
-
78
- export const makeHandler = <R, E>(ix: InteractionBuilder<R, E>) => {
79
- const handle = run(ix.definitions)
80
-
81
- return ({
82
- headers,
83
- body,
84
- success,
85
- empty,
86
- error,
87
- }: HandleWebhookOpts<E | WebhookParseError | BadWebhookSignature>) =>
88
- handle(headers, body)
89
- .flatMap((o) =>
90
- o.match(
91
- () => empty,
92
- (a) => success(a),
93
- ),
94
- )
95
- .catchAllCause(error)
96
- }
package/src/Log/index.ts DELETED
@@ -1,23 +0,0 @@
1
- const make = (debug = false) => ({
2
- info: (...args: any[]) =>
3
- Effect.sync(() => {
4
- console.error("INFO", ...args)
5
- }),
6
- debug: (...args: any[]) =>
7
- debug
8
- ? Effect.sync(() => {
9
- console.error("DEBUG", ...args)
10
- })
11
- : Effect.unit(),
12
- })
13
-
14
- export interface Log extends ReturnType<typeof make> {}
15
- export const Log = Tag<Log>()
16
- export const LiveLog = Layer.succeed(Log)(make(false))
17
- export const LiveLogDebug = Layer.succeed(Log)(make(true))
18
-
19
- export const info = (...args: any[]) =>
20
- Effect.serviceWithEffect(Log)(({ info: log }) => log(...args))
21
-
22
- export const debug = (...args: any[]) =>
23
- Effect.serviceWithEffect(Log)(({ debug }) => debug(...args))
@@ -1,65 +0,0 @@
1
- import { delayFrom } from "./utils.js"
2
- import * as Memory from "./memory.js"
3
-
4
- export type BucketDetails = {
5
- key: "global" | string
6
- resetAfter: number
7
- limit: number
8
- }
9
-
10
- export interface RateLimitStore {
11
- hasBucket: (bucketKey: string) => Effect<never, never, boolean>
12
-
13
- putBucket: (bucket: BucketDetails) => Effect<never, never, void>
14
-
15
- getBucketForRoute: (
16
- route: string,
17
- ) => Effect<never, never, Maybe<BucketDetails>>
18
-
19
- putBucketRoute: (
20
- route: string,
21
- bucketKey: string,
22
- ) => Effect<never, never, void>
23
-
24
- incrementCounter: (
25
- key: string,
26
- window: number,
27
- limit: number,
28
- ) => Effect<never, never, readonly [count: number, ttl: number]>
29
- }
30
-
31
- export const RateLimitStore = Tag<RateLimitStore>()
32
- export const LiveMemoryRateLimitStore = Layer.sync(RateLimitStore)(Memory.make)
33
-
34
- const makeLimiter = Do(($) => {
35
- const store = $(Effect.service(RateLimitStore))
36
- const log = $(Effect.service(Log.Log))
37
-
38
- const maybeWait = (
39
- key: string,
40
- window: Duration,
41
- limit: number,
42
- multiplier = 1.05,
43
- ) => {
44
- const windowMs = window.millis * multiplier
45
- return store
46
- .incrementCounter(key, windowMs, limit)
47
- .map(([count, ttl]) => delayFrom(windowMs, limit, count, ttl))
48
- .tap((d) =>
49
- log.debug("RateLimitStore maybeWait", {
50
- key,
51
- window: window.millis,
52
- windowMs,
53
- limit,
54
- delay: d.millis,
55
- }),
56
- )
57
- .tap(Effect.sleep).asUnit
58
- }
59
-
60
- return { maybeWait }
61
- })
62
-
63
- export interface RateLimiter extends Success<typeof makeLimiter> {}
64
- export const RateLimiter = Tag<RateLimiter>()
65
- export const LiveRateLimiter = Layer.fromEffect(RateLimiter)(makeLimiter)
@@ -1,48 +0,0 @@
1
- interface Counter {
2
- count: number
3
- expires: number
4
- }
5
-
6
- export const make = (): RateLimitStore.RateLimitStore => {
7
- const buckets = new Map<string, RateLimitStore.BucketDetails>()
8
- const routes = new Map<string, string>()
9
- const counters = new Map<string, Counter>()
10
-
11
- const getCounter = (key: string) =>
12
- Maybe.fromNullable(counters.get(key)).filter((c) => c.expires > Date.now())
13
-
14
- return {
15
- hasBucket: (key) => Effect.sync(() => buckets.has(key)),
16
-
17
- putBucket: (bucket) =>
18
- Effect.sync(() => {
19
- buckets.set(bucket.key, bucket)
20
- }),
21
-
22
- getBucketForRoute: (route) =>
23
- Effect.sync(() => Maybe.fromNullable(buckets.get(routes.get(route)!))),
24
-
25
- putBucketRoute: (route, bucket) =>
26
- Effect.sync(() => {
27
- routes.set(route, bucket)
28
- }),
29
-
30
- incrementCounter: (key, window, limit) =>
31
- Effect.sync(() => {
32
- const now = Date.now()
33
- const perRequest = Math.ceil(window / limit)
34
- const counter = getCounter(key).getOrElse(
35
- (): Counter => ({
36
- expires: now,
37
- count: 0,
38
- }),
39
- )
40
-
41
- const count = counter.count + 1
42
- const expires = counter.expires + perRequest
43
- counters.set(key, { ...counter, count, expires })
44
-
45
- return [count, expires - now]
46
- }),
47
- }
48
- }
@@ -1,27 +0,0 @@
1
- import { millis, zero } from "@fp-ts/data/Duration"
2
-
3
- export const delayFrom = (
4
- window: number,
5
- limit: number,
6
- count: number,
7
- ttl: number,
8
- ): Duration => {
9
- const perRequest = Math.ceil(window / limit)
10
-
11
- const totalTime = count * perRequest
12
- const elapsedTime = totalTime - ttl
13
- const elapsedWindows = Math.floor(elapsedTime / window)
14
- const completedRequests = elapsedWindows * limit
15
- const remainingRequests = count - completedRequests
16
- const remainingWindows = Math.floor((remainingRequests - 1) / limit)
17
- const delayRemainder = elapsedTime % window
18
-
19
- const requestRemainder = count % limit
20
- const staggerDelay = requestRemainder * 50
21
-
22
- if (remainingWindows === 0) {
23
- return zero
24
- }
25
-
26
- return millis(remainingWindows * window - delayRemainder + staggerDelay)
27
- }
@@ -1,5 +0,0 @@
1
- export * as Gateway from "dfx/DiscordGateway/index"
2
- export * as WS from "dfx/DiscordGateway/WS/index"
3
- export * as DWS from "dfx/DiscordGateway/DiscordWS/index"
4
- export * as Shard from "dfx/DiscordGateway/Shard/index"
5
- export * as ShardStore from "dfx/DiscordGateway/ShardStore/index"
package/src/common.ts DELETED
@@ -1,30 +0,0 @@
1
- export { Effect, EffectTypeId } from "@effect/io/Effect"
2
- export type { Layer } from "@effect/io/Layer"
3
- export type { Schedule } from "@effect/io/Schedule"
4
- export type { Cause } from "@effect/io/Cause"
5
- export type { Chunk } from "@fp-ts/data/Chunk"
6
- export { Context, Tag } from "@fp-ts/data/Context"
7
- export type { Duration } from "@fp-ts/data/Duration"
8
- export type { Equal } from "@fp-ts/data/Equal"
9
- export type { Option as Maybe } from "@fp-ts/data/Option"
10
- export type { Either } from "@fp-ts/data/Either"
11
- export type { Exit } from "@effect/io/Exit"
12
- export type { EffectSource } from "callbag-effect-ts/Source"
13
- export type { EffectSink } from "callbag-effect-ts/Sink"
14
- export type { HashMap } from "@fp-ts/data/HashMap"
15
- export type { Ref } from "@effect/io/Ref"
16
-
17
- export * as Config from "dfx/DiscordConfig/index"
18
- export * as Discord from "dfx/types"
19
- export * as Http from "dfx/Http/index"
20
- export * as Log from "dfx/Log/index"
21
- export * as RateLimitStore from "dfx/RateLimitStore/index"
22
- export * as Rest from "dfx/DiscordREST/index"
23
- export * as Ix from "dfx/Interactions/index"
24
-
25
- export * as Flags from "./Helpers/flags.js"
26
- export * as IxHelpers from "./Helpers/interactions.js"
27
- export * as Intents from "./Helpers/intents.js"
28
- export * as Members from "./Helpers/members.js"
29
- export * as Perms from "./Helpers/permissions.js"
30
- export * as UI from "./Helpers/ui.js"