@doist/twist-sdk 2.1.2 → 2.1.4

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 (58) hide show
  1. package/dist/cjs/authentication.js +90 -5
  2. package/dist/cjs/batch-builder.js +2 -2
  3. package/dist/cjs/clients/base-client.js +2 -1
  4. package/dist/cjs/clients/channels-client.js +14 -14
  5. package/dist/cjs/clients/comments-client.js +7 -7
  6. package/dist/cjs/clients/conversation-messages-client.js +6 -6
  7. package/dist/cjs/clients/conversations-client.js +16 -16
  8. package/dist/cjs/clients/groups-client.js +10 -10
  9. package/dist/cjs/clients/inbox-client.js +7 -7
  10. package/dist/cjs/clients/reactions-client.js +4 -4
  11. package/dist/cjs/clients/search-client.js +4 -4
  12. package/dist/cjs/clients/threads-client.js +21 -21
  13. package/dist/cjs/clients/users-client.js +15 -15
  14. package/dist/cjs/clients/workspace-users-client.js +11 -11
  15. package/dist/cjs/clients/workspaces-client.js +8 -8
  16. package/dist/cjs/consts/endpoints.js +3 -2
  17. package/dist/cjs/testUtils/msw-setup.js +1 -1
  18. package/dist/cjs/{rest-client.js → transport/fetch-with-retry.js} +108 -153
  19. package/dist/cjs/transport/http-client.js +108 -0
  20. package/dist/cjs/transport/http-dispatcher.js +128 -0
  21. package/dist/cjs/types/api-version.js +6 -0
  22. package/dist/cjs/types/entities.js +4 -4
  23. package/dist/cjs/types/http.js +2 -0
  24. package/dist/cjs/types/index.js +1 -0
  25. package/dist/esm/authentication.js +85 -1
  26. package/dist/esm/batch-builder.js +1 -1
  27. package/dist/esm/clients/base-client.js +2 -1
  28. package/dist/esm/clients/channels-client.js +1 -1
  29. package/dist/esm/clients/comments-client.js +1 -1
  30. package/dist/esm/clients/conversation-messages-client.js +1 -1
  31. package/dist/esm/clients/conversations-client.js +1 -1
  32. package/dist/esm/clients/groups-client.js +1 -1
  33. package/dist/esm/clients/inbox-client.js +1 -1
  34. package/dist/esm/clients/reactions-client.js +1 -1
  35. package/dist/esm/clients/search-client.js +1 -1
  36. package/dist/esm/clients/threads-client.js +1 -1
  37. package/dist/esm/clients/users-client.js +1 -1
  38. package/dist/esm/clients/workspace-users-client.js +1 -1
  39. package/dist/esm/clients/workspaces-client.js +1 -1
  40. package/dist/esm/consts/endpoints.js +3 -2
  41. package/dist/esm/testUtils/msw-setup.js +1 -1
  42. package/dist/esm/{rest-client.js → transport/fetch-with-retry.js} +108 -150
  43. package/dist/esm/transport/http-client.js +103 -0
  44. package/dist/esm/transport/http-dispatcher.js +91 -0
  45. package/dist/esm/types/api-version.js +5 -1
  46. package/dist/esm/types/entities.js +1 -1
  47. package/dist/esm/types/http.js +1 -1
  48. package/dist/esm/types/index.js +1 -0
  49. package/dist/types/authentication.d.ts +5 -1
  50. package/dist/types/consts/endpoints.d.ts +2 -2
  51. package/dist/types/transport/fetch-with-retry.d.ts +4 -0
  52. package/dist/types/{rest-client.d.ts → transport/http-client.d.ts} +1 -4
  53. package/dist/types/transport/http-dispatcher.d.ts +3 -0
  54. package/dist/types/types/api-version.d.ts +3 -1
  55. package/dist/types/types/entities.d.ts +25 -0
  56. package/dist/types/types/http.d.ts +2 -1
  57. package/dist/types/types/index.d.ts +1 -0
  58. package/package.json +1 -1
@@ -46,8 +46,92 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
46
46
  }
47
47
  };
48
48
  import { v4 as uuid } from 'uuid';
49
- import { isSuccess, request } from './rest-client.js';
49
+ import { isSuccess, request } from './transport/http-client.js';
50
50
  import { TwistRequestError } from './types/errors.js';
