onyxcord 2.1.0 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. checksums.yaml +4 -4
  2. data/lib/onyxcord/application_commands/command.rb +4 -97
  3. data/lib/onyxcord/application_commands/context.rb +4 -94
  4. data/lib/onyxcord/application_commands/option.rb +4 -75
  5. data/lib/onyxcord/application_commands/registry.rb +4 -45
  6. data/lib/onyxcord/application_commands.rb +8 -5
  7. data/lib/onyxcord/bot.rb +24 -1759
  8. data/lib/onyxcord/{cache.rb → cache/manager.rb} +16 -14
  9. data/lib/onyxcord/cache/stores/gateway.rb +272 -0
  10. data/lib/onyxcord/commands/bot/channels.rb +48 -0
  11. data/lib/onyxcord/commands/bot/execution.rb +174 -0
  12. data/lib/onyxcord/commands/bot/message_dispatch.rb +58 -0
  13. data/lib/onyxcord/commands/bot/permissions.rb +72 -0
  14. data/lib/onyxcord/commands/bot.rb +209 -0
  15. data/lib/onyxcord/commands/container.rb +21 -2
  16. data/lib/onyxcord/commands/parser.rb +30 -1
  17. data/lib/onyxcord/container.rb +16 -960
  18. data/lib/onyxcord/core/bot/application_commands.rb +210 -0
  19. data/lib/onyxcord/core/bot/awaits.rb +112 -0
  20. data/lib/onyxcord/core/bot/invites.rb +42 -0
  21. data/lib/onyxcord/core/bot/messaging.rb +161 -0
  22. data/lib/onyxcord/core/bot/oauth.rb +27 -0
  23. data/lib/onyxcord/core/bot/presence.rb +103 -0
  24. data/lib/onyxcord/core/bot/runtime.rb +183 -0
  25. data/lib/onyxcord/core/bot/voice.rb +69 -0
  26. data/lib/onyxcord/{logger.rb → core/logger.rb} +5 -0
  27. data/lib/onyxcord/core/version.rb +5 -0
  28. data/lib/onyxcord/events/await/base.rb +48 -0
  29. data/lib/onyxcord/events/await.rb +1 -46
  30. data/lib/onyxcord/events/ban/base.rb +54 -0
  31. data/lib/onyxcord/events/ban/remove.rb +11 -0
  32. data/lib/onyxcord/events/bans.rb +2 -58
  33. data/lib/onyxcord/events/channels/base.rb +91 -0
  34. data/lib/onyxcord/events/channels/delete.rb +73 -0
  35. data/lib/onyxcord/events/channels/pins.rb +44 -0
  36. data/lib/onyxcord/events/channels/recipients.rb +77 -0
  37. data/lib/onyxcord/events/channels.rb +4 -239
  38. data/lib/onyxcord/events/guilds/audit_logs.rb +79 -0
  39. data/lib/onyxcord/events/guilds/base.rb +97 -0
  40. data/lib/onyxcord/events/guilds/emoji.rb +147 -0
  41. data/lib/onyxcord/events/guilds.rb +3 -267
  42. data/lib/onyxcord/events/handlers/channels.rb +133 -0
  43. data/lib/onyxcord/events/handlers/core.rb +146 -0
  44. data/lib/onyxcord/events/handlers/guilds.rb +375 -0
  45. data/lib/onyxcord/events/handlers/interactions.rb +238 -0
  46. data/lib/onyxcord/events/handlers/lifetime.rb +71 -0
  47. data/lib/onyxcord/events/handlers/messages.rb +218 -0
  48. data/lib/onyxcord/events/handlers/presence.rb +56 -0
  49. data/lib/onyxcord/events/handlers/raw.rb +39 -0
  50. data/lib/onyxcord/events/handlers/reactions.rb +98 -0
  51. data/lib/onyxcord/events/handlers/scheduled_events.rb +243 -0
  52. data/lib/onyxcord/events/handlers/voice.rb +46 -0
  53. data/lib/onyxcord/events/integration/base.rb +45 -0
  54. data/lib/onyxcord/events/integration/create.rb +11 -0
  55. data/lib/onyxcord/events/integration/delete.rb +48 -0
  56. data/lib/onyxcord/events/integration/update.rb +11 -0
  57. data/lib/onyxcord/events/integrations.rb +4 -98
  58. data/lib/onyxcord/events/interactions/application_commands.rb +185 -0
  59. data/lib/onyxcord/events/interactions/autocomplete.rb +62 -0
  60. data/lib/onyxcord/events/interactions/base.rb +175 -0
  61. data/lib/onyxcord/events/interactions/components.rb +221 -0
  62. data/lib/onyxcord/events/interactions/permissions.rb +53 -0
  63. data/lib/onyxcord/events/interactions.rb +5 -622
  64. data/lib/onyxcord/events/invite/create.rb +79 -0
  65. data/lib/onyxcord/events/invite/delete.rb +55 -0
  66. data/lib/onyxcord/events/invites.rb +2 -125
  67. data/lib/onyxcord/events/lifetime/base.rb +31 -0
  68. data/lib/onyxcord/events/lifetime.rb +1 -29
  69. data/lib/onyxcord/events/member/add.rb +12 -0
  70. data/lib/onyxcord/events/member/base.rb +67 -0
  71. data/lib/onyxcord/events/member/delete.rb +21 -0
  72. data/lib/onyxcord/events/member/update.rb +25 -0
  73. data/lib/onyxcord/events/members.rb +4 -108
  74. data/lib/onyxcord/events/message/base.rb +295 -0
  75. data/lib/onyxcord/events/message/ids.rb +71 -0
  76. data/lib/onyxcord/events/message/mentions.rb +55 -0
  77. data/lib/onyxcord/events/message/updates.rb +27 -0
  78. data/lib/onyxcord/events/message.rb +4 -397
  79. data/lib/onyxcord/events/poll/add.rb +11 -0
  80. data/lib/onyxcord/events/poll/base.rb +106 -0
  81. data/lib/onyxcord/events/poll/remove.rb +11 -0
  82. data/lib/onyxcord/events/polls.rb +3 -116
  83. data/lib/onyxcord/events/presence/playing.rb +77 -0
  84. data/lib/onyxcord/events/presence/status.rb +60 -0
  85. data/lib/onyxcord/events/presence.rb +2 -129
  86. data/lib/onyxcord/events/raw/base.rb +74 -0
  87. data/lib/onyxcord/events/raw.rb +1 -72
  88. data/lib/onyxcord/events/reactions/base.rb +143 -0
  89. data/lib/onyxcord/events/reactions/clear.rb +99 -0
  90. data/lib/onyxcord/events/reactions.rb +2 -216
  91. data/lib/onyxcord/events/role/create.rb +46 -0
  92. data/lib/onyxcord/events/role/delete.rb +40 -0
  93. data/lib/onyxcord/events/role/update.rb +11 -0
  94. data/lib/onyxcord/events/roles.rb +3 -85
  95. data/lib/onyxcord/events/scheduled_events/events.rb +112 -0
  96. data/lib/onyxcord/events/scheduled_events/users.rb +91 -0
  97. data/lib/onyxcord/events/scheduled_events.rb +2 -169
  98. data/lib/onyxcord/events/thread/base.rb +49 -0
  99. data/lib/onyxcord/events/thread/members.rb +44 -0
  100. data/lib/onyxcord/events/thread/update.rb +18 -0
  101. data/lib/onyxcord/events/threads.rb +3 -98
  102. data/lib/onyxcord/events/typing/base.rb +73 -0
  103. data/lib/onyxcord/events/typing.rb +1 -71
  104. data/lib/onyxcord/events/voice/server_update.rb +48 -0
  105. data/lib/onyxcord/events/voice/state_update.rb +137 -0
  106. data/lib/onyxcord/events/voice_server_update.rb +2 -46
  107. data/lib/onyxcord/events/voice_state_update.rb +2 -135
  108. data/lib/onyxcord/events/webhook/update.rb +65 -0
  109. data/lib/onyxcord/events/webhooks.rb +1 -63
  110. data/lib/onyxcord/gateway/client.rb +460 -0
  111. data/lib/onyxcord/interactions/command.rb +120 -0
  112. data/lib/onyxcord/interactions/context.rb +109 -0
  113. data/lib/onyxcord/interactions/internal/application_command.rb +203 -0
  114. data/lib/onyxcord/interactions/internal/message.rb +152 -0
  115. data/lib/onyxcord/interactions/internal/metadata.rb +109 -0
  116. data/lib/onyxcord/interactions/internal/option_builder.rb +230 -0
  117. data/lib/onyxcord/interactions/internal/permission_builder.rb +90 -0
  118. data/lib/onyxcord/interactions/option.rb +88 -0
  119. data/lib/onyxcord/interactions/registry.rb +50 -0
  120. data/lib/onyxcord/interactions.rb +16 -0
  121. data/lib/onyxcord/internal/async_runtime.rb +32 -0
  122. data/lib/onyxcord/internal/event_bus.rb +591 -0
  123. data/lib/onyxcord/internal/event_executor.rb +155 -0
  124. data/lib/onyxcord/internal/gateway/opcodes.rb +22 -0
  125. data/lib/onyxcord/internal/gateway/session.rb +45 -0
  126. data/lib/onyxcord/internal/http.rb +189 -0
  127. data/lib/onyxcord/internal/json.rb +51 -0
  128. data/lib/onyxcord/{message_payload.rb → internal/message_payload.rb} +3 -3
  129. data/lib/onyxcord/internal/rate_limiter/async_rest.rb +151 -0
  130. data/lib/onyxcord/internal/rate_limiter/gateway.rb +44 -0
  131. data/lib/onyxcord/internal/rate_limiter/rest.rb +144 -0
  132. data/lib/onyxcord/internal/websocket.rb +79 -0
  133. data/lib/onyxcord/light/data.rb +1 -1
  134. data/lib/onyxcord/light/integrations.rb +1 -1
  135. data/lib/onyxcord/light/light_bot.rb +7 -7
  136. data/lib/onyxcord/{data → models}/activity.rb +2 -2
  137. data/lib/onyxcord/{data → models}/application.rb +3 -3
  138. data/lib/onyxcord/{data → models}/avatar_decoration.rb +1 -1
  139. data/lib/onyxcord/{data → models}/channel.rb +23 -23
  140. data/lib/onyxcord/{data → models}/collectibles.rb +1 -1
  141. data/lib/onyxcord/{data → models}/emoji.rb +1 -1
  142. data/lib/onyxcord/models/interaction.rb +450 -0
  143. data/lib/onyxcord/{data → models}/invite.rb +1 -1
  144. data/lib/onyxcord/{data → models}/member.rb +11 -11
  145. data/lib/onyxcord/{data → models}/message.rb +18 -14
  146. data/lib/onyxcord/{data → models}/poll.rb +2 -2
  147. data/lib/onyxcord/{data → models}/primary_server.rb +1 -1
  148. data/lib/onyxcord/{data → models}/profile.rb +4 -4
  149. data/lib/onyxcord/{data → models}/role.rb +6 -12
  150. data/lib/onyxcord/{data → models}/scheduled_event.rb +5 -5
  151. data/lib/onyxcord/{data → models}/server.rb +41 -41
  152. data/lib/onyxcord/{data → models}/server_preview.rb +2 -2
  153. data/lib/onyxcord/{data → models}/team.rb +1 -1
  154. data/lib/onyxcord/{data → models}/user.rb +5 -5
  155. data/lib/onyxcord/{data → models}/webhook.rb +10 -10
  156. data/lib/onyxcord/models.rb +57 -0
  157. data/lib/onyxcord/{api.rb → rest/client.rb} +23 -22
  158. data/lib/onyxcord/{api → rest/routes}/application.rb +79 -57
  159. data/lib/onyxcord/rest/routes/channel/base.rb +73 -0
  160. data/lib/onyxcord/rest/routes/channel/groups.rb +78 -0
  161. data/lib/onyxcord/rest/routes/channel/messages.rb +130 -0
  162. data/lib/onyxcord/rest/routes/channel/permissions.rb +73 -0
  163. data/lib/onyxcord/rest/routes/channel/pins.rb +45 -0
  164. data/lib/onyxcord/rest/routes/channel/polls.rb +32 -0
  165. data/lib/onyxcord/rest/routes/channel/reactions.rb +86 -0
  166. data/lib/onyxcord/rest/routes/channel/threads.rb +176 -0
  167. data/lib/onyxcord/rest/routes/channel/webhooks.rb +47 -0
  168. data/lib/onyxcord/rest/routes/channel.rb +12 -0
  169. data/lib/onyxcord/{api/interaction.rb → rest/routes/interaction/base.rb} +7 -25
  170. data/lib/onyxcord/rest/routes/interaction/response.rb +24 -0
  171. data/lib/onyxcord/rest/routes/interaction.rb +4 -0
  172. data/lib/onyxcord/{api → rest/routes}/invite.rb +7 -7
  173. data/lib/onyxcord/rest/routes/server/admin.rb +174 -0
  174. data/lib/onyxcord/rest/routes/server/assets.rb +25 -0
  175. data/lib/onyxcord/rest/routes/server/bans.rb +67 -0
  176. data/lib/onyxcord/rest/routes/server/base.rb +77 -0
  177. data/lib/onyxcord/rest/routes/server/channels.rb +58 -0
  178. data/lib/onyxcord/rest/routes/server/emoji.rb +48 -0
  179. data/lib/onyxcord/rest/routes/server/members.rb +109 -0
  180. data/lib/onyxcord/rest/routes/server/messages.rb +19 -0
  181. data/lib/onyxcord/rest/routes/server/roles.rb +156 -0
  182. data/lib/onyxcord/rest/routes/server/scheduled_events.rb +86 -0
  183. data/lib/onyxcord/rest/routes/server.rb +12 -0
  184. data/lib/onyxcord/{api → rest/routes}/user.rb +23 -23
  185. data/lib/onyxcord/{api → rest/routes}/webhook.rb +22 -22
  186. data/lib/onyxcord/{allowed_mentions.rb → utils/allowed_mentions.rb} +1 -1
  187. data/lib/onyxcord/utils/timestamp.rb +69 -0
  188. data/lib/onyxcord/voice/{voice_bot.rb → client.rb} +4 -4
  189. data/lib/onyxcord/voice/encoder.rb +1 -1
  190. data/lib/onyxcord/voice/network/udp.rb +135 -0
  191. data/lib/onyxcord/voice/network/websocket.rb +225 -0
  192. data/lib/onyxcord/voice/network.rb +5 -357
  193. data/lib/onyxcord/webhooks/builder.rb +1 -1
  194. data/lib/onyxcord/webhooks/client.rb +13 -13
  195. data/lib/onyxcord/webhooks/modal/group_builder.rb +55 -0
  196. data/lib/onyxcord/webhooks/modal/label_builder.rb +183 -0
  197. data/lib/onyxcord/webhooks/modal.rb +2 -239
  198. data/lib/onyxcord/webhooks/version.rb +3 -3
  199. data/lib/onyxcord/webhooks/view/container_builder.rb +80 -0
  200. data/lib/onyxcord/webhooks/view/file_builder.rb +24 -0
  201. data/lib/onyxcord/webhooks/view/media_gallery_builder.rb +50 -0
  202. data/lib/onyxcord/webhooks/view/row_builder.rb +120 -0
  203. data/lib/onyxcord/webhooks/view/section_builder.rb +61 -0
  204. data/lib/onyxcord/webhooks/view/select_menu_builder.rb +77 -0
  205. data/lib/onyxcord/webhooks/view/separator_builder.rb +22 -0
  206. data/lib/onyxcord/webhooks/view/text_display_builder.rb +20 -0
  207. data/lib/onyxcord/webhooks/view.rb +9 -425
  208. data/lib/onyxcord.rb +106 -42
  209. metadata +207 -92
  210. data/.github/CONTRIBUTING.md +0 -13
  211. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
  212. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -24
  213. data/.github/pull_request_template.md +0 -37
  214. data/.github/workflows/ci.yml +0 -78
  215. data/.github/workflows/codeql.yml +0 -65
  216. data/.github/workflows/deploy.yml +0 -54
  217. data/.github/workflows/release.yml +0 -51
  218. data/.gitignore +0 -17
  219. data/.markdownlint.json +0 -4
  220. data/.overcommit.yml +0 -7
  221. data/.rspec +0 -2
  222. data/.rubocop.yml +0 -129
  223. data/.yardopts +0 -1
  224. data/CHANGELOG.md +0 -257
  225. data/Gemfile +0 -6
  226. data/LICENSE.txt +0 -21
  227. data/README.md +0 -448
  228. data/Rakefile +0 -13
  229. data/lib/onyxcord/api/channel.rb +0 -703
  230. data/lib/onyxcord/api/server.rb +0 -775
  231. data/lib/onyxcord/async/runtime.rb +0 -30
  232. data/lib/onyxcord/commands/command_bot.rb +0 -505
  233. data/lib/onyxcord/data/interaction.rb +0 -1151
  234. data/lib/onyxcord/data.rb +0 -57
  235. data/lib/onyxcord/event_executor.rb +0 -153
  236. data/lib/onyxcord/gateway.rb +0 -505
  237. data/lib/onyxcord/http.rb +0 -186
  238. data/lib/onyxcord/json.rb +0 -49
  239. data/lib/onyxcord/rate_limiter/async_rest.rb +0 -150
  240. data/lib/onyxcord/rate_limiter/gateway.rb +0 -42
  241. data/lib/onyxcord/rate_limiter/rest.rb +0 -142
  242. data/lib/onyxcord/version.rb +0 -7
  243. data/lib/onyxcord/websocket.rb +0 -77
  244. data/onyxcord.gemspec +0 -63
  245. /data/lib/onyxcord/{configuration.rb → core/configuration.rb} +0 -0
  246. /data/lib/onyxcord/{errors.rb → core/errors.rb} +0 -0
  247. /data/lib/onyxcord/{upload.rb → internal/upload.rb} +0 -0
  248. /data/lib/onyxcord/{data → models}/attachment.rb +0 -0
  249. /data/lib/onyxcord/{data → models}/audit_logs.rb +0 -0
  250. /data/lib/onyxcord/{data → models}/call.rb +0 -0
  251. /data/lib/onyxcord/{data → models}/channel_tag.rb +0 -0
  252. /data/lib/onyxcord/{data → models}/component.rb +0 -0
  253. /data/lib/onyxcord/{data → models}/embed.rb +0 -0
  254. /data/lib/onyxcord/{data → models}/install_params.rb +0 -0
  255. /data/lib/onyxcord/{data → models}/integration.rb +0 -0
  256. /data/lib/onyxcord/{data → models}/message_activity.rb +0 -0
  257. /data/lib/onyxcord/{data → models}/overwrite.rb +0 -0
  258. /data/lib/onyxcord/{data → models}/reaction.rb +0 -0
  259. /data/lib/onyxcord/{data → models}/recipient.rb +0 -0
  260. /data/lib/onyxcord/{data → models}/role_connection_data.rb +0 -0
  261. /data/lib/onyxcord/{data → models}/role_subscription.rb +0 -0
  262. /data/lib/onyxcord/{data → models}/snapshot.rb +0 -0
  263. /data/lib/onyxcord/{data → models}/timestamp.rb +0 -0
  264. /data/lib/onyxcord/{data → models}/voice_region.rb +0 -0
  265. /data/lib/onyxcord/{data → models}/voice_state.rb +0 -0
  266. /data/lib/onyxcord/{colour_rgb.rb → utils/colour_rgb.rb} +0 -0
  267. /data/lib/onyxcord/{id_object.rb → utils/id_object.rb} +0 -0
  268. /data/lib/onyxcord/{message_components.rb → utils/message_components.rb} +0 -0
  269. /data/lib/onyxcord/{paginator.rb → utils/paginator.rb} +0 -0
  270. /data/lib/onyxcord/{permissions.rb → utils/permissions.rb} +0 -0
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'onyxcord/message_components'
3
+ require 'onyxcord/utils/message_components'
4
4
 
