@trillboards/api-client 3.2.18 → 3.2.20

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.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { __require } from './chunk-J5TJ35CL.mjs';
2
- export { generatedTypes } from './chunk-J5TJ35CL.mjs';
1
+ import { __require } from './chunk-ZXAHFSNU.mjs';
2
+ export { generatedTypes } from './chunk-ZXAHFSNU.mjs';
3
3
  import { createParser } from 'eventsource-parser';
4
4
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
5
5
  import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
@@ -75,7 +75,7 @@ var TrillboardsError = class _TrillboardsError extends Error {
75
75
  };
76
76
 
77
77
  // src/version.ts
78
- var VERSION = "3.2.18";
78
+ var VERSION = "3.2.20";
79
79
 
80
80
  // src/http.ts
81
81
  var PUBLIC_PATHS = ["/v1/errors", "/v1/changelog", "/api/discover", "/v1/health"];
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/error.ts","../src/version.ts","../src/http.ts","../src/resources/screens.ts","../src/resources/devices.ts","../src/resources/impressions.ts","../src/resources/analytics.ts","../src/resources/earnings.ts","../src/resources/errors.ts","../src/resources/webhooks.ts","../src/resources/fleet.ts","../src/resources/audience.ts","../src/stream.ts","../src/resources/data.ts","../src/resources/billing.ts","../src/resources/routes.ts","../src/resources/creativeExperiments.ts","../src/resources/mediaBuys.ts","../src/client.ts","../src/webhooks.ts"],"names":["path","BASE"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * TrillboardsError — client-side error class that mirrors the server-side\n * canonical error envelope from utils/apiErrors.ts.\n *\n * Error shape from the API:\n * { error: { type, code, message, param, doc_url, request_id, details?, help? } }\n */\n\nimport type { ApiErrorType, ErrorDetail, ErrorResponseBody } from './types';\n\nexport interface TrillboardsErrorOptions {\n type: ApiErrorType;\n code: string;\n message: string;\n statusCode: number;\n param?: string | null;\n requestId?: string;\n docsUrl?: string;\n details?: ErrorDetail[];\n help?: Record<string, unknown>;\n retryAfterSeconds?: number | null;\n}\n\nexport class TrillboardsError extends Error {\n readonly type: ApiErrorType;\n readonly code: string;\n readonly param: string | null;\n readonly requestId: string;\n readonly docsUrl: string;\n readonly statusCode: number;\n readonly details: ErrorDetail[];\n readonly help: Record<string, unknown> | null;\n private readonly _retryAfterSeconds: number | null;\n\n constructor(opts: TrillboardsErrorOptions) {\n super(opts.message);\n this.name = 'TrillboardsError';\n this.type = opts.type;\n this.code = opts.code;\n this.statusCode = opts.statusCode;\n this.param = opts.param ?? null;\n this.requestId = opts.requestId ?? '';\n this.docsUrl = opts.docsUrl ?? `https://api.trillboards.com/docs/errors#${opts.code}`;\n this.details = opts.details ?? [];\n this.help = opts.help ?? null;\n this._retryAfterSeconds = opts.retryAfterSeconds ?? null;\n }\n\n /**\n * Construct a TrillboardsError from an API error response body and fetch Response.\n *\n * The API wraps errors in { error: { ... } }. We unwrap and map to class fields.\n */\n static fromResponse(body: ErrorResponseBody | Record<string, unknown>, response: { status: number; headers: { get(name: string): string | null } }): TrillboardsError {\n const errorObj = (body as ErrorResponseBody)?.error ?? body;\n const errData = errorObj as Record<string, unknown>;\n\n const retryAfterHeader = response.headers.get('retry-after');\n let retryAfterSeconds: number | null = null;\n if (retryAfterHeader) {\n const parsed = parseInt(retryAfterHeader, 10);\n if (!isNaN(parsed)) {\n retryAfterSeconds = parsed;\n }\n }\n\n return new TrillboardsError({\n type: (errData.type as ApiErrorType) ?? 'api_error',\n code: (errData.code as string) ?? 'unknown_error',\n message: (errData.message as string) ?? 'An unknown error occurred.',\n statusCode: response.status,\n param: (errData.param as string | null) ?? null,\n requestId: (errData.request_id as string) ?? '',\n docsUrl: (errData.doc_url as string) ?? undefined,\n details: (errData.details as ErrorDetail[]) ?? [],\n help: (errData.help as Record<string, unknown>) ?? null,\n retryAfterSeconds,\n });\n }\n\n /** True if this is a 429 rate limit response. */\n get isRateLimited(): boolean {\n return this.statusCode === 429;\n }\n\n /**\n * Number of seconds to wait before retrying, from the Retry-After header.\n * Returns null if no Retry-After header was present.\n */\n get retryAfter(): number | null {\n return this._retryAfterSeconds;\n }\n\n /** True if this is an authentication error (401). */\n get isAuthError(): boolean {\n return this.statusCode === 401;\n }\n\n /** True if this is a permission/forbidden error (403). */\n get isForbidden(): boolean {\n return this.statusCode === 403;\n }\n\n /** True if this is a server-side error (5xx). */\n get isServerError(): boolean {\n return this.statusCode >= 500;\n }\n}\n","/**\n * SDK version constant. Sent in User-Agent and X-Trillboards-Client headers.\n * Equal to package.json's version: .github/scripts/check-api-client-version-constant.js\n * fails the PR when they differ, and the publish lane's tests (publish-api-client.yml)\n * refuse the release.\n */\nexport const VERSION = '3.2.18';\n","/**\n * Internal HTTP client for the Trillboards API.\n *\n * Uses native fetch (Node 18+) for JSON requests and cancelable live streams.\n * Sends standard headers: Authorization, Content-Type, User-Agent, X-Trillboards-Client.\n */\n\nimport { TrillboardsError } from './error';\nimport type { ErrorResponseBody, RequestOptions } from './types';\nimport { VERSION } from './version';\n\nexport interface HttpClientConfig {\n apiKey: string;\n baseUrl: string;\n version?: string;\n}\n\nexport interface RetryOptions {\n /** Maximum number of retry attempts after the initial call. Defaults to 6. */\n retries?: number;\n /** Base delay in ms for exponential backoff. Defaults to 1000. */\n baseMs?: number;\n /**\n * Optional callback invoked when an attempt fails with a retryable error.\n * `attempt` is 1-indexed (1 = first failure). Useful for observability —\n * the CTV SDK uses this to emit `upload_error` events without coupling\n * the retry loop to event emission.\n */\n onAttemptError?: (attempt: number, error: unknown) => void;\n}\n\n/**\n * Endpoint prefixes that are publicly accessible and do not require (or want)\n * an Authorization header. Sending a malformed key on these paths causes the\n * server to reject the request even though no auth is needed.\n */\nconst PUBLIC_PATHS = ['/v1/errors', '/v1/changelog', '/api/discover', '/v1/health'];\n\n/**\n * Decide whether an error is worth retrying.\n *\n * Retry: 429 (rate limit), 5xx (transient server), TypeError (network / DNS / TLS).\n * Permanent: every other 4xx, and non-Error rejections.\n */\nfunction isRetryable(err: unknown): boolean {\n if (err instanceof TrillboardsError) {\n return err.statusCode === 429 || err.statusCode >= 500;\n }\n // Native fetch surfaces network / DNS / TLS failures as TypeError.\n if (err instanceof TypeError) return true;\n return false;\n}\n\n/**\n * Compute the delay before the next retry attempt.\n *\n * Honors `Retry-After` (in seconds) parsed from 429 responses; otherwise uses\n * exponential backoff (baseMs * 2^attempt) with full jitter to spread thundering-herd\n * retries from a fleet of devices that all 429'd at the same instant.\n */\nfunction computeBackoffMs(attempt: number, baseMs: number, err: unknown): number {\n if (err instanceof TrillboardsError && err.retryAfter != null && err.retryAfter > 0) {\n return err.retryAfter * 1000;\n }\n const exponential = baseMs * Math.pow(2, attempt);\n // Full jitter: random delay in [0, exponential] — RFC-recommended for retries.\n return Math.floor(Math.random() * exponential);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Wrap an async operation in retry-with-exponential-backoff.\n *\n * - Retries up to `retries` times on retryable errors (429, 5xx, TypeError network).\n * - Honors `Retry-After` header on 429 responses (parsed into TrillboardsError.retryAfter).\n * - Throws the last error after the budget is exhausted.\n * - Permanent 4xx (auth, validation, not-found) throw immediately on first attempt.\n *\n * This is the SINGLE retry primitive in the SDK — every POST/PUT/DELETE is\n * wrapped automatically by HttpClient. GET is left to the caller because\n * idempotency assumptions vary by route.\n */\nexport async function retryWithBackoff<T>(\n operation: () => Promise<T>,\n opts: RetryOptions = {},\n): Promise<T> {\n const retries = opts.retries ?? 6;\n const baseMs = opts.baseMs ?? 1000;\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= retries; attempt += 1) {\n try {\n return await operation();\n } catch (err) {\n lastError = err;\n if (!isRetryable(err) || attempt === retries) {\n throw err;\n }\n // 1-indexed for observability; matches \"attempt 1 failed, attempt 2 failed\".\n if (opts.onAttemptError) {\n try {\n opts.onAttemptError(attempt + 1, err);\n } catch {\n // Never let a buggy observer break the retry loop.\n }\n }\n const delayMs = computeBackoffMs(attempt, baseMs, err);\n await sleep(delayMs);\n }\n }\n\n // Unreachable — the loop above always throws or returns. The throw keeps\n // TypeScript's control-flow analysis honest.\n throw lastError;\n}\n\nexport class HttpClient {\n private readonly config: HttpClientConfig;\n\n constructor(config: HttpClientConfig) {\n this.config = config;\n }\n\n async request<T>(method: string, path: string, options?: RequestOptions): Promise<T> {\n const response = await this.requestResponse(method, path, options);\n\n // Handle 204 No Content\n if (response.status === 204) return undefined as T;\n const json = await this.readJson(response);\n if (!response.ok) throw TrillboardsError.fromResponse(json as ErrorResponseBody, response);\n return json as T;\n }\n\n private async requestResponse(method: string, path: string, options?: RequestOptions & { signal?: AbortSignal }): Promise<Response> {\n const url = this.buildUrl(path, options?.params);\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Trillboards-Client': `typescript-sdk/${VERSION}`,\n 'User-Agent': `trillboards-typescript/${VERSION}`,\n ...(options?.headers ?? {}),\n };\n\n // Only send auth on non-public endpoints. Respect a caller-supplied\n // Authorization header (e.g. per-call OAuth token override) — merging\n // options?.headers first and then blindly writing config.apiKey here\n // meant a callsite passing its own Bearer got silently replaced.\n const callerSuppliedAuth = Object.keys(options?.headers ?? {})\n .some((h) => h.toLowerCase() === 'authorization');\n const isPublic = PUBLIC_PATHS.some(prefix => path.startsWith(prefix));\n if (!isPublic && this.config.apiKey && !callerSuppliedAuth) {\n headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n }\n\n if (this.config.version) {\n headers['Trillboards-Version'] = this.config.version;\n }\n\n const fetchOptions: globalThis.RequestInit = {\n method,\n headers,\n };\n\n if (options?.body !== undefined && options.body !== null) {\n fetchOptions.body = JSON.stringify(options.body);\n }\n\n fetchOptions.signal = options?.signal;\n return fetch(url, fetchOptions);\n }\n\n private async readJson(response: Response): Promise<unknown> {\n try { return await response.json(); }\n catch {\n throw new TrillboardsError({type:'api_error',code:'invalid_response',\n message:`Invalid JSON response from API (HTTP ${response.status}).`,statusCode:response.status});\n }\n }\n\n /** Open one authenticated live tail. The native endpoint has no replay cursor. */\n async openStream(path: string, options?: RequestOptions & { signal?: AbortSignal }): Promise<Response> {\n const response = await this.requestResponse('GET', path, {\n ...options, headers: { Accept:'text/event-stream', ...options?.headers },\n });\n if (!response.ok) throw TrillboardsError.fromResponse(await this.readJson(response) as ErrorResponseBody, response);\n if (!/^text\\/event-stream(?:;|$)/i.test(response.headers.get('content-type') || '') || !response.body) {\n await response.body?.cancel();\n throw new TrillboardsError({type:'api_error',code:'invalid_response',\n message:'Expected a text/event-stream response with a body.',statusCode:response.status});\n }\n return response;\n }\n\n get<T>(path: string, opts?: { params?: Record<string, unknown> }): Promise<T> {\n // GET is not auto-wrapped — idempotency assumptions vary by route and\n // the caller knows whether a retry is safe.\n return this.request<T>('GET', path, { params: opts?.params });\n }\n\n /**\n * POST / PUT / PATCH / DELETE auto-retry on 429 + 5xx + network TypeError\n * via `retryWithBackoff()`. Callers can opt into observability by passing\n * `retry.onAttemptError` to receive a callback per transient failure.\n *\n * The retry behavior is identical across all four methods because all of\n * them are state-changing operations subject to the same transient-failure\n * classes (rate limit, upstream-down, network-flap). The wire idempotency\n * of POST vs DELETE is enforced server-side via Idempotency-Key headers,\n * which the caller can attach via `opts.headers`.\n */\n post<T>(path: string, body?: unknown, opts?: { retry?: RetryOptions; headers?: Record<string, string> }): Promise<T> {\n return retryWithBackoff(() => this.request<T>('POST', path, { body, headers: opts?.headers }), opts?.retry);\n }\n\n put<T>(path: string, body?: unknown, opts?: { retry?: RetryOptions; headers?: Record<string, string> }): Promise<T> {\n return retryWithBackoff(() => this.request<T>('PUT', path, { body, headers: opts?.headers }), opts?.retry);\n }\n\n patch<T>(path: string, body?: unknown, opts?: { retry?: RetryOptions; headers?: Record<string, string> }): Promise<T> {\n return retryWithBackoff(() => this.request<T>('PATCH', path, { body, headers: opts?.headers }), opts?.retry);\n }\n\n delete<T>(path: string, opts?: { retry?: RetryOptions; headers?: Record<string, string> }): Promise<T> {\n return retryWithBackoff(() => this.request<T>('DELETE', path, { headers: opts?.headers }), opts?.retry);\n }\n\n private buildUrl(path: string, params?: Record<string, unknown>): string {\n const base = `${this.config.baseUrl}${path}`;\n if (!params || Object.keys(params).length === 0) {\n return base;\n }\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n searchParams.set(key, String(value));\n }\n }\n return `${base}?${searchParams.toString()}`;\n }\n}\n","/**\n * ScreensClient — Partner API screen management.\n *\n * Base path: /v1/partner (screens are mapped from devices + screen pairs)\n */\n\nimport type { HttpClient } from '../http';\nimport type { ListResponse } from '../types';\nimport type {\n DisplaySettingsInput,\n DisplaySettingsResponse,\n PartnerDeviceRegistrationInput,\n Screen,\n} from '../generated';\n\nexport class ScreensClient {\n constructor(private readonly http: HttpClient) {}\n\n /** List all screens owned by this partner. */\n async list(params?: { limit?: number; offset?: number }): Promise<ListResponse<Screen>> {\n return this.http.get<ListResponse<Screen>>('/v1/partner/devices', { params });\n }\n\n /** Get a single screen by ID. */\n async get(screenId: string): Promise<{ success: boolean; data: Screen }> {\n return this.http.get<{ success: boolean; data: Screen }>(`/v1/partner/device/${screenId}`);\n }\n\n /** Register a new device/screen. */\n async create(body: PartnerDeviceRegistrationInput): Promise<{ success: boolean; data: Screen }> {\n return this.http.post<{ success: boolean; data: Screen }>('/v1/partner/device', body);\n }\n\n /** Get the resolved display settings for one screen. */\n async getDisplaySettings(screenId: string): Promise<DisplaySettingsResponse> {\n return this.http.get(`/v1/partner/screens/${screenId}/display-settings`);\n }\n\n /** Partially update display settings; omitted content-fit keys are preserved. */\n async patchDisplaySettings(\n screenId: string,\n settings: DisplaySettingsInput,\n ): Promise<DisplaySettingsResponse> {\n return this.http.patch(`/v1/partner/screens/${screenId}/display-settings`, settings);\n }\n\n /** Update display settings through the PUT endpoint. */\n async updateDisplaySettings(\n screenId: string,\n settings: DisplaySettingsInput,\n ): Promise<DisplaySettingsResponse> {\n return this.http.put(`/v1/partner/screens/${screenId}/display-settings`, settings);\n }\n\n /** Apply a partial display-settings update to up to 100 screens. */\n async batchUpdateDisplaySettings(\n screenIds: string[],\n settings: DisplaySettingsInput,\n ): Promise<Record<string, unknown>> {\n return this.http.post('/v1/partner/screens/batch/display-settings', {\n screen_ids: screenIds,\n settings,\n });\n }\n\n /** Delete a screen/device. */\n async delete(screenId: string): Promise<{ success: boolean }> {\n return this.http.delete<{ success: boolean }>(`/v1/partner/device/${screenId}`);\n }\n}\n","/**\n * DevicesClient — device registration and heartbeat.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient, RetryOptions } from '../http';\nimport type { ListResponse } from '../types';\nimport type {\n Device,\n PartnerDeviceBatchRegistrationInput,\n PartnerDeviceRegistrationInput,\n} from '../generated';\n\nexport class DevicesClient {\n constructor(private readonly http: HttpClient) {}\n\n /** List all devices for this partner. */\n async list(params?: { limit?: number; offset?: number }): Promise<ListResponse<Device>> {\n return this.http.get<ListResponse<Device>>('/v1/partner/devices', { params });\n }\n\n /** Get a single device by ID. */\n async get(deviceId: string): Promise<{ success: boolean; data: Device }> {\n return this.http.get<{ success: boolean; data: Device }>(`/v1/partner/device/${deviceId}`);\n }\n\n /** Register a new device. */\n async create(body: PartnerDeviceRegistrationInput): Promise<{ success: boolean; data: Device }> {\n return this.http.post<{ success: boolean; data: Device }>('/v1/partner/device', body);\n }\n\n /** Register or re-register up to 100 devices with optional fleet defaults. */\n async createBatch(body: PartnerDeviceBatchRegistrationInput): Promise<{\n success: boolean;\n summary: Record<string, number>;\n devices: Array<Record<string, unknown>>;\n errors: Array<Record<string, unknown>>;\n }> {\n return this.http.post('/v1/partner/devices/batch', body);\n }\n\n /** Delete a device. */\n async delete(deviceId: string): Promise<{ success: boolean }> {\n return this.http.delete<{ success: boolean }>(`/v1/partner/device/${deviceId}`);\n }\n\n /**\n * Send heartbeat for a device.\n *\n * Auto-retries on 429 + 5xx + network TypeError via the shared\n * retryWithBackoff() helper (see http.ts). Pass `opts.retry.onAttemptError`\n * to observe transient failures (e.g. emit an `upload_error` event from\n * the CTV SDK without coupling the retry loop to its event emitter).\n */\n async heartbeat(\n deviceId: string,\n body?: Record<string, unknown>,\n opts?: { retry?: RetryOptions },\n ): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(\n `/v1/partner/device/${deviceId}/heartbeat`,\n body ?? {},\n { retry: opts?.retry },\n );\n }\n}\n","/**\n * ImpressionsClient — impression tracking.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { Impression } from '../generated';\n\nexport class ImpressionsClient {\n constructor(private readonly http: HttpClient) {}\n\n /** Record a single impression. */\n async create(body: {\n screen_id: string;\n device_id: string;\n ad_type?: string;\n duration_seconds?: number;\n metadata?: Record<string, unknown>;\n }): Promise<{ success: boolean; data: Impression }> {\n return this.http.post<{ success: boolean; data: Impression }>('/v1/partner/impression', body);\n }\n\n /** Record a batch of impressions (offline sync). */\n async createBatch(body: {\n impressions: Array<{\n screen_id: string;\n device_id: string;\n ad_type?: string;\n duration_seconds?: number;\n played_at?: string;\n metadata?: Record<string, unknown>;\n }>;\n }): Promise<{ success: boolean; count: number }> {\n return this.http.post<{ success: boolean; count: number }>('/v1/partner/impressions/batch', body);\n }\n}\n","/**\n * AnalyticsClient — partner analytics and reporting.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { AnalyticsData } from '../generated';\n\nexport class AnalyticsClient {\n constructor(private readonly http: HttpClient) {}\n\n /** Get partner analytics summary. */\n async get(params?: {\n period?: 'day' | 'week' | 'month';\n start_date?: string;\n end_date?: string;\n screen_id?: string;\n }): Promise<{ success: boolean; data: AnalyticsData }> {\n return this.http.get<{ success: boolean; data: AnalyticsData }>('/v1/partner/analytics', { params });\n }\n}\n","/**\n * EarningsClient — earnings, payouts, and transaction history.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { EarningsData } from '../generated';\n\nexport class EarningsClient {\n constructor(private readonly http: HttpClient) {}\n\n /** Get earnings summary for the authenticated partner. */\n async get(params?: {\n period?: 'day' | 'week' | 'month';\n start_date?: string;\n end_date?: string;\n }): Promise<{ success: boolean; data: EarningsData }> {\n return this.http.get<{ success: boolean; data: EarningsData }>('/v1/partner/connect/earnings', { params });\n }\n}\n","/**\n * ErrorsClient — access the public error catalog and query partner errors.\n *\n * list() hits /v1/errors (public, no auth required).\n * get() hits /v1/partner/usage (authenticated, partner-scoped).\n */\n\nimport type { HttpClient } from '../http';\nimport type { ListResponse } from '../types';\nimport type { ErrorEntry } from '../generated';\n\nexport class ErrorsClient {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all known API error codes from the public error catalog.\n * This endpoint does NOT require authentication.\n */\n async list(params?: {\n limit?: number;\n offset?: number;\n code?: string;\n type?: string;\n }): Promise<ListResponse<ErrorEntry>> {\n return this.http.get<ListResponse<ErrorEntry>>('/v1/errors', { params });\n }\n\n /** Get a single error by request_id (requires authentication). */\n async get(requestId: string): Promise<{ success: boolean; data: ErrorEntry }> {\n return this.http.get<{ success: boolean; data: ErrorEntry }>(`/v1/partner/usage`, {\n params: { request_id: requestId },\n });\n }\n}\n","/**\n * WebhooksClient — webhook subscription management.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { ListResponse } from '../types';\nimport type { Webhook } from '../generated';\n\nexport class WebhooksClient {\n constructor(private readonly http: HttpClient) {}\n\n /** List all webhook subscriptions. */\n async list(): Promise<ListResponse<Webhook>> {\n return this.http.get<ListResponse<Webhook>>('/v1/partner/webhooks');\n }\n\n /**\n * Create a new webhook subscription.\n *\n * The created `Webhook` carries its signing `secret` (`whsec_…`) — this is the\n * ONLY time it is returned. Persist it securely and pass it to\n * `Webhooks.constructEvent()` to verify the compound `X-Trillboards-Signature`\n * header over the raw delivery body.\n */\n async create(body: {\n url: string;\n events: string[];\n }): Promise<{ success: boolean; data: Webhook }> {\n return this.http.post<{ success: boolean; data: Webhook }>('/v1/partner/webhooks', body);\n }\n\n /** Update a webhook subscription. */\n async update(webhookId: string, body: {\n url?: string;\n events?: string[];\n status?: string;\n }): Promise<{ success: boolean; data: Webhook }> {\n return this.http.patch<{ success: boolean; data: Webhook }>(`/v1/partner/webhooks/${webhookId}`, body);\n }\n\n /** Delete a webhook subscription. */\n async delete(webhookId: string): Promise<{ success: boolean }> {\n return this.http.delete<{ success: boolean }>(`/v1/partner/webhooks/${webhookId}`);\n }\n\n /** Send a test event to a webhook. */\n async test(webhookId: string): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(`/v1/partner/webhooks/${webhookId}/test`);\n }\n}\n","/**\n * FleetClient — fleet-wide device management.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { ListResponse } from '../types';\nimport type { FleetCommand } from '../generated';\n\nexport class FleetClient {\n constructor(private readonly http: HttpClient) {}\n\n /** Push a command to a set of screens. */\n async pushCommand(body: {\n command: string;\n target_screens?: string[];\n venue_type?: string;\n country?: string;\n params?: Record<string, unknown>;\n }): Promise<{ success: boolean; data: FleetCommand }> {\n return this.http.post<{ success: boolean; data: FleetCommand }>('/v1/partner/fleet/command', body);\n }\n\n /** List recent fleet commands. */\n async listCommands(params?: { limit?: number; offset?: number }): Promise<ListResponse<FleetCommand>> {\n return this.http.get<ListResponse<FleetCommand>>('/v1/partner/fleet/commands', { params });\n }\n}\n","/**\n * AudienceClient — audience intelligence API.\n *\n * Base path: /v1/partner/audience\n */\n\nimport type { HttpClient } from '../http';\nimport type { AudienceData } from '../generated';\n\nexport class AudienceClient {\n constructor(private readonly http: HttpClient) {}\n\n /** Get live audience data for a screen. */\n async getLive(screenId: string): Promise<{ success: boolean; data: AudienceData }> {\n return this.http.get<{ success: boolean; data: AudienceData }>(`/v1/partner/audience/live/${screenId}`);\n }\n\n /** Get audience heatmap across screens. */\n async getHeatmap(params?: {\n start_date?: string;\n end_date?: string;\n screen_ids?: string[];\n }): Promise<{ success: boolean; data: Record<string, unknown> }> {\n return this.http.get<{ success: boolean; data: Record<string, unknown> }>('/v1/partner/audience/heatmap', { params });\n }\n\n /** Get aggregate audience statistics. */\n async getStats(params?: {\n period?: 'day' | 'week' | 'month';\n }): Promise<{ success: boolean; data: Record<string, unknown> }> {\n return this.http.get<{ success: boolean; data: Record<string, unknown> }>('/v1/partner/audience/stats', { params });\n }\n}\n","import { createParser } from 'eventsource-parser';\nimport type { HttpClient } from './http';\nimport { TrillboardsError } from './error';\n\n/** The SSE frame and its decoded JSON payload; in-band error events remain events. */\nexport interface DataStreamEvent {\n event: string;\n data: unknown;\n id?: string;\n retry?: number;\n}\nexport interface StreamOptions { signal?: AbortSignal; }\n\n/** Use the same SSE parser as the official MCP transport, with native fetch cancellation. */\nexport async function* readEventStream(http:HttpClient,path:string,\n params:Record<string,unknown>,options:StreamOptions):AsyncGenerator<DataStreamEvent> {\n const controller=new AbortController();\n const abort=()=>controller.abort(options.signal?.reason);\n if(options.signal?.aborted) abort();\n else options.signal?.addEventListener('abort',abort,{once:true});\n let reader:ReadableStreamDefaultReader<Uint8Array>|undefined;\n try {\n const response=await http.openStream(path,{params,signal:controller.signal});\n reader=response.body!.getReader();\n const decoder=new TextDecoder(),events:DataStreamEvent[]=[];\n let retry:number|undefined;\n const parser=createParser({\n onRetry:value=>{retry=value;},\n onEvent:frame=>{\n let data:unknown;\n try { data=JSON.parse(frame.data); }\n catch { throw new TrillboardsError({type:'api_error',code:'invalid_response',\n message:'Expected JSON data in an SSE event.',statusCode:response.status}); }\n events.push({event:frame.event || 'message',data,\n ...(frame.id===undefined?{}:{id:frame.id}),...(retry===undefined?{}:{retry})});\n retry=undefined;\n },\n });\n while(true) {\n const chunk=await reader.read();\n if(chunk.done) break;\n parser.feed(decoder.decode(chunk.value,{stream:true}));\n while(events.length) {\n if(controller.signal.aborted) throw controller.signal.reason;\n yield events.shift()!;\n }\n }\n parser.feed(decoder.decode());\n while(events.length) yield events.shift()!;\n } finally {\n options.signal?.removeEventListener('abort',abort);\n controller.abort();\n try { await reader?.cancel(); } catch { /* Abort may already have closed the reader. */ }\n reader?.releaseLock();\n }\n}\n","/** Native data access through the existing authenticated transport. */\nimport type { HttpClient } from '../http';\nimport type {\n dataApiListScreensOperation, dataApiScreenAudienceHistoryOperation,\n dataApiScreenAudienceLiveOperation, dataApiQueryDslOperation, dataApiStreamOperation,\n} from '../generated';\nimport { readEventStream, type DataStreamEvent, type StreamOptions } from '../stream';\nexport type { DataStreamEvent, StreamOptions } from '../stream';\n\nexport class DataClient {\n constructor(private readonly http: HttpClient) {}\n /** Get venue intelligence data for a screen. */\n getVenueIntelligence(screenId: string): Promise<{success:boolean;data:Record<string,unknown>}> {\n return this.http.get('/v1/partner/venue/'+encodeURIComponent(screenId));\n }\n /** Get API usage summary. */\n getUsage(params?: {period?:'day'|'week'|'month'}): Promise<{success:boolean;data:Record<string,unknown>}> {\n return this.http.get('/v1/partner/usage',{params});\n }\n listScreens(query: dataApiListScreensOperation['query'] = {}): Promise<dataApiListScreensOperation['response']> {\n return this.http.get('/v1/data/screens',{params:query});\n }\n getHistory(screenId:string,query:dataApiScreenAudienceHistoryOperation['query']={}):Promise<dataApiScreenAudienceHistoryOperation['response']> {\n return this.http.get('/v1/data/screens/'+encodeURIComponent(screenId)+'/history',{params:query});\n }\n getAudience(screenId:string):Promise<dataApiScreenAudienceLiveOperation['response']> {\n return this.http.get('/v1/data/screens/'+encodeURIComponent(screenId)+'/audience');\n }\n query(body:dataApiQueryDslOperation['request']):Promise<dataApiQueryDslOperation['response']> {\n return this.http.post('/v1/data/query',body);\n }\n /** One live tail; reconnect explicitly and recover history through bounded reads. */\n stream(query:dataApiStreamOperation['query']={},options:StreamOptions={}):AsyncIterable<DataStreamEvent> {\n return readEventStream(this.http,'/v1/data/stream',query,options);\n }\n}\n","/**\n * BillingClient — usage-based billing and credits.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { BillingInfo, setupBillingOperation, createCreditCheckoutOperation, purchaseCreditsOperation, getBillingUsageSummaryOperation } from '../generated';\n\n/** Reuse the same key only for the exact same financial request. */\nexport interface BillingOperationOptions { idempotencyKey: string; }\n\nexport class BillingClient {\n constructor(private readonly http: HttpClient) {}\n\n setup(body:setupBillingOperation['request']):Promise<setupBillingOperation['response']> {\n return this.http.post('/v1/partner/billing/setup',body);\n }\n\n createCreditCheckout(body:createCreditCheckoutOperation['request'],options:BillingOperationOptions):Promise<createCreditCheckoutOperation['response']> {\n return this.http.post('/v1/partner/billing/credits/checkout',body,{headers:{'Idempotency-Key':options.idempotencyKey}});\n }\n\n purchaseCredits(body:purchaseCreditsOperation['request'],options:BillingOperationOptions):Promise<purchaseCreditsOperation['response']> {\n return this.http.post('/v1/partner/billing/credits',body,{headers:{'Idempotency-Key':options.idempotencyKey}});\n }\n\n /** Read the committed shared credit ledger after Stripe payment completes. */\n getUsageSummary():Promise<getBillingUsageSummaryOperation['response']> {\n return this.http.get('/v1/partner/billing/usage-summary');\n }\n\n /** Get current billing info (plan, credits, usage). */\n async get(): Promise<{ success: boolean; data: BillingInfo }> {\n return this.http.get<{ success: boolean; data: BillingInfo }>('/v1/partner/billing');\n }\n\n /** Get Stripe Connect account status. */\n async getStripeStatus(): Promise<{ success: boolean; data: Record<string, unknown> }> {\n return this.http.get<{ success: boolean; data: Record<string, unknown> }>('/v1/partner/stripe/status');\n }\n\n /** Request a payout transfer. */\n async requestPayout(body?: {\n amount?: number;\n }): Promise<{ success: boolean; data: Record<string, unknown> }> {\n return this.http.post<{ success: boolean; data: Record<string, unknown> }>('/v1/partner/stripe/payout', body ?? {});\n }\n}\n","/**\n * RoutesClient — Sense Anything \"Routes\": alerting + automation on the sensing\n * stream. A Route fires channel actions (webhook / managed WhatsApp / SMS /\n * Slack / email) when a sensed field crosses a threshold on a set of your\n * screens, or on a scheduled digest.\n *\n * Base path: /v1/partner/sensing/routes\n */\n\nimport type { HttpClient } from '../http';\nimport type {\n SensingRoute,\n CreatePartnerSensingRouteRequest,\n UpdatePartnerSensingRouteRequest,\n} from '../generated';\n\nconst BASE = '/v1/partner/sensing/routes';\n\nexport class RoutesClient {\n constructor(private readonly http: HttpClient) {}\n\n /** Create a Route. Every screen in `screenMongoIds` must be one you own. */\n async create(body: CreatePartnerSensingRouteRequest): Promise<{ success: boolean; data: { route: SensingRoute } }> {\n return this.http.post<{ success: boolean; data: { route: SensingRoute } }>(BASE, body);\n }\n\n /** List your Routes. Pass `includeDisabled: false` to return only enabled Routes. */\n async list(params?: { includeDisabled?: boolean }): Promise<{ success: boolean; data: { routes: SensingRoute[] } }> {\n return this.http.get<{ success: boolean; data: { routes: SensingRoute[] } }>(BASE, { params });\n }\n\n /** Get one Route by id. */\n async get(routeId: string): Promise<{ success: boolean; data: { route: SensingRoute } }> {\n return this.http.get<{ success: boolean; data: { route: SensingRoute } }>(`${BASE}/${routeId}`);\n }\n\n /** Update a Route (partial, non-clobbering — only the fields you send change). */\n async update(\n routeId: string,\n body: UpdatePartnerSensingRouteRequest,\n ): Promise<{ success: boolean; data: { route: SensingRoute } }> {\n return this.http.patch<{ success: boolean; data: { route: SensingRoute } }>(`${BASE}/${routeId}`, body);\n }\n\n /** Soft-delete a Route. */\n async delete(routeId: string): Promise<{ success: boolean; data: { routeId: string } }> {\n return this.http.delete<{ success: boolean; data: { routeId: string } }>(`${BASE}/${routeId}`);\n }\n}\n","/** Native funded creative feedback, using the existing partner HTTP client. */\nimport type {HttpClient} from '../http';\nimport type {\n importCreativeFeedbackCreativeOperation,configureCreativeFeedbackBrandOperation,createCreativeFeedbackExperimentOperation,getCreativeFeedbackExperimentOperation,\n registerCreativeFeedbackVariantsOperation,updateCreativeFeedbackPolicyOperation,\n getCreativeFeedbackRewardsOperation,stopCreativeFeedbackExperimentOperation,\n generateCreativeFeedbackCreativeOperation,reviewCreativeFeedbackCreativeOperation,\n} from '../generated';\nconst BASE='/v1/partner/creative-experiments';\nconst path=(id:string)=>`${BASE}/${encodeURIComponent(id)}`;\nexport class CreativeExperimentsClient {\n constructor(private readonly http:HttpClient){}\n create(body:createCreativeFeedbackExperimentOperation['request']):Promise<createCreativeFeedbackExperimentOperation['response']>{return this.http.post(BASE,body);}\n configureBrand(id:string,body:configureCreativeFeedbackBrandOperation['request']):Promise<configureCreativeFeedbackBrandOperation['response']>{return this.http.post(path(id)+'/brand',body);}\n importCreative(id:string,body:importCreativeFeedbackCreativeOperation['request']):Promise<importCreativeFeedbackCreativeOperation['response']>{return this.http.post(path(id)+'/creatives/import',body);}\n get(id:string):Promise<getCreativeFeedbackExperimentOperation['response']>{return this.http.get(path(id));}\n registerVariants(id:string,body:registerCreativeFeedbackVariantsOperation['request']):Promise<registerCreativeFeedbackVariantsOperation['response']>{return this.http.post(path(id)+'/variants',body);}\n updatePolicy(id:string,body:updateCreativeFeedbackPolicyOperation['request']):Promise<updateCreativeFeedbackPolicyOperation['response']>{return this.http.put(path(id)+'/policy',body);}\n getRewards(id:string,query:getCreativeFeedbackRewardsOperation['query']):Promise<getCreativeFeedbackRewardsOperation['response']>{return this.http.get(path(id)+'/rewards',{params:query});}\n generate(id:string,body:generateCreativeFeedbackCreativeOperation['request']):Promise<generateCreativeFeedbackCreativeOperation['response']>{return this.http.post(path(id)+'/creatives/generate',body);}\n review(id:string,body:reviewCreativeFeedbackCreativeOperation['request']):Promise<reviewCreativeFeedbackCreativeOperation['response']>{return this.http.post(path(id)+'/creatives/review',body);}\n stop(id:string,body:stopCreativeFeedbackExperimentOperation['request']):Promise<stopCreativeFeedbackExperimentOperation['response']>{return this.http.post(path(id)+'/stop',body);}\n}\n","/** Native AdCP buying tools on /mcp, using the official protocol client. */\nimport {Client} from '@modelcontextprotocol/sdk/client/index.js';\nimport {StreamableHTTPClientTransport} from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport type {CallToolResult} from '@modelcontextprotocol/sdk/types.js';\nimport type {HttpClientConfig} from '../http';\nimport {VERSION} from '../version';\nimport type {\n Mcp_get_products_Args,Mcp_list_accounts_Args,Mcp_sync_accounts_Args,\n Mcp_create_media_buy_Args,Mcp_get_media_buys_Args,Mcp_update_media_buy_Args,\n Mcp_sync_creatives_Args,Mcp_get_media_buy_delivery_Args,Mcp_discover_inventory_Args,\n} from '../generated';\n\n/** Native MCP errors retain their complete result, including structured receipts. */\nexport class McpToolError extends Error {\n readonly name='McpToolError';\n constructor(readonly tool:string,readonly result:CallToolResult) {\n super('Native MCP tool failed: '+tool);\n }\n}\nexport interface MediaPagination {has_more:boolean;cursor?:string;total_count?:number;}\nexport interface MediaProduct extends Record<string,unknown> {\n product_id:string;name?:string;pricing_options:Array<{pricing_option_id:string;fixed_price?:number;floor_price?:number;currency?:string;[key:string]:unknown}>;\n}\nexport interface MediaFunding extends Record<string,unknown> {\n status:string;required_cents?:number|string;available_cents?:number|string;drawn_cents?:number|string;\n}\nexport interface MediaPackage extends Record<string,unknown> {package_id:string;product_id?:string;}\n/** Selected native response fields; the complete extensible payload is preserved. */\nexport interface MediaBuy extends Record<string,unknown> {\n media_buy_id:string;packages:MediaPackage[];revision:number;media_buy_status?:string;status?:string;funding?:MediaFunding;\n}\nexport interface MediaProductsResponse extends Record<string,unknown> {products:MediaProduct[];pagination?:MediaPagination;}\nexport interface MediaBuysResponse extends Record<string,unknown> {media_buys:MediaBuy[];pagination:MediaPagination;}\nexport interface MediaAccountsResponse extends Record<string,unknown> {accounts:Array<{account_id:string;status:string;[key:string]:unknown}>;pagination?:MediaPagination;}\n\n\nexport interface MediaNativeError extends Record<string,unknown> {code:string;message:string;}\nexport interface MediaBuyUpdateResponse extends Record<string,unknown> {\n media_buy_id:string;revision:number;media_buy_status:string;sandbox:boolean;\n affected_packages?:MediaPackage[];applied:Record<string,unknown>;unsupported:string[];\n placements_updated:number;placement_count:number;\n}\nexport interface MediaDeliveryResponse extends Record<string,unknown> {\n media_buy_id:string;impressions:number;reach_screens:number;contracted_spend_usd:number;sandbox:boolean;\n pacing:{goal_impressions:number;delivered:number;delivery_rate:number};\n dimensions_honoured:string[];dimensions_unsupported:string[];\n}\nexport interface MediaCreativeSyncResponse extends Record<string,unknown> {\n media_buy_id:string|null;advertisement_id:string|null;sandbox:boolean;\n creatives:Array<{creative_id:string;action:string;status?:string;errors?:MediaNativeError[];[key:string]:unknown}>;\n validation_results:Array<Record<string,unknown>>;approved_count:number;rejected_count:number;\n placements_activated:number;servable:boolean;funding?:MediaFunding;moderation?:Record<string,unknown>;\n validated_against:{catalogue_generated_at:string;stale:boolean};\n}\nexport interface MediaAccountsSyncResponse extends Record<string,unknown> {\n dry_run:boolean;\n accounts:Array<{account_id:string|null;action:string;status?:string;errors?:MediaNativeError[];[key:string]:unknown}>;\n}\n\nexport class MediaBuysClient {\n private client?:Client;\n private transport?:StreamableHTTPClientTransport;\n private connecting?:Promise<Client>;\n constructor(private readonly config:HttpClientConfig) {}\n\n private connection():Promise<Client> {\n if(!this.connecting) {\n const client=new Client({name:'trillboards-typescript',version:VERSION});\n const transport=new StreamableHTTPClientTransport(new URL(this.config.baseUrl+'/mcp'),{\n requestInit:{headers:{\n Authorization:'Bearer '+this.config.apiKey,\n 'X-Trillboards-Client':'typescript-sdk/'+VERSION,\n 'User-Agent':'trillboards-typescript/'+VERSION,\n ...(this.config.version?{'Trillboards-Version':this.config.version}:{}),\n }},\n });\n this.client=client;this.transport=transport;\n this.connecting=client.connect(transport).then(()=>client).catch(async error=>{\n await client.close();this.client=undefined;this.transport=undefined;this.connecting=undefined;throw error;\n });\n }\n return this.connecting;\n }\n\n private async call<T>(name:string,args:Record<string,unknown>):Promise<T> {\n const client=await this.connection();\n const result=await client.callTool({name,arguments:args}) as CallToolResult;\n if(result.isError) throw new McpToolError(name,result);\n if(result.structuredContent) return result.structuredContent as T;\n for(const block of result.content) {\n if(block.type!=='text') continue;\n try {return JSON.parse(block.text) as T;} catch { /* A prose summary is not the structured result. */ }\n }\n throw new McpToolError(name,result);\n }\n\n getProducts(args:Mcp_get_products_Args={}):Promise<MediaProductsResponse> {return this.call('get_products',args);}\n listAccounts(args:Mcp_list_accounts_Args={}):Promise<MediaAccountsResponse> {return this.call('list_accounts',args);}\n syncAccounts(args:Mcp_sync_accounts_Args):Promise<MediaAccountsSyncResponse> {return this.call('sync_accounts',args);}\n create(args:Mcp_create_media_buy_Args):Promise<MediaBuy> {return this.call('create_media_buy',args);}\n list(args:Mcp_get_media_buys_Args={}):Promise<MediaBuysResponse> {return this.call('get_media_buys',args);}\n update(args:Mcp_update_media_buy_Args):Promise<MediaBuyUpdateResponse> {return this.call('update_media_buy',args);}\n getDelivery(args:Mcp_get_media_buy_delivery_Args):Promise<MediaDeliveryResponse> {return this.call('get_media_buy_delivery',args);}\n syncCreatives(args:Mcp_sync_creatives_Args):Promise<MediaCreativeSyncResponse> {return this.call('sync_creatives',args);}\n discoverInventory(args:Mcp_discover_inventory_Args={}):Promise<{success:boolean;data:{screens:Array<Record<string,unknown>>;[key:string]:unknown}}> {return this.call('discover_inventory',args);}\n\n /** Release MCP streams and terminate an optional server session. */\n async close():Promise<void> {\n await this.connecting?.catch(()=>undefined);\n const client=this.client,transport=this.transport;\n this.client=undefined;this.transport=undefined;this.connecting=undefined;\n try {if(transport?.sessionId) await transport.terminateSession();}\n finally {await client?.close();}\n }\n}\n","/**\n * TrillboardsClient — main entry point for the Trillboards Partner API SDK.\n *\n * Usage:\n * import { TrillboardsClient } from '@trillboards/api-client';\n *\n * const client = new TrillboardsClient({ apiKey: 'trb_partner_xxxxx' });\n * const screens = await client.screens.list();\n */\n\nimport { HttpClient } from './http';\nimport type { ClientOptions } from './types';\nimport {\n ScreensClient,\n DevicesClient,\n ImpressionsClient,\n AnalyticsClient,\n EarningsClient,\n ErrorsClient,\n WebhooksClient,\n FleetClient,\n AudienceClient,\n DataClient,\n BillingClient,\n RoutesClient,\n CreativeExperimentsClient,\n MediaBuysClient,\n} from './resources';\n\nconst DEFAULT_BASE_URL = 'https://api.trillboards.com';\n\nexport class TrillboardsClient {\n readonly screens: ScreensClient;\n readonly devices: DevicesClient;\n readonly impressions: ImpressionsClient;\n readonly analytics: AnalyticsClient;\n readonly webhooks: WebhooksClient;\n readonly earnings: EarningsClient;\n readonly fleet: FleetClient;\n readonly audience: AudienceClient;\n readonly data: DataClient;\n readonly errors: ErrorsClient;\n readonly billing: BillingClient;\n readonly routes: RoutesClient;\n readonly creativeExperiments: CreativeExperimentsClient;\n readonly mediaBuys: MediaBuysClient;\n\n /** The underlying HTTP client (exposed for advanced use cases). */\n readonly _http: HttpClient;\n\n constructor(options: ClientOptions) {\n if (!options.apiKey) {\n throw new Error(\n 'TrillboardsClient requires an apiKey. Get one at https://trillboards.com/developers'\n );\n }\n\n const baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '');\n\n this._http = new HttpClient({\n apiKey: options.apiKey,\n baseUrl,\n version: options.version,\n });\n\n this.screens = new ScreensClient(this._http);\n this.devices = new DevicesClient(this._http);\n this.impressions = new ImpressionsClient(this._http);\n this.analytics = new AnalyticsClient(this._http);\n this.webhooks = new WebhooksClient(this._http);\n this.earnings = new EarningsClient(this._http);\n this.fleet = new FleetClient(this._http);\n this.audience = new AudienceClient(this._http);\n this.data = new DataClient(this._http);\n this.errors = new ErrorsClient(this._http);\n this.billing = new BillingClient(this._http);\n this.routes = new RoutesClient(this._http);\n this.creativeExperiments = new CreativeExperimentsClient(this._http);\n this.mediaBuys = new MediaBuysClient({apiKey:options.apiKey,baseUrl,version:options.version});\n }\n}\n","/**\n * Webhook signature verification for Trillboards webhooks.\n *\n * Header format produced by the server (matches Stripe-style compound shape):\n *\n * X-Trillboards-Signature: t=<unix_seconds>,v0=<hex>,v1=<hex>\n * X-Trillboards-Timestamp: <unix_seconds> // redundant; same value as t=\n * X-Trillboards-Event: <event_name>\n * X-Trillboards-Webhook-Id: <subscription_id>\n *\n * Where v1 = HMAC-SHA256(secret, `${timestamp}.${payload}`)\n * v0 = HMAC-SHA256(secret, payload) ← legacy body-only, emitted for back-compat\n *\n * `constructEvent` prefers v1 (replay-protected); falls back to v0 when v1 is\n * absent (server in pre-migration state) or when only the legacy\n * `sha256=<hex>` form is present.\n *\n * Replay protection: a configurable tolerance window (default 300s, Stripe-\n * aligned) rejects payloads whose timestamp is too far from the verifier's\n * clock. Adjust via the `tolerance` option.\n *\n * Migration note (since 0.3.0):\n * The 0.2.0-shape `constructEvent(payload, signatureString, secret)` is kept\n * as `constructEventLegacy` for one minor version. It does NOT verify the\n * timestamp (the 0.2.0 verifier had no access to one). Migrate to the new\n * call shape `constructEvent(payload, req.headers, secret)` to gain replay\n * protection and compound-header support.\n */\n\nimport { createHmac, timingSafeEqual } from 'crypto';\nimport { TrillboardsError } from './error';\nimport type { WebhookEvent } from './generated';\n\nconst DEFAULT_TOLERANCE_SECONDS = 300;\n\nexport interface ConstructEventOptions {\n /** Maximum allowed age (seconds) of a signed payload. Default 300 (Stripe-aligned). */\n tolerance?: number;\n /** Override the verifier's current time (seconds). Tests only. */\n nowSec?: number;\n}\n\n/**\n * Headers carried by a Trillboards webhook delivery. Accepts either the\n * canonical Node `IncomingHttpHeaders` shape (lowercase keys) or any\n * Record<string, string|string[]> with case-insensitive lookup.\n */\nexport type WebhookHeaders =\n | Record<string, string | string[] | undefined>\n | { [key: string]: string | string[] | undefined };\n\n/**\n * Parsed signature-header components.\n */\nexport interface ParsedSignatureHeader {\n /** Unix seconds from `t=` if present. */\n timestamp?: number;\n /** Algorithm → hex-digest map. Standard keys: `v0`, `v1`. */\n versions: Map<string, string>;\n /** Set when the raw input matched the legacy `sha256=<hex>` shape. */\n legacy?: string;\n}\n\n/**\n * Parse a Trillboards `X-Trillboards-Signature` header into its component\n * algorithm-keyed digests.\n *\n * Accepts:\n * \"t=<ts>,v1=<hex>\" → canonical\n * \"t=<ts>,v0=<hex>,v1=<hex>\" → canonical with legacy companion\n * \"sha256=<hex>\" → pre-migration emitter (single value)\n *\n * @public\n */\nexport function parseSignatureHeader(rawSig: string): ParsedSignatureHeader {\n const versions = new Map<string, string>();\n let timestamp: number | undefined;\n let legacy: string | undefined;\n\n const trimmed = rawSig.trim();\n if (trimmed.startsWith('sha256=')) {\n legacy = trimmed.slice('sha256='.length);\n return { timestamp, versions, legacy };\n }\n\n for (const part of trimmed.split(',')) {\n const eq = part.indexOf('=');\n if (eq < 0) continue;\n const key = part.slice(0, eq).trim();\n const value = part.slice(eq + 1).trim();\n if (!key || !value) continue;\n if (key === 't') {\n const ts = Number(value);\n if (Number.isFinite(ts)) timestamp = ts;\n } else if (/^v\\d+$/.test(key)) {\n versions.set(key, value);\n }\n }\n return { timestamp, versions, legacy };\n}\n\nfunction getHeader(headers: WebhookHeaders, name: string): string | undefined {\n // Case-insensitive lookup over a heterogeneous shape.\n const lc = name.toLowerCase();\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === lc) {\n const v = (headers as Record<string, string | string[] | undefined>)[key];\n if (Array.isArray(v)) return v[0];\n return v;\n }\n }\n return undefined;\n}\n\nfunction constantTimeEqual(a: string, b: string): boolean {\n const aBuf = Buffer.from(a, 'utf8');\n const bBuf = Buffer.from(b, 'utf8');\n if (aBuf.length !== bBuf.length) return false;\n return timingSafeEqual(aBuf, bBuf);\n}\n\nfunction authError(message: string): TrillboardsError {\n return new TrillboardsError({\n type: 'authentication_error',\n code: 'webhook_signature_invalid',\n message,\n statusCode: 401,\n });\n}\n\n/**\n * Verify a webhook payload signature and parse the event.\n *\n * @param payload — raw request body (string or Buffer). Must be EXACTLY the\n * bytes the server signed — do NOT re-stringify after JSON.parse.\n * @param headers — IncomingHttpHeaders or any Record<string, string|string[]>\n * produced by your HTTP framework. Case-insensitive lookup.\n * For Express, pass `req.headers`. For Next.js, `req.headers`.\n * Backwards-compat: a raw signature string (the 0.2.0 shape)\n * is also accepted and parsed as if it were the value of\n * `X-Trillboards-Signature`; in that case the verifier looks\n * for the timestamp in the compound header itself, OR throws.\n * @param secret — webhook subscription secret (whsec_...).\n * @param opts.tolerance — replay-window in seconds. Default 300.\n * @returns parsed WebhookEvent if signature valid AND timestamp within tolerance.\n * @throws TrillboardsError(authentication_error / webhook_signature_invalid)\n *\n * @example\n * import { Webhooks } from '@trillboards/api-client';\n *\n * app.post('/webhooks', express.raw({ type: 'application/json' }), (req, res) => {\n * try {\n * const event = Webhooks.constructEvent(\n * req.body, // raw Buffer or string\n * req.headers, // IncomingHttpHeaders\n * process.env.WEBHOOK_SECRET!, // your subscription secret\n * );\n * console.log('Received', event.event);\n * res.sendStatus(200);\n * } catch (err) {\n * // TrillboardsError with code \"webhook_signature_invalid\"\n * res.sendStatus(401);\n * }\n * });\n */\nexport function constructEvent(\n payload: string | Buffer,\n headers: WebhookHeaders | string,\n secret: string,\n opts: ConstructEventOptions = {},\n): WebhookEvent {\n let signatureHeader: string | undefined;\n let timestampHeader: string | undefined;\n\n if (typeof headers === 'string') {\n // Back-compat: caller passed the raw X-Trillboards-Signature value (0.2.0 shape).\n // We can still verify if `t=` is in the compound header, but cannot look for a\n // separate X-Trillboards-Timestamp header.\n signatureHeader = headers;\n } else if (headers && typeof headers === 'object') {\n signatureHeader = getHeader(headers, 'X-Trillboards-Signature');\n timestampHeader = getHeader(headers, 'X-Trillboards-Timestamp');\n }\n\n if (!signatureHeader) {\n throw authError('Missing X-Trillboards-Signature header.');\n }\n\n const payloadStr = typeof payload === 'string' ? payload : payload.toString('utf8');\n const parsed = parseSignatureHeader(signatureHeader);\n\n // Resolve timestamp from (1) compound `t=`, (2) separate `X-Trillboards-Timestamp` header.\n let ts = parsed.timestamp;\n if (ts === undefined && timestampHeader) {\n const fromHeader = Number(timestampHeader);\n if (Number.isFinite(fromHeader)) ts = fromHeader;\n }\n\n if (ts === undefined || !Number.isFinite(ts)) {\n throw authError(\n 'Webhook signature missing timestamp. Provide either `t=<unix_seconds>` ' +\n 'inside X-Trillboards-Signature OR a separate X-Trillboards-Timestamp header.',\n );\n }\n\n const tolerance = opts.tolerance ?? DEFAULT_TOLERANCE_SECONDS;\n const now = opts.nowSec ?? Math.floor(Date.now() / 1000);\n if (Math.abs(now - ts) > tolerance) {\n throw authError(\n `Webhook timestamp ${ts} outside tolerance window of ${tolerance}s (now ${now}). ` +\n 'Possible replay attack.',\n );\n }\n\n // Compute the two expected digests. We compute both even if only one is\n // requested because the work is cheap and constant-time semantics matter.\n const v1Expected = createHmac('sha256', secret)\n .update(`${ts}.${payloadStr}`)\n .digest('hex');\n const v0Expected = createHmac('sha256', secret).update(payloadStr).digest('hex');\n\n const v1Provided = parsed.versions.get('v1');\n const v0Provided = parsed.versions.get('v0');\n\n // SECURITY: v1 takes priority. v0 is ONLY accepted when v1 is ABSENT (i.e.\n // the server is still on the pre-migration emitter or the partner-built\n // body-only verifier). Falling back to v0 after a v1 MISMATCH would defeat\n // replay protection: an attacker who captured one delivery could replay\n // the body with a fresh timestamp; recomputed v1 would fail but v0 (which\n // signs body only) would still match. See partner-api.yaml + integrations/\n // webhook-signature-verification.md migration table.\n if (v1Provided) {\n if (constantTimeEqual(v1Provided, v1Expected)) {\n return JSON.parse(payloadStr) as WebhookEvent;\n }\n // v1 was present but did not verify — reject. Do NOT consult v0.\n throw authError(\n 'Webhook v1 signature verification failed. The payload may have been tampered with, ' +\n 'or your webhook secret may be incorrect.',\n );\n }\n\n // v1 absent — fall back to v0 (legacy body-only emitter).\n if (v0Provided && constantTimeEqual(v0Provided, v0Expected)) {\n return JSON.parse(payloadStr) as WebhookEvent;\n }\n\n // Fallback to bare-hex `sha256=<hex>` form (pre-migration emitter that\n // never wrote v1/v0 labels). Same security note: if v1 is the intended\n // canonical, the bare digest IS v1; try v1Expected first, then v0Expected.\n if (parsed.legacy) {\n if (constantTimeEqual(parsed.legacy, v1Expected)) {\n return JSON.parse(payloadStr) as WebhookEvent;\n }\n if (constantTimeEqual(parsed.legacy, v0Expected)) {\n return JSON.parse(payloadStr) as WebhookEvent;\n }\n }\n\n throw authError(\n 'Webhook signature verification failed. The payload may have been tampered with, ' +\n 'or your webhook secret may be incorrect.',\n );\n}\n\nlet legacyWarned = false;\n\n/**\n * @deprecated since 0.3.0 — kept for one minor version for partners stuck on\n * the 0.2.0 call shape. Use `constructEvent(payload, req.headers, secret)`\n * instead — it gains replay protection and compound-header support.\n *\n * Reproduces the 0.2.0 verifier exactly:\n * HMAC-SHA256(secret, payload) compared (constant-time) against the\n * supplied raw-hex signature string.\n *\n * Does NOT verify any timestamp. The 0.2.0 SDK never had access to one and\n * silently accepted any age of payload — that is a vulnerability this\n * legacy shim preserves only for migration compatibility.\n */\nexport function constructEventLegacy(\n payload: string | Buffer,\n signature: string,\n secret: string,\n): WebhookEvent {\n if (!legacyWarned) {\n // eslint-disable-next-line no-console\n console.warn(\n '[@trillboards/api-client] constructEventLegacy is deprecated and unsafe (no replay ' +\n 'protection). Migrate to Webhooks.constructEvent(payload, req.headers, secret). ' +\n 'See https://api.trillboards.com/docs/integrations/webhook-signature-verification.md',\n );\n legacyWarned = true;\n }\n const payloadStr = typeof payload === 'string' ? payload : payload.toString('utf8');\n const expected = createHmac('sha256', secret).update(payloadStr).digest('hex');\n if (!constantTimeEqual(signature, expected)) {\n throw authError(\n 'Legacy webhook signature mismatch. If your server has been upgraded to the ' +\n 'compound-header emitter, switch to Webhooks.constructEvent instead.',\n );\n }\n return JSON.parse(payloadStr) as WebhookEvent;\n}\n\n// ---------------------------------------------------------------------------\n// AdCP RFC 9421 webhook verification\n// ---------------------------------------------------------------------------\n//\n// Trillboards is an AdCP seller agent. Webhooks it pushes to an AdCP buyer are\n// signed with RFC 9421 HTTP Message Signatures — asymmetric Ed25519, no shared\n// secret — so the buyer verifies against the public keys Trillboards publishes\n// at https://api.trillboards.com/.well-known/jwks.json (discoverable through\n// /.well-known/brand.json). Nothing secret crosses the wire.\n//\n// This is the counterpart to `services/webhooks/canonicalSigner.js`'s\n// `signAdcpWebhook`. Fetching and caching the JWKS is the caller's job (it is\n// an HTTPS GET with a Cache-Control the server sets) so this stays a pure,\n// dependency-free function of (request, keys).\n\n/** RFC 9421 `tag` Trillboards stamps on outbound AdCP webhooks. */\nexport const ADCP_WEBHOOK_SIGNING_TAG = 'adcp/webhook-signing/v1';\n/** Components the AdCP webhook profile always covers. */\nconst ADCP_WEBHOOK_COMPONENTS = [\n '@method',\n '@target-uri',\n '@authority',\n 'content-type',\n 'content-digest',\n];\n/** AdCP caps the signature window; a wider one is a replay risk, not a courtesy. */\nconst ADCP_MAX_WINDOW_SECONDS = 300;\n\n/** An Ed25519 public key from the Trillboards JWKS. */\nexport interface AdcpJwk {\n kty: string;\n crv: string;\n x: string;\n kid: string;\n alg?: string;\n use?: string;\n key_ops?: string[];\n adcp_use?: string;\n}\n\nexport interface VerifyAdcpWebhookOptions {\n /** Absolute URL the webhook was delivered to. Must be the URL you published. */\n url: string;\n /** HTTP method of the delivery. Defaults to POST. */\n method?: string;\n /** Delivery headers (case-insensitive). */\n headers: WebhookHeaders;\n /** Raw request body — EXACTLY the bytes received, never a re-stringify. */\n payload: string | Buffer;\n /** Keys from https://api.trillboards.com/.well-known/jwks.json */\n keys: AdcpJwk[];\n /** Override the verifier's clock (seconds). Tests only. */\n nowSec?: number;\n}\n\n/** Split an RFC 8941 dictionary into its top-level members. */\nfunction splitDictionary(headerValue: string): string[] {\n const members: string[] = [];\n let depth = 0;\n let quoted = false;\n let start = 0;\n for (let i = 0; i < headerValue.length; i++) {\n const ch = headerValue[i];\n if (quoted) {\n if (ch === '\\\\') i++;\n else if (ch === '\"') quoted = false;\n continue;\n }\n if (ch === '\"') quoted = true;\n else if (ch === '(') depth++;\n else if (ch === ')') depth--;\n else if (ch === ',' && depth === 0) {\n members.push(headerValue.slice(start, i).trim());\n start = i + 1;\n }\n }\n members.push(headerValue.slice(start).trim());\n return members.filter((member) => member.length > 0);\n}\n\nfunction dictionaryMember(headerValue: string, label: string): string | undefined {\n return splitDictionary(headerValue).find((member) => member.startsWith(`${label}=`));\n}\n\n/**\n * The AdCP label this verifier processes. RFC 8941 dictionaries are unordered,\n * and a relay may prepend its own signature member — so the label is looked up\n * by NAME, never taken from whichever member happens to be first.\n */\nconst ADCP_SIGNATURE_LABEL = 'sig1';\n\n/**\n * Pick the AdCP signature member out of a possibly multi-member header.\n * Prefers the spec's `sig1`; falls back to whichever member carries the AdCP\n * webhook tag, so a relay that renames labels still verifies. Every candidate\n * still has to pass the full checklist afterwards, so a wrong pick fails\n * closed rather than weakening anything.\n */\nfunction selectAdcpSignatureInput(signatureInput: string): { label: string; member: string } {\n const members = splitDictionary(signatureInput);\n\n const named = members.find((member) => member.startsWith(`${ADCP_SIGNATURE_LABEL}=`));\n if (named) return { label: ADCP_SIGNATURE_LABEL, member: named };\n\n const tagged = members.find((member) => member.includes(`tag=\"${ADCP_WEBHOOK_SIGNING_TAG}\"`));\n if (tagged) return { label: tagged.slice(0, tagged.indexOf('=')), member: tagged };\n\n throw authError(\n `AdCP webhook has no \"${ADCP_SIGNATURE_LABEL}\" signature member and no member tagged ` +\n `\"${ADCP_WEBHOOK_SIGNING_TAG}\".`,\n );\n}\n\n/**\n * Canonicalise a URL for `@target-uri` per the AdCP profile. `URL` lowercases\n * the scheme and host, applies UTS-46 ToASCII, strips the default port,\n * collapses dot segments, and drops the fragment; the remaining rules are\n * percent-encoding normalisation and preserving a trailing empty query.\n */\nfunction canonicalTargetUri(rawUrl: string): string {\n const parsed = new URL(rawUrl);\n const beforeFragment = rawUrl.split('#', 1)[0];\n const search = parsed.search || (beforeFragment.endsWith('?') ? '?' : '');\n return `${parsed.protocol}//${parsed.host}${parsed.pathname}${search}`.replace(\n /%([0-9a-fA-F]{2})/g,\n (match, hex: string) => {\n const code = parseInt(hex, 16);\n const unreserved =\n (code >= 0x41 && code <= 0x5a) ||\n (code >= 0x61 && code <= 0x7a) ||\n (code >= 0x30 && code <= 0x39) ||\n code === 0x2d || code === 0x2e || code === 0x5f || code === 0x7e;\n return unreserved ? String.fromCharCode(code) : `%${hex.toUpperCase()}`;\n },\n );\n}\n\n/**\n * Verify an AdCP RFC 9421 webhook signature and parse the event.\n *\n * Checks, in order: header pair present → covered components complete → tag is\n * the webhook tag → signature window sane and unexpired → key resolvable and\n * purpose-valid → body digest matches → signature verifies.\n *\n * Replay defence beyond the window (per-`nonce` dedup) is the caller's — the\n * nonce is exposed on the return value for exactly that.\n *\n * @throws TrillboardsError(authentication_error / webhook_signature_invalid)\n *\n * @example\n * import { Webhooks } from '@trillboards/api-client';\n *\n * const { keys } = await (await fetch(\n * 'https://api.trillboards.com/.well-known/jwks.json',\n * )).json();\n *\n * app.post('/adcp/webhook', express.raw({ type: 'application/json' }), (req, res) => {\n * const { event } = Webhooks.verifyAdcpWebhook({\n * url: `https://buyer.example.com${req.originalUrl}`,\n * headers: req.headers,\n * payload: req.body,\n * keys,\n * });\n * res.sendStatus(200);\n * });\n */\nexport function verifyAdcpWebhook(opts: VerifyAdcpWebhookOptions): {\n event: WebhookEvent;\n keyid: string;\n nonce: string;\n expires: number;\n} {\n const { createHash, createPublicKey, verify: cryptoVerify } = require('crypto');\n\n const signatureInput = getHeader(opts.headers, 'Signature-Input');\n const signature = getHeader(opts.headers, 'Signature');\n if (!signatureInput || !signature) {\n // Both or neither: accepting one without the other is the classic\n // signature-stripping downgrade.\n throw authError('AdCP webhook is missing the Signature / Signature-Input header pair.');\n }\n\n const { label, member: inputMember } = selectAdcpSignatureInput(signatureInput);\n const signatureMember = dictionaryMember(signature, label);\n if (!signatureMember) {\n throw authError(`AdCP webhook Signature has no \"${label}\" member to match Signature-Input.`);\n }\n\n const paramsStart = inputMember.indexOf('(');\n const paramsEnd = inputMember.indexOf(')');\n if (paramsStart < 0 || paramsEnd < 0) {\n throw authError('AdCP webhook Signature-Input is malformed.');\n }\n const components = inputMember\n .slice(paramsStart + 1, paramsEnd)\n .split(' ')\n .map((component) => component.replace(/^\"|\"$/g, ''))\n .filter((component) => component.length > 0);\n\n const readParam = (name: string): string | undefined => {\n const match = new RegExp(`;${name}=(\"?)([^\";]+)\\\\1`).exec(inputMember);\n return match ? match[2] : undefined;\n };\n const created = Number(readParam('created'));\n const expires = Number(readParam('expires'));\n const nonce = readParam('nonce');\n const keyid = readParam('keyid');\n const alg = readParam('alg');\n const tag = readParam('tag');\n\n if (!nonce || !keyid || !alg || !Number.isFinite(created) || !Number.isFinite(expires)) {\n throw authError('AdCP webhook signature is missing a required parameter.');\n }\n if (tag !== ADCP_WEBHOOK_SIGNING_TAG) {\n // A request signature replayed at a webhook endpoint fails here.\n throw authError(`AdCP webhook signature has tag \"${tag}\", expected \"${ADCP_WEBHOOK_SIGNING_TAG}\".`);\n }\n if (alg !== 'ed25519') {\n throw authError(`AdCP webhook signature algorithm \"${alg}\" is not allowed.`);\n }\n for (const required of ADCP_WEBHOOK_COMPONENTS) {\n if (!components.includes(required)) {\n throw authError(`AdCP webhook signature does not cover \"${required}\".`);\n }\n }\n if (expires <= created || expires - created > ADCP_MAX_WINDOW_SECONDS) {\n throw authError('AdCP webhook signature window is invalid.');\n }\n const now = opts.nowSec ?? Math.floor(Date.now() / 1000);\n if (now > expires) {\n throw authError('AdCP webhook signature has expired. Possible replay attack.');\n }\n\n const jwk = opts.keys.find((key) => key.kid === keyid);\n if (!jwk) {\n throw authError(`AdCP webhook signed with unknown key \"${keyid}\". Refresh the JWKS.`);\n }\n if (jwk.key_ops && !jwk.key_ops.includes('verify')) {\n throw authError(`AdCP webhook key \"${keyid}\" is not a verification key.`);\n }\n if (jwk.adcp_use && jwk.adcp_use !== 'request-signing' && jwk.adcp_use !== 'webhook-signing') {\n throw authError(`AdCP webhook key \"${keyid}\" has adcp_use \"${jwk.adcp_use}\".`);\n }\n\n const payloadBuf = typeof opts.payload === 'string' ? Buffer.from(opts.payload, 'utf8') : opts.payload;\n const contentDigest = getHeader(opts.headers, 'Content-Digest');\n const expectedDigest = `sha-256=:${createHash('sha256').update(payloadBuf).digest('base64')}:`;\n if (!contentDigest || contentDigest !== expectedDigest) {\n throw authError('AdCP webhook Content-Digest does not match the body.');\n }\n\n const method = (opts.method ?? 'POST').toUpperCase();\n const target = new URL(opts.url);\n const baseLines = components.map((component) => {\n switch (component) {\n case '@method':\n return `\"@method\": ${method}`;\n case '@target-uri':\n return `\"@target-uri\": ${canonicalTargetUri(opts.url)}`;\n case '@authority':\n return `\"@authority\": ${target.host.toLowerCase()}`;\n default: {\n const value = getHeader(opts.headers, component);\n if (value === undefined) {\n throw authError(`AdCP webhook covers \"${component}\" but the header is absent.`);\n }\n return `\"${component}\": ${value.trim()}`;\n }\n }\n });\n // The `@signature-params` line is the Signature-Input member VERBATIM minus\n // its label — reserialising it would risk a byte that differs from what the\n // signer hashed.\n baseLines.push(`\"@signature-params\": ${inputMember.slice(label.length + 1)}`);\n\n const signatureBytes = Buffer.from(\n signatureMember.slice(label.length + 1).replace(/^:|:$/g, ''),\n 'base64url',\n );\n const publicKey = createPublicKey({ key: jwk, format: 'jwk' });\n if (!cryptoVerify(null, Buffer.from(baseLines.join('\\n'), 'utf8'), publicKey, signatureBytes)) {\n throw authError(\n 'AdCP webhook signature verification failed. The delivery may have been tampered with.',\n );\n }\n\n return {\n event: JSON.parse(payloadBuf.toString('utf8')) as WebhookEvent,\n keyid,\n nonce,\n expires,\n };\n}\n\n/** Namespaced export — matches the Stripe-style API. */\nexport const Webhooks = {\n constructEvent,\n constructEventLegacy,\n parseSignatureHeader,\n verifyAdcpWebhook,\n};\n"]}
1
+ {"version":3,"sources":["../src/error.ts","../src/version.ts","../src/http.ts","../src/resources/screens.ts","../src/resources/devices.ts","../src/resources/impressions.ts","../src/resources/analytics.ts","../src/resources/earnings.ts","../src/resources/errors.ts","../src/resources/webhooks.ts","../src/resources/fleet.ts","../src/resources/audience.ts","../src/stream.ts","../src/resources/data.ts","../src/resources/billing.ts","../src/resources/routes.ts","../src/resources/creativeExperiments.ts","../src/resources/mediaBuys.ts","../src/client.ts","../src/webhooks.ts"],"names":["path","BASE"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * TrillboardsError — client-side error class that mirrors the server-side\n * canonical error envelope from utils/apiErrors.ts.\n *\n * Error shape from the API:\n * { error: { type, code, message, param, doc_url, request_id, details?, help? } }\n */\n\nimport type { ApiErrorType, ErrorDetail, ErrorResponseBody } from './types';\n\nexport interface TrillboardsErrorOptions {\n type: ApiErrorType;\n code: string;\n message: string;\n statusCode: number;\n param?: string | null;\n requestId?: string;\n docsUrl?: string;\n details?: ErrorDetail[];\n help?: Record<string, unknown>;\n retryAfterSeconds?: number | null;\n}\n\nexport class TrillboardsError extends Error {\n readonly type: ApiErrorType;\n readonly code: string;\n readonly param: string | null;\n readonly requestId: string;\n readonly docsUrl: string;\n readonly statusCode: number;\n readonly details: ErrorDetail[];\n readonly help: Record<string, unknown> | null;\n private readonly _retryAfterSeconds: number | null;\n\n constructor(opts: TrillboardsErrorOptions) {\n super(opts.message);\n this.name = 'TrillboardsError';\n this.type = opts.type;\n this.code = opts.code;\n this.statusCode = opts.statusCode;\n this.param = opts.param ?? null;\n this.requestId = opts.requestId ?? '';\n this.docsUrl = opts.docsUrl ?? `https://api.trillboards.com/docs/errors#${opts.code}`;\n this.details = opts.details ?? [];\n this.help = opts.help ?? null;\n this._retryAfterSeconds = opts.retryAfterSeconds ?? null;\n }\n\n /**\n * Construct a TrillboardsError from an API error response body and fetch Response.\n *\n * The API wraps errors in { error: { ... } }. We unwrap and map to class fields.\n */\n static fromResponse(body: ErrorResponseBody | Record<string, unknown>, response: { status: number; headers: { get(name: string): string | null } }): TrillboardsError {\n const errorObj = (body as ErrorResponseBody)?.error ?? body;\n const errData = errorObj as Record<string, unknown>;\n\n const retryAfterHeader = response.headers.get('retry-after');\n let retryAfterSeconds: number | null = null;\n if (retryAfterHeader) {\n const parsed = parseInt(retryAfterHeader, 10);\n if (!isNaN(parsed)) {\n retryAfterSeconds = parsed;\n }\n }\n\n return new TrillboardsError({\n type: (errData.type as ApiErrorType) ?? 'api_error',\n code: (errData.code as string) ?? 'unknown_error',\n message: (errData.message as string) ?? 'An unknown error occurred.',\n statusCode: response.status,\n param: (errData.param as string | null) ?? null,\n requestId: (errData.request_id as string) ?? '',\n docsUrl: (errData.doc_url as string) ?? undefined,\n details: (errData.details as ErrorDetail[]) ?? [],\n help: (errData.help as Record<string, unknown>) ?? null,\n retryAfterSeconds,\n });\n }\n\n /** True if this is a 429 rate limit response. */\n get isRateLimited(): boolean {\n return this.statusCode === 429;\n }\n\n /**\n * Number of seconds to wait before retrying, from the Retry-After header.\n * Returns null if no Retry-After header was present.\n */\n get retryAfter(): number | null {\n return this._retryAfterSeconds;\n }\n\n /** True if this is an authentication error (401). */\n get isAuthError(): boolean {\n return this.statusCode === 401;\n }\n\n /** True if this is a permission/forbidden error (403). */\n get isForbidden(): boolean {\n return this.statusCode === 403;\n }\n\n /** True if this is a server-side error (5xx). */\n get isServerError(): boolean {\n return this.statusCode >= 500;\n }\n}\n","/**\n * SDK version constant. Sent in User-Agent and X-Trillboards-Client headers.\n * Equal to package.json's version: .github/scripts/check-api-client-version-constant.js\n * fails the PR when they differ, and the publish lane's tests (publish-api-client.yml)\n * refuse the release.\n */\nexport const VERSION = '3.2.20';\n","/**\n * Internal HTTP client for the Trillboards API.\n *\n * Uses native fetch (Node 18+) for JSON requests and cancelable live streams.\n * Sends standard headers: Authorization, Content-Type, User-Agent, X-Trillboards-Client.\n */\n\nimport { TrillboardsError } from './error';\nimport type { ErrorResponseBody, RequestOptions } from './types';\nimport { VERSION } from './version';\n\nexport interface HttpClientConfig {\n apiKey: string;\n baseUrl: string;\n version?: string;\n}\n\nexport interface RetryOptions {\n /** Maximum number of retry attempts after the initial call. Defaults to 6. */\n retries?: number;\n /** Base delay in ms for exponential backoff. Defaults to 1000. */\n baseMs?: number;\n /**\n * Optional callback invoked when an attempt fails with a retryable error.\n * `attempt` is 1-indexed (1 = first failure). Useful for observability —\n * the CTV SDK uses this to emit `upload_error` events without coupling\n * the retry loop to event emission.\n */\n onAttemptError?: (attempt: number, error: unknown) => void;\n}\n\n/**\n * Endpoint prefixes that are publicly accessible and do not require (or want)\n * an Authorization header. Sending a malformed key on these paths causes the\n * server to reject the request even though no auth is needed.\n */\nconst PUBLIC_PATHS = ['/v1/errors', '/v1/changelog', '/api/discover', '/v1/health'];\n\n/**\n * Decide whether an error is worth retrying.\n *\n * Retry: 429 (rate limit), 5xx (transient server), TypeError (network / DNS / TLS).\n * Permanent: every other 4xx, and non-Error rejections.\n */\nfunction isRetryable(err: unknown): boolean {\n if (err instanceof TrillboardsError) {\n return err.statusCode === 429 || err.statusCode >= 500;\n }\n // Native fetch surfaces network / DNS / TLS failures as TypeError.\n if (err instanceof TypeError) return true;\n return false;\n}\n\n/**\n * Compute the delay before the next retry attempt.\n *\n * Honors `Retry-After` (in seconds) parsed from 429 responses; otherwise uses\n * exponential backoff (baseMs * 2^attempt) with full jitter to spread thundering-herd\n * retries from a fleet of devices that all 429'd at the same instant.\n */\nfunction computeBackoffMs(attempt: number, baseMs: number, err: unknown): number {\n if (err instanceof TrillboardsError && err.retryAfter != null && err.retryAfter > 0) {\n return err.retryAfter * 1000;\n }\n const exponential = baseMs * Math.pow(2, attempt);\n // Full jitter: random delay in [0, exponential] — RFC-recommended for retries.\n return Math.floor(Math.random() * exponential);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Wrap an async operation in retry-with-exponential-backoff.\n *\n * - Retries up to `retries` times on retryable errors (429, 5xx, TypeError network).\n * - Honors `Retry-After` header on 429 responses (parsed into TrillboardsError.retryAfter).\n * - Throws the last error after the budget is exhausted.\n * - Permanent 4xx (auth, validation, not-found) throw immediately on first attempt.\n *\n * This is the SINGLE retry primitive in the SDK — every POST/PUT/DELETE is\n * wrapped automatically by HttpClient. GET is left to the caller because\n * idempotency assumptions vary by route.\n */\nexport async function retryWithBackoff<T>(\n operation: () => Promise<T>,\n opts: RetryOptions = {},\n): Promise<T> {\n const retries = opts.retries ?? 6;\n const baseMs = opts.baseMs ?? 1000;\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= retries; attempt += 1) {\n try {\n return await operation();\n } catch (err) {\n lastError = err;\n if (!isRetryable(err) || attempt === retries) {\n throw err;\n }\n // 1-indexed for observability; matches \"attempt 1 failed, attempt 2 failed\".\n if (opts.onAttemptError) {\n try {\n opts.onAttemptError(attempt + 1, err);\n } catch {\n // Never let a buggy observer break the retry loop.\n }\n }\n const delayMs = computeBackoffMs(attempt, baseMs, err);\n await sleep(delayMs);\n }\n }\n\n // Unreachable — the loop above always throws or returns. The throw keeps\n // TypeScript's control-flow analysis honest.\n throw lastError;\n}\n\nexport class HttpClient {\n private readonly config: HttpClientConfig;\n\n constructor(config: HttpClientConfig) {\n this.config = config;\n }\n\n async request<T>(method: string, path: string, options?: RequestOptions): Promise<T> {\n const response = await this.requestResponse(method, path, options);\n\n // Handle 204 No Content\n if (response.status === 204) return undefined as T;\n const json = await this.readJson(response);\n if (!response.ok) throw TrillboardsError.fromResponse(json as ErrorResponseBody, response);\n return json as T;\n }\n\n private async requestResponse(method: string, path: string, options?: RequestOptions & { signal?: AbortSignal }): Promise<Response> {\n const url = this.buildUrl(path, options?.params);\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Trillboards-Client': `typescript-sdk/${VERSION}`,\n 'User-Agent': `trillboards-typescript/${VERSION}`,\n ...(options?.headers ?? {}),\n };\n\n // Only send auth on non-public endpoints. Respect a caller-supplied\n // Authorization header (e.g. per-call OAuth token override) — merging\n // options?.headers first and then blindly writing config.apiKey here\n // meant a callsite passing its own Bearer got silently replaced.\n const callerSuppliedAuth = Object.keys(options?.headers ?? {})\n .some((h) => h.toLowerCase() === 'authorization');\n const isPublic = PUBLIC_PATHS.some(prefix => path.startsWith(prefix));\n if (!isPublic && this.config.apiKey && !callerSuppliedAuth) {\n headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n }\n\n if (this.config.version) {\n headers['Trillboards-Version'] = this.config.version;\n }\n\n const fetchOptions: globalThis.RequestInit = {\n method,\n headers,\n };\n\n if (options?.body !== undefined && options.body !== null) {\n fetchOptions.body = JSON.stringify(options.body);\n }\n\n fetchOptions.signal = options?.signal;\n return fetch(url, fetchOptions);\n }\n\n private async readJson(response: Response): Promise<unknown> {\n try { return await response.json(); }\n catch {\n throw new TrillboardsError({type:'api_error',code:'invalid_response',\n message:`Invalid JSON response from API (HTTP ${response.status}).`,statusCode:response.status});\n }\n }\n\n /** Open one authenticated live tail. The native endpoint has no replay cursor. */\n async openStream(path: string, options?: RequestOptions & { signal?: AbortSignal }): Promise<Response> {\n const response = await this.requestResponse('GET', path, {\n ...options, headers: { Accept:'text/event-stream', ...options?.headers },\n });\n if (!response.ok) throw TrillboardsError.fromResponse(await this.readJson(response) as ErrorResponseBody, response);\n if (!/^text\\/event-stream(?:;|$)/i.test(response.headers.get('content-type') || '') || !response.body) {\n await response.body?.cancel();\n throw new TrillboardsError({type:'api_error',code:'invalid_response',\n message:'Expected a text/event-stream response with a body.',statusCode:response.status});\n }\n return response;\n }\n\n get<T>(path: string, opts?: { params?: Record<string, unknown> }): Promise<T> {\n // GET is not auto-wrapped — idempotency assumptions vary by route and\n // the caller knows whether a retry is safe.\n return this.request<T>('GET', path, { params: opts?.params });\n }\n\n /**\n * POST / PUT / PATCH / DELETE auto-retry on 429 + 5xx + network TypeError\n * via `retryWithBackoff()`. Callers can opt into observability by passing\n * `retry.onAttemptError` to receive a callback per transient failure.\n *\n * The retry behavior is identical across all four methods because all of\n * them are state-changing operations subject to the same transient-failure\n * classes (rate limit, upstream-down, network-flap). The wire idempotency\n * of POST vs DELETE is enforced server-side via Idempotency-Key headers,\n * which the caller can attach via `opts.headers`.\n */\n post<T>(path: string, body?: unknown, opts?: { retry?: RetryOptions; headers?: Record<string, string> }): Promise<T> {\n return retryWithBackoff(() => this.request<T>('POST', path, { body, headers: opts?.headers }), opts?.retry);\n }\n\n put<T>(path: string, body?: unknown, opts?: { retry?: RetryOptions; headers?: Record<string, string> }): Promise<T> {\n return retryWithBackoff(() => this.request<T>('PUT', path, { body, headers: opts?.headers }), opts?.retry);\n }\n\n patch<T>(path: string, body?: unknown, opts?: { retry?: RetryOptions; headers?: Record<string, string> }): Promise<T> {\n return retryWithBackoff(() => this.request<T>('PATCH', path, { body, headers: opts?.headers }), opts?.retry);\n }\n\n delete<T>(path: string, opts?: { retry?: RetryOptions; headers?: Record<string, string> }): Promise<T> {\n return retryWithBackoff(() => this.request<T>('DELETE', path, { headers: opts?.headers }), opts?.retry);\n }\n\n private buildUrl(path: string, params?: Record<string, unknown>): string {\n const base = `${this.config.baseUrl}${path}`;\n if (!params || Object.keys(params).length === 0) {\n return base;\n }\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n searchParams.set(key, String(value));\n }\n }\n return `${base}?${searchParams.toString()}`;\n }\n}\n","/**\n * ScreensClient — Partner API screen management.\n *\n * Base path: /v1/partner (screens are mapped from devices + screen pairs)\n */\n\nimport type { HttpClient } from '../http';\nimport type { ListResponse } from '../types';\nimport type {\n DisplaySettingsInput,\n DisplaySettingsResponse,\n PartnerDeviceRegistrationInput,\n Screen,\n} from '../generated';\n\nexport class ScreensClient {\n constructor(private readonly http: HttpClient) {}\n\n /** List all screens owned by this partner. */\n async list(params?: { limit?: number; offset?: number }): Promise<ListResponse<Screen>> {\n return this.http.get<ListResponse<Screen>>('/v1/partner/devices', { params });\n }\n\n /** Get a single screen by ID. */\n async get(screenId: string): Promise<{ success: boolean; data: Screen }> {\n return this.http.get<{ success: boolean; data: Screen }>(`/v1/partner/device/${screenId}`);\n }\n\n /** Register a new device/screen. */\n async create(body: PartnerDeviceRegistrationInput): Promise<{ success: boolean; data: Screen }> {\n return this.http.post<{ success: boolean; data: Screen }>('/v1/partner/device', body);\n }\n\n /** Get the resolved display settings for one screen. */\n async getDisplaySettings(screenId: string): Promise<DisplaySettingsResponse> {\n return this.http.get(`/v1/partner/screens/${screenId}/display-settings`);\n }\n\n /** Partially update display settings; omitted content-fit keys are preserved. */\n async patchDisplaySettings(\n screenId: string,\n settings: DisplaySettingsInput,\n ): Promise<DisplaySettingsResponse> {\n return this.http.patch(`/v1/partner/screens/${screenId}/display-settings`, settings);\n }\n\n /** Update display settings through the PUT endpoint. */\n async updateDisplaySettings(\n screenId: string,\n settings: DisplaySettingsInput,\n ): Promise<DisplaySettingsResponse> {\n return this.http.put(`/v1/partner/screens/${screenId}/display-settings`, settings);\n }\n\n /** Apply a partial display-settings update to up to 100 screens. */\n async batchUpdateDisplaySettings(\n screenIds: string[],\n settings: DisplaySettingsInput,\n ): Promise<Record<string, unknown>> {\n return this.http.post('/v1/partner/screens/batch/display-settings', {\n screen_ids: screenIds,\n settings,\n });\n }\n\n /** Delete a screen/device. */\n async delete(screenId: string): Promise<{ success: boolean }> {\n return this.http.delete<{ success: boolean }>(`/v1/partner/device/${screenId}`);\n }\n}\n","/**\n * DevicesClient — device registration and heartbeat.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient, RetryOptions } from '../http';\nimport type { ListResponse } from '../types';\nimport type {\n Device,\n PartnerDeviceBatchRegistrationInput,\n PartnerDeviceRegistrationInput,\n} from '../generated';\n\nexport class DevicesClient {\n constructor(private readonly http: HttpClient) {}\n\n /** List all devices for this partner. */\n async list(params?: { limit?: number; offset?: number }): Promise<ListResponse<Device>> {\n return this.http.get<ListResponse<Device>>('/v1/partner/devices', { params });\n }\n\n /** Get a single device by ID. */\n async get(deviceId: string): Promise<{ success: boolean; data: Device }> {\n return this.http.get<{ success: boolean; data: Device }>(`/v1/partner/device/${deviceId}`);\n }\n\n /** Register a new device. */\n async create(body: PartnerDeviceRegistrationInput): Promise<{ success: boolean; data: Device }> {\n return this.http.post<{ success: boolean; data: Device }>('/v1/partner/device', body);\n }\n\n /** Register or re-register up to 100 devices with optional fleet defaults. */\n async createBatch(body: PartnerDeviceBatchRegistrationInput): Promise<{\n success: boolean;\n summary: Record<string, number>;\n devices: Array<Record<string, unknown>>;\n errors: Array<Record<string, unknown>>;\n }> {\n return this.http.post('/v1/partner/devices/batch', body);\n }\n\n /** Delete a device. */\n async delete(deviceId: string): Promise<{ success: boolean }> {\n return this.http.delete<{ success: boolean }>(`/v1/partner/device/${deviceId}`);\n }\n\n /**\n * Send heartbeat for a device.\n *\n * Auto-retries on 429 + 5xx + network TypeError via the shared\n * retryWithBackoff() helper (see http.ts). Pass `opts.retry.onAttemptError`\n * to observe transient failures (e.g. emit an `upload_error` event from\n * the CTV SDK without coupling the retry loop to its event emitter).\n */\n async heartbeat(\n deviceId: string,\n body?: Record<string, unknown>,\n opts?: { retry?: RetryOptions },\n ): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(\n `/v1/partner/device/${deviceId}/heartbeat`,\n body ?? {},\n { retry: opts?.retry },\n );\n }\n}\n","/**\n * ImpressionsClient — impression tracking.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { Impression } from '../generated';\n\nexport class ImpressionsClient {\n constructor(private readonly http: HttpClient) {}\n\n /** Record a single impression. */\n async create(body: {\n screen_id: string;\n device_id: string;\n ad_type?: string;\n duration_seconds?: number;\n metadata?: Record<string, unknown>;\n }): Promise<{ success: boolean; data: Impression }> {\n return this.http.post<{ success: boolean; data: Impression }>('/v1/partner/impression', body);\n }\n\n /** Record a batch of impressions (offline sync). */\n async createBatch(body: {\n impressions: Array<{\n screen_id: string;\n device_id: string;\n ad_type?: string;\n duration_seconds?: number;\n played_at?: string;\n metadata?: Record<string, unknown>;\n }>;\n }): Promise<{ success: boolean; count: number }> {\n return this.http.post<{ success: boolean; count: number }>('/v1/partner/impressions/batch', body);\n }\n}\n","/**\n * AnalyticsClient — partner analytics and reporting.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { AnalyticsData } from '../generated';\n\nexport class AnalyticsClient {\n constructor(private readonly http: HttpClient) {}\n\n /** Get partner analytics summary. */\n async get(params?: {\n period?: 'day' | 'week' | 'month';\n start_date?: string;\n end_date?: string;\n screen_id?: string;\n }): Promise<{ success: boolean; data: AnalyticsData }> {\n return this.http.get<{ success: boolean; data: AnalyticsData }>('/v1/partner/analytics', { params });\n }\n}\n","/**\n * EarningsClient — earnings, payouts, and transaction history.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { EarningsData } from '../generated';\n\nexport class EarningsClient {\n constructor(private readonly http: HttpClient) {}\n\n /** Get earnings summary for the authenticated partner. */\n async get(params?: {\n period?: 'day' | 'week' | 'month';\n start_date?: string;\n end_date?: string;\n }): Promise<{ success: boolean; data: EarningsData }> {\n return this.http.get<{ success: boolean; data: EarningsData }>('/v1/partner/connect/earnings', { params });\n }\n}\n","/**\n * ErrorsClient — access the public error catalog and query partner errors.\n *\n * list() hits /v1/errors (public, no auth required).\n * get() hits /v1/partner/usage (authenticated, partner-scoped).\n */\n\nimport type { HttpClient } from '../http';\nimport type { ListResponse } from '../types';\nimport type { ErrorEntry } from '../generated';\n\nexport class ErrorsClient {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all known API error codes from the public error catalog.\n * This endpoint does NOT require authentication.\n */\n async list(params?: {\n limit?: number;\n offset?: number;\n code?: string;\n type?: string;\n }): Promise<ListResponse<ErrorEntry>> {\n return this.http.get<ListResponse<ErrorEntry>>('/v1/errors', { params });\n }\n\n /** Get a single error by request_id (requires authentication). */\n async get(requestId: string): Promise<{ success: boolean; data: ErrorEntry }> {\n return this.http.get<{ success: boolean; data: ErrorEntry }>(`/v1/partner/usage`, {\n params: { request_id: requestId },\n });\n }\n}\n","/**\n * WebhooksClient — webhook subscription management.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { ListResponse } from '../types';\nimport type { Webhook } from '../generated';\n\nexport class WebhooksClient {\n constructor(private readonly http: HttpClient) {}\n\n /** List all webhook subscriptions. */\n async list(): Promise<ListResponse<Webhook>> {\n return this.http.get<ListResponse<Webhook>>('/v1/partner/webhooks');\n }\n\n /**\n * Create a new webhook subscription.\n *\n * The created `Webhook` carries its signing `secret` (`whsec_…`) — this is the\n * ONLY time it is returned. Persist it securely and pass it to\n * `Webhooks.constructEvent()` to verify the compound `X-Trillboards-Signature`\n * header over the raw delivery body.\n */\n async create(body: {\n url: string;\n events: string[];\n }): Promise<{ success: boolean; data: Webhook }> {\n return this.http.post<{ success: boolean; data: Webhook }>('/v1/partner/webhooks', body);\n }\n\n /** Update a webhook subscription. */\n async update(webhookId: string, body: {\n url?: string;\n events?: string[];\n status?: string;\n }): Promise<{ success: boolean; data: Webhook }> {\n return this.http.patch<{ success: boolean; data: Webhook }>(`/v1/partner/webhooks/${webhookId}`, body);\n }\n\n /** Delete a webhook subscription. */\n async delete(webhookId: string): Promise<{ success: boolean }> {\n return this.http.delete<{ success: boolean }>(`/v1/partner/webhooks/${webhookId}`);\n }\n\n /** Send a test event to a webhook. */\n async test(webhookId: string): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(`/v1/partner/webhooks/${webhookId}/test`);\n }\n}\n","/**\n * FleetClient — fleet-wide device management.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { ListResponse } from '../types';\nimport type { FleetCommand } from '../generated';\n\nexport class FleetClient {\n constructor(private readonly http: HttpClient) {}\n\n /** Push a command to a set of screens. */\n async pushCommand(body: {\n command: string;\n target_screens?: string[];\n venue_type?: string;\n country?: string;\n params?: Record<string, unknown>;\n }): Promise<{ success: boolean; data: FleetCommand }> {\n return this.http.post<{ success: boolean; data: FleetCommand }>('/v1/partner/fleet/command', body);\n }\n\n /** List recent fleet commands. */\n async listCommands(params?: { limit?: number; offset?: number }): Promise<ListResponse<FleetCommand>> {\n return this.http.get<ListResponse<FleetCommand>>('/v1/partner/fleet/commands', { params });\n }\n}\n","/**\n * AudienceClient — audience intelligence API.\n *\n * Base path: /v1/partner/audience\n */\n\nimport type { HttpClient } from '../http';\nimport type { AudienceData } from '../generated';\n\nexport class AudienceClient {\n constructor(private readonly http: HttpClient) {}\n\n /** Get live audience data for a screen. */\n async getLive(screenId: string): Promise<{ success: boolean; data: AudienceData }> {\n return this.http.get<{ success: boolean; data: AudienceData }>(`/v1/partner/audience/live/${screenId}`);\n }\n\n /** Get audience heatmap across screens. */\n async getHeatmap(params?: {\n start_date?: string;\n end_date?: string;\n screen_ids?: string[];\n }): Promise<{ success: boolean; data: Record<string, unknown> }> {\n return this.http.get<{ success: boolean; data: Record<string, unknown> }>('/v1/partner/audience/heatmap', { params });\n }\n\n /** Get aggregate audience statistics. */\n async getStats(params?: {\n period?: 'day' | 'week' | 'month';\n }): Promise<{ success: boolean; data: Record<string, unknown> }> {\n return this.http.get<{ success: boolean; data: Record<string, unknown> }>('/v1/partner/audience/stats', { params });\n }\n}\n","import { createParser } from 'eventsource-parser';\nimport type { HttpClient } from './http';\nimport { TrillboardsError } from './error';\n\n/** The SSE frame and its decoded JSON payload; in-band error events remain events. */\nexport interface DataStreamEvent {\n event: string;\n data: unknown;\n id?: string;\n retry?: number;\n}\nexport interface StreamOptions { signal?: AbortSignal; }\n\n/** Use the same SSE parser as the official MCP transport, with native fetch cancellation. */\nexport async function* readEventStream(http:HttpClient,path:string,\n params:Record<string,unknown>,options:StreamOptions):AsyncGenerator<DataStreamEvent> {\n const controller=new AbortController();\n const abort=()=>controller.abort(options.signal?.reason);\n if(options.signal?.aborted) abort();\n else options.signal?.addEventListener('abort',abort,{once:true});\n let reader:ReadableStreamDefaultReader<Uint8Array>|undefined;\n try {\n const response=await http.openStream(path,{params,signal:controller.signal});\n reader=response.body!.getReader();\n const decoder=new TextDecoder(),events:DataStreamEvent[]=[];\n let retry:number|undefined;\n const parser=createParser({\n onRetry:value=>{retry=value;},\n onEvent:frame=>{\n let data:unknown;\n try { data=JSON.parse(frame.data); }\n catch { throw new TrillboardsError({type:'api_error',code:'invalid_response',\n message:'Expected JSON data in an SSE event.',statusCode:response.status}); }\n events.push({event:frame.event || 'message',data,\n ...(frame.id===undefined?{}:{id:frame.id}),...(retry===undefined?{}:{retry})});\n retry=undefined;\n },\n });\n while(true) {\n const chunk=await reader.read();\n if(chunk.done) break;\n parser.feed(decoder.decode(chunk.value,{stream:true}));\n while(events.length) {\n if(controller.signal.aborted) throw controller.signal.reason;\n yield events.shift()!;\n }\n }\n parser.feed(decoder.decode());\n while(events.length) yield events.shift()!;\n } finally {\n options.signal?.removeEventListener('abort',abort);\n controller.abort();\n try { await reader?.cancel(); } catch { /* Abort may already have closed the reader. */ }\n reader?.releaseLock();\n }\n}\n","/** Native data access through the existing authenticated transport. */\nimport type { HttpClient } from '../http';\nimport type {\n dataApiListScreensOperation, dataApiScreenAudienceHistoryOperation,\n dataApiScreenAudienceLiveOperation, dataApiQueryDslOperation, dataApiStreamOperation,\n} from '../generated';\nimport { readEventStream, type DataStreamEvent, type StreamOptions } from '../stream';\nexport type { DataStreamEvent, StreamOptions } from '../stream';\n\nexport class DataClient {\n constructor(private readonly http: HttpClient) {}\n /** Get venue intelligence data for a screen. */\n getVenueIntelligence(screenId: string): Promise<{success:boolean;data:Record<string,unknown>}> {\n return this.http.get('/v1/partner/venue/'+encodeURIComponent(screenId));\n }\n /** Get API usage summary. */\n getUsage(params?: {period?:'day'|'week'|'month'}): Promise<{success:boolean;data:Record<string,unknown>}> {\n return this.http.get('/v1/partner/usage',{params});\n }\n listScreens(query: dataApiListScreensOperation['query'] = {}): Promise<dataApiListScreensOperation['response']> {\n return this.http.get('/v1/data/screens',{params:query});\n }\n getHistory(screenId:string,query:dataApiScreenAudienceHistoryOperation['query']={}):Promise<dataApiScreenAudienceHistoryOperation['response']> {\n return this.http.get('/v1/data/screens/'+encodeURIComponent(screenId)+'/history',{params:query});\n }\n getAudience(screenId:string):Promise<dataApiScreenAudienceLiveOperation['response']> {\n return this.http.get('/v1/data/screens/'+encodeURIComponent(screenId)+'/audience');\n }\n query(body:dataApiQueryDslOperation['request']):Promise<dataApiQueryDslOperation['response']> {\n return this.http.post('/v1/data/query',body);\n }\n /** One live tail; reconnect explicitly and recover history through bounded reads. */\n stream(query:dataApiStreamOperation['query']={},options:StreamOptions={}):AsyncIterable<DataStreamEvent> {\n return readEventStream(this.http,'/v1/data/stream',query,options);\n }\n}\n","/**\n * BillingClient — usage-based billing and credits.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { BillingInfo, setupBillingOperation, createCreditCheckoutOperation, purchaseCreditsOperation, getBillingUsageSummaryOperation } from '../generated';\n\n/** Reuse the same key only for the exact same financial request. */\nexport interface BillingOperationOptions { idempotencyKey: string; }\n\nexport class BillingClient {\n constructor(private readonly http: HttpClient) {}\n\n setup(body:setupBillingOperation['request']):Promise<setupBillingOperation['response']> {\n return this.http.post('/v1/partner/billing/setup',body);\n }\n\n createCreditCheckout(body:createCreditCheckoutOperation['request'],options:BillingOperationOptions):Promise<createCreditCheckoutOperation['response']> {\n return this.http.post('/v1/partner/billing/credits/checkout',body,{headers:{'Idempotency-Key':options.idempotencyKey}});\n }\n\n purchaseCredits(body:purchaseCreditsOperation['request'],options:BillingOperationOptions):Promise<purchaseCreditsOperation['response']> {\n return this.http.post('/v1/partner/billing/credits',body,{headers:{'Idempotency-Key':options.idempotencyKey}});\n }\n\n /** Read the committed shared credit ledger after Stripe payment completes. */\n getUsageSummary():Promise<getBillingUsageSummaryOperation['response']> {\n return this.http.get('/v1/partner/billing/usage-summary');\n }\n\n /** Get current billing info (plan, credits, usage). */\n async get(): Promise<{ success: boolean; data: BillingInfo }> {\n return this.http.get<{ success: boolean; data: BillingInfo }>('/v1/partner/billing');\n }\n\n /** Get Stripe Connect account status. */\n async getStripeStatus(): Promise<{ success: boolean; data: Record<string, unknown> }> {\n return this.http.get<{ success: boolean; data: Record<string, unknown> }>('/v1/partner/stripe/status');\n }\n\n /** Request a payout transfer. */\n async requestPayout(body?: {\n amount?: number;\n }): Promise<{ success: boolean; data: Record<string, unknown> }> {\n return this.http.post<{ success: boolean; data: Record<string, unknown> }>('/v1/partner/stripe/payout', body ?? {});\n }\n}\n","/**\n * RoutesClient — Sense Anything \"Routes\": alerting + automation on the sensing\n * stream. A Route fires channel actions (webhook / managed WhatsApp / SMS /\n * Slack / email) when a sensed field crosses a threshold on a set of your\n * screens, or on a scheduled digest.\n *\n * Base path: /v1/partner/sensing/routes\n */\n\nimport type { HttpClient } from '../http';\nimport type {\n SensingRoute,\n CreatePartnerSensingRouteRequest,\n UpdatePartnerSensingRouteRequest,\n} from '../generated';\n\nconst BASE = '/v1/partner/sensing/routes';\n\nexport class RoutesClient {\n constructor(private readonly http: HttpClient) {}\n\n /** Create a Route. Every screen in `screenMongoIds` must be one you own. */\n async create(body: CreatePartnerSensingRouteRequest): Promise<{ success: boolean; data: { route: SensingRoute } }> {\n return this.http.post<{ success: boolean; data: { route: SensingRoute } }>(BASE, body);\n }\n\n /** List your Routes. Pass `includeDisabled: false` to return only enabled Routes. */\n async list(params?: { includeDisabled?: boolean }): Promise<{ success: boolean; data: { routes: SensingRoute[] } }> {\n return this.http.get<{ success: boolean; data: { routes: SensingRoute[] } }>(BASE, { params });\n }\n\n /** Get one Route by id. */\n async get(routeId: string): Promise<{ success: boolean; data: { route: SensingRoute } }> {\n return this.http.get<{ success: boolean; data: { route: SensingRoute } }>(`${BASE}/${routeId}`);\n }\n\n /** Update a Route (partial, non-clobbering — only the fields you send change). */\n async update(\n routeId: string,\n body: UpdatePartnerSensingRouteRequest,\n ): Promise<{ success: boolean; data: { route: SensingRoute } }> {\n return this.http.patch<{ success: boolean; data: { route: SensingRoute } }>(`${BASE}/${routeId}`, body);\n }\n\n /** Soft-delete a Route. */\n async delete(routeId: string): Promise<{ success: boolean; data: { routeId: string } }> {\n return this.http.delete<{ success: boolean; data: { routeId: string } }>(`${BASE}/${routeId}`);\n }\n}\n","/** Native funded creative feedback, using the existing partner HTTP client. */\nimport type {HttpClient} from '../http';\nimport type {\n importCreativeFeedbackCreativeOperation,configureCreativeFeedbackBrandOperation,createCreativeFeedbackExperimentOperation,getCreativeFeedbackExperimentOperation,\n registerCreativeFeedbackVariantsOperation,updateCreativeFeedbackPolicyOperation,\n getCreativeFeedbackRewardsOperation,stopCreativeFeedbackExperimentOperation,\n generateCreativeFeedbackCreativeOperation,reviewCreativeFeedbackCreativeOperation,\n} from '../generated';\nconst BASE='/v1/partner/creative-experiments';\nconst path=(id:string)=>`${BASE}/${encodeURIComponent(id)}`;\nexport class CreativeExperimentsClient {\n constructor(private readonly http:HttpClient){}\n create(body:createCreativeFeedbackExperimentOperation['request']):Promise<createCreativeFeedbackExperimentOperation['response']>{return this.http.post(BASE,body);}\n configureBrand(id:string,body:configureCreativeFeedbackBrandOperation['request']):Promise<configureCreativeFeedbackBrandOperation['response']>{return this.http.post(path(id)+'/brand',body);}\n importCreative(id:string,body:importCreativeFeedbackCreativeOperation['request']):Promise<importCreativeFeedbackCreativeOperation['response']>{return this.http.post(path(id)+'/creatives/import',body);}\n get(id:string):Promise<getCreativeFeedbackExperimentOperation['response']>{return this.http.get(path(id));}\n registerVariants(id:string,body:registerCreativeFeedbackVariantsOperation['request']):Promise<registerCreativeFeedbackVariantsOperation['response']>{return this.http.post(path(id)+'/variants',body);}\n updatePolicy(id:string,body:updateCreativeFeedbackPolicyOperation['request']):Promise<updateCreativeFeedbackPolicyOperation['response']>{return this.http.put(path(id)+'/policy',body);}\n getRewards(id:string,query:getCreativeFeedbackRewardsOperation['query']):Promise<getCreativeFeedbackRewardsOperation['response']>{return this.http.get(path(id)+'/rewards',{params:query});}\n generate(id:string,body:generateCreativeFeedbackCreativeOperation['request']):Promise<generateCreativeFeedbackCreativeOperation['response']>{return this.http.post(path(id)+'/creatives/generate',body);}\n review(id:string,body:reviewCreativeFeedbackCreativeOperation['request']):Promise<reviewCreativeFeedbackCreativeOperation['response']>{return this.http.post(path(id)+'/creatives/review',body);}\n stop(id:string,body:stopCreativeFeedbackExperimentOperation['request']):Promise<stopCreativeFeedbackExperimentOperation['response']>{return this.http.post(path(id)+'/stop',body);}\n}\n","/** Native AdCP buying tools on /mcp, using the official protocol client. */\nimport {Client} from '@modelcontextprotocol/sdk/client/index.js';\nimport {StreamableHTTPClientTransport} from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport type {CallToolResult} from '@modelcontextprotocol/sdk/types.js';\nimport type {HttpClientConfig} from '../http';\nimport {VERSION} from '../version';\nimport type {\n Mcp_get_products_Args,Mcp_list_accounts_Args,Mcp_sync_accounts_Args,\n Mcp_create_media_buy_Args,Mcp_get_media_buys_Args,Mcp_update_media_buy_Args,\n Mcp_sync_creatives_Args,Mcp_get_media_buy_delivery_Args,Mcp_discover_inventory_Args,\n} from '../generated';\n\n/** Native MCP errors retain their complete result, including structured receipts. */\nexport class McpToolError extends Error {\n readonly name='McpToolError';\n constructor(readonly tool:string,readonly result:CallToolResult) {\n super('Native MCP tool failed: '+tool);\n }\n}\nexport interface MediaPagination {has_more:boolean;cursor?:string;total_count?:number;}\nexport interface MediaProduct extends Record<string,unknown> {\n product_id:string;name?:string;pricing_options:Array<{pricing_option_id:string;fixed_price?:number;floor_price?:number;currency?:string;[key:string]:unknown}>;\n}\nexport interface MediaFunding extends Record<string,unknown> {\n status:string;required_cents?:number|string;available_cents?:number|string;drawn_cents?:number|string;\n}\nexport interface MediaPackage extends Record<string,unknown> {package_id:string;product_id?:string;}\n/** Selected native response fields; the complete extensible payload is preserved. */\nexport interface MediaBuy extends Record<string,unknown> {\n media_buy_id:string;packages:MediaPackage[];revision:number;media_buy_status?:string;status?:string;funding?:MediaFunding;\n}\nexport interface MediaProductsResponse extends Record<string,unknown> {products:MediaProduct[];pagination?:MediaPagination;}\nexport interface MediaBuysResponse extends Record<string,unknown> {media_buys:MediaBuy[];pagination:MediaPagination;}\nexport interface MediaAccountsResponse extends Record<string,unknown> {accounts:Array<{account_id:string;status:string;[key:string]:unknown}>;pagination?:MediaPagination;}\n\n\nexport interface MediaNativeError extends Record<string,unknown> {code:string;message:string;}\nexport interface MediaBuyUpdateResponse extends Record<string,unknown> {\n media_buy_id:string;revision:number;media_buy_status:string;sandbox:boolean;\n affected_packages?:MediaPackage[];applied:Record<string,unknown>;unsupported:string[];\n placements_updated:number;placement_count:number;\n}\nexport interface MediaDeliveryResponse extends Record<string,unknown> {\n media_buy_id:string;impressions:number;reach_screens:number;contracted_spend_usd:number;sandbox:boolean;\n pacing:{goal_impressions:number;delivered:number;delivery_rate:number};\n dimensions_honoured:string[];dimensions_unsupported:string[];\n}\nexport interface MediaCreativeSyncResponse extends Record<string,unknown> {\n media_buy_id:string|null;advertisement_id:string|null;sandbox:boolean;\n creatives:Array<{creative_id:string;action:string;status?:string;errors?:MediaNativeError[];[key:string]:unknown}>;\n validation_results:Array<Record<string,unknown>>;approved_count:number;rejected_count:number;\n placements_activated:number;servable:boolean;funding?:MediaFunding;moderation?:Record<string,unknown>;\n validated_against:{catalogue_generated_at:string;stale:boolean};\n}\nexport interface MediaAccountsSyncResponse extends Record<string,unknown> {\n dry_run:boolean;\n accounts:Array<{account_id:string|null;action:string;status?:string;errors?:MediaNativeError[];[key:string]:unknown}>;\n}\n\nexport class MediaBuysClient {\n private client?:Client;\n private transport?:StreamableHTTPClientTransport;\n private connecting?:Promise<Client>;\n constructor(private readonly config:HttpClientConfig) {}\n\n private connection():Promise<Client> {\n if(!this.connecting) {\n const client=new Client({name:'trillboards-typescript',version:VERSION});\n const transport=new StreamableHTTPClientTransport(new URL(this.config.baseUrl+'/mcp'),{\n requestInit:{headers:{\n Authorization:'Bearer '+this.config.apiKey,\n 'X-Trillboards-Client':'typescript-sdk/'+VERSION,\n 'User-Agent':'trillboards-typescript/'+VERSION,\n ...(this.config.version?{'Trillboards-Version':this.config.version}:{}),\n }},\n });\n this.client=client;this.transport=transport;\n this.connecting=client.connect(transport).then(()=>client).catch(async error=>{\n await client.close();this.client=undefined;this.transport=undefined;this.connecting=undefined;throw error;\n });\n }\n return this.connecting;\n }\n\n private async call<T>(name:string,args:Record<string,unknown>):Promise<T> {\n const client=await this.connection();\n const result=await client.callTool({name,arguments:args}) as CallToolResult;\n if(result.isError) throw new McpToolError(name,result);\n if(result.structuredContent) return result.structuredContent as T;\n for(const block of result.content) {\n if(block.type!=='text') continue;\n try {return JSON.parse(block.text) as T;} catch { /* A prose summary is not the structured result. */ }\n }\n throw new McpToolError(name,result);\n }\n\n getProducts(args:Mcp_get_products_Args={}):Promise<MediaProductsResponse> {return this.call('get_products',args);}\n listAccounts(args:Mcp_list_accounts_Args={}):Promise<MediaAccountsResponse> {return this.call('list_accounts',args);}\n syncAccounts(args:Mcp_sync_accounts_Args):Promise<MediaAccountsSyncResponse> {return this.call('sync_accounts',args);}\n create(args:Mcp_create_media_buy_Args):Promise<MediaBuy> {return this.call('create_media_buy',args);}\n list(args:Mcp_get_media_buys_Args={}):Promise<MediaBuysResponse> {return this.call('get_media_buys',args);}\n update(args:Mcp_update_media_buy_Args):Promise<MediaBuyUpdateResponse> {return this.call('update_media_buy',args);}\n getDelivery(args:Mcp_get_media_buy_delivery_Args):Promise<MediaDeliveryResponse> {return this.call('get_media_buy_delivery',args);}\n syncCreatives(args:Mcp_sync_creatives_Args):Promise<MediaCreativeSyncResponse> {return this.call('sync_creatives',args);}\n discoverInventory(args:Mcp_discover_inventory_Args={}):Promise<{success:boolean;data:{screens:Array<Record<string,unknown>>;[key:string]:unknown}}> {return this.call('discover_inventory',args);}\n\n /** Release MCP streams and terminate an optional server session. */\n async close():Promise<void> {\n await this.connecting?.catch(()=>undefined);\n const client=this.client,transport=this.transport;\n this.client=undefined;this.transport=undefined;this.connecting=undefined;\n try {if(transport?.sessionId) await transport.terminateSession();}\n finally {await client?.close();}\n }\n}\n","/**\n * TrillboardsClient — main entry point for the Trillboards Partner API SDK.\n *\n * Usage:\n * import { TrillboardsClient } from '@trillboards/api-client';\n *\n * const client = new TrillboardsClient({ apiKey: 'trb_partner_xxxxx' });\n * const screens = await client.screens.list();\n */\n\nimport { HttpClient } from './http';\nimport type { ClientOptions } from './types';\nimport {\n ScreensClient,\n DevicesClient,\n ImpressionsClient,\n AnalyticsClient,\n EarningsClient,\n ErrorsClient,\n WebhooksClient,\n FleetClient,\n AudienceClient,\n DataClient,\n BillingClient,\n RoutesClient,\n CreativeExperimentsClient,\n MediaBuysClient,\n} from './resources';\n\nconst DEFAULT_BASE_URL = 'https://api.trillboards.com';\n\nexport class TrillboardsClient {\n readonly screens: ScreensClient;\n readonly devices: DevicesClient;\n readonly impressions: ImpressionsClient;\n readonly analytics: AnalyticsClient;\n readonly webhooks: WebhooksClient;\n readonly earnings: EarningsClient;\n readonly fleet: FleetClient;\n readonly audience: AudienceClient;\n readonly data: DataClient;\n readonly errors: ErrorsClient;\n readonly billing: BillingClient;\n readonly routes: RoutesClient;\n readonly creativeExperiments: CreativeExperimentsClient;\n readonly mediaBuys: MediaBuysClient;\n\n /** The underlying HTTP client (exposed for advanced use cases). */\n readonly _http: HttpClient;\n\n constructor(options: ClientOptions) {\n if (!options.apiKey) {\n throw new Error(\n 'TrillboardsClient requires an apiKey. Get one at https://trillboards.com/developers'\n );\n }\n\n const baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '');\n\n this._http = new HttpClient({\n apiKey: options.apiKey,\n baseUrl,\n version: options.version,\n });\n\n this.screens = new ScreensClient(this._http);\n this.devices = new DevicesClient(this._http);\n this.impressions = new ImpressionsClient(this._http);\n this.analytics = new AnalyticsClient(this._http);\n this.webhooks = new WebhooksClient(this._http);\n this.earnings = new EarningsClient(this._http);\n this.fleet = new FleetClient(this._http);\n this.audience = new AudienceClient(this._http);\n this.data = new DataClient(this._http);\n this.errors = new ErrorsClient(this._http);\n this.billing = new BillingClient(this._http);\n this.routes = new RoutesClient(this._http);\n this.creativeExperiments = new CreativeExperimentsClient(this._http);\n this.mediaBuys = new MediaBuysClient({apiKey:options.apiKey,baseUrl,version:options.version});\n }\n}\n","/**\n * Webhook signature verification for Trillboards webhooks.\n *\n * Header format produced by the server (matches Stripe-style compound shape):\n *\n * X-Trillboards-Signature: t=<unix_seconds>,v0=<hex>,v1=<hex>\n * X-Trillboards-Timestamp: <unix_seconds> // redundant; same value as t=\n * X-Trillboards-Event: <event_name>\n * X-Trillboards-Webhook-Id: <subscription_id>\n *\n * Where v1 = HMAC-SHA256(secret, `${timestamp}.${payload}`)\n * v0 = HMAC-SHA256(secret, payload) ← legacy body-only, emitted for back-compat\n *\n * `constructEvent` prefers v1 (replay-protected); falls back to v0 when v1 is\n * absent (server in pre-migration state) or when only the legacy\n * `sha256=<hex>` form is present.\n *\n * Replay protection: a configurable tolerance window (default 300s, Stripe-\n * aligned) rejects payloads whose timestamp is too far from the verifier's\n * clock. Adjust via the `tolerance` option.\n *\n * Migration note (since 0.3.0):\n * The 0.2.0-shape `constructEvent(payload, signatureString, secret)` is kept\n * as `constructEventLegacy` for one minor version. It does NOT verify the\n * timestamp (the 0.2.0 verifier had no access to one). Migrate to the new\n * call shape `constructEvent(payload, req.headers, secret)` to gain replay\n * protection and compound-header support.\n */\n\nimport { createHmac, timingSafeEqual } from 'crypto';\nimport { TrillboardsError } from './error';\nimport type { WebhookEvent } from './generated';\n\nconst DEFAULT_TOLERANCE_SECONDS = 300;\n\nexport interface ConstructEventOptions {\n /** Maximum allowed age (seconds) of a signed payload. Default 300 (Stripe-aligned). */\n tolerance?: number;\n /** Override the verifier's current time (seconds). Tests only. */\n nowSec?: number;\n}\n\n/**\n * Headers carried by a Trillboards webhook delivery. Accepts either the\n * canonical Node `IncomingHttpHeaders` shape (lowercase keys) or any\n * Record<string, string|string[]> with case-insensitive lookup.\n */\nexport type WebhookHeaders =\n | Record<string, string | string[] | undefined>\n | { [key: string]: string | string[] | undefined };\n\n/**\n * Parsed signature-header components.\n */\nexport interface ParsedSignatureHeader {\n /** Unix seconds from `t=` if present. */\n timestamp?: number;\n /** Algorithm → hex-digest map. Standard keys: `v0`, `v1`. */\n versions: Map<string, string>;\n /** Set when the raw input matched the legacy `sha256=<hex>` shape. */\n legacy?: string;\n}\n\n/**\n * Parse a Trillboards `X-Trillboards-Signature` header into its component\n * algorithm-keyed digests.\n *\n * Accepts:\n * \"t=<ts>,v1=<hex>\" → canonical\n * \"t=<ts>,v0=<hex>,v1=<hex>\" → canonical with legacy companion\n * \"sha256=<hex>\" → pre-migration emitter (single value)\n *\n * @public\n */\nexport function parseSignatureHeader(rawSig: string): ParsedSignatureHeader {\n const versions = new Map<string, string>();\n let timestamp: number | undefined;\n let legacy: string | undefined;\n\n const trimmed = rawSig.trim();\n if (trimmed.startsWith('sha256=')) {\n legacy = trimmed.slice('sha256='.length);\n return { timestamp, versions, legacy };\n }\n\n for (const part of trimmed.split(',')) {\n const eq = part.indexOf('=');\n if (eq < 0) continue;\n const key = part.slice(0, eq).trim();\n const value = part.slice(eq + 1).trim();\n if (!key || !value) continue;\n if (key === 't') {\n const ts = Number(value);\n if (Number.isFinite(ts)) timestamp = ts;\n } else if (/^v\\d+$/.test(key)) {\n versions.set(key, value);\n }\n }\n return { timestamp, versions, legacy };\n}\n\nfunction getHeader(headers: WebhookHeaders, name: string): string | undefined {\n // Case-insensitive lookup over a heterogeneous shape.\n const lc = name.toLowerCase();\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === lc) {\n const v = (headers as Record<string, string | string[] | undefined>)[key];\n if (Array.isArray(v)) return v[0];\n return v;\n }\n }\n return undefined;\n}\n\nfunction constantTimeEqual(a: string, b: string): boolean {\n const aBuf = Buffer.from(a, 'utf8');\n const bBuf = Buffer.from(b, 'utf8');\n if (aBuf.length !== bBuf.length) return false;\n return timingSafeEqual(aBuf, bBuf);\n}\n\nfunction authError(message: string): TrillboardsError {\n return new TrillboardsError({\n type: 'authentication_error',\n code: 'webhook_signature_invalid',\n message,\n statusCode: 401,\n });\n}\n\n/**\n * Verify a webhook payload signature and parse the event.\n *\n * @param payload — raw request body (string or Buffer). Must be EXACTLY the\n * bytes the server signed — do NOT re-stringify after JSON.parse.\n * @param headers — IncomingHttpHeaders or any Record<string, string|string[]>\n * produced by your HTTP framework. Case-insensitive lookup.\n * For Express, pass `req.headers`. For Next.js, `req.headers`.\n * Backwards-compat: a raw signature string (the 0.2.0 shape)\n * is also accepted and parsed as if it were the value of\n * `X-Trillboards-Signature`; in that case the verifier looks\n * for the timestamp in the compound header itself, OR throws.\n * @param secret — webhook subscription secret (whsec_...).\n * @param opts.tolerance — replay-window in seconds. Default 300.\n * @returns parsed WebhookEvent if signature valid AND timestamp within tolerance.\n * @throws TrillboardsError(authentication_error / webhook_signature_invalid)\n *\n * @example\n * import { Webhooks } from '@trillboards/api-client';\n *\n * app.post('/webhooks', express.raw({ type: 'application/json' }), (req, res) => {\n * try {\n * const event = Webhooks.constructEvent(\n * req.body, // raw Buffer or string\n * req.headers, // IncomingHttpHeaders\n * process.env.WEBHOOK_SECRET!, // your subscription secret\n * );\n * console.log('Received', event.event);\n * res.sendStatus(200);\n * } catch (err) {\n * // TrillboardsError with code \"webhook_signature_invalid\"\n * res.sendStatus(401);\n * }\n * });\n */\nexport function constructEvent(\n payload: string | Buffer,\n headers: WebhookHeaders | string,\n secret: string,\n opts: ConstructEventOptions = {},\n): WebhookEvent {\n let signatureHeader: string | undefined;\n let timestampHeader: string | undefined;\n\n if (typeof headers === 'string') {\n // Back-compat: caller passed the raw X-Trillboards-Signature value (0.2.0 shape).\n // We can still verify if `t=` is in the compound header, but cannot look for a\n // separate X-Trillboards-Timestamp header.\n signatureHeader = headers;\n } else if (headers && typeof headers === 'object') {\n signatureHeader = getHeader(headers, 'X-Trillboards-Signature');\n timestampHeader = getHeader(headers, 'X-Trillboards-Timestamp');\n }\n\n if (!signatureHeader) {\n throw authError('Missing X-Trillboards-Signature header.');\n }\n\n const payloadStr = typeof payload === 'string' ? payload : payload.toString('utf8');\n const parsed = parseSignatureHeader(signatureHeader);\n\n // Resolve timestamp from (1) compound `t=`, (2) separate `X-Trillboards-Timestamp` header.\n let ts = parsed.timestamp;\n if (ts === undefined && timestampHeader) {\n const fromHeader = Number(timestampHeader);\n if (Number.isFinite(fromHeader)) ts = fromHeader;\n }\n\n if (ts === undefined || !Number.isFinite(ts)) {\n throw authError(\n 'Webhook signature missing timestamp. Provide either `t=<unix_seconds>` ' +\n 'inside X-Trillboards-Signature OR a separate X-Trillboards-Timestamp header.',\n );\n }\n\n const tolerance = opts.tolerance ?? DEFAULT_TOLERANCE_SECONDS;\n const now = opts.nowSec ?? Math.floor(Date.now() / 1000);\n if (Math.abs(now - ts) > tolerance) {\n throw authError(\n `Webhook timestamp ${ts} outside tolerance window of ${tolerance}s (now ${now}). ` +\n 'Possible replay attack.',\n );\n }\n\n // Compute the two expected digests. We compute both even if only one is\n // requested because the work is cheap and constant-time semantics matter.\n const v1Expected = createHmac('sha256', secret)\n .update(`${ts}.${payloadStr}`)\n .digest('hex');\n const v0Expected = createHmac('sha256', secret).update(payloadStr).digest('hex');\n\n const v1Provided = parsed.versions.get('v1');\n const v0Provided = parsed.versions.get('v0');\n\n // SECURITY: v1 takes priority. v0 is ONLY accepted when v1 is ABSENT (i.e.\n // the server is still on the pre-migration emitter or the partner-built\n // body-only verifier). Falling back to v0 after a v1 MISMATCH would defeat\n // replay protection: an attacker who captured one delivery could replay\n // the body with a fresh timestamp; recomputed v1 would fail but v0 (which\n // signs body only) would still match. See partner-api.yaml + integrations/\n // webhook-signature-verification.md migration table.\n if (v1Provided) {\n if (constantTimeEqual(v1Provided, v1Expected)) {\n return JSON.parse(payloadStr) as WebhookEvent;\n }\n // v1 was present but did not verify — reject. Do NOT consult v0.\n throw authError(\n 'Webhook v1 signature verification failed. The payload may have been tampered with, ' +\n 'or your webhook secret may be incorrect.',\n );\n }\n\n // v1 absent — fall back to v0 (legacy body-only emitter).\n if (v0Provided && constantTimeEqual(v0Provided, v0Expected)) {\n return JSON.parse(payloadStr) as WebhookEvent;\n }\n\n // Fallback to bare-hex `sha256=<hex>` form (pre-migration emitter that\n // never wrote v1/v0 labels). Same security note: if v1 is the intended\n // canonical, the bare digest IS v1; try v1Expected first, then v0Expected.\n if (parsed.legacy) {\n if (constantTimeEqual(parsed.legacy, v1Expected)) {\n return JSON.parse(payloadStr) as WebhookEvent;\n }\n if (constantTimeEqual(parsed.legacy, v0Expected)) {\n return JSON.parse(payloadStr) as WebhookEvent;\n }\n }\n\n throw authError(\n 'Webhook signature verification failed. The payload may have been tampered with, ' +\n 'or your webhook secret may be incorrect.',\n );\n}\n\nlet legacyWarned = false;\n\n/**\n * @deprecated since 0.3.0 — kept for one minor version for partners stuck on\n * the 0.2.0 call shape. Use `constructEvent(payload, req.headers, secret)`\n * instead — it gains replay protection and compound-header support.\n *\n * Reproduces the 0.2.0 verifier exactly:\n * HMAC-SHA256(secret, payload) compared (constant-time) against the\n * supplied raw-hex signature string.\n *\n * Does NOT verify any timestamp. The 0.2.0 SDK never had access to one and\n * silently accepted any age of payload — that is a vulnerability this\n * legacy shim preserves only for migration compatibility.\n */\nexport function constructEventLegacy(\n payload: string | Buffer,\n signature: string,\n secret: string,\n): WebhookEvent {\n if (!legacyWarned) {\n // eslint-disable-next-line no-console\n console.warn(\n '[@trillboards/api-client] constructEventLegacy is deprecated and unsafe (no replay ' +\n 'protection). Migrate to Webhooks.constructEvent(payload, req.headers, secret). ' +\n 'See https://api.trillboards.com/docs/integrations/webhook-signature-verification.md',\n );\n legacyWarned = true;\n }\n const payloadStr = typeof payload === 'string' ? payload : payload.toString('utf8');\n const expected = createHmac('sha256', secret).update(payloadStr).digest('hex');\n if (!constantTimeEqual(signature, expected)) {\n throw authError(\n 'Legacy webhook signature mismatch. If your server has been upgraded to the ' +\n 'compound-header emitter, switch to Webhooks.constructEvent instead.',\n );\n }\n return JSON.parse(payloadStr) as WebhookEvent;\n}\n\n// ---------------------------------------------------------------------------\n// AdCP RFC 9421 webhook verification\n// ---------------------------------------------------------------------------\n//\n// Trillboards is an AdCP seller agent. Webhooks it pushes to an AdCP buyer are\n// signed with RFC 9421 HTTP Message Signatures — asymmetric Ed25519, no shared\n// secret — so the buyer verifies against the public keys Trillboards publishes\n// at https://api.trillboards.com/.well-known/jwks.json (discoverable through\n// /.well-known/brand.json). Nothing secret crosses the wire.\n//\n// This is the counterpart to `services/webhooks/canonicalSigner.js`'s\n// `signAdcpWebhook`. Fetching and caching the JWKS is the caller's job (it is\n// an HTTPS GET with a Cache-Control the server sets) so this stays a pure,\n// dependency-free function of (request, keys).\n\n/** RFC 9421 `tag` Trillboards stamps on outbound AdCP webhooks. */\nexport const ADCP_WEBHOOK_SIGNING_TAG = 'adcp/webhook-signing/v1';\n/** Components the AdCP webhook profile always covers. */\nconst ADCP_WEBHOOK_COMPONENTS = [\n '@method',\n '@target-uri',\n '@authority',\n 'content-type',\n 'content-digest',\n];\n/** AdCP caps the signature window; a wider one is a replay risk, not a courtesy. */\nconst ADCP_MAX_WINDOW_SECONDS = 300;\n\n/** An Ed25519 public key from the Trillboards JWKS. */\nexport interface AdcpJwk {\n kty: string;\n crv: string;\n x: string;\n kid: string;\n alg?: string;\n use?: string;\n key_ops?: string[];\n adcp_use?: string;\n}\n\nexport interface VerifyAdcpWebhookOptions {\n /** Absolute URL the webhook was delivered to. Must be the URL you published. */\n url: string;\n /** HTTP method of the delivery. Defaults to POST. */\n method?: string;\n /** Delivery headers (case-insensitive). */\n headers: WebhookHeaders;\n /** Raw request body — EXACTLY the bytes received, never a re-stringify. */\n payload: string | Buffer;\n /** Keys from https://api.trillboards.com/.well-known/jwks.json */\n keys: AdcpJwk[];\n /** Override the verifier's clock (seconds). Tests only. */\n nowSec?: number;\n}\n\n/** Split an RFC 8941 dictionary into its top-level members. */\nfunction splitDictionary(headerValue: string): string[] {\n const members: string[] = [];\n let depth = 0;\n let quoted = false;\n let start = 0;\n for (let i = 0; i < headerValue.length; i++) {\n const ch = headerValue[i];\n if (quoted) {\n if (ch === '\\\\') i++;\n else if (ch === '\"') quoted = false;\n continue;\n }\n if (ch === '\"') quoted = true;\n else if (ch === '(') depth++;\n else if (ch === ')') depth--;\n else if (ch === ',' && depth === 0) {\n members.push(headerValue.slice(start, i).trim());\n start = i + 1;\n }\n }\n members.push(headerValue.slice(start).trim());\n return members.filter((member) => member.length > 0);\n}\n\nfunction dictionaryMember(headerValue: string, label: string): string | undefined {\n return splitDictionary(headerValue).find((member) => member.startsWith(`${label}=`));\n}\n\n/**\n * The AdCP label this verifier processes. RFC 8941 dictionaries are unordered,\n * and a relay may prepend its own signature member — so the label is looked up\n * by NAME, never taken from whichever member happens to be first.\n */\nconst ADCP_SIGNATURE_LABEL = 'sig1';\n\n/**\n * Pick the AdCP signature member out of a possibly multi-member header.\n * Prefers the spec's `sig1`; falls back to whichever member carries the AdCP\n * webhook tag, so a relay that renames labels still verifies. Every candidate\n * still has to pass the full checklist afterwards, so a wrong pick fails\n * closed rather than weakening anything.\n */\nfunction selectAdcpSignatureInput(signatureInput: string): { label: string; member: string } {\n const members = splitDictionary(signatureInput);\n\n const named = members.find((member) => member.startsWith(`${ADCP_SIGNATURE_LABEL}=`));\n if (named) return { label: ADCP_SIGNATURE_LABEL, member: named };\n\n const tagged = members.find((member) => member.includes(`tag=\"${ADCP_WEBHOOK_SIGNING_TAG}\"`));\n if (tagged) return { label: tagged.slice(0, tagged.indexOf('=')), member: tagged };\n\n throw authError(\n `AdCP webhook has no \"${ADCP_SIGNATURE_LABEL}\" signature member and no member tagged ` +\n `\"${ADCP_WEBHOOK_SIGNING_TAG}\".`,\n );\n}\n\n/**\n * Canonicalise a URL for `@target-uri` per the AdCP profile. `URL` lowercases\n * the scheme and host, applies UTS-46 ToASCII, strips the default port,\n * collapses dot segments, and drops the fragment; the remaining rules are\n * percent-encoding normalisation and preserving a trailing empty query.\n */\nfunction canonicalTargetUri(rawUrl: string): string {\n const parsed = new URL(rawUrl);\n const beforeFragment = rawUrl.split('#', 1)[0];\n const search = parsed.search || (beforeFragment.endsWith('?') ? '?' : '');\n return `${parsed.protocol}//${parsed.host}${parsed.pathname}${search}`.replace(\n /%([0-9a-fA-F]{2})/g,\n (match, hex: string) => {\n const code = parseInt(hex, 16);\n const unreserved =\n (code >= 0x41 && code <= 0x5a) ||\n (code >= 0x61 && code <= 0x7a) ||\n (code >= 0x30 && code <= 0x39) ||\n code === 0x2d || code === 0x2e || code === 0x5f || code === 0x7e;\n return unreserved ? String.fromCharCode(code) : `%${hex.toUpperCase()}`;\n },\n );\n}\n\n/**\n * Verify an AdCP RFC 9421 webhook signature and parse the event.\n *\n * Checks, in order: header pair present → covered components complete → tag is\n * the webhook tag → signature window sane and unexpired → key resolvable and\n * purpose-valid → body digest matches → signature verifies.\n *\n * Replay defence beyond the window (per-`nonce` dedup) is the caller's — the\n * nonce is exposed on the return value for exactly that.\n *\n * @throws TrillboardsError(authentication_error / webhook_signature_invalid)\n *\n * @example\n * import { Webhooks } from '@trillboards/api-client';\n *\n * const { keys } = await (await fetch(\n * 'https://api.trillboards.com/.well-known/jwks.json',\n * )).json();\n *\n * app.post('/adcp/webhook', express.raw({ type: 'application/json' }), (req, res) => {\n * const { event } = Webhooks.verifyAdcpWebhook({\n * url: `https://buyer.example.com${req.originalUrl}`,\n * headers: req.headers,\n * payload: req.body,\n * keys,\n * });\n * res.sendStatus(200);\n * });\n */\nexport function verifyAdcpWebhook(opts: VerifyAdcpWebhookOptions): {\n event: WebhookEvent;\n keyid: string;\n nonce: string;\n expires: number;\n} {\n const { createHash, createPublicKey, verify: cryptoVerify } = require('crypto');\n\n const signatureInput = getHeader(opts.headers, 'Signature-Input');\n const signature = getHeader(opts.headers, 'Signature');\n if (!signatureInput || !signature) {\n // Both or neither: accepting one without the other is the classic\n // signature-stripping downgrade.\n throw authError('AdCP webhook is missing the Signature / Signature-Input header pair.');\n }\n\n const { label, member: inputMember } = selectAdcpSignatureInput(signatureInput);\n const signatureMember = dictionaryMember(signature, label);\n if (!signatureMember) {\n throw authError(`AdCP webhook Signature has no \"${label}\" member to match Signature-Input.`);\n }\n\n const paramsStart = inputMember.indexOf('(');\n const paramsEnd = inputMember.indexOf(')');\n if (paramsStart < 0 || paramsEnd < 0) {\n throw authError('AdCP webhook Signature-Input is malformed.');\n }\n const components = inputMember\n .slice(paramsStart + 1, paramsEnd)\n .split(' ')\n .map((component) => component.replace(/^\"|\"$/g, ''))\n .filter((component) => component.length > 0);\n\n const readParam = (name: string): string | undefined => {\n const match = new RegExp(`;${name}=(\"?)([^\";]+)\\\\1`).exec(inputMember);\n return match ? match[2] : undefined;\n };\n const created = Number(readParam('created'));\n const expires = Number(readParam('expires'));\n const nonce = readParam('nonce');\n const keyid = readParam('keyid');\n const alg = readParam('alg');\n const tag = readParam('tag');\n\n if (!nonce || !keyid || !alg || !Number.isFinite(created) || !Number.isFinite(expires)) {\n throw authError('AdCP webhook signature is missing a required parameter.');\n }\n if (tag !== ADCP_WEBHOOK_SIGNING_TAG) {\n // A request signature replayed at a webhook endpoint fails here.\n throw authError(`AdCP webhook signature has tag \"${tag}\", expected \"${ADCP_WEBHOOK_SIGNING_TAG}\".`);\n }\n if (alg !== 'ed25519') {\n throw authError(`AdCP webhook signature algorithm \"${alg}\" is not allowed.`);\n }\n for (const required of ADCP_WEBHOOK_COMPONENTS) {\n if (!components.includes(required)) {\n throw authError(`AdCP webhook signature does not cover \"${required}\".`);\n }\n }\n if (expires <= created || expires - created > ADCP_MAX_WINDOW_SECONDS) {\n throw authError('AdCP webhook signature window is invalid.');\n }\n const now = opts.nowSec ?? Math.floor(Date.now() / 1000);\n if (now > expires) {\n throw authError('AdCP webhook signature has expired. Possible replay attack.');\n }\n\n const jwk = opts.keys.find((key) => key.kid === keyid);\n if (!jwk) {\n throw authError(`AdCP webhook signed with unknown key \"${keyid}\". Refresh the JWKS.`);\n }\n if (jwk.key_ops && !jwk.key_ops.includes('verify')) {\n throw authError(`AdCP webhook key \"${keyid}\" is not a verification key.`);\n }\n if (jwk.adcp_use && jwk.adcp_use !== 'request-signing' && jwk.adcp_use !== 'webhook-signing') {\n throw authError(`AdCP webhook key \"${keyid}\" has adcp_use \"${jwk.adcp_use}\".`);\n }\n\n const payloadBuf = typeof opts.payload === 'string' ? Buffer.from(opts.payload, 'utf8') : opts.payload;\n const contentDigest = getHeader(opts.headers, 'Content-Digest');\n const expectedDigest = `sha-256=:${createHash('sha256').update(payloadBuf).digest('base64')}:`;\n if (!contentDigest || contentDigest !== expectedDigest) {\n throw authError('AdCP webhook Content-Digest does not match the body.');\n }\n\n const method = (opts.method ?? 'POST').toUpperCase();\n const target = new URL(opts.url);\n const baseLines = components.map((component) => {\n switch (component) {\n case '@method':\n return `\"@method\": ${method}`;\n case '@target-uri':\n return `\"@target-uri\": ${canonicalTargetUri(opts.url)}`;\n case '@authority':\n return `\"@authority\": ${target.host.toLowerCase()}`;\n default: {\n const value = getHeader(opts.headers, component);\n if (value === undefined) {\n throw authError(`AdCP webhook covers \"${component}\" but the header is absent.`);\n }\n return `\"${component}\": ${value.trim()}`;\n }\n }\n });\n // The `@signature-params` line is the Signature-Input member VERBATIM minus\n // its label — reserialising it would risk a byte that differs from what the\n // signer hashed.\n baseLines.push(`\"@signature-params\": ${inputMember.slice(label.length + 1)}`);\n\n const signatureBytes = Buffer.from(\n signatureMember.slice(label.length + 1).replace(/^:|:$/g, ''),\n 'base64url',\n );\n const publicKey = createPublicKey({ key: jwk, format: 'jwk' });\n if (!cryptoVerify(null, Buffer.from(baseLines.join('\\n'), 'utf8'), publicKey, signatureBytes)) {\n throw authError(\n 'AdCP webhook signature verification failed. The delivery may have been tampered with.',\n );\n }\n\n return {\n event: JSON.parse(payloadBuf.toString('utf8')) as WebhookEvent,\n keyid,\n nonce,\n expires,\n };\n}\n\n/** Namespaced export — matches the Stripe-style API. */\nexport const Webhooks = {\n constructEvent,\n constructEventLegacy,\n parseSignatureHeader,\n verifyAdcpWebhook,\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trillboards/api-client",
3
- "version": "3.2.18",
3
+ "version": "3.2.20",
4
4
  "description": "Official TypeScript SDK for the Trillboards DOOH Partner API",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",