@dispatchtickets/sdk 0.3.0 → 0.5.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.
- package/README.md +57 -9
- package/dist/index.cjs +397 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +509 -15
- package/dist/index.d.ts +509 -15
- package/dist/index.js +389 -67
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
package/dist/index.js
CHANGED
|
@@ -5,33 +5,45 @@ var DispatchTicketsError = class extends Error {
|
|
|
5
5
|
code;
|
|
6
6
|
statusCode;
|
|
7
7
|
details;
|
|
8
|
-
|
|
8
|
+
/** Request ID for debugging with support */
|
|
9
|
+
requestId;
|
|
10
|
+
constructor(message, code, statusCode, details, requestId) {
|
|
9
11
|
super(message);
|
|
10
12
|
this.name = "DispatchTicketsError";
|
|
11
13
|
this.code = code;
|
|
12
14
|
this.statusCode = statusCode;
|
|
13
15
|
this.details = details;
|
|
16
|
+
this.requestId = requestId;
|
|
14
17
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
15
18
|
}
|
|
16
19
|
};
|
|
17
20
|
var AuthenticationError = class extends DispatchTicketsError {
|
|
18
|
-
constructor(message = "Invalid or missing API key") {
|
|
19
|
-
super(message, "authentication_error", 401);
|
|
21
|
+
constructor(message = "Invalid or missing API key", requestId) {
|
|
22
|
+
super(message, "authentication_error", 401, void 0, requestId);
|
|
20
23
|
this.name = "AuthenticationError";
|
|
21
24
|
}
|
|
22
25
|
};
|
|
23
26
|
var RateLimitError = class extends DispatchTicketsError {
|
|
24
27
|
retryAfter;
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
/** Rate limit ceiling */
|
|
29
|
+
limit;
|
|
30
|
+
/** Remaining requests in current window */
|
|
31
|
+
remaining;
|
|
32
|
+
/** Unix timestamp when rate limit resets */
|
|
33
|
+
reset;
|
|
34
|
+
constructor(message = "Rate limit exceeded", retryAfter, requestId, rateLimitInfo) {
|
|
35
|
+
super(message, "rate_limit_error", 429, void 0, requestId);
|
|
27
36
|
this.name = "RateLimitError";
|
|
28
37
|
this.retryAfter = retryAfter;
|
|
38
|
+
this.limit = rateLimitInfo?.limit;
|
|
39
|
+
this.remaining = rateLimitInfo?.remaining;
|
|
40
|
+
this.reset = rateLimitInfo?.reset;
|
|
29
41
|
}
|
|
30
42
|
};
|
|
31
43
|
var ValidationError = class extends DispatchTicketsError {
|
|
32
44
|
errors;
|
|
33
|
-
constructor(message = "Validation failed", errors) {
|
|
34
|
-
super(message, "validation_error", 400, { errors });
|
|
45
|
+
constructor(message = "Validation failed", errors, requestId) {
|
|
46
|
+
super(message, "validation_error", 400, { errors }, requestId);
|
|
35
47
|
this.name = "ValidationError";
|
|
36
48
|
this.errors = errors;
|
|
37
49
|
}
|
|
@@ -39,22 +51,22 @@ var ValidationError = class extends DispatchTicketsError {
|
|
|
39
51
|
var NotFoundError = class extends DispatchTicketsError {
|
|
40
52
|
resourceType;
|
|
41
53
|
resourceId;
|
|
42
|
-
constructor(message = "Resource not found", resourceType, resourceId) {
|
|
43
|
-
super(message, "not_found", 404, { resourceType, resourceId });
|
|
54
|
+
constructor(message = "Resource not found", resourceType, resourceId, requestId) {
|
|
55
|
+
super(message, "not_found", 404, { resourceType, resourceId }, requestId);
|
|
44
56
|
this.name = "NotFoundError";
|
|
45
57
|
this.resourceType = resourceType;
|
|
46
58
|
this.resourceId = resourceId;
|
|
47
59
|
}
|
|
48
60
|
};
|
|
49
61
|
var ConflictError = class extends DispatchTicketsError {
|
|
50
|
-
constructor(message = "Resource conflict") {
|
|
51
|
-
super(message, "conflict", 409);
|
|
62
|
+
constructor(message = "Resource conflict", requestId) {
|
|
63
|
+
super(message, "conflict", 409, void 0, requestId);
|
|
52
64
|
this.name = "ConflictError";
|
|
53
65
|
}
|
|
54
66
|
};
|
|
55
67
|
var ServerError = class extends DispatchTicketsError {
|
|
56
|
-
constructor(message = "Internal server error", statusCode = 500) {
|
|
57
|
-
super(message, "server_error", statusCode);
|
|
68
|
+
constructor(message = "Internal server error", statusCode = 500, requestId) {
|
|
69
|
+
super(message, "server_error", statusCode, void 0, requestId);
|
|
58
70
|
this.name = "ServerError";
|
|
59
71
|
}
|
|
60
72
|
};
|
|
@@ -70,14 +82,68 @@ var NetworkError = class extends DispatchTicketsError {
|
|
|
70
82
|
this.name = "NetworkError";
|
|
71
83
|
}
|
|
72
84
|
};
|
|
85
|
+
function isDispatchTicketsError(error) {
|
|
86
|
+
return error instanceof DispatchTicketsError;
|
|
87
|
+
}
|
|
88
|
+
function isAuthenticationError(error) {
|
|
89
|
+
return error instanceof AuthenticationError;
|
|
90
|
+
}
|
|
91
|
+
function isRateLimitError(error) {
|
|
92
|
+
return error instanceof RateLimitError;
|
|
93
|
+
}
|
|
94
|
+
function isValidationError(error) {
|
|
95
|
+
return error instanceof ValidationError;
|
|
96
|
+
}
|
|
97
|
+
function isNotFoundError(error) {
|
|
98
|
+
return error instanceof NotFoundError;
|
|
99
|
+
}
|
|
100
|
+
function isConflictError(error) {
|
|
101
|
+
return error instanceof ConflictError;
|
|
102
|
+
}
|
|
103
|
+
function isServerError(error) {
|
|
104
|
+
return error instanceof ServerError;
|
|
105
|
+
}
|
|
106
|
+
function isTimeoutError(error) {
|
|
107
|
+
return error instanceof TimeoutError;
|
|
108
|
+
}
|
|
109
|
+
function isNetworkError(error) {
|
|
110
|
+
return error instanceof NetworkError;
|
|
111
|
+
}
|
|
73
112
|
|
|
74
113
|
// src/utils/http.ts
|
|
75
114
|
var HttpClient = class {
|
|
76
115
|
config;
|
|
77
116
|
fetchFn;
|
|
117
|
+
retryConfig;
|
|
118
|
+
/** Rate limit info from the last response */
|
|
119
|
+
_lastRateLimit;
|
|
120
|
+
/** Request ID from the last response */
|
|
121
|
+
_lastRequestId;
|
|
78
122
|
constructor(config) {
|
|
79
123
|
this.config = config;
|
|
80
124
|
this.fetchFn = config.fetch ?? fetch;
|
|
125
|
+
this.retryConfig = {
|
|
126
|
+
maxRetries: config.retry?.maxRetries ?? config.maxRetries,
|
|
127
|
+
retryableStatuses: config.retry?.retryableStatuses ?? [429, 500, 502, 503, 504],
|
|
128
|
+
retryOnNetworkError: config.retry?.retryOnNetworkError ?? true,
|
|
129
|
+
retryOnTimeout: config.retry?.retryOnTimeout ?? true,
|
|
130
|
+
initialDelayMs: config.retry?.initialDelayMs ?? 1e3,
|
|
131
|
+
maxDelayMs: config.retry?.maxDelayMs ?? 3e4,
|
|
132
|
+
backoffMultiplier: config.retry?.backoffMultiplier ?? 2,
|
|
133
|
+
jitter: config.retry?.jitter ?? 0.25
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Get rate limit info from the last response
|
|
138
|
+
*/
|
|
139
|
+
get lastRateLimit() {
|
|
140
|
+
return this._lastRateLimit;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get request ID from the last response
|
|
144
|
+
*/
|
|
145
|
+
get lastRequestId() {
|
|
146
|
+
return this._lastRequestId;
|
|
81
147
|
}
|
|
82
148
|
/**
|
|
83
149
|
* Execute an HTTP request with retry logic
|
|
@@ -87,43 +153,89 @@ var HttpClient = class {
|
|
|
87
153
|
const headers = this.buildHeaders(options.headers, options.idempotencyKey);
|
|
88
154
|
let lastError;
|
|
89
155
|
let attempt = 0;
|
|
90
|
-
while (attempt <= this.
|
|
156
|
+
while (attempt <= this.retryConfig.maxRetries) {
|
|
157
|
+
const requestContext = {
|
|
158
|
+
method: options.method,
|
|
159
|
+
url,
|
|
160
|
+
headers,
|
|
161
|
+
body: options.body,
|
|
162
|
+
attempt
|
|
163
|
+
};
|
|
91
164
|
try {
|
|
92
|
-
|
|
93
|
-
|
|
165
|
+
if (this.config.hooks?.onRequest) {
|
|
166
|
+
await this.config.hooks.onRequest(requestContext);
|
|
167
|
+
}
|
|
168
|
+
const startTime = Date.now();
|
|
169
|
+
const response = await this.executeRequest(
|
|
170
|
+
url,
|
|
171
|
+
options.method,
|
|
172
|
+
headers,
|
|
173
|
+
options.body,
|
|
174
|
+
options.signal
|
|
175
|
+
);
|
|
176
|
+
const durationMs = Date.now() - startTime;
|
|
177
|
+
const result = await this.handleResponse(response, requestContext, durationMs);
|
|
178
|
+
return result;
|
|
94
179
|
} catch (error) {
|
|
95
180
|
lastError = error;
|
|
96
|
-
if (
|
|
97
|
-
|
|
98
|
-
throw error;
|
|
99
|
-
}
|
|
100
|
-
if (error instanceof RateLimitError && error.retryAfter) {
|
|
101
|
-
if (attempt < this.config.maxRetries) {
|
|
102
|
-
await this.sleep(error.retryAfter * 1e3);
|
|
103
|
-
attempt++;
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
if (error instanceof ServerError) {
|
|
108
|
-
if (attempt < this.config.maxRetries) {
|
|
109
|
-
await this.sleep(this.calculateBackoff(attempt));
|
|
110
|
-
attempt++;
|
|
111
|
-
continue;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
181
|
+
if (this.config.hooks?.onError) {
|
|
182
|
+
await this.config.hooks.onError(lastError, requestContext);
|
|
114
183
|
}
|
|
115
|
-
if (
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
continue;
|
|
184
|
+
if (attempt < this.retryConfig.maxRetries && this.shouldRetry(lastError)) {
|
|
185
|
+
const delay = this.calculateDelay(lastError, attempt);
|
|
186
|
+
if (this.config.hooks?.onRetry) {
|
|
187
|
+
await this.config.hooks.onRetry(requestContext, lastError, delay);
|
|
120
188
|
}
|
|
189
|
+
await this.sleep(delay);
|
|
190
|
+
attempt++;
|
|
191
|
+
continue;
|
|
121
192
|
}
|
|
122
|
-
throw
|
|
193
|
+
throw lastError;
|
|
123
194
|
}
|
|
124
195
|
}
|
|
125
196
|
throw lastError || new NetworkError("Request failed after retries");
|
|
126
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* Execute request and return response with rate limit info
|
|
200
|
+
*/
|
|
201
|
+
async requestWithRateLimit(options) {
|
|
202
|
+
const data = await this.request(options);
|
|
203
|
+
return {
|
|
204
|
+
data,
|
|
205
|
+
rateLimit: this._lastRateLimit,
|
|
206
|
+
requestId: this._lastRequestId
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
shouldRetry(error) {
|
|
210
|
+
if (error instanceof AuthenticationError || error instanceof ValidationError || error instanceof NotFoundError || error instanceof ConflictError) {
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
if (error instanceof RateLimitError) {
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
if (error instanceof ServerError && error.statusCode) {
|
|
217
|
+
return this.retryConfig.retryableStatuses.includes(error.statusCode);
|
|
218
|
+
}
|
|
219
|
+
if (error instanceof NetworkError) {
|
|
220
|
+
return this.retryConfig.retryOnNetworkError;
|
|
221
|
+
}
|
|
222
|
+
if (error instanceof TimeoutError) {
|
|
223
|
+
return this.retryConfig.retryOnTimeout;
|
|
224
|
+
}
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
calculateDelay(error, attempt) {
|
|
228
|
+
if (error instanceof RateLimitError && error.retryAfter) {
|
|
229
|
+
return error.retryAfter * 1e3;
|
|
230
|
+
}
|
|
231
|
+
const baseDelay = this.retryConfig.initialDelayMs;
|
|
232
|
+
const delay = Math.min(
|
|
233
|
+
baseDelay * Math.pow(this.retryConfig.backoffMultiplier, attempt),
|
|
234
|
+
this.retryConfig.maxDelayMs
|
|
235
|
+
);
|
|
236
|
+
const jitter = delay * this.retryConfig.jitter * Math.random();
|
|
237
|
+
return delay + jitter;
|
|
238
|
+
}
|
|
127
239
|
buildUrl(path, query) {
|
|
128
240
|
const url = new URL(path, this.config.baseUrl);
|
|
129
241
|
if (query) {
|
|
@@ -147,9 +259,11 @@ var HttpClient = class {
|
|
|
147
259
|
}
|
|
148
260
|
return headers;
|
|
149
261
|
}
|
|
150
|
-
async executeRequest(url, method, headers, body) {
|
|
262
|
+
async executeRequest(url, method, headers, body, userSignal) {
|
|
151
263
|
const controller = new AbortController();
|
|
152
264
|
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
265
|
+
const abortHandler = () => controller.abort();
|
|
266
|
+
userSignal?.addEventListener("abort", abortHandler);
|
|
153
267
|
try {
|
|
154
268
|
if (this.config.debug) {
|
|
155
269
|
console.log(`[DispatchTickets] ${method} ${url}`);
|
|
@@ -157,6 +271,9 @@ var HttpClient = class {
|
|
|
157
271
|
console.log("[DispatchTickets] Body:", JSON.stringify(body, null, 2));
|
|
158
272
|
}
|
|
159
273
|
}
|
|
274
|
+
if (userSignal?.aborted) {
|
|
275
|
+
throw new Error("Request aborted");
|
|
276
|
+
}
|
|
160
277
|
const response = await this.fetchFn(url, {
|
|
161
278
|
method,
|
|
162
279
|
headers,
|
|
@@ -167,6 +284,9 @@ var HttpClient = class {
|
|
|
167
284
|
} catch (error) {
|
|
168
285
|
if (error instanceof Error) {
|
|
169
286
|
if (error.name === "AbortError") {
|
|
287
|
+
if (userSignal?.aborted) {
|
|
288
|
+
throw new NetworkError("Request aborted by user");
|
|
289
|
+
}
|
|
170
290
|
throw new TimeoutError(`Request timed out after ${this.config.timeout}ms`);
|
|
171
291
|
}
|
|
172
292
|
throw new NetworkError(error.message);
|
|
@@ -174,11 +294,42 @@ var HttpClient = class {
|
|
|
174
294
|
throw new NetworkError("Unknown network error");
|
|
175
295
|
} finally {
|
|
176
296
|
clearTimeout(timeoutId);
|
|
297
|
+
userSignal?.removeEventListener("abort", abortHandler);
|
|
177
298
|
}
|
|
178
299
|
}
|
|
179
|
-
|
|
300
|
+
extractRateLimitInfo(response) {
|
|
301
|
+
const limit = response.headers.get("x-ratelimit-limit");
|
|
302
|
+
const remaining = response.headers.get("x-ratelimit-remaining");
|
|
303
|
+
const reset = response.headers.get("x-ratelimit-reset");
|
|
304
|
+
if (limit && remaining && reset) {
|
|
305
|
+
return {
|
|
306
|
+
limit: parseInt(limit, 10),
|
|
307
|
+
remaining: parseInt(remaining, 10),
|
|
308
|
+
reset: parseInt(reset, 10)
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
return void 0;
|
|
312
|
+
}
|
|
313
|
+
async handleResponse(response, requestContext, durationMs) {
|
|
180
314
|
const contentType = response.headers.get("content-type");
|
|
181
315
|
const isJson = contentType?.includes("application/json");
|
|
316
|
+
const requestId = response.headers.get("x-request-id") ?? void 0;
|
|
317
|
+
const rateLimitInfo = this.extractRateLimitInfo(response);
|
|
318
|
+
this._lastRequestId = requestId;
|
|
319
|
+
this._lastRateLimit = rateLimitInfo;
|
|
320
|
+
if (this.config.debug && requestId) {
|
|
321
|
+
console.log(`[DispatchTickets] Request ID: ${requestId}`);
|
|
322
|
+
}
|
|
323
|
+
if (response.ok && this.config.hooks?.onResponse) {
|
|
324
|
+
await this.config.hooks.onResponse({
|
|
325
|
+
request: requestContext,
|
|
326
|
+
status: response.status,
|
|
327
|
+
headers: response.headers,
|
|
328
|
+
requestId,
|
|
329
|
+
rateLimit: rateLimitInfo,
|
|
330
|
+
durationMs
|
|
331
|
+
});
|
|
332
|
+
}
|
|
182
333
|
if (response.ok) {
|
|
183
334
|
if (response.status === 204 || !isJson) {
|
|
184
335
|
return void 0;
|
|
@@ -195,31 +346,36 @@ var HttpClient = class {
|
|
|
195
346
|
const message = errorData.message || errorData.error || response.statusText;
|
|
196
347
|
switch (response.status) {
|
|
197
348
|
case 401:
|
|
198
|
-
throw new AuthenticationError(message);
|
|
349
|
+
throw new AuthenticationError(message, requestId);
|
|
199
350
|
case 400:
|
|
200
351
|
case 422:
|
|
201
|
-
throw new ValidationError(message, errorData.errors);
|
|
352
|
+
throw new ValidationError(message, errorData.errors, requestId);
|
|
202
353
|
case 404:
|
|
203
|
-
throw new NotFoundError(message);
|
|
354
|
+
throw new NotFoundError(message, void 0, void 0, requestId);
|
|
204
355
|
case 409:
|
|
205
|
-
throw new ConflictError(message);
|
|
356
|
+
throw new ConflictError(message, requestId);
|
|
206
357
|
case 429: {
|
|
207
358
|
const retryAfter = response.headers.get("retry-after");
|
|
208
|
-
throw new RateLimitError(
|
|
359
|
+
throw new RateLimitError(
|
|
360
|
+
message,
|
|
361
|
+
retryAfter ? parseInt(retryAfter, 10) : void 0,
|
|
362
|
+
requestId,
|
|
363
|
+
rateLimitInfo
|
|
364
|
+
);
|
|
209
365
|
}
|
|
210
366
|
default:
|
|
211
367
|
if (response.status >= 500) {
|
|
212
|
-
throw new ServerError(message, response.status);
|
|
368
|
+
throw new ServerError(message, response.status, requestId);
|
|
213
369
|
}
|
|
214
|
-
throw new DispatchTicketsError(
|
|
370
|
+
throw new DispatchTicketsError(
|
|
371
|
+
message,
|
|
372
|
+
"api_error",
|
|
373
|
+
response.status,
|
|
374
|
+
errorData,
|
|
375
|
+
requestId
|
|
376
|
+
);
|
|
215
377
|
}
|
|
216
378
|
}
|
|
217
|
-
calculateBackoff(attempt) {
|
|
218
|
-
const baseDelay = 1e3;
|
|
219
|
-
const maxDelay = 3e4;
|
|
220
|
-
const delay = Math.min(baseDelay * Math.pow(2, attempt), maxDelay);
|
|
221
|
-
return delay + Math.random() * delay * 0.25;
|
|
222
|
-
}
|
|
223
379
|
sleep(ms) {
|
|
224
380
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
225
381
|
}
|
|
@@ -231,11 +387,12 @@ var BaseResource = class {
|
|
|
231
387
|
constructor(http) {
|
|
232
388
|
this.http = http;
|
|
233
389
|
}
|
|
234
|
-
async _get(path, query) {
|
|
390
|
+
async _get(path, query, options) {
|
|
235
391
|
return this.http.request({
|
|
236
392
|
method: "GET",
|
|
237
393
|
path,
|
|
238
|
-
query
|
|
394
|
+
query,
|
|
395
|
+
signal: options?.signal
|
|
239
396
|
});
|
|
240
397
|
}
|
|
241
398
|
async _post(path, body, options) {
|
|
@@ -244,28 +401,32 @@ var BaseResource = class {
|
|
|
244
401
|
path,
|
|
245
402
|
body,
|
|
246
403
|
idempotencyKey: options?.idempotencyKey,
|
|
247
|
-
query: options?.query
|
|
404
|
+
query: options?.query,
|
|
405
|
+
signal: options?.signal
|
|
248
406
|
});
|
|
249
407
|
}
|
|
250
|
-
async _patch(path, body) {
|
|
408
|
+
async _patch(path, body, options) {
|
|
251
409
|
return this.http.request({
|
|
252
410
|
method: "PATCH",
|
|
253
411
|
path,
|
|
254
|
-
body
|
|
412
|
+
body,
|
|
413
|
+
signal: options?.signal
|
|
255
414
|
});
|
|
256
415
|
}
|
|
257
|
-
async _put(path, body) {
|
|
416
|
+
async _put(path, body, options) {
|
|
258
417
|
return this.http.request({
|
|
259
418
|
method: "PUT",
|
|
260
419
|
path,
|
|
261
|
-
body
|
|
420
|
+
body,
|
|
421
|
+
signal: options?.signal
|
|
262
422
|
});
|
|
263
423
|
}
|
|
264
|
-
async _delete(path, query) {
|
|
424
|
+
async _delete(path, query, options) {
|
|
265
425
|
return this.http.request({
|
|
266
426
|
method: "DELETE",
|
|
267
427
|
path,
|
|
268
|
-
query
|
|
428
|
+
query,
|
|
429
|
+
signal: options?.signal
|
|
269
430
|
});
|
|
270
431
|
}
|
|
271
432
|
};
|
|
@@ -904,48 +1065,207 @@ var DispatchTickets = class {
|
|
|
904
1065
|
http;
|
|
905
1066
|
/**
|
|
906
1067
|
* Accounts resource for managing the current account and API keys
|
|
1068
|
+
*
|
|
1069
|
+
* @example
|
|
1070
|
+
* ```typescript
|
|
1071
|
+
* // Get current account
|
|
1072
|
+
* const account = await client.accounts.me();
|
|
1073
|
+
*
|
|
1074
|
+
* // Get usage statistics
|
|
1075
|
+
* const usage = await client.accounts.getUsage();
|
|
1076
|
+
*
|
|
1077
|
+
* // Create a new API key
|
|
1078
|
+
* const newKey = await client.accounts.createApiKey({
|
|
1079
|
+
* name: 'Production',
|
|
1080
|
+
* allBrands: true,
|
|
1081
|
+
* });
|
|
1082
|
+
* ```
|
|
907
1083
|
*/
|
|
908
1084
|
accounts;
|
|
909
1085
|
/**
|
|
910
1086
|
* Brands (workspaces) resource
|
|
1087
|
+
*
|
|
1088
|
+
* Brands are isolated containers for tickets. Each brand can have its own
|
|
1089
|
+
* email address, categories, tags, and settings.
|
|
1090
|
+
*
|
|
1091
|
+
* @example
|
|
1092
|
+
* ```typescript
|
|
1093
|
+
* // List all brands
|
|
1094
|
+
* const brands = await client.brands.list();
|
|
1095
|
+
*
|
|
1096
|
+
* // Create a new brand
|
|
1097
|
+
* const brand = await client.brands.create({
|
|
1098
|
+
* name: 'Acme Support',
|
|
1099
|
+
* slug: 'acme',
|
|
1100
|
+
* });
|
|
1101
|
+
*
|
|
1102
|
+
* // Get inbound email address
|
|
1103
|
+
* const email = client.brands.getInboundEmail('br_abc123');
|
|
1104
|
+
* // Returns: br_abc123@inbound.dispatchtickets.com
|
|
1105
|
+
* ```
|
|
911
1106
|
*/
|
|
912
1107
|
brands;
|
|
913
1108
|
/**
|
|
914
1109
|
* Tickets resource
|
|
1110
|
+
*
|
|
1111
|
+
* @example
|
|
1112
|
+
* ```typescript
|
|
1113
|
+
* // Create a ticket
|
|
1114
|
+
* const ticket = await client.tickets.create('ws_abc123', {
|
|
1115
|
+
* title: 'Issue with billing',
|
|
1116
|
+
* body: 'I was charged twice...',
|
|
1117
|
+
* priority: 'high',
|
|
1118
|
+
* });
|
|
1119
|
+
*
|
|
1120
|
+
* // Iterate through all tickets
|
|
1121
|
+
* for await (const ticket of client.tickets.list('ws_abc123', { status: 'open' })) {
|
|
1122
|
+
* console.log(ticket.title);
|
|
1123
|
+
* }
|
|
1124
|
+
* ```
|
|
915
1125
|
*/
|
|
916
1126
|
tickets;
|
|
917
1127
|
/**
|
|
918
1128
|
* Comments resource
|
|
1129
|
+
*
|
|
1130
|
+
* @example
|
|
1131
|
+
* ```typescript
|
|
1132
|
+
* // Add a comment
|
|
1133
|
+
* const comment = await client.comments.create('ws_abc123', 'tkt_xyz', {
|
|
1134
|
+
* body: 'Thanks for your patience!',
|
|
1135
|
+
* authorType: 'AGENT',
|
|
1136
|
+
* });
|
|
1137
|
+
*
|
|
1138
|
+
* // List comments
|
|
1139
|
+
* const comments = await client.comments.list('ws_abc123', 'tkt_xyz');
|
|
1140
|
+
* ```
|
|
919
1141
|
*/
|
|
920
1142
|
comments;
|
|
921
1143
|
/**
|
|
922
1144
|
* Attachments resource
|
|
1145
|
+
*
|
|
1146
|
+
* @example
|
|
1147
|
+
* ```typescript
|
|
1148
|
+
* // Simple upload
|
|
1149
|
+
* const attachment = await client.attachments.upload(
|
|
1150
|
+
* 'ws_abc123',
|
|
1151
|
+
* 'tkt_xyz',
|
|
1152
|
+
* fileBuffer,
|
|
1153
|
+
* 'document.pdf',
|
|
1154
|
+
* 'application/pdf'
|
|
1155
|
+
* );
|
|
1156
|
+
*
|
|
1157
|
+
* // Get download URL
|
|
1158
|
+
* const { downloadUrl } = await client.attachments.get('ws_abc123', 'tkt_xyz', 'att_abc');
|
|
1159
|
+
* ```
|
|
923
1160
|
*/
|
|
924
1161
|
attachments;
|
|
925
1162
|
/**
|
|
926
1163
|
* Webhooks resource
|
|
1164
|
+
*
|
|
1165
|
+
* @example
|
|
1166
|
+
* ```typescript
|
|
1167
|
+
* // Create a webhook
|
|
1168
|
+
* const webhook = await client.webhooks.create('ws_abc123', {
|
|
1169
|
+
* url: 'https://example.com/webhook',
|
|
1170
|
+
* secret: 'your-secret',
|
|
1171
|
+
* events: ['ticket.created', 'ticket.updated'],
|
|
1172
|
+
* });
|
|
1173
|
+
* ```
|
|
927
1174
|
*/
|
|
928
1175
|
webhooks;
|
|
929
1176
|
/**
|
|
930
1177
|
* Categories resource
|
|
1178
|
+
*
|
|
1179
|
+
* @example
|
|
1180
|
+
* ```typescript
|
|
1181
|
+
* // Create a category
|
|
1182
|
+
* await client.categories.create('ws_abc123', { name: 'Billing', color: '#ef4444' });
|
|
1183
|
+
*
|
|
1184
|
+
* // Get category stats
|
|
1185
|
+
* const stats = await client.categories.getStats('ws_abc123');
|
|
1186
|
+
* ```
|
|
931
1187
|
*/
|
|
932
1188
|
categories;
|
|
933
1189
|
/**
|
|
934
1190
|
* Tags resource
|
|
1191
|
+
*
|
|
1192
|
+
* @example
|
|
1193
|
+
* ```typescript
|
|
1194
|
+
* // Create a tag
|
|
1195
|
+
* await client.tags.create('ws_abc123', { name: 'urgent', color: '#f59e0b' });
|
|
1196
|
+
*
|
|
1197
|
+
* // Merge tags
|
|
1198
|
+
* await client.tags.merge('ws_abc123', 'tag_target', ['tag_source1', 'tag_source2']);
|
|
1199
|
+
* ```
|
|
935
1200
|
*/
|
|
936
1201
|
tags;
|
|
937
1202
|
/**
|
|
938
1203
|
* Customers resource
|
|
1204
|
+
*
|
|
1205
|
+
* @example
|
|
1206
|
+
* ```typescript
|
|
1207
|
+
* // Create a customer
|
|
1208
|
+
* const customer = await client.customers.create('ws_abc123', {
|
|
1209
|
+
* email: 'user@example.com',
|
|
1210
|
+
* name: 'Jane Doe',
|
|
1211
|
+
* });
|
|
1212
|
+
*
|
|
1213
|
+
* // Search customers
|
|
1214
|
+
* const results = await client.customers.search('ws_abc123', 'jane');
|
|
1215
|
+
* ```
|
|
939
1216
|
*/
|
|
940
1217
|
customers;
|
|
941
1218
|
/**
|
|
942
1219
|
* Custom fields resource
|
|
1220
|
+
*
|
|
1221
|
+
* @example
|
|
1222
|
+
* ```typescript
|
|
1223
|
+
* // Get all field definitions
|
|
1224
|
+
* const fields = await client.fields.getAll('ws_abc123');
|
|
1225
|
+
*
|
|
1226
|
+
* // Create a field
|
|
1227
|
+
* await client.fields.create('ws_abc123', 'ticket', {
|
|
1228
|
+
* key: 'order_id',
|
|
1229
|
+
* label: 'Order ID',
|
|
1230
|
+
* type: 'text',
|
|
1231
|
+
* required: true,
|
|
1232
|
+
* });
|
|
1233
|
+
* ```
|
|
943
1234
|
*/
|
|
944
1235
|
fields;
|
|
945
1236
|
/**
|
|
946
1237
|
* Static webhook utilities
|
|
1238
|
+
*
|
|
1239
|
+
* @example
|
|
1240
|
+
* ```typescript
|
|
1241
|
+
* // Verify webhook signature
|
|
1242
|
+
* const isValid = DispatchTickets.webhooks.verifySignature(
|
|
1243
|
+
* rawBody,
|
|
1244
|
+
* req.headers['x-dispatch-signature'],
|
|
1245
|
+
* 'your-secret'
|
|
1246
|
+
* );
|
|
1247
|
+
*
|
|
1248
|
+
* // Generate signature for testing
|
|
1249
|
+
* const signature = DispatchTickets.webhooks.generateSignature(
|
|
1250
|
+
* JSON.stringify(payload),
|
|
1251
|
+
* 'your-secret'
|
|
1252
|
+
* );
|
|
1253
|
+
* ```
|
|
947
1254
|
*/
|
|
948
1255
|
static webhooks = webhookUtils;
|
|
1256
|
+
/**
|
|
1257
|
+
* Create a new Dispatch Tickets client
|
|
1258
|
+
*
|
|
1259
|
+
* @param config - Client configuration options
|
|
1260
|
+
* @throws Error if API key is not provided
|
|
1261
|
+
*
|
|
1262
|
+
* @example
|
|
1263
|
+
* ```typescript
|
|
1264
|
+
* const client = new DispatchTickets({
|
|
1265
|
+
* apiKey: 'sk_live_...',
|
|
1266
|
+
* });
|
|
1267
|
+
* ```
|
|
1268
|
+
*/
|
|
949
1269
|
constructor(config) {
|
|
950
1270
|
if (!config.apiKey) {
|
|
951
1271
|
throw new Error("API key is required");
|
|
@@ -954,9 +1274,11 @@ var DispatchTickets = class {
|
|
|
954
1274
|
baseUrl: config.baseUrl || "https://dispatch-tickets-api.onrender.com/v1",
|
|
955
1275
|
apiKey: config.apiKey,
|
|
956
1276
|
timeout: config.timeout ?? 3e4,
|
|
957
|
-
maxRetries: config.maxRetries ?? 3,
|
|
1277
|
+
maxRetries: config.maxRetries ?? config.retry?.maxRetries ?? 3,
|
|
958
1278
|
debug: config.debug ?? false,
|
|
959
|
-
fetch: config.fetch
|
|
1279
|
+
fetch: config.fetch,
|
|
1280
|
+
retry: config.retry,
|
|
1281
|
+
hooks: config.hooks
|
|
960
1282
|
};
|
|
961
1283
|
this.http = new HttpClient(httpConfig);
|
|
962
1284
|
this.accounts = new AccountsResource(this.http);
|
|
@@ -1012,6 +1334,6 @@ async function collectAll(iterable) {
|
|
|
1012
1334
|
return items;
|
|
1013
1335
|
}
|
|
1014
1336
|
|
|
1015
|
-
export { AuthenticationError, ConflictError, DispatchTickets, DispatchTicketsError, NetworkError, NotFoundError, RateLimitError, ServerError, TimeoutError, ValidationError, collectAll, isCommentCreatedEvent, isTicketCreatedEvent, isTicketUpdatedEvent, parseWebhookEvent, webhookUtils };
|
|
1337
|
+
export { AuthenticationError, ConflictError, DispatchTickets, DispatchTicketsError, NetworkError, NotFoundError, RateLimitError, ServerError, TimeoutError, ValidationError, collectAll, isAuthenticationError, isCommentCreatedEvent, isConflictError, isDispatchTicketsError, isNetworkError, isNotFoundError, isRateLimitError, isServerError, isTicketCreatedEvent, isTicketUpdatedEvent, isTimeoutError, isValidationError, parseWebhookEvent, webhookUtils };
|
|
1016
1338
|
//# sourceMappingURL=index.js.map
|
|
1017
1339
|
//# sourceMappingURL=index.js.map
|