5
5
  # A reusable view representing a component collection, with builder methods.
6
6
  class OnyxCord::Webhooks::View
@@ -48,431 +48,15 @@ class OnyxCord::Webhooks::View
48
48
  IS_COMPONENTS_V2 = OnyxCord::MessageComponents::IS_COMPONENTS_V2
49
49
  V2_COMPONENT_TYPES = OnyxCord::MessageComponents::V2_COMPONENT_TYPES
50
50
 
51
- # This builder is used when constructing an ActionRow. Button and select menu components must be within an action row, but this can
52
- # change in the future. A message can have 10 action rows, each action row can hold a weight of 5. Buttons have a weight of 1,
53
- # and dropdowns have a weight of 5.
54
- class RowBuilder
55
- # @!visibility private
56
- def initialize(id: nil)
57
- @id = id
58
- @components = []
51
+ require 'onyxcord/webhooks/view/row_builder'
52
+ require 'onyxcord/webhooks/view/select_menu_builder'
53
+ require 'onyxcord/webhooks/view/text_display_builder'
54
+ require 'onyxcord/webhooks/view/separator_builder'
55
+ require 'onyxcord/webhooks/view/file_builder'
56
+ require 'onyxcord/webhooks/view/media_gallery_builder'
57
+ require 'onyxcord/webhooks/view/section_builder'
58
+ require 'onyxcord/webhooks/view/container_builder'
59
59
 
