@erinjs/core 1.0.0 → 1.2.4

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 (394) hide show
  1. package/{core/LICENSE → LICENSE} +203 -203
  2. package/README.md +46 -0
  3. package/dist/index.d.mts +2084 -0
  4. package/dist/index.d.ts +2084 -0
  5. package/dist/index.js +3867 -0
  6. package/dist/index.mjs +3809 -0
  7. package/package.json +50 -15
  8. package/core/.changeset/README.md +0 -8
  9. package/core/.changeset/community-bootstrap-release.md +0 -17
  10. package/core/.changeset/config.json +0 -11
  11. package/core/.changeset/no-changelog.js +0 -16
  12. package/core/.changeset/pre.json +0 -17
  13. package/core/.editorconfig +0 -13
  14. package/core/.gitattributes +0 -2
  15. package/core/.github/CODE_OF_CONDUCT.md +0 -23
  16. package/core/.github/FUNDING.yml +0 -7
  17. package/core/.github/ISSUE_TEMPLATE/bug_report.md +0 -31
  18. package/core/.github/ISSUE_TEMPLATE/feature_request.md +0 -23
  19. package/core/.github/PULL_REQUEST_TEMPLATE.md +0 -16
  20. package/core/.github/dependabot.yml +0 -16
  21. package/core/.github/workflows/autoapp.yml +0 -16
  22. package/core/.github/workflows/ci.yml +0 -187
  23. package/core/.github/workflows/codeql.yml +0 -30
  24. package/core/.github/workflows/deploy-docs.yml +0 -54
  25. package/core/.github/workflows/publish.yml +0 -43
  26. package/core/.lintstagedrc.json +0 -4
  27. package/core/.nvmrc +0 -1
  28. package/core/.prettierignore +0 -8
  29. package/core/.prettierrc +0 -11
  30. package/core/CONTRIBUTING.md +0 -70
  31. package/core/README.md +0 -61
  32. package/core/SECURITY.md +0 -21
  33. package/core/apps/docs/index.html +0 -28
  34. package/core/apps/docs/middleware.ts +0 -21
  35. package/core/apps/docs/package.json +0 -33
  36. package/core/apps/docs/public/@flux.png +0 -0
  37. package/core/apps/docs/public/docs/latest/guides.json +0 -1420
  38. package/core/apps/docs/public/docs/latest/main.json +0 -14981
  39. package/core/apps/docs/public/docs/latest/rag-index.json +0 -1
  40. package/core/apps/docs/public/docs/v1.0.5/guides.json +0 -226
  41. package/core/apps/docs/public/docs/v1.0.5/main.json +0 -7920
  42. package/core/apps/docs/public/docs/v1.0.6/guides.json +0 -226
  43. package/core/apps/docs/public/docs/v1.0.6/main.json +0 -7920
  44. package/core/apps/docs/public/docs/v1.0.7/guides.json +0 -259
  45. package/core/apps/docs/public/docs/v1.0.7/main.json +0 -8652
  46. package/core/apps/docs/public/docs/v1.0.8/guides.json +0 -313
  47. package/core/apps/docs/public/docs/v1.0.8/main.json +0 -9618
  48. package/core/apps/docs/public/docs/v1.0.9/guides.json +0 -319
  49. package/core/apps/docs/public/docs/v1.0.9/main.json +0 -10694
  50. package/core/apps/docs/public/docs/v1.1.0/guides.json +0 -589
  51. package/core/apps/docs/public/docs/v1.1.0/main.json +0 -12576
  52. package/core/apps/docs/public/docs/v1.1.2/guides.json +0 -650
  53. package/core/apps/docs/public/docs/v1.1.2/main.json +0 -13239
  54. package/core/apps/docs/public/docs/v1.1.3/guides.json +0 -650
  55. package/core/apps/docs/public/docs/v1.1.3/main.json +0 -13239
  56. package/core/apps/docs/public/docs/v1.1.4/guides.json +0 -708
  57. package/core/apps/docs/public/docs/v1.1.4/main.json +0 -13231
  58. package/core/apps/docs/public/docs/v1.1.5/guides.json +0 -1035
  59. package/core/apps/docs/public/docs/v1.1.5/main.json +0 -13838
  60. package/core/apps/docs/public/docs/v1.1.6/guides.json +0 -1041
  61. package/core/apps/docs/public/docs/v1.1.6/main.json +0 -14313
  62. package/core/apps/docs/public/docs/v1.1.8/guides.json +0 -1047
  63. package/core/apps/docs/public/docs/v1.1.8/main.json +0 -14421
  64. package/core/apps/docs/public/docs/v1.1.9/guides.json +0 -1047
  65. package/core/apps/docs/public/docs/v1.1.9/main.json +0 -14421
  66. package/core/apps/docs/public/docs/v1.2.0/guides.json +0 -1212
  67. package/core/apps/docs/public/docs/v1.2.0/main.json +0 -14663
  68. package/core/apps/docs/public/docs/v1.2.1/guides.json +0 -1293
  69. package/core/apps/docs/public/docs/v1.2.1/main.json +0 -14828
  70. package/core/apps/docs/public/docs/v1.2.2/guides.json +0 -1293
  71. package/core/apps/docs/public/docs/v1.2.2/main.json +0 -15025
  72. package/core/apps/docs/public/docs/v1.2.3/guides.json +0 -1420
  73. package/core/apps/docs/public/docs/v1.2.3/main.json +0 -14954
  74. package/core/apps/docs/public/docs/v1.2.4/guides.json +0 -1420
  75. package/core/apps/docs/public/docs/v1.2.4/main.json +0 -14981
  76. package/core/apps/docs/public/docs/versions.json +0 -24
  77. package/core/apps/docs/public/flux.png +0 -0
  78. package/core/apps/docs/public/locales/en.json +0 -50
  79. package/core/apps/docs/public/locales/guides-en.json +0 -512
  80. package/core/apps/docs/public/robots.txt +0 -4
  81. package/core/apps/docs/public/sitemap.xml +0 -33
  82. package/core/apps/docs/src/App.vue +0 -538
  83. package/core/apps/docs/src/components/ApiCategorySection.vue +0 -42
  84. package/core/apps/docs/src/components/ApiDiscordCompat.vue +0 -65
  85. package/core/apps/docs/src/components/ApiEndpointCard.vue +0 -313
  86. package/core/apps/docs/src/components/ApiSchemaBlock.vue +0 -131
  87. package/core/apps/docs/src/components/CodeBlock.vue +0 -177
  88. package/core/apps/docs/src/components/CommunityCallout.vue +0 -90
  89. package/core/apps/docs/src/components/ConstructorSection.vue +0 -82
  90. package/core/apps/docs/src/components/DocDescription.vue +0 -40
  91. package/core/apps/docs/src/components/FluxerLogo.vue +0 -3
  92. package/core/apps/docs/src/components/Footer.vue +0 -106
  93. package/core/apps/docs/src/components/GuideCodeBlock.vue +0 -102
  94. package/core/apps/docs/src/components/GuideDiscordCompat.vue +0 -77
  95. package/core/apps/docs/src/components/GuideDiscordCompatCallout.vue +0 -83
  96. package/core/apps/docs/src/components/GuideTable.vue +0 -77
  97. package/core/apps/docs/src/components/GuideTip.vue +0 -38
  98. package/core/apps/docs/src/components/MethodsSection.vue +0 -195
  99. package/core/apps/docs/src/components/ParamsTable.vue +0 -70
  100. package/core/apps/docs/src/components/PropertiesSection.vue +0 -143
  101. package/core/apps/docs/src/components/SearchBar.vue +0 -76
  102. package/core/apps/docs/src/components/SearchModal.vue +0 -361
  103. package/core/apps/docs/src/components/SidebarNav.vue +0 -225
  104. package/core/apps/docs/src/components/SponsorBanner.vue +0 -153
  105. package/core/apps/docs/src/components/TypeSignature.vue +0 -187
  106. package/core/apps/docs/src/components/VersionPicker.vue +0 -191
  107. package/core/apps/docs/src/composables/useSearchIndex.ts +0 -144
  108. package/core/apps/docs/src/composables/useVersionedPath.ts +0 -20
  109. package/core/apps/docs/src/data/apiEndpoints.ts +0 -1073
  110. package/core/apps/docs/src/data/changelog.ts +0 -717
  111. package/core/apps/docs/src/data/guides.ts +0 -2362
  112. package/core/apps/docs/src/env.d.ts +0 -7
  113. package/core/apps/docs/src/locales/guides-en.json +0 -512
  114. package/core/apps/docs/src/main.ts +0 -27
  115. package/core/apps/docs/src/pages/ApiReferenceLayout.vue +0 -175
  116. package/core/apps/docs/src/pages/ApiReferencePage.vue +0 -128
  117. package/core/apps/docs/src/pages/Changelog.vue +0 -288
  118. package/core/apps/docs/src/pages/ClassPage.vue +0 -319
  119. package/core/apps/docs/src/pages/ClassesList.vue +0 -100
  120. package/core/apps/docs/src/pages/DocsLayout.vue +0 -127
  121. package/core/apps/docs/src/pages/GuidePage.vue +0 -279
  122. package/core/apps/docs/src/pages/GuidesIndex.vue +0 -166
  123. package/core/apps/docs/src/pages/GuidesLayout.vue +0 -245
  124. package/core/apps/docs/src/pages/Home.vue +0 -125
  125. package/core/apps/docs/src/pages/NotFound.vue +0 -57
  126. package/core/apps/docs/src/pages/TypedefPage.vue +0 -230
  127. package/core/apps/docs/src/pages/TypedefsList.vue +0 -168
  128. package/core/apps/docs/src/pages/VersionLayout.vue +0 -15
  129. package/core/apps/docs/src/router.ts +0 -73
  130. package/core/apps/docs/src/stores/docs.ts +0 -54
  131. package/core/apps/docs/src/stores/guides.ts +0 -53
  132. package/core/apps/docs/src/stores/version.ts +0 -67
  133. package/core/apps/docs/src/styles/main.css +0 -278
  134. package/core/apps/docs/src/styles/prism.css +0 -95
  135. package/core/apps/docs/src/types/doc-schema.ts +0 -112
  136. package/core/apps/docs/tsconfig.json +0 -17
  137. package/core/apps/docs/tsconfig.node.json +0 -10
  138. package/core/apps/docs/vite.config.d.ts +0 -2
  139. package/core/apps/docs/vite.config.js +0 -26
  140. package/core/apps/docs/vite.config.ts +0 -28
  141. package/core/apps/docs-vitepress/.vitepress/config.ts +0 -141
  142. package/core/apps/docs-vitepress/api-data/latest/main.json +0 -15035
  143. package/core/apps/docs-vitepress/api-data/v1.2.4/main.json +0 -15035
  144. package/core/apps/docs-vitepress/api-data/versions.json +0 -6
  145. package/core/apps/docs-vitepress/index.md +0 -15
  146. package/core/apps/docs-vitepress/package-lock.json +0 -2924
  147. package/core/apps/docs-vitepress/package.json +0 -20
  148. package/core/apps/docs-vitepress/public/CNAME +0 -1
  149. package/core/apps/docs-vitepress/scripts/generate-api.ts +0 -243
  150. package/core/apps/docs-vitepress/scripts/migrate-guides.ts +0 -129
  151. package/core/apps/docs-vitepress/tsconfig.json +0 -11
  152. package/core/apps/docs-vitepress/v/latest/guides/attachments-by-url.md +0 -57
  153. package/core/apps/docs-vitepress/v/latest/guides/attachments.md +0 -62
  154. package/core/apps/docs-vitepress/v/latest/guides/basic-bot.md +0 -49
  155. package/core/apps/docs-vitepress/v/latest/guides/channels.md +0 -180
  156. package/core/apps/docs-vitepress/v/latest/guides/deprecated-apis.md +0 -58
  157. package/core/apps/docs-vitepress/v/latest/guides/discord-js-compatibility.md +0 -42
  158. package/core/apps/docs-vitepress/v/latest/guides/editing-embeds.md +0 -65
  159. package/core/apps/docs-vitepress/v/latest/guides/embed-media.md +0 -87
  160. package/core/apps/docs-vitepress/v/latest/guides/embeds.md +0 -166
  161. package/core/apps/docs-vitepress/v/latest/guides/emojis.md +0 -77
  162. package/core/apps/docs-vitepress/v/latest/guides/events.md +0 -202
  163. package/core/apps/docs-vitepress/v/latest/guides/gifs.md +0 -47
  164. package/core/apps/docs-vitepress/v/latest/guides/installation.md +0 -10
  165. package/core/apps/docs-vitepress/v/latest/guides/moderation.md +0 -89
  166. package/core/apps/docs-vitepress/v/latest/guides/permissions.md +0 -130
  167. package/core/apps/docs-vitepress/v/latest/guides/prefix-commands.md +0 -41
  168. package/core/apps/docs-vitepress/v/latest/guides/profile-urls.md +0 -58
  169. package/core/apps/docs-vitepress/v/latest/guides/reactions.md +0 -69
  170. package/core/apps/docs-vitepress/v/latest/guides/roles.md +0 -130
  171. package/core/apps/docs-vitepress/v/latest/guides/sending-without-reply.md +0 -172
  172. package/core/apps/docs-vitepress/v/latest/guides/voice.md +0 -109
  173. package/core/apps/docs-vitepress/v/latest/guides/wait-for-guilds.md +0 -37
  174. package/core/apps/docs-vitepress/v/latest/guides/webhook-attachments-embeds.md +0 -73
  175. package/core/apps/docs-vitepress/v/latest/guides/webhooks.md +0 -131
  176. package/core/eslint.config.js +0 -80
  177. package/core/examples/.env.example +0 -22
  178. package/core/examples/README.md +0 -68
  179. package/core/examples/first-steps-bot.js +0 -118
  180. package/core/examples/minimal-bot.js +0 -17
  181. package/core/examples/moderation-bot.js +0 -209
  182. package/core/examples/package.json +0 -14
  183. package/core/examples/ping-bot.js +0 -1146
  184. package/core/examples/reaction-bot.js +0 -70
  185. package/core/examples/reaction-roles-bot.js +0 -140
  186. package/core/examples/webhook-bot.js +0 -239
  187. package/core/flux.png +0 -0
  188. package/core/package.json +0 -78
  189. package/core/packages/builders/package.json +0 -51
  190. package/core/packages/builders/src/index.ts +0 -13
  191. package/core/packages/builders/src/messages/AttachmentBuilder.test.ts +0 -79
  192. package/core/packages/builders/src/messages/AttachmentBuilder.ts +0 -69
  193. package/core/packages/builders/src/messages/EmbedBuilder.test.ts +0 -266
  194. package/core/packages/builders/src/messages/EmbedBuilder.ts +0 -239
  195. package/core/packages/builders/src/messages/MessagePayload.test.ts +0 -118
  196. package/core/packages/builders/src/messages/MessagePayload.ts +0 -122
  197. package/core/packages/builders/tsconfig.json +0 -9
  198. package/core/packages/builders/tsup.config.ts +0 -9
  199. package/core/packages/builders/vitest.config.ts +0 -9
  200. package/core/packages/collection/package.json +0 -47
  201. package/core/packages/collection/src/Collection.test.ts +0 -232
  202. package/core/packages/collection/src/Collection.ts +0 -196
  203. package/core/packages/collection/src/index.ts +0 -1
  204. package/core/packages/collection/tsconfig.json +0 -9
  205. package/core/packages/collection/tsup.config.ts +0 -9
  206. package/core/packages/collection/vitest.config.ts +0 -9
  207. package/core/packages/docgen/package.json +0 -26
  208. package/core/packages/docgen/src/extract.ts +0 -262
  209. package/core/packages/docgen/src/formatType.ts +0 -24
  210. package/core/packages/docgen/src/index.ts +0 -103
  211. package/core/packages/docgen/src/schema.ts +0 -100
  212. package/core/packages/docgen/src/visitor.ts +0 -147
  213. package/core/packages/docgen/tsconfig.json +0 -9
  214. package/core/packages/docgen/tsup.config.ts +0 -9
  215. package/core/packages/fluxer-core/README.md +0 -26
  216. package/core/packages/fluxer-core/package.json +0 -60
  217. package/core/packages/fluxer-core/src/client/ChannelManager.ts +0 -143
  218. package/core/packages/fluxer-core/src/client/Client.gateway.test.ts +0 -84
  219. package/core/packages/fluxer-core/src/client/Client.resolveEmoji.test.ts +0 -45
  220. package/core/packages/fluxer-core/src/client/Client.ts +0 -558
  221. package/core/packages/fluxer-core/src/client/ClientUser.ts +0 -40
  222. package/core/packages/fluxer-core/src/client/EventHandlerRegistry.ts +0 -469
  223. package/core/packages/fluxer-core/src/client/GuildManager.ts +0 -79
  224. package/core/packages/fluxer-core/src/client/GuildMemberManager.ts +0 -91
  225. package/core/packages/fluxer-core/src/client/MessageManager.ts +0 -58
  226. package/core/packages/fluxer-core/src/client/UsersManager.ts +0 -122
  227. package/core/packages/fluxer-core/src/errors/ErrorCodes.test.ts +0 -19
  228. package/core/packages/fluxer-core/src/errors/ErrorCodes.ts +0 -12
  229. package/core/packages/fluxer-core/src/errors/FluxerError.test.ts +0 -32
  230. package/core/packages/fluxer-core/src/errors/FluxerError.ts +0 -15
  231. package/core/packages/fluxer-core/src/index.ts +0 -85
  232. package/core/packages/fluxer-core/src/structures/Base.ts +0 -7
  233. package/core/packages/fluxer-core/src/structures/Channel.ts +0 -508
  234. package/core/packages/fluxer-core/src/structures/Guild.test.ts +0 -189
  235. package/core/packages/fluxer-core/src/structures/Guild.ts +0 -734
  236. package/core/packages/fluxer-core/src/structures/GuildBan.ts +0 -35
  237. package/core/packages/fluxer-core/src/structures/GuildEmoji.ts +0 -57
  238. package/core/packages/fluxer-core/src/structures/GuildMember.test.ts +0 -203
  239. package/core/packages/fluxer-core/src/structures/GuildMember.ts +0 -213
  240. package/core/packages/fluxer-core/src/structures/GuildMemberRoleManager.ts +0 -121
  241. package/core/packages/fluxer-core/src/structures/GuildSticker.ts +0 -56
  242. package/core/packages/fluxer-core/src/structures/Invite.test.ts +0 -103
  243. package/core/packages/fluxer-core/src/structures/Invite.ts +0 -121
  244. package/core/packages/fluxer-core/src/structures/Message.test.ts +0 -109
  245. package/core/packages/fluxer-core/src/structures/Message.ts +0 -397
  246. package/core/packages/fluxer-core/src/structures/MessageReaction.ts +0 -72
  247. package/core/packages/fluxer-core/src/structures/PartialMessage.ts +0 -12
  248. package/core/packages/fluxer-core/src/structures/Role.test.ts +0 -77
  249. package/core/packages/fluxer-core/src/structures/Role.ts +0 -112
  250. package/core/packages/fluxer-core/src/structures/User.test.ts +0 -110
  251. package/core/packages/fluxer-core/src/structures/User.ts +0 -109
  252. package/core/packages/fluxer-core/src/structures/Webhook.test.ts +0 -109
  253. package/core/packages/fluxer-core/src/structures/Webhook.ts +0 -258
  254. package/core/packages/fluxer-core/src/util/Constants.test.ts +0 -16
  255. package/core/packages/fluxer-core/src/util/Constants.ts +0 -7
  256. package/core/packages/fluxer-core/src/util/Events.ts +0 -46
  257. package/core/packages/fluxer-core/src/util/MessageCollector.ts +0 -87
  258. package/core/packages/fluxer-core/src/util/Options.ts +0 -33
  259. package/core/packages/fluxer-core/src/util/ReactionCollector.ts +0 -116
  260. package/core/packages/fluxer-core/src/util/cdn.test.ts +0 -108
  261. package/core/packages/fluxer-core/src/util/cdn.ts +0 -130
  262. package/core/packages/fluxer-core/src/util/guildUtils.ts +0 -33
  263. package/core/packages/fluxer-core/src/util/messageUtils.test.ts +0 -74
  264. package/core/packages/fluxer-core/src/util/messageUtils.ts +0 -119
  265. package/core/packages/fluxer-core/src/util/permissions.test.ts +0 -95
  266. package/core/packages/fluxer-core/src/util/permissions.ts +0 -43
  267. package/core/packages/fluxer-core/tsconfig.json +0 -9
  268. package/core/packages/fluxer-core/tsup.config.ts +0 -9
  269. package/core/packages/fluxer-core/vitest.config.ts +0 -9
  270. package/core/packages/rest/package.json +0 -52
  271. package/core/packages/rest/src/REST.test.ts +0 -64
  272. package/core/packages/rest/src/REST.ts +0 -90
  273. package/core/packages/rest/src/RateLimitManager.test.ts +0 -71
  274. package/core/packages/rest/src/RateLimitManager.ts +0 -60
  275. package/core/packages/rest/src/RequestManager.test.ts +0 -87
  276. package/core/packages/rest/src/RequestManager.ts +0 -172
  277. package/core/packages/rest/src/errors/FluxerAPIError.test.ts +0 -57
  278. package/core/packages/rest/src/errors/FluxerAPIError.ts +0 -21
  279. package/core/packages/rest/src/errors/HTTPError.test.ts +0 -55
  280. package/core/packages/rest/src/errors/HTTPError.ts +0 -25
  281. package/core/packages/rest/src/errors/RateLimitError.test.ts +0 -41
  282. package/core/packages/rest/src/errors/RateLimitError.ts +0 -15
  283. package/core/packages/rest/src/errors/index.ts +0 -3
  284. package/core/packages/rest/src/index.ts +0 -6
  285. package/core/packages/rest/src/utils/constants.test.ts +0 -31
  286. package/core/packages/rest/src/utils/constants.ts +0 -5
  287. package/core/packages/rest/src/utils/files.test.ts +0 -37
  288. package/core/packages/rest/src/utils/files.ts +0 -75
  289. package/core/packages/rest/tsconfig.json +0 -9
  290. package/core/packages/rest/tsup.config.ts +0 -9
  291. package/core/packages/rest/vitest.config.ts +0 -9
  292. package/core/packages/types/package.json +0 -46
  293. package/core/packages/types/src/api/ban.ts +0 -8
  294. package/core/packages/types/src/api/channel.ts +0 -65
  295. package/core/packages/types/src/api/embed.ts +0 -82
  296. package/core/packages/types/src/api/emoji.ts +0 -12
  297. package/core/packages/types/src/api/errors.ts +0 -68
  298. package/core/packages/types/src/api/gateway.ts +0 -14
  299. package/core/packages/types/src/api/guild.ts +0 -123
  300. package/core/packages/types/src/api/index.ts +0 -15
  301. package/core/packages/types/src/api/instance.ts +0 -32
  302. package/core/packages/types/src/api/interaction.ts +0 -26
  303. package/core/packages/types/src/api/invite.ts +0 -28
  304. package/core/packages/types/src/api/message.ts +0 -140
  305. package/core/packages/types/src/api/role.ts +0 -41
  306. package/core/packages/types/src/api/sticker.ts +0 -14
  307. package/core/packages/types/src/api/user.ts +0 -79
  308. package/core/packages/types/src/api/webhook.ts +0 -41
  309. package/core/packages/types/src/common/index.ts +0 -1
  310. package/core/packages/types/src/common/snowflake.test.ts +0 -9
  311. package/core/packages/types/src/common/snowflake.ts +0 -8
  312. package/core/packages/types/src/gateway/events.ts +0 -189
  313. package/core/packages/types/src/gateway/index.ts +0 -3
  314. package/core/packages/types/src/gateway/opcodes.ts +0 -17
  315. package/core/packages/types/src/gateway/payloads.ts +0 -481
  316. package/core/packages/types/src/index.ts +0 -4
  317. package/core/packages/types/src/rest/index.ts +0 -1
  318. package/core/packages/types/src/rest/routes.test.ts +0 -169
  319. package/core/packages/types/src/rest/routes.ts +0 -109
  320. package/core/packages/types/tsconfig.json +0 -9
  321. package/core/packages/types/tsup.config.ts +0 -9
  322. package/core/packages/types/vitest.config.ts +0 -9
  323. package/core/packages/util/package.json +0 -51
  324. package/core/packages/util/src/BitField.test.ts +0 -96
  325. package/core/packages/util/src/BitField.ts +0 -105
  326. package/core/packages/util/src/MessageFlagsBitField.test.ts +0 -42
  327. package/core/packages/util/src/MessageFlagsBitField.ts +0 -20
  328. package/core/packages/util/src/PermissionsBitField.test.ts +0 -79
  329. package/core/packages/util/src/PermissionsBitField.ts +0 -97
  330. package/core/packages/util/src/SnowflakeUtil.test.ts +0 -69
  331. package/core/packages/util/src/SnowflakeUtil.ts +0 -65
  332. package/core/packages/util/src/UserFlagsBitField.test.ts +0 -39
  333. package/core/packages/util/src/UserFlagsBitField.ts +0 -48
  334. package/core/packages/util/src/deprecation.test.ts +0 -44
  335. package/core/packages/util/src/deprecation.ts +0 -28
  336. package/core/packages/util/src/emojiShortcodes.generated.ts +0 -5
  337. package/core/packages/util/src/emojiShortcodes.test.ts +0 -41
  338. package/core/packages/util/src/emojiShortcodes.ts +0 -22
  339. package/core/packages/util/src/formatters.test.ts +0 -65
  340. package/core/packages/util/src/formatters.ts +0 -35
  341. package/core/packages/util/src/index.ts +0 -34
  342. package/core/packages/util/src/resolvers.test.ts +0 -198
  343. package/core/packages/util/src/resolvers.ts +0 -127
  344. package/core/packages/util/src/tenorUtils.test.ts +0 -75
  345. package/core/packages/util/src/tenorUtils.ts +0 -86
  346. package/core/packages/util/tsconfig.json +0 -9
  347. package/core/packages/util/tsup.config.ts +0 -9
  348. package/core/packages/util/vitest.config.ts +0 -9
  349. package/core/packages/voice/README.md +0 -42
  350. package/core/packages/voice/package.json +0 -67
  351. package/core/packages/voice/src/LiveKitRtcConnection.receive.test.ts +0 -24
  352. package/core/packages/voice/src/LiveKitRtcConnection.ts +0 -1767
  353. package/core/packages/voice/src/VoiceConnection.ts +0 -413
  354. package/core/packages/voice/src/VoiceManager.receive.test.ts +0 -61
  355. package/core/packages/voice/src/VoiceManager.test.ts +0 -44
  356. package/core/packages/voice/src/VoiceManager.ts +0 -503
  357. package/core/packages/voice/src/exports.test.ts +0 -38
  358. package/core/packages/voice/src/index.ts +0 -51
  359. package/core/packages/voice/src/livekit.test.ts +0 -48
  360. package/core/packages/voice/src/livekit.ts +0 -33
  361. package/core/packages/voice/src/mp4box.d.ts +0 -32
  362. package/core/packages/voice/src/opusUtils.test.ts +0 -29
  363. package/core/packages/voice/src/opusUtils.ts +0 -86
  364. package/core/packages/voice/src/streamPreviewPlaceholder.test.ts +0 -16
  365. package/core/packages/voice/src/streamPreviewPlaceholder.ts +0 -8
  366. package/core/packages/voice/src/ws.d.ts +0 -1
  367. package/core/packages/voice/tsconfig.json +0 -5
  368. package/core/packages/voice/tsup.config.ts +0 -10
  369. package/core/packages/voice/vitest.config.ts +0 -9
  370. package/core/packages/ws/package.json +0 -52
  371. package/core/packages/ws/src/WebSocketManager.ts +0 -130
  372. package/core/packages/ws/src/WebSocketShard.ts +0 -296
  373. package/core/packages/ws/src/index.ts +0 -12
  374. package/core/packages/ws/src/utils/constants.test.ts +0 -46
  375. package/core/packages/ws/src/utils/constants.ts +0 -22
  376. package/core/packages/ws/src/utils/getWebSocket.ts +0 -55
  377. package/core/packages/ws/src/ws.d.ts +0 -10
  378. package/core/packages/ws/tsconfig.json +0 -9
  379. package/core/packages/ws/tsup.config.ts +0 -9
  380. package/core/pnpm-lock.yaml +0 -7033
  381. package/core/pnpm-workspace.yaml +0 -4
  382. package/core/scripts/generate-ai-rag.ts +0 -240
  383. package/core/scripts/generate-docs.ts +0 -143
  384. package/core/scripts/generate-emoji-shortcodes.ts +0 -58
  385. package/core/scripts/generate-types.ts +0 -6
  386. package/core/scripts/publish-ordered.js +0 -63
  387. package/core/scripts/test-cjs-require.mjs +0 -43
  388. package/core/scripts/test-esm-imports.mjs +0 -42
  389. package/core/scripts/test-package-exports.mjs +0 -98
  390. package/core/scripts/test-smoke.mjs +0 -103
  391. package/core/tsconfig.json +0 -18
  392. package/core/turbo.json +0 -30
  393. package/core/vitest.config.ts +0 -17
  394. package/core/wrangler.jsonc +0 -9
