@dispatchtickets/sdk 0.5.0 → 0.7.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.cjs +311 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +471 -1
- package/dist/index.d.ts +471 -1
- package/dist/index.js +311 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/utils/http.ts","../src/resources/base.ts","../src/resources/accounts.ts","../src/resources/brands.ts","../src/resources/tickets.ts","../src/resources/comments.ts","../src/resources/attachments.ts","../src/resources/webhooks.ts","../src/resources/categories.ts","../src/resources/tags.ts","../src/resources/customers.ts","../src/resources/fields.ts","../src/utils/webhooks.ts","../src/client.ts","../src/types/events.ts","../src/utils/pagination.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Base error class for all Dispatch Tickets SDK errors\n */\nexport class DispatchTicketsError extends Error {\n readonly code: string;\n readonly statusCode?: number;\n readonly details?: Record<string, unknown>;\n /** Request ID for debugging with support */\n readonly requestId?: string;\n\n constructor(\n message: string,\n code: string,\n statusCode?: number,\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message);\n this.name = 'DispatchTicketsError';\n this.code = code;\n this.statusCode = statusCode;\n this.details = details;\n this.requestId = requestId;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when API key is missing or invalid\n */\nexport class AuthenticationError extends DispatchTicketsError {\n constructor(message = 'Invalid or missing API key', requestId?: string) {\n super(message, 'authentication_error', 401, undefined, requestId);\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * Thrown when rate limit is exceeded\n */\nexport class RateLimitError extends DispatchTicketsError {\n readonly retryAfter?: number;\n /** Rate limit ceiling */\n readonly limit?: number;\n /** Remaining requests in current window */\n readonly remaining?: number;\n /** Unix timestamp when rate limit resets */\n readonly reset?: number;\n\n constructor(\n message = 'Rate limit exceeded',\n retryAfter?: number,\n requestId?: string,\n rateLimitInfo?: { limit?: number; remaining?: number; reset?: number }\n ) {\n super(message, 'rate_limit_error', 429, undefined, requestId);\n this.name = 'RateLimitError';\n this.retryAfter = retryAfter;\n this.limit = rateLimitInfo?.limit;\n this.remaining = rateLimitInfo?.remaining;\n this.reset = rateLimitInfo?.reset;\n }\n}\n\n/**\n * Thrown when request validation fails\n */\nexport class ValidationError extends DispatchTicketsError {\n readonly errors?: Array<{ field: string; message: string }>;\n\n constructor(\n message = 'Validation failed',\n errors?: Array<{ field: string; message: string }>,\n requestId?: string\n ) {\n super(message, 'validation_error', 400, { errors }, requestId);\n this.name = 'ValidationError';\n this.errors = errors;\n }\n}\n\n/**\n * Thrown when a resource is not found\n */\nexport class NotFoundError extends DispatchTicketsError {\n readonly resourceType?: string;\n readonly resourceId?: string;\n\n constructor(\n message = 'Resource not found',\n resourceType?: string,\n resourceId?: string,\n requestId?: string\n ) {\n super(message, 'not_found', 404, { resourceType, resourceId }, requestId);\n this.name = 'NotFoundError';\n this.resourceType = resourceType;\n this.resourceId = resourceId;\n }\n}\n\n/**\n * Thrown when there's a conflict (e.g., duplicate resource)\n */\nexport class ConflictError extends DispatchTicketsError {\n constructor(message = 'Resource conflict', requestId?: string) {\n super(message, 'conflict', 409, undefined, requestId);\n this.name = 'ConflictError';\n }\n}\n\n/**\n * Thrown when the server returns an unexpected error\n */\nexport class ServerError extends DispatchTicketsError {\n constructor(message = 'Internal server error', statusCode = 500, requestId?: string) {\n super(message, 'server_error', statusCode, undefined, requestId);\n this.name = 'ServerError';\n }\n}\n\n/**\n * Thrown when request times out\n */\nexport class TimeoutError extends DispatchTicketsError {\n constructor(message = 'Request timed out') {\n super(message, 'timeout_error');\n this.name = 'TimeoutError';\n }\n}\n\n/**\n * Thrown when network connection fails\n */\nexport class NetworkError extends DispatchTicketsError {\n constructor(message = 'Network error') {\n super(message, 'network_error');\n this.name = 'NetworkError';\n }\n}\n\n// ============================================\n// Type Guards\n// ============================================\n\n/**\n * Check if an error is a DispatchTicketsError\n */\nexport function isDispatchTicketsError(error: unknown): error is DispatchTicketsError {\n return error instanceof DispatchTicketsError;\n}\n\n/**\n * Check if an error is an AuthenticationError\n */\nexport function isAuthenticationError(error: unknown): error is AuthenticationError {\n return error instanceof AuthenticationError;\n}\n\n/**\n * Check if an error is a RateLimitError\n */\nexport function isRateLimitError(error: unknown): error is RateLimitError {\n return error instanceof RateLimitError;\n}\n\n/**\n * Check if an error is a ValidationError\n */\nexport function isValidationError(error: unknown): error is ValidationError {\n return error instanceof ValidationError;\n}\n\n/**\n * Check if an error is a NotFoundError\n */\nexport function isNotFoundError(error: unknown): error is NotFoundError {\n return error instanceof NotFoundError;\n}\n\n/**\n * Check if an error is a ConflictError\n */\nexport function isConflictError(error: unknown): error is ConflictError {\n return error instanceof ConflictError;\n}\n\n/**\n * Check if an error is a ServerError\n */\nexport function isServerError(error: unknown): error is ServerError {\n return error instanceof ServerError;\n}\n\n/**\n * Check if an error is a TimeoutError\n */\nexport function isTimeoutError(error: unknown): error is TimeoutError {\n return error instanceof TimeoutError;\n}\n\n/**\n * Check if an error is a NetworkError\n */\nexport function isNetworkError(error: unknown): error is NetworkError {\n return error instanceof NetworkError;\n}\n","import {\n DispatchTicketsError,\n AuthenticationError,\n RateLimitError,\n ValidationError,\n NotFoundError,\n ConflictError,\n ServerError,\n TimeoutError,\n NetworkError,\n} from '../errors.js';\n\n/**\n * Custom fetch function type\n */\nexport type FetchFunction = typeof fetch;\n\n/**\n * Request context passed to hooks\n */\nexport interface RequestContext {\n /** HTTP method */\n method: string;\n /** Full URL being requested */\n url: string;\n /** Request headers */\n headers: Record<string, string>;\n /** Request body (if any) */\n body?: unknown;\n /** Retry attempt number (0 = first attempt) */\n attempt: number;\n}\n\n/**\n * Response context passed to hooks\n */\nexport interface ResponseContext {\n /** The request that was made */\n request: RequestContext;\n /** HTTP status code */\n status: number;\n /** Response headers */\n headers: Headers;\n /** Request ID from server */\n requestId?: string;\n /** Rate limit info from server */\n rateLimit?: RateLimitInfo;\n /** Duration of the request in milliseconds */\n durationMs: number;\n}\n\n/**\n * Retry configuration options\n */\nexport interface RetryConfig {\n /**\n * Maximum number of retry attempts\n * @default 3\n */\n maxRetries?: number;\n\n /**\n * HTTP status codes that should trigger a retry\n * @default [429, 500, 502, 503, 504]\n */\n retryableStatuses?: number[];\n\n /**\n * Whether to retry on network errors\n * @default true\n */\n retryOnNetworkError?: boolean;\n\n /**\n * Whether to retry on timeout errors\n * @default true\n */\n retryOnTimeout?: boolean;\n\n /**\n * Initial delay between retries in milliseconds\n * @default 1000\n */\n initialDelayMs?: number;\n\n /**\n * Maximum delay between retries in milliseconds\n * @default 30000\n */\n maxDelayMs?: number;\n\n /**\n * Multiplier for exponential backoff\n * @default 2\n */\n backoffMultiplier?: number;\n\n /**\n * Jitter factor (0-1) to add randomness to delays\n * @default 0.25\n */\n jitter?: number;\n}\n\n/**\n * Hooks for observability and customization\n */\nexport interface Hooks {\n /**\n * Called before each request is sent\n * Can modify the request or throw to abort\n */\n onRequest?: (context: RequestContext) => void | Promise<void>;\n\n /**\n * Called after each successful response\n */\n onResponse?: (context: ResponseContext) => void | Promise<void>;\n\n /**\n * Called when an error occurs (before retry)\n */\n onError?: (error: Error, context: RequestContext) => void | Promise<void>;\n\n /**\n * Called before each retry attempt\n */\n onRetry?: (context: RequestContext, error: Error, delayMs: number) => void | Promise<void>;\n}\n\nexport interface HttpClientConfig {\n baseUrl: string;\n apiKey: string;\n timeout: number;\n maxRetries: number;\n debug?: boolean;\n /**\n * Custom fetch implementation for testing/mocking\n */\n fetch?: FetchFunction;\n /**\n * Fine-grained retry configuration\n */\n retry?: RetryConfig;\n /**\n * Hooks for observability\n */\n hooks?: Hooks;\n}\n\nexport interface RequestOptions {\n method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';\n path: string;\n body?: unknown;\n query?: Record<string, string | number | boolean | undefined>;\n headers?: Record<string, string>;\n idempotencyKey?: string;\n /**\n * AbortSignal to cancel the request\n */\n signal?: AbortSignal;\n}\n\ninterface ApiErrorResponse {\n message?: string;\n error?: string;\n errors?: Array<{ field: string; message: string }>;\n code?: string;\n}\n\n/**\n * Rate limit information from response headers\n */\nexport interface RateLimitInfo {\n /** Maximum requests allowed in the current window */\n limit: number;\n /** Remaining requests in the current window */\n remaining: number;\n /** Unix timestamp (seconds) when the rate limit resets */\n reset: number;\n}\n\n/**\n * Response wrapper with rate limit info\n */\nexport interface ResponseWithRateLimit<T> {\n data: T;\n rateLimit?: RateLimitInfo;\n requestId?: string;\n}\n\n/**\n * HTTP client with retry logic, hooks, and error handling\n */\nexport class HttpClient {\n private readonly config: HttpClientConfig;\n private readonly fetchFn: FetchFunction;\n private readonly retryConfig: Required<RetryConfig>;\n\n /** Rate limit info from the last response */\n private _lastRateLimit?: RateLimitInfo;\n /** Request ID from the last response */\n private _lastRequestId?: string;\n\n constructor(config: HttpClientConfig) {\n this.config = config;\n this.fetchFn = config.fetch ?? fetch;\n\n // Merge retry config with defaults\n this.retryConfig = {\n maxRetries: config.retry?.maxRetries ?? config.maxRetries,\n retryableStatuses: config.retry?.retryableStatuses ?? [429, 500, 502, 503, 504],\n retryOnNetworkError: config.retry?.retryOnNetworkError ?? true,\n retryOnTimeout: config.retry?.retryOnTimeout ?? true,\n initialDelayMs: config.retry?.initialDelayMs ?? 1000,\n maxDelayMs: config.retry?.maxDelayMs ?? 30000,\n backoffMultiplier: config.retry?.backoffMultiplier ?? 2,\n jitter: config.retry?.jitter ?? 0.25,\n };\n }\n\n /**\n * Get rate limit info from the last response\n */\n get lastRateLimit(): RateLimitInfo | undefined {\n return this._lastRateLimit;\n }\n\n /**\n * Get request ID from the last response\n */\n get lastRequestId(): string | undefined {\n return this._lastRequestId;\n }\n\n /**\n * Execute an HTTP request with retry logic\n */\n async request<T>(options: RequestOptions): Promise<T> {\n const url = this.buildUrl(options.path, options.query);\n const headers = this.buildHeaders(options.headers, options.idempotencyKey);\n\n let lastError: Error | undefined;\n let attempt = 0;\n\n while (attempt <= this.retryConfig.maxRetries) {\n const requestContext: RequestContext = {\n method: options.method,\n url,\n headers,\n body: options.body,\n attempt,\n };\n\n try {\n // Call onRequest hook\n if (this.config.hooks?.onRequest) {\n await this.config.hooks.onRequest(requestContext);\n }\n\n const startTime = Date.now();\n const response = await this.executeRequest(\n url,\n options.method,\n headers,\n options.body,\n options.signal\n );\n const durationMs = Date.now() - startTime;\n\n const result = await this.handleResponse<T>(response, requestContext, durationMs);\n return result;\n } catch (error) {\n lastError = error as Error;\n\n // Call onError hook\n if (this.config.hooks?.onError) {\n await this.config.hooks.onError(lastError, requestContext);\n }\n\n // Check if we should retry\n if (attempt < this.retryConfig.maxRetries && this.shouldRetry(lastError)) {\n const delay = this.calculateDelay(lastError, attempt);\n\n // Call onRetry hook\n if (this.config.hooks?.onRetry) {\n await this.config.hooks.onRetry(requestContext, lastError, delay);\n }\n\n await this.sleep(delay);\n attempt++;\n continue;\n }\n\n throw lastError;\n }\n }\n\n throw lastError || new NetworkError('Request failed after retries');\n }\n\n /**\n * Execute request and return response with rate limit info\n */\n async requestWithRateLimit<T>(options: RequestOptions): Promise<ResponseWithRateLimit<T>> {\n const data = await this.request<T>(options);\n return {\n data,\n rateLimit: this._lastRateLimit,\n requestId: this._lastRequestId,\n };\n }\n\n private shouldRetry(error: Error): boolean {\n // Never retry client errors (except rate limits handled specially)\n if (\n error instanceof AuthenticationError ||\n error instanceof ValidationError ||\n error instanceof NotFoundError ||\n error instanceof ConflictError\n ) {\n return false;\n }\n\n // Retry on rate limit (uses retry-after header for delay)\n if (error instanceof RateLimitError) {\n return true;\n }\n\n // Retry on configured status codes (ServerError)\n if (error instanceof ServerError && error.statusCode) {\n return this.retryConfig.retryableStatuses.includes(error.statusCode);\n }\n\n // Retry on network errors if configured\n if (error instanceof NetworkError) {\n return this.retryConfig.retryOnNetworkError;\n }\n\n // Retry on timeout if configured\n if (error instanceof TimeoutError) {\n return this.retryConfig.retryOnTimeout;\n }\n\n return false;\n }\n\n private calculateDelay(error: Error, attempt: number): number {\n // Use retry-after header for rate limits\n if (error instanceof RateLimitError && error.retryAfter) {\n return error.retryAfter * 1000;\n }\n\n // Exponential backoff with jitter\n const baseDelay = this.retryConfig.initialDelayMs;\n const delay = Math.min(\n baseDelay * Math.pow(this.retryConfig.backoffMultiplier, attempt),\n this.retryConfig.maxDelayMs\n );\n\n // Add jitter\n const jitter = delay * this.retryConfig.jitter * Math.random();\n return delay + jitter;\n }\n\n private buildUrl(path: string, query?: Record<string, string | number | boolean | undefined>): string {\n const url = new URL(path, this.config.baseUrl);\n\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n return url.toString();\n }\n\n private buildHeaders(\n customHeaders?: Record<string, string>,\n idempotencyKey?: string\n ): Record<string, string> {\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.config.apiKey}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n ...customHeaders,\n };\n\n if (idempotencyKey) {\n headers['X-Idempotency-Key'] = idempotencyKey;\n }\n\n return headers;\n }\n\n private async executeRequest(\n url: string,\n method: string,\n headers: Record<string, string>,\n body?: unknown,\n userSignal?: AbortSignal\n ): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n // Create a combined signal that aborts on either timeout or user signal\n const abortHandler = () => controller.abort();\n userSignal?.addEventListener('abort', abortHandler);\n\n try {\n if (this.config.debug) {\n console.log(`[DispatchTickets] ${method} ${url}`);\n if (body) {\n console.log('[DispatchTickets] Body:', JSON.stringify(body, null, 2));\n }\n }\n\n // Check if user already aborted\n if (userSignal?.aborted) {\n throw new Error('Request aborted');\n }\n\n const response = await this.fetchFn(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n return response;\n } catch (error) {\n if (error instanceof Error) {\n // Check if it was a user abort vs timeout\n if (error.name === 'AbortError') {\n if (userSignal?.aborted) {\n throw new NetworkError('Request aborted by user');\n }\n throw new TimeoutError(`Request timed out after ${this.config.timeout}ms`);\n }\n throw new NetworkError(error.message);\n }\n throw new NetworkError('Unknown network error');\n } finally {\n clearTimeout(timeoutId);\n userSignal?.removeEventListener('abort', abortHandler);\n }\n }\n\n private extractRateLimitInfo(response: Response): RateLimitInfo | undefined {\n const limit = response.headers.get('x-ratelimit-limit');\n const remaining = response.headers.get('x-ratelimit-remaining');\n const reset = response.headers.get('x-ratelimit-reset');\n\n if (limit && remaining && reset) {\n return {\n limit: parseInt(limit, 10),\n remaining: parseInt(remaining, 10),\n reset: parseInt(reset, 10),\n };\n }\n\n return undefined;\n }\n\n private async handleResponse<T>(\n response: Response,\n requestContext: RequestContext,\n durationMs: number\n ): Promise<T> {\n const contentType = response.headers.get('content-type');\n const isJson = contentType?.includes('application/json');\n\n // Extract request ID and rate limit info\n const requestId = response.headers.get('x-request-id') ?? undefined;\n const rateLimitInfo = this.extractRateLimitInfo(response);\n\n // Store for access via getters\n this._lastRequestId = requestId;\n this._lastRateLimit = rateLimitInfo;\n\n if (this.config.debug && requestId) {\n console.log(`[DispatchTickets] Request ID: ${requestId}`);\n }\n\n // Call onResponse hook for successful responses\n if (response.ok && this.config.hooks?.onResponse) {\n await this.config.hooks.onResponse({\n request: requestContext,\n status: response.status,\n headers: response.headers,\n requestId,\n rateLimit: rateLimitInfo,\n durationMs,\n });\n }\n\n if (response.ok) {\n if (response.status === 204 || !isJson) {\n return undefined as T;\n }\n return (await response.json()) as T;\n }\n\n // Handle error responses\n let errorData: ApiErrorResponse = {};\n if (isJson) {\n try {\n errorData = (await response.json()) as ApiErrorResponse;\n } catch {\n // Ignore JSON parse errors for error responses\n }\n }\n\n const message = errorData.message || errorData.error || response.statusText;\n\n switch (response.status) {\n case 401:\n throw new AuthenticationError(message, requestId);\n case 400:\n case 422:\n throw new ValidationError(message, errorData.errors, requestId);\n case 404:\n throw new NotFoundError(message, undefined, undefined, requestId);\n case 409:\n throw new ConflictError(message, requestId);\n case 429: {\n const retryAfter = response.headers.get('retry-after');\n throw new RateLimitError(\n message,\n retryAfter ? parseInt(retryAfter, 10) : undefined,\n requestId,\n rateLimitInfo\n );\n }\n default:\n if (response.status >= 500) {\n throw new ServerError(message, response.status, requestId);\n }\n throw new DispatchTicketsError(\n message,\n 'api_error',\n response.status,\n errorData as Record<string, unknown>,\n requestId\n );\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { HttpClient, RequestOptions } from '../utils/http.js';\n\n/**\n * Options for API requests\n */\nexport interface ApiRequestOptions {\n /**\n * AbortSignal to cancel the request\n *\n * @example\n * ```typescript\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 5000);\n *\n * const ticket = await client.tickets.get('ws_abc', 'tkt_xyz', {\n * signal: controller.signal,\n * });\n * ```\n */\n signal?: AbortSignal;\n}\n\n/**\n * Base class for all resource classes\n * @internal\n */\nexport abstract class BaseResource {\n protected readonly http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n protected async _get<T>(\n path: string,\n query?: RequestOptions['query'],\n options?: ApiRequestOptions\n ): Promise<T> {\n return this.http.request<T>({\n method: 'GET',\n path,\n query,\n signal: options?.signal,\n });\n }\n\n protected async _post<T>(\n path: string,\n body?: unknown,\n options?: { idempotencyKey?: string; query?: RequestOptions['query']; signal?: AbortSignal }\n ): Promise<T> {\n return this.http.request<T>({\n method: 'POST',\n path,\n body,\n idempotencyKey: options?.idempotencyKey,\n query: options?.query,\n signal: options?.signal,\n });\n }\n\n protected async _patch<T>(\n path: string,\n body?: unknown,\n options?: ApiRequestOptions\n ): Promise<T> {\n return this.http.request<T>({\n method: 'PATCH',\n path,\n body,\n signal: options?.signal,\n });\n }\n\n protected async _put<T>(\n path: string,\n body?: unknown,\n options?: ApiRequestOptions\n ): Promise<T> {\n return this.http.request<T>({\n method: 'PUT',\n path,\n body,\n signal: options?.signal,\n });\n }\n\n protected async _delete<T>(\n path: string,\n query?: RequestOptions['query'],\n options?: ApiRequestOptions\n ): Promise<T> {\n return this.http.request<T>({\n method: 'DELETE',\n path,\n query,\n signal: options?.signal,\n });\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Account,\n AccountUsage,\n ApiKey,\n ApiKeyWithSecret,\n CreateApiKeyInput,\n UpdateApiKeyScopeInput,\n} from '../types/account.js';\n\n/**\n * Accounts resource for managing the current account\n */\nexport class AccountsResource extends BaseResource {\n /**\n * Get the current account\n */\n async me(): Promise<Account> {\n return this._get<Account>('/accounts/me');\n }\n\n /**\n * Get usage statistics for the current account\n */\n async getUsage(): Promise<AccountUsage> {\n return this._get<AccountUsage>('/accounts/me/usage');\n }\n\n /**\n * List all API keys for the current account\n */\n async listApiKeys(): Promise<ApiKey[]> {\n return this._get<ApiKey[]>('/accounts/me/api-keys');\n }\n\n /**\n * Create a new API key\n *\n * Note: The full key value is only returned once on creation.\n * Store it securely as it cannot be retrieved again.\n */\n async createApiKey(data: CreateApiKeyInput): Promise<ApiKeyWithSecret> {\n return this._post<ApiKeyWithSecret>('/accounts/me/api-keys', data);\n }\n\n /**\n * Update the brand scope for an API key\n */\n async updateApiKeyScope(\n keyId: string,\n data: UpdateApiKeyScopeInput\n ): Promise<{ success: boolean }> {\n return this._patch<{ success: boolean }>(\n `/accounts/me/api-keys/${keyId}/scope`,\n data\n );\n }\n\n /**\n * Revoke an API key\n */\n async revokeApiKey(keyId: string): Promise<void> {\n await this._delete<void>(`/accounts/me/api-keys/${keyId}`);\n }\n}\n","import { BaseResource } from './base.js';\nimport type { Brand, CreateBrandInput, UpdateBrandInput, DeleteBrandPreview } from '../types/brand.js';\n\n/**\n * Brands resource for managing workspaces\n */\nexport class BrandsResource extends BaseResource {\n /**\n * Create a new brand\n */\n async create(data: CreateBrandInput): Promise<Brand> {\n return this._post<Brand>('/brands', data);\n }\n\n /**\n * List all brands\n */\n async list(): Promise<Brand[]> {\n return this._get<Brand[]>('/brands');\n }\n\n /**\n * Get a brand by ID\n */\n async get(brandId: string): Promise<Brand> {\n return this._get<Brand>(`/brands/${brandId}`);\n }\n\n /**\n * Update a brand\n */\n async update(brandId: string, data: UpdateBrandInput): Promise<Brand> {\n return this._patch<Brand>(`/brands/${brandId}`, data);\n }\n\n /**\n * Delete a brand\n * @param brandId - The brand ID\n * @param confirm - Set to true to actually delete; false to preview what would be deleted\n */\n async delete(brandId: string, confirm = true): Promise<void | DeleteBrandPreview> {\n if (confirm) {\n await this._delete<void>(`/brands/${brandId}`, { confirm: true });\n return;\n }\n return this._delete<DeleteBrandPreview>(`/brands/${brandId}`);\n }\n\n /**\n * Get the ticket schema for a brand\n */\n async getSchema(brandId: string): Promise<Record<string, unknown>> {\n return this._get<Record<string, unknown>>(`/brands/${brandId}/schema`);\n }\n\n /**\n * Update the ticket schema for a brand\n */\n async updateSchema(brandId: string, schema: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this._put<Record<string, unknown>>(`/brands/${brandId}/schema`, schema);\n }\n\n /**\n * Get the inbound email address for a brand\n *\n * Emails sent to this address will automatically create tickets.\n *\n * @param brandId - The brand ID\n * @param domain - Optional custom inbound domain (default: inbound.dispatchtickets.com)\n * @returns The inbound email address\n *\n * @example\n * ```typescript\n * const email = client.brands.getInboundEmail('br_abc123');\n * // Returns: br_abc123@inbound.dispatchtickets.com\n *\n * // With custom domain:\n * const customEmail = client.brands.getInboundEmail('br_abc123', 'support.mycompany.com');\n * // Returns: br_abc123@support.mycompany.com\n * ```\n */\n getInboundEmail(brandId: string, domain = 'inbound.dispatchtickets.com'): string {\n return `${brandId}@${domain}`;\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Ticket,\n CreateTicketInput,\n UpdateTicketInput,\n ListTicketsFilters,\n CreateTicketOptions,\n MergeTicketsInput,\n BulkActionResult,\n} from '../types/ticket.js';\nimport type { PaginatedResponse, BulkAction } from '../types/common.js';\n\n/**\n * Tickets resource\n */\nexport class TicketsResource extends BaseResource {\n /**\n * Create a new ticket\n */\n async create(\n brandId: string,\n data: CreateTicketInput,\n options?: CreateTicketOptions\n ): Promise<Ticket> {\n return this._post<Ticket>(`/brands/${brandId}/tickets`, data, {\n idempotencyKey: options?.idempotencyKey,\n });\n }\n\n /**\n * List tickets with pagination (async iterator)\n * Automatically fetches all pages\n */\n async *list(\n brandId: string,\n filters?: Omit<ListTicketsFilters, 'cursor'>\n ): AsyncIterable<Ticket> {\n let cursor: string | undefined;\n let hasMore = true;\n\n while (hasMore) {\n const page = await this.listPage(brandId, { ...filters, cursor });\n for (const ticket of page.data) {\n yield ticket;\n }\n cursor = page.pagination.cursor;\n hasMore = page.pagination.hasMore;\n }\n }\n\n /**\n * List a single page of tickets\n */\n async listPage(\n brandId: string,\n filters?: ListTicketsFilters\n ): Promise<PaginatedResponse<Ticket>> {\n const query = this.buildListQuery(filters);\n return this._get<PaginatedResponse<Ticket>>(`/brands/${brandId}/tickets`, query);\n }\n\n /**\n * Get a ticket by ID\n */\n async get(brandId: string, ticketId: string): Promise<Ticket> {\n return this._get<Ticket>(`/brands/${brandId}/tickets/${ticketId}`);\n }\n\n /**\n * Update a ticket\n */\n async update(\n brandId: string,\n ticketId: string,\n data: UpdateTicketInput\n ): Promise<Ticket> {\n return this._patch<Ticket>(`/brands/${brandId}/tickets/${ticketId}`, data);\n }\n\n /**\n * Delete a ticket\n */\n async delete(brandId: string, ticketId: string): Promise<Ticket> {\n return this._delete<Ticket>(`/brands/${brandId}/tickets/${ticketId}`);\n }\n\n /**\n * Mark a ticket as spam or not spam\n */\n async markAsSpam(brandId: string, ticketId: string, isSpam: boolean): Promise<Ticket> {\n return this._post<Ticket>(`/brands/${brandId}/tickets/${ticketId}/spam`, { isSpam });\n }\n\n /**\n * Merge tickets into a target ticket\n */\n async merge(\n brandId: string,\n targetTicketId: string,\n sourceTicketIds: string[]\n ): Promise<Ticket> {\n return this._post<Ticket>(`/brands/${brandId}/tickets/${targetTicketId}/merge`, {\n sourceTicketIds,\n } satisfies MergeTicketsInput);\n }\n\n /**\n * Perform a bulk action on multiple tickets\n */\n async bulk(\n brandId: string,\n action: BulkAction,\n ticketIds: string[],\n options?: {\n assigneeId?: string | null;\n categoryId?: string | null;\n tags?: string[];\n }\n ): Promise<BulkActionResult> {\n return this._post<BulkActionResult>(`/brands/${brandId}/tickets/bulk`, {\n action,\n ticketIds,\n ...options,\n });\n }\n\n private buildListQuery(\n filters?: ListTicketsFilters\n ): Record<string, string | number | boolean | undefined> {\n if (!filters) return {};\n\n const query: Record<string, string | number | boolean | undefined> = {};\n\n if (filters.status) {\n query.status = Array.isArray(filters.status)\n ? filters.status.join(',')\n : filters.status;\n }\n if (filters.priority) query.priority = filters.priority;\n if (filters.assigneeId) query.assigneeId = filters.assigneeId;\n if (filters.customerId) query.customerId = filters.customerId;\n if (filters.customerEmail) query.customerEmail = filters.customerEmail;\n if (filters.createdBy) query.createdBy = filters.createdBy;\n if (filters.createdAfter) query.createdAfter = filters.createdAfter;\n if (filters.createdBefore) query.createdBefore = filters.createdBefore;\n if (filters.hasAttachments !== undefined) query.hasAttachments = filters.hasAttachments;\n if (filters.isSpam !== undefined) query.isSpam = filters.isSpam;\n if (filters.search) query.search = filters.search;\n if (filters.categoryId) query.categoryId = filters.categoryId;\n if (filters.tagIds) query.tagIds = filters.tagIds.join(',');\n if (filters.source) query.source = filters.source;\n if (filters.sort) query.sort = filters.sort;\n if (filters.order) query.order = filters.order;\n if (filters.limit) query.limit = filters.limit;\n if (filters.cursor) query.cursor = filters.cursor;\n\n return query;\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Comment,\n CreateCommentInput,\n UpdateCommentInput,\n CreateCommentOptions,\n} from '../types/comment.js';\n\n/**\n * Comments resource\n */\nexport class CommentsResource extends BaseResource {\n /**\n * Create a new comment on a ticket\n */\n async create(\n brandId: string,\n ticketId: string,\n data: CreateCommentInput,\n options?: CreateCommentOptions\n ): Promise<Comment> {\n return this._post<Comment>(\n `/brands/${brandId}/tickets/${ticketId}/comments`,\n data,\n { idempotencyKey: options?.idempotencyKey }\n );\n }\n\n /**\n * List all comments on a ticket\n */\n async list(brandId: string, ticketId: string): Promise<Comment[]> {\n return this._get<Comment[]>(`/brands/${brandId}/tickets/${ticketId}/comments`);\n }\n\n /**\n * Get a comment by ID\n */\n async get(brandId: string, ticketId: string, commentId: string): Promise<Comment> {\n return this._get<Comment>(\n `/brands/${brandId}/tickets/${ticketId}/comments/${commentId}`\n );\n }\n\n /**\n * Update a comment\n */\n async update(\n brandId: string,\n ticketId: string,\n commentId: string,\n data: UpdateCommentInput\n ): Promise<Comment> {\n return this._patch<Comment>(\n `/brands/${brandId}/tickets/${ticketId}/comments/${commentId}`,\n data\n );\n }\n\n /**\n * Delete a comment\n */\n async delete(brandId: string, ticketId: string, commentId: string): Promise<Comment> {\n return this._delete<Comment>(\n `/brands/${brandId}/tickets/${ticketId}/comments/${commentId}`\n );\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Attachment,\n AttachmentWithUrl,\n InitiateUploadInput,\n InitiateUploadResponse,\n} from '../types/attachment.js';\n\n/**\n * Attachments resource\n */\nexport class AttachmentsResource extends BaseResource {\n /**\n * Initiate an upload and get a presigned URL\n */\n async initiateUpload(\n brandId: string,\n ticketId: string,\n data: InitiateUploadInput\n ): Promise<InitiateUploadResponse> {\n return this._post<InitiateUploadResponse>(\n `/brands/${brandId}/tickets/${ticketId}/attachments`,\n data\n );\n }\n\n /**\n * Confirm that an upload has completed\n */\n async confirmUpload(\n brandId: string,\n ticketId: string,\n attachmentId: string\n ): Promise<Attachment> {\n return this._post<Attachment>(\n `/brands/${brandId}/tickets/${ticketId}/attachments/${attachmentId}/confirm`\n );\n }\n\n /**\n * List all attachments on a ticket\n */\n async list(brandId: string, ticketId: string): Promise<Attachment[]> {\n return this._get<Attachment[]>(`/brands/${brandId}/tickets/${ticketId}/attachments`);\n }\n\n /**\n * Get an attachment with its download URL\n */\n async get(\n brandId: string,\n ticketId: string,\n attachmentId: string\n ): Promise<AttachmentWithUrl> {\n return this._get<AttachmentWithUrl>(\n `/brands/${brandId}/tickets/${ticketId}/attachments/${attachmentId}`\n );\n }\n\n /**\n * Delete an attachment\n */\n async delete(\n brandId: string,\n ticketId: string,\n attachmentId: string\n ): Promise<void> {\n await this._delete<void>(\n `/brands/${brandId}/tickets/${ticketId}/attachments/${attachmentId}`\n );\n }\n\n /**\n * Convenience method: Upload a file in one step\n * Handles: initiate -> upload to presigned URL -> confirm\n */\n async upload(\n brandId: string,\n ticketId: string,\n file: Blob | Buffer | ArrayBuffer,\n filename: string,\n contentType: string\n ): Promise<Attachment> {\n // Get file size\n let size: number;\n if (file instanceof Blob) {\n size = file.size;\n } else if (Buffer.isBuffer(file)) {\n size = file.length;\n } else {\n size = file.byteLength;\n }\n\n // Initiate upload\n const { uploadUrl, attachmentId } = await this.initiateUpload(brandId, ticketId, {\n filename,\n contentType,\n size,\n });\n\n // Upload to presigned URL\n const uploadResponse = await fetch(uploadUrl, {\n method: 'PUT',\n headers: {\n 'Content-Type': contentType,\n 'Content-Length': String(size),\n },\n body: file,\n });\n\n if (!uploadResponse.ok) {\n throw new Error(`Upload failed: ${uploadResponse.statusText}`);\n }\n\n // Confirm upload\n return this.confirmUpload(brandId, ticketId, attachmentId);\n }\n}\n","import { BaseResource } from './base.js';\nimport type { Webhook, CreateWebhookInput, WebhookDelivery } from '../types/webhook.js';\n\n/**\n * Webhooks resource\n */\nexport class WebhooksResource extends BaseResource {\n /**\n * Create a new webhook\n */\n async create(brandId: string, data: CreateWebhookInput): Promise<Webhook> {\n return this._post<Webhook>(`/brands/${brandId}/webhooks`, data);\n }\n\n /**\n * List all webhooks for a brand\n */\n async list(brandId: string): Promise<Webhook[]> {\n return this._get<Webhook[]>(`/brands/${brandId}/webhooks`);\n }\n\n /**\n * Get a webhook by ID\n */\n async get(brandId: string, webhookId: string): Promise<Webhook> {\n return this._get<Webhook>(`/brands/${brandId}/webhooks/${webhookId}`);\n }\n\n /**\n * Delete a webhook\n */\n async delete(brandId: string, webhookId: string): Promise<void> {\n await this._delete<void>(`/brands/${brandId}/webhooks/${webhookId}`);\n }\n\n /**\n * Get webhook delivery history\n */\n async getDeliveries(brandId: string, webhookId: string): Promise<WebhookDelivery[]> {\n return this._get<WebhookDelivery[]>(\n `/brands/${brandId}/webhooks/${webhookId}/deliveries`\n );\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Category,\n CreateCategoryInput,\n UpdateCategoryInput,\n CategoryStats,\n} from '../types/category.js';\n\n/**\n * Categories resource\n */\nexport class CategoriesResource extends BaseResource {\n /**\n * Create a new category\n */\n async create(brandId: string, data: CreateCategoryInput): Promise<Category> {\n return this._post<Category>(`/brands/${brandId}/categories`, data);\n }\n\n /**\n * List all categories for a brand\n */\n async list(brandId: string): Promise<Category[]> {\n return this._get<Category[]>(`/brands/${brandId}/categories`);\n }\n\n /**\n * Get a category by ID\n */\n async get(brandId: string, categoryId: string): Promise<Category> {\n return this._get<Category>(`/brands/${brandId}/categories/${categoryId}`);\n }\n\n /**\n * Update a category\n */\n async update(\n brandId: string,\n categoryId: string,\n data: UpdateCategoryInput\n ): Promise<Category> {\n return this._patch<Category>(`/brands/${brandId}/categories/${categoryId}`, data);\n }\n\n /**\n * Delete a category\n */\n async delete(brandId: string, categoryId: string): Promise<void> {\n await this._delete<void>(`/brands/${brandId}/categories/${categoryId}`);\n }\n\n /**\n * Get category statistics (ticket counts)\n */\n async getStats(brandId: string): Promise<CategoryStats> {\n return this._get<CategoryStats>(`/brands/${brandId}/categories/stats`);\n }\n\n /**\n * Reorder categories\n */\n async reorder(brandId: string, categoryIds: string[]): Promise<void> {\n await this._post<void>(`/brands/${brandId}/categories/reorder`, { categoryIds });\n }\n}\n","import { BaseResource } from './base.js';\nimport type { Tag, CreateTagInput, UpdateTagInput } from '../types/tag.js';\n\n/**\n * Tags resource\n */\nexport class TagsResource extends BaseResource {\n /**\n * Create a new tag\n */\n async create(brandId: string, data: CreateTagInput): Promise<Tag> {\n return this._post<Tag>(`/brands/${brandId}/tags`, data);\n }\n\n /**\n * List all tags for a brand\n */\n async list(brandId: string): Promise<Tag[]> {\n return this._get<Tag[]>(`/brands/${brandId}/tags`);\n }\n\n /**\n * Update a tag\n */\n async update(brandId: string, tagId: string, data: UpdateTagInput): Promise<Tag> {\n return this._patch<Tag>(`/brands/${brandId}/tags/${tagId}`, data);\n }\n\n /**\n * Delete a tag\n */\n async delete(brandId: string, tagId: string): Promise<void> {\n await this._delete<void>(`/brands/${brandId}/tags/${tagId}`);\n }\n\n /**\n * Merge tags into a target tag\n */\n async merge(brandId: string, targetTagId: string, sourceTagIds: string[]): Promise<Tag> {\n return this._post<Tag>(`/brands/${brandId}/tags/${targetTagId}/merge`, {\n sourceTagIds,\n });\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Customer,\n CreateCustomerInput,\n UpdateCustomerInput,\n ListCustomersFilters,\n} from '../types/customer.js';\nimport type { PaginatedResponse } from '../types/common.js';\n\n/**\n * Customers resource\n */\nexport class CustomersResource extends BaseResource {\n /**\n * Create a new customer\n */\n async create(brandId: string, data: CreateCustomerInput): Promise<Customer> {\n return this._post<Customer>(`/brands/${brandId}/customers`, data);\n }\n\n /**\n * List customers with pagination (async iterator)\n */\n async *list(\n brandId: string,\n filters?: Omit<ListCustomersFilters, 'cursor'>\n ): AsyncIterable<Customer> {\n let cursor: string | undefined;\n let hasMore = true;\n\n while (hasMore) {\n const page = await this.listPage(brandId, { ...filters, cursor });\n for (const customer of page.data) {\n yield customer;\n }\n cursor = page.pagination.cursor;\n hasMore = page.pagination.hasMore;\n }\n }\n\n /**\n * List a single page of customers\n */\n async listPage(\n brandId: string,\n filters?: ListCustomersFilters\n ): Promise<PaginatedResponse<Customer>> {\n const query = this.buildListQuery(filters);\n return this._get<PaginatedResponse<Customer>>(`/brands/${brandId}/customers`, query);\n }\n\n /**\n * Search customers (autocomplete)\n */\n async search(brandId: string, query: string): Promise<Customer[]> {\n return this._get<Customer[]>(`/brands/${brandId}/customers/search`, { q: query });\n }\n\n /**\n * Get a customer by ID\n */\n async get(brandId: string, customerId: string): Promise<Customer> {\n return this._get<Customer>(`/brands/${brandId}/customers/${customerId}`);\n }\n\n /**\n * Update a customer\n */\n async update(\n brandId: string,\n customerId: string,\n data: UpdateCustomerInput\n ): Promise<Customer> {\n return this._patch<Customer>(`/brands/${brandId}/customers/${customerId}`, data);\n }\n\n /**\n * Delete a customer\n */\n async delete(brandId: string, customerId: string): Promise<Customer> {\n return this._delete<Customer>(`/brands/${brandId}/customers/${customerId}`);\n }\n\n private buildListQuery(\n filters?: ListCustomersFilters\n ): Record<string, string | number | boolean | undefined> {\n if (!filters) return {};\n\n const query: Record<string, string | number | boolean | undefined> = {};\n\n if (filters.limit) query.limit = filters.limit;\n if (filters.cursor) query.cursor = filters.cursor;\n if (filters.sort) query.sort = filters.sort;\n if (filters.order) query.order = filters.order;\n\n return query;\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n FieldDefinition,\n FieldDefinitions,\n CreateFieldInput,\n UpdateFieldInput,\n EntityType,\n} from '../types/field.js';\n\n/**\n * Custom fields resource\n */\nexport class FieldsResource extends BaseResource {\n /**\n * Get all field definitions for a brand\n */\n async getAll(brandId: string): Promise<FieldDefinitions> {\n return this._get<FieldDefinitions>(`/brands/${brandId}/fields`);\n }\n\n /**\n * Get field definitions for a specific entity type\n */\n async list(brandId: string, entityType: EntityType): Promise<FieldDefinition[]> {\n return this._get<FieldDefinition[]>(`/brands/${brandId}/fields/${entityType}`);\n }\n\n /**\n * Create a new field definition\n */\n async create(\n brandId: string,\n entityType: EntityType,\n data: CreateFieldInput\n ): Promise<FieldDefinition> {\n return this._post<FieldDefinition>(`/brands/${brandId}/fields/${entityType}`, data);\n }\n\n /**\n * Update a field definition\n */\n async update(\n brandId: string,\n entityType: EntityType,\n key: string,\n data: UpdateFieldInput\n ): Promise<FieldDefinition> {\n return this._patch<FieldDefinition>(\n `/brands/${brandId}/fields/${entityType}/${key}`,\n data\n );\n }\n\n /**\n * Delete a field definition\n */\n async delete(brandId: string, entityType: EntityType, key: string): Promise<void> {\n await this._delete<void>(`/brands/${brandId}/fields/${entityType}/${key}`);\n }\n\n /**\n * Reorder field definitions\n */\n async reorder(brandId: string, entityType: EntityType, keys: string[]): Promise<void> {\n await this._post<void>(`/brands/${brandId}/fields/${entityType}/reorder`, { keys });\n }\n}\n","import { createHmac, timingSafeEqual } from 'crypto';\n\n/**\n * Webhook signature verification utilities\n */\nexport const webhookUtils = {\n /**\n * Verify a webhook signature\n *\n * @param payload - The raw request body as a string\n * @param signature - The X-Dispatch-Signature header value\n * @param secret - Your webhook secret\n * @returns true if the signature is valid\n *\n * @example\n * ```typescript\n * import { DispatchTickets } from '@dispatchtickets/sdk';\n *\n * app.post('/webhooks', (req, res) => {\n * const signature = req.headers['x-dispatch-signature'];\n * const isValid = DispatchTickets.webhooks.verifySignature(\n * req.rawBody,\n * signature,\n * process.env.WEBHOOK_SECRET\n * );\n *\n * if (!isValid) {\n * return res.status(401).send('Invalid signature');\n * }\n *\n * // Process webhook...\n * });\n * ```\n */\n verifySignature(payload: string, signature: string, secret: string): boolean {\n if (!signature || !secret) {\n return false;\n }\n\n // Signature format: sha256=<hex>\n const parts = signature.split('=');\n if (parts.length !== 2 || parts[0] !== 'sha256') {\n return false;\n }\n\n const receivedSignature = parts[1];\n const expectedSignature = createHmac('sha256', secret)\n .update(payload)\n .digest('hex');\n\n // Use timing-safe comparison to prevent timing attacks\n try {\n const receivedBuffer = Buffer.from(receivedSignature, 'hex');\n const expectedBuffer = Buffer.from(expectedSignature, 'hex');\n\n if (receivedBuffer.length !== expectedBuffer.length) {\n return false;\n }\n\n return timingSafeEqual(receivedBuffer, expectedBuffer);\n } catch {\n return false;\n }\n },\n\n /**\n * Generate a signature for testing purposes\n *\n * @param payload - The payload to sign\n * @param secret - The secret to sign with\n * @returns The signature in the format sha256=<hex>\n */\n generateSignature(payload: string, secret: string): string {\n const signature = createHmac('sha256', secret)\n .update(payload)\n .digest('hex');\n return `sha256=${signature}`;\n },\n};\n","import {\n HttpClient,\n HttpClientConfig,\n FetchFunction,\n RetryConfig,\n Hooks,\n} from './utils/http.js';\nimport { AccountsResource } from './resources/accounts.js';\nimport { BrandsResource } from './resources/brands.js';\nimport { TicketsResource } from './resources/tickets.js';\nimport { CommentsResource } from './resources/comments.js';\nimport { AttachmentsResource } from './resources/attachments.js';\nimport { WebhooksResource } from './resources/webhooks.js';\nimport { CategoriesResource } from './resources/categories.js';\nimport { TagsResource } from './resources/tags.js';\nimport { CustomersResource } from './resources/customers.js';\nimport { FieldsResource } from './resources/fields.js';\nimport { webhookUtils } from './utils/webhooks.js';\n\n/**\n * Configuration options for the Dispatch Tickets client\n *\n * @example\n * ```typescript\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * timeout: 30000,\n * retry: {\n * maxRetries: 5,\n * retryableStatuses: [429, 500, 502, 503, 504],\n * },\n * hooks: {\n * onRequest: (ctx) => console.log(`${ctx.method} ${ctx.url}`),\n * onResponse: (ctx) => console.log(`${ctx.status} in ${ctx.durationMs}ms`),\n * },\n * });\n * ```\n */\nexport interface DispatchTicketsConfig {\n /**\n * Your API key (required)\n *\n * Get your API key from the Dispatch Tickets dashboard.\n * Keys starting with `sk_live_` are production keys.\n * Keys starting with `sk_test_` are test keys.\n */\n apiKey: string;\n\n /**\n * Base URL for the API\n * @default 'https://dispatch-tickets-api.onrender.com/v1'\n */\n baseUrl?: string;\n\n /**\n * Request timeout in milliseconds\n * @default 30000\n */\n timeout?: number;\n\n /**\n * Maximum number of retries for failed requests\n * @default 3\n * @deprecated Use `retry.maxRetries` instead for fine-grained control\n */\n maxRetries?: number;\n\n /**\n * Enable debug logging\n *\n * When enabled, logs all requests, responses, and request IDs to console.\n * @default false\n */\n debug?: boolean;\n\n /**\n * Custom fetch implementation for testing/mocking\n *\n * @example\n * ```typescript\n * const mockFetch = vi.fn().mockResolvedValue({\n * ok: true,\n * status: 200,\n * headers: { get: () => 'application/json' },\n * json: () => Promise.resolve({ id: 'test' }),\n * });\n *\n * const client = new DispatchTickets({\n * apiKey: 'sk_test_...',\n * fetch: mockFetch,\n * });\n * ```\n */\n fetch?: FetchFunction;\n\n /**\n * Fine-grained retry configuration\n *\n * @example\n * ```typescript\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * retry: {\n * maxRetries: 5,\n * retryableStatuses: [429, 500, 502, 503, 504],\n * initialDelayMs: 500,\n * maxDelayMs: 60000,\n * backoffMultiplier: 2,\n * jitter: 0.25,\n * },\n * });\n * ```\n */\n retry?: RetryConfig;\n\n /**\n * Hooks for observability and customization\n *\n * @example\n * ```typescript\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * hooks: {\n * onRequest: (ctx) => {\n * console.log(`[${new Date().toISOString()}] ${ctx.method} ${ctx.url}`);\n * },\n * onResponse: (ctx) => {\n * console.log(`[${ctx.requestId}] ${ctx.status} in ${ctx.durationMs}ms`);\n * },\n * onError: (error, ctx) => {\n * console.error(`Request failed: ${error.message}`);\n * // Send to error tracking service\n * Sentry.captureException(error);\n * },\n * onRetry: (ctx, error, delayMs) => {\n * console.log(`Retrying in ${delayMs}ms (attempt ${ctx.attempt + 1})`);\n * },\n * },\n * });\n * ```\n */\n hooks?: Hooks;\n}\n\n/**\n * Dispatch Tickets SDK client\n *\n * The main entry point for interacting with the Dispatch Tickets API.\n * Create a client instance with your API key and use the resource methods\n * to manage tickets, comments, attachments, and more.\n *\n * @example Basic usage\n * ```typescript\n * import { DispatchTickets } from '@dispatchtickets/sdk';\n *\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * });\n *\n * // List brands\n * const brands = await client.brands.list();\n *\n * // Create a ticket\n * const ticket = await client.tickets.create('ws_abc123', {\n * title: 'Help with login',\n * body: 'I cannot log in to my account',\n * });\n *\n * // Iterate through all tickets\n * for await (const ticket of client.tickets.list('ws_abc123', { status: 'open' })) {\n * console.log(ticket.title);\n * }\n * ```\n *\n * @example With request cancellation\n * ```typescript\n * const controller = new AbortController();\n *\n * // Cancel after 5 seconds\n * setTimeout(() => controller.abort(), 5000);\n *\n * try {\n * const tickets = await client.tickets.listPage('ws_abc123', {}, {\n * signal: controller.signal,\n * });\n * } catch (error) {\n * if (error.message === 'Request aborted by user') {\n * console.log('Request was cancelled');\n * }\n * }\n * ```\n *\n * @example With hooks for logging\n * ```typescript\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * hooks: {\n * onRequest: (ctx) => console.log(`→ ${ctx.method} ${ctx.url}`),\n * onResponse: (ctx) => console.log(`← ${ctx.status} (${ctx.durationMs}ms)`),\n * },\n * });\n * ```\n */\nexport class DispatchTickets {\n private readonly http: HttpClient;\n\n /**\n * Accounts resource for managing the current account and API keys\n *\n * @example\n * ```typescript\n * // Get current account\n * const account = await client.accounts.me();\n *\n * // Get usage statistics\n * const usage = await client.accounts.getUsage();\n *\n * // Create a new API key\n * const newKey = await client.accounts.createApiKey({\n * name: 'Production',\n * allBrands: true,\n * });\n * ```\n */\n readonly accounts: AccountsResource;\n\n /**\n * Brands (workspaces) resource\n *\n * Brands are isolated containers for tickets. Each brand can have its own\n * email address, categories, tags, and settings.\n *\n * @example\n * ```typescript\n * // List all brands\n * const brands = await client.brands.list();\n *\n * // Create a new brand\n * const brand = await client.brands.create({\n * name: 'Acme Support',\n * slug: 'acme',\n * });\n *\n * // Get inbound email address\n * const email = client.brands.getInboundEmail('br_abc123');\n * // Returns: br_abc123@inbound.dispatchtickets.com\n * ```\n */\n readonly brands: BrandsResource;\n\n /**\n * Tickets resource\n *\n * @example\n * ```typescript\n * // Create a ticket\n * const ticket = await client.tickets.create('ws_abc123', {\n * title: 'Issue with billing',\n * body: 'I was charged twice...',\n * priority: 'high',\n * });\n *\n * // Iterate through all tickets\n * for await (const ticket of client.tickets.list('ws_abc123', { status: 'open' })) {\n * console.log(ticket.title);\n * }\n * ```\n */\n readonly tickets: TicketsResource;\n\n /**\n * Comments resource\n *\n * @example\n * ```typescript\n * // Add a comment\n * const comment = await client.comments.create('ws_abc123', 'tkt_xyz', {\n * body: 'Thanks for your patience!',\n * authorType: 'AGENT',\n * });\n *\n * // List comments\n * const comments = await client.comments.list('ws_abc123', 'tkt_xyz');\n * ```\n */\n readonly comments: CommentsResource;\n\n /**\n * Attachments resource\n *\n * @example\n * ```typescript\n * // Simple upload\n * const attachment = await client.attachments.upload(\n * 'ws_abc123',\n * 'tkt_xyz',\n * fileBuffer,\n * 'document.pdf',\n * 'application/pdf'\n * );\n *\n * // Get download URL\n * const { downloadUrl } = await client.attachments.get('ws_abc123', 'tkt_xyz', 'att_abc');\n * ```\n */\n readonly attachments: AttachmentsResource;\n\n /**\n * Webhooks resource\n *\n * @example\n * ```typescript\n * // Create a webhook\n * const webhook = await client.webhooks.create('ws_abc123', {\n * url: 'https://example.com/webhook',\n * secret: 'your-secret',\n * events: ['ticket.created', 'ticket.updated'],\n * });\n * ```\n */\n readonly webhooks: WebhooksResource;\n\n /**\n * Categories resource\n *\n * @example\n * ```typescript\n * // Create a category\n * await client.categories.create('ws_abc123', { name: 'Billing', color: '#ef4444' });\n *\n * // Get category stats\n * const stats = await client.categories.getStats('ws_abc123');\n * ```\n */\n readonly categories: CategoriesResource;\n\n /**\n * Tags resource\n *\n * @example\n * ```typescript\n * // Create a tag\n * await client.tags.create('ws_abc123', { name: 'urgent', color: '#f59e0b' });\n *\n * // Merge tags\n * await client.tags.merge('ws_abc123', 'tag_target', ['tag_source1', 'tag_source2']);\n * ```\n */\n readonly tags: TagsResource;\n\n /**\n * Customers resource\n *\n * @example\n * ```typescript\n * // Create a customer\n * const customer = await client.customers.create('ws_abc123', {\n * email: 'user@example.com',\n * name: 'Jane Doe',\n * });\n *\n * // Search customers\n * const results = await client.customers.search('ws_abc123', 'jane');\n * ```\n */\n readonly customers: CustomersResource;\n\n /**\n * Custom fields resource\n *\n * @example\n * ```typescript\n * // Get all field definitions\n * const fields = await client.fields.getAll('ws_abc123');\n *\n * // Create a field\n * await client.fields.create('ws_abc123', 'ticket', {\n * key: 'order_id',\n * label: 'Order ID',\n * type: 'text',\n * required: true,\n * });\n * ```\n */\n readonly fields: FieldsResource;\n\n /**\n * Static webhook utilities\n *\n * @example\n * ```typescript\n * // Verify webhook signature\n * const isValid = DispatchTickets.webhooks.verifySignature(\n * rawBody,\n * req.headers['x-dispatch-signature'],\n * 'your-secret'\n * );\n *\n * // Generate signature for testing\n * const signature = DispatchTickets.webhooks.generateSignature(\n * JSON.stringify(payload),\n * 'your-secret'\n * );\n * ```\n */\n static readonly webhooks = webhookUtils;\n\n /**\n * Create a new Dispatch Tickets client\n *\n * @param config - Client configuration options\n * @throws Error if API key is not provided\n *\n * @example\n * ```typescript\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * });\n * ```\n */\n constructor(config: DispatchTicketsConfig) {\n if (!config.apiKey) {\n throw new Error('API key is required');\n }\n\n const httpConfig: HttpClientConfig = {\n baseUrl: config.baseUrl || 'https://dispatch-tickets-api.onrender.com/v1',\n apiKey: config.apiKey,\n timeout: config.timeout ?? 30000,\n maxRetries: config.maxRetries ?? config.retry?.maxRetries ?? 3,\n debug: config.debug ?? false,\n fetch: config.fetch,\n retry: config.retry,\n hooks: config.hooks,\n };\n\n this.http = new HttpClient(httpConfig);\n\n // Initialize resources\n this.accounts = new AccountsResource(this.http);\n this.brands = new BrandsResource(this.http);\n this.tickets = new TicketsResource(this.http);\n this.comments = new CommentsResource(this.http);\n this.attachments = new AttachmentsResource(this.http);\n this.webhooks = new WebhooksResource(this.http);\n this.categories = new CategoriesResource(this.http);\n this.tags = new TagsResource(this.http);\n this.customers = new CustomersResource(this.http);\n this.fields = new FieldsResource(this.http);\n }\n}\n","import type { TicketStatus, TicketPriority, TicketSource, AuthorType } from './common.js';\n\n/**\n * All supported webhook event types\n */\nexport type WebhookEventType =\n | 'ticket.created'\n | 'ticket.updated'\n | 'ticket.comment.created';\n\n/**\n * Base webhook event envelope\n */\nexport interface WebhookEventEnvelope<T extends WebhookEventType, D> {\n /** Unique event ID */\n id: string;\n /** Event type */\n event: T;\n /** Brand ID that triggered the event */\n brand_id: string;\n /** Event data */\n data: D;\n /** ISO timestamp when event was created */\n timestamp: string;\n}\n\n/**\n * Customer info included in events\n */\nexport interface EventCustomerInfo {\n customerId: string | null;\n customerEmail: string | null;\n customerName: string | null;\n}\n\n/**\n * Payload for ticket.created event\n */\nexport interface TicketCreatedData extends EventCustomerInfo {\n id: string;\n ticketNumber: number;\n title: string;\n status: TicketStatus;\n priority: TicketPriority;\n source: TicketSource;\n createdAt: string;\n}\n\n/**\n * Payload for ticket.updated event\n */\nexport interface TicketUpdatedData extends EventCustomerInfo {\n id: string;\n ticketNumber: number;\n title: string;\n status: TicketStatus;\n priority: TicketPriority;\n assigneeId: string | null;\n updatedAt: string;\n /** List of field names that were changed */\n changes: string[];\n}\n\n/**\n * Comment data in ticket.comment.created event\n */\nexport interface EventCommentData {\n id: string;\n body: string;\n authorId: string | null;\n authorType: AuthorType;\n createdAt: string;\n}\n\n/**\n * Payload for ticket.comment.created event\n */\nexport interface CommentCreatedData extends EventCustomerInfo {\n ticketId: string;\n /** Formatted ticket number (e.g., \"ACME-123\") */\n ticketNumber: string;\n comment: EventCommentData;\n}\n\n/**\n * Ticket created webhook event\n */\nexport type TicketCreatedEvent = WebhookEventEnvelope<'ticket.created', TicketCreatedData>;\n\n/**\n * Ticket updated webhook event\n */\nexport type TicketUpdatedEvent = WebhookEventEnvelope<'ticket.updated', TicketUpdatedData>;\n\n/**\n * Comment created webhook event\n */\nexport type CommentCreatedEvent = WebhookEventEnvelope<'ticket.comment.created', CommentCreatedData>;\n\n/**\n * Union of all webhook events\n */\nexport type WebhookEvent = TicketCreatedEvent | TicketUpdatedEvent | CommentCreatedEvent;\n\n/**\n * Map of event types to their data types\n */\nexport interface WebhookEventMap {\n 'ticket.created': TicketCreatedEvent;\n 'ticket.updated': TicketUpdatedEvent;\n 'ticket.comment.created': CommentCreatedEvent;\n}\n\n/**\n * Type guard to check if event is a ticket.created event\n */\nexport function isTicketCreatedEvent(event: WebhookEvent): event is TicketCreatedEvent {\n return event.event === 'ticket.created';\n}\n\n/**\n * Type guard to check if event is a ticket.updated event\n */\nexport function isTicketUpdatedEvent(event: WebhookEvent): event is TicketUpdatedEvent {\n return event.event === 'ticket.updated';\n}\n\n/**\n * Type guard to check if event is a ticket.comment.created event\n */\nexport function isCommentCreatedEvent(event: WebhookEvent): event is CommentCreatedEvent {\n return event.event === 'ticket.comment.created';\n}\n\n/**\n * Parse and validate a webhook payload\n *\n * @param payload - Raw JSON payload string or parsed object\n * @returns Typed webhook event\n * @throws Error if payload is invalid\n *\n * @example\n * ```typescript\n * import { parseWebhookEvent, isTicketCreatedEvent } from '@dispatchtickets/sdk';\n *\n * app.post('/webhooks', (req, res) => {\n * const event = parseWebhookEvent(req.body);\n *\n * if (isTicketCreatedEvent(event)) {\n * console.log('New ticket:', event.data.title);\n * }\n * });\n * ```\n */\nexport function parseWebhookEvent(payload: string | object): WebhookEvent {\n const event = typeof payload === 'string' ? JSON.parse(payload) : payload;\n\n if (!event || typeof event !== 'object') {\n throw new Error('Invalid webhook payload: expected object');\n }\n\n if (!event.event || typeof event.event !== 'string') {\n throw new Error('Invalid webhook payload: missing event type');\n }\n\n if (!event.id || typeof event.id !== 'string') {\n throw new Error('Invalid webhook payload: missing event id');\n }\n\n if (!event.data || typeof event.data !== 'object') {\n throw new Error('Invalid webhook payload: missing data');\n }\n\n const validEvents: WebhookEventType[] = ['ticket.created', 'ticket.updated', 'ticket.comment.created'];\n if (!validEvents.includes(event.event)) {\n throw new Error(`Invalid webhook payload: unknown event type \"${event.event}\"`);\n }\n\n return event as WebhookEvent;\n}\n","import type { PaginatedResponse } from '../types/common.js';\n\n/**\n * Options for paginated requests\n */\nexport interface PaginationOptions {\n limit?: number;\n cursor?: string;\n}\n\n/**\n * Create an async iterator from a paginated API endpoint\n */\nexport function createPaginatedIterator<T>(\n fetchPage: (cursor?: string) => Promise<PaginatedResponse<T>>\n): AsyncIterable<T> {\n return {\n [Symbol.asyncIterator](): AsyncIterator<T> {\n let cursor: string | undefined;\n let hasMore = true;\n let currentPage: T[] = [];\n let currentIndex = 0;\n\n return {\n async next(): Promise<IteratorResult<T>> {\n // If we have items in the current page, return the next one\n if (currentIndex < currentPage.length) {\n return { value: currentPage[currentIndex++], done: false };\n }\n\n // If no more pages, we're done\n if (!hasMore) {\n return { value: undefined, done: true };\n }\n\n // Fetch the next page\n const response = await fetchPage(cursor);\n currentPage = response.data;\n currentIndex = 0;\n cursor = response.pagination.cursor;\n hasMore = response.pagination.hasMore;\n\n // If the page is empty, we're done\n if (currentPage.length === 0) {\n return { value: undefined, done: true };\n }\n\n return { value: currentPage[currentIndex++], done: false };\n },\n };\n },\n };\n}\n\n/**\n * Collect all items from an async iterable into an array\n */\nexport async function collectAll<T>(iterable: AsyncIterable<T>): Promise<T[]> {\n const items: T[] = [];\n for await (const item of iterable) {\n items.push(item);\n }\n return items;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/utils/http.ts","../src/resources/base.ts","../src/resources/accounts.ts","../src/resources/brands.ts","../src/resources/tickets.ts","../src/resources/comments.ts","../src/resources/attachments.ts","../src/resources/webhooks.ts","../src/resources/categories.ts","../src/resources/tags.ts","../src/resources/customers.ts","../src/resources/fields.ts","../src/utils/webhooks.ts","../src/client.ts","../src/resources/portal-tickets.ts","../src/portal.ts","../src/types/events.ts","../src/utils/pagination.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Base error class for all Dispatch Tickets SDK errors\n */\nexport class DispatchTicketsError extends Error {\n readonly code: string;\n readonly statusCode?: number;\n readonly details?: Record<string, unknown>;\n /** Request ID for debugging with support */\n readonly requestId?: string;\n\n constructor(\n message: string,\n code: string,\n statusCode?: number,\n details?: Record<string, unknown>,\n requestId?: string\n ) {\n super(message);\n this.name = 'DispatchTicketsError';\n this.code = code;\n this.statusCode = statusCode;\n this.details = details;\n this.requestId = requestId;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when API key is missing or invalid\n */\nexport class AuthenticationError extends DispatchTicketsError {\n constructor(message = 'Invalid or missing API key', requestId?: string) {\n super(message, 'authentication_error', 401, undefined, requestId);\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * Thrown when rate limit is exceeded\n */\nexport class RateLimitError extends DispatchTicketsError {\n readonly retryAfter?: number;\n /** Rate limit ceiling */\n readonly limit?: number;\n /** Remaining requests in current window */\n readonly remaining?: number;\n /** Unix timestamp when rate limit resets */\n readonly reset?: number;\n\n constructor(\n message = 'Rate limit exceeded',\n retryAfter?: number,\n requestId?: string,\n rateLimitInfo?: { limit?: number; remaining?: number; reset?: number }\n ) {\n super(message, 'rate_limit_error', 429, undefined, requestId);\n this.name = 'RateLimitError';\n this.retryAfter = retryAfter;\n this.limit = rateLimitInfo?.limit;\n this.remaining = rateLimitInfo?.remaining;\n this.reset = rateLimitInfo?.reset;\n }\n}\n\n/**\n * Thrown when request validation fails\n */\nexport class ValidationError extends DispatchTicketsError {\n readonly errors?: Array<{ field: string; message: string }>;\n\n constructor(\n message = 'Validation failed',\n errors?: Array<{ field: string; message: string }>,\n requestId?: string\n ) {\n super(message, 'validation_error', 400, { errors }, requestId);\n this.name = 'ValidationError';\n this.errors = errors;\n }\n}\n\n/**\n * Thrown when a resource is not found\n */\nexport class NotFoundError extends DispatchTicketsError {\n readonly resourceType?: string;\n readonly resourceId?: string;\n\n constructor(\n message = 'Resource not found',\n resourceType?: string,\n resourceId?: string,\n requestId?: string\n ) {\n super(message, 'not_found', 404, { resourceType, resourceId }, requestId);\n this.name = 'NotFoundError';\n this.resourceType = resourceType;\n this.resourceId = resourceId;\n }\n}\n\n/**\n * Thrown when there's a conflict (e.g., duplicate resource)\n */\nexport class ConflictError extends DispatchTicketsError {\n constructor(message = 'Resource conflict', requestId?: string) {\n super(message, 'conflict', 409, undefined, requestId);\n this.name = 'ConflictError';\n }\n}\n\n/**\n * Thrown when the server returns an unexpected error\n */\nexport class ServerError extends DispatchTicketsError {\n constructor(message = 'Internal server error', statusCode = 500, requestId?: string) {\n super(message, 'server_error', statusCode, undefined, requestId);\n this.name = 'ServerError';\n }\n}\n\n/**\n * Thrown when request times out\n */\nexport class TimeoutError extends DispatchTicketsError {\n constructor(message = 'Request timed out') {\n super(message, 'timeout_error');\n this.name = 'TimeoutError';\n }\n}\n\n/**\n * Thrown when network connection fails\n */\nexport class NetworkError extends DispatchTicketsError {\n constructor(message = 'Network error') {\n super(message, 'network_error');\n this.name = 'NetworkError';\n }\n}\n\n// ============================================\n// Type Guards\n// ============================================\n\n/**\n * Check if an error is a DispatchTicketsError\n */\nexport function isDispatchTicketsError(error: unknown): error is DispatchTicketsError {\n return error instanceof DispatchTicketsError;\n}\n\n/**\n * Check if an error is an AuthenticationError\n */\nexport function isAuthenticationError(error: unknown): error is AuthenticationError {\n return error instanceof AuthenticationError;\n}\n\n/**\n * Check if an error is a RateLimitError\n */\nexport function isRateLimitError(error: unknown): error is RateLimitError {\n return error instanceof RateLimitError;\n}\n\n/**\n * Check if an error is a ValidationError\n */\nexport function isValidationError(error: unknown): error is ValidationError {\n return error instanceof ValidationError;\n}\n\n/**\n * Check if an error is a NotFoundError\n */\nexport function isNotFoundError(error: unknown): error is NotFoundError {\n return error instanceof NotFoundError;\n}\n\n/**\n * Check if an error is a ConflictError\n */\nexport function isConflictError(error: unknown): error is ConflictError {\n return error instanceof ConflictError;\n}\n\n/**\n * Check if an error is a ServerError\n */\nexport function isServerError(error: unknown): error is ServerError {\n return error instanceof ServerError;\n}\n\n/**\n * Check if an error is a TimeoutError\n */\nexport function isTimeoutError(error: unknown): error is TimeoutError {\n return error instanceof TimeoutError;\n}\n\n/**\n * Check if an error is a NetworkError\n */\nexport function isNetworkError(error: unknown): error is NetworkError {\n return error instanceof NetworkError;\n}\n","import {\n DispatchTicketsError,\n AuthenticationError,\n RateLimitError,\n ValidationError,\n NotFoundError,\n ConflictError,\n ServerError,\n TimeoutError,\n NetworkError,\n} from '../errors.js';\n\n/**\n * Custom fetch function type\n */\nexport type FetchFunction = typeof fetch;\n\n/**\n * Request context passed to hooks\n */\nexport interface RequestContext {\n /** HTTP method */\n method: string;\n /** Full URL being requested */\n url: string;\n /** Request headers */\n headers: Record<string, string>;\n /** Request body (if any) */\n body?: unknown;\n /** Retry attempt number (0 = first attempt) */\n attempt: number;\n}\n\n/**\n * Response context passed to hooks\n */\nexport interface ResponseContext {\n /** The request that was made */\n request: RequestContext;\n /** HTTP status code */\n status: number;\n /** Response headers */\n headers: Headers;\n /** Request ID from server */\n requestId?: string;\n /** Rate limit info from server */\n rateLimit?: RateLimitInfo;\n /** Duration of the request in milliseconds */\n durationMs: number;\n}\n\n/**\n * Retry configuration options\n */\nexport interface RetryConfig {\n /**\n * Maximum number of retry attempts\n * @default 3\n */\n maxRetries?: number;\n\n /**\n * HTTP status codes that should trigger a retry\n * @default [429, 500, 502, 503, 504]\n */\n retryableStatuses?: number[];\n\n /**\n * Whether to retry on network errors\n * @default true\n */\n retryOnNetworkError?: boolean;\n\n /**\n * Whether to retry on timeout errors\n * @default true\n */\n retryOnTimeout?: boolean;\n\n /**\n * Initial delay between retries in milliseconds\n * @default 1000\n */\n initialDelayMs?: number;\n\n /**\n * Maximum delay between retries in milliseconds\n * @default 30000\n */\n maxDelayMs?: number;\n\n /**\n * Multiplier for exponential backoff\n * @default 2\n */\n backoffMultiplier?: number;\n\n /**\n * Jitter factor (0-1) to add randomness to delays\n * @default 0.25\n */\n jitter?: number;\n}\n\n/**\n * Hooks for observability and customization\n */\nexport interface Hooks {\n /**\n * Called before each request is sent\n * Can modify the request or throw to abort\n */\n onRequest?: (context: RequestContext) => void | Promise<void>;\n\n /**\n * Called after each successful response\n */\n onResponse?: (context: ResponseContext) => void | Promise<void>;\n\n /**\n * Called when an error occurs (before retry)\n */\n onError?: (error: Error, context: RequestContext) => void | Promise<void>;\n\n /**\n * Called before each retry attempt\n */\n onRetry?: (context: RequestContext, error: Error, delayMs: number) => void | Promise<void>;\n}\n\nexport interface HttpClientConfig {\n baseUrl: string;\n apiKey: string;\n timeout: number;\n maxRetries: number;\n debug?: boolean;\n /**\n * Custom fetch implementation for testing/mocking\n */\n fetch?: FetchFunction;\n /**\n * Fine-grained retry configuration\n */\n retry?: RetryConfig;\n /**\n * Hooks for observability\n */\n hooks?: Hooks;\n}\n\nexport interface RequestOptions {\n method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';\n path: string;\n body?: unknown;\n query?: Record<string, string | number | boolean | undefined>;\n headers?: Record<string, string>;\n idempotencyKey?: string;\n /**\n * AbortSignal to cancel the request\n */\n signal?: AbortSignal;\n}\n\ninterface ApiErrorResponse {\n message?: string;\n error?: string;\n errors?: Array<{ field: string; message: string }>;\n code?: string;\n}\n\n/**\n * Rate limit information from response headers\n */\nexport interface RateLimitInfo {\n /** Maximum requests allowed in the current window */\n limit: number;\n /** Remaining requests in the current window */\n remaining: number;\n /** Unix timestamp (seconds) when the rate limit resets */\n reset: number;\n}\n\n/**\n * Response wrapper with rate limit info\n */\nexport interface ResponseWithRateLimit<T> {\n data: T;\n rateLimit?: RateLimitInfo;\n requestId?: string;\n}\n\n/**\n * HTTP client with retry logic, hooks, and error handling\n */\nexport class HttpClient {\n private readonly config: HttpClientConfig;\n private readonly fetchFn: FetchFunction;\n private readonly retryConfig: Required<RetryConfig>;\n\n /** Rate limit info from the last response */\n private _lastRateLimit?: RateLimitInfo;\n /** Request ID from the last response */\n private _lastRequestId?: string;\n\n constructor(config: HttpClientConfig) {\n this.config = config;\n this.fetchFn = config.fetch ?? fetch;\n\n // Merge retry config with defaults\n this.retryConfig = {\n maxRetries: config.retry?.maxRetries ?? config.maxRetries,\n retryableStatuses: config.retry?.retryableStatuses ?? [429, 500, 502, 503, 504],\n retryOnNetworkError: config.retry?.retryOnNetworkError ?? true,\n retryOnTimeout: config.retry?.retryOnTimeout ?? true,\n initialDelayMs: config.retry?.initialDelayMs ?? 1000,\n maxDelayMs: config.retry?.maxDelayMs ?? 30000,\n backoffMultiplier: config.retry?.backoffMultiplier ?? 2,\n jitter: config.retry?.jitter ?? 0.25,\n };\n }\n\n /**\n * Get rate limit info from the last response\n */\n get lastRateLimit(): RateLimitInfo | undefined {\n return this._lastRateLimit;\n }\n\n /**\n * Get request ID from the last response\n */\n get lastRequestId(): string | undefined {\n return this._lastRequestId;\n }\n\n /**\n * Execute an HTTP request with retry logic\n */\n async request<T>(options: RequestOptions): Promise<T> {\n const url = this.buildUrl(options.path, options.query);\n const headers = this.buildHeaders(options.headers, options.idempotencyKey);\n\n let lastError: Error | undefined;\n let attempt = 0;\n\n while (attempt <= this.retryConfig.maxRetries) {\n const requestContext: RequestContext = {\n method: options.method,\n url,\n headers,\n body: options.body,\n attempt,\n };\n\n try {\n // Call onRequest hook\n if (this.config.hooks?.onRequest) {\n await this.config.hooks.onRequest(requestContext);\n }\n\n const startTime = Date.now();\n const response = await this.executeRequest(\n url,\n options.method,\n headers,\n options.body,\n options.signal\n );\n const durationMs = Date.now() - startTime;\n\n const result = await this.handleResponse<T>(response, requestContext, durationMs);\n return result;\n } catch (error) {\n lastError = error as Error;\n\n // Call onError hook\n if (this.config.hooks?.onError) {\n await this.config.hooks.onError(lastError, requestContext);\n }\n\n // Check if we should retry\n if (attempt < this.retryConfig.maxRetries && this.shouldRetry(lastError)) {\n const delay = this.calculateDelay(lastError, attempt);\n\n // Call onRetry hook\n if (this.config.hooks?.onRetry) {\n await this.config.hooks.onRetry(requestContext, lastError, delay);\n }\n\n await this.sleep(delay);\n attempt++;\n continue;\n }\n\n throw lastError;\n }\n }\n\n throw lastError || new NetworkError('Request failed after retries');\n }\n\n /**\n * Execute request and return response with rate limit info\n */\n async requestWithRateLimit<T>(options: RequestOptions): Promise<ResponseWithRateLimit<T>> {\n const data = await this.request<T>(options);\n return {\n data,\n rateLimit: this._lastRateLimit,\n requestId: this._lastRequestId,\n };\n }\n\n private shouldRetry(error: Error): boolean {\n // Never retry client errors (except rate limits handled specially)\n if (\n error instanceof AuthenticationError ||\n error instanceof ValidationError ||\n error instanceof NotFoundError ||\n error instanceof ConflictError\n ) {\n return false;\n }\n\n // Retry on rate limit (uses retry-after header for delay)\n if (error instanceof RateLimitError) {\n return true;\n }\n\n // Retry on configured status codes (ServerError)\n if (error instanceof ServerError && error.statusCode) {\n return this.retryConfig.retryableStatuses.includes(error.statusCode);\n }\n\n // Retry on network errors if configured\n if (error instanceof NetworkError) {\n return this.retryConfig.retryOnNetworkError;\n }\n\n // Retry on timeout if configured\n if (error instanceof TimeoutError) {\n return this.retryConfig.retryOnTimeout;\n }\n\n return false;\n }\n\n private calculateDelay(error: Error, attempt: number): number {\n // Use retry-after header for rate limits\n if (error instanceof RateLimitError && error.retryAfter) {\n return error.retryAfter * 1000;\n }\n\n // Exponential backoff with jitter\n const baseDelay = this.retryConfig.initialDelayMs;\n const delay = Math.min(\n baseDelay * Math.pow(this.retryConfig.backoffMultiplier, attempt),\n this.retryConfig.maxDelayMs\n );\n\n // Add jitter\n const jitter = delay * this.retryConfig.jitter * Math.random();\n return delay + jitter;\n }\n\n private buildUrl(path: string, query?: Record<string, string | number | boolean | undefined>): string {\n const url = new URL(path, this.config.baseUrl);\n\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n return url.toString();\n }\n\n private buildHeaders(\n customHeaders?: Record<string, string>,\n idempotencyKey?: string\n ): Record<string, string> {\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.config.apiKey}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n ...customHeaders,\n };\n\n if (idempotencyKey) {\n headers['X-Idempotency-Key'] = idempotencyKey;\n }\n\n return headers;\n }\n\n private async executeRequest(\n url: string,\n method: string,\n headers: Record<string, string>,\n body?: unknown,\n userSignal?: AbortSignal\n ): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n // Create a combined signal that aborts on either timeout or user signal\n const abortHandler = () => controller.abort();\n userSignal?.addEventListener('abort', abortHandler);\n\n try {\n if (this.config.debug) {\n console.log(`[DispatchTickets] ${method} ${url}`);\n if (body) {\n console.log('[DispatchTickets] Body:', JSON.stringify(body, null, 2));\n }\n }\n\n // Check if user already aborted\n if (userSignal?.aborted) {\n throw new Error('Request aborted');\n }\n\n const response = await this.fetchFn(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n return response;\n } catch (error) {\n if (error instanceof Error) {\n // Check if it was a user abort vs timeout\n if (error.name === 'AbortError') {\n if (userSignal?.aborted) {\n throw new NetworkError('Request aborted by user');\n }\n throw new TimeoutError(`Request timed out after ${this.config.timeout}ms`);\n }\n throw new NetworkError(error.message);\n }\n throw new NetworkError('Unknown network error');\n } finally {\n clearTimeout(timeoutId);\n userSignal?.removeEventListener('abort', abortHandler);\n }\n }\n\n private extractRateLimitInfo(response: Response): RateLimitInfo | undefined {\n const limit = response.headers.get('x-ratelimit-limit');\n const remaining = response.headers.get('x-ratelimit-remaining');\n const reset = response.headers.get('x-ratelimit-reset');\n\n if (limit && remaining && reset) {\n return {\n limit: parseInt(limit, 10),\n remaining: parseInt(remaining, 10),\n reset: parseInt(reset, 10),\n };\n }\n\n return undefined;\n }\n\n private async handleResponse<T>(\n response: Response,\n requestContext: RequestContext,\n durationMs: number\n ): Promise<T> {\n const contentType = response.headers.get('content-type');\n const isJson = contentType?.includes('application/json');\n\n // Extract request ID and rate limit info\n const requestId = response.headers.get('x-request-id') ?? undefined;\n const rateLimitInfo = this.extractRateLimitInfo(response);\n\n // Store for access via getters\n this._lastRequestId = requestId;\n this._lastRateLimit = rateLimitInfo;\n\n if (this.config.debug && requestId) {\n console.log(`[DispatchTickets] Request ID: ${requestId}`);\n }\n\n // Call onResponse hook for successful responses\n if (response.ok && this.config.hooks?.onResponse) {\n await this.config.hooks.onResponse({\n request: requestContext,\n status: response.status,\n headers: response.headers,\n requestId,\n rateLimit: rateLimitInfo,\n durationMs,\n });\n }\n\n if (response.ok) {\n if (response.status === 204 || !isJson) {\n return undefined as T;\n }\n return (await response.json()) as T;\n }\n\n // Handle error responses\n let errorData: ApiErrorResponse = {};\n if (isJson) {\n try {\n errorData = (await response.json()) as ApiErrorResponse;\n } catch {\n // Ignore JSON parse errors for error responses\n }\n }\n\n const message = errorData.message || errorData.error || response.statusText;\n\n switch (response.status) {\n case 401:\n throw new AuthenticationError(message, requestId);\n case 400:\n case 422:\n throw new ValidationError(message, errorData.errors, requestId);\n case 404:\n throw new NotFoundError(message, undefined, undefined, requestId);\n case 409:\n throw new ConflictError(message, requestId);\n case 429: {\n const retryAfter = response.headers.get('retry-after');\n throw new RateLimitError(\n message,\n retryAfter ? parseInt(retryAfter, 10) : undefined,\n requestId,\n rateLimitInfo\n );\n }\n default:\n if (response.status >= 500) {\n throw new ServerError(message, response.status, requestId);\n }\n throw new DispatchTicketsError(\n message,\n 'api_error',\n response.status,\n errorData as Record<string, unknown>,\n requestId\n );\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { HttpClient, RequestOptions } from '../utils/http.js';\n\n/**\n * Options for API requests\n */\nexport interface ApiRequestOptions {\n /**\n * AbortSignal to cancel the request\n *\n * @example\n * ```typescript\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 5000);\n *\n * const ticket = await client.tickets.get('ws_abc', 'tkt_xyz', {\n * signal: controller.signal,\n * });\n * ```\n */\n signal?: AbortSignal;\n}\n\n/**\n * Base class for all resource classes\n * @internal\n */\nexport abstract class BaseResource {\n protected readonly http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n\n protected async _get<T>(\n path: string,\n query?: RequestOptions['query'],\n options?: ApiRequestOptions\n ): Promise<T> {\n return this.http.request<T>({\n method: 'GET',\n path,\n query,\n signal: options?.signal,\n });\n }\n\n protected async _post<T>(\n path: string,\n body?: unknown,\n options?: { idempotencyKey?: string; query?: RequestOptions['query']; signal?: AbortSignal }\n ): Promise<T> {\n return this.http.request<T>({\n method: 'POST',\n path,\n body,\n idempotencyKey: options?.idempotencyKey,\n query: options?.query,\n signal: options?.signal,\n });\n }\n\n protected async _patch<T>(\n path: string,\n body?: unknown,\n options?: ApiRequestOptions\n ): Promise<T> {\n return this.http.request<T>({\n method: 'PATCH',\n path,\n body,\n signal: options?.signal,\n });\n }\n\n protected async _put<T>(\n path: string,\n body?: unknown,\n options?: ApiRequestOptions\n ): Promise<T> {\n return this.http.request<T>({\n method: 'PUT',\n path,\n body,\n signal: options?.signal,\n });\n }\n\n protected async _delete<T>(\n path: string,\n query?: RequestOptions['query'],\n options?: ApiRequestOptions\n ): Promise<T> {\n return this.http.request<T>({\n method: 'DELETE',\n path,\n query,\n signal: options?.signal,\n });\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Account,\n AccountUsage,\n ApiKey,\n ApiKeyWithSecret,\n CreateApiKeyInput,\n UpdateApiKeyScopeInput,\n} from '../types/account.js';\n\n/**\n * Accounts resource for managing the current account\n */\nexport class AccountsResource extends BaseResource {\n /**\n * Get the current account\n */\n async me(): Promise<Account> {\n return this._get<Account>('/accounts/me');\n }\n\n /**\n * Get usage statistics for the current account\n */\n async getUsage(): Promise<AccountUsage> {\n return this._get<AccountUsage>('/accounts/me/usage');\n }\n\n /**\n * List all API keys for the current account\n */\n async listApiKeys(): Promise<ApiKey[]> {\n return this._get<ApiKey[]>('/accounts/me/api-keys');\n }\n\n /**\n * Create a new API key\n *\n * Note: The full key value is only returned once on creation.\n * Store it securely as it cannot be retrieved again.\n */\n async createApiKey(data: CreateApiKeyInput): Promise<ApiKeyWithSecret> {\n return this._post<ApiKeyWithSecret>('/accounts/me/api-keys', data);\n }\n\n /**\n * Update the brand scope for an API key\n */\n async updateApiKeyScope(\n keyId: string,\n data: UpdateApiKeyScopeInput\n ): Promise<{ success: boolean }> {\n return this._patch<{ success: boolean }>(\n `/accounts/me/api-keys/${keyId}/scope`,\n data\n );\n }\n\n /**\n * Revoke an API key\n */\n async revokeApiKey(keyId: string): Promise<void> {\n await this._delete<void>(`/accounts/me/api-keys/${keyId}`);\n }\n}\n","import { BaseResource } from './base.js';\nimport type { Brand, CreateBrandInput, UpdateBrandInput, DeleteBrandPreview } from '../types/brand.js';\nimport type {\n PortalTokenResponse,\n GeneratePortalTokenInput,\n SendMagicLinkInput,\n} from '../types/portal.js';\n\n/**\n * Brands resource for managing workspaces\n */\nexport class BrandsResource extends BaseResource {\n /**\n * Create a new brand\n */\n async create(data: CreateBrandInput): Promise<Brand> {\n return this._post<Brand>('/brands', data);\n }\n\n /**\n * List all brands\n */\n async list(): Promise<Brand[]> {\n return this._get<Brand[]>('/brands');\n }\n\n /**\n * Get a brand by ID\n */\n async get(brandId: string): Promise<Brand> {\n return this._get<Brand>(`/brands/${brandId}`);\n }\n\n /**\n * Update a brand\n */\n async update(brandId: string, data: UpdateBrandInput): Promise<Brand> {\n return this._patch<Brand>(`/brands/${brandId}`, data);\n }\n\n /**\n * Delete a brand\n * @param brandId - The brand ID\n * @param confirm - Set to true to actually delete; false to preview what would be deleted\n */\n async delete(brandId: string, confirm = true): Promise<void | DeleteBrandPreview> {\n if (confirm) {\n await this._delete<void>(`/brands/${brandId}`, { confirm: true });\n return;\n }\n return this._delete<DeleteBrandPreview>(`/brands/${brandId}`);\n }\n\n /**\n * Get the ticket schema for a brand\n */\n async getSchema(brandId: string): Promise<Record<string, unknown>> {\n return this._get<Record<string, unknown>>(`/brands/${brandId}/schema`);\n }\n\n /**\n * Update the ticket schema for a brand\n */\n async updateSchema(brandId: string, schema: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this._put<Record<string, unknown>>(`/brands/${brandId}/schema`, schema);\n }\n\n /**\n * Get the inbound email address for a brand\n *\n * Emails sent to this address will automatically create tickets.\n *\n * @param brandId - The brand ID\n * @param domain - Optional custom inbound domain (default: inbound.dispatchtickets.com)\n * @returns The inbound email address\n *\n * @example\n * ```typescript\n * const email = client.brands.getInboundEmail('br_abc123');\n * // Returns: br_abc123@inbound.dispatchtickets.com\n *\n * // With custom domain:\n * const customEmail = client.brands.getInboundEmail('br_abc123', 'support.mycompany.com');\n * // Returns: br_abc123@support.mycompany.com\n * ```\n */\n getInboundEmail(brandId: string, domain = 'inbound.dispatchtickets.com'): string {\n return `${brandId}@${domain}`;\n }\n\n // ===========================================================================\n // Portal Token Management\n // ===========================================================================\n\n /**\n * Generate a portal token for a customer\n *\n * Use this for \"authenticated mode\" where your backend already knows who the\n * customer is (they're logged into your app). Generate a portal token and\n * pass it to your frontend to initialize the DispatchPortal client.\n *\n * @param brandId - The brand ID\n * @param data - Customer email and optional name\n * @returns Portal token response with JWT token and expiry\n *\n * @example\n * ```typescript\n * // On your backend (Node.js, Next.js API route, etc.)\n * const { token, expiresAt } = await client.brands.generatePortalToken(\n * 'br_abc123',\n * {\n * email: req.user.email,\n * name: req.user.name,\n * }\n * );\n *\n * // Return token to your frontend\n * res.json({ portalToken: token });\n * ```\n */\n async generatePortalToken(\n brandId: string,\n data: GeneratePortalTokenInput\n ): Promise<PortalTokenResponse> {\n return this._post<PortalTokenResponse>(`/brands/${brandId}/portal/token`, data);\n }\n\n /**\n * Send a magic link email to a customer\n *\n * Use this for \"self-auth mode\" where customers access the portal without\n * being logged into your app. They receive an email with a link that\n * authenticates them directly.\n *\n * @param brandId - The brand ID\n * @param data - Customer email and portal URL to redirect to\n * @returns Success status\n *\n * @example\n * ```typescript\n * // Customer requests access via your portal login form\n * await client.brands.sendPortalMagicLink('br_abc123', {\n * email: 'customer@example.com',\n * portalUrl: 'https://yourapp.com/support/portal',\n * });\n *\n * // Customer receives email with link like:\n * // https://yourapp.com/support/portal?token=xyz...\n *\n * // Your portal page then calls DispatchPortal.verify(token)\n * ```\n */\n async sendPortalMagicLink(\n brandId: string,\n data: SendMagicLinkInput\n ): Promise<{ success: boolean }> {\n return this._post<{ success: boolean }>(`/brands/${brandId}/portal/magic-link`, data);\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Ticket,\n CreateTicketInput,\n UpdateTicketInput,\n ListTicketsFilters,\n CreateTicketOptions,\n MergeTicketsInput,\n BulkActionResult,\n} from '../types/ticket.js';\nimport type { PaginatedResponse, BulkAction } from '../types/common.js';\n\n/**\n * Tickets resource\n */\nexport class TicketsResource extends BaseResource {\n /**\n * Create a new ticket\n */\n async create(\n brandId: string,\n data: CreateTicketInput,\n options?: CreateTicketOptions\n ): Promise<Ticket> {\n return this._post<Ticket>(`/brands/${brandId}/tickets`, data, {\n idempotencyKey: options?.idempotencyKey,\n });\n }\n\n /**\n * List tickets with pagination (async iterator)\n * Automatically fetches all pages\n */\n async *list(\n brandId: string,\n filters?: Omit<ListTicketsFilters, 'cursor'>\n ): AsyncIterable<Ticket> {\n let cursor: string | undefined;\n let hasMore = true;\n\n while (hasMore) {\n const page = await this.listPage(brandId, { ...filters, cursor });\n for (const ticket of page.data) {\n yield ticket;\n }\n cursor = page.pagination.cursor;\n hasMore = page.pagination.hasMore;\n }\n }\n\n /**\n * List a single page of tickets\n */\n async listPage(\n brandId: string,\n filters?: ListTicketsFilters\n ): Promise<PaginatedResponse<Ticket>> {\n const query = this.buildListQuery(filters);\n return this._get<PaginatedResponse<Ticket>>(`/brands/${brandId}/tickets`, query);\n }\n\n /**\n * Get a ticket by ID\n */\n async get(brandId: string, ticketId: string): Promise<Ticket> {\n return this._get<Ticket>(`/brands/${brandId}/tickets/${ticketId}`);\n }\n\n /**\n * Update a ticket\n */\n async update(\n brandId: string,\n ticketId: string,\n data: UpdateTicketInput\n ): Promise<Ticket> {\n return this._patch<Ticket>(`/brands/${brandId}/tickets/${ticketId}`, data);\n }\n\n /**\n * Delete a ticket\n */\n async delete(brandId: string, ticketId: string): Promise<Ticket> {\n return this._delete<Ticket>(`/brands/${brandId}/tickets/${ticketId}`);\n }\n\n /**\n * Mark a ticket as spam or not spam\n */\n async markAsSpam(brandId: string, ticketId: string, isSpam: boolean): Promise<Ticket> {\n return this._post<Ticket>(`/brands/${brandId}/tickets/${ticketId}/spam`, { isSpam });\n }\n\n /**\n * Merge tickets into a target ticket\n */\n async merge(\n brandId: string,\n targetTicketId: string,\n sourceTicketIds: string[]\n ): Promise<Ticket> {\n return this._post<Ticket>(`/brands/${brandId}/tickets/${targetTicketId}/merge`, {\n sourceTicketIds,\n } satisfies MergeTicketsInput);\n }\n\n /**\n * Perform a bulk action on multiple tickets\n */\n async bulk(\n brandId: string,\n action: BulkAction,\n ticketIds: string[],\n options?: {\n assigneeId?: string | null;\n categoryId?: string | null;\n tags?: string[];\n }\n ): Promise<BulkActionResult> {\n return this._post<BulkActionResult>(`/brands/${brandId}/tickets/bulk`, {\n action,\n ticketIds,\n ...options,\n });\n }\n\n private buildListQuery(\n filters?: ListTicketsFilters\n ): Record<string, string | number | boolean | undefined> {\n if (!filters) return {};\n\n const query: Record<string, string | number | boolean | undefined> = {};\n\n if (filters.status) {\n query.status = Array.isArray(filters.status)\n ? filters.status.join(',')\n : filters.status;\n }\n if (filters.priority) query.priority = filters.priority;\n if (filters.assigneeId) query.assigneeId = filters.assigneeId;\n if (filters.customerId) query.customerId = filters.customerId;\n if (filters.customerEmail) query.customerEmail = filters.customerEmail;\n if (filters.createdBy) query.createdBy = filters.createdBy;\n if (filters.createdAfter) query.createdAfter = filters.createdAfter;\n if (filters.createdBefore) query.createdBefore = filters.createdBefore;\n if (filters.hasAttachments !== undefined) query.hasAttachments = filters.hasAttachments;\n if (filters.isSpam !== undefined) query.isSpam = filters.isSpam;\n if (filters.search) query.search = filters.search;\n if (filters.categoryId) query.categoryId = filters.categoryId;\n if (filters.tagIds) query.tagIds = filters.tagIds.join(',');\n if (filters.source) query.source = filters.source;\n if (filters.sort) query.sort = filters.sort;\n if (filters.order) query.order = filters.order;\n if (filters.limit) query.limit = filters.limit;\n if (filters.cursor) query.cursor = filters.cursor;\n\n return query;\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Comment,\n CreateCommentInput,\n UpdateCommentInput,\n CreateCommentOptions,\n} from '../types/comment.js';\n\n/**\n * Comments resource\n */\nexport class CommentsResource extends BaseResource {\n /**\n * Create a new comment on a ticket\n */\n async create(\n brandId: string,\n ticketId: string,\n data: CreateCommentInput,\n options?: CreateCommentOptions\n ): Promise<Comment> {\n return this._post<Comment>(\n `/brands/${brandId}/tickets/${ticketId}/comments`,\n data,\n { idempotencyKey: options?.idempotencyKey }\n );\n }\n\n /**\n * List all comments on a ticket\n */\n async list(brandId: string, ticketId: string): Promise<Comment[]> {\n return this._get<Comment[]>(`/brands/${brandId}/tickets/${ticketId}/comments`);\n }\n\n /**\n * Get a comment by ID\n */\n async get(brandId: string, ticketId: string, commentId: string): Promise<Comment> {\n return this._get<Comment>(\n `/brands/${brandId}/tickets/${ticketId}/comments/${commentId}`\n );\n }\n\n /**\n * Update a comment\n */\n async update(\n brandId: string,\n ticketId: string,\n commentId: string,\n data: UpdateCommentInput\n ): Promise<Comment> {\n return this._patch<Comment>(\n `/brands/${brandId}/tickets/${ticketId}/comments/${commentId}`,\n data\n );\n }\n\n /**\n * Delete a comment\n */\n async delete(brandId: string, ticketId: string, commentId: string): Promise<Comment> {\n return this._delete<Comment>(\n `/brands/${brandId}/tickets/${ticketId}/comments/${commentId}`\n );\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Attachment,\n AttachmentWithUrl,\n InitiateUploadInput,\n InitiateUploadResponse,\n} from '../types/attachment.js';\n\n/**\n * Attachments resource\n */\nexport class AttachmentsResource extends BaseResource {\n /**\n * Initiate an upload and get a presigned URL\n */\n async initiateUpload(\n brandId: string,\n ticketId: string,\n data: InitiateUploadInput\n ): Promise<InitiateUploadResponse> {\n return this._post<InitiateUploadResponse>(\n `/brands/${brandId}/tickets/${ticketId}/attachments`,\n data\n );\n }\n\n /**\n * Confirm that an upload has completed\n */\n async confirmUpload(\n brandId: string,\n ticketId: string,\n attachmentId: string\n ): Promise<Attachment> {\n return this._post<Attachment>(\n `/brands/${brandId}/tickets/${ticketId}/attachments/${attachmentId}/confirm`\n );\n }\n\n /**\n * List all attachments on a ticket\n */\n async list(brandId: string, ticketId: string): Promise<Attachment[]> {\n return this._get<Attachment[]>(`/brands/${brandId}/tickets/${ticketId}/attachments`);\n }\n\n /**\n * Get an attachment with its download URL\n */\n async get(\n brandId: string,\n ticketId: string,\n attachmentId: string\n ): Promise<AttachmentWithUrl> {\n return this._get<AttachmentWithUrl>(\n `/brands/${brandId}/tickets/${ticketId}/attachments/${attachmentId}`\n );\n }\n\n /**\n * Delete an attachment\n */\n async delete(\n brandId: string,\n ticketId: string,\n attachmentId: string\n ): Promise<void> {\n await this._delete<void>(\n `/brands/${brandId}/tickets/${ticketId}/attachments/${attachmentId}`\n );\n }\n\n /**\n * Convenience method: Upload a file in one step\n * Handles: initiate -> upload to presigned URL -> confirm\n */\n async upload(\n brandId: string,\n ticketId: string,\n file: Blob | Buffer | ArrayBuffer,\n filename: string,\n contentType: string\n ): Promise<Attachment> {\n // Get file size\n let size: number;\n if (file instanceof Blob) {\n size = file.size;\n } else if (Buffer.isBuffer(file)) {\n size = file.length;\n } else {\n size = file.byteLength;\n }\n\n // Initiate upload\n const { uploadUrl, attachmentId } = await this.initiateUpload(brandId, ticketId, {\n filename,\n contentType,\n size,\n });\n\n // Upload to presigned URL\n const uploadResponse = await fetch(uploadUrl, {\n method: 'PUT',\n headers: {\n 'Content-Type': contentType,\n 'Content-Length': String(size),\n },\n body: file,\n });\n\n if (!uploadResponse.ok) {\n throw new Error(`Upload failed: ${uploadResponse.statusText}`);\n }\n\n // Confirm upload\n return this.confirmUpload(brandId, ticketId, attachmentId);\n }\n}\n","import { BaseResource } from './base.js';\nimport type { Webhook, CreateWebhookInput, WebhookDelivery } from '../types/webhook.js';\n\n/**\n * Webhooks resource\n */\nexport class WebhooksResource extends BaseResource {\n /**\n * Create a new webhook\n */\n async create(brandId: string, data: CreateWebhookInput): Promise<Webhook> {\n return this._post<Webhook>(`/brands/${brandId}/webhooks`, data);\n }\n\n /**\n * List all webhooks for a brand\n */\n async list(brandId: string): Promise<Webhook[]> {\n return this._get<Webhook[]>(`/brands/${brandId}/webhooks`);\n }\n\n /**\n * Get a webhook by ID\n */\n async get(brandId: string, webhookId: string): Promise<Webhook> {\n return this._get<Webhook>(`/brands/${brandId}/webhooks/${webhookId}`);\n }\n\n /**\n * Delete a webhook\n */\n async delete(brandId: string, webhookId: string): Promise<void> {\n await this._delete<void>(`/brands/${brandId}/webhooks/${webhookId}`);\n }\n\n /**\n * Get webhook delivery history\n */\n async getDeliveries(brandId: string, webhookId: string): Promise<WebhookDelivery[]> {\n return this._get<WebhookDelivery[]>(\n `/brands/${brandId}/webhooks/${webhookId}/deliveries`\n );\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Category,\n CreateCategoryInput,\n UpdateCategoryInput,\n CategoryStats,\n} from '../types/category.js';\n\n/**\n * Categories resource\n */\nexport class CategoriesResource extends BaseResource {\n /**\n * Create a new category\n */\n async create(brandId: string, data: CreateCategoryInput): Promise<Category> {\n return this._post<Category>(`/brands/${brandId}/categories`, data);\n }\n\n /**\n * List all categories for a brand\n */\n async list(brandId: string): Promise<Category[]> {\n return this._get<Category[]>(`/brands/${brandId}/categories`);\n }\n\n /**\n * Get a category by ID\n */\n async get(brandId: string, categoryId: string): Promise<Category> {\n return this._get<Category>(`/brands/${brandId}/categories/${categoryId}`);\n }\n\n /**\n * Update a category\n */\n async update(\n brandId: string,\n categoryId: string,\n data: UpdateCategoryInput\n ): Promise<Category> {\n return this._patch<Category>(`/brands/${brandId}/categories/${categoryId}`, data);\n }\n\n /**\n * Delete a category\n */\n async delete(brandId: string, categoryId: string): Promise<void> {\n await this._delete<void>(`/brands/${brandId}/categories/${categoryId}`);\n }\n\n /**\n * Get category statistics (ticket counts)\n */\n async getStats(brandId: string): Promise<CategoryStats> {\n return this._get<CategoryStats>(`/brands/${brandId}/categories/stats`);\n }\n\n /**\n * Reorder categories\n */\n async reorder(brandId: string, categoryIds: string[]): Promise<void> {\n await this._post<void>(`/brands/${brandId}/categories/reorder`, { categoryIds });\n }\n}\n","import { BaseResource } from './base.js';\nimport type { Tag, CreateTagInput, UpdateTagInput } from '../types/tag.js';\n\n/**\n * Tags resource\n */\nexport class TagsResource extends BaseResource {\n /**\n * Create a new tag\n */\n async create(brandId: string, data: CreateTagInput): Promise<Tag> {\n return this._post<Tag>(`/brands/${brandId}/tags`, data);\n }\n\n /**\n * List all tags for a brand\n */\n async list(brandId: string): Promise<Tag[]> {\n return this._get<Tag[]>(`/brands/${brandId}/tags`);\n }\n\n /**\n * Update a tag\n */\n async update(brandId: string, tagId: string, data: UpdateTagInput): Promise<Tag> {\n return this._patch<Tag>(`/brands/${brandId}/tags/${tagId}`, data);\n }\n\n /**\n * Delete a tag\n */\n async delete(brandId: string, tagId: string): Promise<void> {\n await this._delete<void>(`/brands/${brandId}/tags/${tagId}`);\n }\n\n /**\n * Merge tags into a target tag\n */\n async merge(brandId: string, targetTagId: string, sourceTagIds: string[]): Promise<Tag> {\n return this._post<Tag>(`/brands/${brandId}/tags/${targetTagId}/merge`, {\n sourceTagIds,\n });\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n Customer,\n CreateCustomerInput,\n UpdateCustomerInput,\n ListCustomersFilters,\n} from '../types/customer.js';\nimport type { PaginatedResponse } from '../types/common.js';\n\n/**\n * Customers resource\n */\nexport class CustomersResource extends BaseResource {\n /**\n * Create a new customer\n */\n async create(brandId: string, data: CreateCustomerInput): Promise<Customer> {\n return this._post<Customer>(`/brands/${brandId}/customers`, data);\n }\n\n /**\n * List customers with pagination (async iterator)\n */\n async *list(\n brandId: string,\n filters?: Omit<ListCustomersFilters, 'cursor'>\n ): AsyncIterable<Customer> {\n let cursor: string | undefined;\n let hasMore = true;\n\n while (hasMore) {\n const page = await this.listPage(brandId, { ...filters, cursor });\n for (const customer of page.data) {\n yield customer;\n }\n cursor = page.pagination.cursor;\n hasMore = page.pagination.hasMore;\n }\n }\n\n /**\n * List a single page of customers\n */\n async listPage(\n brandId: string,\n filters?: ListCustomersFilters\n ): Promise<PaginatedResponse<Customer>> {\n const query = this.buildListQuery(filters);\n return this._get<PaginatedResponse<Customer>>(`/brands/${brandId}/customers`, query);\n }\n\n /**\n * Search customers (autocomplete)\n */\n async search(brandId: string, query: string): Promise<Customer[]> {\n return this._get<Customer[]>(`/brands/${brandId}/customers/search`, { q: query });\n }\n\n /**\n * Get a customer by ID\n */\n async get(brandId: string, customerId: string): Promise<Customer> {\n return this._get<Customer>(`/brands/${brandId}/customers/${customerId}`);\n }\n\n /**\n * Update a customer\n */\n async update(\n brandId: string,\n customerId: string,\n data: UpdateCustomerInput\n ): Promise<Customer> {\n return this._patch<Customer>(`/brands/${brandId}/customers/${customerId}`, data);\n }\n\n /**\n * Delete a customer\n */\n async delete(brandId: string, customerId: string): Promise<Customer> {\n return this._delete<Customer>(`/brands/${brandId}/customers/${customerId}`);\n }\n\n private buildListQuery(\n filters?: ListCustomersFilters\n ): Record<string, string | number | boolean | undefined> {\n if (!filters) return {};\n\n const query: Record<string, string | number | boolean | undefined> = {};\n\n if (filters.limit) query.limit = filters.limit;\n if (filters.cursor) query.cursor = filters.cursor;\n if (filters.sort) query.sort = filters.sort;\n if (filters.order) query.order = filters.order;\n\n return query;\n }\n}\n","import { BaseResource } from './base.js';\nimport type {\n FieldDefinition,\n FieldDefinitions,\n CreateFieldInput,\n UpdateFieldInput,\n EntityType,\n} from '../types/field.js';\n\n/**\n * Custom fields resource\n */\nexport class FieldsResource extends BaseResource {\n /**\n * Get all field definitions for a brand\n */\n async getAll(brandId: string): Promise<FieldDefinitions> {\n return this._get<FieldDefinitions>(`/brands/${brandId}/fields`);\n }\n\n /**\n * Get field definitions for a specific entity type\n */\n async list(brandId: string, entityType: EntityType): Promise<FieldDefinition[]> {\n return this._get<FieldDefinition[]>(`/brands/${brandId}/fields/${entityType}`);\n }\n\n /**\n * Create a new field definition\n */\n async create(\n brandId: string,\n entityType: EntityType,\n data: CreateFieldInput\n ): Promise<FieldDefinition> {\n return this._post<FieldDefinition>(`/brands/${brandId}/fields/${entityType}`, data);\n }\n\n /**\n * Update a field definition\n */\n async update(\n brandId: string,\n entityType: EntityType,\n key: string,\n data: UpdateFieldInput\n ): Promise<FieldDefinition> {\n return this._patch<FieldDefinition>(\n `/brands/${brandId}/fields/${entityType}/${key}`,\n data\n );\n }\n\n /**\n * Delete a field definition\n */\n async delete(brandId: string, entityType: EntityType, key: string): Promise<void> {\n await this._delete<void>(`/brands/${brandId}/fields/${entityType}/${key}`);\n }\n\n /**\n * Reorder field definitions\n */\n async reorder(brandId: string, entityType: EntityType, keys: string[]): Promise<void> {\n await this._post<void>(`/brands/${brandId}/fields/${entityType}/reorder`, { keys });\n }\n}\n","import { createHmac, timingSafeEqual } from 'crypto';\n\n/**\n * Webhook signature verification utilities\n */\nexport const webhookUtils = {\n /**\n * Verify a webhook signature\n *\n * @param payload - The raw request body as a string\n * @param signature - The X-Dispatch-Signature header value\n * @param secret - Your webhook secret\n * @returns true if the signature is valid\n *\n * @example\n * ```typescript\n * import { DispatchTickets } from '@dispatchtickets/sdk';\n *\n * app.post('/webhooks', (req, res) => {\n * const signature = req.headers['x-dispatch-signature'];\n * const isValid = DispatchTickets.webhooks.verifySignature(\n * req.rawBody,\n * signature,\n * process.env.WEBHOOK_SECRET\n * );\n *\n * if (!isValid) {\n * return res.status(401).send('Invalid signature');\n * }\n *\n * // Process webhook...\n * });\n * ```\n */\n verifySignature(payload: string, signature: string, secret: string): boolean {\n if (!signature || !secret) {\n return false;\n }\n\n // Signature format: sha256=<hex>\n const parts = signature.split('=');\n if (parts.length !== 2 || parts[0] !== 'sha256') {\n return false;\n }\n\n const receivedSignature = parts[1];\n const expectedSignature = createHmac('sha256', secret)\n .update(payload)\n .digest('hex');\n\n // Use timing-safe comparison to prevent timing attacks\n try {\n const receivedBuffer = Buffer.from(receivedSignature, 'hex');\n const expectedBuffer = Buffer.from(expectedSignature, 'hex');\n\n if (receivedBuffer.length !== expectedBuffer.length) {\n return false;\n }\n\n return timingSafeEqual(receivedBuffer, expectedBuffer);\n } catch {\n return false;\n }\n },\n\n /**\n * Generate a signature for testing purposes\n *\n * @param payload - The payload to sign\n * @param secret - The secret to sign with\n * @returns The signature in the format sha256=<hex>\n */\n generateSignature(payload: string, secret: string): string {\n const signature = createHmac('sha256', secret)\n .update(payload)\n .digest('hex');\n return `sha256=${signature}`;\n },\n};\n","import {\n HttpClient,\n HttpClientConfig,\n FetchFunction,\n RetryConfig,\n Hooks,\n} from './utils/http.js';\nimport { AccountsResource } from './resources/accounts.js';\nimport { BrandsResource } from './resources/brands.js';\nimport { TicketsResource } from './resources/tickets.js';\nimport { CommentsResource } from './resources/comments.js';\nimport { AttachmentsResource } from './resources/attachments.js';\nimport { WebhooksResource } from './resources/webhooks.js';\nimport { CategoriesResource } from './resources/categories.js';\nimport { TagsResource } from './resources/tags.js';\nimport { CustomersResource } from './resources/customers.js';\nimport { FieldsResource } from './resources/fields.js';\nimport { webhookUtils } from './utils/webhooks.js';\n\n/**\n * Configuration options for the Dispatch Tickets client\n *\n * @example\n * ```typescript\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * timeout: 30000,\n * retry: {\n * maxRetries: 5,\n * retryableStatuses: [429, 500, 502, 503, 504],\n * },\n * hooks: {\n * onRequest: (ctx) => console.log(`${ctx.method} ${ctx.url}`),\n * onResponse: (ctx) => console.log(`${ctx.status} in ${ctx.durationMs}ms`),\n * },\n * });\n * ```\n */\nexport interface DispatchTicketsConfig {\n /**\n * Your API key (required)\n *\n * Get your API key from the Dispatch Tickets dashboard.\n * Keys starting with `sk_live_` are production keys.\n * Keys starting with `sk_test_` are test keys.\n */\n apiKey: string;\n\n /**\n * Base URL for the API\n * @default 'https://dispatch-tickets-api.onrender.com/v1'\n */\n baseUrl?: string;\n\n /**\n * Request timeout in milliseconds\n * @default 30000\n */\n timeout?: number;\n\n /**\n * Maximum number of retries for failed requests\n * @default 3\n * @deprecated Use `retry.maxRetries` instead for fine-grained control\n */\n maxRetries?: number;\n\n /**\n * Enable debug logging\n *\n * When enabled, logs all requests, responses, and request IDs to console.\n * @default false\n */\n debug?: boolean;\n\n /**\n * Custom fetch implementation for testing/mocking\n *\n * @example\n * ```typescript\n * const mockFetch = vi.fn().mockResolvedValue({\n * ok: true,\n * status: 200,\n * headers: { get: () => 'application/json' },\n * json: () => Promise.resolve({ id: 'test' }),\n * });\n *\n * const client = new DispatchTickets({\n * apiKey: 'sk_test_...',\n * fetch: mockFetch,\n * });\n * ```\n */\n fetch?: FetchFunction;\n\n /**\n * Fine-grained retry configuration\n *\n * @example\n * ```typescript\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * retry: {\n * maxRetries: 5,\n * retryableStatuses: [429, 500, 502, 503, 504],\n * initialDelayMs: 500,\n * maxDelayMs: 60000,\n * backoffMultiplier: 2,\n * jitter: 0.25,\n * },\n * });\n * ```\n */\n retry?: RetryConfig;\n\n /**\n * Hooks for observability and customization\n *\n * @example\n * ```typescript\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * hooks: {\n * onRequest: (ctx) => {\n * console.log(`[${new Date().toISOString()}] ${ctx.method} ${ctx.url}`);\n * },\n * onResponse: (ctx) => {\n * console.log(`[${ctx.requestId}] ${ctx.status} in ${ctx.durationMs}ms`);\n * },\n * onError: (error, ctx) => {\n * console.error(`Request failed: ${error.message}`);\n * // Send to error tracking service\n * Sentry.captureException(error);\n * },\n * onRetry: (ctx, error, delayMs) => {\n * console.log(`Retrying in ${delayMs}ms (attempt ${ctx.attempt + 1})`);\n * },\n * },\n * });\n * ```\n */\n hooks?: Hooks;\n}\n\n/**\n * Dispatch Tickets SDK client\n *\n * The main entry point for interacting with the Dispatch Tickets API.\n * Create a client instance with your API key and use the resource methods\n * to manage tickets, comments, attachments, and more.\n *\n * @example Basic usage\n * ```typescript\n * import { DispatchTickets } from '@dispatchtickets/sdk';\n *\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * });\n *\n * // List brands\n * const brands = await client.brands.list();\n *\n * // Create a ticket\n * const ticket = await client.tickets.create('ws_abc123', {\n * title: 'Help with login',\n * body: 'I cannot log in to my account',\n * });\n *\n * // Iterate through all tickets\n * for await (const ticket of client.tickets.list('ws_abc123', { status: 'open' })) {\n * console.log(ticket.title);\n * }\n * ```\n *\n * @example With request cancellation\n * ```typescript\n * const controller = new AbortController();\n *\n * // Cancel after 5 seconds\n * setTimeout(() => controller.abort(), 5000);\n *\n * try {\n * const tickets = await client.tickets.listPage('ws_abc123', {}, {\n * signal: controller.signal,\n * });\n * } catch (error) {\n * if (error.message === 'Request aborted by user') {\n * console.log('Request was cancelled');\n * }\n * }\n * ```\n *\n * @example With hooks for logging\n * ```typescript\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * hooks: {\n * onRequest: (ctx) => console.log(`→ ${ctx.method} ${ctx.url}`),\n * onResponse: (ctx) => console.log(`← ${ctx.status} (${ctx.durationMs}ms)`),\n * },\n * });\n * ```\n */\nexport class DispatchTickets {\n private readonly http: HttpClient;\n\n /**\n * Accounts resource for managing the current account and API keys\n *\n * @example\n * ```typescript\n * // Get current account\n * const account = await client.accounts.me();\n *\n * // Get usage statistics\n * const usage = await client.accounts.getUsage();\n *\n * // Create a new API key\n * const newKey = await client.accounts.createApiKey({\n * name: 'Production',\n * allBrands: true,\n * });\n * ```\n */\n readonly accounts: AccountsResource;\n\n /**\n * Brands (workspaces) resource\n *\n * Brands are isolated containers for tickets. Each brand can have its own\n * email address, categories, tags, and settings.\n *\n * @example\n * ```typescript\n * // List all brands\n * const brands = await client.brands.list();\n *\n * // Create a new brand\n * const brand = await client.brands.create({\n * name: 'Acme Support',\n * slug: 'acme',\n * });\n *\n * // Get inbound email address\n * const email = client.brands.getInboundEmail('br_abc123');\n * // Returns: br_abc123@inbound.dispatchtickets.com\n * ```\n */\n readonly brands: BrandsResource;\n\n /**\n * Tickets resource\n *\n * @example\n * ```typescript\n * // Create a ticket\n * const ticket = await client.tickets.create('ws_abc123', {\n * title: 'Issue with billing',\n * body: 'I was charged twice...',\n * priority: 'high',\n * });\n *\n * // Iterate through all tickets\n * for await (const ticket of client.tickets.list('ws_abc123', { status: 'open' })) {\n * console.log(ticket.title);\n * }\n * ```\n */\n readonly tickets: TicketsResource;\n\n /**\n * Comments resource\n *\n * @example\n * ```typescript\n * // Add a comment\n * const comment = await client.comments.create('ws_abc123', 'tkt_xyz', {\n * body: 'Thanks for your patience!',\n * authorType: 'AGENT',\n * });\n *\n * // List comments\n * const comments = await client.comments.list('ws_abc123', 'tkt_xyz');\n * ```\n */\n readonly comments: CommentsResource;\n\n /**\n * Attachments resource\n *\n * @example\n * ```typescript\n * // Simple upload\n * const attachment = await client.attachments.upload(\n * 'ws_abc123',\n * 'tkt_xyz',\n * fileBuffer,\n * 'document.pdf',\n * 'application/pdf'\n * );\n *\n * // Get download URL\n * const { downloadUrl } = await client.attachments.get('ws_abc123', 'tkt_xyz', 'att_abc');\n * ```\n */\n readonly attachments: AttachmentsResource;\n\n /**\n * Webhooks resource\n *\n * @example\n * ```typescript\n * // Create a webhook\n * const webhook = await client.webhooks.create('ws_abc123', {\n * url: 'https://example.com/webhook',\n * secret: 'your-secret',\n * events: ['ticket.created', 'ticket.updated'],\n * });\n * ```\n */\n readonly webhooks: WebhooksResource;\n\n /**\n * Categories resource\n *\n * @example\n * ```typescript\n * // Create a category\n * await client.categories.create('ws_abc123', { name: 'Billing', color: '#ef4444' });\n *\n * // Get category stats\n * const stats = await client.categories.getStats('ws_abc123');\n * ```\n */\n readonly categories: CategoriesResource;\n\n /**\n * Tags resource\n *\n * @example\n * ```typescript\n * // Create a tag\n * await client.tags.create('ws_abc123', { name: 'urgent', color: '#f59e0b' });\n *\n * // Merge tags\n * await client.tags.merge('ws_abc123', 'tag_target', ['tag_source1', 'tag_source2']);\n * ```\n */\n readonly tags: TagsResource;\n\n /**\n * Customers resource\n *\n * @example\n * ```typescript\n * // Create a customer\n * const customer = await client.customers.create('ws_abc123', {\n * email: 'user@example.com',\n * name: 'Jane Doe',\n * });\n *\n * // Search customers\n * const results = await client.customers.search('ws_abc123', 'jane');\n * ```\n */\n readonly customers: CustomersResource;\n\n /**\n * Custom fields resource\n *\n * @example\n * ```typescript\n * // Get all field definitions\n * const fields = await client.fields.getAll('ws_abc123');\n *\n * // Create a field\n * await client.fields.create('ws_abc123', 'ticket', {\n * key: 'order_id',\n * label: 'Order ID',\n * type: 'text',\n * required: true,\n * });\n * ```\n */\n readonly fields: FieldsResource;\n\n /**\n * Static webhook utilities\n *\n * @example\n * ```typescript\n * // Verify webhook signature\n * const isValid = DispatchTickets.webhooks.verifySignature(\n * rawBody,\n * req.headers['x-dispatch-signature'],\n * 'your-secret'\n * );\n *\n * // Generate signature for testing\n * const signature = DispatchTickets.webhooks.generateSignature(\n * JSON.stringify(payload),\n * 'your-secret'\n * );\n * ```\n */\n static readonly webhooks = webhookUtils;\n\n /**\n * Create a new Dispatch Tickets client\n *\n * @param config - Client configuration options\n * @throws Error if API key is not provided\n *\n * @example\n * ```typescript\n * const client = new DispatchTickets({\n * apiKey: 'sk_live_...',\n * });\n * ```\n */\n constructor(config: DispatchTicketsConfig) {\n if (!config.apiKey) {\n throw new Error('API key is required');\n }\n\n const httpConfig: HttpClientConfig = {\n baseUrl: config.baseUrl || 'https://dispatch-tickets-api.onrender.com/v1',\n apiKey: config.apiKey,\n timeout: config.timeout ?? 30000,\n maxRetries: config.maxRetries ?? config.retry?.maxRetries ?? 3,\n debug: config.debug ?? false,\n fetch: config.fetch,\n retry: config.retry,\n hooks: config.hooks,\n };\n\n this.http = new HttpClient(httpConfig);\n\n // Initialize resources\n this.accounts = new AccountsResource(this.http);\n this.brands = new BrandsResource(this.http);\n this.tickets = new TicketsResource(this.http);\n this.comments = new CommentsResource(this.http);\n this.attachments = new AttachmentsResource(this.http);\n this.webhooks = new WebhooksResource(this.http);\n this.categories = new CategoriesResource(this.http);\n this.tags = new TagsResource(this.http);\n this.customers = new CustomersResource(this.http);\n this.fields = new FieldsResource(this.http);\n }\n}\n","import { BaseResource, ApiRequestOptions } from './base.js';\nimport type {\n PortalTicket,\n PortalTicketDetail,\n PortalComment,\n PortalCreateTicketInput,\n PortalListTicketsFilters,\n PortalTicketListResponse,\n} from '../types/portal.js';\n\n/**\n * Options for creating a ticket via portal\n */\nexport interface PortalCreateTicketOptions extends ApiRequestOptions {\n /** Idempotency key to prevent duplicate creation */\n idempotencyKey?: string;\n}\n\n/**\n * Options for adding a comment via portal\n */\nexport interface PortalAddCommentOptions extends ApiRequestOptions {\n /** Idempotency key to prevent duplicate creation */\n idempotencyKey?: string;\n}\n\n/**\n * Portal tickets resource\n *\n * Provides methods for customers to manage their tickets via the portal API.\n *\n * @example\n * ```typescript\n * const portal = new DispatchPortal({ token: 'portal_token...' });\n *\n * // List tickets\n * const { data: tickets } = await portal.tickets.list();\n *\n * // Create a ticket\n * const ticket = await portal.tickets.create({\n * title: 'Need help with my order',\n * body: 'Order #12345 has not arrived...',\n * });\n *\n * // Add a comment\n * await portal.tickets.addComment(ticket.id, 'Any update on this?');\n * ```\n */\nexport class PortalTicketsResource extends BaseResource {\n /**\n * List the customer's tickets\n *\n * Returns a paginated list of tickets belonging to the authenticated customer.\n *\n * @param filters - Optional filters and pagination\n * @param options - Request options\n * @returns Paginated ticket list\n *\n * @example\n * ```typescript\n * // List all tickets\n * const { data: tickets, pagination } = await portal.tickets.list();\n *\n * // Filter by status\n * const openTickets = await portal.tickets.list({ status: 'open' });\n *\n * // Paginate\n * const page2 = await portal.tickets.list({ cursor: pagination.nextCursor });\n * ```\n */\n async list(\n filters?: PortalListTicketsFilters,\n options?: ApiRequestOptions\n ): Promise<PortalTicketListResponse> {\n const query = this.buildListQuery(filters);\n return this._get<PortalTicketListResponse>('/portal/tickets', query, options);\n }\n\n /**\n * Iterate through all tickets with automatic pagination\n *\n * @param filters - Optional filters (cursor is managed automatically)\n * @returns Async iterator of tickets\n *\n * @example\n * ```typescript\n * for await (const ticket of portal.tickets.listAll({ status: 'open' })) {\n * console.log(ticket.title);\n * }\n * ```\n */\n async *listAll(\n filters?: Omit<PortalListTicketsFilters, 'cursor'>\n ): AsyncIterable<PortalTicket> {\n let cursor: string | undefined;\n let hasMore = true;\n\n while (hasMore) {\n const response = await this.list({ ...filters, cursor });\n for (const ticket of response.data) {\n yield ticket;\n }\n cursor = response.pagination.nextCursor ?? undefined;\n hasMore = response.pagination.hasMore;\n }\n }\n\n /**\n * Get a ticket by ID\n *\n * Returns the ticket with its comments (excludes internal comments).\n *\n * @param ticketId - Ticket ID\n * @param options - Request options\n * @returns Ticket detail with comments\n *\n * @example\n * ```typescript\n * const ticket = await portal.tickets.get('tkt_abc123');\n * console.log(ticket.title);\n * console.log(`${ticket.comments.length} comments`);\n * ```\n */\n async get(ticketId: string, options?: ApiRequestOptions): Promise<PortalTicketDetail> {\n return this._get<PortalTicketDetail>(`/portal/tickets/${ticketId}`, undefined, options);\n }\n\n /**\n * Create a new ticket\n *\n * @param data - Ticket data\n * @param options - Request options including idempotency key\n * @returns Created ticket\n *\n * @example\n * ```typescript\n * const ticket = await portal.tickets.create({\n * title: 'Need help with billing',\n * body: 'I was charged twice for my subscription...',\n * });\n * ```\n */\n async create(\n data: PortalCreateTicketInput,\n options?: PortalCreateTicketOptions\n ): Promise<PortalTicket> {\n return this._post<PortalTicket>('/portal/tickets', data, {\n idempotencyKey: options?.idempotencyKey,\n signal: options?.signal,\n });\n }\n\n /**\n * Add a comment to a ticket\n *\n * @param ticketId - Ticket ID\n * @param body - Comment text\n * @param options - Request options including idempotency key\n * @returns Created comment\n *\n * @example\n * ```typescript\n * const comment = await portal.tickets.addComment(\n * 'tkt_abc123',\n * 'Here is the additional information you requested...'\n * );\n * ```\n */\n async addComment(\n ticketId: string,\n body: string,\n options?: PortalAddCommentOptions\n ): Promise<PortalComment> {\n return this._post<PortalComment>(`/portal/tickets/${ticketId}/comments`, { body }, {\n idempotencyKey: options?.idempotencyKey,\n signal: options?.signal,\n });\n }\n\n /**\n * Build query parameters from filters\n */\n private buildListQuery(\n filters?: PortalListTicketsFilters\n ): Record<string, string | number> | undefined {\n if (!filters) return undefined;\n\n const query: Record<string, string | number> = {};\n\n if (filters.status) query.status = filters.status;\n if (filters.sort) query.sort = filters.sort;\n if (filters.order) query.order = filters.order;\n if (filters.limit) query.limit = filters.limit;\n if (filters.cursor) query.cursor = filters.cursor;\n\n return Object.keys(query).length > 0 ? query : undefined;\n }\n}\n","import { HttpClient, HttpClientConfig, FetchFunction } from './utils/http.js';\nimport { PortalTicketsResource } from './resources/portal-tickets.js';\nimport type { PortalTokenResponse } from './types/portal.js';\n\n/**\n * Configuration options for the Dispatch Portal client\n *\n * @example\n * ```typescript\n * const portal = new DispatchPortal({\n * token: 'portal_token_from_backend...',\n * });\n * ```\n */\nexport interface DispatchPortalConfig {\n /**\n * Portal token (required)\n *\n * Obtain this token by:\n * 1. Your backend calls `client.brands.generatePortalToken()` with the customer's email\n * 2. Pass the token to your frontend\n * 3. Frontend creates DispatchPortal with this token\n *\n * Or for self-auth mode:\n * 1. Customer clicks magic link email\n * 2. Your portal page calls `DispatchPortal.verify()` with the URL token\n * 3. Use the returned token to create DispatchPortal\n */\n token: string;\n\n /**\n * Base URL for the API\n * @default 'https://dispatch-tickets-api.onrender.com/v1'\n */\n baseUrl?: string;\n\n /**\n * Request timeout in milliseconds\n * @default 30000\n */\n timeout?: number;\n\n /**\n * Custom fetch implementation (for testing)\n */\n fetch?: FetchFunction;\n}\n\nconst DEFAULT_BASE_URL = 'https://dispatch-tickets-api.onrender.com/v1';\nconst DEFAULT_TIMEOUT = 30000;\n\n/**\n * Dispatch Portal SDK client\n *\n * Customer-facing client for interacting with the portal API.\n * Use this to let customers view and manage their own tickets.\n *\n * @example Authenticated mode (backend generates token)\n * ```typescript\n * // On your backend:\n * const client = new DispatchTickets({ apiKey: 'sk_live_...' });\n * const { token } = await client.brands.generatePortalToken('br_abc123', {\n * email: 'customer@example.com',\n * name: 'Jane Doe',\n * });\n * // Pass token to frontend...\n *\n * // On your frontend:\n * const portal = new DispatchPortal({ token });\n * const { data: tickets } = await portal.tickets.list();\n * ```\n *\n * @example Self-auth mode (magic link)\n * ```typescript\n * // Customer clicks magic link, lands on your portal with ?token=xyz\n * const urlToken = new URLSearchParams(window.location.search).get('token');\n *\n * // Verify the magic link token\n * const { token } = await DispatchPortal.verify(urlToken);\n *\n * // Now use the portal token\n * const portal = new DispatchPortal({ token });\n * const { data: tickets } = await portal.tickets.list();\n * ```\n */\nexport class DispatchPortal {\n private readonly http: HttpClient;\n private readonly config: DispatchPortalConfig;\n\n /**\n * Tickets resource for viewing and creating tickets\n *\n * @example\n * ```typescript\n * // List tickets\n * const { data: tickets } = await portal.tickets.list();\n *\n * // Create a ticket\n * const ticket = await portal.tickets.create({\n * title: 'Need help',\n * body: 'Something is broken...',\n * });\n *\n * // Add a comment\n * await portal.tickets.addComment(ticket.id, 'Here is more info...');\n * ```\n */\n readonly tickets: PortalTicketsResource;\n\n /**\n * Create a new Dispatch Portal client\n *\n * @param config - Portal client configuration\n * @throws Error if token is not provided\n */\n constructor(config: DispatchPortalConfig) {\n if (!config.token) {\n throw new Error('Portal token is required');\n }\n\n this.config = config;\n\n const httpConfig: HttpClientConfig = {\n baseUrl: config.baseUrl || DEFAULT_BASE_URL,\n apiKey: config.token, // HttpClient uses this as Bearer token\n timeout: config.timeout ?? DEFAULT_TIMEOUT,\n maxRetries: 2, // Fewer retries for portal (end-user experience)\n fetch: config.fetch,\n };\n\n this.http = new HttpClient(httpConfig);\n this.tickets = new PortalTicketsResource(this.http);\n }\n\n /**\n * Verify a magic link token and get a portal token\n *\n * Call this when the customer clicks the magic link and lands on your portal.\n * The magic link contains a short-lived token that can be exchanged for a\n * longer-lived portal token.\n *\n * @param magicLinkToken - The token from the magic link URL\n * @param baseUrl - Optional API base URL\n * @param fetchFn - Optional custom fetch function (for testing)\n * @returns Portal token response\n *\n * @example\n * ```typescript\n * // Customer lands on: https://yourapp.com/portal?token=xyz\n * const urlToken = new URLSearchParams(window.location.search).get('token');\n *\n * const { token, email, name } = await DispatchPortal.verify(urlToken);\n *\n * // Store token and create client\n * localStorage.setItem('portalToken', token);\n * const portal = new DispatchPortal({ token });\n * ```\n */\n static async verify(\n magicLinkToken: string,\n baseUrl: string = DEFAULT_BASE_URL,\n fetchFn: FetchFunction = fetch\n ): Promise<PortalTokenResponse> {\n const url = `${baseUrl}/portal/verify`;\n\n const response = await fetchFn(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n },\n body: JSON.stringify({ token: magicLinkToken }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({})) as { message?: string };\n throw new Error(errorData.message || 'Failed to verify magic link token');\n }\n\n return response.json() as Promise<PortalTokenResponse>;\n }\n\n /**\n * Refresh the current portal token\n *\n * Call this before the token expires to get a new token with extended expiry.\n * The new token will have the same customer context.\n *\n * @returns New portal token response\n *\n * @example\n * ```typescript\n * // Check if token is close to expiry and refresh\n * const { token: newToken, expiresAt } = await portal.refresh();\n *\n * // Create new client with refreshed token\n * const newPortal = new DispatchPortal({ token: newToken });\n * ```\n */\n async refresh(): Promise<PortalTokenResponse> {\n return this.http.request<PortalTokenResponse>({\n method: 'POST',\n path: '/portal/refresh',\n });\n }\n\n /**\n * Get the current token\n *\n * Useful for storing/passing the token.\n */\n get token(): string {\n return this.config.token;\n }\n}\n","import type { TicketStatus, TicketPriority, TicketSource, AuthorType } from './common.js';\n\n/**\n * All supported webhook event types\n */\nexport type WebhookEventType =\n | 'ticket.created'\n | 'ticket.updated'\n | 'ticket.comment.created';\n\n/**\n * Base webhook event envelope\n */\nexport interface WebhookEventEnvelope<T extends WebhookEventType, D> {\n /** Unique event ID */\n id: string;\n /** Event type */\n event: T;\n /** Brand ID that triggered the event */\n brand_id: string;\n /** Event data */\n data: D;\n /** ISO timestamp when event was created */\n timestamp: string;\n}\n\n/**\n * Customer info included in events\n */\nexport interface EventCustomerInfo {\n customerId: string | null;\n customerEmail: string | null;\n customerName: string | null;\n}\n\n/**\n * Payload for ticket.created event\n */\nexport interface TicketCreatedData extends EventCustomerInfo {\n id: string;\n ticketNumber: number;\n title: string;\n status: TicketStatus;\n priority: TicketPriority;\n source: TicketSource;\n createdAt: string;\n}\n\n/**\n * Payload for ticket.updated event\n */\nexport interface TicketUpdatedData extends EventCustomerInfo {\n id: string;\n ticketNumber: number;\n title: string;\n status: TicketStatus;\n priority: TicketPriority;\n assigneeId: string | null;\n updatedAt: string;\n /** List of field names that were changed */\n changes: string[];\n}\n\n/**\n * Comment data in ticket.comment.created event\n */\nexport interface EventCommentData {\n id: string;\n body: string;\n authorId: string | null;\n authorType: AuthorType;\n createdAt: string;\n}\n\n/**\n * Payload for ticket.comment.created event\n */\nexport interface CommentCreatedData extends EventCustomerInfo {\n ticketId: string;\n /** Formatted ticket number (e.g., \"ACME-123\") */\n ticketNumber: string;\n comment: EventCommentData;\n}\n\n/**\n * Ticket created webhook event\n */\nexport type TicketCreatedEvent = WebhookEventEnvelope<'ticket.created', TicketCreatedData>;\n\n/**\n * Ticket updated webhook event\n */\nexport type TicketUpdatedEvent = WebhookEventEnvelope<'ticket.updated', TicketUpdatedData>;\n\n/**\n * Comment created webhook event\n */\nexport type CommentCreatedEvent = WebhookEventEnvelope<'ticket.comment.created', CommentCreatedData>;\n\n/**\n * Union of all webhook events\n */\nexport type WebhookEvent = TicketCreatedEvent | TicketUpdatedEvent | CommentCreatedEvent;\n\n/**\n * Map of event types to their data types\n */\nexport interface WebhookEventMap {\n 'ticket.created': TicketCreatedEvent;\n 'ticket.updated': TicketUpdatedEvent;\n 'ticket.comment.created': CommentCreatedEvent;\n}\n\n/**\n * Type guard to check if event is a ticket.created event\n */\nexport function isTicketCreatedEvent(event: WebhookEvent): event is TicketCreatedEvent {\n return event.event === 'ticket.created';\n}\n\n/**\n * Type guard to check if event is a ticket.updated event\n */\nexport function isTicketUpdatedEvent(event: WebhookEvent): event is TicketUpdatedEvent {\n return event.event === 'ticket.updated';\n}\n\n/**\n * Type guard to check if event is a ticket.comment.created event\n */\nexport function isCommentCreatedEvent(event: WebhookEvent): event is CommentCreatedEvent {\n return event.event === 'ticket.comment.created';\n}\n\n/**\n * Parse and validate a webhook payload\n *\n * @param payload - Raw JSON payload string or parsed object\n * @returns Typed webhook event\n * @throws Error if payload is invalid\n *\n * @example\n * ```typescript\n * import { parseWebhookEvent, isTicketCreatedEvent } from '@dispatchtickets/sdk';\n *\n * app.post('/webhooks', (req, res) => {\n * const event = parseWebhookEvent(req.body);\n *\n * if (isTicketCreatedEvent(event)) {\n * console.log('New ticket:', event.data.title);\n * }\n * });\n * ```\n */\nexport function parseWebhookEvent(payload: string | object): WebhookEvent {\n const event = typeof payload === 'string' ? JSON.parse(payload) : payload;\n\n if (!event || typeof event !== 'object') {\n throw new Error('Invalid webhook payload: expected object');\n }\n\n if (!event.event || typeof event.event !== 'string') {\n throw new Error('Invalid webhook payload: missing event type');\n }\n\n if (!event.id || typeof event.id !== 'string') {\n throw new Error('Invalid webhook payload: missing event id');\n }\n\n if (!event.data || typeof event.data !== 'object') {\n throw new Error('Invalid webhook payload: missing data');\n }\n\n const validEvents: WebhookEventType[] = ['ticket.created', 'ticket.updated', 'ticket.comment.created'];\n if (!validEvents.includes(event.event)) {\n throw new Error(`Invalid webhook payload: unknown event type \"${event.event}\"`);\n }\n\n return event as WebhookEvent;\n}\n","import type { PaginatedResponse } from '../types/common.js';\n\n/**\n * Options for paginated requests\n */\nexport interface PaginationOptions {\n limit?: number;\n cursor?: string;\n}\n\n/**\n * Create an async iterator from a paginated API endpoint\n */\nexport function createPaginatedIterator<T>(\n fetchPage: (cursor?: string) => Promise<PaginatedResponse<T>>\n): AsyncIterable<T> {\n return {\n [Symbol.asyncIterator](): AsyncIterator<T> {\n let cursor: string | undefined;\n let hasMore = true;\n let currentPage: T[] = [];\n let currentIndex = 0;\n\n return {\n async next(): Promise<IteratorResult<T>> {\n // If we have items in the current page, return the next one\n if (currentIndex < currentPage.length) {\n return { value: currentPage[currentIndex++], done: false };\n }\n\n // If no more pages, we're done\n if (!hasMore) {\n return { value: undefined, done: true };\n }\n\n // Fetch the next page\n const response = await fetchPage(cursor);\n currentPage = response.data;\n currentIndex = 0;\n cursor = response.pagination.cursor;\n hasMore = response.pagination.hasMore;\n\n // If the page is empty, we're done\n if (currentPage.length === 0) {\n return { value: undefined, done: true };\n }\n\n return { value: currentPage[currentIndex++], done: false };\n },\n };\n },\n };\n}\n\n/**\n * Collect all items from an async iterable into an array\n */\nexport async function collectAll<T>(iterable: AsyncIterable<T>): Promise<T[]> {\n const items: T[] = [];\n for await (const item of iterable) {\n items.push(item);\n }\n return items;\n}\n"]}
|