@trillboards/api-client 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -635,7 +635,7 @@ declare const Webhooks: {
635
635
  * SDK version constant. Sent in User-Agent and X-Trillboards-Client headers.
636
636
  * Keep in sync with package.json version.
637
637
  */
638
- declare const VERSION = "0.1.0";
638
+ declare const VERSION = "0.1.2";
639
639
 
640
640
  declare const generatedTypes: {};
641
641
 
package/dist/index.d.ts CHANGED
@@ -635,7 +635,7 @@ declare const Webhooks: {
635
635
  * SDK version constant. Sent in User-Agent and X-Trillboards-Client headers.
636
636
  * Keep in sync with package.json version.
637
637
  */
638
- declare const VERSION = "0.1.0";
638
+ declare const VERSION = "0.1.2";
639
639
 
640
640
  declare const generatedTypes: {};
641
641
 
package/dist/index.js CHANGED
@@ -72,9 +72,10 @@ var TrillboardsError = class _TrillboardsError extends Error {
72
72
  };
73
73
 
74
74
  // src/version.ts
75
- var VERSION = "0.1.0";
75
+ var VERSION = "0.1.2";
76
76
 
77
77
  // src/http.ts
78
+ var PUBLIC_PATHS = ["/v1/errors", "/v1/changelog", "/api/discover", "/v1/health"];
78
79
  var HttpClient = class {
79
80
  constructor(config) {
80
81
  this.config = config;
@@ -82,12 +83,15 @@ var HttpClient = class {
82
83
  async request(method, path, options) {
83
84
  const url = this.buildUrl(path, options?.params);
84
85
  const headers = {
85
- "Authorization": `Bearer ${this.config.apiKey}`,
86
86
  "Content-Type": "application/json",
87
87
  "X-Trillboards-Client": `typescript-sdk/${VERSION}`,
88
88
  "User-Agent": `trillboards-typescript/${VERSION}`,
89
89
  ...options?.headers ?? {}
90
90
  };
91
+ const isPublic = PUBLIC_PATHS.some((prefix) => path.startsWith(prefix));
92
+ if (!isPublic && this.config.apiKey) {
93
+ headers["Authorization"] = `Bearer ${this.config.apiKey}`;
94
+ }
91
95
  if (this.config.version) {
92
96
  headers["Trillboards-Version"] = this.config.version;
93
97
  }
package/dist/index.js.map CHANGED
@@ -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/resources/data.ts","../src/resources/billing.ts","../src/client.ts","../src/webhooks.ts","../src/generated/index.ts"],"names":["createHmac","timingSafeEqual"],"mappings":"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","file":"index.js","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 * Keep in sync with package.json version.\n */\nexport const VERSION = '0.1.0';\n","/**\n * Internal HTTP client for the Trillboards API.\n *\n * Uses native fetch (Node 18+). Zero runtime dependencies.\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 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 url = this.buildUrl(path, options?.params);\n\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.config.apiKey}`,\n 'Content-Type': 'application/json',\n 'X-Trillboards-Client': `typescript-sdk/${VERSION}`,\n 'User-Agent': `trillboards-typescript/${VERSION}`,\n ...(options?.headers ?? {}),\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 const response = await fetch(url, fetchOptions);\n\n // Handle 204 No Content\n if (response.status === 204) {\n return undefined as T;\n }\n\n let json: unknown;\n try {\n json = await response.json();\n } catch {\n throw new TrillboardsError({\n type: 'api_error',\n code: 'invalid_response',\n message: `Invalid JSON response from API (HTTP ${response.status}).`,\n statusCode: response.status,\n });\n }\n\n if (!response.ok) {\n throw TrillboardsError.fromResponse(json as ErrorResponseBody, response);\n }\n\n return json as T;\n }\n\n get<T>(path: string, opts?: { params?: Record<string, unknown> }): Promise<T> {\n return this.request<T>('GET', path, { params: opts?.params });\n }\n\n post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('POST', path, { body });\n }\n\n put<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('PUT', path, { body });\n }\n\n patch<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('PATCH', path, { body });\n }\n\n delete<T>(path: string): Promise<T> {\n return this.request<T>('DELETE', path);\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, Screen } from '../types';\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: {\n device_name: string;\n device_type?: string;\n venue_type?: string;\n country?: string;\n city?: string;\n timezone?: string;\n resolution?: string;\n }): Promise<{ success: boolean; data: Screen }> {\n return this.http.post<{ success: boolean; data: Screen }>('/v1/partner/device', body);\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 } from '../http';\nimport type { Device, ListResponse } from '../types';\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: {\n device_name: string;\n device_type?: string;\n platform?: string;\n }): Promise<{ success: boolean; data: Device }> {\n return this.http.post<{ success: boolean; data: Device }>('/v1/partner/device', 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 /** Send heartbeat for a device. */\n async heartbeat(deviceId: string, body?: Record<string, unknown>): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(`/v1/partner/device/${deviceId}/heartbeat`, body ?? {});\n }\n}\n","/**\n * ImpressionsClient — impression tracking.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { Impression } from '../types';\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 '../types';\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 '../types';\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 — query the partner error log.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { ErrorEntry, ListResponse } from '../types';\n\nexport class ErrorsClient {\n constructor(private readonly http: HttpClient) {}\n\n /** List recent errors for this partner. */\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/partner/usage', { params });\n }\n\n /** Get a single error by request_id. */\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, Webhook } from '../types';\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 /** Create a new webhook subscription. */\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 { FleetCommand, ListResponse } from '../types';\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 '../types';\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","/**\n * DataClient — data export and venue intelligence.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\n\nexport class DataClient {\n constructor(private readonly http: HttpClient) {}\n\n /** Get venue intelligence data for a screen. */\n async getVenueIntelligence(screenId: string): Promise<{ success: boolean; data: Record<string, unknown> }> {\n return this.http.get<{ success: boolean; data: Record<string, unknown> }>(`/v1/partner/venue/${screenId}`);\n }\n\n /** Get API usage summary. */\n async getUsage(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/usage', { params });\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 } from '../types';\n\nexport class BillingClient {\n constructor(private readonly http: HttpClient) {}\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 * 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} 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\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 }\n}\n","/**\n * Webhook signature verification for Trillboards Partner API webhooks.\n *\n * Uses HMAC-SHA256 with timing-safe comparison to prevent signature\n * forgery and timing attacks.\n */\n\nimport { createHmac, timingSafeEqual } from 'crypto';\nimport { TrillboardsError } from './error';\nimport type { WebhookEvent } from './types';\n\n/**\n * Verify a webhook payload signature and parse the event.\n *\n * @param payload - Raw request body as string or Buffer.\n * @param signature - The signature from the `X-Trillboards-Signature` header.\n * @param secret - The webhook secret from your webhook subscription.\n * @returns The parsed WebhookEvent if signature is valid.\n * @throws TrillboardsError if the signature does not match.\n *\n * @example\n * ```typescript\n * import { Webhooks } from '@trillboards/api-client';\n *\n * app.post('/webhooks', (req, res) => {\n * const event = Webhooks.constructEvent(\n * req.body,\n * req.headers['x-trillboards-signature'],\n * process.env.WEBHOOK_SECRET\n * );\n * console.log('Received event:', event.type);\n * res.sendStatus(200);\n * });\n * ```\n */\nexport function constructEvent(\n payload: string | Buffer,\n signature: string,\n secret: string,\n): WebhookEvent {\n const payloadStr = typeof payload === 'string' ? payload : payload.toString('utf8');\n\n const expectedSignature = createHmac('sha256', secret)\n .update(payloadStr)\n .digest('hex');\n\n const sigBuffer = Buffer.from(signature, 'utf8');\n const expectedBuffer = Buffer.from(expectedSignature, 'utf8');\n\n if (sigBuffer.length !== expectedBuffer.length || !timingSafeEqual(sigBuffer, expectedBuffer)) {\n throw new TrillboardsError({\n type: 'authentication_error',\n code: 'webhook_signature_invalid',\n message: 'Webhook signature verification failed. The payload may have been tampered with.',\n statusCode: 401,\n });\n }\n\n return JSON.parse(payloadStr) as WebhookEvent;\n}\n\nexport const Webhooks = { constructEvent };\n","// Auto-generated from OpenAPI specs — run npm run generate to populate\n//\n// This directory will contain auto-generated TypeScript types derived from\n// trillboard-api/docs/openapi/partner-api.yaml and the generated fragments\n// at trillboard-api/docs/openapi/generated/partner-api-generated.json.\n\nexport const generatedTypes = {} as const;\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/resources/data.ts","../src/resources/billing.ts","../src/client.ts","../src/webhooks.ts","../src/generated/index.ts"],"names":["createHmac","timingSafeEqual"],"mappings":"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","file":"index.js","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 * Keep in sync with package.json version.\n */\nexport const VERSION = '0.1.2';\n","/**\n * Internal HTTP client for the Trillboards API.\n *\n * Uses native fetch (Node 18+). Zero runtime dependencies.\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\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\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 url = this.buildUrl(path, options?.params);\n\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\n const isPublic = PUBLIC_PATHS.some(prefix => path.startsWith(prefix));\n if (!isPublic && this.config.apiKey) {\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 const response = await fetch(url, fetchOptions);\n\n // Handle 204 No Content\n if (response.status === 204) {\n return undefined as T;\n }\n\n let json: unknown;\n try {\n json = await response.json();\n } catch {\n throw new TrillboardsError({\n type: 'api_error',\n code: 'invalid_response',\n message: `Invalid JSON response from API (HTTP ${response.status}).`,\n statusCode: response.status,\n });\n }\n\n if (!response.ok) {\n throw TrillboardsError.fromResponse(json as ErrorResponseBody, response);\n }\n\n return json as T;\n }\n\n get<T>(path: string, opts?: { params?: Record<string, unknown> }): Promise<T> {\n return this.request<T>('GET', path, { params: opts?.params });\n }\n\n post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('POST', path, { body });\n }\n\n put<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('PUT', path, { body });\n }\n\n patch<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('PATCH', path, { body });\n }\n\n delete<T>(path: string): Promise<T> {\n return this.request<T>('DELETE', path);\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, Screen } from '../types';\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: {\n device_name: string;\n device_type?: string;\n venue_type?: string;\n country?: string;\n city?: string;\n timezone?: string;\n resolution?: string;\n }): Promise<{ success: boolean; data: Screen }> {\n return this.http.post<{ success: boolean; data: Screen }>('/v1/partner/device', body);\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 } from '../http';\nimport type { Device, ListResponse } from '../types';\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: {\n device_name: string;\n device_type?: string;\n platform?: string;\n }): Promise<{ success: boolean; data: Device }> {\n return this.http.post<{ success: boolean; data: Device }>('/v1/partner/device', 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 /** Send heartbeat for a device. */\n async heartbeat(deviceId: string, body?: Record<string, unknown>): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(`/v1/partner/device/${deviceId}/heartbeat`, body ?? {});\n }\n}\n","/**\n * ImpressionsClient — impression tracking.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { Impression } from '../types';\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 '../types';\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 '../types';\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 — query the partner error log.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { ErrorEntry, ListResponse } from '../types';\n\nexport class ErrorsClient {\n constructor(private readonly http: HttpClient) {}\n\n /** List recent errors for this partner. */\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/partner/usage', { params });\n }\n\n /** Get a single error by request_id. */\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, Webhook } from '../types';\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 /** Create a new webhook subscription. */\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 { FleetCommand, ListResponse } from '../types';\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 '../types';\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","/**\n * DataClient — data export and venue intelligence.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\n\nexport class DataClient {\n constructor(private readonly http: HttpClient) {}\n\n /** Get venue intelligence data for a screen. */\n async getVenueIntelligence(screenId: string): Promise<{ success: boolean; data: Record<string, unknown> }> {\n return this.http.get<{ success: boolean; data: Record<string, unknown> }>(`/v1/partner/venue/${screenId}`);\n }\n\n /** Get API usage summary. */\n async getUsage(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/usage', { params });\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 } from '../types';\n\nexport class BillingClient {\n constructor(private readonly http: HttpClient) {}\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 * 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} 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\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 }\n}\n","/**\n * Webhook signature verification for Trillboards Partner API webhooks.\n *\n * Uses HMAC-SHA256 with timing-safe comparison to prevent signature\n * forgery and timing attacks.\n */\n\nimport { createHmac, timingSafeEqual } from 'crypto';\nimport { TrillboardsError } from './error';\nimport type { WebhookEvent } from './types';\n\n/**\n * Verify a webhook payload signature and parse the event.\n *\n * @param payload - Raw request body as string or Buffer.\n * @param signature - The signature from the `X-Trillboards-Signature` header.\n * @param secret - The webhook secret from your webhook subscription.\n * @returns The parsed WebhookEvent if signature is valid.\n * @throws TrillboardsError if the signature does not match.\n *\n * @example\n * ```typescript\n * import { Webhooks } from '@trillboards/api-client';\n *\n * app.post('/webhooks', (req, res) => {\n * const event = Webhooks.constructEvent(\n * req.body,\n * req.headers['x-trillboards-signature'],\n * process.env.WEBHOOK_SECRET\n * );\n * console.log('Received event:', event.type);\n * res.sendStatus(200);\n * });\n * ```\n */\nexport function constructEvent(\n payload: string | Buffer,\n signature: string,\n secret: string,\n): WebhookEvent {\n const payloadStr = typeof payload === 'string' ? payload : payload.toString('utf8');\n\n const expectedSignature = createHmac('sha256', secret)\n .update(payloadStr)\n .digest('hex');\n\n const sigBuffer = Buffer.from(signature, 'utf8');\n const expectedBuffer = Buffer.from(expectedSignature, 'utf8');\n\n if (sigBuffer.length !== expectedBuffer.length || !timingSafeEqual(sigBuffer, expectedBuffer)) {\n throw new TrillboardsError({\n type: 'authentication_error',\n code: 'webhook_signature_invalid',\n message: 'Webhook signature verification failed. The payload may have been tampered with.',\n statusCode: 401,\n });\n }\n\n return JSON.parse(payloadStr) as WebhookEvent;\n}\n\nexport const Webhooks = { constructEvent };\n","// Auto-generated from OpenAPI specs — run npm run generate to populate\n//\n// This directory will contain auto-generated TypeScript types derived from\n// trillboard-api/docs/openapi/partner-api.yaml and the generated fragments\n// at trillboard-api/docs/openapi/generated/partner-api-generated.json.\n\nexport const generatedTypes = {} as const;\n"]}
package/dist/index.mjs CHANGED
@@ -70,9 +70,10 @@ var TrillboardsError = class _TrillboardsError extends Error {
70
70
  };
