@trillboards/ads-sdk 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/README.md +158 -0
- package/dist/index.d.mts +602 -0
- package/dist/index.d.ts +602 -0
- package/dist/index.js +1752 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1739 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react-native.d.mts +154 -0
- package/dist/react-native.d.ts +154 -0
- package/dist/react-native.js +193 -0
- package/dist/react-native.js.map +1 -0
- package/dist/react-native.mjs +190 -0
- package/dist/react-native.mjs.map +1 -0
- package/dist/react.d.mts +239 -0
- package/dist/react.d.ts +239 -0
- package/dist/react.js +1891 -0
- package/dist/react.js.map +1 -0
- package/dist/react.mjs +1885 -0
- package/dist/react.mjs.map +1 -0
- package/dist/server.d.mts +238 -0
- package/dist/server.d.ts +238 -0
- package/dist/server.js +209 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +200 -0
- package/dist/server.mjs.map +1 -0
- package/dist/trillboards-lite.global.js +2 -0
- package/dist/trillboards-lite.global.js.map +1 -0
- package/package.json +109 -0
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
interface VastTagBuilderConfig {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
apiBase?: string;
|
|
4
|
+
}
|
|
5
|
+
interface BuildTagOptions {
|
|
6
|
+
deviceId: string;
|
|
7
|
+
width?: number;
|
|
8
|
+
height?: number;
|
|
9
|
+
orientation?: 'portrait' | 'landscape';
|
|
10
|
+
muted?: boolean;
|
|
11
|
+
autoplay?: boolean;
|
|
12
|
+
userAgent?: string;
|
|
13
|
+
}
|
|
14
|
+
interface VastTagResult {
|
|
15
|
+
url: string;
|
|
16
|
+
sources: Array<{
|
|
17
|
+
name: string;
|
|
18
|
+
vast_url: string;
|
|
19
|
+
priority: number;
|
|
20
|
+
timeout_ms: number;
|
|
21
|
+
}>;
|
|
22
|
+
auctionWinner?: {
|
|
23
|
+
source: string;
|
|
24
|
+
bid_price_cpm: number;
|
|
25
|
+
vast_url: string;
|
|
26
|
+
} | null;
|
|
27
|
+
}
|
|
28
|
+
declare class VastTagBuilder {
|
|
29
|
+
private authFetch;
|
|
30
|
+
constructor(config: VastTagBuilderConfig);
|
|
31
|
+
buildTag(options: BuildTagOptions): Promise<VastTagResult>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface TrackingBatchConfig {
|
|
35
|
+
apiKey: string;
|
|
36
|
+
apiBase?: string;
|
|
37
|
+
}
|
|
38
|
+
interface ImpressionReport {
|
|
39
|
+
adId: string;
|
|
40
|
+
impressionId: string;
|
|
41
|
+
deviceId: string;
|
|
42
|
+
screenId?: string;
|
|
43
|
+
duration: number;
|
|
44
|
+
completed: boolean;
|
|
45
|
+
timestamp: string;
|
|
46
|
+
}
|
|
47
|
+
interface TrackingResult {
|
|
48
|
+
success: boolean;
|
|
49
|
+
tracked: number;
|
|
50
|
+
proofs: Array<{
|
|
51
|
+
impressionId: string;
|
|
52
|
+
proof: string;
|
|
53
|
+
publicKeyUrl: string;
|
|
54
|
+
}>;
|
|
55
|
+
}
|
|
56
|
+
declare class TrackingBatch {
|
|
57
|
+
private apiBase;
|
|
58
|
+
private authFetch;
|
|
59
|
+
constructor(config: TrackingBatchConfig);
|
|
60
|
+
report(impressions: ImpressionReport[]): Promise<TrackingResult>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
interface LiveAudience {
|
|
64
|
+
face_count: number;
|
|
65
|
+
attention_score: number;
|
|
66
|
+
mood: string | null;
|
|
67
|
+
income_level: string | null;
|
|
68
|
+
purchase_intent: number | null;
|
|
69
|
+
dwell_time_ms: number | null;
|
|
70
|
+
timestamp: string;
|
|
71
|
+
}
|
|
72
|
+
interface AudiencePrediction {
|
|
73
|
+
predicted_face_count: number;
|
|
74
|
+
predicted_attention_score: number;
|
|
75
|
+
predicted_mood: string | null;
|
|
76
|
+
confidence: number;
|
|
77
|
+
hour: number;
|
|
78
|
+
dayOfWeek: number;
|
|
79
|
+
}
|
|
80
|
+
interface LookalikeScreen {
|
|
81
|
+
screenId: string;
|
|
82
|
+
similarity: number;
|
|
83
|
+
audience_profile: Record<string, unknown>;
|
|
84
|
+
}
|
|
85
|
+
declare class AudienceClient {
|
|
86
|
+
private authFetch;
|
|
87
|
+
constructor(apiKey: string, apiBase: string);
|
|
88
|
+
getLive(screenId: string): Promise<LiveAudience>;
|
|
89
|
+
predict(screenId: string, options: {
|
|
90
|
+
hour: number;
|
|
91
|
+
dayOfWeek: number;
|
|
92
|
+
}): Promise<AudiencePrediction>;
|
|
93
|
+
findLookalikes(screenId: string, options?: {
|
|
94
|
+
limit?: number;
|
|
95
|
+
minSimilarity?: number;
|
|
96
|
+
}): Promise<LookalikeScreen[]>;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
interface ScreenDailyAnalytics {
|
|
100
|
+
date: string;
|
|
101
|
+
ads: {
|
|
102
|
+
plays_started: number;
|
|
103
|
+
plays_completed: number;
|
|
104
|
+
completion_rate: number;
|
|
105
|
+
programmatic_plays: number;
|
|
106
|
+
direct_plays: number;
|
|
107
|
+
};
|
|
108
|
+
audience: {
|
|
109
|
+
avg_face_count: number;
|
|
110
|
+
avg_attention_score: number;
|
|
111
|
+
peak_viewers: number;
|
|
112
|
+
};
|
|
113
|
+
earnings: {
|
|
114
|
+
programmatic_cents: number;
|
|
115
|
+
direct_cents: number;
|
|
116
|
+
total_cents: number;
|
|
117
|
+
};
|
|
118
|
+
streaming: {
|
|
119
|
+
seconds: number;
|
|
120
|
+
uptime_percentage: number;
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
interface EarningsData {
|
|
124
|
+
screenId: string;
|
|
125
|
+
period: string;
|
|
126
|
+
impressions_count: number;
|
|
127
|
+
cpm_rate: number;
|
|
128
|
+
gross_revenue: number;
|
|
129
|
+
earner_revenue: number;
|
|
130
|
+
earner_share_rate: number;
|
|
131
|
+
}
|
|
132
|
+
declare class AnalyticsClient {
|
|
133
|
+
private authFetch;
|
|
134
|
+
constructor(apiKey: string, apiBase: string);
|
|
135
|
+
getScreenDaily(screenId: string, options: {
|
|
136
|
+
startDate: string;
|
|
137
|
+
endDate: string;
|
|
138
|
+
}): Promise<ScreenDailyAnalytics[]>;
|
|
139
|
+
getEarnings(options?: {
|
|
140
|
+
screenId?: string;
|
|
141
|
+
startDate?: string;
|
|
142
|
+
endDate?: string;
|
|
143
|
+
}): Promise<EarningsData[]>;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
interface AuctionResult {
|
|
147
|
+
auction_id: string;
|
|
148
|
+
screen_id: string;
|
|
149
|
+
timestamp: string;
|
|
150
|
+
winning_bid: {
|
|
151
|
+
bid_price_cpm: number;
|
|
152
|
+
dsp_name: string;
|
|
153
|
+
creative_id: string;
|
|
154
|
+
vast_url: string;
|
|
155
|
+
} | null;
|
|
156
|
+
all_bids: Array<{
|
|
157
|
+
dsp_name: string;
|
|
158
|
+
bid_price_cpm: number;
|
|
159
|
+
latency_ms: number;
|
|
160
|
+
}>;
|
|
161
|
+
latency_ms: number;
|
|
162
|
+
floor_price_cpm: number;
|
|
163
|
+
}
|
|
164
|
+
declare class AuctionClient {
|
|
165
|
+
private authFetch;
|
|
166
|
+
constructor(apiKey: string, apiBase: string);
|
|
167
|
+
list(options?: {
|
|
168
|
+
screenId?: string;
|
|
169
|
+
limit?: number;
|
|
170
|
+
offset?: number;
|
|
171
|
+
}): Promise<AuctionResult[]>;
|
|
172
|
+
get(auctionId: string): Promise<AuctionResult>;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
interface CreativeReview {
|
|
176
|
+
creative_id: string;
|
|
177
|
+
advertiser_name: string;
|
|
178
|
+
creative_url: string;
|
|
179
|
+
status: 'pending' | 'approved' | 'flagged' | 'blocked';
|
|
180
|
+
iab_categories: string[];
|
|
181
|
+
age_rating: string | null;
|
|
182
|
+
brand_detected: string | null;
|
|
183
|
+
content_flags: string[];
|
|
184
|
+
reviewed_at: string | null;
|
|
185
|
+
created_at: string;
|
|
186
|
+
}
|
|
187
|
+
interface CreativeStats {
|
|
188
|
+
total: number;
|
|
189
|
+
pending: number;
|
|
190
|
+
approved: number;
|
|
191
|
+
flagged: number;
|
|
192
|
+
blocked: number;
|
|
193
|
+
}
|
|
194
|
+
declare class CreativeClient {
|
|
195
|
+
private authFetch;
|
|
196
|
+
constructor(apiKey: string, apiBase: string);
|
|
197
|
+
list(options?: {
|
|
198
|
+
status?: string;
|
|
199
|
+
limit?: number;
|
|
200
|
+
offset?: number;
|
|
201
|
+
}): Promise<CreativeReview[]>;
|
|
202
|
+
getStats(): Promise<CreativeStats>;
|
|
203
|
+
block(creativeId: string, reason?: string): Promise<void>;
|
|
204
|
+
unblock(creativeId: string): Promise<void>;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
interface PartnerClientConfig {
|
|
208
|
+
apiKey: string;
|
|
209
|
+
apiBase?: string;
|
|
210
|
+
}
|
|
211
|
+
declare class PartnerClient {
|
|
212
|
+
private apiKey;
|
|
213
|
+
private apiBase;
|
|
214
|
+
private authFetch;
|
|
215
|
+
readonly audience: AudienceClient;
|
|
216
|
+
readonly analytics: AnalyticsClient;
|
|
217
|
+
readonly auctions: AuctionClient;
|
|
218
|
+
readonly creatives: CreativeClient;
|
|
219
|
+
constructor(config: PartnerClientConfig);
|
|
220
|
+
createVastTagBuilder(): VastTagBuilder;
|
|
221
|
+
createTrackingBatch(): TrackingBatch;
|
|
222
|
+
protected fetch(path: string, options?: RequestInit): Promise<any>;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Create a reusable authenticated fetch function bound to a
|
|
227
|
+
* specific API key and base URL.
|
|
228
|
+
*
|
|
229
|
+
* - Strips trailing slashes from `apiBase` to avoid double-slash paths.
|
|
230
|
+
* - Applies a 10-second timeout via `AbortSignal.timeout` unless
|
|
231
|
+
* the caller provides their own `signal`.
|
|
232
|
+
* - Always sends `Authorization: Bearer <key>` and
|
|
233
|
+
* `Content-Type: application/json`.
|
|
234
|
+
* - Throws on non-2xx responses.
|
|
235
|
+
*/
|
|
236
|
+
declare function createAuthenticatedFetch(apiKey: string, apiBase: string): (path: string, options?: RequestInit) => Promise<any>;
|
|
237
|
+
|
|
238
|
+
export { AnalyticsClient, AuctionClient, type AuctionResult, AudienceClient, type AudiencePrediction, type BuildTagOptions, CreativeClient, type CreativeReview, type CreativeStats, type EarningsData, type ImpressionReport, type LiveAudience, type LookalikeScreen, PartnerClient, type PartnerClientConfig, type ScreenDailyAnalytics, TrackingBatch, type TrackingBatchConfig, type TrackingResult, VastTagBuilder, type VastTagBuilderConfig, type VastTagResult, createAuthenticatedFetch };
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/server/fetchWithAuth.ts
|
|
4
|
+
function createAuthenticatedFetch(apiKey, apiBase) {
|
|
5
|
+
const base = apiBase.replace(/\/+$/, "");
|
|
6
|
+
return async (path, options) => {
|
|
7
|
+
const response = await globalThis.fetch(`${base}${path}`, {
|
|
8
|
+
...options,
|
|
9
|
+
signal: options?.signal ?? AbortSignal.timeout(1e4),
|
|
10
|
+
headers: {
|
|
11
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
12
|
+
"Content-Type": "application/json",
|
|
13
|
+
...options?.headers ?? {}
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
if (!response.ok) {
|
|
17
|
+
throw new Error(`API error: HTTP ${response.status}`);
|
|
18
|
+
}
|
|
19
|
+
return response.json();
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/server/VastTagBuilder.ts
|
|
24
|
+
var VastTagBuilder = class {
|
|
25
|
+
constructor(config) {
|
|
26
|
+
this.authFetch = createAuthenticatedFetch(config.apiKey, config.apiBase ?? "https://api.trillboards.com/v1");
|
|
27
|
+
}
|
|
28
|
+
async buildTag(options) {
|
|
29
|
+
const params = new URLSearchParams();
|
|
30
|
+
if (options.width) params.set("slot_w", String(options.width));
|
|
31
|
+
if (options.height) params.set("slot_h", String(options.height));
|
|
32
|
+
if (options.orientation) params.set("orientation", options.orientation);
|
|
33
|
+
if (options.muted !== void 0) params.set("muted", options.muted ? "1" : "0");
|
|
34
|
+
if (options.autoplay !== void 0) params.set("autoplay", options.autoplay ? "1" : "0");
|
|
35
|
+
if (options.userAgent) params.set("ua", options.userAgent);
|
|
36
|
+
const query = params.toString();
|
|
37
|
+
const path = `/partner/device/${options.deviceId}/ads${query ? `?${query}` : ""}`;
|
|
38
|
+
const data = await this.authFetch(path);
|
|
39
|
+
const hbs = data.data?.header_bidding_settings;
|
|
40
|
+
return {
|
|
41
|
+
url: hbs?.vast_tag_url ?? "",
|
|
42
|
+
sources: (hbs?.vast_waterfall?.sources ?? []).map((s) => ({
|
|
43
|
+
name: s.name,
|
|
44
|
+
vast_url: s.vast_url,
|
|
45
|
+
priority: s.priority,
|
|
46
|
+
timeout_ms: s.timeout_ms
|
|
47
|
+
})),
|
|
48
|
+
auctionWinner: hbs?.auction_winner ?? null
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// src/server/TrackingBatch.ts
|
|
54
|
+
var TrackingBatch = class {
|
|
55
|
+
constructor(config) {
|
|
56
|
+
this.apiBase = (config.apiBase ?? "https://api.trillboards.com/v1").replace(/\/+$/, "");
|
|
57
|
+
this.authFetch = createAuthenticatedFetch(config.apiKey, config.apiBase ?? "https://api.trillboards.com/v1");
|
|
58
|
+
}
|
|
59
|
+
async report(impressions) {
|
|
60
|
+
const data = await this.authFetch("/partner/tracking/batch", {
|
|
61
|
+
method: "POST",
|
|
62
|
+
body: JSON.stringify({ impressions })
|
|
63
|
+
});
|
|
64
|
+
return {
|
|
65
|
+
success: data.success ?? true,
|
|
66
|
+
tracked: data.data?.tracked ?? impressions.length,
|
|
67
|
+
proofs: (data.data?.proofs ?? []).map((p) => ({
|
|
68
|
+
impressionId: p.impression_id,
|
|
69
|
+
proof: p.proof,
|
|
70
|
+
publicKeyUrl: p.public_key_url ?? `${this.apiBase}/.well-known/public-key`
|
|
71
|
+
}))
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// src/server/AudienceClient.ts
|
|
77
|
+
var AudienceClient = class {
|
|
78
|
+
constructor(apiKey, apiBase) {
|
|
79
|
+
this.authFetch = createAuthenticatedFetch(apiKey, apiBase);
|
|
80
|
+
}
|
|
81
|
+
async getLive(screenId) {
|
|
82
|
+
const data = await this.authFetch(`/partner/audience/live/${screenId}`);
|
|
83
|
+
return data.data ?? data;
|
|
84
|
+
}
|
|
85
|
+
async predict(screenId, options) {
|
|
86
|
+
const params = new URLSearchParams({
|
|
87
|
+
hour: String(options.hour),
|
|
88
|
+
day_of_week: String(options.dayOfWeek)
|
|
89
|
+
});
|
|
90
|
+
const data = await this.authFetch(`/partner/audience/predict/${screenId}?${params}`);
|
|
91
|
+
return data.data ?? data;
|
|
92
|
+
}
|
|
93
|
+
async findLookalikes(screenId, options) {
|
|
94
|
+
const params = new URLSearchParams();
|
|
95
|
+
if (options?.limit) params.set("limit", String(options.limit));
|
|
96
|
+
if (options?.minSimilarity) params.set("min_similarity", String(options.minSimilarity));
|
|
97
|
+
const query = params.toString();
|
|
98
|
+
const data = await this.authFetch(`/partner/audience/lookalikes/${screenId}${query ? `?${query}` : ""}`);
|
|
99
|
+
return data.data ?? [];
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// src/server/AnalyticsClient.ts
|
|
104
|
+
var AnalyticsClient = class {
|
|
105
|
+
constructor(apiKey, apiBase) {
|
|
106
|
+
this.authFetch = createAuthenticatedFetch(apiKey, apiBase);
|
|
107
|
+
}
|
|
108
|
+
async getScreenDaily(screenId, options) {
|
|
109
|
+
const params = new URLSearchParams({
|
|
110
|
+
start_date: options.startDate,
|
|
111
|
+
end_date: options.endDate
|
|
112
|
+
});
|
|
113
|
+
const data = await this.authFetch(`/partner/screens/${screenId}/analytics?${params}`);
|
|
114
|
+
return data.data ?? [];
|
|
115
|
+
}
|
|
116
|
+
async getEarnings(options) {
|
|
117
|
+
const params = new URLSearchParams();
|
|
118
|
+
if (options?.screenId) params.set("screen_id", options.screenId);
|
|
119
|
+
if (options?.startDate) params.set("start_date", options.startDate);
|
|
120
|
+
if (options?.endDate) params.set("end_date", options.endDate);
|
|
121
|
+
const query = params.toString();
|
|
122
|
+
const data = await this.authFetch(`/partner/earnings${query ? `?${query}` : ""}`);
|
|
123
|
+
return data.data ?? [];
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// src/server/AuctionClient.ts
|
|
128
|
+
var AuctionClient = class {
|
|
129
|
+
constructor(apiKey, apiBase) {
|
|
130
|
+
this.authFetch = createAuthenticatedFetch(apiKey, apiBase);
|
|
131
|
+
}
|
|
132
|
+
async list(options) {
|
|
133
|
+
const params = new URLSearchParams();
|
|
134
|
+
if (options?.screenId) params.set("screen_id", options.screenId);
|
|
135
|
+
if (options?.limit) params.set("limit", String(options.limit));
|
|
136
|
+
if (options?.offset) params.set("offset", String(options.offset));
|
|
137
|
+
const query = params.toString();
|
|
138
|
+
const data = await this.authFetch(`/partner/auctions${query ? `?${query}` : ""}`);
|
|
139
|
+
return data.data ?? [];
|
|
140
|
+
}
|
|
141
|
+
async get(auctionId) {
|
|
142
|
+
const data = await this.authFetch(`/partner/auctions/${auctionId}`);
|
|
143
|
+
return data.data ?? data;
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// src/server/CreativeClient.ts
|
|
148
|
+
var CreativeClient = class {
|
|
149
|
+
constructor(apiKey, apiBase) {
|
|
150
|
+
this.authFetch = createAuthenticatedFetch(apiKey, apiBase);
|
|
151
|
+
}
|
|
152
|
+
async list(options) {
|
|
153
|
+
const params = new URLSearchParams();
|
|
154
|
+
if (options?.status) params.set("status", options.status);
|
|
155
|
+
if (options?.limit) params.set("limit", String(options.limit));
|
|
156
|
+
if (options?.offset) params.set("offset", String(options.offset));
|
|
157
|
+
const query = params.toString();
|
|
158
|
+
const data = await this.authFetch(`/openrtb/v1/creative-review${query ? `?${query}` : ""}`);
|
|
159
|
+
return data.data ?? [];
|
|
160
|
+
}
|
|
161
|
+
async getStats() {
|
|
162
|
+
const data = await this.authFetch("/openrtb/v1/creative-review/stats");
|
|
163
|
+
return data.data ?? data;
|
|
164
|
+
}
|
|
165
|
+
async block(creativeId, reason) {
|
|
166
|
+
await this.authFetch(`/openrtb/v1/creative-review/${creativeId}/block`, {
|
|
167
|
+
method: "POST",
|
|
168
|
+
body: JSON.stringify({ reason })
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
async unblock(creativeId) {
|
|
172
|
+
await this.authFetch(`/openrtb/v1/creative-review/${creativeId}/unblock`, {
|
|
173
|
+
method: "POST"
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
// src/server/PartnerClient.ts
|
|
179
|
+
var PartnerClient = class {
|
|
180
|
+
constructor(config) {
|
|
181
|
+
this.apiKey = config.apiKey;
|
|
182
|
+
this.apiBase = config.apiBase ?? "https://api.trillboards.com/v1";
|
|
183
|
+
this.authFetch = createAuthenticatedFetch(this.apiKey, this.apiBase);
|
|
184
|
+
this.audience = new AudienceClient(this.apiKey, this.apiBase);
|
|
185
|
+
this.analytics = new AnalyticsClient(this.apiKey, this.apiBase);
|
|
186
|
+
this.auctions = new AuctionClient(this.apiKey, this.apiBase);
|
|
187
|
+
this.creatives = new CreativeClient(this.apiKey, this.apiBase);
|
|
188
|
+
}
|
|
189
|
+
createVastTagBuilder() {
|
|
190
|
+
return new VastTagBuilder({ apiKey: this.apiKey, apiBase: this.apiBase });
|
|
191
|
+
}
|
|
192
|
+
createTrackingBatch() {
|
|
193
|
+
return new TrackingBatch({ apiKey: this.apiKey, apiBase: this.apiBase });
|
|
194
|
+
}
|
|
195
|
+
async fetch(path, options = {}) {
|
|
196
|
+
return this.authFetch(path, options);
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
exports.AnalyticsClient = AnalyticsClient;
|
|
201
|
+
exports.AuctionClient = AuctionClient;
|
|
202
|
+
exports.AudienceClient = AudienceClient;
|
|
203
|
+
exports.CreativeClient = CreativeClient;
|
|
204
|
+
exports.PartnerClient = PartnerClient;
|
|
205
|
+
exports.TrackingBatch = TrackingBatch;
|
|
206
|
+
exports.VastTagBuilder = VastTagBuilder;
|
|
207
|
+
exports.createAuthenticatedFetch = createAuthenticatedFetch;
|
|
208
|
+
//# sourceMappingURL=server.js.map
|
|
209
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server/fetchWithAuth.ts","../src/server/VastTagBuilder.ts","../src/server/TrackingBatch.ts","../src/server/AudienceClient.ts","../src/server/AnalyticsClient.ts","../src/server/AuctionClient.ts","../src/server/CreativeClient.ts","../src/server/PartnerClient.ts"],"names":[],"mappings":"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","file":"server.js","sourcesContent":["// ─────────────────────────────────────────────────────────────\n// @trillboards/ads-sdk — Shared authenticated fetch utility\n// ─────────────────────────────────────────────────────────────\n\n/**\n * Create a reusable authenticated fetch function bound to a\n * specific API key and base URL.\n *\n * - Strips trailing slashes from `apiBase` to avoid double-slash paths.\n * - Applies a 10-second timeout via `AbortSignal.timeout` unless\n * the caller provides their own `signal`.\n * - Always sends `Authorization: Bearer <key>` and\n * `Content-Type: application/json`.\n * - Throws on non-2xx responses.\n */\nexport function createAuthenticatedFetch(apiKey: string, apiBase: string) {\n const base = apiBase.replace(/\\/+$/, '');\n\n return async (path: string, options?: RequestInit): Promise<any> => {\n const response = await globalThis.fetch(`${base}${path}`, {\n ...options,\n signal: options?.signal ?? AbortSignal.timeout(10000),\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n ...((options?.headers as Record<string, string>) ?? {}),\n },\n });\n\n if (!response.ok) {\n throw new Error(`API error: HTTP ${response.status}`);\n }\n\n return response.json();\n };\n}\n","import { createAuthenticatedFetch } from './fetchWithAuth';\n\nexport interface VastTagBuilderConfig {\n apiKey: string;\n apiBase?: string;\n}\n\nexport interface BuildTagOptions {\n deviceId: string;\n width?: number;\n height?: number;\n orientation?: 'portrait' | 'landscape';\n muted?: boolean;\n autoplay?: boolean;\n userAgent?: string;\n}\n\nexport interface VastTagResult {\n url: string;\n sources: Array<{\n name: string;\n vast_url: string;\n priority: number;\n timeout_ms: number;\n }>;\n auctionWinner?: {\n source: string;\n bid_price_cpm: number;\n vast_url: string;\n } | null;\n}\n\nexport class VastTagBuilder {\n private authFetch: ReturnType<typeof createAuthenticatedFetch>;\n\n constructor(config: VastTagBuilderConfig) {\n this.authFetch = createAuthenticatedFetch(config.apiKey, config.apiBase ?? 'https://api.trillboards.com/v1');\n }\n\n async buildTag(options: BuildTagOptions): Promise<VastTagResult> {\n const params = new URLSearchParams();\n if (options.width) params.set('slot_w', String(options.width));\n if (options.height) params.set('slot_h', String(options.height));\n if (options.orientation) params.set('orientation', options.orientation);\n if (options.muted !== undefined) params.set('muted', options.muted ? '1' : '0');\n if (options.autoplay !== undefined) params.set('autoplay', options.autoplay ? '1' : '0');\n if (options.userAgent) params.set('ua', options.userAgent);\n\n const query = params.toString();\n const path = `/partner/device/${options.deviceId}/ads${query ? `?${query}` : ''}`;\n\n const data = await this.authFetch(path);\n const hbs = data.data?.header_bidding_settings;\n\n return {\n url: hbs?.vast_tag_url ?? '',\n sources: (hbs?.vast_waterfall?.sources ?? []).map((s: any) => ({\n name: s.name,\n vast_url: s.vast_url,\n priority: s.priority,\n timeout_ms: s.timeout_ms,\n })),\n auctionWinner: hbs?.auction_winner ?? null,\n };\n }\n}\n","import { createAuthenticatedFetch } from './fetchWithAuth';\n\nexport interface TrackingBatchConfig {\n apiKey: string;\n apiBase?: string;\n}\n\nexport interface ImpressionReport {\n adId: string;\n impressionId: string;\n deviceId: string;\n screenId?: string;\n duration: number;\n completed: boolean;\n timestamp: string;\n}\n\nexport interface TrackingResult {\n success: boolean;\n tracked: number;\n proofs: Array<{\n impressionId: string;\n proof: string;\n publicKeyUrl: string;\n }>;\n}\n\nexport class TrackingBatch {\n private apiBase: string;\n private authFetch: ReturnType<typeof createAuthenticatedFetch>;\n\n constructor(config: TrackingBatchConfig) {\n this.apiBase = (config.apiBase ?? 'https://api.trillboards.com/v1').replace(/\\/+$/, '');\n this.authFetch = createAuthenticatedFetch(config.apiKey, config.apiBase ?? 'https://api.trillboards.com/v1');\n }\n\n async report(impressions: ImpressionReport[]): Promise<TrackingResult> {\n const data = await this.authFetch('/partner/tracking/batch', {\n method: 'POST',\n body: JSON.stringify({ impressions }),\n });\n\n return {\n success: data.success ?? true,\n tracked: data.data?.tracked ?? impressions.length,\n proofs: (data.data?.proofs ?? []).map((p: any) => ({\n impressionId: p.impression_id,\n proof: p.proof,\n publicKeyUrl: p.public_key_url ?? `${this.apiBase}/.well-known/public-key`,\n })),\n };\n }\n}\n","import { createAuthenticatedFetch } from './fetchWithAuth';\n\nexport interface LiveAudience {\n face_count: number;\n attention_score: number;\n mood: string | null;\n income_level: string | null;\n purchase_intent: number | null;\n dwell_time_ms: number | null;\n timestamp: string;\n}\n\nexport interface AudiencePrediction {\n predicted_face_count: number;\n predicted_attention_score: number;\n predicted_mood: string | null;\n confidence: number;\n hour: number;\n dayOfWeek: number;\n}\n\nexport interface LookalikeScreen {\n screenId: string;\n similarity: number;\n audience_profile: Record<string, unknown>;\n}\n\nexport class AudienceClient {\n private authFetch: ReturnType<typeof createAuthenticatedFetch>;\n\n constructor(apiKey: string, apiBase: string) {\n this.authFetch = createAuthenticatedFetch(apiKey, apiBase);\n }\n\n async getLive(screenId: string): Promise<LiveAudience> {\n const data = await this.authFetch(`/partner/audience/live/${screenId}`);\n return data.data ?? data;\n }\n\n async predict(screenId: string, options: { hour: number; dayOfWeek: number }): Promise<AudiencePrediction> {\n const params = new URLSearchParams({\n hour: String(options.hour),\n day_of_week: String(options.dayOfWeek),\n });\n const data = await this.authFetch(`/partner/audience/predict/${screenId}?${params}`);\n return data.data ?? data;\n }\n\n async findLookalikes(screenId: string, options?: { limit?: number; minSimilarity?: number }): Promise<LookalikeScreen[]> {\n const params = new URLSearchParams();\n if (options?.limit) params.set('limit', String(options.limit));\n if (options?.minSimilarity) params.set('min_similarity', String(options.minSimilarity));\n const query = params.toString();\n const data = await this.authFetch(`/partner/audience/lookalikes/${screenId}${query ? `?${query}` : ''}`);\n return data.data ?? [];\n }\n}\n","import { createAuthenticatedFetch } from './fetchWithAuth';\n\nexport interface ScreenDailyAnalytics {\n date: string;\n ads: {\n plays_started: number;\n plays_completed: number;\n completion_rate: number;\n programmatic_plays: number;\n direct_plays: number;\n };\n audience: {\n avg_face_count: number;\n avg_attention_score: number;\n peak_viewers: number;\n };\n earnings: {\n programmatic_cents: number;\n direct_cents: number;\n total_cents: number;\n };\n streaming: {\n seconds: number;\n uptime_percentage: number;\n };\n}\n\nexport interface EarningsData {\n screenId: string;\n period: string;\n impressions_count: number;\n cpm_rate: number;\n gross_revenue: number;\n earner_revenue: number;\n earner_share_rate: number;\n}\n\nexport class AnalyticsClient {\n private authFetch: ReturnType<typeof createAuthenticatedFetch>;\n\n constructor(apiKey: string, apiBase: string) {\n this.authFetch = createAuthenticatedFetch(apiKey, apiBase);\n }\n\n async getScreenDaily(screenId: string, options: { startDate: string; endDate: string }): Promise<ScreenDailyAnalytics[]> {\n const params = new URLSearchParams({\n start_date: options.startDate,\n end_date: options.endDate,\n });\n const data = await this.authFetch(`/partner/screens/${screenId}/analytics?${params}`);\n return data.data ?? [];\n }\n\n async getEarnings(options?: { screenId?: string; startDate?: string; endDate?: string }): Promise<EarningsData[]> {\n const params = new URLSearchParams();\n if (options?.screenId) params.set('screen_id', options.screenId);\n if (options?.startDate) params.set('start_date', options.startDate);\n if (options?.endDate) params.set('end_date', options.endDate);\n const query = params.toString();\n const data = await this.authFetch(`/partner/earnings${query ? `?${query}` : ''}`);\n return data.data ?? [];\n }\n}\n","import { createAuthenticatedFetch } from './fetchWithAuth';\n\nexport interface AuctionResult {\n auction_id: string;\n screen_id: string;\n timestamp: string;\n winning_bid: {\n bid_price_cpm: number;\n dsp_name: string;\n creative_id: string;\n vast_url: string;\n } | null;\n all_bids: Array<{\n dsp_name: string;\n bid_price_cpm: number;\n latency_ms: number;\n }>;\n latency_ms: number;\n floor_price_cpm: number;\n}\n\nexport class AuctionClient {\n private authFetch: ReturnType<typeof createAuthenticatedFetch>;\n\n constructor(apiKey: string, apiBase: string) {\n this.authFetch = createAuthenticatedFetch(apiKey, apiBase);\n }\n\n async list(options?: { screenId?: string; limit?: number; offset?: number }): Promise<AuctionResult[]> {\n const params = new URLSearchParams();\n if (options?.screenId) params.set('screen_id', options.screenId);\n if (options?.limit) params.set('limit', String(options.limit));\n if (options?.offset) params.set('offset', String(options.offset));\n const query = params.toString();\n const data = await this.authFetch(`/partner/auctions${query ? `?${query}` : ''}`);\n return data.data ?? [];\n }\n\n async get(auctionId: string): Promise<AuctionResult> {\n const data = await this.authFetch(`/partner/auctions/${auctionId}`);\n return data.data ?? data;\n }\n}\n","import { createAuthenticatedFetch } from './fetchWithAuth';\n\nexport interface CreativeReview {\n creative_id: string;\n advertiser_name: string;\n creative_url: string;\n status: 'pending' | 'approved' | 'flagged' | 'blocked';\n iab_categories: string[];\n age_rating: string | null;\n brand_detected: string | null;\n content_flags: string[];\n reviewed_at: string | null;\n created_at: string;\n}\n\nexport interface CreativeStats {\n total: number;\n pending: number;\n approved: number;\n flagged: number;\n blocked: number;\n}\n\nexport class CreativeClient {\n private authFetch: ReturnType<typeof createAuthenticatedFetch>;\n\n constructor(apiKey: string, apiBase: string) {\n this.authFetch = createAuthenticatedFetch(apiKey, apiBase);\n }\n\n async list(options?: { status?: string; limit?: number; offset?: number }): Promise<CreativeReview[]> {\n const params = new URLSearchParams();\n if (options?.status) params.set('status', options.status);\n if (options?.limit) params.set('limit', String(options.limit));\n if (options?.offset) params.set('offset', String(options.offset));\n const query = params.toString();\n const data = await this.authFetch(`/openrtb/v1/creative-review${query ? `?${query}` : ''}`);\n return data.data ?? [];\n }\n\n async getStats(): Promise<CreativeStats> {\n const data = await this.authFetch('/openrtb/v1/creative-review/stats');\n return data.data ?? data;\n }\n\n async block(creativeId: string, reason?: string): Promise<void> {\n await this.authFetch(`/openrtb/v1/creative-review/${creativeId}/block`, {\n method: 'POST',\n body: JSON.stringify({ reason }),\n });\n }\n\n async unblock(creativeId: string): Promise<void> {\n await this.authFetch(`/openrtb/v1/creative-review/${creativeId}/unblock`, {\n method: 'POST',\n });\n }\n}\n","import { VastTagBuilder } from './VastTagBuilder';\nimport { TrackingBatch } from './TrackingBatch';\nimport { AudienceClient } from './AudienceClient';\nimport { AnalyticsClient } from './AnalyticsClient';\nimport { AuctionClient } from './AuctionClient';\nimport { CreativeClient } from './CreativeClient';\nimport { createAuthenticatedFetch } from './fetchWithAuth';\n\nexport interface PartnerClientConfig {\n apiKey: string;\n apiBase?: string;\n}\n\nexport class PartnerClient {\n private apiKey: string;\n private apiBase: string;\n private authFetch: ReturnType<typeof createAuthenticatedFetch>;\n\n readonly audience: AudienceClient;\n readonly analytics: AnalyticsClient;\n readonly auctions: AuctionClient;\n readonly creatives: CreativeClient;\n\n constructor(config: PartnerClientConfig) {\n this.apiKey = config.apiKey;\n this.apiBase = config.apiBase ?? 'https://api.trillboards.com/v1';\n this.authFetch = createAuthenticatedFetch(this.apiKey, this.apiBase);\n this.audience = new AudienceClient(this.apiKey, this.apiBase);\n this.analytics = new AnalyticsClient(this.apiKey, this.apiBase);\n this.auctions = new AuctionClient(this.apiKey, this.apiBase);\n this.creatives = new CreativeClient(this.apiKey, this.apiBase);\n }\n\n createVastTagBuilder(): VastTagBuilder {\n return new VastTagBuilder({ apiKey: this.apiKey, apiBase: this.apiBase });\n }\n\n createTrackingBatch(): TrackingBatch {\n return new TrackingBatch({ apiKey: this.apiKey, apiBase: this.apiBase });\n }\n\n protected async fetch(path: string, options: RequestInit = {}): Promise<any> {\n return this.authFetch(path, options);\n }\n}\n"]}
|