@dispatchtickets/sdk 0.1.0 → 0.3.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/dist/index.d.cts CHANGED
@@ -1,9 +1,17 @@
1
+ /**
2
+ * Custom fetch function type
3
+ */
4
+ type FetchFunction = typeof fetch;
1
5
  interface HttpClientConfig {
2
6
  baseUrl: string;
3
7
  apiKey: string;
4
8
  timeout: number;
5
9
  maxRetries: number;
6
10
  debug?: boolean;
11
+ /**
12
+ * Custom fetch implementation for testing/mocking
13
+ */
14
+ fetch?: FetchFunction;
7
15
  }
8
16
  interface RequestOptions {
9
17
  method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';
@@ -18,6 +26,7 @@ interface RequestOptions {
18
26
  */
19
27
  declare class HttpClient {
20
28
  private readonly config;
29
+ private readonly fetchFn;
21
30
  constructor(config: HttpClientConfig);
22
31
  /**
23
32
  * Execute an HTTP request with retry logic
@@ -47,6 +56,104 @@ declare abstract class BaseResource {
47
56
  protected _delete<T>(path: string, query?: RequestOptions['query']): Promise<T>;
48
57
  }
49
58
 
59
+ /**
60
+ * Account represents the organization/company using Dispatch Tickets
61
+ */
62
+ interface Account {
63
+ id: string;
64
+ stackbeCustomerId: string;
65
+ stackbeOrganizationId: string;
66
+ createdAt: string;
67
+ updatedAt: string;
68
+ }
69
+ /**
70
+ * Usage statistics for the account
71
+ */
72
+ interface AccountUsage {
73
+ ticketsThisMonth: number;
74
+ ticketsTotal: number;
75
+ brandsCount: number;
76
+ plan?: {
77
+ name: string;
78
+ ticketLimit: number;
79
+ brandLimit: number | null;
80
+ };
81
+ }
82
+ /**
83
+ * API key for programmatic access
84
+ */
85
+ interface ApiKey {
86
+ id: string;
87
+ name: string;
88
+ keyPreview: string;
89
+ allBrands: boolean;
90
+ brandIds: string[];
91
+ lastUsedAt: string | null;
92
+ createdAt: string;
93
+ }
94
+ /**
95
+ * API key with the full key value (only returned on creation)
96
+ */
97
+ interface ApiKeyWithSecret extends ApiKey {
98
+ key: string;
99
+ }
100
+ /**
101
+ * Input for creating an API key
102
+ */
103
+ interface CreateApiKeyInput {
104
+ name: string;
105
+ /**
106
+ * If true, the API key can access all brands (current and future)
107
+ */
108
+ allBrands?: boolean;
109
+ /**
110
+ * Specific brand IDs this key can access (ignored if allBrands is true)
111
+ */
112
+ brandIds?: string[];
113
+ }
114
+ /**
115
+ * Input for updating API key scope
116
+ */
117
+ interface UpdateApiKeyScopeInput {
118
+ allBrands?: boolean;
119
+ brandIds?: string[];
120
+ }
121
+
122
+ /**
123
+ * Accounts resource for managing the current account
124
+ */
125
+ declare class AccountsResource extends BaseResource {
126
+ /**
127
+ * Get the current account
128
+ */
129
+ me(): Promise<Account>;
130
+ /**
131
+ * Get usage statistics for the current account
132
+ */
133
+ getUsage(): Promise<AccountUsage>;
134
+ /**
135
+ * List all API keys for the current account
136
+ */
137
+ listApiKeys(): Promise<ApiKey[]>;
138
+ /**
139
+ * Create a new API key
140
+ *
141
+ * Note: The full key value is only returned once on creation.
142
+ * Store it securely as it cannot be retrieved again.
143
+ */
144
+ createApiKey(data: CreateApiKeyInput): Promise<ApiKeyWithSecret>;
145
+ /**
146
+ * Update the brand scope for an API key
147
+ */
148
+ updateApiKeyScope(keyId: string, data: UpdateApiKeyScopeInput): Promise<{
149
+ success: boolean;
150
+ }>;
151
+ /**
152
+ * Revoke an API key
153
+ */
154
+ revokeApiKey(keyId: string): Promise<void>;
155
+ }
156
+
50
157
  /**
51
158
  * Brand (workspace) resource
52
159
  */
@@ -144,6 +251,26 @@ declare class BrandsResource extends BaseResource {
144
251
  * Update the ticket schema for a brand
145
252
  */
146
253
  updateSchema(brandId: string, schema: Record<string, unknown>): Promise<Record<string, unknown>>;
254
+ /**
255
+ * Get the inbound email address for a brand
256
+ *
257
+ * Emails sent to this address will automatically create tickets.
258
+ *
259
+ * @param brandId - The brand ID
260
+ * @param domain - Optional custom inbound domain (default: inbound.dispatchtickets.com)
261
+ * @returns The inbound email address
262
+ *
263
+ * @example
264
+ * ```typescript
265
+ * const email = client.brands.getInboundEmail('br_abc123');
266
+ * // Returns: br_abc123@inbound.dispatchtickets.com
267
+ *
268
+ * // With custom domain:
269
+ * const customEmail = client.brands.getInboundEmail('br_abc123', 'support.mycompany.com');
270
+ * // Returns: br_abc123@support.mycompany.com
271
+ * ```
272
+ */
273
+ getInboundEmail(brandId: string, domain?: string): string;
147
274
  }
148
275
 
149
276
  /**
@@ -185,9 +312,10 @@ type AuthorType = 'CUSTOMER' | 'AGENT' | 'SYSTEM';
185
312
  */
186
313
  type AttachmentStatus = 'PENDING' | 'UPLOADED' | 'FAILED';
187
314
  /**
188
- * Webhook event types
315
+ * Webhook event type strings (for subscription)
316
+ * @deprecated Use WebhookEventType from events.ts for typed event handling
189
317
  */
190
- type WebhookEvent = 'ticket.created' | 'ticket.updated' | 'ticket.deleted' | 'comment.created' | 'comment.updated' | 'comment.deleted' | 'attachment.created' | 'attachment.deleted';
318
+ type WebhookEventName = 'ticket.created' | 'ticket.updated' | 'ticket.deleted' | 'ticket.comment.created' | 'comment.created' | 'comment.updated' | 'comment.deleted' | 'attachment.created' | 'attachment.deleted';
191
319
  /**
192
320
  * Custom field types
193
321
  */
@@ -655,7 +783,7 @@ interface Webhook {
655
783
  id: string;
656
784
  brandId: string;
657
785
  url: string;
658
- events: WebhookEvent[];
786
+ events: WebhookEventName[];
659
787
  enabled: boolean;
660
788
  failureCount: number;
661
789
  lastTriggered?: string;
@@ -669,7 +797,7 @@ interface Webhook {
669
797
  interface CreateWebhookInput {
670
798
  url: string;
671
799
  secret: string;
672
- events: WebhookEvent[];
800
+ events: WebhookEventName[];
673
801
  }
674
802
  /**
675
803
  * Webhook delivery record
@@ -677,7 +805,7 @@ interface CreateWebhookInput {
677
805
  interface WebhookDelivery {
678
806
  id: string;
679
807
  webhookId: string;
680
- event: WebhookEvent;
808
+ event: WebhookEventName;
681
809
  payload: Record<string, unknown>;
682
810
  status: 'PENDING' | 'SUCCESS' | 'FAILED' | 'RETRYING';
683
811
  attempts: number;
@@ -922,6 +1050,10 @@ interface DispatchTicketsConfig {
922
1050
  * @default false
923
1051
  */
924
1052
  debug?: boolean;
1053
+ /**
1054
+ * Custom fetch implementation for testing/mocking
1055
+ */
1056
+ fetch?: FetchFunction;
925
1057
  }
926
1058
  /**
927
1059
  * Dispatch Tickets SDK client
@@ -951,6 +1083,10 @@ interface DispatchTicketsConfig {
951
1083
  */
952
1084
  declare class DispatchTickets {
953
1085
  private readonly http;
1086
+ /**
1087
+ * Accounts resource for managing the current account and API keys
1088
+ */
1089
+ readonly accounts: AccountsResource;
954
1090
  /**
955
1091
  * Brands (workspaces) resource
956
1092
  */
@@ -1065,6 +1201,136 @@ declare class NetworkError extends DispatchTicketsError {
1065
1201
  constructor(message?: string);
1066
1202
  }
1067
1203
 
1204
+ /**
1205
+ * All supported webhook event types
1206
+ */
1207
+ type WebhookEventType = 'ticket.created' | 'ticket.updated' | 'ticket.comment.created';
1208
+ /**
1209
+ * Base webhook event envelope
1210
+ */
1211
+ interface WebhookEventEnvelope<T extends WebhookEventType, D> {
1212
+ /** Unique event ID */
1213
+ id: string;
1214
+ /** Event type */
1215
+ event: T;
1216
+ /** Brand ID that triggered the event */
1217
+ brand_id: string;
1218
+ /** Event data */
1219
+ data: D;
1220
+ /** ISO timestamp when event was created */
1221
+ timestamp: string;
1222
+ }
1223
+ /**
1224
+ * Customer info included in events
1225
+ */
1226
+ interface EventCustomerInfo {
1227
+ customerId: string | null;
1228
+ customerEmail: string | null;
1229
+ customerName: string | null;
1230
+ }
1231
+ /**
1232
+ * Payload for ticket.created event
1233
+ */
1234
+ interface TicketCreatedData extends EventCustomerInfo {
1235
+ id: string;
1236
+ ticketNumber: number;
1237
+ title: string;
1238
+ status: TicketStatus;
1239
+ priority: TicketPriority;
1240
+ source: TicketSource;
1241
+ createdAt: string;
1242
+ }
1243
+ /**
1244
+ * Payload for ticket.updated event
1245
+ */
1246
+ interface TicketUpdatedData extends EventCustomerInfo {
1247
+ id: string;
1248
+ ticketNumber: number;
1249
+ title: string;
1250
+ status: TicketStatus;
1251
+ priority: TicketPriority;
1252
+ assigneeId: string | null;
1253
+ updatedAt: string;
1254
+ /** List of field names that were changed */
1255
+ changes: string[];
1256
+ }
1257
+ /**
1258
+ * Comment data in ticket.comment.created event
1259
+ */
1260
+ interface EventCommentData {
1261
+ id: string;
1262
+ body: string;
1263
+ authorId: string | null;
1264
+ authorType: AuthorType;
1265
+ createdAt: string;
1266
+ }
1267
+ /**
1268
+ * Payload for ticket.comment.created event
1269
+ */
1270
+ interface CommentCreatedData extends EventCustomerInfo {
1271
+ ticketId: string;
1272
+ /** Formatted ticket number (e.g., "ACME-123") */
1273
+ ticketNumber: string;
1274
+ comment: EventCommentData;
1275
+ }
1276
+ /**
1277
+ * Ticket created webhook event
1278
+ */
1279
+ type TicketCreatedEvent = WebhookEventEnvelope<'ticket.created', TicketCreatedData>;
1280
+ /**
1281
+ * Ticket updated webhook event
1282
+ */
1283
+ type TicketUpdatedEvent = WebhookEventEnvelope<'ticket.updated', TicketUpdatedData>;
1284
+ /**
1285
+ * Comment created webhook event
1286
+ */
1287
+ type CommentCreatedEvent = WebhookEventEnvelope<'ticket.comment.created', CommentCreatedData>;
1288
+ /**
1289
+ * Union of all webhook events
1290
+ */
1291
+ type WebhookEvent = TicketCreatedEvent | TicketUpdatedEvent | CommentCreatedEvent;
1292
+ /**
1293
+ * Map of event types to their data types
1294
+ */
1295
+ interface WebhookEventMap {
1296
+ 'ticket.created': TicketCreatedEvent;
1297
+ 'ticket.updated': TicketUpdatedEvent;
1298
+ 'ticket.comment.created': CommentCreatedEvent;
1299
+ }
1300
+ /**
1301
+ * Type guard to check if event is a ticket.created event
1302
+ */
1303
+ declare function isTicketCreatedEvent(event: WebhookEvent): event is TicketCreatedEvent;
1304
+ /**
1305
+ * Type guard to check if event is a ticket.updated event
1306
+ */
1307
+ declare function isTicketUpdatedEvent(event: WebhookEvent): event is TicketUpdatedEvent;
1308
+ /**
1309
+ * Type guard to check if event is a ticket.comment.created event
1310
+ */
1311
+ declare function isCommentCreatedEvent(event: WebhookEvent): event is CommentCreatedEvent;
1312
+ /**
1313
+ * Parse and validate a webhook payload
1314
+ *
1315
+ * @param payload - Raw JSON payload string or parsed object
1316
+ * @returns Typed webhook event
1317
+ * @throws Error if payload is invalid
1318
+ *
1319
+ * @example
1320
+ * ```typescript
1321
+ * import { parseWebhookEvent, isTicketCreatedEvent } from '@dispatchtickets/sdk';
1322
+ *
1323
+ * app.post('/webhooks', (req, res) => {
1324
+ * const event = parseWebhookEvent(req.body);
1325
+ *
1326
+ * if (isTicketCreatedEvent(event)) {
1327
+ * console.log('New ticket:', event.data.title);
1328
+ * }
1329
+ * });
1330
+ * ```
1331
+ */
1332
+ declare function parseWebhookEvent(payload: string | object): WebhookEvent;
1333
+
1068
1334
  /**
1069
1335
  * Webhook signature verification utilities
1070
1336
  */
@@ -1113,4 +1379,4 @@ declare const webhookUtils: {
1113
1379
  */
1114
1380
  declare function collectAll<T>(iterable: AsyncIterable<T>): Promise<T[]>;
1115
1381
 
1116
- export { type Attachment, type AttachmentStatus, type AttachmentWithUrl, AuthenticationError, type AuthorType, type Brand, type BulkAction, type BulkActionResult, type Category, type CategoryStats, type Comment, type Company, ConflictError, 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 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 TicketPriority, type TicketSource, type TicketStatus, TimeoutError, type UpdateBrandInput, type UpdateCategoryInput, type UpdateCommentInput, type UpdateCustomerInput, type UpdateFieldInput, type UpdateTagInput, type UpdateTicketInput, ValidationError, type Webhook, type WebhookDelivery, type WebhookEvent, collectAll, webhookUtils };
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 };