51
+ /**
52
+ * OAuth scopes for the Twist API.
53
+ *
54
+ * @remarks
55
+ * Request only the scopes your application needs:
56
+ *
57
+ * **User Scopes:**
58
+ * - `user:read` - Access user's personal settings
59
+ * - `user:write` - Access and update user's personal settings
60
+ *
61
+ * **Workspace Scopes:**
62
+ * - `workspaces:read` - Access teams the user is part of
63
+ * - `workspaces:write` - Access and update teams the user is part of
64
+ *
65
+ * **Channel Scopes:**
66
+ * - `channels:read` - Access channels
67
+ * - `channels:write` - Access and update channels
68
+ * - `channels:remove` - Access, update, and delete channels
69
+ *
70
+ * **Thread Scopes:**
71
+ * - `threads:read` - Access threads
72
+ * - `threads:write` - Access and update threads
73
+ * - `threads:remove` - Access, update, and delete threads
74
+ *
75
+ * **Comment Scopes:**
76
+ * - `comments:read` - Access comments
77
+ * - `comments:write` - Access and update comments
78
+ * - `comments:remove` - Access, update, and delete comments
79
+ *
80
+ * **Group Scopes:**
81
+ * - `groups:read` - Access groups
82
+ * - `groups:write` - Access and update groups
83
+ * - `groups:remove` - Access, update, and delete groups
84
+ *
85
+ * **Message Scopes:**
86
+ * - `messages:read` - Access messages
87
+ * - `messages:write` - Access and update messages
88
+ * - `messages:remove` - Access, update, and delete messages
89
+ *
90
+ * **Reaction Scopes:**
91
+ * - `reactions:read` - Access reactions
92
+ * - `reactions:write` - Access and update reactions
93
+ * - `reactions:remove` - Access, update, and delete reactions
94
+ *
95
+ * **Search Scopes:**
96
+ * - `search:read` - Search
97
+ *
98
+ * **Attachment Scopes:**
99
+ * - `attachments:read` - Access attachments
100
+ * - `attachments:write` - Access and update attachments
101
+ *
102
+ * **Notification Scopes:**
103
+ * - `notifications:read` - Read user's notifications settings
104
+ * - `notifications:write` - Read and update user's notifications settings
105
+ */
106
+ export var TWIST_SCOPES = [
107
+ 'user:read',
108
+ 'user:write',
109
+ 'workspaces:read',
110
+ 'workspaces:write',
111
+ 'channels:read',
112
+ 'channels:write',
113
+ 'channels:remove',
114
+ 'threads:read',
115
+ 'threads:write',
116
+ 'threads:remove',
117
+ 'comments:read',
118
+ 'comments:write',
119
+ 'comments:remove',
120
+ 'groups:read',
121
+ 'groups:write',
122
+ 'groups:remove',
123
+ 'messages:read',
124
+ 'messages:write',
125
+ 'messages:remove',
126
+ 'reactions:read',
127
+ 'reactions:write',
128
+ 'reactions:remove',
129
+ 'search:read',
130
+ 'attachments:read',
131
+ 'attachments:write',
132
+ 'notifications:read',
133
+ 'notifications:write',
134
+ ];
51
135
  export function getAuthStateParameter() {
52
136
  return uuid();
53
137
  }
@@ -60,7 +60,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
60
60
  };
61
61
  import { z } from 'zod';
62
62
  import { BaseClient } from './clients/base-client.js';
63
- import { fetchWithRetry } from './rest-client.js';
63
+ import { fetchWithRetry } from './transport/fetch-with-retry.js';
64
64
  import { camelCaseKeys, snakeCaseKeys } from './utils/case-conversion.js';
65
65
  import { transformTimestamps } from './utils/timestamp-conversion.js';
