@doist/twist-sdk 2.1.3 → 2.2.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 (47) hide show
  1. package/dist/cjs/authentication.js +5 -5
  2. package/dist/cjs/batch-builder.js +2 -2
  3. package/dist/cjs/clients/add-comment-helper.js +35 -0
  4. package/dist/cjs/clients/channels-client.js +14 -14
  5. package/dist/cjs/clients/comments-client.js +8 -21
  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 +54 -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/testUtils/msw-setup.js +1 -1
  17. package/dist/cjs/{rest-client.js → transport/fetch-with-retry.js} +108 -153
  18. package/dist/cjs/transport/http-client.js +108 -0
  19. package/dist/cjs/transport/http-dispatcher.js +128 -0
  20. package/dist/cjs/types/requests.js +3 -1
  21. package/dist/esm/authentication.js +1 -1
  22. package/dist/esm/batch-builder.js +1 -1
  23. package/dist/esm/clients/add-comment-helper.js +32 -0
  24. package/dist/esm/clients/channels-client.js +1 -1
  25. package/dist/esm/clients/comments-client.js +3 -16
  26. package/dist/esm/clients/conversation-messages-client.js +1 -1
  27. package/dist/esm/clients/conversations-client.js +1 -1
  28. package/dist/esm/clients/groups-client.js +1 -1
  29. package/dist/esm/clients/inbox-client.js +1 -1
  30. package/dist/esm/clients/reactions-client.js +1 -1
  31. package/dist/esm/clients/search-client.js +1 -1
  32. package/dist/esm/clients/threads-client.js +35 -2
  33. package/dist/esm/clients/users-client.js +1 -1
  34. package/dist/esm/clients/workspace-users-client.js +1 -1
  35. package/dist/esm/clients/workspaces-client.js +1 -1
  36. package/dist/esm/testUtils/msw-setup.js +1 -1
  37. package/dist/esm/{rest-client.js → transport/fetch-with-retry.js} +108 -150
  38. package/dist/esm/transport/http-client.js +103 -0
  39. package/dist/esm/transport/http-dispatcher.js +91 -0
  40. package/dist/esm/types/requests.js +2 -0
  41. package/dist/types/clients/add-comment-helper.d.ts +14 -0
  42. package/dist/types/clients/threads-client.d.ts +57 -2
  43. package/dist/types/transport/fetch-with-retry.d.ts +4 -0
  44. package/dist/types/{rest-client.d.ts → transport/http-client.d.ts} +1 -4
  45. package/dist/types/transport/http-dispatcher.d.ts +3 -0
  46. package/dist/types/types/requests.d.ts +18 -0
  47. package/package.json +1 -1
@@ -15,8 +15,9 @@ 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
+ import { addCommentRequest } from './add-comment-helper.js';
20
21
  import { BaseClient } from './base-client.js';
21
22
  /**
22
23
  * Client for interacting with Twist comment endpoints.
@@ -67,21 +68,7 @@ var CommentsClient = /** @class */ (function (_super) {
67
68
  }).then(function (response) { return wrappedSchema.parse(response.data); });
68
69
  };
69
70
  CommentsClient.prototype.createComment = function (args, options) {
70
- var method = 'POST';
71
- var url = "".concat(ENDPOINT_COMMENTS, "/add");
72
- var params = args;
73
- var schema = CommentSchema;
74
- if (options === null || options === void 0 ? void 0 : options.batch) {
75
- return { method: method, url: url, params: params, schema: schema };
76
- }
77
- return request({
78
- httpMethod: method,
79
- baseUri: this.getBaseUri(),
80
- relativePath: url,
81
- apiToken: this.apiToken,
82
- payload: params,
83
- customFetch: this.customFetch,
84
- }).then(function (response) { return schema.parse(response.data); });
71
+ return addCommentRequest({ baseUri: this.getBaseUri(), apiToken: this.apiToken, customFetch: this.customFetch }, args, options);
85
72
  };
86
73
  CommentsClient.prototype.updateComment = function (args, options) {
87
74
  var method = 'POST';
@@ -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
  /**
@@ -13,10 +13,33 @@ var __extends = (this && this.__extends) || (function () {
13
13
  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
14
14
  };
15
15
  })();
16
+ var __assign = (this && this.__assign) || function () {
17
+ __assign = Object.assign || function(t) {
18
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
19
+ s = arguments[i];
20
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
21
+ t[p] = s[p];
22
+ }
23
+ return t;
24
+ };
25
+ return __assign.apply(this, arguments);
26
+ };
27
+ var __rest = (this && this.__rest) || function (s, e) {
28
+ var t = {};
29
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
30
+ t[p] = s[p];
31
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
32
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
33
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
34
+ t[p[i]] = s[p[i]];
35
+ }
36
+ return t;
37
+ };
16
38
  import { z } from 'zod';
17
39
  import { ENDPOINT_THREADS } from '../consts/endpoints.js';
18
- import { request } from '../rest-client.js';
19
- import { ThreadSchema, UnreadThreadSchema } from '../types/entities.js';
40
+ import { request } from '../transport/http-client.js';
41
+ import { ThreadSchema, UnreadThreadSchema, } from '../types/entities.js';
42
+ import { addCommentRequest } from './add-comment-helper.js';
20
43
  import { BaseClient } from './base-client.js';
21
44
  /**
22
45
  * Client for interacting with Twist thread endpoints.
@@ -358,6 +381,16 @@ var ThreadsClient = /** @class */ (function (_super) {
358
381
  customFetch: this.customFetch,
359
382
  }).then(function (response) { return schema.parse(response.data); });
360
383
  };
