@trillboards/api-client 0.1.1 → 0.1.3
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 +9 -5
- package/dist/index.d.ts +9 -5
- package/dist/index.js +12 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +12 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -341,22 +341,26 @@ declare class EarningsClient {
|
|
|
341
341
|
}
|
|
342
342
|
|
|
343
343
|
/**
|
|
344
|
-
* ErrorsClient —
|
|
344
|
+
* ErrorsClient — access the public error catalog and query partner errors.
|
|
345
345
|
*
|
|
346
|
-
*
|
|
346
|
+
* list() hits /v1/errors (public, no auth required).
|
|
347
|
+
* get() hits /v1/partner/usage (authenticated, partner-scoped).
|
|
347
348
|
*/
|
|
348
349
|
|
|
349
350
|
declare class ErrorsClient {
|
|
350
351
|
private readonly http;
|
|
351
352
|
constructor(http: HttpClient);
|
|
352
|
-
/**
|
|
353
|
+
/**
|
|
354
|
+
* List all known API error codes from the public error catalog.
|
|
355
|
+
* This endpoint does NOT require authentication.
|
|
356
|
+
*/
|
|
353
357
|
list(params?: {
|
|
354
358
|
limit?: number;
|
|
355
359
|
offset?: number;
|
|
356
360
|
code?: string;
|
|
357
361
|
type?: string;
|
|
358
362
|
}): Promise<ListResponse<ErrorEntry>>;
|
|
359
|
-
/** Get a single error by request_id. */
|
|
363
|
+
/** Get a single error by request_id (requires authentication). */
|
|
360
364
|
get(requestId: string): Promise<{
|
|
361
365
|
success: boolean;
|
|
362
366
|
data: ErrorEntry;
|
|
@@ -635,7 +639,7 @@ declare const Webhooks: {
|
|
|
635
639
|
* SDK version constant. Sent in User-Agent and X-Trillboards-Client headers.
|
|
636
640
|
* Keep in sync with package.json version.
|
|
637
641
|
*/
|
|
638
|
-
declare const VERSION = "0.1.
|
|
642
|
+
declare const VERSION = "0.1.3";
|
|
639
643
|
|
|
640
644
|
declare const generatedTypes: {};
|
|
641
645
|
|
package/dist/index.d.ts
CHANGED
|
@@ -341,22 +341,26 @@ declare class EarningsClient {
|
|
|
341
341
|
}
|
|
342
342
|
|
|
343
343
|
/**
|
|
344
|
-
* ErrorsClient —
|
|
344
|
+
* ErrorsClient — access the public error catalog and query partner errors.
|
|
345
345
|
*
|
|
346
|
-
*
|
|
346
|
+
* list() hits /v1/errors (public, no auth required).
|
|
347
|
+
* get() hits /v1/partner/usage (authenticated, partner-scoped).
|
|
347
348
|
*/
|
|
348
349
|
|
|
349
350
|
declare class ErrorsClient {
|
|
350
351
|
private readonly http;
|
|
351
352
|
constructor(http: HttpClient);
|
|
352
|
-
/**
|
|
353
|
+
/**
|
|
354
|
+
* List all known API error codes from the public error catalog.
|
|
355
|
+
* This endpoint does NOT require authentication.
|
|
356
|
+
*/
|
|
353
357
|
list(params?: {
|
|
354
358
|
limit?: number;
|
|
355
359
|
offset?: number;
|
|
356
360
|
code?: string;
|
|
357
361
|
type?: string;
|
|
358
362
|
}): Promise<ListResponse<ErrorEntry>>;
|
|
359
|
-
/** Get a single error by request_id. */
|
|
363
|
+
/** Get a single error by request_id (requires authentication). */
|
|
360
364
|
get(requestId: string): Promise<{
|
|
361
365
|
success: boolean;
|
|
362
366
|
data: ErrorEntry;
|
|
@@ -635,7 +639,7 @@ declare const Webhooks: {
|
|
|
635
639
|
* SDK version constant. Sent in User-Agent and X-Trillboards-Client headers.
|
|
636
640
|
* Keep in sync with package.json version.
|
|
637
641
|
*/
|
|
638
|
-
declare const VERSION = "0.1.
|
|
642
|
+
declare const VERSION = "0.1.3";
|
|
639
643
|
|
|
640
644
|
declare const generatedTypes: {};
|
|
641
645
|
|
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.
|
|
75
|
+
var VERSION = "0.1.3";
|
|
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
|
}
|
|
@@ -240,11 +244,14 @@ var ErrorsClient = class {
|
|
|
240
244
|
constructor(http) {
|
|
241
245
|
this.http = http;
|
|
242
246
|
}
|
|
243
|
-
/**
|
|
247
|
+
/**
|
|
248
|
+
* List all known API error codes from the public error catalog.
|
|
249
|
+
* This endpoint does NOT require authentication.
|
|
250
|
+
*/
|
|
244
251
|
async list(params) {
|
|
245
|
-
return this.http.get("/v1/
|
|
252
|
+
return this.http.get("/v1/errors", { params });
|
|
246
253
|
}
|
|
247
|
-
/** Get a single error by request_id. */
|
|
254
|
+
/** Get a single error by request_id (requires authentication). */
|
|
248
255
|
async get(requestId) {
|
|
249
256
|
return this.http.get(`/v1/partner/usage`, {
|
|
250
257
|
params: { request_id: requestId }
|
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.3';\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 — access the public error catalog and query partner errors.\n *\n * list() hits /v1/errors (public, no auth required).\n * get() hits /v1/partner/usage (authenticated, partner-scoped).\n */\n\nimport type { HttpClient } from '../http';\nimport type { ErrorEntry, ListResponse } from '../types';\n\nexport class ErrorsClient {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all known API error codes from the public error catalog.\n * This endpoint does NOT require authentication.\n */\n async list(params?: {\n limit?: number;\n offset?: number;\n code?: string;\n type?: string;\n }): Promise<ListResponse<ErrorEntry>> {\n return this.http.get<ListResponse<ErrorEntry>>('/v1/errors', { params });\n }\n\n /** Get a single error by request_id (requires authentication). */\n async get(requestId: string): Promise<{ success: boolean; data: ErrorEntry }> {\n return this.http.get<{ success: boolean; data: ErrorEntry }>(`/v1/partner/usage`, {\n params: { request_id: requestId },\n });\n }\n}\n","/**\n * WebhooksClient — webhook subscription management.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { ListResponse, 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.
|
|
73
|
+
var VERSION = "0.1.3";
|
|
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
|
}
|
|
@@ -238,11 +242,14 @@ var ErrorsClient = class {
|
|
|
238
242
|
constructor(http) {
|
|
239
243
|
this.http = http;
|
|
240
244
|
}
|
|
241
|
-
/**
|
|
245
|
+
/**
|
|
246
|
+
* List all known API error codes from the public error catalog.
|
|
247
|
+
* This endpoint does NOT require authentication.
|
|
248
|
+
*/
|
|
242
249
|
async list(params) {
|
|
243
|
-
return this.http.get("/v1/
|
|
250
|
+
return this.http.get("/v1/errors", { params });
|
|
244
251
|
}
|
|
245
|
-
/** Get a single error by request_id. */
|
|
252
|
+
/** Get a single error by request_id (requires authentication). */
|
|
246
253
|
async get(requestId) {
|
|
247
254
|
return this.http.get(`/v1/partner/usage`, {
|
|
248
255
|
params: { request_id: requestId }
|
package/dist/index.mjs.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":[],"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.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.3';\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 — access the public error catalog and query partner errors.\n *\n * list() hits /v1/errors (public, no auth required).\n * get() hits /v1/partner/usage (authenticated, partner-scoped).\n */\n\nimport type { HttpClient } from '../http';\nimport type { ErrorEntry, ListResponse } from '../types';\n\nexport class ErrorsClient {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List all known API error codes from the public error catalog.\n * This endpoint does NOT require authentication.\n */\n async list(params?: {\n limit?: number;\n offset?: number;\n code?: string;\n type?: string;\n }): Promise<ListResponse<ErrorEntry>> {\n return this.http.get<ListResponse<ErrorEntry>>('/v1/errors', { params });\n }\n\n /** Get a single error by request_id (requires authentication). */\n async get(requestId: string): Promise<{ success: boolean; data: ErrorEntry }> {\n return this.http.get<{ success: boolean; data: ErrorEntry }>(`/v1/partner/usage`, {\n params: { request_id: requestId },\n });\n }\n}\n","/**\n * WebhooksClient — webhook subscription management.\n *\n * Base path: /v1/partner\n */\n\nimport type { HttpClient } from '../http';\nimport type { ListResponse, 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"]}
|