djs-selfbot-v13 3.1.6 → 3.1.7

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 (148) hide show
  1. package/README.md +31 -16
  2. package/package.json +15 -8
  3. package/src/client/BaseClient.js +3 -2
  4. package/src/client/Client.js +539 -187
  5. package/src/client/actions/Action.js +13 -18
  6. package/src/client/actions/ActionsManager.js +1 -7
  7. package/src/client/actions/AutoModerationActionExecution.js +0 -1
  8. package/src/client/actions/AutoModerationRuleCreate.js +0 -1
  9. package/src/client/actions/AutoModerationRuleDelete.js +0 -1
  10. package/src/client/actions/AutoModerationRuleUpdate.js +0 -1
  11. package/src/client/actions/InteractionCreate.js +115 -0
  12. package/src/client/actions/MessageCreate.js +4 -0
  13. package/src/client/actions/PresenceUpdate.js +16 -17
  14. package/src/client/websocket/WebSocketManager.js +31 -11
  15. package/src/client/websocket/WebSocketShard.js +38 -39
  16. package/src/client/websocket/handlers/APPLICATION_COMMAND_AUTOCOMPLETE_RESPONSE.js +23 -0
  17. package/src/client/websocket/handlers/CALL_CREATE.js +3 -3
  18. package/src/client/websocket/handlers/CALL_DELETE.js +2 -2
  19. package/src/client/websocket/handlers/CALL_UPDATE.js +2 -2
  20. package/src/client/websocket/handlers/CHANNEL_RECIPIENT_ADD.js +13 -16
  21. package/src/client/websocket/handlers/CHANNEL_RECIPIENT_REMOVE.js +11 -11
  22. package/src/client/websocket/handlers/GUILD_APPLICATION_COMMANDS_UPDATE.js +11 -0
  23. package/src/client/websocket/handlers/GUILD_CREATE.js +0 -7
  24. package/src/client/websocket/handlers/GUILD_MEMBER_LIST_UPDATE.js +55 -0
  25. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUNDS_UPDATE.js +0 -0
  26. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_CREATE.js +0 -0
  27. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_DELETE.js +0 -0
  28. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.js +0 -0
  29. package/src/client/websocket/handlers/INTERACTION_CREATE.js +16 -0
  30. package/src/client/websocket/handlers/INTERACTION_FAILURE.js +18 -0
  31. package/src/client/websocket/handlers/INTERACTION_MODAL_CREATE.js +0 -1
  32. package/src/client/websocket/handlers/INTERACTION_SUCCESS.js +30 -0
  33. package/src/client/websocket/handlers/MESSAGE_ACK.js +16 -0
  34. package/src/client/websocket/handlers/READY.js +137 -47
  35. package/src/client/websocket/handlers/RELATIONSHIP_ADD.js +5 -7
  36. package/src/client/websocket/handlers/RELATIONSHIP_REMOVE.js +4 -6
  37. package/src/client/websocket/handlers/RELATIONSHIP_UPDATE.js +9 -32
  38. package/src/client/websocket/handlers/SOUNDBOARD_SOUNDS.js +0 -0
  39. package/src/client/websocket/handlers/USER_GUILD_SETTINGS_UPDATE.js +8 -2
  40. package/src/client/websocket/handlers/USER_NOTE_UPDATE.js +1 -1
  41. package/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js +5 -1
  42. package/src/client/websocket/handlers/VOICE_CHANNEL_EFFECT_SEND.js +0 -0
  43. package/src/client/websocket/handlers/index.js +20 -15
  44. package/src/errors/Messages.js +69 -24
  45. package/src/index.js +43 -12
  46. package/src/managers/ApplicationCommandManager.js +12 -9
  47. package/src/managers/ApplicationCommandPermissionsManager.js +11 -3
  48. package/src/managers/ChannelManager.js +4 -2
  49. package/src/managers/ClientUserSettingManager.js +279 -161
  50. package/src/managers/DeveloperPortalManager.js +104 -0
  51. package/src/managers/GuildApplicationCommandManager.js +28 -0
  52. package/src/managers/GuildBanManager.js +1 -1
  53. package/src/managers/GuildChannelManager.js +0 -2
  54. package/src/managers/GuildFolderManager.js +24 -0
  55. package/src/managers/GuildForumThreadManager.js +28 -22
  56. package/src/managers/GuildMemberManager.js +216 -40
  57. package/src/managers/GuildSettingManager.js +15 -22
  58. package/src/managers/MessageManager.js +44 -42
  59. package/src/managers/PermissionOverwriteManager.js +1 -1
  60. package/src/managers/ReactionUserManager.js +5 -5
  61. package/src/managers/RelationshipManager.js +74 -81
  62. package/src/managers/SessionManager.js +57 -0
  63. package/src/managers/ThreadManager.js +45 -12
  64. package/src/managers/ThreadMemberManager.js +1 -1
  65. package/src/managers/UserManager.js +10 -6
  66. package/src/rest/APIRequest.js +20 -42
  67. package/src/rest/CaptchaSolver.js +132 -0
  68. package/src/rest/DiscordAPIError.js +16 -17
  69. package/src/rest/RESTManager.js +21 -1
  70. package/src/rest/RequestHandler.js +21 -35
  71. package/src/structures/ApplicationCommand.js +456 -19
  72. package/src/structures/ApplicationRoleConnectionMetadata.js +0 -3
  73. package/src/structures/AutoModerationRule.js +5 -5
  74. package/src/structures/AutocompleteInteraction.js +0 -1
  75. package/src/structures/BaseGuildTextChannel.js +12 -10
  76. package/src/structures/BaseGuildVoiceChannel.js +18 -16
  77. package/src/structures/{CallState.js → Call.js} +12 -17
  78. package/src/structures/CategoryChannel.js +0 -2
  79. package/src/structures/Channel.js +3 -2
  80. package/src/structures/ClientApplication.js +204 -0
  81. package/src/structures/ClientPresence.js +8 -12
  82. package/src/structures/ClientUser.js +336 -117
  83. package/src/structures/ContextMenuInteraction.js +1 -1
  84. package/src/structures/DMChannel.js +92 -29
  85. package/src/structures/DeveloperPortalApplication.js +520 -0
  86. package/src/structures/ForumChannel.js +10 -0
  87. package/src/structures/Guild.js +271 -135
  88. package/src/structures/GuildAuditLogs.js +5 -0
  89. package/src/structures/GuildChannel.js +2 -16
  90. package/src/structures/GuildFolder.js +75 -0
  91. package/src/structures/GuildMember.js +145 -27
  92. package/src/structures/Interaction.js +62 -1
  93. package/src/structures/InteractionResponse.js +114 -0
  94. package/src/structures/Invite.js +52 -35
  95. package/src/structures/Message.js +202 -222
  96. package/src/structures/MessageAttachment.js +0 -11
  97. package/src/structures/MessageButton.js +67 -1
  98. package/src/structures/MessageEmbed.js +1 -1
  99. package/src/structures/MessageMentions.js +2 -3
  100. package/src/structures/MessagePayload.js +46 -4
  101. package/src/structures/MessageReaction.js +1 -1
  102. package/src/structures/MessageSelectMenu.js +252 -1
  103. package/src/structures/Modal.js +180 -75
  104. package/src/structures/PartialGroupDMChannel.js +433 -0
  105. package/src/structures/Presence.js +2 -2
  106. package/src/structures/RichPresence.js +34 -14
  107. package/src/structures/Role.js +2 -18
  108. package/src/structures/SelectMenuInteraction.js +151 -2
  109. package/src/structures/Session.js +81 -0
  110. package/src/structures/Team.js +49 -0
  111. package/src/structures/TextInputComponent.js +70 -0
  112. package/src/structures/ThreadChannel.js +19 -0
  113. package/src/structures/User.js +345 -117
  114. package/src/structures/UserContextMenuInteraction.js +2 -2
  115. package/src/structures/VoiceState.js +39 -74
  116. package/src/structures/WebEmbed.js +52 -38
  117. package/src/structures/Webhook.js +11 -17
  118. package/src/structures/interfaces/Application.js +23 -146
  119. package/src/structures/interfaces/TextBasedChannel.js +256 -411
  120. package/src/util/ApplicationFlags.js +1 -1
  121. package/src/util/Constants.js +284 -106
  122. package/src/util/Formatters.js +2 -16
  123. package/src/util/LimitedCollection.js +1 -1
  124. package/src/util/Options.js +68 -48
  125. package/src/util/Permissions.js +0 -5
  126. package/src/util/PurchasedFlags.js +0 -2
  127. package/src/util/RemoteAuth.js +356 -221
  128. package/src/util/Sweepers.js +1 -1
  129. package/src/util/Util.js +36 -76
  130. package/src/util/Voice.js +1456 -0
  131. package/src/util/arRPC/index.js +229 -0
  132. package/src/util/arRPC/process/detectable.json +1 -0
  133. package/src/util/arRPC/process/index.js +102 -0
  134. package/src/util/arRPC/process/native/index.js +5 -0
  135. package/src/util/arRPC/process/native/linux.js +37 -0
  136. package/src/util/arRPC/process/native/win32.js +25 -0
  137. package/src/util/arRPC/transports/ipc.js +281 -0
  138. package/src/util/arRPC/transports/websocket.js +128 -0
  139. package/typings/enums.d.ts +73 -18
  140. package/typings/index.d.ts +1249 -897
  141. package/typings/rawDataTypes.d.ts +9 -68
  142. package/src/client/websocket/handlers/USER_REQUIRED_ACTION_UPDATE.js +0 -78
  143. package/src/client/websocket/handlers/VOICE_CHANNEL_STATUS_UPDATE.js +0 -12
  144. package/src/managers/UserNoteManager.js +0 -53
  145. package/src/structures/GroupDMChannel.js +0 -387
  146. package/src/util/AttachmentFlags.js +0 -38
  147. package/src/util/InviteFlags.js +0 -29
  148. package/src/util/RoleFlags.js +0 -37
