@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.d.ts
CHANGED
|
@@ -2,6 +2,105 @@
|
|
|
2
2
|
* Custom fetch function type
|
|
3
3
|
*/
|
|
4
4
|
type FetchFunction = typeof fetch;
|
|
5
|
+
/**
|
|
6
|
+
* Request context passed to hooks
|
|
7
|
+
*/
|
|
8
|
+
interface RequestContext {
|
|
9
|
+
/** HTTP method */
|
|
10
|
+
method: string;
|
|
11
|
+
/** Full URL being requested */
|
|
12
|
+
url: string;
|
|
13
|
+
/** Request headers */
|
|
14
|
+
headers: Record<string, string>;
|
|
15
|
+
/** Request body (if any) */
|
|
16
|
+
body?: unknown;
|
|
17
|
+
/** Retry attempt number (0 = first attempt) */
|
|
18
|
+
attempt: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Response context passed to hooks
|
|
22
|
+
*/
|
|
23
|
+
interface ResponseContext {
|
|
24
|
+
/** The request that was made */
|
|
25
|
+
request: RequestContext;
|
|
26
|
+
/** HTTP status code */
|
|
27
|
+
status: number;
|
|
28
|
+
/** Response headers */
|
|
29
|
+
headers: Headers;
|
|
30
|
+
/** Request ID from server */
|
|
31
|
+
requestId?: string;
|
|
32
|
+
/** Rate limit info from server */
|
|
33
|
+
rateLimit?: RateLimitInfo;
|
|
34
|
+
/** Duration of the request in milliseconds */
|
|
35
|
+
durationMs: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Retry configuration options
|
|
39
|
+
*/
|
|
40
|
+
interface RetryConfig {
|
|
41
|
+
/**
|
|
42
|
+
* Maximum number of retry attempts
|
|
43
|
+
* @default 3
|
|
44
|
+
*/
|
|
45
|
+
maxRetries?: number;
|
|
46
|
+
/**
|
|
47
|
+
* HTTP status codes that should trigger a retry
|
|
48
|
+
* @default [429, 500, 502, 503, 504]
|
|
49
|
+
*/
|
|
50
|
+
retryableStatuses?: number[];
|
|
51
|
+
/**
|
|
52
|
+
* Whether to retry on network errors
|
|
53
|
+
* @default true
|
|
54
|
+
*/
|
|
55
|
+
retryOnNetworkError?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Whether to retry on timeout errors
|
|
58
|
+
* @default true
|
|
59
|
+
*/
|
|
60
|
+
retryOnTimeout?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Initial delay between retries in milliseconds
|
|
63
|
+
* @default 1000
|
|
64
|
+
*/
|
|
65
|
+
initialDelayMs?: number;
|
|
66
|
+
/**
|
|
67
|
+
* Maximum delay between retries in milliseconds
|
|
68
|
+
* @default 30000
|
|
69
|
+
*/
|
|
70
|
+
maxDelayMs?: number;
|
|
71
|
+
/**
|
|
72
|
+
* Multiplier for exponential backoff
|
|
73
|
+
* @default 2
|
|
74
|
+
*/
|
|
75
|
+
backoffMultiplier?: number;
|
|
76
|
+
/**
|
|
77
|
+
* Jitter factor (0-1) to add randomness to delays
|
|
78
|
+
* @default 0.25
|
|
79
|
+
*/
|
|
80
|
+
jitter?: number;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Hooks for observability and customization
|
|
84
|
+
*/
|
|
85
|
+
interface Hooks {
|
|
86
|
+
/**
|
|
87
|
+
* Called before each request is sent
|
|
88
|
+
* Can modify the request or throw to abort
|
|
89
|
+
*/
|
|
90
|
+
onRequest?: (context: RequestContext) => void | Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Called after each successful response
|
|
93
|
+
*/
|
|
94
|
+
onResponse?: (context: ResponseContext) => void | Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Called when an error occurs (before retry)
|
|
97
|
+
*/
|
|
98
|
+
onError?: (error: Error, context: RequestContext) => void | Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Called before each retry attempt
|
|
101
|
+
*/
|
|
102
|
+
onRetry?: (context: RequestContext, error: Error, delayMs: number) => void | Promise<void>;
|
|
103
|
+
}
|
|
5
104
|
interface HttpClientConfig {
|
|
6
105
|
baseUrl: string;
|
|
7
106
|
apiKey: string;
|
|
@@ -12,6 +111,14 @@ interface HttpClientConfig {
|
|
|
12
111
|
* Custom fetch implementation for testing/mocking
|
|
13
112
|
*/
|
|
14
113
|
fetch?: FetchFunction;
|
|
114
|
+
/**
|
|
115
|
+
* Fine-grained retry configuration
|
|
116
|
+
*/
|
|
117
|
+
retry?: RetryConfig;
|
|
118
|
+
/**
|
|
119
|
+
* Hooks for observability
|
|
120
|
+
*/
|
|
121
|
+
hooks?: Hooks;
|
|
15
122
|
}
|
|
16
123
|
interface RequestOptions {
|
|
17
124
|
method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';
|
|
@@ -20,40 +127,103 @@ interface RequestOptions {
|
|
|
20
127
|
query?: Record<string, string | number | boolean | undefined>;
|
|
21
128
|
headers?: Record<string, string>;
|
|
22
129
|
idempotencyKey?: string;
|
|
130
|
+
/**
|
|
131
|
+
* AbortSignal to cancel the request
|
|
132
|
+
*/
|
|
133
|
+
signal?: AbortSignal;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Rate limit information from response headers
|
|
137
|
+
*/
|
|
138
|
+
interface RateLimitInfo {
|
|
139
|
+
/** Maximum requests allowed in the current window */
|
|
140
|
+
limit: number;
|
|
141
|
+
/** Remaining requests in the current window */
|
|
142
|
+
remaining: number;
|
|
143
|
+
/** Unix timestamp (seconds) when the rate limit resets */
|
|
144
|
+
reset: number;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Response wrapper with rate limit info
|
|
148
|
+
*/
|
|
149
|
+
interface ResponseWithRateLimit<T> {
|
|
150
|
+
data: T;
|
|
151
|
+
rateLimit?: RateLimitInfo;
|
|
152
|
+
requestId?: string;
|
|
23
153
|
}
|
|
24
154
|
/**
|
|
25
|
-
* HTTP client with retry logic and error handling
|
|
155
|
+
* HTTP client with retry logic, hooks, and error handling
|
|
26
156
|
*/
|
|
27
157
|
declare class HttpClient {
|
|
28
158
|
private readonly config;
|
|
29
159
|
private readonly fetchFn;
|
|
160
|
+
private readonly retryConfig;
|
|
161
|
+
/** Rate limit info from the last response */
|
|
162
|
+
private _lastRateLimit?;
|
|
163
|
+
/** Request ID from the last response */
|
|
164
|
+
private _lastRequestId?;
|
|
30
165
|
constructor(config: HttpClientConfig);
|
|
166
|
+
/**
|
|
167
|
+
* Get rate limit info from the last response
|
|
168
|
+
*/
|
|
169
|
+
get lastRateLimit(): RateLimitInfo | undefined;
|
|
170
|
+
/**
|
|
171
|
+
* Get request ID from the last response
|
|
172
|
+
*/
|
|
173
|
+
get lastRequestId(): string | undefined;
|
|
31
174
|
/**
|
|
32
175
|
* Execute an HTTP request with retry logic
|
|
33
176
|
*/
|
|
34
177
|
request<T>(options: RequestOptions): Promise<T>;
|
|
178
|
+
/**
|
|
179
|
+
* Execute request and return response with rate limit info
|
|
180
|
+
*/
|
|
181
|
+
requestWithRateLimit<T>(options: RequestOptions): Promise<ResponseWithRateLimit<T>>;
|
|
182
|
+
private shouldRetry;
|
|
183
|
+
private calculateDelay;
|
|
35
184
|
private buildUrl;
|
|
36
185
|
private buildHeaders;
|
|
37
186
|
private executeRequest;
|
|
187
|
+
private extractRateLimitInfo;
|
|
38
188
|
private handleResponse;
|
|
39
|
-
private calculateBackoff;
|
|
40
189
|
private sleep;
|
|
41
190
|
}
|
|
42
191
|
|
|
192
|
+
/**
|
|
193
|
+
* Options for API requests
|
|
194
|
+
*/
|
|
195
|
+
interface ApiRequestOptions {
|
|
196
|
+
/**
|
|
197
|
+
* AbortSignal to cancel the request
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```typescript
|
|
201
|
+
* const controller = new AbortController();
|
|
202
|
+
* setTimeout(() => controller.abort(), 5000);
|
|
203
|
+
*
|
|
204
|
+
* const ticket = await client.tickets.get('ws_abc', 'tkt_xyz', {
|
|
205
|
+
* signal: controller.signal,
|
|
206
|
+
* });
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
signal?: AbortSignal;
|
|
210
|
+
}
|
|
43
211
|
/**
|
|
44
212
|
* Base class for all resource classes
|
|
213
|
+
* @internal
|
|
45
214
|
*/
|
|
46
215
|
declare abstract class BaseResource {
|
|
47
216
|
protected readonly http: HttpClient;
|
|
48
217
|
constructor(http: HttpClient);
|
|
49
|
-
protected _get<T>(path: string, query?: RequestOptions['query']): Promise<T>;
|
|
218
|
+
protected _get<T>(path: string, query?: RequestOptions['query'], options?: ApiRequestOptions): Promise<T>;
|
|
50
219
|
protected _post<T>(path: string, body?: unknown, options?: {
|
|
51
220
|
idempotencyKey?: string;
|
|
52
221
|
query?: RequestOptions['query'];
|
|
222
|
+
signal?: AbortSignal;
|
|
53
223
|
}): Promise<T>;
|
|
54
|
-
protected _patch<T>(path: string, body?: unknown): Promise<T>;
|
|
55
|
-
protected _put<T>(path: string, body?: unknown): Promise<T>;
|
|
56
|
-
protected _delete<T>(path: string, query?: RequestOptions['query']): Promise<T>;
|
|
224
|
+
protected _patch<T>(path: string, body?: unknown, options?: ApiRequestOptions): Promise<T>;
|
|
225
|
+
protected _put<T>(path: string, body?: unknown, options?: ApiRequestOptions): Promise<T>;
|
|
226
|
+
protected _delete<T>(path: string, query?: RequestOptions['query'], options?: ApiRequestOptions): Promise<T>;
|
|
57
227
|
}
|
|
58
228
|
|
|
59
229
|
/**
|
|
@@ -1024,10 +1194,30 @@ declare class FieldsResource extends BaseResource {
|
|
|
1024
1194
|
|
|
1025
1195
|
/**
|
|
1026
1196
|
* Configuration options for the Dispatch Tickets client
|
|
1197
|
+
*
|
|
1198
|
+
* @example
|
|
1199
|
+
* ```typescript
|
|
1200
|
+
* const client = new DispatchTickets({
|
|
1201
|
+
* apiKey: 'sk_live_...',
|
|
1202
|
+
* timeout: 30000,
|
|
1203
|
+
* retry: {
|
|
1204
|
+
* maxRetries: 5,
|
|
1205
|
+
* retryableStatuses: [429, 500, 502, 503, 504],
|
|
1206
|
+
* },
|
|
1207
|
+
* hooks: {
|
|
1208
|
+
* onRequest: (ctx) => console.log(`${ctx.method} ${ctx.url}`),
|
|
1209
|
+
* onResponse: (ctx) => console.log(`${ctx.status} in ${ctx.durationMs}ms`),
|
|
1210
|
+
* },
|
|
1211
|
+
* });
|
|
1212
|
+
* ```
|
|
1027
1213
|
*/
|
|
1028
1214
|
interface DispatchTicketsConfig {
|
|
1029
1215
|
/**
|
|
1030
1216
|
* Your API key (required)
|
|
1217
|
+
*
|
|
1218
|
+
* Get your API key from the Dispatch Tickets dashboard.
|
|
1219
|
+
* Keys starting with `sk_live_` are production keys.
|
|
1220
|
+
* Keys starting with `sk_test_` are test keys.
|
|
1031
1221
|
*/
|
|
1032
1222
|
apiKey: string;
|
|
1033
1223
|
/**
|
|
@@ -1043,22 +1233,90 @@ interface DispatchTicketsConfig {
|
|
|
1043
1233
|
/**
|
|
1044
1234
|
* Maximum number of retries for failed requests
|
|
1045
1235
|
* @default 3
|
|
1236
|
+
* @deprecated Use `retry.maxRetries` instead for fine-grained control
|
|
1046
1237
|
*/
|
|
1047
1238
|
maxRetries?: number;
|
|
1048
1239
|
/**
|
|
1049
1240
|
* Enable debug logging
|
|
1241
|
+
*
|
|
1242
|
+
* When enabled, logs all requests, responses, and request IDs to console.
|
|
1050
1243
|
* @default false
|
|
1051
1244
|
*/
|
|
1052
1245
|
debug?: boolean;
|
|
1053
1246
|
/**
|
|
1054
1247
|
* Custom fetch implementation for testing/mocking
|
|
1248
|
+
*
|
|
1249
|
+
* @example
|
|
1250
|
+
* ```typescript
|
|
1251
|
+
* const mockFetch = vi.fn().mockResolvedValue({
|
|
1252
|
+
* ok: true,
|
|
1253
|
+
* status: 200,
|
|
1254
|
+
* headers: { get: () => 'application/json' },
|
|
1255
|
+
* json: () => Promise.resolve({ id: 'test' }),
|
|
1256
|
+
* });
|
|
1257
|
+
*
|
|
1258
|
+
* const client = new DispatchTickets({
|
|
1259
|
+
* apiKey: 'sk_test_...',
|
|
1260
|
+
* fetch: mockFetch,
|
|
1261
|
+
* });
|
|
1262
|
+
* ```
|
|
1055
1263
|
*/
|
|
1056
1264
|
fetch?: FetchFunction;
|
|
1265
|
+
/**
|
|
1266
|
+
* Fine-grained retry configuration
|
|
1267
|
+
*
|
|
1268
|
+
* @example
|
|
1269
|
+
* ```typescript
|
|
1270
|
+
* const client = new DispatchTickets({
|
|
1271
|
+
* apiKey: 'sk_live_...',
|
|
1272
|
+
* retry: {
|
|
1273
|
+
* maxRetries: 5,
|
|
1274
|
+
* retryableStatuses: [429, 500, 502, 503, 504],
|
|
1275
|
+
* initialDelayMs: 500,
|
|
1276
|
+
* maxDelayMs: 60000,
|
|
1277
|
+
* backoffMultiplier: 2,
|
|
1278
|
+
* jitter: 0.25,
|
|
1279
|
+
* },
|
|
1280
|
+
* });
|
|
1281
|
+
* ```
|
|
1282
|
+
*/
|
|
1283
|
+
retry?: RetryConfig;
|
|
1284
|
+
/**
|
|
1285
|
+
* Hooks for observability and customization
|
|
1286
|
+
*
|
|
1287
|
+
* @example
|
|
1288
|
+
* ```typescript
|
|
1289
|
+
* const client = new DispatchTickets({
|
|
1290
|
+
* apiKey: 'sk_live_...',
|
|
1291
|
+
* hooks: {
|
|
1292
|
+
* onRequest: (ctx) => {
|
|
1293
|
+
* console.log(`[${new Date().toISOString()}] ${ctx.method} ${ctx.url}`);
|
|
1294
|
+
* },
|
|
1295
|
+
* onResponse: (ctx) => {
|
|
1296
|
+
* console.log(`[${ctx.requestId}] ${ctx.status} in ${ctx.durationMs}ms`);
|
|
1297
|
+
* },
|
|
1298
|
+
* onError: (error, ctx) => {
|
|
1299
|
+
* console.error(`Request failed: ${error.message}`);
|
|
1300
|
+
* // Send to error tracking service
|
|
1301
|
+
* Sentry.captureException(error);
|
|
1302
|
+
* },
|
|
1303
|
+
* onRetry: (ctx, error, delayMs) => {
|
|
1304
|
+
* console.log(`Retrying in ${delayMs}ms (attempt ${ctx.attempt + 1})`);
|
|
1305
|
+
* },
|
|
1306
|
+
* },
|
|
1307
|
+
* });
|
|
1308
|
+
* ```
|
|
1309
|
+
*/
|
|
1310
|
+
hooks?: Hooks;
|
|
1057
1311
|
}
|
|
1058
1312
|
/**
|
|
1059
1313
|
* Dispatch Tickets SDK client
|
|
1060
1314
|
*
|
|
1061
|
-
*
|
|
1315
|
+
* The main entry point for interacting with the Dispatch Tickets API.
|
|
1316
|
+
* Create a client instance with your API key and use the resource methods
|
|
1317
|
+
* to manage tickets, comments, attachments, and more.
|
|
1318
|
+
*
|
|
1319
|
+
* @example Basic usage
|
|
1062
1320
|
* ```typescript
|
|
1063
1321
|
* import { DispatchTickets } from '@dispatchtickets/sdk';
|
|
1064
1322
|
*
|
|
@@ -1080,56 +1338,244 @@ interface DispatchTicketsConfig {
|
|
|
1080
1338
|
* console.log(ticket.title);
|
|
1081
1339
|
* }
|
|
1082
1340
|
* ```
|
|
1341
|
+
*
|
|
1342
|
+
* @example With request cancellation
|
|
1343
|
+
* ```typescript
|
|
1344
|
+
* const controller = new AbortController();
|
|
1345
|
+
*
|
|
1346
|
+
* // Cancel after 5 seconds
|
|
1347
|
+
* setTimeout(() => controller.abort(), 5000);
|
|
1348
|
+
*
|
|
1349
|
+
* try {
|
|
1350
|
+
* const tickets = await client.tickets.listPage('ws_abc123', {}, {
|
|
1351
|
+
* signal: controller.signal,
|
|
1352
|
+
* });
|
|
1353
|
+
* } catch (error) {
|
|
1354
|
+
* if (error.message === 'Request aborted by user') {
|
|
1355
|
+
* console.log('Request was cancelled');
|
|
1356
|
+
* }
|
|
1357
|
+
* }
|
|
1358
|
+
* ```
|
|
1359
|
+
*
|
|
1360
|
+
* @example With hooks for logging
|
|
1361
|
+
* ```typescript
|
|
1362
|
+
* const client = new DispatchTickets({
|
|
1363
|
+
* apiKey: 'sk_live_...',
|
|
1364
|
+
* hooks: {
|
|
1365
|
+
* onRequest: (ctx) => console.log(`→ ${ctx.method} ${ctx.url}`),
|
|
1366
|
+
* onResponse: (ctx) => console.log(`← ${ctx.status} (${ctx.durationMs}ms)`),
|
|
1367
|
+
* },
|
|
1368
|
+
* });
|
|
1369
|
+
* ```
|
|
1083
1370
|
*/
|
|
1084
1371
|
declare class DispatchTickets {
|
|
1085
1372
|
private readonly http;
|
|
1086
1373
|
/**
|
|
1087
1374
|
* Accounts resource for managing the current account and API keys
|
|
1375
|
+
*
|
|
1376
|
+
* @example
|
|
1377
|
+
* ```typescript
|
|
1378
|
+
* // Get current account
|
|
1379
|
+
* const account = await client.accounts.me();
|
|
1380
|
+
*
|
|
1381
|
+
* // Get usage statistics
|
|
1382
|
+
* const usage = await client.accounts.getUsage();
|
|
1383
|
+
*
|
|
1384
|
+
* // Create a new API key
|
|
1385
|
+
* const newKey = await client.accounts.createApiKey({
|
|
1386
|
+
* name: 'Production',
|
|
1387
|
+
* allBrands: true,
|
|
1388
|
+
* });
|
|
1389
|
+
* ```
|
|
1088
1390
|
*/
|
|
1089
1391
|
readonly accounts: AccountsResource;
|
|
1090
1392
|
/**
|
|
1091
1393
|
* Brands (workspaces) resource
|
|
1394
|
+
*
|
|
1395
|
+
* Brands are isolated containers for tickets. Each brand can have its own
|
|
1396
|
+
* email address, categories, tags, and settings.
|
|
1397
|
+
*
|
|
1398
|
+
* @example
|
|
1399
|
+
* ```typescript
|
|
1400
|
+
* // List all brands
|
|
1401
|
+
* const brands = await client.brands.list();
|
|
1402
|
+
*
|
|
1403
|
+
* // Create a new brand
|
|
1404
|
+
* const brand = await client.brands.create({
|
|
1405
|
+
* name: 'Acme Support',
|
|
1406
|
+
* slug: 'acme',
|
|
1407
|
+
* });
|
|
1408
|
+
*
|
|
1409
|
+
* // Get inbound email address
|
|
1410
|
+
* const email = client.brands.getInboundEmail('br_abc123');
|
|
1411
|
+
* // Returns: br_abc123@inbound.dispatchtickets.com
|
|
1412
|
+
* ```
|
|
1092
1413
|
*/
|
|
1093
1414
|
readonly brands: BrandsResource;
|
|
1094
1415
|
/**
|
|
1095
1416
|
* Tickets resource
|
|
1417
|
+
*
|
|
1418
|
+
* @example
|
|
1419
|
+
* ```typescript
|
|
1420
|
+
* // Create a ticket
|
|
1421
|
+
* const ticket = await client.tickets.create('ws_abc123', {
|
|
1422
|
+
* title: 'Issue with billing',
|
|
1423
|
+
* body: 'I was charged twice...',
|
|
1424
|
+
* priority: 'high',
|
|
1425
|
+
* });
|
|
1426
|
+
*
|
|
1427
|
+
* // Iterate through all tickets
|
|
1428
|
+
* for await (const ticket of client.tickets.list('ws_abc123', { status: 'open' })) {
|
|
1429
|
+
* console.log(ticket.title);
|
|
1430
|
+
* }
|
|
1431
|
+
* ```
|
|
1096
1432
|
*/
|
|
1097
1433
|
readonly tickets: TicketsResource;
|
|
1098
1434
|
/**
|
|
1099
1435
|
* Comments resource
|
|
1436
|
+
*
|
|
1437
|
+
* @example
|
|
1438
|
+
* ```typescript
|
|
1439
|
+
* // Add a comment
|
|
1440
|
+
* const comment = await client.comments.create('ws_abc123', 'tkt_xyz', {
|
|
1441
|
+
* body: 'Thanks for your patience!',
|
|
1442
|
+
* authorType: 'AGENT',
|
|
1443
|
+
* });
|
|
1444
|
+
*
|
|
1445
|
+
* // List comments
|
|
1446
|
+
* const comments = await client.comments.list('ws_abc123', 'tkt_xyz');
|
|
1447
|
+
* ```
|
|
1100
1448
|
*/
|
|
1101
1449
|
readonly comments: CommentsResource;
|
|
1102
1450
|
/**
|
|
1103
1451
|
* Attachments resource
|
|
1452
|
+
*
|
|
1453
|
+
* @example
|
|
1454
|
+
* ```typescript
|
|
1455
|
+
* // Simple upload
|
|
1456
|
+
* const attachment = await client.attachments.upload(
|
|
1457
|
+
* 'ws_abc123',
|
|
1458
|
+
* 'tkt_xyz',
|
|
1459
|
+
* fileBuffer,
|
|
1460
|
+
* 'document.pdf',
|
|
1461
|
+
* 'application/pdf'
|
|
1462
|
+
* );
|
|
1463
|
+
*
|
|
1464
|
+
* // Get download URL
|
|
1465
|
+
* const { downloadUrl } = await client.attachments.get('ws_abc123', 'tkt_xyz', 'att_abc');
|
|
1466
|
+
* ```
|
|
1104
1467
|
*/
|
|
1105
1468
|
readonly attachments: AttachmentsResource;
|
|
1106
1469
|
/**
|
|
1107
1470
|
* Webhooks resource
|
|
1471
|
+
*
|
|
1472
|
+
* @example
|
|
1473
|
+
* ```typescript
|
|
1474
|
+
* // Create a webhook
|
|
1475
|
+
* const webhook = await client.webhooks.create('ws_abc123', {
|
|
1476
|
+
* url: 'https://example.com/webhook',
|
|
1477
|
+
* secret: 'your-secret',
|
|
1478
|
+
* events: ['ticket.created', 'ticket.updated'],
|
|
1479
|
+
* });
|
|
1480
|
+
* ```
|
|
1108
1481
|
*/
|
|
1109
1482
|
readonly webhooks: WebhooksResource;
|
|
1110
1483
|
/**
|
|
1111
1484
|
* Categories resource
|
|
1485
|
+
*
|
|
1486
|
+
* @example
|
|
1487
|
+
* ```typescript
|
|
1488
|
+
* // Create a category
|
|
1489
|
+
* await client.categories.create('ws_abc123', { name: 'Billing', color: '#ef4444' });
|
|
1490
|
+
*
|
|
1491
|
+
* // Get category stats
|
|
1492
|
+
* const stats = await client.categories.getStats('ws_abc123');
|
|
1493
|
+
* ```
|
|
1112
1494
|
*/
|
|
1113
1495
|
readonly categories: CategoriesResource;
|
|
1114
1496
|
/**
|
|
1115
1497
|
* Tags resource
|
|
1498
|
+
*
|
|
1499
|
+
* @example
|
|
1500
|
+
* ```typescript
|
|
1501
|
+
* // Create a tag
|
|
1502
|
+
* await client.tags.create('ws_abc123', { name: 'urgent', color: '#f59e0b' });
|
|
1503
|
+
*
|
|
1504
|
+
* // Merge tags
|
|
1505
|
+
* await client.tags.merge('ws_abc123', 'tag_target', ['tag_source1', 'tag_source2']);
|
|
1506
|
+
* ```
|
|
1116
1507
|
*/
|
|
1117
1508
|
readonly tags: TagsResource;
|
|
1118
1509
|
/**
|
|
1119
1510
|
* Customers resource
|
|
1511
|
+
*
|
|
1512
|
+
* @example
|
|
1513
|
+
* ```typescript
|
|
1514
|
+
* // Create a customer
|
|
1515
|
+
* const customer = await client.customers.create('ws_abc123', {
|
|
1516
|
+
* email: 'user@example.com',
|
|
1517
|
+
* name: 'Jane Doe',
|
|
1518
|
+
* });
|
|
1519
|
+
*
|
|
1520
|
+
* // Search customers
|
|
1521
|
+
* const results = await client.customers.search('ws_abc123', 'jane');
|
|
1522
|
+
* ```
|
|
1120
1523
|
*/
|
|
1121
1524
|
readonly customers: CustomersResource;
|
|
1122
1525
|
/**
|
|
1123
1526
|
* Custom fields resource
|
|
1527
|
+
*
|
|
1528
|
+
* @example
|
|
1529
|
+
* ```typescript
|
|
1530
|
+
* // Get all field definitions
|
|
1531
|
+
* const fields = await client.fields.getAll('ws_abc123');
|
|
1532
|
+
*
|
|
1533
|
+
* // Create a field
|
|
1534
|
+
* await client.fields.create('ws_abc123', 'ticket', {
|
|
1535
|
+
* key: 'order_id',
|
|
1536
|
+
* label: 'Order ID',
|
|
1537
|
+
* type: 'text',
|
|
1538
|
+
* required: true,
|
|
1539
|
+
* });
|
|
1540
|
+
* ```
|
|
1124
1541
|
*/
|
|
1125
1542
|
readonly fields: FieldsResource;
|
|
1126
1543
|
/**
|
|
1127
1544
|
* Static webhook utilities
|
|
1545
|
+
*
|
|
1546
|
+
* @example
|
|
1547
|
+
* ```typescript
|
|
1548
|
+
* // Verify webhook signature
|
|
1549
|
+
* const isValid = DispatchTickets.webhooks.verifySignature(
|
|
1550
|
+
* rawBody,
|
|
1551
|
+
* req.headers['x-dispatch-signature'],
|
|
1552
|
+
* 'your-secret'
|
|
1553
|
+
* );
|
|
1554
|
+
*
|
|
1555
|
+
* // Generate signature for testing
|
|
1556
|
+
* const signature = DispatchTickets.webhooks.generateSignature(
|
|
1557
|
+
* JSON.stringify(payload),
|
|
1558
|
+
* 'your-secret'
|
|
1559
|
+
* );
|
|
1560
|
+
* ```
|
|
1128
1561
|
*/
|
|
1129
1562
|
static readonly webhooks: {
|
|
1130
1563
|
verifySignature(payload: string, signature: string, secret: string): boolean;
|
|
1131
1564
|
generateSignature(payload: string, secret: string): string;
|
|
1132
1565
|
};
|
|
1566
|
+
/**
|
|
1567
|
+
* Create a new Dispatch Tickets client
|
|
1568
|
+
*
|
|
1569
|
+
* @param config - Client configuration options
|
|
1570
|
+
* @throws Error if API key is not provided
|
|
1571
|
+
*
|
|
1572
|
+
* @example
|
|
1573
|
+
* ```typescript
|
|
1574
|
+
* const client = new DispatchTickets({
|
|
1575
|
+
* apiKey: 'sk_live_...',
|
|
1576
|
+
* });
|
|
1577
|
+
* ```
|
|
1578
|
+
*/
|
|
1133
1579
|
constructor(config: DispatchTicketsConfig);
|
|
1134
1580
|
}
|
|
1135
1581
|
|
|
@@ -1140,20 +1586,32 @@ declare class DispatchTicketsError extends Error {
|
|
|
1140
1586
|
readonly code: string;
|
|
1141
1587
|
readonly statusCode?: number;
|
|
1142
1588
|
readonly details?: Record<string, unknown>;
|
|
1143
|
-
|
|
1589
|
+
/** Request ID for debugging with support */
|
|
1590
|
+
readonly requestId?: string;
|
|
1591
|
+
constructor(message: string, code: string, statusCode?: number, details?: Record<string, unknown>, requestId?: string);
|
|
1144
1592
|
}
|
|
1145
1593
|
/**
|
|
1146
1594
|
* Thrown when API key is missing or invalid
|
|
1147
1595
|
*/
|
|
1148
1596
|
declare class AuthenticationError extends DispatchTicketsError {
|
|
1149
|
-
constructor(message?: string);
|
|
1597
|
+
constructor(message?: string, requestId?: string);
|
|
1150
1598
|
}
|
|
1151
1599
|
/**
|
|
1152
1600
|
* Thrown when rate limit is exceeded
|
|
1153
1601
|
*/
|
|
1154
1602
|
declare class RateLimitError extends DispatchTicketsError {
|
|
1155
1603
|
readonly retryAfter?: number;
|
|
1156
|
-
|
|
1604
|
+
/** Rate limit ceiling */
|
|
1605
|
+
readonly limit?: number;
|
|
1606
|
+
/** Remaining requests in current window */
|
|
1607
|
+
readonly remaining?: number;
|
|
1608
|
+
/** Unix timestamp when rate limit resets */
|
|
1609
|
+
readonly reset?: number;
|
|
1610
|
+
constructor(message?: string, retryAfter?: number, requestId?: string, rateLimitInfo?: {
|
|
1611
|
+
limit?: number;
|
|
1612
|
+
remaining?: number;
|
|
1613
|
+
reset?: number;
|
|
1614
|
+
});
|
|
1157
1615
|
}
|
|
1158
1616
|
/**
|
|
1159
1617
|
* Thrown when request validation fails
|
|
@@ -1166,7 +1624,7 @@ declare class ValidationError extends DispatchTicketsError {
|
|
|
1166
1624
|
constructor(message?: string, errors?: Array<{
|
|
1167
1625
|
field: string;
|
|
1168
1626
|
message: string;
|
|
1169
|
-
}
|
|
1627
|
+
}>, requestId?: string);
|
|
1170
1628
|
}
|
|
1171
1629
|
/**
|
|
1172
1630
|
* Thrown when a resource is not found
|
|
@@ -1174,19 +1632,19 @@ declare class ValidationError extends DispatchTicketsError {
|
|
|
1174
1632
|
declare class NotFoundError extends DispatchTicketsError {
|
|
1175
1633
|
readonly resourceType?: string;
|
|
1176
1634
|
readonly resourceId?: string;
|
|
1177
|
-
constructor(message?: string, resourceType?: string, resourceId?: string);
|
|
1635
|
+
constructor(message?: string, resourceType?: string, resourceId?: string, requestId?: string);
|
|
1178
1636
|
}
|
|
1179
1637
|
/**
|
|
1180
1638
|
* Thrown when there's a conflict (e.g., duplicate resource)
|
|
1181
1639
|
*/
|
|
1182
1640
|
declare class ConflictError extends DispatchTicketsError {
|
|
1183
|
-
constructor(message?: string);
|
|
1641
|
+
constructor(message?: string, requestId?: string);
|
|
1184
1642
|
}
|
|
1185
1643
|
/**
|
|
1186
1644
|
* Thrown when the server returns an unexpected error
|
|
1187
1645
|
*/
|
|
1188
1646
|
declare class ServerError extends DispatchTicketsError {
|
|
1189
|
-
constructor(message?: string, statusCode?: number);
|
|
1647
|
+
constructor(message?: string, statusCode?: number, requestId?: string);
|
|
1190
1648
|
}
|
|
1191
1649
|
/**
|
|
1192
1650
|
* Thrown when request times out
|
|
@@ -1200,6 +1658,42 @@ declare class TimeoutError extends DispatchTicketsError {
|
|
|
1200
1658
|
declare class NetworkError extends DispatchTicketsError {
|
|
1201
1659
|
constructor(message?: string);
|
|
1202
1660
|
}
|
|
1661
|
+
/**
|
|
1662
|
+
* Check if an error is a DispatchTicketsError
|
|
1663
|
+
*/
|
|
1664
|
+
declare function isDispatchTicketsError(error: unknown): error is DispatchTicketsError;
|
|
1665
|
+
/**
|
|
1666
|
+
* Check if an error is an AuthenticationError
|
|
1667
|
+
*/
|
|
1668
|
+
declare function isAuthenticationError(error: unknown): error is AuthenticationError;
|
|
1669
|
+
/**
|
|
1670
|
+
* Check if an error is a RateLimitError
|
|
1671
|
+
*/
|
|
1672
|
+
declare function isRateLimitError(error: unknown): error is RateLimitError;
|
|
1673
|
+
/**
|
|
1674
|
+
* Check if an error is a ValidationError
|
|
1675
|
+
*/
|
|
1676
|
+
declare function isValidationError(error: unknown): error is ValidationError;
|
|
1677
|
+
/**
|
|
1678
|
+
* Check if an error is a NotFoundError
|
|
1679
|
+
*/
|
|
1680
|
+
declare function isNotFoundError(error: unknown): error is NotFoundError;
|
|
1681
|
+
/**
|
|
1682
|
+
* Check if an error is a ConflictError
|
|
1683
|
+
*/
|
|
1684
|
+
declare function isConflictError(error: unknown): error is ConflictError;
|
|
1685
|
+
/**
|
|
1686
|
+
* Check if an error is a ServerError
|
|
1687
|
+
*/
|
|
1688
|
+
declare function isServerError(error: unknown): error is ServerError;
|
|
1689
|
+
/**
|
|
1690
|
+
* Check if an error is a TimeoutError
|
|
1691
|
+
*/
|
|
1692
|
+
declare function isTimeoutError(error: unknown): error is TimeoutError;
|
|
1693
|
+
/**
|
|
1694
|
+
* Check if an error is a NetworkError
|
|
1695
|
+
*/
|
|
1696
|
+
declare function isNetworkError(error: unknown): error is NetworkError;
|
|
1203
1697
|
|
|
1204
1698
|
/**
|
|
1205
1699
|
* All supported webhook event types
|
|
@@ -1379,4 +1873,4 @@ declare const webhookUtils: {
|
|
|
1379
1873
|
*/
|
|
1380
1874
|
declare function collectAll<T>(iterable: AsyncIterable<T>): Promise<T[]>;
|
|
1381
1875
|
|
|
1382
|
-
export { type Account, type AccountUsage, type ApiKey, type ApiKeyWithSecret, type Attachment, type AttachmentStatus, type AttachmentWithUrl, AuthenticationError, type AuthorType, type Brand, type BulkAction, type BulkActionResult, type Category, type CategoryStats, type Comment, type CommentCreatedData, type CommentCreatedEvent, type Company, ConflictError, type CreateApiKeyInput, type CreateBrandInput, type CreateCategoryInput, type CreateCommentInput, type CreateCommentOptions, type CreateCustomerInput, type CreateFieldInput, type CreateTagInput, type CreateTicketInput, type CreateTicketOptions, type CreateWebhookInput, type Customer, type DeleteBrandPreview, DispatchTickets, type DispatchTicketsConfig, DispatchTicketsError, type EntityType, type EventCommentData, type EventCustomerInfo, type FieldDefinition, type FieldDefinitions, type FieldType, type InitiateUploadInput, type InitiateUploadResponse, type Link, type ListCustomersFilters, type ListTicketsFilters, type MergeTagsInput, type MergeTicketsInput, NetworkError, NotFoundError, type PaginatedResponse, RateLimitError, ServerError, type SortOrder, type Tag, type Ticket, type TicketCreatedData, type TicketCreatedEvent, type TicketPriority, type TicketSource, type TicketStatus, type TicketUpdatedData, type TicketUpdatedEvent, TimeoutError, type UpdateApiKeyScopeInput, type UpdateBrandInput, type UpdateCategoryInput, type UpdateCommentInput, type UpdateCustomerInput, type UpdateFieldInput, type UpdateTagInput, type UpdateTicketInput, ValidationError, type Webhook, type WebhookDelivery, type WebhookEvent, type WebhookEventEnvelope, type WebhookEventMap, type WebhookEventName, type WebhookEventType, collectAll, isCommentCreatedEvent, isTicketCreatedEvent, isTicketUpdatedEvent, parseWebhookEvent, webhookUtils };
|
|
1876
|
+
export { type Account, type AccountUsage, type ApiKey, type ApiKeyWithSecret, type ApiRequestOptions, type Attachment, type AttachmentStatus, type AttachmentWithUrl, AuthenticationError, type AuthorType, type Brand, type BulkAction, type BulkActionResult, type Category, type CategoryStats, type Comment, type CommentCreatedData, type CommentCreatedEvent, type Company, ConflictError, type CreateApiKeyInput, type CreateBrandInput, type CreateCategoryInput, type CreateCommentInput, type CreateCommentOptions, type CreateCustomerInput, type CreateFieldInput, type CreateTagInput, type CreateTicketInput, type CreateTicketOptions, type CreateWebhookInput, type Customer, type DeleteBrandPreview, DispatchTickets, type DispatchTicketsConfig, DispatchTicketsError, type EntityType, type EventCommentData, type EventCustomerInfo, type FieldDefinition, type FieldDefinitions, type FieldType, type Hooks, type InitiateUploadInput, type InitiateUploadResponse, type Link, type ListCustomersFilters, type ListTicketsFilters, type MergeTagsInput, type MergeTicketsInput, NetworkError, NotFoundError, type PaginatedResponse, RateLimitError, type RateLimitInfo, type RequestContext, type ResponseContext, type RetryConfig, ServerError, type SortOrder, type Tag, type Ticket, type TicketCreatedData, type TicketCreatedEvent, type TicketPriority, type TicketSource, type TicketStatus, type TicketUpdatedData, type TicketUpdatedEvent, TimeoutError, type UpdateApiKeyScopeInput, type UpdateBrandInput, type UpdateCategoryInput, type UpdateCommentInput, type UpdateCustomerInput, type UpdateFieldInput, type UpdateTagInput, type UpdateTicketInput, ValidationError, type Webhook, type WebhookDelivery, type WebhookEvent, type WebhookEventEnvelope, type WebhookEventMap, type WebhookEventName, type WebhookEventType, collectAll, isAuthenticationError, isCommentCreatedEvent, isConflictError, isDispatchTicketsError, isNetworkError, isNotFoundError, isRateLimitError, isServerError, isTicketCreatedEvent, isTicketUpdatedEvent, isTimeoutError, isValidationError, parseWebhookEvent, webhookUtils };
|