@@ -1,413 +0,0 @@
1
- import { EventEmitter } from 'events';
2
- import { Client } from '@erinjs/core';
3
- import { VoiceChannel } from '@erinjs/core';
4
- import {
5
- GatewayVoiceServerUpdateDispatchData,
6
- GatewayVoiceStateUpdateDispatchData,
7
- } from '@erinjs/types';
8
- import * as nacl from 'tweetnacl';
9
- import * as dgram from 'dgram';
10
- import * as ws from 'ws';
11
- import { Readable } from 'node:stream';
12
- import { opus } from 'prism-media';
13
- /** Minimal WebSocket type for voice (ws module). */
14
- interface VoiceWebSocket {
15
- send(data: string | Buffer | ArrayBufferLike): void;
16
- close(code?: number): void;
17
- readyState: number;
18
- on(event: string, listener: (...args: unknown[]) => void): void;
19
- once(event: string, listener: (...args: unknown[]) => void): void;
20
- off(event: string, listener: (...args: unknown[]) => void): void;
21
- removeAllListeners(event?: string): void;
22
- }
23
-
24
- const VOICE_WS_OPCODES = {
25
- Identify: 0,
26
- SelectProtocol: 1,
27
- Ready: 2,
28
- Heartbeat: 3,
29
- SessionDescription: 4,
30
- Speaking: 5,
31
- } as const;
32
- const VOICE_VERSION = 4;
33
- const CHANNELS = 2;
34
- /** RTP timestamp increment per 20ms Opus frame (48kHz equivalent). */
35
- const OPUS_FRAME_TICKS = 960 * (CHANNELS === 2 ? 2 : 1);
36
- /** Interval at which Discord expects Opus frames (20ms). */
37
- const AUDIO_FRAME_INTERVAL_MS = 20;
38
-
39
- /** Log full HTTP response for a URL (used when WebSocket gets unexpected status e.g. 200). */
40
- async function logFullResponse(url: string): Promise<void> {
41
- try {
42
- // fetch only supports http/https; wss:// -> https:// for the same endpoint
43
- const fetchUrl = url.replace(/^wss:\/\//i, 'https://').replace(/^ws:\/\//i, 'http://');
44
- const res = await fetch(fetchUrl, { method: 'GET' });
45
- const body = await res.text();
46
- const headers: Record<string, string> = {};
47
- res.headers.forEach((v, k) => {
48
- headers[k] = v;
49
- });
50
- console.error('[voice] Full response from', url, {
51
- status: res.status,
52
- statusText: res.statusText,
53
- headers,
54
- body: body.slice(0, 2000) + (body.length > 2000 ? '...' : ''),
55
- });
56
- } catch (e) {
57
- console.error('[voice] Could not fetch URL for logging:', e);
58
- }
59
- }
60
-
61
- export interface VoiceConnectionEvents {
62
- ready: [];
63
- error: [err: Error];
64
- disconnect: [];
65
- }
66
-
67
- /** Voice connection using Discord's UDP-based protocol. Emits `ready`, `error`, `disconnect`. */
68
- export class VoiceConnection extends EventEmitter {
69
- readonly client: Client;
70
- readonly channel: VoiceChannel;
71
- readonly guildId: string;
72
- private _sessionId: string | null = null;
73
- private _token: string | null = null;
74
- private _endpoint: string | null = null;
75
- private _userId: string;
76
- private voiceWs: VoiceWebSocket | null = null;
77
- private udpSocket: dgram.Socket | null = null;
78
- private ssrc: number = 0;
79
- private secretKey: Uint8Array | null = null;
80
- private heartbeatInterval: ReturnType<typeof setInterval> | null = null;
81
- private sequence = 0;
82
- private timestamp = 0;
83
- private _playing = false;
84
- private _destroyed = false;
85
- private currentStream: { destroy?: () => void } | null = null;
86
- private remoteUdpAddress: string = '';
87
- private remoteUdpPort: number = 0;
88
- private audioPacketQueue: Buffer[] = [];
89
- private pacingInterval: ReturnType<typeof setInterval> | null = null;
90
-
91
- constructor(client: Client, channel: VoiceChannel, userId: string) {
92
- super();
93
- this.client = client;
94
- this.channel = channel;
95
- this.guildId = channel.guildId;
96
- this._userId = userId;
97
- }
98
-
99
- /** Discord voice session ID. */
100
- get sessionId(): string | null {
101
- return this._sessionId;
102
- }
103
-
104
- /** Whether audio is currently playing. */
105
- get playing(): boolean {
106
- return this._playing;
107
- }
108
-
109
- /** Called when we have both server update and state update. */
110
- async connect(
111
- server: GatewayVoiceServerUpdateDispatchData,
112
- state: GatewayVoiceStateUpdateDispatchData,
113
- ): Promise<void> {
114
- this._token = server.token;
115
- const raw = (server.endpoint ?? '').trim();
116
- this._sessionId = state.session_id;
117
- if (!raw || !this._token || !this._sessionId) {
118
- this.emit('error', new Error('Missing voice server or session data'));
119
- return;
120
- }
121
- // Endpoint may be a full URL (path + query, e.g. wss://host/rtc?access_token=...) or host[/path]
122
- let wsUrl: string;
123
- if (raw.includes('?')) {
124
- // Full stream URL: use as-is, ensure wss
125
- wsUrl = /^wss?:\/\//i.test(raw) ? raw : raw.replace(/^https?:\/\//i, 'wss://');
126
- if (!/^wss?:\/\//i.test(wsUrl)) wsUrl = `wss://${wsUrl}`;
127
- } else {
128
- const normalized = raw.replace(/^(wss|ws|https?):\/\//i, '').replace(/^\/+/, '') || raw;
129
- wsUrl = `wss://${normalized}?v=${VOICE_VERSION}`;
130
- }
131
- // Host only (for UDP address fallback in Ready handler)
132
- const hostPart =
133
- raw
134
- .replace(/^(wss|ws|https?):\/\//i, '')
135
- .replace(/^\/+/, '')
136
- .split('/')[0] ?? '';
137
- this._endpoint = hostPart.split('?')[0] || hostPart;
138
- const WS = await this.getWebSocketConstructor();
139
- this.voiceWs = new WS(wsUrl);
140
- return new Promise((resolve, reject) => {
141
- const resolveReady = () => {
142
- cleanup();
143
- resolve();
144
- this.emit('ready');
145
- };
146
- const onOpen = () => {
147
- this.voiceWs!.off('error', onError);
148
- this.sendVoiceOp(VOICE_WS_OPCODES.Identify, {
149
- server_id: this.guildId,
150
- user_id: this._userId,
151
- session_id: this._sessionId!,
152
- token: this._token!,
153
- });
154
- };
155
- const onError = (err: unknown) => {
156
- if (err instanceof Error && /Unexpected server response/i.test(err.message)) {
157
- logFullResponse(wsUrl).catch(() => {});
158
- }
159
- cleanup();
160
- reject(err instanceof Error ? err : new Error(String(err)));
161
- };
162
- const onMessage = (data: Buffer | ArrayBuffer) => {
163
- const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
164
- const payload = JSON.parse(buf.toString());
165
- const op = payload.op;
166
- const d = payload.d;
167
- if (op === VOICE_WS_OPCODES.Ready) {
168
- this.ssrc = d.ssrc;
169
- const port = d.port;
170
- const address = (d as { address?: string }).address ?? this._endpoint!.split(':')[0];
171
- this.remoteUdpAddress = address;
172
- this.remoteUdpPort = port;
173
- this.setupUDP(address, port, () => {
174
- // SelectProtocol sent; wait for SessionDescription before resolving
175
- });
176
- } else if (op === VOICE_WS_OPCODES.SessionDescription) {
177
- this.secretKey = new Uint8Array(d.secret_key);
178
- if (this.heartbeatInterval) {
179
- clearInterval(this.heartbeatInterval);
180
- this.heartbeatInterval = null;
181
- }
182
- this.heartbeatInterval = setInterval(() => {
183
- this.sendVoiceOp(VOICE_WS_OPCODES.Heartbeat, Date.now());
184
- }, d.heartbeat_interval ?? 5000);
185
- resolveReady();
186
- } else if (op === VOICE_WS_OPCODES.Heartbeat) {
187
- // ack
188
- }
189
- };
190
- const cleanup = () => {
191
- if (this.voiceWs) {
192
- this.voiceWs.removeAllListeners();
193
- }
194
- };
195
- const ws = this.voiceWs!;
196
- ws.on('open', onOpen);
197
- ws.on('error', onError);
198
- ws.on('message', (data: unknown) => onMessage(data as Buffer | ArrayBuffer));
199
- ws.once('close', () => {
200
- cleanup();
201
- if (!this._destroyed) reject(new Error('Voice WebSocket closed'));
202
- });
203
- });
204
- }
205
-
206
- private async getWebSocketConstructor(): Promise<new (url: string) => VoiceWebSocket> {
207
- try {
208
- return ws.default as new (url: string) => VoiceWebSocket;
209
- } catch {
210
- throw new Error('Install "ws" for voice support: pnpm add ws');
211
- }
212
- }
213
-
214
- private sendVoiceOp(op: number, d: unknown): void {
215
- if (!this.voiceWs || this.voiceWs.readyState !== 1) return;
216
- this.voiceWs.send(JSON.stringify({ op, d }));
217
- }
218
-
219
- private setupUDP(remoteAddress: string, remotePort: number, onReady: () => void): void {
220
- const socket = dgram.createSocket('udp4');
221
- this.udpSocket = socket;
222
- const discovery = Buffer.alloc(70);
223
- discovery.writeUInt32BE(0x00000001, 0);
224
- discovery.writeUInt16BE(70, 4);
225
- discovery.writeUInt32BE(this.ssrc, 6);
226
- socket.send(discovery, 0, discovery.length, remotePort, remoteAddress, () => {
227
- socket.once('message', (msg: Buffer) => {
228
- if (msg.length < 70) {
229
- this.emit('error', new Error('UDP discovery response too short'));
230
- return;
231
- }
232
- const len = msg.readUInt16BE(4);
233
- let ourIp = '';
234
- let i = 10;
235
- while (i < Math.min(70, len + 8) && msg[i] !== 0) {
236
- ourIp += String.fromCharCode(msg[i]);
237
- i++;
238
- }
239
- const ourPort = msg.readUInt16BE(68);
240
- this.sendVoiceOp(VOICE_WS_OPCODES.SelectProtocol, {
241
- protocol: 'udp',
242
- data: {
243
- address: ourIp,
244
- port: ourPort,
245
- mode: 'xsalsa20_poly1305',
246
- },
247
- });
248
- onReady();
249
- });
250
- });
251
- }
252
-
253
- /**
254
- * Play a stream of raw Opus packets
255
- * Uses the same queue and 20ms pacing as play(). Use this for local files (MP3 → PCM → Opus) or other Opus sources.
256
- */
257
- playOpus(stream: NodeJS.ReadableStream): void {
258
- this.stop();
259
- this._playing = true;
260
- this.currentStream = stream as { destroy?: () => void };
261
- this.audioPacketQueue = [];
262
- this.sendVoiceOp(VOICE_WS_OPCODES.Speaking, { speaking: 1, delay: 0 });
263
-
264
- const stopPacing = () => {
265
- if (this.pacingInterval) {
266
- clearInterval(this.pacingInterval);
267
- this.pacingInterval = null;
268
- }
269
- };
270
- this.pacingInterval = setInterval(() => {
271
- const packet = this.audioPacketQueue.shift();
272
- if (packet && this.secretKey && this.udpSocket) this.sendAudioFrame(packet);
273
- if (this.audioPacketQueue.length === 0 && !this._playing) stopPacing();
274
- }, AUDIO_FRAME_INTERVAL_MS);
275
-
276
- stream.on('data', (chunk: Buffer) => {
277
- if (!this._playing) return;
278
- if (Buffer.isBuffer(chunk) && chunk.length > 0) this.audioPacketQueue.push(chunk);
279
- });
280
- stream.on('error', (err: Error) => {
281
- this._playing = false;
282
- this.currentStream = null;
283
- stopPacing();
284
- this.emit('error', err);
285
- });
286
- stream.on('end', () => {
287
- this._playing = false;
288
- this.currentStream = null;
289
- if (this.audioPacketQueue.length === 0) stopPacing();
290
- });
291
- }
292
-
293
- /**
294
- * Play a direct WebM/Opus URL or stream. Fetches the URL (if string), demuxes with prism-media WebmDemuxer,
295
- * and sends Opus packets to the voice connection. No FFmpeg or encoding; input must be WebM with Opus.
296
- */
297
- async play(urlOrStream: string | NodeJS.ReadableStream): Promise<void> {
298
- this.stop();
299
-
300
- let inputStream: NodeJS.ReadableStream;
301
- if (typeof urlOrStream === 'string') {
302
- try {
303
- const response = await fetch(urlOrStream);
304
- if (!response.ok) throw new Error(`HTTP ${response.status}`);
305
- if (!response.body) throw new Error('No response body');
306
- inputStream = Readable.fromWeb(response.body as Parameters<typeof Readable.fromWeb>[0]);
307
- } catch (e) {
308
- const err = e instanceof Error ? e : new Error(String(e));
309
- this.emit('error', err);
310
- return;
311
- }
312
- } else {
313
- inputStream = urlOrStream;
314
- }
315
-
316
- const demuxer = new opus.WebmDemuxer();
317
- (inputStream as NodeJS.ReadableStream).pipe(demuxer);
318
-
319
- this._playing = true;
320
- this.currentStream = demuxer;
321
- this.audioPacketQueue = [];
322
- this.sendVoiceOp(VOICE_WS_OPCODES.Speaking, { speaking: 1, delay: 0 });
323
-
324
- const stopPacing = () => {
325
- if (this.pacingInterval) {
326
- clearInterval(this.pacingInterval);
327
- this.pacingInterval = null;
328
- }
329
- };
330
- this.pacingInterval = setInterval(() => {
331
- const packet = this.audioPacketQueue.shift();
332
- if (packet && this.secretKey && this.udpSocket) this.sendAudioFrame(packet);
333
- if (this.audioPacketQueue.length === 0 && !this._playing) stopPacing();
334
- }, AUDIO_FRAME_INTERVAL_MS);
335
-
336
- demuxer.on('data', (chunk: Buffer) => {
337
- if (!this._playing) return;
338
- if (Buffer.isBuffer(chunk) && chunk.length > 0) this.audioPacketQueue.push(chunk);
339
- });
340
- demuxer.on('error', (err: Error) => {
341
- this._playing = false;
342
- this.currentStream = null;
343
- stopPacing();
344
- this.emit('error', err);
345
- });
346
- demuxer.on('end', () => {
347
- this._playing = false;
348
- this.currentStream = null;
349
- if (this.audioPacketQueue.length === 0) stopPacing();
350
- });
351
- }
352
-
353
- private sendAudioFrame(opusPayload: Buffer): void {
354
- if (!this.udpSocket || !this.secretKey) return;
355
- const rtpHeader = Buffer.alloc(12);
356
- rtpHeader[0] = 0x80;
357
- rtpHeader[1] = 0x78;
358
- rtpHeader.writeUInt16BE(this.sequence++, 2);
359
- rtpHeader.writeUInt32BE(this.timestamp, 4);
360
- rtpHeader.writeUInt32BE(this.ssrc, 8);
361
- this.timestamp += OPUS_FRAME_TICKS;
362
- const nonce = Buffer.alloc(24);
363
- rtpHeader.copy(nonce, 0, 0, 12);
364
- const encrypted = nacl.secretbox(opusPayload, new Uint8Array(nonce), this.secretKey);
365
- const packet = Buffer.concat([rtpHeader, Buffer.from(encrypted)]);
366
- if (this.remoteUdpPort && this.remoteUdpAddress && this.udpSocket) {
367
- this.udpSocket.send(packet, 0, packet.length, this.remoteUdpPort, this.remoteUdpAddress);
368
- }
369
- }
370
-
371
- /** Stop playback and clear the queue. */
372
- stop(): void {
373
- this._playing = false;
374
- this.audioPacketQueue = [];
375
- if (this.pacingInterval) {
376
- clearInterval(this.pacingInterval);
377
- this.pacingInterval = null;
378
- }
379
- if (this.currentStream) {
380
- if (typeof this.currentStream.destroy === 'function') this.currentStream.destroy();
381
- this.currentStream = null;
382
- }
383
- }
384
-
385
- /** Disconnect from voice (closes WebSocket and UDP). */
386
- disconnect(): void {
387
- this._destroyed = true;
388
- this.stop();
389
- if (this.heartbeatInterval) {
390
- clearInterval(this.heartbeatInterval);
391
- this.heartbeatInterval = null;
392
- }
393
- if (this.voiceWs) {
394
- this.voiceWs.close();
395
- this.voiceWs = null;
396
- }
397
- if (this.udpSocket) {
398
- this.udpSocket.close();
399
- this.udpSocket = null;
400
- }
401
- this.emit('disconnect');
402
- }
403
-
404
- /** Disconnect and remove all listeners. */
405
- destroy(): void {
406
- if (this.currentStream) {
407
- if (typeof this.currentStream.destroy === 'function') this.currentStream.destroy();
408
- this.currentStream = null;
409
- }
410
- this.disconnect();
411
- this.removeAllListeners();
412
- }
413
- }
@@ -1,61 +0,0 @@
1
- import { describe, it, expect, vi } from 'vitest';
2
- import { VoiceManager } from './VoiceManager.js';
3
- import { LiveKitRtcConnection } from './LiveKitRtcConnection.js';
4
-
5
- function makeClient() {
6
- return {
7
- on: vi.fn(),
8
- emit: vi.fn(),
9
- sendToGateway: vi.fn(),
10
- user: { id: 'bot' },
11
- rest: { post: vi.fn() },
12
- };
13
- }
14
-
15
- describe('VoiceManager receive helpers', () => {
16
- it('lists participants in a channel from voice state map', () => {
17
- const manager = new VoiceManager(makeClient() as never);
18
-
19
- manager.voiceStates.set(
20
- 'g1',
21
- new Map([
22
- ['u1', 'c1'],
23
- ['u2', 'c1'],
24
- ['u3', 'c2'],
25
- ]),
26
- );
27
-
28
- expect(manager.listParticipantsInChannel('g1', 'c1')).toEqual(['u1', 'u2']);
29
- expect(manager.listParticipantsInChannel('g1', 'missing')).toEqual([]);
30
- });
31
-
32
- it('subscribes known channel participants for livekit connections', () => {
33
- const client = makeClient();
34
- const manager = new VoiceManager(client as never);
35
-
36
- const channel = { id: 'c1', guildId: 'g1' } as never;
37
- const conn = new LiveKitRtcConnection(client as never, channel, 'bot');
38
- const subscribeSpy = vi
39
- .spyOn(conn, 'subscribeParticipantAudio')
40
- .mockImplementation((participantId) => ({ participantId, stop: vi.fn() }));
41
-
42
- manager.voiceStates.set(
43
- 'g1',
44
- new Map([
45
- ['bot', 'c1'],
46
- ['u1', 'c1'],
47
- ['u2', 'c1'],
48
- ['u3', 'c9'],
49
- ]),
50
- );
51
- (manager as unknown as { connections: Map<string, LiveKitRtcConnection> }).connections.set(
52
- 'c1',
53
- conn,
54
- );
55
-
56
- const subs = manager.subscribeChannelParticipants('c1');
57
-
58
- expect(subscribeSpy).toHaveBeenCalledTimes(2);
59
- expect(subs.map((s) => s.participantId)).toEqual(['u1', 'u2']);
60
- });
61
- });
@@ -1,44 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { EventEmitter } from 'events';
3
- import { Events } from '@erinjs/core';
4
- import { VoiceManager } from './VoiceManager.js';
5
-
6
- /** Minimal Client mock - VoiceManager only needs .on() for voice events. */
7
- function createMockClient(): EventEmitter & { user?: { id: string } } {
8
- const client = new EventEmitter() as EventEmitter & { user?: { id: string } };
9
- return client;
10
- }
11
-
12
- describe('VoiceManager', () => {
13
- it('getVoiceChannelId returns null for unknown guild', () => {
14
- const client = createMockClient();
15
- const vm = new VoiceManager(client);
16
- expect(vm.getVoiceChannelId('guild1', 'user1')).toBeNull();
17
- });
18
-
19
- it('getVoiceChannelId returns channel after VoiceStatesSync', () => {
20
- const client = createMockClient();
21
- const vm = new VoiceManager(client);
22
- client.emit(Events.VoiceStatesSync, {
23
- guildId: 'guild1',
24
- voiceStates: [
25
- { user_id: 'user1', channel_id: 'channel1' },
26
- { user_id: 'user2', channel_id: null },
27
- ],
28
- });
29
- expect(vm.getVoiceChannelId('guild1', 'user1')).toBe('channel1');
30
- expect(vm.getVoiceChannelId('guild1', 'user2')).toBeNull();
31
- expect(vm.getVoiceChannelId('guild1', 'user3')).toBeNull();
32
- });
33
-
34
- it('getVoiceChannelId returns null for user not in guild map', () => {
35
- const client = createMockClient();
36
- const vm = new VoiceManager(client);
37
- client.emit(Events.VoiceStatesSync, {
38
- guildId: 'guild1',
39
- voiceStates: [{ user_id: 'user1', channel_id: 'channel1' }],
40
- });
41
- expect(vm.getVoiceChannelId('guild1', 'user2')).toBeNull();
42
- expect(vm.getVoiceChannelId('guild2', 'user1')).toBeNull();
43
- });
44
- });