@@ -2,19 +2,109 @@
2
2
 
3
3
  const { Collection } = require('@discordjs/collection');
4
4
  const BaseManager = require('./BaseManager');
5
- const { TypeError } = require('../errors/DJSError');
5
+ const GuildFolderManager = require('./GuildFolderManager');
6
+ const { Error, TypeError } = require('../errors/DJSError');
7
+ const GuildFolder = require('../structures/GuildFolder');
6
8
  const { CustomStatus } = require('../structures/RichPresence');
7
- const { ActivityTypes } = require('../util/Constants');
8
-
9
+ const { localeSetting, DMScanLevel, stickerAnimationMode } = require('../util/Constants');
9
10
  /**
10
11
  * Manages API methods for users and stores their cache.
11
12
  * @extends {BaseManager}
12
13
  * @see {@link https://luna.gitlab.io/discord-unofficial-docs/user_settings.html}
13
14
  */
14
15
  class ClientUserSettingManager extends BaseManager {
15
- #rawSetting = {};
16
16
  constructor(client) {
17
17
  super(client);
18
+ /**
19
+ * Raw data
20
+ * @type {Object}
21
+ */
22
+ this.rawSetting = {};
23
+ /**
24
+ * Language
25
+ * @type {?string}
26
+ */
27
+ this.locale = null;
28
+ /**
29
+ * From: Setting => ACTIVITY SETTINGS => Activity Status => Display current activity as a status message
30
+ * @type {?boolean}
31
+ */
32
+ this.activityDisplay = null;
33
+ /**
34
+ * Disable Direct Message from servers
35
+ * @type {Collection<Snowflake, boolean>}
36
+ */
37
+ this.disableDMfromServer = new Collection();
38
+ /**
39
+ * Allow direct messages from server members
40
+ * @type {?boolean}
41
+ */
42
+ this.DMfromServerMode = null;
43
+ /**
44
+ * Display images
45
+ * @type {?boolean}
46
+ */
47
+ this.displayImage = null;
48
+ /**
49
+ * Display linked images
50
+ * @type {?boolean}
51
+ */
52
+ this.linkedImageDisplay = null;
53
+ /**
54
+ * From: Setting => APP SETTINGS => Accessibility => Automatically play GIFs when Discord is focused.
55
+ * @type {?boolean}
56
+ */
57
+ this.autoplayGIF = null;
58
+ /**
59
+ * Show embeds and preview website links pasted into chat
60
+ * @type {?boolean}
61
+ */
62
+ this.previewLink = null;
63
+ /**
64
+ * From: Setting => APP SETTINGS => Accessibility => Play Animated Emojis
65
+ * @type {?boolean}
66
+ */
67
+ this.animatedEmojis = null;
68
+ /**
69
+ * From: Setting => APP SETTINGS => Accessibility => Text-to-speech => Allow playback
70
+ * @type {?boolean}
71
+ */
72
+ this.allowTTS = null;
73
+ /**
74
+ * From: Setting => APP SETTINGS => Appearance => Message Display => Compact Mode
75
+ * @type {?boolean}
76
+ */
77
+ this.compactMode = null;
78
+ /**
79
+ * From: Setting => APP SETTINGS => Text & Images => Emoji => Convert Emoticons
80
+ * @type {?boolean}
81
+ */
82
+ this.convertEmoticons = null;
83
+ /**
84
+ * SAFE DIRECT MESSAGING
85
+ * @type {?DMScanLevel}
86
+ */
87
+ this.DMScanLevel = null;
88
+ /**
89
+ * From: Setting => APP SETTINGS => Appearance => Theme
90
+ * @type {'dark' | 'light' | null}
91
+ */
92
+ this.theme = '';
93
+ /**
94
+ * Developer Mode (Copy ID, etc.)
95
+ * @type {?boolean}
96
+ */
97
+ this.developerMode = null;
98
+ /**
99
+ * AFK timeout (receives notifications)
100
+ * @type {?number}
101
+ */
102
+ this.afkTimeout = null;
103
+ /**
104
+ * Sticker animation mode
105
+ * @type {?stickerAnimationMode}
106
+ */
107
+ this.stickerAnimationMode = null;
18
108
  /**
19
109
  * WHO CAN ADD YOU AS A FRIEND ?
20
110
  * @type {?object}
@@ -25,240 +115,153 @@ class ClientUserSettingManager extends BaseManager {
25
115
  mutual_friends: null,
26
116
  mutual_guilds: null,
27
117
  };
118
+ /**
119
+ * From: Setting => APP SETTINGS => Text & Images => Emoji => Show emoji reactions
120
+ * @type {?boolean}
121
+ */
122
+ this.showEmojiReactions = null;
123
+ /**
124
+ * Custom Stauts
125
+ * @type {?object}
126
+ * @see {@link https://luna.gitlab.io/discord-unofficial-docs/custom_status.html#customstatus-structure}
127
+ */
128
+ this.customStatus = null;
129
+ /**
130
+ * Guild folder and position
131
+ * @type {GuildFolderManager}
132
+ */
133
+ this.guildFolder = new GuildFolderManager(client);
134
+ // Todo: add new method from Discum
28
135
  }
29
136
  /**
30
137
  * Patch data file
31
- * https://luna.gitlab.io/discord-unofficial-docs/docs/user_settings
138
+ * https://github.com/Merubokkusu/Discord-S.C.U.M/blob/master/discum/user/user.py
32
139
  * @private
33
140
  * @param {Object} data Raw Data to patch
34
141
  */
35
142
  _patch(data = {}) {
36
- this.#rawSetting = Object.assign(this.#rawSetting, data);
37
- this.client.emit('debug', `[SETTING > ClientUser] Sync setting`);
143
+ this.rawSetting = Object.assign(this.rawSetting, data);
38
144
  if ('locale' in data) {
39
- /**
40
- * The user's chosen language option
41
- * @type {?string}
42
- * @see {@link https://discord.com/developers/docs/reference#locales}
43
- */
44
- this.locale = data.locale;
145
+ this.locale = localeSetting[data.locale];
45
146
  }
46
147
  if ('show_current_game' in data) {
47
- /**
48
- * Show playing status for detected/added games
49
- * <info>Setting => ACTIVITY SETTINGS => Activity Status => Display current activity as a status message</info>
50
- * @type {?boolean}
51
- */
52
148
  this.activityDisplay = data.show_current_game;
53
149
  }
54
150
  if ('default_guilds_restricted' in data) {
55
- /**
56
- * Allow DMs from guild members by default on guild join
57
- * @type {?boolean}
58
- */
59
- this.allowDMsFromGuild = data.default_guilds_restricted;
151
+ this.DMfromServerMode = data.default_guilds_restricted;
60
152
  }
61
153
  if ('inline_attachment_media' in data) {
62
- /**
63
- * Display images and video when uploaded directly
64
- * @type {?boolean}
65
- */
66
154
  this.displayImage = data.inline_attachment_media;
67
155
  }
68
156
  if ('inline_embed_media' in data) {
69
- /**
70
- * Display images and video when linked
71
- * @type {?boolean}
72
- */
73
157
  this.linkedImageDisplay = data.inline_embed_media;
74
158
  }
75
159
  if ('gif_auto_play' in data) {
76
- /**
77
- * Play GIFs without hovering over them
78
- * <info>Setting => APP SETTINGS => Accessibility => Automatically play GIFs when Discord is focused.</info>
79
- * @type {?boolean}
80
- */
81
160
  this.autoplayGIF = data.gif_auto_play;
82
161
  }
83
162
  if ('render_embeds' in data) {
84
- /**
85
- * Show embeds and preview website links pasted into chat
86
- * @type {?boolean}
87
- */
88
163
  this.previewLink = data.render_embeds;
89
164
  }
90
165
  if ('animate_emoji' in data) {
91
- /**
92
- * Play animated emoji without hovering over them
93
- * <info>Setting => APP SETTINGS => Accessibility => Play Animated Emojis</info>
94
- * @type {?boolean}
95
- */
96
- this.animatedEmoji = data.animate_emoji;
166
+ this.animatedEmojis = data.animate_emoji;
97
167
  }
98
168
  if ('enable_tts_command' in data) {
99
- /**
100
- * Enable /tts command and playback
101
- * <info>Setting => APP SETTINGS => Accessibility => Text-to-speech => Allow playback</info>
102
- * @type {?boolean}
103
- */
104
169
  this.allowTTS = data.enable_tts_command;
105
170
  }
106
171
  if ('message_display_compact' in data) {
107
- /**
108
- * Use compact mode
109
- * <info>Setting => APP SETTINGS => Appearance => Message Display => Compact Mode</info>
110
- * @type {?boolean}
111
- */
112
172
  this.compactMode = data.message_display_compact;
113
173
  }
114
174
  if ('convert_emoticons' in data) {
115
- /**
116
- * Convert "old fashioned" emoticons to emojis
117
- * <info>Setting => APP SETTINGS => Text & Images => Emoji => Convert Emoticons</info>
118
- * @type {?boolean}
119
- */
120
175
  this.convertEmoticons = data.convert_emoticons;
121
176
  }
122
177
  if ('explicit_content_filter' in data) {
123
- /**
124
- * Content filter level
125
- * <info>
126
- * * `0`: Off
127
- * * `1`: Friends excluded
128
- * * `2`: Scan everyone
129
- * </info>
130
- * @type {?number}
131
- */
132
- this.DMScanLevel = data.explicit_content_filter;
178
+ this.DMScanLevel = DMScanLevel[data.explicit_content_filter];
133
179
  }
134
180
  if ('theme' in data) {
135
- /**
136
- * Client theme
137
- * <info>Setting => APP SETTINGS => Appearance => Theme
138
- * * `dark`
139
- * * `light`
140
- * </info>
141
- * @type {?string}
142
- */
143
181
  this.theme = data.theme;
144
182
  }
145
183
  if ('developer_mode' in data) {
146
- /**
147
- * Show the option to copy ids in right click menus
148
- * @type {?boolean}
149
- */
150
184
  this.developerMode = data.developer_mode;
151
185
  }
152
186
  if ('afk_timeout' in data) {
153
- /**
154
- * How many seconds being idle before the user is marked as "AFK"; this handles when push notifications are sent
155
- * @type {?number}
156
- */
157
- this.afkTimeout = data.afk_timeout;
187
+ this.afkTimeout = data.afk_timeout * 1000; // Second => milisecond
158
188
  }
159
189
  if ('animate_stickers' in data) {
160
- /**
161
- * When stickers animate
162
- * <info>
163
- * * `0`: Always
164
- * * `1`: On hover/focus
165
- * * `2`: Never
166
- * </info>
167
- * @type {?number}
168
- */
169
- this.stickerAnimationMode = data.animate_stickers;
190
+ this.stickerAnimationMode = stickerAnimationMode[data.animate_stickers];
170
191
  }
171
192
  if ('render_reactions' in data) {
172
- /**
173
- * Display reactions
174
- * <info>Setting => APP SETTINGS => Text & Images => Emoji => Show emoji reactions</info>
175
- * @type {?boolean}
176
- */
177
193
  this.showEmojiReactions = data.render_reactions;
178
194
  }
179
- if ('status' in data) {
180
- this.client.presence.status = data.status;
181
- if (!('custom_status' in data)) {
182
- this.client.emit('debug', '[SETTING > ClientUser] Sync status');
183
- this.client.user.setStatus(data.status);
184
- }
185
- }
186
195
  if ('custom_status' in data) {
187
- this.customStatus = data.custom_status;
188
- const activities = this.client.presence.activities.filter(
189
- a => ![ActivityTypes.CUSTOM, 'CUSTOM'].includes(a.type),
190
- );
191
- if (data.custom_status) {
192
- const custom = new CustomStatus();
193
- custom.setState(data.custom_status.text);
194
- let emoji;
195
- if (data.custom_status.emoji_id) {
196
- emoji = this.client.emojis.cache.get(data.custom_status.emoji_id);
197
- } else if (data.custom_status.emoji_name) {
198
- emoji = `:${data.custom_status.emoji_name}:`;
199
- }
200
- if (emoji) custom.setEmoji(emoji);
201
- activities.push(custom);
202
- }
203
- this.client.emit('debug', '[SETTING > ClientUser] Sync activities & status');
204
- this.client.user.setPresence({ activities });
196
+ this.customStatus = data.custom_status || {}; // Thanks PinkDuwc._#3443 reported this issue
197
+ this.customStatus.status = data.status;
205
198
  }
206
199
  if ('friend_source_flags' in data) {
207
- // Todo
200
+ this.addFriendFrom = {
201
+ all: data.friend_source_flags.all || false,
202
+ mutual_friends: data.friend_source_flags.all ? true : data.friend_source_flags.mutual_friends,
203
+ mutual_guilds: data.friend_source_flags.all ? true : data.friend_source_flags.mutual_guilds,
204
+ };
208
205
  }
209
- if ('restricted_guilds' in data) {
210
- /**
211
- * Disable Direct Message from servers
212
- * @type {Collection<Snowflake, Guild>}
213
- */
214
- this.disableDMfromGuilds = new Collection(
215
- data.restricted_guilds.map(guildId => [guildId, this.client.guilds.cache.get(guildId)]),
206
+ if ('guild_folders' in data) {
207
+ data.guild_folders.map((folder, index) =>
208
+ this.guildFolder.cache.set(index, new GuildFolder(this.client, folder)),
216
209
  );
217
210
  }
211
+ if ('restricted_guilds' in data) {
212
+ this.disableDMfromServer = new Collection(data.restricted_guilds.map(guildId => [guildId, true]));
213
+ }
218
214
  }
219
-
220
- /**
221
- * Raw data
222
- * @type {Object}
223
- */
224
- get raw() {
225
- return this.#rawSetting;
226
- }
227
-
228
215
  async fetch() {
216
+ if (this.client.bot) throw new Error('INVALID_BOT_METHOD');
229
217
  const data = await this.client.api.users('@me').settings.get();
230
218
  this._patch(data);
231
219
  return this;
232
220
  }
233
-
234
221
  /**
235
222
  * Edit data
236
- * @param {any} data Data to edit
223
+ * @param {Object} data Data to edit
224
+ * @private
237
225
  */
238
226
  async edit(data) {
227
+ if (this.client.bot) throw new Error('INVALID_BOT_METHOD');
239
228
  const res = await this.client.api.users('@me').settings.patch({ data });
240
229
  this._patch(res);
241
230
  return this;
242
231
  }
243
-
244
232
  /**
245
- * Toggle compact mode
246
- * @returns {Promise<this>}
233
+ * Set compact mode
234
+ * @param {boolean | null} value Compact mode enable or disable
235
+ * @returns {boolean}
247
236
  */
248
- toggleCompactMode() {
249
- return this.edit({ message_display_compact: !this.compactMode });
237
+ async setDisplayCompactMode(value) {
238
+ if (typeof value !== 'boolean' && value !== null) {
239
+ throw new TypeError('INVALID_TYPE', 'value', 'boolean | null', true);
240
+ }
241
+ if (!value) value = !this.compactMode;
242
+ if (value !== this.compactMode) {
243
+ await this.edit({ message_display_compact: value });
244
+ }
245
+ return this.compactMode;
250
246
  }
251
247
  /**
252
248
  * Discord Theme
253
- * @param {string} value Theme to set (dark | light)
254
- * @returns {Promise<this>}
249
+ * @param {null |dark |light} value Theme to set
250
+ * @returns {theme}
255
251
  */
256
- setTheme(value) {
252
+ async setTheme(value) {
257
253
  const validValues = ['dark', 'light'];
254
+ if (typeof value !== 'string' && value !== null) {
255
+ throw new TypeError('INVALID_TYPE', 'value', 'string | null', true);
256
+ }
258
257
  if (!validValues.includes(value)) {
259
- throw new TypeError('INVALID_TYPE', 'value', 'dark | light', true);
258
+ if (value == validValues[0]) value = validValues[1];
259
+ else value = validValues[0];
260
+ }
261
+ if (value !== this.theme) {
262
+ await this.edit({ theme: value });
260
263
  }
261
- return this.edit({ theme: value });
264
+ return this.theme;
262
265
  }
263
266
 
264
267
  /**
@@ -273,11 +276,10 @@ class ClientUserSettingManager extends BaseManager {
273
276
  /**
274
277
  * Set custom status
275
278
  * @param {?CustomStatus | CustomStatusOption} options CustomStatus
276
- * @returns {Promise<this>}
277
279
  */
278
280
  setCustomStatus(options) {
279
281
  if (typeof options !== 'object') {
280
- return this.edit({ custom_status: null });
282
+ this.edit({ custom_status: null });
281
283
  } else if (options instanceof CustomStatus) {
282
284
  options = options.toJSON();
283
285
  let data = {
@@ -296,7 +298,7 @@ class ClientUserSettingManager extends BaseManager {
296
298
  data.emoji_name = typeof options.emoji?.name === 'string' ? options.emoji?.name : null;
297
299
  }
298
300
  }
299
- return this.edit({ custom_status: data });
301
+ this.edit({ custom_status: data });
300
302
  } else {
301
303
  let data = {
302
304
  emoji_name: null,
@@ -325,8 +327,124 @@ class ClientUserSettingManager extends BaseManager {
325
327
  data.expires_at = new Date(options.expires).toISOString();
326
328
  }
327
329
  if (['online', 'idle', 'dnd', 'invisible'].includes(options.status)) this.edit({ status: options.status });
328
- return this.edit({ custom_status: data });
330
+ this.edit({ custom_status: data });
331
+ }
332
+ }
333
+
334
+ /**
335
+ * * Locale Setting, must be one of:
336
+ * * `DANISH`
337
+ * * `GERMAN`
338
+ * * `ENGLISH_UK`
339
+ * * `ENGLISH_US`
340
+ * * `SPANISH`
341
+ * * `FRENCH`
342
+ * * `CROATIAN`
343
+ * * `ITALIAN`
344
+ * * `LITHUANIAN`
345
+ * * `HUNGARIAN`
346
+ * * `DUTCH`
347
+ * * `NORWEGIAN`
348
+ * * `POLISH`
349
+ * * `BRAZILIAN_PORTUGUESE`
350
+ * * `ROMANIA_ROMANIAN`
351
+ * * `FINNISH`
352
+ * * `SWEDISH`
353
+ * * `VIETNAMESE`
354
+ * * `TURKISH`
355
+ * * `CZECH`
356
+ * * `GREEK`
357
+ * * `BULGARIAN`
358
+ * * `RUSSIAN`
359
+ * * `UKRAINIAN`
360
+ * * `HINDI`
361
+ * * `THAI`
362
+ * * `CHINA_CHINESE`
363
+ * * `JAPANESE`
364
+ * * `TAIWAN_CHINESE`
365
+ * * `KOREAN`
366
+ * @param {localeSetting} value Locale to set
367
+ * @returns {locale}
368
+ */
369
+ async setLocale(value) {
370
+ if (typeof value !== 'string') {
371
+ throw new TypeError('INVALID_TYPE', 'value', 'string', true);
372
+ }
373
+ if (!localeSetting[value]) throw new Error('INVALID_LOCALE');
374
+ if (localeSetting[value] !== this.locale) {
375
+ await this.edit({ locale: localeSetting[value] });
376
+ }
377
+ return this.locale;
378
+ }
379
+ // TODO: Guild positions & folders
380
+ // Change Index in Array [Hidden]
381
+ /**
382
+ *
383
+ * @param {Array} array Array
384
+ * @param {number} from Index1
385
+ * @param {number} to Index2
386
+ * @returns {Array}
387
+ * @private
388
+ */
389
+ _move(array, from, to) {
390
+ array.splice(to, 0, array.splice(from, 1)[0]);
391
+ return array;
392
+ }
393
+ // TODO: Move Guild
394
+ // folder to folder
395
+ // folder to home
396
+ // home to home
397
+ // home to folder
398
+ /**
399
+ * Change Guild Position (from * to Folder or Home)
400
+ * @param {GuildIDResolve} guildId guild.id
401
+ * @param {number} newPosition Guild Position
402
+ * * **WARNING**: Type = `FOLDER`, newPosition is the guild's index in the Folder.
403
+ * @param {number} type Move to folder or home
404
+ * * `FOLDER`: 1
405
+ * * `HOME`: 2
406
+ * @param {FolderID} folderId If you want to move to folder
407
+ * @private
408
+ */
409
+ guildChangePosition(guildId, newPosition, type, folderId) {
410
+ // Get Guild default position
411
+ // Escape
412
+ const oldGuildFolderPosition = this.rawSetting.guild_folders.findIndex(value => value.guild_ids.includes(guildId));
413
+ const newGuildFolderPosition = this.rawSetting.guild_folders.findIndex(value =>
414
+ value.guild_ids.includes(this.rawSetting.guild_positions[newPosition]),
415
+ );
416
+ if (type == 2 || `${type}`.toUpperCase() == 'HOME') {
417
+ // Delete GuildID from Folder and create new Folder
418
+ // Check it is folder
419
+ const folder = this.rawSetting.guild_folders[oldGuildFolderPosition];
420
+ if (folder.id) {
421
+ this.rawSetting.guild_folders[oldGuildFolderPosition].guild_ids = this.rawSetting.guild_folders[
422
+ oldGuildFolderPosition
423
+ ].guild_ids.filter(v => v !== guildId);
424
+ }
425
+ this.rawSetting.guild_folders = this._move(
426
+ this.rawSetting.guild_folders,
427
+ oldGuildFolderPosition,
428
+ newGuildFolderPosition,
429
+ );
430
+ this.rawSetting.guild_folders[newGuildFolderPosition].id = null;
431
+ } else if (type == 1 || `${type}`.toUpperCase() == 'FOLDER') {
432
+ // Delete GuildID from oldFolder
433
+ this.rawSetting.guild_folders[oldGuildFolderPosition].guild_ids = this.rawSetting.guild_folders[
434
+ oldGuildFolderPosition
435
+ ].guild_ids.filter(v => v !== guildId);
436
+ // Index new Folder
437
+ const folderIndex = this.rawSetting.guild_folders.findIndex(value => value.id == folderId);
438
+ const folder = this.rawSetting.guild_folders[folderIndex];
439
+ folder.guild_ids.push(guildId);
440
+ folder.guild_ids = [...new Set(folder.guild_ids)];
441
+ folder.guild_ids = this._move(
442
+ folder.guild_ids,
443
+ folder.guild_ids.findIndex(v => v == guildId),
444
+ newPosition,
445
+ );
329
446
  }
447
+ this.edit({ guild_folders: this.rawSetting.guild_folders });
330
448
  }
331
449
 
332
450
  /**
@@ -0,0 +1,104 @@
1
+ 'use strict';
2
+
3
+ const { Collection } = require('@discordjs/collection');
4
+ const BaseManager = require('./BaseManager');
5
+ const DeveloperPortalApplication = require('../structures/DeveloperPortalApplication');
6
+ const Team = require('../structures/Team');
7
+
8
+ /**
9
+ * Manages API methods for users and stores their cache.
10
+ * @extends {BaseManager}
11
+ */
12
+ class DeveloperPortalManager extends BaseManager {
13
+ constructor(client) {
14
+ super(client);
15
+ /**
16
+ * A collection of all the applications the client has.
17
+ * @type {Collection<Snowflake, DeveloperPortalApplication>}
18
+ * @readonly
19
+ */
20
+ this.applications = new Collection();
21
+ /**
22
+ * A collection of all the teams the client has.
23
+ * @type {Collection<Snowflake, Team>}
24
+ * @readonly
25
+ */
26
+ this.teams = new Collection(); // Collection<Snowflake, Team>
27
+ }
28
+ /**
29
+ * Fetches all the applications & teams the client has.
30
+ * @returns {Promise<DeveloperPortalManager>}
31
+ */
32
+ async fetch() {
33
+ const promise1 = this.client.api.applications.get({
34
+ query: {
35
+ with_team_applications: true,
36
+ },
37
+ });
38
+ const promise2 = this.client.api.teams.get();
39
+ const [applications, teams] = await Promise.all([promise1, promise2]);
40
+ for (const team of teams) {
41
+ this.teams.set(team.id, new Team(this.client, team));
42
+ }
43
+ for (const application of applications) {
44
+ this.applications.set(application.id, new DeveloperPortalApplication(this.client, application));
45
+ }
46
+ return this;
47
+ }
48
+
49
+ /**
50
+ * Creates a new Team.
51
+ * @param {string} name Name of the team
52
+ * @returns {Promise<Team>}
53
+ */
54
+ async createTeam(name) {
55
+ const team = await this.client.api.teams.post({
56
+ data: {
57
+ name: name,
58
+ },
59
+ });
60
+
61
+ this.teams.set(team.id, new Team(this.client, team));
62
+ return this.teams.get(team.id);
63
+ }
64
+
65
+ /**
66
+ * Creates a new application.
67
+ * @param {string} name Name of the application
68
+ * @param {?Snowflake | Team} teamId The team to create the application in
69
+ * @returns {Promise<DeveloperPortalApplication>}
70
+ */
71
+ async createApplication(name, teamId = null) {
72
+ teamId = teamId instanceof Team ? teamId.id : teamId;
73
+ const application = await this.client.api.applications.post({
74
+ data: {
75
+ name,
76
+ team_id: teamId,
77
+ },
78
+ });
79
+ this.applications.set(application.id, new DeveloperPortalApplication(this.client, application));
80
+ return this.applications.get(application.id);
81
+ }
82
+
83
+ /**
84
+ * Deletes an application.
85
+ * @param {Snowflake} id Application ID
86
+ * @param {?number} MFACode 2FA code (if 2FA is enabled)
87
+ * @returns {Promise<void>}
88
+ */
89
+ async deleteApplication(id, MFACode) {
90
+ if (MFACode) {
91
+ await this.client.api.applications[`${id}/delete`].post({
92
+ query: {
93
+ code: MFACode,
94
+ },
95
+ });
96
+ } else {
97
+ await this.client.api.applications[`${id}/delete`].post();
98
+ }
99
+ this.applications.delete(id);
100
+ return undefined;
101
+ }
102
+ }
103
+
104
+ module.exports = DeveloperPortalManager;
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ const ApplicationCommandManager = require('./ApplicationCommandManager');
4
+ const ApplicationCommandPermissionsManager = require('./ApplicationCommandPermissionsManager');
5
+
6
+ /**
7
+ * An extension for guild-specific application commands.
8
+ * @extends {ApplicationCommandManager}
9
+ */
10
+ class GuildApplicationCommandManager extends ApplicationCommandManager {
11
+ constructor(guild, iterable) {
12
+ super(guild.client, iterable);
13
+
14
+ /**
15
+ * The guild that this manager belongs to
16
+ * @type {Guild}
17
+ */
18
+ this.guild = guild;
19
+
20
+ /**
21
+ * The manager for permissions of arbitrary commands on this guild
22
+ * @type {ApplicationCommandPermissionsManager}
23
+ */
24
+ this.permissions = new ApplicationCommandPermissionsManager(this);
25
+ }
26
+ }
27
+
28
+ module.exports = GuildApplicationCommandManager;