@thead-vantage/react 2.16.0 → 2.17.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/package.json +1 -1
- package/src/components/AdBanner.tsx +14 -9
- package/src/lib/ads.ts +52 -42
- package/src/lib/thead-vantage-config.ts +3 -9
package/package.json
CHANGED
|
@@ -43,17 +43,22 @@ export function AdBanner({
|
|
|
43
43
|
userSegment,
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
46
|
+
// Only log in development mode
|
|
47
|
+
if (process.env.NODE_ENV === 'development') {
|
|
48
|
+
console.log('[AdBanner] Processed response:', {
|
|
49
|
+
success: response.success,
|
|
50
|
+
hasAd: !!response.ad,
|
|
51
|
+
devMode: response.dev_mode,
|
|
52
|
+
message: response.message,
|
|
53
|
+
_dev_note: response._dev_note,
|
|
54
|
+
fullResponse: response,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
54
57
|
|
|
55
58
|
if (response.success && response.ad) {
|
|
56
|
-
|
|
59
|
+
if (process.env.NODE_ENV === 'development') {
|
|
60
|
+
console.log('[AdBanner] Setting ad:', response.ad);
|
|
61
|
+
}
|
|
57
62
|
setAd(response.ad);
|
|
58
63
|
setDevMode(response.dev_mode || false);
|
|
59
64
|
|
package/src/lib/ads.ts
CHANGED
|
@@ -3,7 +3,17 @@
|
|
|
3
3
|
* Automatically handles development mode to prevent tracking
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { getApiBaseUrl, shouldUseDevFlags } from './thead-vantage-config';
|
|
6
|
+
import { getApiBaseUrl, shouldUseDevFlags, isDevelopmentMode } from './thead-vantage-config';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Helper function to log only in development mode
|
|
10
|
+
* Errors and warnings are always logged
|
|
11
|
+
*/
|
|
12
|
+
function devLog(...args: unknown[]): void {
|
|
13
|
+
if (process.env.NODE_ENV === 'development' || isDevelopmentMode()) {
|
|
14
|
+
console.log(...args);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
7
17
|
|
|
8
18
|
export interface AdData {
|
|
9
19
|
id: string;
|
|
@@ -147,7 +157,7 @@ export async function fetchAdBanner(params: FetchAdBannerParams): Promise<AdBann
|
|
|
147
157
|
|
|
148
158
|
// Log the request (without exposing the API key)
|
|
149
159
|
const logUrl = url.replace(new RegExp(`api_key=${params.apiKey}`, 'g'), 'api_key=***');
|
|
150
|
-
|
|
160
|
+
devLog('[AdBanner] Fetching ad from:', logUrl);
|
|
151
161
|
|
|
152
162
|
// Make direct request to thead-vantage.com
|
|
153
163
|
// Try to make a "simple request" that doesn't trigger preflight
|
|
@@ -205,8 +215,8 @@ export async function fetchAdBanner(params: FetchAdBannerParams): Promise<AdBann
|
|
|
205
215
|
const data: AdsResponse = await response.json();
|
|
206
216
|
|
|
207
217
|
// Debug logging - log the FULL response to see exactly what we're getting
|
|
208
|
-
|
|
209
|
-
|
|
218
|
+
devLog('[AdBanner] Full API Response:', JSON.stringify(data, null, 2));
|
|
219
|
+
devLog('[AdBanner] API Response Summary:', {
|
|
210
220
|
success: data.success,
|
|
211
221
|
hasAd: !!data.ad,
|
|
212
222
|
hasAds: !!(data.ads && Array.isArray(data.ads)),
|
|
@@ -246,19 +256,19 @@ export async function fetchAdBanner(params: FetchAdBannerParams): Promise<AdBann
|
|
|
246
256
|
|
|
247
257
|
// Handle both single ad and array of ads
|
|
248
258
|
if (data.ads && Array.isArray(data.ads) && data.ads.length > 0) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
259
|
+
// If we get an array, use the first ad and ensure it's Ad type
|
|
260
|
+
const firstAd = data.ads[0];
|
|
261
|
+
devLog('[AdBanner] Processing ads array, first ad:', JSON.stringify(firstAd, null, 2));
|
|
262
|
+
|
|
263
|
+
// Check if it's already an Ad, otherwise convert from AdData
|
|
264
|
+
let ad: Ad = isAd(firstAd)
|
|
265
|
+
? firstAd
|
|
266
|
+
: convertToAd(firstAd as AdData);
|
|
267
|
+
|
|
268
|
+
// Normalize the type (standard -> image)
|
|
269
|
+
ad = normalizeAdType(ad);
|
|
270
|
+
|
|
271
|
+
devLog('[AdBanner] Converted ad:', JSON.stringify(ad, null, 2));
|
|
262
272
|
|
|
263
273
|
return {
|
|
264
274
|
success: data.success,
|
|
@@ -271,19 +281,19 @@ export async function fetchAdBanner(params: FetchAdBannerParams): Promise<AdBann
|
|
|
271
281
|
|
|
272
282
|
// Handle single ad response - convert AdData to Ad
|
|
273
283
|
if (data.ad) {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
284
|
+
devLog('[AdBanner] Processing single ad:', JSON.stringify(data.ad, null, 2));
|
|
285
|
+
|
|
286
|
+
// Check if it's already in Ad format or needs conversion
|
|
287
|
+
let ad: Ad;
|
|
288
|
+
if (isAd(data.ad)) {
|
|
289
|
+
// Already in Ad format, normalize the type
|
|
290
|
+
ad = normalizeAdType(data.ad);
|
|
291
|
+
} else {
|
|
292
|
+
// Convert from AdData format
|
|
293
|
+
ad = convertToAd(data.ad);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
devLog('[AdBanner] Converted ad:', JSON.stringify(ad, null, 2));
|
|
287
297
|
|
|
288
298
|
return {
|
|
289
299
|
success: data.success,
|
|
@@ -456,7 +466,7 @@ export async function trackImpression(adId: string, apiKey: string, apiUrl?: str
|
|
|
456
466
|
// Check if we should skip tracking (dev mode)
|
|
457
467
|
const useDevFlags = shouldUseDevFlags();
|
|
458
468
|
if (useDevFlags) {
|
|
459
|
-
|
|
469
|
+
devLog(`[DEV] Impression tracking skipped for ad: ${adId}`);
|
|
460
470
|
return;
|
|
461
471
|
}
|
|
462
472
|
|
|
@@ -485,16 +495,16 @@ export async function trackImpression(adId: string, apiKey: string, apiUrl?: str
|
|
|
485
495
|
|
|
486
496
|
const data = await response.json();
|
|
487
497
|
if (data.dev_mode) {
|
|
488
|
-
|
|
498
|
+
devLog(`[DEV] Impression tracking skipped for ad: ${adId}`);
|
|
489
499
|
} else {
|
|
490
|
-
|
|
500
|
+
devLog(`[AdBanner] Impression tracked successfully for ad: ${adId}`);
|
|
491
501
|
}
|
|
492
502
|
} catch (error) {
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
503
|
+
// Handle CORS errors gracefully (tracking failures shouldn't break the app)
|
|
504
|
+
if (error instanceof TypeError && (error.message.includes('CORS') || error.message.includes('Failed to fetch'))) {
|
|
505
|
+
// This is expected until the server configures CORS for /api/ads/track endpoint
|
|
506
|
+
// The ad still displays correctly, tracking just won't work until server-side CORS is fixed
|
|
507
|
+
devLog(`[AdBanner] Tracking impression failed (CORS): The /api/ads/track endpoint needs CORS headers configured on the server. Ad still displayed successfully.`);
|
|
498
508
|
} else {
|
|
499
509
|
console.error('Error tracking impression:', error);
|
|
500
510
|
}
|
|
@@ -545,7 +555,7 @@ export async function trackClick(adId: string, apiKey: string, apiUrl?: string):
|
|
|
545
555
|
// Check if we should skip tracking (dev mode)
|
|
546
556
|
const useDevFlags = shouldUseDevFlags();
|
|
547
557
|
if (useDevFlags) {
|
|
548
|
-
|
|
558
|
+
devLog(`[DEV] Click tracking skipped for ad: ${adId}`);
|
|
549
559
|
return;
|
|
550
560
|
}
|
|
551
561
|
|
|
@@ -574,16 +584,16 @@ export async function trackClick(adId: string, apiKey: string, apiUrl?: string):
|
|
|
574
584
|
|
|
575
585
|
const data = await response.json();
|
|
576
586
|
if (data.dev_mode) {
|
|
577
|
-
|
|
587
|
+
devLog(`[DEV] Click tracking skipped for ad: ${adId}`);
|
|
578
588
|
} else {
|
|
579
|
-
|
|
589
|
+
devLog(`[AdBanner] Click tracked successfully for ad: ${adId}`);
|
|
580
590
|
}
|
|
581
591
|
} catch (error) {
|
|
582
592
|
// Handle CORS errors gracefully (tracking failures shouldn't break the app)
|
|
583
593
|
if (error instanceof TypeError && (error.message.includes('CORS') || error.message.includes('Failed to fetch'))) {
|
|
584
594
|
// This is expected until the server configures CORS for /api/ads/track endpoint
|
|
585
595
|
// The ad still works correctly, click tracking just won't work until server-side CORS is fixed
|
|
586
|
-
|
|
596
|
+
devLog(`[AdBanner] Tracking click failed (CORS): The /api/ads/track endpoint needs CORS headers configured on the server. Ad still works correctly.`);
|
|
587
597
|
} else {
|
|
588
598
|
console.error('Error tracking click:', error);
|
|
589
599
|
}
|
|
@@ -116,15 +116,9 @@ export function getApiBaseUrl(explicitApiUrl?: string): string {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
// Log which URL was selected (helpful for debugging)
|
|
119
|
-
//
|
|
120
|
-
if (typeof window !== 'undefined') {
|
|
121
|
-
|
|
122
|
-
console.log(`[TheAd Vantage] API Base URL selected: ${selectedUrl} (reason: ${reason})`);
|
|
123
|
-
} else {
|
|
124
|
-
// In production, log to console but only if there's an issue (helps with debugging)
|
|
125
|
-
// We'll log errors separately, but this helps identify configuration issues
|
|
126
|
-
console.debug(`[TheAd Vantage] API Base URL: ${selectedUrl}`);
|
|
127
|
-
}
|
|
119
|
+
// Only log in development mode
|
|
120
|
+
if (typeof window !== 'undefined' && (process.env.NODE_ENV === 'development' || isDevelopmentMode())) {
|
|
121
|
+
console.log(`[TheAd Vantage] API Base URL selected: ${selectedUrl} (reason: ${reason})`);
|
|
128
122
|
}
|
|
129
123
|
|
|
130
124
|
return selectedUrl;
|