60
- yield self if block_given?
61
- end
62
-
63
- # Add a button to this action row.
64
- # @param style [Symbol, Integer] The button's style type. See {BUTTON_STYLES}
65
- # @param id [Integer, nil] The unique 32-bit ID of the button component. This is not to be confused with the `custom_id`.
66
- # @param label [String, nil] The text label for the button. Either a label or emoji must be provided.
67
- # @param emoji [#to_h, String, Integer] An emoji ID, or unicode emoji to attach to the button. Can also be an object
68
- # that responds to `#to_h` which returns a hash in the format of `{ id: Integer, name: string }`.
69
- # @param custom_id [String] Custom IDs are used to pass state to the events that are raised from interactions.
70
- # There is a limit of 100 characters to each custom_id.
71
- # @param disabled [true, false] Whether this button is disabled and shown as greyed out.
72
- # @param url [String, nil] The URL, when using a link style button.
73
- def button(style:, id: nil, label: nil, emoji: nil, custom_id: nil, disabled: nil, url: nil, sku_id: nil)
74
- style = BUTTON_STYLES[style] || style
75
-
76
- emoji = case emoji
77
- when Integer, String
78
- emoji.to_i.positive? ? { id: emoji } : { name: emoji }
79
- else
80
- emoji&.to_h
81
- end
82
-
83
- @components << { type: COMPONENT_TYPES[:button], id: id, label: label, emoji: emoji, style: style, custom_id: custom_id, disabled: disabled, url: url, sku_id: sku_id }.compact
84
- end
85
-
86
- # Add a string select to this action row.
87
- # @param custom_id [String] Custom IDs are used to pass state to the events that are raised from interactions.
88
- # There is a limit of 100 characters to each custom_id.
89
- # @param id [Integer, nil] The unique 32-bit ID of the string select. This is not to be confused with the `custom_id`.
90
- # @param options [Array<Hash>] Options that can be selected in this menu. Can also be provided via the yielded builder.
91
- # @param placeholder [String, nil] Default text to show when no entries are selected.
92
- # @param min_values [Integer, nil] The minimum amount of values a user must select.
93
- # @param max_values [Integer, nil] The maximum amount of values a user can select.
94
- # @param disabled [true, false, nil] Grey out the component to make it unusable.
95
- # @yieldparam builder [SelectMenuBuilder]
96
- def string_select(custom_id:, options: [], id: nil, placeholder: nil, min_values: nil, max_values: nil, disabled: nil)
97
- builder = SelectMenuBuilder.new(custom_id, options, placeholder, min_values, max_values, disabled, select_type: :string_select, id: id)
98
-
99
- yield builder if block_given?
100
-
101
- @components << builder.to_h
102
- end
103
-
104
- alias_method :select_menu, :string_select
105
-
106
- # Add a user select to this action row.
107
- # @param custom_id [String] Custom IDs are used to pass state to the events that are raised from interactions.
108
- # There is a limit of 100 characters to each custom_id.
109
- # @param id [Integer, nil] The unique 32-bit ID of the user select. This is not to be confused with the `custom_id`.
110
- # @param placeholder [String, nil] Default text to show when no entries are selected.
111
- # @param min_values [Integer, nil] The minimum amount of values a user must select.
112
- # @param max_values [Integer, nil] The maximum amount of values a user can select.
113
- # @param disabled [true, false, nil] Grey out the component to make it unusable.
114
- # @param default_values [Array<User, Member, Recipient, Integer, String, Hash>, nil] The users to populate in the select menu by default.
115
- def user_select(custom_id:, id: nil, placeholder: nil, min_values: nil, max_values: nil, disabled: nil, default_values: nil)
116
- @components << SelectMenuBuilder.new(custom_id, [], placeholder, min_values, max_values, disabled, select_type: :user_select, id: id, default_values: default_values).to_h
117
- end
118
-
119
- # Add a role select to this action row.
120
- # @param custom_id [String] Custom IDs are used to pass state to the events that are raised from interactions.
121
- # There is a limit of 100 characters to each custom_id.
122
- # @param id [Integer, nil] The unique 32-bit ID of the role select. This is not to be confused with the `custom_id`.
123
- # @param placeholder [String, nil] Default text to show when no entries are selected.
124
- # @param min_values [Integer, nil] The minimum amount of values a user must select.
125
- # @param max_values [Integer, nil] The maximum amount of values a user can select.
126
- # @param disabled [true, false, nil] Grey out the component to make it unusable.
127
- # @param default_values [Array<Role, Integer, String, Hash>, nil] The roles to populate in the select menu by default.
128
- def role_select(custom_id:, id: nil, placeholder: nil, min_values: nil, max_values: nil, disabled: nil, default_values: nil)
129
- @components << SelectMenuBuilder.new(custom_id, [], placeholder, min_values, max_values, disabled, select_type: :role_select, id: id, default_values: default_values).to_h
130
- end
131
-
132
- # Add a mentionable select to this action row.
133
- # @param custom_id [String] Custom IDs are used to pass state to the events that are raised from interactions.
134
- # There is a limit of 100 characters to each custom_id.
135
- # @param id [Integer, nil] The unique 32-bit ID of the mentionable select. This is not to be confused with the `custom_id`.
136
- # @param placeholder [String, nil] Default text to show when no entries are selected.
137
- # @param min_values [Integer, nil] The minimum amount of values a user must select.
138
- # @param max_values [Integer, nil] The maximum amount of values a user can select.
139
- # @param disabled [true, false, nil] Grey out the component to make it unusable.
140
- # @param default_values [Array<User, Role, Member, Recipient, Hash>, nil] The mentionable entities to populate in the select menu by default.
141
- def mentionable_select(custom_id:, id: nil, placeholder: nil, min_values: nil, max_values: nil, disabled: nil, default_values: nil)
142
- @components << SelectMenuBuilder.new(custom_id, [], placeholder, min_values, max_values, disabled, select_type: :mentionable_select, id: id, default_values: default_values).to_h
143
- end
144
-
145
- # Add a channel select to this action row.
146
- # @param custom_id [String] Custom IDs are used to pass state to the events that are raised from interactions.
147
- # There is a limit of 100 characters to each custom_id.
148
- # @param id [Integer, nil] The unique 32-bit ID of the channel select. This is not to be confused with the `custom_id`.
149
- # @param placeholder [String, nil] Default text to show when no entries are selected.
150
- # @param min_values [Integer, nil] The minimum amount of values a user must select.
151
- # @param max_values [Integer, nil] The maximum amount of values a user can select.
152
- # @param disabled [true, false, nil] Grey out the component to make it unusable.
153
- # @param types [Array<Symbol, Integer>, nil] The channel types to include in the select menu.
154
- # @param default_values [Array<Channel, Integer, String, Hash>, nil] The channels to populate in the select menu by default.
155
- def channel_select(custom_id:, id: nil, placeholder: nil, min_values: nil, max_values: nil, disabled: nil, types: nil, default_values: nil)
156
- builder = SelectMenuBuilder.new(custom_id, [], placeholder, min_values, max_values, disabled, select_type: :channel_select, id: id, default_values: default_values).to_h
157
-
158
- builder[:channel_types] = types.map { |type| OnyxCord::Channel::TYPES[type] || type } if types
159
-
160
- @components << builder
161
- end
162
-
163
- # @!visibility private
164
- def to_h
165
- { type: COMPONENT_TYPES[:action_row], id: @id, components: @components }.compact
166
- end
167
- end
168
-
169
- # A builder to assist in adding options to select menus.
170
- class SelectMenuBuilder
171
- # @!visibility private
172
- def initialize(custom_id, options = [], placeholder = nil, min_values = nil, max_values = nil, disabled = nil, select_type: :string_select, id: nil, required: nil, default_values: nil)
173
- @id = id
174
- @custom_id = custom_id
175
- @options = options
176
- @placeholder = placeholder
177
- @min_values = min_values
178
- @max_values = max_values
179
- @disabled = disabled
180
- @select_type = select_type
181
- @required = required
182
- @default_values = process_defaults(default_values)
183
- end
184
-
185
- # Add an option to this select menu.
186
- # @param label [String] The title of this option.
187
- # @param value [String] The value that this option represents.
188
- # @param description [String, nil] An optional description of the option.
189
- # @param emoji [#to_h, String, Integer] An emoji ID, or unicode emoji to attach to the button. Can also be an object
190
- # that responds to `#to_h` which returns a hash in the format of `{ id: Integer, name: string }`.
191
- # @param default [true, false, nil] Whether this is the default selected option.
192
- def option(label:, value:, description: nil, emoji: nil, default: nil)
193
- emoji = case emoji
194
- when Integer, String
195
- emoji.to_i.positive? ? { id: emoji } : { name: emoji }
196
- else
197
- emoji&.to_h
198
- end
199
-
200
- @options << { label: label, value: value, description: description, emoji: emoji, default: default }
201
- end
202
-
203
- # @!visibility private
204
- def to_h
205
- {
206
- type: COMPONENT_TYPES[@select_type],
207
- id: @id,
208
- options: @options,
209
- placeholder: @placeholder,
210
- min_values: @min_values,
211
- max_values: @max_values,
212
- custom_id: @custom_id,
213
- disabled: @disabled,
214
- required: @required,
215
- default_values: @default_values
216
- }.compact
217
- end
218
-
219
- private
220
-
221
- # @!visibility private
222
- def process_defaults(default_values)
223
- if @select_type == :mentionable_select
224
- default_values&.map do |default_value|
225
- case default_value
226
- when OnyxCord::Recipient, OnyxCord::User, OnyxCord::Member
227
- { id: default_value.id, type: :user }
228
- when OnyxCord::Role
229
- { id: default_value.id, type: :role }
230
- when Hash
231
- default_value
232
- else
233
- raise TypeError, "Unsupported type: #{default_value.class}"
234
- end
235
- end
236
- else
237
- default_values&.map { |id| id.is_a?(Hash) ? id : { id: id.resolve_id, type: @select_type[..-8] } }
238
- end
239
- end
240
- end
241
-
242
- # A text display component allows you to send message content.
243
- class TextDisplayBuilder
244
- # Create a text display component.
245
- # @param content [String] The content of the text display component.
246
- # @param id [Integer, nil] The unique 32-bit ID of the text display component.
247
- def initialize(content:, id: nil)
248
- @id = id
249
- @content = content
250
- end
251
-
252
- # @!visibility private
253
- def to_h
254
- { type: COMPONENT_TYPES[:text_display], id: @id, content: @content }.compact
255
- end
256
- end
257
-
258
- # A separator allows you to add a barrier between components.
259
- class SeparatorBuilder
260
- # Create a separator component.
261
- # @param divider [true, false] Whether or not the separator should act as a visible barrier.
262
- # @param id [Integer, nil] The unique 32-bit ID of the separator component.
263
- # @param spacing [Symbol, Integer] The size of the separator component's padding. See {SEPARATOR_SIZES}.
264
- def initialize(divider:, id: nil, spacing: nil)
265
- @id = id
266
- @divider = divider
267
- @spacing = SEPARATOR_SIZES[spacing] || spacing
268
- end
269
-
270
- # @!visibility private
271
- def to_h
272
- { type: COMPONENT_TYPES[:separator], id: @id, divider: @divider, spacing: @spacing }.compact
273
- end
274
- end
275
-
276
- # A file component lets you send a file via an attachment://<filename> reference.
277
- class FileBuilder
278
- # Create a file component.
279
- # @param url [String] An `attachment://<filename>` reference to the attached file.
280
- # @param id [Integer, nil] The unique 32-bit ID of the file component.
281
- # @param spoiler [true, false] Whether or not to apply a spoiler label to the file.
282
- def initialize(url = nil, id: nil, spoiler: false, **kwargs)
283
- url = kwargs.fetch(:url, url)
284
-
285
- @id = id
286
- @file = { url: }
287
- @spoiler = spoiler
288
- end
289
-
290
- # @!visibility private
291
- def to_h
292
- { type: COMPONENT_TYPES[:file], id: @id, spoiler: @spoiler, file: @file }.compact
293
- end
294
- end
295
-
296
- # A media gallery component is a gallery grid.
297
- class MediaGalleryBuilder
298
- # Create a media gallery component.
299
- # @param id [Integer, nil] The unique 32-bit ID of the media gallery component.
300
- # @yieldparam builder [MediaGalleryBuilder] Yields the initialized media gallery component.
301
- def initialize(*items, id: nil)
302
- @id = id
303
- @items = []
304
-
305
- items.each { |item| self.item(item) }
306
-
307
- yield self if block_given?
308
- end
309
-
310
- # Add a gallery item to the media gallery component.
311
- # @param url [String] The URL to the gallery item's media.
312
- # @param description [String, nil] The description of the gallery item.
313
- # @param spoiler [true, false] Whether or not to apply a spoiler label to the gallery item.
314
- def item(item = nil, url: nil, description: nil, spoiler: nil)
315
- url, description, spoiler = normalize_item(item, url, description, spoiler)
316
- raise ArgumentError, 'media gallery item requires a url' if url.nil? || url.to_s.empty?
317
-
318
- @items << { media: { url: url }, description: description, spoiler: spoiler }.compact
319
- end
320
-
321
- # @!visibility private
322
- def to_h
323
- { type: COMPONENT_TYPES[:media_gallery], id: @id, items: @items }.compact
324
- end
325
-
326
- private
327
-
328
- def normalize_item(item, url, description, spoiler)
329
- if item.is_a?(Hash)
330
- media = item[:media] || item['media'] || {}
331
- url ||= item[:url] || item['url'] || media[:url] || media['url']
332
- description = item[:description] || item['description'] if description.nil?
333
- spoiler = item[:spoiler] || item['spoiler'] if spoiler.nil?
334
- else
335
- url ||= item
336
- end
337
-
338
- [url, description, spoiler.nil? ? false : spoiler]
339
- end
340
- end
341
-
342
- # A section allows you to group together an accessory with text display components.
343
- class SectionBuilder
344
- # Create a section component.
345
- # @param id [Integer, nil] The unique 32-bit ID of the section component.
346
- # @yieldparam builder [SectionBuilder] Yields the initialized section component.
347
- def initialize(id: nil)
348
- @id = id
349
- @accessory = nil
350
- @components = []
351
-
352
- yield self if block_given?
353
- end
354
-
355
- # Add a text display component to this section.
356
- # @see TextDisplayBuilder#initialize
357
- def text_display(...)
358
- @components << TextDisplayBuilder.new(...)
359
- end
360
-
361
- # Set the thumbnail for the section. This is mutually exclusive with {#button}.
362
- # @param url [String] The URL to the thumbnail image.
363
- # @param id [Integer, nil] The unique 32-bit ID of the thumbnail component.
364
- # @param description [String, nil] The description of the thumbnail.
365
- # @param spoiler [true, false] Whether or not to apply a spoiler label to the thumbnail.
366
- def thumbnail(url:, id: nil, description: nil, spoiler: false)
367
- @accessory = { type: COMPONENT_TYPES[:thumbnail], id: id, media: { url: }, description: description, spoiler: spoiler }.compact
368
- end
369
-
370
- # Set the button for the section. This is mutually exclusive with {#thumbnail}.
371
- # @param style [Symbol, Integer] The button's style type. See {BUTTON_STYLES}
372
- # @param id [Integer, nil] The unique 32-bit ID of the button component. This is not to be confused with the `custom_id`.
373
- # @param label [String, nil] The text label for the button. Either a label or emoji must be provided.
374
- # @param emoji [#to_h, String, Integer] An emoji ID, or unicode emoji to attach to the button. Can also be an object
375
- # that responds to `#to_h` which returns a hash in the format of `{ id: Integer, name: string }`.
376
- # @param custom_id [String] Custom IDs are used to pass state to the events that are raised from interactions.
377
- # There is a limit of 100 characters to each custom_id.
378
- # @param disabled [true, false] Whether this button is disabled and shown as greyed out.
379
- # @param url [String, nil] The URL, when using a link style button.
380
- def button(style:, id: nil, label: nil, emoji: nil, custom_id: nil, disabled: nil, url: nil, sku_id: nil)
381
- style = BUTTON_STYLES[style] || style
382
-
383
- emoji = case emoji
384
- when Integer, String
385
- emoji.to_i.positive? ? { id: emoji } : { name: emoji }
386
- else
387
- emoji&.to_h
388
- end
389
-
390
- @accessory = { type: COMPONENT_TYPES[:button], id: id, label: label, emoji: emoji, style: style, custom_id: custom_id, disabled: disabled, url: url, sku_id: sku_id }.compact
391
- end
392
-
393
- # @!visibility private
394
- def to_h
395
- { type: COMPONENT_TYPES[:section], id: @id, components: @components.map(&:to_h), accessory: @accessory }.compact
396
- end
397
- end
398
-
399
- # This builder can be used to construct a container. These are similar to embeds.
400
- class ContainerBuilder
401
- # Create a container component.
402
- # @param id [Integer, nil] The unique 32-bit ID of the container component.
403
- # @param colour [Array, Integer, String, ColourRGB, nil] The accent colour of the container
404
- # component. This argument can be passed via the American spelling (`color:`) as well.
405
- # @param spoiler [true, false] Whether or not to apply a spoiler label to the container component.
406
- # @yieldparam builder [ContainerBuilder] Yields the initialized container component.
407
- def initialize(id: nil, color: nil, colour: nil, spoiler: false)
408
- @id = id
409
- @spoiler = spoiler
410
- @components = []
411
- self.colour = (colour || color)
412
-
413
- yield self if block_given?
414
- end
415
-
416
- # Add a row component to the container.
417
- # @see RowBuilder#initialize
418
- def row(...)
419
- @components << RowBuilder.new(...)
420
- end
421
-
422
- # Add a file component to the container.
423
- # @see FileBuilder#initialize
424
- def file(...)
425
- @components << FileBuilder.new(...)
426
- end
427
-
428
- alias_method :file_display, :file
429
-
430
- # Add a section component to the container.
431
- # @see SectionBuilder#initialize
432
- def section(...)
433
- @components << SectionBuilder.new(...)
434
- end
435
-
436
- # Add a separator component to the container.
437
- # @see SeparatorBuilder#initialize
438
- def separator(...)
439
- @components << SeparatorBuilder.new(...)
440
- end
441
-
442
- # Add a text display component to the container.
443
- # @see TextDisplayBuilder#initialize
444
- def text_display(...)
445
- @components << TextDisplayBuilder.new(...)
446
- end
447
-
448
- # Add a media gallery component to the container.
449
- # @see MediaGalleryBuilder#initialize
450
- def media_gallery(*items, id: nil, &block)
451
- @components << MediaGalleryBuilder.new(*items, id: id, &block)
452
- end
453
-
454
- # Set the color of the container.
455
- # @param colour [Array, Integer, String, ColourRGB, nil] The accent colour of the container component, or `nil` to clear the accent colour.
456
- def colour=(colour)
457
- @colour = case colour
458
- when Array
459
- (colour[0] << 16) | (colour[1] << 8) | colour[2]
460
- when String
461
- colour.delete('#').to_i(16)
462
- else
463
- colour&.to_i
464
- end
465
- end
466
-
467
- alias_method :color=, :colour=
468
-
469
- # @!visibility private
470
- def to_h
471
- { type: COMPONENT_TYPES[:container], id: @id, accent_color: @colour, spoiler: @spoiler, components: @components.map(&:to_h) }.compact
472
- end
473
- end
474
-
475
- # @!visibility private
476
60
  def initialize
