seyfert 0.1.0 → 1.0.0

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 (193) hide show
  1. package/README.md +19 -30
  2. package/lib/api/CDN.d.ts +0 -8
  3. package/lib/api/CDN.js +7 -13
  4. package/lib/api/Router.d.ts +2 -2
  5. package/lib/api/Router.js +1 -1
  6. package/lib/api/Routes/applications.d.ts +1 -1
  7. package/lib/api/Routes/channels.d.ts +1 -1
  8. package/lib/api/Routes/gateway.d.ts +1 -1
  9. package/lib/api/Routes/guilds.d.ts +1 -1
  10. package/lib/api/Routes/interactions.d.ts +1 -1
  11. package/lib/api/Routes/invites.d.ts +1 -1
  12. package/lib/api/Routes/stage-instances.d.ts +1 -1
  13. package/lib/api/Routes/stickers.d.ts +1 -1
  14. package/lib/api/Routes/users.d.ts +1 -1
  15. package/lib/api/Routes/voice.d.ts +1 -1
  16. package/lib/api/Routes/webhooks.d.ts +1 -1
  17. package/lib/api/api.d.ts +39 -0
  18. package/lib/api/api.js +318 -0
  19. package/lib/api/bucket.d.ts +19 -0
  20. package/lib/api/bucket.js +71 -0
  21. package/lib/api/index.d.ts +1 -1
  22. package/lib/api/index.js +1 -1
  23. package/lib/api/shared.d.ts +31 -5
  24. package/lib/api/shared.js +2 -7
  25. package/lib/api/utils/constants.d.ts +1 -30
  26. package/lib/api/utils/constants.js +2 -41
  27. package/lib/api/utils/types.d.ts +1 -320
  28. package/lib/api/utils/utils.d.ts +0 -38
  29. package/lib/api/utils/utils.js +1 -139
  30. package/lib/builders/ActionRow.js +1 -1
  31. package/lib/builders/Attachment.d.ts +14 -6
  32. package/lib/builders/Attachment.js +30 -7
  33. package/lib/builders/Button.d.ts +3 -12
  34. package/lib/builders/Button.js +0 -11
  35. package/lib/builders/{MessageEmbed.d.ts → Embed.d.ts} +15 -15
  36. package/lib/builders/{MessageEmbed.js → Embed.js} +16 -16
  37. package/lib/builders/Modal.js +1 -1
  38. package/lib/builders/SelectMenu.d.ts +14 -15
  39. package/lib/builders/SelectMenu.js +19 -18
  40. package/lib/builders/index.d.ts +1 -1
  41. package/lib/builders/index.js +1 -1
  42. package/lib/builders/types.d.ts +2 -2
  43. package/lib/cache/adapters/default.js +2 -2
  44. package/lib/cache/adapters/redis.d.ts +2 -3
  45. package/lib/cache/adapters/redis.js +13 -5
  46. package/lib/cache/adapters/workeradapter.d.ts +9 -1
  47. package/lib/cache/adapters/workeradapter.js +7 -3
  48. package/lib/cache/index.d.ts +20 -6
  49. package/lib/cache/index.js +26 -10
  50. package/lib/cache/resources/channels.d.ts +6 -2
  51. package/lib/cache/resources/channels.js +12 -6
  52. package/lib/cache/resources/default/base.d.ts +17 -16
  53. package/lib/cache/resources/default/base.js +25 -24
  54. package/lib/cache/resources/default/guild-based.d.ts +22 -19
  55. package/lib/cache/resources/default/guild-based.js +32 -31
  56. package/lib/cache/resources/default/guild-related.d.ts +22 -19
  57. package/lib/cache/resources/default/guild-related.js +37 -43
  58. package/lib/cache/resources/emojis.d.ts +4 -2
  59. package/lib/cache/resources/emojis.js +8 -6
  60. package/lib/cache/resources/guilds.d.ts +4 -2
  61. package/lib/cache/resources/guilds.js +15 -8
  62. package/lib/cache/resources/members.d.ts +4 -2
  63. package/lib/cache/resources/members.js +16 -13
  64. package/lib/cache/resources/overwrites.d.ts +25 -0
  65. package/lib/cache/resources/overwrites.js +39 -0
  66. package/lib/cache/resources/presence.js +3 -4
  67. package/lib/cache/resources/roles.d.ts +4 -2
  68. package/lib/cache/resources/roles.js +8 -6
  69. package/lib/cache/resources/stickers.d.ts +4 -2
  70. package/lib/cache/resources/stickers.js +8 -6
  71. package/lib/cache/resources/threads.d.ts +4 -2
  72. package/lib/cache/resources/threads.js +8 -6
  73. package/lib/cache/resources/users.d.ts +4 -2
  74. package/lib/cache/resources/users.js +8 -6
  75. package/lib/cache/resources/voice-states.d.ts +3 -3
  76. package/lib/cache/resources/voice-states.js +6 -7
  77. package/lib/client/base.d.ts +49 -16
  78. package/lib/client/base.js +21 -17
  79. package/lib/client/client.d.ts +14 -3
  80. package/lib/client/client.js +21 -21
  81. package/lib/client/httpclient.d.ts +3 -5
  82. package/lib/client/httpclient.js +29 -16
  83. package/lib/client/{oninteraction.d.ts → oninteractioncreate.d.ts} +1 -1
  84. package/lib/client/{oninteraction.js → oninteractioncreate.js} +34 -23
  85. package/lib/client/onmessagecreate.d.ts +3 -0
  86. package/lib/client/onmessagecreate.js +337 -0
  87. package/lib/client/workerclient.d.ts +5 -1
  88. package/lib/client/workerclient.js +67 -44
  89. package/lib/collection.d.ts +1 -1
  90. package/lib/collection.js +9 -6
  91. package/lib/commands/applications/chat.d.ts +32 -25
  92. package/lib/commands/applications/chat.js +51 -34
  93. package/lib/commands/applications/chatcontext.d.ts +34 -16
  94. package/lib/commands/applications/chatcontext.js +99 -20
  95. package/lib/commands/applications/menu.d.ts +9 -8
  96. package/lib/commands/applications/menu.js +14 -5
  97. package/lib/commands/applications/menucontext.d.ts +27 -10
  98. package/lib/commands/applications/menucontext.js +51 -7
  99. package/lib/commands/applications/options.d.ts +13 -13
  100. package/lib/commands/applications/shared.d.ts +7 -2
  101. package/lib/commands/decorators.d.ts +14 -14
  102. package/lib/commands/decorators.js +9 -5
  103. package/lib/commands/handler.d.ts +2 -1
  104. package/lib/commands/handler.js +60 -14
  105. package/lib/commands/index.d.ts +1 -1
  106. package/lib/commands/index.js +2 -1
  107. package/lib/commands/optionresolver.d.ts +6 -5
  108. package/lib/commands/optionresolver.js +10 -6
  109. package/lib/common/bot/watcher.d.ts +3 -3
  110. package/lib/common/bot/watcher.js +3 -1
  111. package/lib/common/index.d.ts +1 -1
  112. package/lib/common/index.js +2 -1
  113. package/lib/common/it/logger.d.ts +11 -0
  114. package/lib/common/it/logger.js +51 -2
  115. package/lib/common/it/utils.d.ts +3 -13
  116. package/lib/common/it/utils.js +9 -30
  117. package/lib/common/shorters/channels.d.ts +55 -5
  118. package/lib/common/shorters/channels.js +59 -0
  119. package/lib/common/shorters/guilds.d.ts +5 -2
  120. package/lib/common/shorters/guilds.js +18 -0
  121. package/lib/common/shorters/messages.js +0 -2
  122. package/lib/common/shorters/overwrites.d.ts +29 -0
  123. package/lib/common/shorters/overwrites.js +63 -0
  124. package/lib/common/shorters/roles.js +3 -3
  125. package/lib/common/shorters/webhook.d.ts +2 -2
  126. package/lib/common/types/util.d.ts +2 -1
  127. package/lib/common/types/write.d.ts +3 -7
  128. package/lib/components/handler.d.ts +12 -18
  129. package/lib/components/handler.js +58 -103
  130. package/lib/components/index.d.ts +0 -1
  131. package/lib/components/index.js +0 -1
  132. package/lib/components/listener.d.ts +2 -2
  133. package/lib/components/listener.js +2 -3
  134. package/lib/events/event.d.ts +2 -2
  135. package/lib/events/handler.d.ts +3 -2
  136. package/lib/events/handler.js +14 -6
  137. package/lib/events/hooks/dispatch.d.ts +2 -1
  138. package/lib/events/hooks/dispatch.js +5 -1
  139. package/lib/events/hooks/thread.d.ts +63 -63
  140. package/lib/index.d.ts +8 -5
  141. package/lib/index.js +20 -10
  142. package/lib/langs/handler.d.ts +6 -4
  143. package/lib/langs/handler.js +10 -8
  144. package/lib/langs/router.d.ts +8 -9
  145. package/lib/langs/router.js +5 -5
  146. package/lib/structures/ClientUser.d.ts +1 -16
  147. package/lib/structures/ClientUser.js +0 -31
  148. package/lib/structures/Guild.d.ts +1 -1
  149. package/lib/structures/GuildMember.d.ts +12 -0
  150. package/lib/structures/GuildMember.js +14 -0
  151. package/lib/structures/GuildRole.d.ts +4 -2
  152. package/lib/structures/GuildRole.js +4 -1
  153. package/lib/structures/GuildTemplate.js +1 -1
  154. package/lib/structures/Interaction.d.ts +2 -0
  155. package/lib/structures/Interaction.js +12 -13
  156. package/lib/structures/Message.d.ts +7 -2
  157. package/lib/structures/Message.js +6 -3
  158. package/lib/structures/Sticker.d.ts +1 -1
  159. package/lib/structures/Sticker.js +1 -1
  160. package/lib/structures/User.d.ts +5 -0
  161. package/lib/structures/User.js +3 -0
  162. package/lib/structures/Webhook.d.ts +1 -1
  163. package/lib/structures/Webhook.js +1 -1
  164. package/lib/structures/channels.d.ts +45 -6
  165. package/lib/structures/channels.js +23 -7
  166. package/lib/structures/extra/BitField.d.ts +9 -6
  167. package/lib/structures/extra/BitField.js +27 -3
  168. package/lib/structures/extra/Permissions.d.ts +6 -1
  169. package/lib/structures/extra/Permissions.js +7 -0
  170. package/lib/websocket/discord/basesocket.js +0 -1
  171. package/lib/websocket/discord/workermanager.d.ts +9 -1
  172. package/lib/websocket/discord/workermanager.js +21 -13
  173. package/package.json +21 -20
  174. package/lib/api/REST.d.ts +0 -127
  175. package/lib/api/REST.js +0 -424
  176. package/lib/api/errors/DiscordAPIError.d.ts +0 -51
  177. package/lib/api/errors/DiscordAPIError.js +0 -81
  178. package/lib/api/errors/HTTPError.d.ts +0 -20
  179. package/lib/api/errors/HTTPError.js +0 -28
  180. package/lib/api/errors/RateLimitError.d.ts +0 -19
  181. package/lib/api/errors/RateLimitError.js +0 -37
  182. package/lib/api/handlers/BurstHandler.d.ts +0 -51
  183. package/lib/api/handlers/BurstHandler.js +0 -124
  184. package/lib/api/handlers/SequentialHandler.d.ts +0 -81
  185. package/lib/api/handlers/SequentialHandler.js +0 -365
  186. package/lib/api/handlers/Shared.d.ts +0 -14
  187. package/lib/api/handlers/Shared.js +0 -125
  188. package/lib/api/interfaces/Handler.d.ts +0 -21
  189. package/lib/api/interfaces/Handler.js +0 -2
  190. package/lib/websocket/discord/handlemessage.d.ts +0 -0
  191. package/lib/websocket/discord/handlemessage.js +0 -1
  192. package/lib/websocket/discord/memberUpdate.d.ts +0 -16
  193. package/lib/websocket/discord/memberUpdate.js +0 -47