71
71
 
72
72
  // src/version.ts
73
- var VERSION = "0.1.0";
73
+ var VERSION = "0.1.2";
74
74
 
75
75
  // src/http.ts
76
+ var PUBLIC_PATHS = ["/v1/errors", "/v1/changelog", "/api/discover", "/v1/health"];
76
77
  var HttpClient = class {
77
78
  constructor(config) {
78
79
  this.config = config;
@@ -80,12 +81,15 @@ var HttpClient = class {
80
81
  async request(method, path, options) {
81
82
  const url = this.buildUrl(path, options?.params);
82
83
  const headers = {
83
- "Authorization": `Bearer ${this.config.apiKey}`,
84
84
  "Content-Type": "application/json",
85
85
  "X-Trillboards-Client": `typescript-sdk/${VERSION}`,
86
86
  "User-Agent": `trillboards-typescript/${VERSION}`,
87
87
  ...options?.headers ?? {}
88
88
  };
89
+ const isPublic = PUBLIC_PATHS.some((prefix) => path.startsWith(prefix));
90
+ if (!isPublic && this.config.apiKey) {
91
+ headers["Authorization"] = `Bearer ${this.config.apiKey}`;
92
+ }
89
93
  if (this.config.version) {
90
94
  headers["Trillboards-Version"] = this.config.version;
91
95
  }
@@ -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/resources/data.ts","../src/resources/billing.ts","../src/client.ts","../src/webhooks.ts","../src/generated/index.ts"],"names":[],"mappings":";;;AAuBO,IAAM,gBAAA,GAAN,MAAM,iBAAA,SAAyB,KAAA,CAAM;AAAA,EAW1C,YAAY,IAAA,EAA+B;AACzC,IAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAClB,IAAA,IAAA,CAAK,IAAA,GAAO,kBAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,aAAa,IAAA,CAAK,UAAA;AACvB,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAK,KAAA,IAAS,IAAA;AAC3B,IAAA,IAAA,CAAK,SAAA,GAAY,KAAK,SAAA,IAAa,EAAA;AACnC,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,CAAA,wCAAA,EAA2C,KAAK,IAAI,CAAA,CAAA;AACnF,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,EAAC;AAChC,IAAA,IAAA,CAAK,IAAA,GAAO,KAAK,IAAA,IAAQ,IAAA;AACzB,IAAA,IAAA,CAAK,kBAAA,GAAqB,KAAK,iBAAA,IAAqB,IAAA;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,YAAA,CAAa,IAAA,EAAmD,QAAA,EAA+F;AACpK,IAAA,MAAM,QAAA,GAAY,MAA4B,KAAA,IAAS,IAAA;AACvD,IAAA,MAAM,OAAA,GAAU,QAAA;AAEhB,IAAA,MAAM,gBAAA,GAAmB,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAA;AAC3D,IAAA,IAAI,iBAAA,GAAmC,IAAA;AACvC,IAAA,IAAI,gBAAA,EAAkB;AACpB,MAAA,MAAM,MAAA,GAAS,QAAA,CAAS,gBAAA,EAAkB,EAAE,CAAA;AAC5C,MAAA,IAAI,CAAC,KAAA,CAAM,MAAM,CAAA,EAAG;AAClB,QAAA,iBAAA,GAAoB,MAAA;AAAA,MACtB;AAAA,IACF;AAEA,IAAA,OAAO,IAAI,iBAAA,CAAiB;AAAA,MAC1B,IAAA,EAAO,QAAQ,IAAA,IAAyB,WAAA;AAAA,MACxC,IAAA,EAAO,QAAQ,IAAA,IAAmB,eAAA;AAAA,MAClC,OAAA,EAAU,QAAQ,OAAA,IAAsB,4BAAA;AAAA,MACxC,YAAY,QAAA,CAAS,MAAA;AAAA,MACrB,KAAA,EAAQ,QAAQ,KAAA,IAA2B,IAAA;AAAA,MAC3C,SAAA,EAAY,QAAQ,UAAA,IAAyB,EAAA;AAAA,MAC7C,OAAA,EAAU,QAAQ,OAAA,IAAsB,MAAA;AAAA,MACxC,OAAA,EAAU,OAAA,CAAQ,OAAA,IAA6B,EAAC;AAAA,MAChD,IAAA,EAAO,QAAQ,IAAA,IAAoC,IAAA;AAAA,MACnD;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,IAAI,aAAA,GAAyB;AAC3B,IAAA,OAAO,KAAK,UAAA,KAAe,GAAA;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,UAAA,GAA4B;AAC9B,IAAA,OAAO,IAAA,CAAK,kBAAA;AAAA,EACd;AAAA;AAAA,EAGA,IAAI,WAAA,GAAuB;AACzB,IAAA,OAAO,KAAK,UAAA,KAAe,GAAA;AAAA,EAC7B;AAAA;AAAA,EAGA,IAAI,WAAA,GAAuB;AACzB,IAAA,OAAO,KAAK,UAAA,KAAe,GAAA;AAAA,EAC7B;AAAA;AAAA,EAGA,IAAI,aAAA,GAAyB;AAC3B,IAAA,OAAO,KAAK,UAAA,IAAc,GAAA;AAAA,EAC5B;AACF;;;ACvGO,IAAM,OAAA,GAAU;;;ACahB,IAAM,aAAN,MAAiB;AAAA,EAGtB,YAAY,MAAA,EAA0B;AACpC,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AAAA,EAEA,MAAM,OAAA,CAAW,MAAA,EAAgB,IAAA,EAAc,OAAA,EAAsC;AACnF,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,SAAS,MAAM,CAAA;AAE/C,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,eAAA,EAAiB,CAAA,OAAA,EAAU,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,CAAA;AAAA,MAC7C,cAAA,EAAgB,kBAAA;AAAA,MAChB,sBAAA,EAAwB,kBAAkB,OAAO,CAAA,CAAA;AAAA,MACjD,YAAA,EAAc,0BAA0B,OAAO,CAAA,CAAA;AAAA,MAC/C,GAAI,OAAA,EAAS,OAAA,IAAW;AAAC,KAC3B;AAEA,IAAA,IAAI,IAAA,CAAK,OAAO,OAAA,EAAS;AACvB,MAAA,OAAA,CAAQ,qBAAqB,CAAA,GAAI,IAAA,CAAK,MAAA,CAAO,OAAA;AAAA,IAC/C;AAEA,IAAA,MAAM,YAAA,GAAuC;AAAA,MAC3C,MAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,IAAI,OAAA,EAAS,IAAA,KAAS,MAAA,IAAa,OAAA,CAAQ,SAAS,IAAA,EAAM;AACxD,MAAA,YAAA,CAAa,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,IAAI,CAAA;AAAA,IACjD;AAEA,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK,YAAY,CAAA;AAG9C,IAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI;AACF,MAAA,IAAA,GAAO,MAAM,SAAS,IAAA,EAAK;AAAA,IAC7B,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,gBAAA,CAAiB;AAAA,QACzB,IAAA,EAAM,WAAA;AAAA,QACN,IAAA,EAAM,kBAAA;AAAA,QACN,OAAA,EAAS,CAAA,qCAAA,EAAwC,QAAA,CAAS,MAAM,CAAA,EAAA,CAAA;AAAA,QAChE,YAAY,QAAA,CAAS;AAAA,OACtB,CAAA;AAAA,IACH;AAEA,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,gBAAA,CAAiB,YAAA,CAAa,IAAA,EAA2B,QAAQ,CAAA;AAAA,IACzE;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,GAAA,CAAO,MAAc,IAAA,EAAyD;AAC5E,IAAA,OAAO,IAAA,CAAK,QAAW,KAAA,EAAO,IAAA,EAAM,EAAE,MAAA,EAAQ,IAAA,EAAM,QAAQ,CAAA;AAAA,EAC9D;AAAA,EAEA,IAAA,CAAQ,MAAc,IAAA,EAA4B;AAChD,IAAA,OAAO,KAAK,OAAA,CAAW,MAAA,EAAQ,IAAA,EAAM,EAAE,MAAM,CAAA;AAAA,EAC/C;AAAA,EAEA,GAAA,CAAO,MAAc,IAAA,EAA4B;AAC/C,IAAA,OAAO,KAAK,OAAA,CAAW,KAAA,EAAO,IAAA,EAAM,EAAE,MAAM,CAAA;AAAA,EAC9C;AAAA,EAEA,KAAA,CAAS,MAAc,IAAA,EAA4B;AACjD,IAAA,OAAO,KAAK,OAAA,CAAW,OAAA,EAAS,IAAA,EAAM,EAAE,MAAM,CAAA;AAAA,EAChD;AAAA,EAEA,OAAU,IAAA,EAA0B;AAClC,IAAA,OAAO,IAAA,CAAK,OAAA,CAAW,QAAA,EAAU,IAAI,CAAA;AAAA,EACvC;AAAA,EAEQ,QAAA,CAAS,MAAc,MAAA,EAA0C;AACvE,IAAA,MAAM,OAAO,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,OAAO,GAAG,IAAI,CAAA,CAAA;AAC1C,IAAA,IAAI,CAAC,MAAA,IAAU,MAAA,CAAO,KAAK,MAAM,CAAA,CAAE,WAAW,CAAA,EAAG;AAC/C,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,MAAM,YAAA,GAAe,IAAI,eAAA,EAAgB;AACzC,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AACjD,MAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AACzC,QAAA,YAAA,CAAa,GAAA,CAAI,GAAA,EAAK,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,MACrC;AAAA,IACF;AACA,IAAA,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,YAAA,CAAa,UAAU,CAAA,CAAA;AAAA,EAC3C;AACF,CAAA;;;AClGO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA,EAGhD,MAAM,KAAK,MAAA,EAA6E;AACtF,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAA0B,qBAAA,EAAuB,EAAE,QAAQ,CAAA;AAAA,EAC9E;AAAA;AAAA,EAGA,MAAM,IAAI,QAAA,EAA+D;AACvE,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAwC,CAAA,mBAAA,EAAsB,QAAQ,CAAA,CAAE,CAAA;AAAA,EAC3F;AAAA;AAAA,EAGA,MAAM,OAAO,IAAA,EAQmC;AAC9C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAyC,oBAAA,EAAsB,IAAI,CAAA;AAAA,EACtF;AAAA;AAAA,EAGA,MAAM,OAAO,QAAA,EAAiD;AAC5D,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,MAAA,CAA6B,CAAA,mBAAA,EAAsB,QAAQ,CAAA,CAAE,CAAA;AAAA,EAChF;AACF;;;AC9BO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA,EAGhD,MAAM,KAAK,MAAA,EAA6E;AACtF,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAA0B,qBAAA,EAAuB,EAAE,QAAQ,CAAA;AAAA,EAC9E;AAAA;AAAA,EAGA,MAAM,IAAI,QAAA,EAA+D;AACvE,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAwC,CAAA,mBAAA,EAAsB,QAAQ,CAAA,CAAE,CAAA;AAAA,EAC3F;AAAA;AAAA,EAGA,MAAM,OAAO,IAAA,EAImC;AAC9C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAAyC,oBAAA,EAAsB,IAAI,CAAA;AAAA,EACtF;AAAA;AAAA,EAGA,MAAM,OAAO,QAAA,EAAiD;AAC5D,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,MAAA,CAA6B,CAAA,mBAAA,EAAsB,QAAQ,CAAA,CAAE,CAAA;AAAA,EAChF;AAAA;AAAA,EAGA,MAAM,SAAA,CAAU,QAAA,EAAkB,IAAA,EAA+D;AAC/F,IAAA,OAAO,IAAA,CAAK,KAAK,IAAA,CAA2B,CAAA,mBAAA,EAAsB,QAAQ,CAAA,UAAA,CAAA,EAAc,IAAA,IAAQ,EAAE,CAAA;AAAA,EACpG;AACF;;;AC/BO,IAAM,oBAAN,MAAwB;AAAA,EAC7B,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA,EAGhD,MAAM,OAAO,IAAA,EAMuC;AAClD,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAA6C,wBAAA,EAA0B,IAAI,CAAA;AAAA,EAC9F;AAAA;AAAA,EAGA,MAAM,YAAY,IAAA,EAS+B;AAC/C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAA0C,+BAAA,EAAiC,IAAI,CAAA;AAAA,EAClG;AACF;;;AC3BO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA,EAGhD,MAAM,IAAI,MAAA,EAK6C;AACrD,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAA+C,uBAAA,EAAyB,EAAE,QAAQ,CAAA;AAAA,EACrG;AACF;;;ACZO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA,EAGhD,MAAM,IAAI,MAAA,EAI4C;AACpD,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAA8C,8BAAA,EAAgC,EAAE,QAAQ,CAAA;AAAA,EAC3G;AACF;;;ACXO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA,EAGhD,MAAM,KAAK,MAAA,EAK2B;AACpC,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAA8B,mBAAA,EAAqB,EAAE,QAAQ,CAAA;AAAA,EAChF;AAAA;AAAA,EAGA,MAAM,IAAI,SAAA,EAAoE;AAC5E,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAA4C,CAAA,iBAAA,CAAA,EAAqB;AAAA,MAChF,MAAA,EAAQ,EAAE,UAAA,EAAY,SAAA;AAAU,KACjC,CAAA;AAAA,EACH;AACF;;;ACnBO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA,EAGhD,MAAM,IAAA,GAAuC;AAC3C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAA2B,sBAAsB,CAAA;AAAA,EACpE;AAAA;AAAA,EAGA,MAAM,OAAO,IAAA,EAGoC;AAC/C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAA0C,sBAAA,EAAwB,IAAI,CAAA;AAAA,EACzF;AAAA;AAAA,EAGA,MAAM,MAAA,CAAO,SAAA,EAAmB,IAAA,EAIiB;AAC/C,IAAA,OAAO,KAAK,IAAA,CAAK,KAAA,CAA2C,CAAA,qBAAA,EAAwB,SAAS,IAAI,IAAI,CAAA;AAAA,EACvG;AAAA;AAAA,EAGA,MAAM,OAAO,SAAA,EAAkD;AAC7D,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,MAAA,CAA6B,CAAA,qBAAA,EAAwB,SAAS,CAAA,CAAE,CAAA;AAAA,EACnF;AAAA;AAAA,EAGA,MAAM,KAAK,SAAA,EAAkD;AAC3D,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAA2B,CAAA,qBAAA,EAAwB,SAAS,CAAA,KAAA,CAAO,CAAA;AAAA,EACtF;AACF;;;AClCO,IAAM,cAAN,MAAkB;AAAA,EACvB,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA,EAGhD,MAAM,YAAY,IAAA,EAMoC;AACpD,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,IAAA,CAA+C,2BAAA,EAA6B,IAAI,CAAA;AAAA,EACnG;AAAA;AAAA,EAGA,MAAM,aAAa,MAAA,EAAmF;AACpG,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAgC,4BAAA,EAA8B,EAAE,QAAQ,CAAA;AAAA,EAC3F;AACF;;;AClBO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA,EAGhD,MAAM,QAAQ,QAAA,EAAqE;AACjF,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAA8C,CAAA,0BAAA,EAA6B,QAAQ,CAAA,CAAE,CAAA;AAAA,EACxG;AAAA;AAAA,EAGA,MAAM,WAAW,MAAA,EAIgD;AAC/D,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAyD,8BAAA,EAAgC,EAAE,QAAQ,CAAA;AAAA,EACtH;AAAA;AAAA,EAGA,MAAM,SAAS,MAAA,EAEkD;AAC/D,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAyD,4BAAA,EAA8B,EAAE,QAAQ,CAAA;AAAA,EACpH;AACF;;;ACxBO,IAAM,aAAN,MAAiB;AAAA,EACtB,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA,EAGhD,MAAM,qBAAqB,QAAA,EAAgF;AACzG,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAyD,CAAA,kBAAA,EAAqB,QAAQ,CAAA,CAAE,CAAA;AAAA,EAC3G;AAAA;AAAA,EAGA,MAAM,SAAS,MAAA,EAEkD;AAC/D,IAAA,OAAO,KAAK,IAAA,CAAK,GAAA,CAAyD,mBAAA,EAAqB,EAAE,QAAQ,CAAA;AAAA,EAC3G;AACF;;;ACbO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAA6B,IAAA,EAAkB;AAAlB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAAmB;AAAA;AAAA,EAGhD,MAAM,GAAA,GAAwD;AAC5D,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAA6C,qBAAqB,CAAA;AAAA,EACrF;AAAA;AAAA,EAGA,MAAM,eAAA,GAAgF;AACpF,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,CAAyD,2BAA2B,CAAA;AAAA,EACvG;AAAA;AAAA,EAGA,MAAM,cAAc,IAAA,EAE6C;AAC/D,IAAA,OAAO,KAAK,IAAA,CAAK,IAAA,CAA0D,2BAAA,EAA6B,IAAA,IAAQ,EAAE,CAAA;AAAA,EACpH;AACF;;;ACFA,IAAM,gBAAA,GAAmB,6BAAA;AAElB,IAAM,oBAAN,MAAwB;AAAA,EAgB7B,YAAY,OAAA,EAAwB;AAClC,IAAA,IAAI,CAAC,QAAQ,MAAA,EAAQ;AACnB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,WAAW,OAAA,CAAQ,OAAA,IAAW,gBAAA,EAAkB,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAExE,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAI,UAAA,CAAW;AAAA,MAC1B,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,OAAA;AAAA,MACA,SAAS,OAAA,CAAQ;AAAA,KAClB,CAAA;AAED,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,aAAA,CAAc,IAAA,CAAK,KAAK,CAAA;AAC3C,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,aAAA,CAAc,IAAA,CAAK,KAAK,CAAA;AAC3C,IAAA,IAAA,CAAK,WAAA,GAAc,IAAI,iBAAA,CAAkB,IAAA,CAAK,KAAK,CAAA;AACnD,IAAA,IAAA,CAAK,SAAA,GAAY,IAAI,eAAA,CAAgB,IAAA,CAAK,KAAK,CAAA;AAC/C,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,cAAA,CAAe,IAAA,CAAK,KAAK,CAAA;AAC7C,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,cAAA,CAAe,IAAA,CAAK,KAAK,CAAA;AAC7C,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAI,WAAA,CAAY,IAAA,CAAK,KAAK,CAAA;AACvC,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,cAAA,CAAe,IAAA,CAAK,KAAK,CAAA;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,IAAI,UAAA,CAAW,IAAA,CAAK,KAAK,CAAA;AACrC,IAAA,IAAA,CAAK,MAAA,GAAS,IAAI,YAAA,CAAa,IAAA,CAAK,KAAK,CAAA;AACzC,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,aAAA,CAAc,IAAA,CAAK,KAAK,CAAA;AAAA,EAC7C;AACF;ACpCO,SAAS,cAAA,CACd,OAAA,EACA,SAAA,EACA,MAAA,EACc;AACd,EAAA,MAAM,aAAa,OAAO,OAAA,KAAY,WAAW,OAAA,GAAU,OAAA,CAAQ,SAAS,MAAM,CAAA;AAElF,EAAA,MAAM,iBAAA,GAAoB,WAAW,QAAA,EAAU,MAAM,EAClD,MAAA,CAAO,UAAU,CAAA,CACjB,MAAA,CAAO,KAAK,CAAA;AAEf,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,IAAA,CAAK,SAAA,EAAW,MAAM,CAAA;AAC/C,EAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,IAAA,CAAK,iBAAA,EAAmB,MAAM,CAAA;AAE5D,EAAA,IAAI,SAAA,CAAU,WAAW,cAAA,CAAe,MAAA,IAAU,CAAC,eAAA,CAAgB,SAAA,EAAW,cAAc,CAAA,EAAG;AAC7F,IAAA,MAAM,IAAI,gBAAA,CAAiB;AAAA,MACzB,IAAA,EAAM,sBAAA;AAAA,MACN,IAAA,EAAM,2BAAA;AAAA,MACN,OAAA,EAAS,iFAAA;AAAA,MACT,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,IAAA,CAAK,MAAM,UAAU,CAAA;AAC9B;AAEO,IAAM,QAAA,GAAW,EAAE,cAAA;;;ACvDnB,IAAM,iBAAiB","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 * Keep in sync with package.json version.\n */\nexport const VERSION = '0.1.0';\n","/**\n * Internal HTTP client for the Trillboards API.\n *\n * Uses native fetch (Node 18+). Zero runtime dependencies.\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 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 url = this.buildUrl(path, options?.params);\n\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.config.apiKey}`,\n 'Content-Type': 'application/json',\n 'X-Trillboards-Client': `typescript-sdk/${VERSION}`,\n 'User-Agent': `trillboards-typescript/${VERSION}`,\n ...(options?.headers ?? {}),\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 const response = await fetch(url, fetchOptions);\n\n // Handle 204 No Content\n if (response.status === 204) {\n return undefined as T;\n }\n\n let json: unknown;\n try {\n json = await response.json();\n } catch {\n throw new TrillboardsError({\n type: 'api_error',\n code: 'invalid_response',\n message: `Invalid JSON response from API (HTTP ${response.status}).`,\n statusCode: response.status,\n });\n }\n\n if (!response.ok) {\n throw TrillboardsError.fromResponse(json as ErrorResponseBody, response);\n }\n\n return json as T;\n }\n\n get<T>(path: string, opts?: { params?: Record<string, unknown> }): Promise<T> {\n return this.request<T>('GET', path, { params: opts?.params });\n }\n\n post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('POST', path, { body });\n }\n\n put<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('PUT', path, { body });\n }\n\n patch<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('PATCH', path, { body });\n }\n\n delete<T>(path: string): Promise<T> {\n return this.request<T>('DELETE', path);\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, Screen } from '../types';\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: {\n device_name: string;\n device_type?: string;\n venue_type?: string;\n country?: string;\n city?: string;\n timezone?: string;\n resolution?: string;\n }): Promise<{ success: boolean; data: Screen }> {\n return this.http.post<{ success: boolean; data: Screen }>('/v1/partner/device', body);\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 } from '../http';\nimport type { Device, ListResponse } from '../types';\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: {\n device_name: string;\n device_type?: string;\n platform?: string;\n }): Promise<{ success: boolean; data: Device }> {\n return this.http.post<{ success: boolean; data: Device }>('/v1/partner/device', 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 /** Send heartbeat for a device. */\n async heartbeat(deviceId: string, body?: Record<string, unknown>): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(`/v1/partner/device/${deviceId}/heartbeat`, body ?? {});\n }\n}\n","/**\n * ImpressionsClient — impression tracking.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { Impression } from '../types';\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 '../types';\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 '../types';\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 — query the partner error log.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { ErrorEntry, ListResponse } from '../types';\n\nexport class ErrorsClient {\n constructor(private readonly http: HttpClient) {}\n\n /** List recent errors for this partner. */\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/partner/usage', { params });\n }\n\n /** Get a single error by request_id. */\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, Webhook } from '../types';\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 /** Create a new webhook subscription. */\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 { FleetCommand, ListResponse } from '../types';\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 '../types';\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","/**\n * DataClient — data export and venue intelligence.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\n\nexport class DataClient {\n constructor(private readonly http: HttpClient) {}\n\n /** Get venue intelligence data for a screen. */\n async getVenueIntelligence(screenId: string): Promise<{ success: boolean; data: Record<string, unknown> }> {\n return this.http.get<{ success: boolean; data: Record<string, unknown> }>(`/v1/partner/venue/${screenId}`);\n }\n\n /** Get API usage summary. */\n async getUsage(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/usage', { params });\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 } from '../types';\n\nexport class BillingClient {\n constructor(private readonly http: HttpClient) {}\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 * 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} 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\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 }\n}\n","/**\n * Webhook signature verification for Trillboards Partner API webhooks.\n *\n * Uses HMAC-SHA256 with timing-safe comparison to prevent signature\n * forgery and timing attacks.\n */\n\nimport { createHmac, timingSafeEqual } from 'crypto';\nimport { TrillboardsError } from './error';\nimport type { WebhookEvent } from './types';\n\n/**\n * Verify a webhook payload signature and parse the event.\n *\n * @param payload - Raw request body as string or Buffer.\n * @param signature - The signature from the `X-Trillboards-Signature` header.\n * @param secret - The webhook secret from your webhook subscription.\n * @returns The parsed WebhookEvent if signature is valid.\n * @throws TrillboardsError if the signature does not match.\n *\n * @example\n * ```typescript\n * import { Webhooks } from '@trillboards/api-client';\n *\n * app.post('/webhooks', (req, res) => {\n * const event = Webhooks.constructEvent(\n * req.body,\n * req.headers['x-trillboards-signature'],\n * process.env.WEBHOOK_SECRET\n * );\n * console.log('Received event:', event.type);\n * res.sendStatus(200);\n * });\n * ```\n */\nexport function constructEvent(\n payload: string | Buffer,\n signature: string,\n secret: string,\n): WebhookEvent {\n const payloadStr = typeof payload === 'string' ? payload : payload.toString('utf8');\n\n const expectedSignature = createHmac('sha256', secret)\n .update(payloadStr)\n .digest('hex');\n\n const sigBuffer = Buffer.from(signature, 'utf8');\n const expectedBuffer = Buffer.from(expectedSignature, 'utf8');\n\n if (sigBuffer.length !== expectedBuffer.length || !timingSafeEqual(sigBuffer, expectedBuffer)) {\n throw new TrillboardsError({\n type: 'authentication_error',\n code: 'webhook_signature_invalid',\n message: 'Webhook signature verification failed. The payload may have been tampered with.',\n statusCode: 401,\n });\n }\n\n return JSON.parse(payloadStr) as WebhookEvent;\n}\n\nexport const Webhooks = { constructEvent };\n","// Auto-generated from OpenAPI specs — run npm run generate to populate\n//\n// This directory will contain auto-generated TypeScript types derived from\n// trillboard-api/docs/openapi/partner-api.yaml and the generated fragments\n// at trillboard-api/docs/openapi/generated/partner-api-generated.json.\n\nexport const generatedTypes = {} as const;\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/resources/data.ts","../src/resources/billing.ts","../src/client.ts","../src/webhooks.ts","../src/generated/index.ts"],"names":[],"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 * Keep in sync with package.json version.\n */\nexport const VERSION = '0.1.2';\n","/**\n * Internal HTTP client for the Trillboards API.\n *\n * Uses native fetch (Node 18+). Zero runtime dependencies.\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\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\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 url = this.buildUrl(path, options?.params);\n\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\n const isPublic = PUBLIC_PATHS.some(prefix => path.startsWith(prefix));\n if (!isPublic && this.config.apiKey) {\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 const response = await fetch(url, fetchOptions);\n\n // Handle 204 No Content\n if (response.status === 204) {\n return undefined as T;\n }\n\n let json: unknown;\n try {\n json = await response.json();\n } catch {\n throw new TrillboardsError({\n type: 'api_error',\n code: 'invalid_response',\n message: `Invalid JSON response from API (HTTP ${response.status}).`,\n statusCode: response.status,\n });\n }\n\n if (!response.ok) {\n throw TrillboardsError.fromResponse(json as ErrorResponseBody, response);\n }\n\n return json as T;\n }\n\n get<T>(path: string, opts?: { params?: Record<string, unknown> }): Promise<T> {\n return this.request<T>('GET', path, { params: opts?.params });\n }\n\n post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('POST', path, { body });\n }\n\n put<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('PUT', path, { body });\n }\n\n patch<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('PATCH', path, { body });\n }\n\n delete<T>(path: string): Promise<T> {\n return this.request<T>('DELETE', path);\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, Screen } from '../types';\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: {\n device_name: string;\n device_type?: string;\n venue_type?: string;\n country?: string;\n city?: string;\n timezone?: string;\n resolution?: string;\n }): Promise<{ success: boolean; data: Screen }> {\n return this.http.post<{ success: boolean; data: Screen }>('/v1/partner/device', body);\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 } from '../http';\nimport type { Device, ListResponse } from '../types';\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: {\n device_name: string;\n device_type?: string;\n platform?: string;\n }): Promise<{ success: boolean; data: Device }> {\n return this.http.post<{ success: boolean; data: Device }>('/v1/partner/device', 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 /** Send heartbeat for a device. */\n async heartbeat(deviceId: string, body?: Record<string, unknown>): Promise<{ success: boolean }> {\n return this.http.post<{ success: boolean }>(`/v1/partner/device/${deviceId}/heartbeat`, body ?? {});\n }\n}\n","/**\n * ImpressionsClient — impression tracking.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { Impression } from '../types';\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 '../types';\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 '../types';\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 — query the partner error log.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { ErrorEntry, ListResponse } from '../types';\n\nexport class ErrorsClient {\n constructor(private readonly http: HttpClient) {}\n\n /** List recent errors for this partner. */\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/partner/usage', { params });\n }\n\n /** Get a single error by request_id. */\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, Webhook } from '../types';\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 /** Create a new webhook subscription. */\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 { FleetCommand, ListResponse } from '../types';\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 '../types';\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","/**\n * DataClient — data export and venue intelligence.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\n\nexport class DataClient {\n constructor(private readonly http: HttpClient) {}\n\n /** Get venue intelligence data for a screen. */\n async getVenueIntelligence(screenId: string): Promise<{ success: boolean; data: Record<string, unknown> }> {\n return this.http.get<{ success: boolean; data: Record<string, unknown> }>(`/v1/partner/venue/${screenId}`);\n }\n\n /** Get API usage summary. */\n async getUsage(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/usage', { params });\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 } from '../types';\n\nexport class BillingClient {\n constructor(private readonly http: HttpClient) {}\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 * 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} 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\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 }\n}\n","/**\n * Webhook signature verification for Trillboards Partner API webhooks.\n *\n * Uses HMAC-SHA256 with timing-safe comparison to prevent signature\n * forgery and timing attacks.\n */\n\nimport { createHmac, timingSafeEqual } from 'crypto';\nimport { TrillboardsError } from './error';\nimport type { WebhookEvent } from './types';\n\n/**\n * Verify a webhook payload signature and parse the event.\n *\n * @param payload - Raw request body as string or Buffer.\n * @param signature - The signature from the `X-Trillboards-Signature` header.\n * @param secret - The webhook secret from your webhook subscription.\n * @returns The parsed WebhookEvent if signature is valid.\n * @throws TrillboardsError if the signature does not match.\n *\n * @example\n * ```typescript\n * import { Webhooks } from '@trillboards/api-client';\n *\n * app.post('/webhooks', (req, res) => {\n * const event = Webhooks.constructEvent(\n * req.body,\n * req.headers['x-trillboards-signature'],\n * process.env.WEBHOOK_SECRET\n * );\n * console.log('Received event:', event.type);\n * res.sendStatus(200);\n * });\n * ```\n */\nexport function constructEvent(\n payload: string | Buffer,\n signature: string,\n secret: string,\n): WebhookEvent {\n const payloadStr = typeof payload === 'string' ? payload : payload.toString('utf8');\n\n const expectedSignature = createHmac('sha256', secret)\n .update(payloadStr)\n .digest('hex');\n\n const sigBuffer = Buffer.from(signature, 'utf8');\n const expectedBuffer = Buffer.from(expectedSignature, 'utf8');\n\n if (sigBuffer.length !== expectedBuffer.length || !timingSafeEqual(sigBuffer, expectedBuffer)) {\n throw new TrillboardsError({\n type: 'authentication_error',\n code: 'webhook_signature_invalid',\n message: 'Webhook signature verification failed. The payload may have been tampered with.',\n statusCode: 401,\n });\n }\n\n return JSON.parse(payloadStr) as WebhookEvent;\n}\n\nexport const Webhooks = { constructEvent };\n","// Auto-generated from OpenAPI specs — run npm run generate to populate\n//\n// This directory will contain auto-generated TypeScript types derived from\n// trillboard-api/docs/openapi/partner-api.yaml and the generated fragments\n// at trillboard-api/docs/openapi/generated/partner-api-generated.json.\n\nexport const generatedTypes = {} as const;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trillboards/api-client",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Official TypeScript SDK for the Trillboards DOOH Partner API",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",