477
61
  @components = []
478
62
 
data/lib/onyxcord.rb CHANGED
@@ -2,18 +2,9 @@
2
2
 
3
3
  require 'base64'
4
4
  require 'mime/types'
5
- require 'onyxcord/json'
6
- require 'onyxcord/http'
7
- require 'onyxcord/version'
8
- require 'onyxcord/configuration'
9
- require 'onyxcord/event_executor'
10
- require 'onyxcord/message_components'
11
- require 'onyxcord/message_payload'
12
- require 'onyxcord/upload'
13
- require 'onyxcord/webhooks'
14
- require 'onyxcord/bot'
15
- require 'onyxcord/commands/command_bot'
16
- require 'onyxcord/logger'
5
+ require 'zeitwerk'
6
+ require_relative 'onyxcord/core/version'
7
+ require_relative 'onyxcord/core/logger'
17
8
 
18
9
  # All onyxcord functionality, to be extended by other files
19
10
  module OnyxCord
@@ -107,39 +98,36 @@ module OnyxCord
107
98
  # @param msg [String] The message to split.
108
99
  # @return [Array<String>] the message split into chunks
109
100
  def self.split_message(msg)
110
- # If the messages is empty, return an empty array
111
101
  return [] if msg.empty?
112
102
 
113
- # Split the message into lines
114
- lines = msg.lines
115
-
116
- # Turn the message into a "triangle" of consecutively longer slices, for example the array [1,2,3,4] would become
117
- # [
118
- # [1],
119
- # [1, 2],
120
- # [1, 2, 3],
121
- # [1, 2, 3, 4]
122
- # ]
123
- tri = (0...lines.length).map { |i| lines.combination(i + 1).first }
124
-
125
- # Join the individual elements together to get an array of strings with consecutively more lines
126
- joined = tri.map(&:join)
127
-
128
- # Find the largest element that is still below the character limit, or if none such element exists return the first
129
- ideal = joined.max_by { |e| e.length > CHARACTER_LIMIT ? -1 : e.length }
130
-
131
- # If it's still larger than the character limit (none was smaller than it) split it into the largest chunk without
132
- # cutting words apart, breaking on the nearest space within character limit, otherwise just return an array with one element
133
- ideal_ary = ideal.length > CHARACTER_LIMIT ? ideal.split(/(.{1,#{CHARACTER_LIMIT}}\b|.{1,#{CHARACTER_LIMIT}})/o).reject(&:empty?) : [ideal]
134
-
135
- # Slice off the ideal part and strip newlines
136
- rest = msg[ideal.length..].strip
137
-
138
- # If none remains, return an empty array -> we're done
139
- return [] unless rest
103
+ chunks = []
104
+ current = +''
105
+
106
+ msg.lines.each do |line|
107
+ if line.length > CHARACTER_LIMIT
108
+ chunks << current unless current.empty?
109
+ current = +''
110
+ rest = line
111
+ until rest.empty?
112
+ break chunks << rest if rest.length <= CHARACTER_LIMIT
113
+
114
+ chunk = rest[0, CHARACTER_LIMIT]
115
+ split_at = chunk.rindex(' ')
116
+ split_at = split_at ? split_at + 1 : CHARACTER_LIMIT
117
+ chunks << rest[0, split_at]
118
+ rest = rest[split_at..]
119
+ end
120
+ elsif current.length + line.length <= CHARACTER_LIMIT
121
+ current << line
122
+ else
123
+ chunks << current
124
+ current = line.dup
125
+ end
126
+ end
140
127
 
141
- # Otherwise, call the method recursively to split the rest of the string and add it onto the ideal array
142
- ideal_ary + split_message(rest)
128
+ chunks << current unless current.empty?
129
+ chunks[-1] = chunks[-1].delete_suffix("\n") if chunks[-1]
130
+ chunks
143
131
  end
144
132
 
145
133
  # @param time [Time, Integer] The time to create the timestamp from, or a unix timestamp integer.
@@ -185,3 +173,79 @@ class String
185
173
  to_i
186
174
  end
187
175
  end
176
+
177
+ # Zeitwerk setup. Files with legacy public constants are ignored and loaded by
178
+ # their aggregators below; renaming every public class is a separate breaking cut.
179
+ loader = Zeitwerk::Loader.for_gem
180
+ loader.tag = 'onyxcord'
181
+ loader.push_dir("#{__dir__}/onyxcord", namespace: OnyxCord)
182
+
183
+ loader.ignore(
184
+ "#{__dir__}/onyxcord/core/version.rb",
185
+ "#{__dir__}/onyxcord/core/logger.rb",
186
+ "#{__dir__}/onyxcord/internal",
187
+ "#{__dir__}/onyxcord/utils",
188
+ "#{__dir__}/onyxcord/models.rb",
189
+ "#{__dir__}/onyxcord/models",
190
+ "#{__dir__}/onyxcord/events",
191
+ "#{__dir__}/onyxcord/rest",
192
+ "#{__dir__}/onyxcord/webhooks.rb",
193
+ "#{__dir__}/onyxcord/webhooks",
194
+ "#{__dir__}/onyxcord/voice",
195
+ "#{__dir__}/onyxcord/interactions/internal",
196
+ "#{__dir__}/onyxcord/application_commands.rb",
197
+ "#{__dir__}/onyxcord/application_commands",
198
+ "#{__dir__}/onyxcord/interactions",
199
+ "#{__dir__}/onyxcord/cache",
200
+ "#{__dir__}/onyxcord/gateway",
201
+ "#{__dir__}/onyxcord/container.rb",
202
+ "#{__dir__}/onyxcord/bot.rb",
203
+ "#{__dir__}/onyxcord/commands"
204
+ )
205
+
206
+ loader.setup
207
+
208
+ %w[
209
+ internal/json
210
+ internal/http
211
+ internal/async_runtime
212
+ internal/event_executor
213
+ internal/message_payload
214
+ internal/upload
215
+ internal/websocket
216
+ internal/gateway/opcodes
217
+ internal/gateway/session
218
+ internal/rate_limiter/rest
219
+ internal/rate_limiter/async_rest
220
+ internal/rate_limiter/gateway
221
+ core/errors
222
+ core/configuration
223
+ utils/id_object
224
+ utils/permissions
225
+ utils/allowed_mentions
226
+ utils/colour_rgb
227
+ utils/paginator
228
+ utils/message_components
229
+ rest/client
230
+ rest/routes/channel
231
+ rest/routes/server
232
+ rest/routes/invite
233
+ rest/routes/user
234
+ rest/routes/webhook
235
+ rest/routes/interaction
236
+ rest/routes/application
237
+ models
238
+ cache/manager
239
+ await
240
+ container
241
+ internal/event_bus
242
+ gateway/client
243
+ application_commands
244
+ interactions/registry
245
+ voice/client
246
+ webhooks
247
+ bot
248
+ commands/bot
249
+ ].each { |path| require_relative "onyxcord/#{path}" }
250
+
251
+ loader.eager_load if ENV['ONYXCORD_EAGER_LOAD']