@wildix/xbees-conversations-client 1.2.7 → 1.2.9

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.
@@ -32,6 +32,40 @@ class ConversationsClient extends smithy_client_1.Client {
32
32
  this.middlewareStack.add(smithy_utils_1.authorizationMiddleware.bind(this, configuration.token), { step: "build" });
33
33
  this.middlewareStack.use((0, middleware_user_agent_1.getUserAgentPlugin)(this.config));
34
34
  this.middlewareStack.use((0, middleware_retry_1.getRetryPlugin)(this.config));
35
+ this.middlewareStack.add((next) => async (args) => {
36
+ try {
37
+ return await next(args);
38
+ }
39
+ catch (error) {
40
+ const statusCode = error?.$metadata?.httpStatusCode ?? error?.$response?.statusCode;
41
+ const headers = error?.$response?.headers;
42
+ if (statusCode === 429 && headers) {
43
+ const headerEntries = Object.entries(headers);
44
+ const getHeaderWithKey = (name) => {
45
+ const normalizedName = name.toLowerCase();
46
+ for (const [key, value] of headerEntries) {
47
+ if (key.toLowerCase() === normalizedName && typeof value === "string") {
48
+ return [key, value];
49
+ }
50
+ }
51
+ return undefined;
52
+ };
53
+ const retryAfterHeader = getHeaderWithKey("retry-after");
54
+ if (retryAfterHeader) {
55
+ const [retryAfterKey, retryAfterValue] = retryAfterHeader;
56
+ const retryAfterNumeric = Number(retryAfterValue);
57
+ if (!Number.isNaN(retryAfterNumeric) && retryAfterNumeric >= 1000) {
58
+ headers[retryAfterKey] = new Date(Date.now() + retryAfterNumeric).toUTCString();
59
+ }
60
+ }
61
+ }
62
+ throw error;
63
+ }
64
+ }, {
65
+ name: "retryAfterHeaderNormalizationMiddleware",
66
+ step: "finalizeRequest",
67
+ priority: "low",
68
+ });
35
69
  if (configuration?.retryLogging) {
36
70
  this.middlewareStack.add((next) => async (args) => {
37
71
  const request = args.request;
@@ -52,8 +86,47 @@ class ConversationsClient extends smithy_client_1.Client {
52
86
  catch (error) {
53
87
  const statusCode = error?.$metadata?.httpStatusCode ?? error?.$response?.statusCode;
54
88
  const willRetry = attempt < maxAttempts && this.config.retryDecider(error);
89
+ const responseHeaders = (error?.$response?.headers ?? {});
90
+ const headerEntries = Object.entries(responseHeaders);
91
+ const getHeader = (...names) => {
92
+ const normalizedNames = names.map((name) => name.toLowerCase());
93
+ for (const [key, value] of headerEntries) {
94
+ if (normalizedNames.includes(key.toLowerCase())) {
95
+ return value;
96
+ }
97
+ }
98
+ return undefined;
99
+ };
100
+ const retryAfterRaw = getHeader("retry-after");
101
+ const rateLimitResetRaw = getHeader("x-ratelimit-reset", "ratelimit-reset", "rateLimitReset");
102
+ const rateLimitRaw = getHeader("x-ratelimit-limit", "ratelimit-limit", "rateLimit");
103
+ const rateLimitRemainingRaw = getHeader("x-ratelimit-remaining", "ratelimit-remaining", "rateLimitRemaining");
104
+ let retryAfterDelayMs;
105
+ if (retryAfterRaw !== undefined) {
106
+ const retryAfterNumeric = Number(retryAfterRaw);
107
+ if (!Number.isNaN(retryAfterNumeric)) {
108
+ retryAfterDelayMs = retryAfterNumeric >= 1000 ? retryAfterNumeric : retryAfterNumeric * 1000;
109
+ }
110
+ else {
111
+ retryAfterDelayMs = new Date(retryAfterRaw).getTime() - Date.now();
112
+ }
113
+ }
114
+ let rateLimitResetDelayMs;
115
+ if (rateLimitResetRaw !== undefined) {
116
+ const resetValue = Number(rateLimitResetRaw);
117
+ if (!Number.isNaN(resetValue)) {
118
+ if (resetValue > 1000000000) {
119
+ rateLimitResetDelayMs = (resetValue * 1000) - Date.now();
120
+ }
121
+ else {
122
+ rateLimitResetDelayMs = resetValue >= 1000 ? resetValue : resetValue * 1000;
123
+ }
124
+ }
125
+ }
55
126
  if (willRetry) {
56
127
  console.warn(`[ConversationsClient] Retry decision: will retry after attempt ${attempt}/${maxAttempts} (status=${statusCode ?? "unknown"}, time=${new Date().toISOString()})`);
128
+ console.warn(`[ConversationsClient] Retry headers: retry-after=${retryAfterRaw ?? "n/a"}, x-ratelimit-reset=${rateLimitResetRaw ?? "n/a"}, x-ratelimit-limit=${rateLimitRaw ?? "n/a"}, x-ratelimit-remaining=${rateLimitRemainingRaw ?? "n/a"}`);
129
+ console.warn(`[ConversationsClient] Parsed retry timing: retryAfterDelayMs=${retryAfterDelayMs ?? "n/a"}, rateLimitResetDelayMs=${rateLimitResetDelayMs ?? "n/a"}`);
57
130
  }
58
131
  else {
59
132
  console.warn(`[ConversationsClient] Retry decision: stop after attempt ${attempt}/${maxAttempts} (status=${statusCode ?? "unknown"}, time=${new Date().toISOString()})`);
@@ -29,6 +29,40 @@ export class ConversationsClient extends __Client {
29
29
  this.middlewareStack.add(authorizationMiddleware.bind(this, configuration.token), { step: "build" });
30
30
  this.middlewareStack.use(getUserAgentPlugin(this.config));
31
31
  this.middlewareStack.use(getRetryPlugin(this.config));
32
+ this.middlewareStack.add((next) => async (args) => {
33
+ try {
34
+ return await next(args);
35
+ }
36
+ catch (error) {
37
+ const statusCode = error?.$metadata?.httpStatusCode ?? error?.$response?.statusCode;
38
+ const headers = error?.$response?.headers;
39
+ if (statusCode === 429 && headers) {
40
+ const headerEntries = Object.entries(headers);
41
+ const getHeaderWithKey = (name) => {
42
+ const normalizedName = name.toLowerCase();
43
+ for (const [key, value] of headerEntries) {
44
+ if (key.toLowerCase() === normalizedName && typeof value === "string") {
45
+ return [key, value];
46
+ }
47
+ }
48
+ return undefined;
49
+ };
50
+ const retryAfterHeader = getHeaderWithKey("retry-after");
51
+ if (retryAfterHeader) {
52
+ const [retryAfterKey, retryAfterValue] = retryAfterHeader;
53
+ const retryAfterNumeric = Number(retryAfterValue);
54
+ if (!Number.isNaN(retryAfterNumeric) && retryAfterNumeric >= 1000) {
55
+ headers[retryAfterKey] = new Date(Date.now() + retryAfterNumeric).toUTCString();
56
+ }
57
+ }
58
+ }
59
+ throw error;
60
+ }
61
+ }, {
62
+ name: "retryAfterHeaderNormalizationMiddleware",
63
+ step: "finalizeRequest",
64
+ priority: "low",
65
+ });
32
66
  if (configuration?.retryLogging) {
33
67
  this.middlewareStack.add((next) => async (args) => {
34
68
  const request = args.request;
@@ -49,8 +83,47 @@ export class ConversationsClient extends __Client {
49
83
  catch (error) {
50
84
  const statusCode = error?.$metadata?.httpStatusCode ?? error?.$response?.statusCode;
51
85
  const willRetry = attempt < maxAttempts && this.config.retryDecider(error);
86
+ const responseHeaders = (error?.$response?.headers ?? {});
87
+ const headerEntries = Object.entries(responseHeaders);
88
+ const getHeader = (...names) => {
89
+ const normalizedNames = names.map((name) => name.toLowerCase());
90
+ for (const [key, value] of headerEntries) {
91
+ if (normalizedNames.includes(key.toLowerCase())) {
92
+ return value;
93
+ }
94
+ }
95
+ return undefined;
96
+ };
97
+ const retryAfterRaw = getHeader("retry-after");
98
+ const rateLimitResetRaw = getHeader("x-ratelimit-reset", "ratelimit-reset", "rateLimitReset");
99
+ const rateLimitRaw = getHeader("x-ratelimit-limit", "ratelimit-limit", "rateLimit");
100
+ const rateLimitRemainingRaw = getHeader("x-ratelimit-remaining", "ratelimit-remaining", "rateLimitRemaining");
101
+ let retryAfterDelayMs;
102
+ if (retryAfterRaw !== undefined) {
103
+ const retryAfterNumeric = Number(retryAfterRaw);
104
+ if (!Number.isNaN(retryAfterNumeric)) {
105
+ retryAfterDelayMs = retryAfterNumeric >= 1000 ? retryAfterNumeric : retryAfterNumeric * 1000;
106
+ }
107
+ else {
108
+ retryAfterDelayMs = new Date(retryAfterRaw).getTime() - Date.now();
109
+ }
110
+ }
111
+ let rateLimitResetDelayMs;
112
+ if (rateLimitResetRaw !== undefined) {
113
+ const resetValue = Number(rateLimitResetRaw);
114
+ if (!Number.isNaN(resetValue)) {
115
+ if (resetValue > 1000000000) {
116
+ rateLimitResetDelayMs = (resetValue * 1000) - Date.now();
117
+ }
118
+ else {
119
+ rateLimitResetDelayMs = resetValue >= 1000 ? resetValue : resetValue * 1000;
120
+ }
121
+ }
122
+ }
52
123
  if (willRetry) {
53
124
  console.warn(`[ConversationsClient] Retry decision: will retry after attempt ${attempt}/${maxAttempts} (status=${statusCode ?? "unknown"}, time=${new Date().toISOString()})`);
125
+ console.warn(`[ConversationsClient] Retry headers: retry-after=${retryAfterRaw ?? "n/a"}, x-ratelimit-reset=${rateLimitResetRaw ?? "n/a"}, x-ratelimit-limit=${rateLimitRaw ?? "n/a"}, x-ratelimit-remaining=${rateLimitRemainingRaw ?? "n/a"}`);
126
+ console.warn(`[ConversationsClient] Parsed retry timing: retryAfterDelayMs=${retryAfterDelayMs ?? "n/a"}, rateLimitResetDelayMs=${rateLimitResetDelayMs ?? "n/a"}`);
54
127
  }
55
128
  else {
56
129
  console.warn(`[ConversationsClient] Retry decision: stop after attempt ${attempt}/${maxAttempts} (status=${statusCode ?? "unknown"}, time=${new Date().toISOString()})`);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wildix/xbees-conversations-client",
3
3
  "description": "@wildix/xbees-conversations-client client",
4
- "version": "1.2.7",
4
+ "version": "1.2.9",
5
5
  "scripts": {
6
6
  "build": "concurrently 'yarn:build:cjs' 'yarn:build:es' 'yarn:build:types'",
7
7
  "build:cjs": "tsc -p tsconfig.cjs.json",