@discordjs/rest 2.2.1-dev.1705968584-bfc7bb556 → 2.3.0-dev.1706616235-278396e81

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.
package/dist/index.d.mts CHANGED
@@ -112,7 +112,7 @@ interface RESTOptions {
112
112
  *
113
113
  * @defaultValue `50`
114
114
  */
115
- offset: number;
115
+ offset: GetRateLimitOffsetFunction | number;
116
116
  /**
117
117
  * Determines how rate limiting and pre-emptive throttling should be handled.
118
118
  * When an array of strings, each element is treated as a prefix for the request route
@@ -210,6 +210,10 @@ interface RateLimitData {
210
210
  * A function that determines whether the rate limit hit should throw an Error
211
211
  */
212
212
  type RateLimitQueueFilter = (rateLimitData: RateLimitData) => Awaitable<boolean>;
213
+ /**
214
+ * A function that determines the rate limit offset for a given request.
215
+ */
216
+ type GetRateLimitOffsetFunction = (route: string) => number;
213
217
  interface APIRequest {
214
218
  /**
215
219
  * The data that was used to form the body of this request
@@ -897,4 +901,4 @@ declare function calculateUserDefaultAvatarIndex(userId: Snowflake): number;
897
901
  */
898
902
  declare const version: string;
899
903
 
900
- export { ALLOWED_EXTENSIONS, ALLOWED_SIZES, ALLOWED_STICKER_EXTENSIONS, APIRequest, BaseImageURLOptions, BurstHandlerMajorIdKey, CDN, DEPRECATION_WARNING_PREFIX, DefaultRestOptions, DefaultUserAgent, DefaultUserAgentAppendix, DiscordAPIError, DiscordErrorData, HTTPError, HandlerRequestData, HashData, ImageExtension, ImageSize, ImageURLOptions, InternalRequest, InvalidRequestWarningData, MakeURLOptions, OAuthErrorData, OverwrittenMimeTypes, REST, RESTEvents, RESTOptions, RateLimitData, RateLimitError, RateLimitQueueFilter, RawFile, RequestBody, RequestData, RequestHeaders, RequestMethod, ResponseLike, RestEvents, RestEventsMap, RouteData, RouteLike, StickerExtension, calculateUserDefaultAvatarIndex, makeURLSearchParams, parseResponse, version };
904
+ export { ALLOWED_EXTENSIONS, ALLOWED_SIZES, ALLOWED_STICKER_EXTENSIONS, APIRequest, BaseImageURLOptions, BurstHandlerMajorIdKey, CDN, DEPRECATION_WARNING_PREFIX, DefaultRestOptions, DefaultUserAgent, DefaultUserAgentAppendix, DiscordAPIError, DiscordErrorData, GetRateLimitOffsetFunction, HTTPError, HandlerRequestData, HashData, ImageExtension, ImageSize, ImageURLOptions, InternalRequest, InvalidRequestWarningData, MakeURLOptions, OAuthErrorData, OverwrittenMimeTypes, REST, RESTEvents, RESTOptions, RateLimitData, RateLimitError, RateLimitQueueFilter, RawFile, RequestBody, RequestData, RequestHeaders, RequestMethod, ResponseLike, RestEvents, RestEventsMap, RouteData, RouteLike, StickerExtension, calculateUserDefaultAvatarIndex, makeURLSearchParams, parseResponse, version };
package/dist/index.d.ts CHANGED
@@ -112,7 +112,7 @@ interface RESTOptions {
112
112
  *
113
113
  * @defaultValue `50`
114
114
  */
115
- offset: number;
115
+ offset: GetRateLimitOffsetFunction | number;
116
116
  /**
117
117
  * Determines how rate limiting and pre-emptive throttling should be handled.
118
118
  * When an array of strings, each element is treated as a prefix for the request route
@@ -210,6 +210,10 @@ interface RateLimitData {
210
210
  * A function that determines whether the rate limit hit should throw an Error
211
211
  */
212
212
  type RateLimitQueueFilter = (rateLimitData: RateLimitData) => Awaitable<boolean>;
213
+ /**
214
+ * A function that determines the rate limit offset for a given request.
215
+ */
216
+ type GetRateLimitOffsetFunction = (route: string) => number;
213
217
  interface APIRequest {
214
218
  /**
215
219
  * The data that was used to form the body of this request
@@ -897,4 +901,4 @@ declare function calculateUserDefaultAvatarIndex(userId: Snowflake): number;
897
901
  */
898
902
  declare const version: string;
899
903
 
900
- export { ALLOWED_EXTENSIONS, ALLOWED_SIZES, ALLOWED_STICKER_EXTENSIONS, APIRequest, BaseImageURLOptions, BurstHandlerMajorIdKey, CDN, DEPRECATION_WARNING_PREFIX, DefaultRestOptions, DefaultUserAgent, DefaultUserAgentAppendix, DiscordAPIError, DiscordErrorData, HTTPError, HandlerRequestData, HashData, ImageExtension, ImageSize, ImageURLOptions, InternalRequest, InvalidRequestWarningData, MakeURLOptions, OAuthErrorData, OverwrittenMimeTypes, REST, RESTEvents, RESTOptions, RateLimitData, RateLimitError, RateLimitQueueFilter, RawFile, RequestBody, RequestData, RequestHeaders, RequestMethod, ResponseLike, RestEvents, RestEventsMap, RouteData, RouteLike, StickerExtension, calculateUserDefaultAvatarIndex, makeURLSearchParams, parseResponse, version };
904
+ export { ALLOWED_EXTENSIONS, ALLOWED_SIZES, ALLOWED_STICKER_EXTENSIONS, APIRequest, BaseImageURLOptions, BurstHandlerMajorIdKey, CDN, DEPRECATION_WARNING_PREFIX, DefaultRestOptions, DefaultUserAgent, DefaultUserAgentAppendix, DiscordAPIError, DiscordErrorData, GetRateLimitOffsetFunction, HTTPError, HandlerRequestData, HashData, ImageExtension, ImageSize, ImageURLOptions, InternalRequest, InvalidRequestWarningData, MakeURLOptions, OAuthErrorData, OverwrittenMimeTypes, REST, RESTEvents, RESTOptions, RateLimitData, RateLimitError, RateLimitQueueFilter, RawFile, RequestBody, RequestData, RequestHeaders, RequestMethod, ResponseLike, RestEvents, RestEventsMap, RouteData, RouteLike, StickerExtension, calculateUserDefaultAvatarIndex, makeURLSearchParams, parseResponse, version };
package/dist/index.js CHANGED
@@ -124,7 +124,7 @@ __name(resolveBody, "resolveBody");
124
124
  // src/lib/utils/constants.ts
125
125
  var import_util = require("@discordjs/util");
126
126
  var import_v10 = require("discord-api-types/v10");
127
- var DefaultUserAgent = `DiscordBot (https://discord.js.org, 2.2.1-dev.1705968584-bfc7bb556)`;
127
+ var DefaultUserAgent = `DiscordBot (https://discord.js.org, 2.3.0-dev.1706616235-278396e81)`;
128
128
  var DefaultUserAgentAppendix = (0, import_util.getUserAgentAppendix)();
129
129
  var DefaultRestOptions = {
130
130
  agent: null,
@@ -321,6 +321,14 @@ function deprecationWarning(message) {
321
321
  }
322
322
  }
323
323
  __name(deprecationWarning, "deprecationWarning");
324
+ function normalizeRateLimitOffset(offset, route) {
325
+ if (typeof offset === "number") {
326
+ return Math.max(0, offset);
327
+ }
328
+ const result = offset(route);
329
+ return Math.max(0, result);
330
+ }
331
+ __name(normalizeRateLimitOffset, "normalizeRateLimitOffset");
324
332
 
325
333
  // src/lib/CDN.ts
326
334
  var deprecationEmittedForEmoji = false;
@@ -782,8 +790,9 @@ var BurstHandler = class {
782
790
  const status = res.status;
783
791
  let retryAfter = 0;
784
792
  const retry = res.headers.get("Retry-After");
793
+ const offset = normalizeRateLimitOffset(this.manager.options.offset, routeId.bucketRoute);
785
794
  if (retry)
786
- retryAfter = Number(retry) * 1e3 + this.manager.options.offset;
795
+ retryAfter = Number(retry) * 1e3 + offset;
787
796
  if (status === 401 || status === 403 || status === 429) {
788
797
  incrementInvalidCount(this.manager);
789
798
  }
@@ -908,8 +917,9 @@ var SequentialHandler = class {
908
917
  /**
909
918
  * The time until queued requests can continue
910
919
  */
911
- get timeToReset() {
912
- return this.reset + this.manager.options.offset - Date.now();
920
+ getTimeToReset(routeId) {
921
+ const offset = normalizeRateLimitOffset(this.manager.options.offset, routeId.bucketRoute);
922
+ return this.reset + offset - Date.now();
913
923
  }
914
924
  /**
915
925
  * Emits a debug message
@@ -979,15 +989,16 @@ var SequentialHandler = class {
979
989
  let timeout;
980
990
  let delay;
981
991
  if (isGlobal) {
992
+ const offset2 = normalizeRateLimitOffset(this.manager.options.offset, routeId.bucketRoute);
982
993
  limit2 = this.manager.options.globalRequestsPerSecond;
983
- timeout = this.manager.globalReset + this.manager.options.offset - Date.now();
994
+ timeout = this.manager.globalReset + offset2 - Date.now();
984
995
  if (!this.manager.globalDelay) {
985
996
  this.manager.globalDelay = this.globalDelayFor(timeout);
986
997
  }
987
998
  delay = this.manager.globalDelay;
988
999
  } else {
989
1000
  limit2 = this.limit;
990
- timeout = this.timeToReset;
1001
+ timeout = this.getTimeToReset(routeId);
991
1002
  delay = sleep(timeout);
992
1003
  }
993
1004
  const rateLimitData = {
@@ -1030,11 +1041,12 @@ var SequentialHandler = class {
1030
1041
  const hash = res.headers.get("X-RateLimit-Bucket");
1031
1042
  const retry = res.headers.get("Retry-After");
1032
1043
  const scope = res.headers.get("X-RateLimit-Scope") ?? "user";
1044
+ const offset = normalizeRateLimitOffset(this.manager.options.offset, routeId.bucketRoute);
1033
1045
  this.limit = limit ? Number(limit) : Number.POSITIVE_INFINITY;
1034
1046
  this.remaining = remaining ? Number(remaining) : 1;
1035
- this.reset = reset ? Number(reset) * 1e3 + Date.now() + this.manager.options.offset : Date.now();
1047
+ this.reset = reset ? Number(reset) * 1e3 + Date.now() + offset : Date.now();
1036
1048
  if (retry)
1037
- retryAfter = Number(retry) * 1e3 + this.manager.options.offset;
1049
+ retryAfter = Number(retry) * 1e3 + offset;
1038
1050
  if (hash && hash !== this.hash) {
1039
1051
  this.debug(["Received bucket hash update", ` Old Hash : ${this.hash}`, ` New Hash : ${hash}`].join("\n"));
1040
1052
  this.manager.hashes.set(`${method}:${routeId.bucketRoute}`, { value: hash, lastAccess: Date.now() });
@@ -1063,11 +1075,12 @@ var SequentialHandler = class {
1063
1075
  let limit2;
1064
1076
  let timeout;
1065
1077
  if (isGlobal) {
1078
+ const offset2 = normalizeRateLimitOffset(this.manager.options.offset, routeId.bucketRoute);
1066
1079
  limit2 = this.manager.options.globalRequestsPerSecond;
1067
- timeout = this.manager.globalReset + this.manager.options.offset - Date.now();
1080
+ timeout = this.manager.globalReset + offset2 - Date.now();
1068
1081
  } else {
1069
1082
  limit2 = this.limit;
1070
- timeout = this.timeToReset;
1083
+ timeout = this.getTimeToReset(routeId);
1071
1084
  }
1072
1085
  await onRateLimit(this.manager, {
1073
1086
  global: isGlobal,
@@ -1165,7 +1178,6 @@ var REST = class _REST extends import_async_event_emitter.AsyncEventEmitter {
1165
1178
  super();
1166
1179
  this.cdn = new CDN(options.cdn ?? DefaultRestOptions.cdn);
1167
1180
  this.options = { ...DefaultRestOptions, ...options };
1168
- this.options.offset = Math.max(0, this.options.offset);
1169
1181
  this.globalRemaining = Math.max(1, this.options.globalRequestsPerSecond);
1170
1182
  this.agent = options.agent ?? null;
1171
1183
  this.setupSweepers();
@@ -1442,7 +1454,7 @@ var REST = class _REST extends import_async_event_emitter.AsyncEventEmitter {
1442
1454
  };
1443
1455
 
1444
1456
  // src/shared.ts
1445
- var version = "2.2.1-dev.1705968584-bfc7bb556";
1457
+ var version = "2.3.0-dev.1706616235-278396e81";
1446
1458
 
1447
1459
  // src/index.ts
1448
1460
  globalThis.FormData ??= import_undici2.FormData;