66
66
  /**
@@ -1,4 +1,5 @@
1
1
  import { getTwistBaseUri } from '../consts/endpoints.js';
2
+ import { DEFAULT_API_VERSION } from '../types/api-version.js';
2
3
  /**
3
4
  * Base client class that provides centralized URL management and configuration
4
5
  * for all Twist API clients. Fixes the trailing slash bug and eliminates code duplication.
@@ -7,7 +8,7 @@ var BaseClient = /** @class */ (function () {
7
8
  function BaseClient(config) {
8
9
  this.apiToken = config.apiToken;
9
10
  this.baseUrl = config.baseUrl;
10
- this.defaultVersion = config.version || 'v3';
11
+ this.defaultVersion = config.version || DEFAULT_API_VERSION;
11
12
  this.customFetch = config.customFetch;
12
13
  }
13
14
  /**
@@ -15,7 +15,7 @@ var __extends = (this && this.__extends) || (function () {
15
15
  })();
16
16
  import { z } from 'zod';
17
17
  import { ENDPOINT_CHANNELS } from '../consts/endpoints.js';
18
- import { request } from '../rest-client.js';
18
+ import { request } from '../transport/http-client.js';
19
19
  import { ChannelSchema } from '../types/entities.js';
20
20
  import { BaseClient } from './base-client.js';
21
21
  /**
@@ -15,7 +15,7 @@ var __extends = (this && this.__extends) || (function () {
15
15
  })();
16
16
  import { z } from 'zod';
17
17
  import { ENDPOINT_COMMENTS } from '../consts/endpoints.js';
18
- import { request } from '../rest-client.js';
18
+ import { request } from '../transport/http-client.js';
19
19
  import { CommentSchema } from '../types/entities.js';
20
20
  import { BaseClient } from './base-client.js';
21
21
  /**
@@ -15,7 +15,7 @@ var __extends = (this && this.__extends) || (function () {
15
15
  })();
16
16
  import { z } from 'zod';
17
17
  import { ENDPOINT_CONVERSATION_MESSAGES } from '../consts/endpoints.js';
18
- import { request } from '../rest-client.js';
18
+ import { request } from '../transport/http-client.js';
19
19
  import { ConversationMessageSchema } from '../types/entities.js';
20
20
  import { BaseClient } from './base-client.js';
21
21
  /**
@@ -15,7 +15,7 @@ var __extends = (this && this.__extends) || (function () {
15
15
  })();
16
16
  import { z } from 'zod';
17
17
  import { ENDPOINT_CONVERSATIONS } from '../consts/endpoints.js';
18
- import { request } from '../rest-client.js';
18
+ import { request } from '../transport/http-client.js';
19
19
  import { ConversationSchema, UnreadConversationSchema, } from '../types/entities.js';
20
20
  import { BaseClient } from './base-client.js';
21
21
  /**
@@ -14,7 +14,7 @@ var __extends = (this && this.__extends) || (function () {
14
14
  };
15
15
  })();
16
16
  import { ENDPOINT_GROUPS } from '../consts/endpoints.js';
17
- import { request } from '../rest-client.js';
17
+ import { request } from '../transport/http-client.js';
18
18
  import { GroupSchema } from '../types/entities.js';
19
19
  import { BaseClient } from './base-client.js';
20
20
  /**
@@ -15,7 +15,7 @@ var __extends = (this && this.__extends) || (function () {
15
15
  })();
16
16
  import { z } from 'zod';
17
17
  import { ENDPOINT_INBOX } from '../consts/endpoints.js';
18
- import { request } from '../rest-client.js';
18
+ import { request } from '../transport/http-client.js';
19
19
  import { InboxThreadSchema } from '../types/entities.js';
20
20
  import { BaseClient } from './base-client.js';
21
21
  /**
@@ -14,7 +14,7 @@ var __extends = (this && this.__extends) || (function () {
14
14
  };
15
15
  })();
16
16
  import { ENDPOINT_REACTIONS } from '../consts/endpoints.js';
17
- import { request } from '../rest-client.js';
17
+ import { request } from '../transport/http-client.js';
18
18
  import { BaseClient } from './base-client.js';
19
19
  /**
20
20
  * Client for interacting with Twist reaction endpoints.
@@ -25,7 +25,7 @@ var __assign = (this && this.__assign) || function () {
25
25
  return __assign.apply(this, arguments);
26
26
  };
27
27
  import { ENDPOINT_SEARCH } from '../consts/endpoints.js';
28
- import { request } from '../rest-client.js';
28
+ import { request } from '../transport/http-client.js';
29
29
  import { SearchResultSchema, } from '../types/entities.js';
30
30
  import { BaseClient } from './base-client.js';
31
31
  /**
@@ -15,7 +15,7 @@ var __extends = (this && this.__extends) || (function () {
15
15
  })();
16
16
  import { z } from 'zod';
17
17
  import { ENDPOINT_THREADS } from '../consts/endpoints.js';
18
- import { request } from '../rest-client.js';
18
+ import { request } from '../transport/http-client.js';
19
19
  import { ThreadSchema, UnreadThreadSchema } from '../types/entities.js';
20
20
  import { BaseClient } from './base-client.js';
21
21
  /**
@@ -14,7 +14,7 @@ var __extends = (this && this.__extends) || (function () {
14
14
  };
15
15
  })();
16
16
  import { ENDPOINT_USERS } from '../consts/endpoints.js';
17
- import { request } from '../rest-client.js';
17
+ import { request } from '../transport/http-client.js';
18
18
  import { UserSchema } from '../types/entities.js';
19
19
  import { BaseClient } from './base-client.js';
20
20
  /**
@@ -13,7 +13,7 @@ var __extends = (this && this.__extends) || (function () {
13
13
  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
14
14
  };
15
15
  })();
16
- import { request } from '../rest-client.js';
16
+ import { request } from '../transport/http-client.js';
17
17
  import { WorkspaceUserSchema } from '../types/entities.js';
18
18
  import { BaseClient } from './base-client.js';
19
19
  /**
@@ -14,7 +14,7 @@ var __extends = (this && this.__extends) || (function () {
14
14
  };
15
15
  })();
16
16
  import { ENDPOINT_WORKSPACES } from '../consts/endpoints.js';
17
- import { request } from '../rest-client.js';
17
+ import { request } from '../transport/http-client.js';
18
18
  import { ChannelSchema, WorkspaceSchema } from '../types/entities.js';
19
19
  import { BaseClient } from './base-client.js';
20
20
  /**
@@ -1,5 +1,6 @@
1
+ import { DEFAULT_API_VERSION } from '../types/api-version.js';
1
2
  var BASE_URI = 'https://api.twist.com';
2
- export var API_VERSION = 'v3';
3
+ export var API_VERSION = DEFAULT_API_VERSION;
3
4
  /**
4
5
  * @deprecated Use getTwistBaseUri() instead. This constant is kept for backward compatibility.
5
6
  */
@@ -12,7 +13,7 @@ export var API_BASE_URI = "/api/".concat(API_VERSION, "/");
12
13
  * @returns Complete base URI with trailing slash (e.g., 'https://api.twist.com/api/v3/')
13
14
  */
14
15
  export function getTwistBaseUri(version, domainBase) {
15
- if (version === void 0) { version = 'v3'; }
16
+ if (version === void 0) { version = DEFAULT_API_VERSION; }
16
17
  if (domainBase === void 0) { domainBase = BASE_URI; }
17
18
  return new URL("/api/".concat(version, "/"), domainBase).toString();
18
19
  }
@@ -4,7 +4,7 @@ import { afterAll, afterEach, beforeAll } from 'vitest';
4
4
  export var server = setupServer();
5
5
  // Start server before all tests
6
6
  beforeAll(function () {
7
- // Only warn on unhandled requests instead of error, since rest-client.test.ts
7
+ // Only warn on unhandled requests instead of error, since transport/http-client.test.ts
8
8
  // uses direct fetch mocking which bypasses MSW
9
9
  server.listen({ onUnhandledRequest: 'warn' });
10
10
  });
@@ -45,117 +45,26 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
45
45
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
46
  }
47
47
  };