@@ -1,51 +0,0 @@
1
- import type { RequestInit } from 'undici-types';
2
- import type { REST } from '../REST.js';
3
- import type { IHandler } from '../interfaces/Handler.js';
4
- import type { HandlerRequestData, ResponseLike, RouteData } from '../utils/types.js';
5
- /**
6
- * The structure used to handle burst requests for a given bucket.
7
- * Burst requests have no ratelimit handling but allow for pre- and post-processing
8
- * of data in the same manner as sequentially queued requests.
9
- *
10
- * @remarks
11
- * This queue may still emit a rate limit error if an unexpected 429 is hit
12
- */
13
- export declare class BurstHandler implements IHandler {
14
- private readonly manager;
15
- private readonly hash;
16
- private readonly majorParameter;
17
- /**
18
- * {@inheritdoc IHandler.id}
19
- */
20
- readonly id: string;
21
- /**
22
- * {@inheritDoc IHandler.inactive}
23
- */
24
- inactive: boolean;
25
- /**
26
- * @param manager - The request manager
27
- * @param hash - The hash that this RequestHandler handles
28
- * @param majorParameter - The major parameter for this handler
29
- */
30
- constructor(manager: REST, hash: string, majorParameter: string);
31
- /**
32
- * Emits a debug message
33
- *
34
- * @param message - The message to debug
35
- */
36
- private debug;
37
- /**
38
- * {@inheritDoc IHandler.queueRequest}
39
- */
40
- queueRequest(routeId: RouteData, url: string, options: RequestInit, requestData: HandlerRequestData): Promise<ResponseLike>;
41
- /**
42
- * The method that actually makes the request to the API, and updates info about the bucket accordingly
43
- *
44
- * @param routeId - The generalized API route with literal ids for major parameters
45
- * @param url - The fully resolved URL to make the request to
46
- * @param options - The fetch options needed to make the request
47
- * @param requestData - Extra data from the user's request needed for errors and additional processing
48
- * @param retries - The number of retries this request has already attempted (recursion)
49
- */
50
- private runRequest;
51
- }
@@ -1,124 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BurstHandler = void 0;
4
- const utils_js_1 = require("../utils/utils.js");
5
- const Shared_js_1 = require("./Shared.js");
6
- /**
7
- * The structure used to handle burst requests for a given bucket.
8
- * Burst requests have no ratelimit handling but allow for pre- and post-processing
9
- * of data in the same manner as sequentially queued requests.
10
- *
11
- * @remarks
12
- * This queue may still emit a rate limit error if an unexpected 429 is hit
13
- */
14
- class BurstHandler {
15
- manager;
16
- hash;
17
- majorParameter;
18
- /**
19
- * {@inheritdoc IHandler.id}
20
- */
21
- id;
22
- /**
23
- * {@inheritDoc IHandler.inactive}
24
- */
25
- inactive = false;
26
- /**
27
- * @param manager - The request manager
28
- * @param hash - The hash that this RequestHandler handles
29
- * @param majorParameter - The major parameter for this handler
30
- */
31
- constructor(manager, hash, majorParameter) {
32
- this.manager = manager;
33
- this.hash = hash;
34
- this.majorParameter = majorParameter;
35
- this.id = `${hash}:${majorParameter}`;
36
- }
37
- /**
38
- * Emits a debug message
39
- *
40
- * @param message - The message to debug
41
- */
42
- debug(message) {
43
- this.manager.debugger?.info(`#${this.id} ${message}`);
44
- }
45
- /**
46
- * {@inheritDoc IHandler.queueRequest}
47
- */
48
- async queueRequest(routeId, url, options, requestData) {
49
- return this.runRequest(routeId, url, options, requestData);
50
- }
51
- /**
52
- * The method that actually makes the request to the API, and updates info about the bucket accordingly
53
- *
54
- * @param routeId - The generalized API route with literal ids for major parameters
55
- * @param url - The fully resolved URL to make the request to
56
- * @param options - The fetch options needed to make the request
57
- * @param requestData - Extra data from the user's request needed for errors and additional processing
58
- * @param retries - The number of retries this request has already attempted (recursion)
59
- */
60
- async runRequest(routeId, url, options, requestData, retries = 0) {
61
- const method = options.method ?? 'get';
62
- const res = await (0, Shared_js_1.makeNetworkRequest)(this.manager, routeId, url, options, requestData, retries);
63
- // Retry requested
64
- if (res === null) {
65
- // eslint-disable-next-line no-param-reassign
66
- return this.runRequest(routeId, url, options, requestData, ++retries);
67
- }
68
- const status = res.status;
69
- let retryAfter = 0;
70
- const retry = res.headers.get('Retry-After');
71
- // Amount of time in milliseconds until we should retry if rate limited (globally or otherwise)
72
- if (retry)
73
- retryAfter = Number(retry) * 1_000 + this.manager.options.offset;
74
- // Count the invalid requests
75
- if (status === 401 || status === 403 || status === 429) {
76
- (0, Shared_js_1.incrementInvalidCount)(this.manager);
77
- }
78
- if (status >= 200 && status < 300) {
79
- return res;
80
- }
81
- if (status === 429) {
82
- // Unexpected ratelimit
83
- const isGlobal = res.headers.has('X-RateLimit-Global');
84
- const scope = (res.headers.get('X-RateLimit-Scope') ?? 'user');
85
- await (0, utils_js_1.onRateLimit)(this.manager, {
86
- global: isGlobal,
87
- method,
88
- url,
89
- route: routeId.bucketRoute,
90
- majorParameter: this.majorParameter,
91
- hash: this.hash,
92
- limit: Number.POSITIVE_INFINITY,
93
- timeToReset: retryAfter,
94
- retryAfter,
95
- sublimitTimeout: 0,
96
- scope,
97
- });
98
- this.debug([
99
- 'Encountered unexpected 429 rate limit',
100
- ` Global : ${isGlobal}`,
101
- ` Method : ${method}`,
102
- ` URL : ${url}`,
103
- ` Bucket : ${routeId.bucketRoute}`,
104
- ` Major parameter: ${routeId.majorParameter}`,
105
- ` Hash : ${this.hash}`,
106
- ` Limit : ${Number.POSITIVE_INFINITY}`,
107
- ` Retry After : ${retryAfter}ms`,
108
- ' Sublimit : None',
109
- ` Scope : ${scope}`,
110
- ].join('\n'));
111
- // We are bypassing all other limits, but an encountered limit should be respected (it's probably a non-punished rate limit anyways)
112
- await (0, utils_js_1.sleep)(retryAfter);
113
- // Since this is not a server side issue, the next request should pass, so we don't bump the retries counter
114
- return this.runRequest(routeId, url, options, requestData, retries);
115
- }
116
- const handled = await (0, Shared_js_1.handleErrors)(this.manager, res, method, url, requestData, retries);
117
- if (handled === null) {
118
- // eslint-disable-next-line no-param-reassign
119
- return this.runRequest(routeId, url, options, requestData, ++retries);
120
- }
121
- return handled;
122
- }
123
- }
124
- exports.BurstHandler = BurstHandler;
@@ -1,81 +0,0 @@
1
- import type { RequestInit } from 'undici-types';
2
- import type { REST } from '../REST.js';
3
- import type { IHandler } from '../interfaces/Handler.js';
4
- import type { HandlerRequestData, ResponseLike, RouteData } from '../utils/types.js';
5
- /**
6
- * The structure used to handle sequential requests for a given bucket
7
- */
8
- export declare class SequentialHandler implements IHandler {
9
- #private;
10
- private readonly manager;
11
- private readonly hash;
12
- private readonly majorParameter;
13
- /**
14
- * {@inheritDoc IHandler.id}
15
- */
16
- readonly id: string;
17
- /**
18
- * The time this rate limit bucket will reset
19
- */
20
- private reset;
21
- /**
22
- * The remaining requests that can be made before we are rate limited
23
- */
24
- private remaining;
25
- /**
26
- * The total number of requests that can be made before we are rate limited
27
- */
28
- private limit;
29
- /**
30
- * @param manager - The request manager
31
- * @param hash - The hash that this RequestHandler handles
32
- * @param majorParameter - The major parameter for this handler
33
- */
34
- constructor(manager: REST, hash: string, majorParameter: string);
35
- /**
36
- * {@inheritDoc IHandler.inactive}
37
- */
38
- get inactive(): boolean;
39
- /**
40
- * If the rate limit bucket is currently limited by the global limit
41
- */
42
- private get globalLimited();
43
- /**
44
- * If the rate limit bucket is currently limited by its limit
45
- */
46
- private get localLimited();
47
- /**
48
- * If the rate limit bucket is currently limited
49
- */
50
- private get limited();
51
- /**
52
- * The time until queued requests can continue
53
- */
54
- private get timeToReset();
55
- /**
56
- * Emits a debug message
57
- *
58
- * @param message - The message to debug
59
- */
60
- private debug;
61
- /**
62
- * Delay all requests for the specified amount of time, handling global rate limits
63
- *
64
- * @param time - The amount of time to delay all requests for
65
- */
66
- private globalDelayFor;
67
- /**
68
- * {@inheritDoc IHandler.queueRequest}
69
- */
70
- queueRequest(routeId: RouteData, url: string, options: RequestInit, requestData: HandlerRequestData): Promise<ResponseLike>;
71
- /**
72
- * The method that actually makes the request to the api, and updates info about the bucket accordingly
73
- *
74
- * @param routeId - The generalized api route with literal ids for major parameters
75
- * @param url - The fully resolved url to make the request to
76
- * @param options - The fetch options needed to make the request
77
- * @param requestData - Extra data from the user's request needed for errors and additional processing
78
- * @param retries - The number of retries this request has already attempted (recursion)
79
- */
80
- private runRequest;
81
- }
@@ -1,365 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SequentialHandler = void 0;
4
- const async_queue_1 = require("@sapphire/async-queue");
5
- const utils_js_1 = require("../utils/utils.js");
6
- const Shared_js_1 = require("./Shared.js");
7
- var QueueType;
8
- (function (QueueType) {
9
- QueueType[QueueType["Standard"] = 0] = "Standard";
10
- QueueType[QueueType["Sublimit"] = 1] = "Sublimit";
11
- })(QueueType || (QueueType = {}));
12
- /**
13
- * The structure used to handle sequential requests for a given bucket
14
- */
15
- class SequentialHandler {
16
- manager;
17
- hash;
18
- majorParameter;
19
- /**
20
- * {@inheritDoc IHandler.id}
21
- */
22
- id;
23
- /**
24
- * The time this rate limit bucket will reset
25
- */
26
- reset = -1;
27
- /**
28
- * The remaining requests that can be made before we are rate limited
29
- */
30
- remaining = 1;
31
- /**
32
- * The total number of requests that can be made before we are rate limited
33
- */
34
- limit = Number.POSITIVE_INFINITY;
35
- /**
36
- * The interface used to sequence async requests sequentially
37
- */
38
- #asyncQueue = new async_queue_1.AsyncQueue();
39
- /**
40
- * The interface used to sequence sublimited async requests sequentially
41
- */
42
- #sublimitedQueue = null;
43
- /**
44
- * A promise wrapper for when the sublimited queue is finished being processed or null when not being processed
45
- */
46
- #sublimitPromise = null;
47
- /**
48
- * Whether the sublimit queue needs to be shifted in the finally block
49
- */
50
- #shiftSublimit = false;
51
- /**
52
- * @param manager - The request manager
53
- * @param hash - The hash that this RequestHandler handles
54
- * @param majorParameter - The major parameter for this handler
55
- */
56
- constructor(manager, hash, majorParameter) {
57
- this.manager = manager;
58
- this.hash = hash;
59
- this.majorParameter = majorParameter;
60
- this.id = `${hash}:${majorParameter}`;
61
- }
62
- /**
63
- * {@inheritDoc IHandler.inactive}
64
- */
65
- get inactive() {
66
- return (this.#asyncQueue.remaining === 0 &&
67
- (this.#sublimitedQueue === null || this.#sublimitedQueue.remaining === 0) &&
68
- !this.limited);
69
- }
70
- /**
71
- * If the rate limit bucket is currently limited by the global limit
72
- */
73
- get globalLimited() {
74
- return this.manager.globalRemaining <= 0 && Date.now() < this.manager.globalReset;
75
- }
76
- /**
77
- * If the rate limit bucket is currently limited by its limit
78
- */
79
- get localLimited() {
80
- return this.remaining <= 0 && Date.now() < this.reset;
81
- }
82
- /**
83
- * If the rate limit bucket is currently limited
84
- */
85
- get limited() {
86
- return this.globalLimited || this.localLimited;
87
- }
88
- /**
89
- * The time until queued requests can continue
90
- */
91
- get timeToReset() {
92
- return this.reset + this.manager.options.offset - Date.now();
93
- }
94
- /**
95
- * Emits a debug message
96
- *
97
- * @param message - The message to debug
98
- */
99
- debug(message) {
100
- this.manager.debugger?.info(`#${this.id} ${message}`);
101
- }
102
- /**
103
- * Delay all requests for the specified amount of time, handling global rate limits
104
- *
105
- * @param time - The amount of time to delay all requests for
106
- */
107
- async globalDelayFor(time) {
108
- await (0, utils_js_1.sleep)(time);
109
- this.manager.globalDelay = null;
110
- }
111
- /**
112
- * {@inheritDoc IHandler.queueRequest}
113
- */
114
- async queueRequest(routeId, url, options, requestData) {
115
- let queue = this.#asyncQueue;
116
- let queueType = QueueType.Standard;
117
- // Separate sublimited requests when already sublimited
118
- if (this.#sublimitedQueue && (0, utils_js_1.hasSublimit)(routeId.bucketRoute, requestData.body, options.method)) {
119
- queue = this.#sublimitedQueue;
120
- queueType = QueueType.Sublimit;
121
- }
122
- // Wait for any previous requests to be completed before this one is run
123
- await queue.wait({ signal: requestData.signal });
124
- // This set handles retroactively sublimiting requests
125
- if (queueType === QueueType.Standard) {
126
- if (this.#sublimitedQueue && (0, utils_js_1.hasSublimit)(routeId.bucketRoute, requestData.body, options.method)) {
127
- /**
128
- * Remove the request from the standard queue, it should never be possible to get here while processing the
129
- * sublimit queue so there is no need to worry about shifting the wrong request
130
- */
131
- queue = this.#sublimitedQueue;
132
- const wait = queue.wait();
133
- this.#asyncQueue.shift();
134
- await wait;
135
- }
136
- else if (this.#sublimitPromise) {
137
- // Stall requests while the sublimit queue gets processed
138
- await this.#sublimitPromise.promise;
139
- }
140
- }
141
- try {
142
- // Make the request, and return the results
143
- return this.runRequest(routeId, url, options, requestData);
144
- }
145
- finally {
146
- // Allow the next request to fire
147
- queue.shift();
148
- if (this.#shiftSublimit) {
149
- this.#shiftSublimit = false;
150
- this.#sublimitedQueue?.shift();
151
- }
152
- // If this request is the last request in a sublimit
153
- if (this.#sublimitedQueue?.remaining === 0) {
154
- this.#sublimitPromise?.resolve();
155
- this.#sublimitedQueue = null;
156
- }
157
- }
158
- }
159
- /**
160
- * The method that actually makes the request to the api, and updates info about the bucket accordingly
161
- *
162
- * @param routeId - The generalized api route with literal ids for major parameters
163
- * @param url - The fully resolved url to make the request to
164
- * @param options - The fetch options needed to make the request
165
- * @param requestData - Extra data from the user's request needed for errors and additional processing
166
- * @param retries - The number of retries this request has already attempted (recursion)
167
- */
168
- async runRequest(routeId, url, options, requestData, retries = 0) {
169
- /*
170
- * After calculations have been done, pre-emptively stop further requests
171
- * Potentially loop until this task can run if e.g. the global rate limit is hit twice
172
- */
173
- while (this.limited) {
174
- const isGlobal = this.globalLimited;
175
- let limit;
176
- let timeout;
177
- let delay;
178
- if (isGlobal) {
179
- // Set RateLimitData based on the global limit
180
- limit = this.manager.options.globalRequestsPerSecond;
181
- timeout = this.manager.globalReset + this.manager.options.offset - Date.now();
182
- // If this is the first task to reach the global timeout, set the global delay
183
- if (!this.manager.globalDelay) {
184
- // The global delay function clears the global delay state when it is resolved
185
- this.manager.globalDelay = this.globalDelayFor(timeout);
186
- }
187
- delay = this.manager.globalDelay;
188
- }
189
- else {
190
- // Set RateLimitData based on the route-specific limit
191
- limit = this.limit;
192
- timeout = this.timeToReset;
193
- delay = (0, utils_js_1.sleep)(timeout);
194
- }
195
- const rateLimitData = {
196
- global: isGlobal,
197
- method: options.method ?? 'get',
198
- url,
199
- route: routeId.bucketRoute,
200
- majorParameter: this.majorParameter,
201
- hash: this.hash,
202
- limit,
203
- timeToReset: timeout,
204
- retryAfter: timeout,
205
- sublimitTimeout: 0,
206
- scope: 'user',
207
- };
208
- // Let library users know they have hit a rate limit
209
- this.manager.debugger?.info(rateLimitData);
210
- // Determine whether a RateLimitError should be thrown
211
- await (0, utils_js_1.onRateLimit)(this.manager, rateLimitData);
212
- // When not erroring, emit debug for what is happening
213
- if (isGlobal) {
214
- this.debug(`Global rate limit hit, blocking all requests for ${timeout}ms`);
215
- }
216
- else {
217
- this.debug(`Waiting ${timeout}ms for rate limit to pass`);
218
- }
219
- // Wait the remaining time left before the rate limit resets
220
- await delay;
221
- }
222
- // As the request goes out, update the global usage information
223
- if (!this.manager.globalReset || this.manager.globalReset < Date.now()) {
224
- this.manager.globalReset = Date.now() + 1_000;
225
- this.manager.globalRemaining = this.manager.options.globalRequestsPerSecond;
226
- }
227
- this.manager.globalRemaining--;
228
- const method = options.method ?? 'get';
229
- const res = await (0, Shared_js_1.makeNetworkRequest)(this.manager, routeId, url, options, requestData, retries);
230
- // Retry requested
231
- if (res === null) {
232
- // eslint-disable-next-line no-param-reassign
233
- return this.runRequest(routeId, url, options, requestData, ++retries);
234
- }
235
- const status = res.status;
236
- let retryAfter = 0;
237
- const limit = res.headers.get('X-RateLimit-Limit');
238
- const remaining = res.headers.get('X-RateLimit-Remaining');
239
- const reset = res.headers.get('X-RateLimit-Reset-After');
240
- const hash = res.headers.get('X-RateLimit-Bucket');
241
- const retry = res.headers.get('Retry-After');
242
- const scope = (res.headers.get('X-RateLimit-Scope') ?? 'user');
243
- // Update the total number of requests that can be made before the rate limit resets
244
- this.limit = limit ? Number(limit) : Number.POSITIVE_INFINITY;
245
- // Update the number of remaining requests that can be made before the rate limit resets
246
- this.remaining = remaining ? Number(remaining) : 1;
247
- // Update the time when this rate limit resets (reset-after is in seconds)
248
- this.reset = reset ? Number(reset) * 1_000 + Date.now() + this.manager.options.offset : Date.now();
249
- // Amount of time in milliseconds until we should retry if rate limited (globally or otherwise)
250
- if (retry)
251
- retryAfter = Number(retry) * 1_000 + this.manager.options.offset;
252
- // Handle buckets via the hash header retroactively
253
- if (hash && hash !== this.hash) {
254
- // Let library users know when rate limit buckets have been updated
255
- this.debug(['Received bucket hash update', ` Old Hash : ${this.hash}`, ` New Hash : ${hash}`].join('\n'));
256
- // This queue will eventually be eliminated via attrition
257
- this.manager.hashes.set(`${method}:${routeId.bucketRoute}`, { value: hash, lastAccess: Date.now() });
258
- }
259
- else if (hash) {
260
- // Handle the case where hash value doesn't change
261
- // Fetch the hash data from the manager
262
- const hashData = this.manager.hashes.get(`${method}:${routeId.bucketRoute}`);
263
- // When fetched, update the last access of the hash
264
- if (hashData) {
265
- hashData.lastAccess = Date.now();
266
- }
267
- }
268
- // Handle retryAfter, which means we have actually hit a rate limit
269
- let sublimitTimeout = null;
270
- if (retryAfter > 0) {
271
- if (res.headers.has('X-RateLimit-Global')) {
272
- this.manager.globalRemaining = 0;
273
- this.manager.globalReset = Date.now() + retryAfter;
274
- }
275
- else if (!this.localLimited) {
276
- /*
277
- * This is a sublimit (e.g. 2 channel name changes/10 minutes) since the headers don't indicate a
278
- * route-wide rate limit. Don't update remaining or reset to avoid rate limiting the whole
279
- * endpoint, just set a reset time on the request itself to avoid retrying too soon.
280
- */
281
- sublimitTimeout = retryAfter;
282
- }
283
- }
284
- // Count the invalid requests
285
- if (status === 401 || status === 403 || status === 429) {
286
- (0, Shared_js_1.incrementInvalidCount)(this.manager);
287
- }
288
- if (res.ok) {
289
- return res;
290
- }
291
- if (status === 429) {
292
- // A rate limit was hit - this may happen if the route isn't associated with an official bucket hash yet, or when first globally rate limited
293
- const isGlobal = this.globalLimited;
294
- let limit;
295
- let timeout;
296
- if (isGlobal) {
297
- // Set RateLimitData based on the global limit
298
- limit = this.manager.options.globalRequestsPerSecond;
299
- timeout = this.manager.globalReset + this.manager.options.offset - Date.now();
300
- }
301
- else {
302
- // Set RateLimitData based on the route-specific limit
303
- limit = this.limit;
304
- timeout = this.timeToReset;
305
- }
306
- await (0, utils_js_1.onRateLimit)(this.manager, {
307
- global: isGlobal,
308
- method,
309
- url,
310
- route: routeId.bucketRoute,
311
- majorParameter: this.majorParameter,
312
- hash: this.hash,
313
- limit,
314
- timeToReset: timeout,
315
- retryAfter,
316
- sublimitTimeout: sublimitTimeout ?? 0,
317
- scope,
318
- });
319
- this.debug([
320
- 'Encountered unexpected 429 rate limit',
321
- ` Global : ${isGlobal.toString()}`,
322
- ` Method : ${method}`,
323
- ` URL : ${url}`,
324
- ` Bucket : ${routeId.bucketRoute}`,
325
- ` Major parameter: ${routeId.majorParameter}`,
326
- ` Hash : ${this.hash}`,
327
- ` Limit : ${limit}`,
328
- ` Retry After : ${retryAfter}ms`,
329
- ` Sublimit : ${sublimitTimeout ? `${sublimitTimeout}ms` : 'None'}`,
330
- ` Scope : ${scope}`,
331
- ].join('\n'));
332
- // If caused by a sublimit, wait it out here so other requests on the route can be handled
333
- if (sublimitTimeout) {
334
- // Normally the sublimit queue will not exist, however, if a sublimit is hit while in the sublimit queue, it will
335
- const firstSublimit = !this.#sublimitedQueue;
336
- if (firstSublimit) {
337
- this.#sublimitedQueue = new async_queue_1.AsyncQueue();
338
- void this.#sublimitedQueue.wait();
339
- this.#asyncQueue.shift();
340
- }
341
- this.#sublimitPromise?.resolve();
342
- this.#sublimitPromise = null;
343
- await (0, utils_js_1.sleep)(sublimitTimeout);
344
- let resolve;
345
- // eslint-disable-next-line promise/param-names, no-promise-executor-return
346
- const promise = new Promise(res => (resolve = res));
347
- this.#sublimitPromise = { promise, resolve: resolve };
348
- if (firstSublimit) {
349
- // Re-queue this request so it can be shifted by the finally
350
- await this.#asyncQueue.wait();
351
- this.#shiftSublimit = true;
352
- }
353
- }
354
- // Since this is not a server side issue, the next request should pass, so we don't bump the retries counter
355
- return this.runRequest(routeId, url, options, requestData, retries);
356
- }
357
- const handled = await (0, Shared_js_1.handleErrors)(this.manager, res, method, url, requestData, retries);
358
- if (handled === null) {
359
- // eslint-disable-next-line no-param-reassign
360
- return this.runRequest(routeId, url, options, requestData, ++retries);
361
- }
362
- return handled;
363
- }
364
- }
365
- exports.SequentialHandler = SequentialHandler;
@@ -1,14 +0,0 @@
1
- import type { REST } from '../REST.js';
2
- import type { HandlerRequestData, ResponseLike } from '../utils/types.js';
3
- /**
4
- * Handles 5xx and 4xx errors (not 429's) conventionally. 429's should be handled before calling this function
5
- *
6
- * @param manager - The manager that holds options and emits informational events
7
- * @param res - The response received from {@link makeNetworkRequest}
8
- * @param method - The method used to make the request
9
- * @param url - The fully resolved url to make the request to
10
- * @param requestData - Extra data from the user's request needed for errors and additional processing
11
- * @param retries - The number of retries this request has already attempted (recursion occurs on the handler)
12
- * @returns The response if the status code is not handled or null to request a retry
13
- */
14
- export declare function handleErrors(manager: REST, res: ResponseLike, method: string, url: string, requestData: HandlerRequestData, retries: number): Promise<ResponseLike | null>;