384
+ ThreadsClient.prototype.closeThread = function (args, options) {
385
+ return this.addCommentWithAction(args, 'close', options);
386
+ };
387
+ ThreadsClient.prototype.reopenThread = function (args, options) {
388
+ return this.addCommentWithAction(args, 'reopen', options);
389
+ };
390
+ ThreadsClient.prototype.addCommentWithAction = function (args, threadAction, options) {
391
+ var id = args.id, rest = __rest(args, ["id"]);
392
+ return addCommentRequest({ baseUri: this.getBaseUri(), apiToken: this.apiToken, customFetch: this.customFetch }, __assign({ threadId: id }, rest), __assign(__assign({}, options), { threadAction: threadAction }));
393
+ };
361
394
  return ThreadsClient;
362
395
  }(BaseClient));
363
396
  export { ThreadsClient };
@@ -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
  /**
@@ -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
  }
@@ -0,0 +1,103 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
+ return new (P || (P = Promise))(function (resolve, reject) {
15
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
19
+ });
20
+ };
21
+ var __generator = (this && this.__generator) || function (thisArg, body) {
22
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
23
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24
+ function verb(n) { return function (v) { return step([n, v]); }; }
25
+ function step(op) {
26
+ if (f) throw new TypeError("Generator is already executing.");
27
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
28
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29
+ if (y = 0, t) op = [op[0] & 2, t.value];
30
+ switch (op[0]) {
31
+ case 0: case 1: t = op; break;
32
+ case 4: _.label++; return { value: op[1], done: false };
33
+ case 5: _.label++; y = op[1]; op = [0]; continue;
34
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
35
+ default:
36
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40
+ if (t[2]) _.ops.pop();
41
+ _.trys.pop(); continue;
42
+ }
43
+ op = body.call(thisArg, _);
44
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
+ }
47
+ };
48
+ import { snakeCaseKeys } from '../utils/case-conversion.js';
49
+ import { fetchWithRetry } from './fetch-with-retry.js';
50
+ export function paramsSerializer(params) {
51
+ var qs = new URLSearchParams();
52
+ Object.keys(params).forEach(function (key) {
53
+ var value = params[key];
54
+ if (value != null) {
55
+ if (Array.isArray(value)) {
56
+ qs.append(key, value.join(','));
57
+ }
58
+ else {
59
+ qs.append(key, String(value));
60
+ }
61
+ }
62
+ });
63
+ return qs.toString();
64
+ }
65
+ var defaultHeaders = {
66
+ 'Content-Type': 'application/json',
67
+ };
68
+ function getAuthHeader(apiToken) {
69
+ return "Bearer ".concat(apiToken);
70
+ }
71
+ function getRequestConfiguration(baseURL, apiToken, requestId) {
72
+ var authHeader = apiToken ? { Authorization: getAuthHeader(apiToken) } : undefined;
73
+ var requestIdHeader = requestId ? { 'X-Request-Id': requestId } : undefined;
74
+ var headers = __assign(__assign(__assign({}, defaultHeaders), authHeader), requestIdHeader);
75
+ return { baseURL: baseURL, headers: headers, timeout: 30000 };
76
+ }
77
+ export function request(args) {
78
+ return __awaiter(this, void 0, void 0, function () {
79
+ var httpMethod, baseUri, relativePath, apiToken, payload, requestId, customFetch, config, url, options, searchParams, urlWithParams;
80
+ return __generator(this, function (_a) {
81
+ httpMethod = args.httpMethod, baseUri = args.baseUri, relativePath = args.relativePath, apiToken = args.apiToken, payload = args.payload, requestId = args.requestId, customFetch = args.customFetch;
82
+ config = getRequestConfiguration(baseUri, apiToken, requestId);
83
+ url = new URL(relativePath, config.baseURL).toString();
84
+ options = {
85
+ method: httpMethod,
86
+ headers: config.headers,
87
+ timeout: config.timeout,
88
+ };
89
+ if (httpMethod === 'GET' && payload) {
90
+ searchParams = paramsSerializer(snakeCaseKeys(payload));
91
+ urlWithParams = searchParams ? "".concat(url, "?").concat(searchParams) : url;
92
+ return [2 /*return*/, fetchWithRetry(urlWithParams, options, 3, customFetch)];
93
+ }
94
+ if (payload && httpMethod !== 'GET') {
95
+ options.body = JSON.stringify(snakeCaseKeys(payload));
96
+ }
97
+ return [2 /*return*/, fetchWithRetry(url, options, 3, customFetch)];
98
+ });
99
+ });
100
+ }
101
+ export function isSuccess(response) {
102
+ return response.status >= 200 && response.status < 300;
103
+ }