48
- import { Agent } from 'undici';
49
- import { TwistRequestError } from './types/errors.js';
50
- import { camelCaseKeys, snakeCaseKeys } from './utils/case-conversion.js';
51
- import { transformTimestamps } from './utils/timestamp-conversion.js';
52
- /**
53
- * HTTP agent with keepAlive disabled to prevent hanging connections
54
- * This ensures the process exits immediately after requests complete
55
- */
56
- var httpAgent = new Agent({
57
- keepAliveTimeout: 1, // Close connections after 1ms of idle time
58
- keepAliveMaxTimeout: 1, // Maximum time to keep connections alive
59
- });
60
- export function paramsSerializer(params) {
61
- var qs = new URLSearchParams();
62
- Object.keys(params).forEach(function (key) {
63
- var value = params[key];
64
- if (value != null) {
65
- if (Array.isArray(value)) {
66
- qs.append(key, value.join(','));
67
- }
68
- else {
69
- qs.append(key, String(value));
70
- }
71
- }
72
- });
73
- return qs.toString();
74
- }
75
- var defaultHeaders = {
76
- 'Content-Type': 'application/json',
77
- };
78
- function getAuthHeader(apiToken) {
79
- return "Bearer ".concat(apiToken);
80
- }
81
- function getRequestConfiguration(baseURL, apiToken, requestId) {
82
- var authHeader = apiToken ? { Authorization: getAuthHeader(apiToken) } : undefined;
83
- var requestIdHeader = requestId ? { 'X-Request-Id': requestId } : undefined;
84
- var headers = __assign(__assign(__assign({}, defaultHeaders), authHeader), requestIdHeader);
85
- return { baseURL: baseURL, headers: headers, timeout: 30000 };
86
- }
87
- function sleep(ms) {
88
- return __awaiter(this, void 0, void 0, function () {
89
- return __generator(this, function (_a) {
90
- return [2 /*return*/, new Promise(function (resolve) { return setTimeout(resolve, ms); })];
91
- });
92
- });
93
- }
94
- function isNetworkError(error) {
95
- return error.name === 'TypeError' || error.message.toLowerCase().includes('network');
96
- }
97
- function getRetryDelay(retryCount) {
98
- return retryCount === 1 ? 0 : 500;
99
- }
100
- /**
101
- * Creates an AbortSignal that aborts after timeoutMs. Returns the signal and a
102
- * clear function to cancel the timeout early.
103
- */
104
- function createTimeoutSignal(timeoutMs, existingSignal) {
105
- var controller = new AbortController();
106
- var timeoutId = setTimeout(function () {
107
- controller.abort(new Error("Request timeout after ".concat(timeoutMs, "ms")));
108
- }, timeoutMs);
109
- function clear() {
110
- clearTimeout(timeoutId);
111
- }
112
- // Forward existing signal if provided
113
- if (existingSignal) {
114
- if (existingSignal.aborted) {
115
- controller.abort(existingSignal.reason);
116
- }
117
- else {
118
- existingSignal.addEventListener('abort', function () {
119
- controller.abort(existingSignal.reason);
120
- clear();
121
- }, { once: true });
122
- }
123
- }
124
- return { signal: controller.signal, clear: clear };
125
- }
126
- /**
127
- * Converts native fetch Response to CustomFetchResponse for consistent interface
128
- */
129
- function convertResponseToCustomFetch(response) {
130
- var headers = {};
131
- response.headers.forEach(function (value, key) {
132
- headers[key] = value;
133
- });
134
- return {
135
- ok: response.ok,
136
- status: response.status,
137
- statusText: response.statusText,
138
- headers: headers,
139
- text: function () { return response.clone().text(); },
140
- json: function () { return response.json(); },
141
- };
142
- }
48
+ import { TwistRequestError } from '../types/errors.js';
49
+ import { camelCaseKeys } from '../utils/case-conversion.js';
50
+ import { transformTimestamps } from '../utils/timestamp-conversion.js';
51
+ import { getDefaultDispatcher } from './http-dispatcher.js';
143
52
  export function fetchWithRetry(url_1, options_1) {
144
53
  return __awaiter(this, arguments, void 0, function (url, options, maxRetries, customFetch) {
145
- var lastError, attempt, clearTimeoutFn, requestSignal, timeoutResult, response, _a, _b, responseText, responseData, camelCased, transformed, error_1, delay;
146
- var _c;
54
+ var lastError, attempt, clearTimeoutFn, requestSignal, timeoutResult, response, _a, responseText, responseData, camelCased, transformed, error_1, delay;
55
+ var _b;
147
56
  if (maxRetries === void 0) { maxRetries = 3; }
148
- return __generator(this, function (_d) {
149
- switch (_d.label) {
57
+ return __generator(this, function (_c) {
58
+ switch (_c.label) {
150
59
  case 0:
151
60
  attempt = 0;
152
- _d.label = 1;
61
+ _c.label = 1;
153
62
  case 1:
154
63
  if (!(attempt <= maxRetries)) return [3 /*break*/, 13];
155
64
  clearTimeoutFn = void 0;
156
- _d.label = 2;
65
+ _c.label = 2;
157
66
  case 2:
158
- _d.trys.push([2, 8, , 12]);
67
+ _c.trys.push([2, 8, , 12]);
159
68
  requestSignal = options.signal || undefined;
160
69
  if (options.timeout && options.timeout > 0) {
161
70
  timeoutResult = createTimeoutSignal(options.timeout, requestSignal);
@@ -165,26 +74,22 @@ export function fetchWithRetry(url_1, options_1) {
165
74
  if (!customFetch) return [3 /*break*/, 4];
166
75
  return [4 /*yield*/, customFetch(url, options)];
167
76
  case 3:
168
- _a = _d.sent();
77
+ _a = _c.sent();
169
78
  return [3 /*break*/, 6];
170
- case 4:
171
- _b = convertResponseToCustomFetch;
172
- return [4 /*yield*/, fetch(url, __assign(__assign({}, options), { signal: requestSignal,
173
- // @ts-expect-error - dispatcher is valid for Node.js fetch but not in TS types
174
- dispatcher: httpAgent }))];
79
+ case 4: return [4 /*yield*/, fetchWithDefaultTransport(url, options, requestSignal)];
175
80
  case 5:
176
- _a = _b.apply(void 0, [_d.sent()]);
177
- _d.label = 6;
81
+ _a = _c.sent();
82
+ _c.label = 6;
178
83
  case 6:
179
84
  response = _a;
180
85
  return [4 /*yield*/, response.text()];
181
86
  case 7:
182
- responseText = _d.sent();
87
+ responseText = _c.sent();
183
88
  responseData = void 0;
184
89
  try {
185
90
  responseData = responseText ? JSON.parse(responseText) : undefined;
186
91
  }
187
- catch (_e) {
92
+ catch (_d) {
188
93
  responseData = responseText;
189
94
  }
190
95
  if (!response.ok) {
@@ -192,7 +97,6 @@ export function fetchWithRetry(url_1, options_1) {
192
97
  }
193
98
  camelCased = camelCaseKeys(responseData);
194
99
  transformed = transformTimestamps(camelCased);
195
- // Success – clear pending timeout (if any) so Node can exit promptly
196
100
  if (clearTimeoutFn) {
197
101
  clearTimeoutFn();
198
102
  }
@@ -202,27 +106,20 @@ export function fetchWithRetry(url_1, options_1) {
202
106
  headers: response.headers,
203
107
  }];
204
108
  case 8:
205
- error_1 = _d.sent();
109
+ error_1 = _c.sent();
110
+ if (clearTimeoutFn) {
111
+ clearTimeoutFn();
112
+ }
206
113
  lastError = error_1 instanceof Error ? error_1 : new Error('Unknown error');
207
114
  if (!(attempt < maxRetries && isNetworkError(lastError))) return [3 /*break*/, 11];
208
115
  delay = getRetryDelay(attempt + 1);
209
116
  if (!(delay > 0)) return [3 /*break*/, 10];
210
117
  return [4 /*yield*/, sleep(delay)];
211
118
  case 9:
212
- _d.sent();
213
- _d.label = 10;
214
- case 10:
215
- // Retry path ensure this attempt's timeout is cleared before looping
216
- if (clearTimeoutFn) {
217
- clearTimeoutFn();
218
- }
219
- return [3 /*break*/, 12];
220
- case 11:
221
- // Final error – clear timeout before throwing
222
- if (clearTimeoutFn) {
223
- clearTimeoutFn();
224
- }
225
- return [3 /*break*/, 13];
119
+ _c.sent();
120
+ _c.label = 10;
121
+ case 10: return [3 /*break*/, 12];
122
+ case 11: return [3 /*break*/, 13];
226
123
  case 12:
227
124
  attempt++;
228
125
  return [3 /*break*/, 1];
@@ -230,35 +127,96 @@ export function fetchWithRetry(url_1, options_1) {
230
127
  if (lastError instanceof TwistRequestError) {
231
128
  throw lastError;
232
129
  }
233
- throw new TwistRequestError((_c = lastError === null || lastError === void 0 ? void 0 : lastError.message) !== null && _c !== void 0 ? _c : 'Request failed');
130
+ throw new TwistRequestError((_b = lastError === null || lastError === void 0 ? void 0 : lastError.message) !== null && _b !== void 0 ? _b : 'Request failed');
234
131
  }
235
132
  });
236
133
  });
237
134
  }
238
- export function request(args) {
135
+ function fetchWithDefaultTransport(url, options, signal) {
239
136
  return __awaiter(this, void 0, void 0, function () {
240
- var httpMethod, baseUri, relativePath, apiToken, payload, requestId, customFetch, config, url, options, searchParams, urlWithParams;
241
- return __generator(this, function (_a) {
242
- httpMethod = args.httpMethod, baseUri = args.baseUri, relativePath = args.relativePath, apiToken = args.apiToken, payload = args.payload, requestId = args.requestId, customFetch = args.customFetch;
243
- config = getRequestConfiguration(baseUri, apiToken, requestId);
244
- url = new URL(relativePath, config.baseURL).toString();
245
- options = {
246
- method: httpMethod,
247
- headers: config.headers,
248
- timeout: config.timeout,
249
- };
250
- if (httpMethod === 'GET' && payload) {
251
- searchParams = paramsSerializer(snakeCaseKeys(payload));
252
- urlWithParams = searchParams ? "".concat(url, "?").concat(searchParams) : url;
253
- return [2 /*return*/, fetchWithRetry(urlWithParams, options, 3, customFetch)];
254
- }
255
- if (payload && httpMethod !== 'GET') {
256
- options.body = JSON.stringify(snakeCaseKeys(payload));
137
+ var dispatcher, response, _a;
138
+ return __generator(this, function (_b) {
139
+ switch (_b.label) {
140
+ case 0: return [4 /*yield*/, getDefaultDispatcher()];
141
+ case 1:
142
+ dispatcher = _b.sent();
143
+ if (!dispatcher) return [3 /*break*/, 3];
144
+ return [4 /*yield*/, fetch(url, __assign(__assign({}, options), { signal: signal,
145
+ // @ts-expect-error - dispatcher is valid for Node.js fetch but not in TS types
146
+ dispatcher: dispatcher }))];
147
+ case 2:
148
+ _a = _b.sent();
149
+ return [3 /*break*/, 5];
150
+ case 3: return [4 /*yield*/, fetch(url, __assign(__assign({}, options), { signal: signal }))];
151
+ case 4:
152
+ _a = _b.sent();
153
+ _b.label = 5;
154
+ case 5:
155
+ response = _a;
156
+ return [2 /*return*/, convertResponseToCustomFetch(response)];
257
157
  }
258
- return [2 /*return*/, fetchWithRetry(url, options, 3, customFetch)];
259
158
  });
260
159
  });
261
160
  }
262
- export function isSuccess(response) {
263
- return response.status >= 200 && response.status < 300;
161
+ function sleep(ms) {
162
+ return __awaiter(this, void 0, void 0, function () {
163
+ return __generator(this, function (_a) {
164
+ return [2 /*return*/, new Promise(function (resolve) { return setTimeout(resolve, ms); })];
165
+ });
166
+ });
167
+ }
168
+ var timeoutErrorName = 'TimeoutError';
169
+ function createTimeoutError(timeoutMs) {
170
+ var error = new Error("Request timeout after ".concat(timeoutMs, "ms"));
171
+ error.name = timeoutErrorName;
172
+ return error;
173
+ }
174
+ function isNetworkError(error) {
175
+ return (error.name === 'TypeError' ||
176
+ error.name === timeoutErrorName ||
177
+ error.message.toLowerCase().includes('network'));
178
+ }
179
+ function getRetryDelay(retryCount) {
180
+ return retryCount === 1 ? 0 : 500;
181
+ }
182
+ function createTimeoutSignal(timeoutMs, existingSignal) {
183
+ var controller = new AbortController();
184
+ var timeoutId = setTimeout(function () {
185
+ controller.abort(createTimeoutError(timeoutMs));
186
+ }, timeoutMs);
187
+ var abortHandler;
188
+ function clear() {
189
+ clearTimeout(timeoutId);
190
+ if (existingSignal && abortHandler) {
191
+ existingSignal.removeEventListener('abort', abortHandler);
192
+ }
193
+ }
194
+ if (existingSignal) {
195
+ if (existingSignal.aborted) {
196
+ clearTimeout(timeoutId);
197
+ controller.abort(existingSignal.reason);
198
+ }
199
+ else {
200
+ abortHandler = function () {
201
+ clearTimeout(timeoutId);
202
+ controller.abort(existingSignal.reason);
203
+ };
204
+ existingSignal.addEventListener('abort', abortHandler, { once: true });
205
+ }
206
+ }
207
+ return { signal: controller.signal, clear: clear };
208
+ }
209
+ function convertResponseToCustomFetch(response) {
210
+ var headers = {};
211
+ response.headers.forEach(function (value, key) {
212
+ headers[key] = value;
213
+ });
214
+ return {
215
+ ok: response.ok,
216
+ status: response.status,
217
+ statusText: response.statusText,
218
+ headers: headers,
219
+ text: function () { return response.clone().text(); },
220
+ json: function () { return response.json(); },
221
+ };
264
222
  }