@adhese/sdk 0.7.0 → 0.8.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/README.md +71 -41
- package/dist/index.cjs +676 -666
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +79 -40
- package/dist/index.js +678 -668
- package/dist/index.js.map +1 -1
- package/package.json +12 -6
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { toValue, ref, computed, watch, effectScope, reactive, shallowReactive, watchEffect } from "@vue/runtime-core";
|
|
2
2
|
import { debounce, round, isDeepEqual } from "remeda";
|
|
3
3
|
import { union, coerce, literal, number, string, ZodIssueCode, NEVER, object, unknown, lazy } from "zod";
|
|
4
4
|
async function waitForDomLoad() {
|
|
@@ -150,109 +150,16 @@ function renderInline(ad, element) {
|
|
|
150
150
|
function generateName(location, format, slot) {
|
|
151
151
|
return `${location}${slot ? `${slot}` : ""}-${format}`;
|
|
152
152
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
);
|
|
164
|
-
return !((_a = context.getAll) == null ? void 0 : _a.call(context).some((activeSlot) => activeSlot.name.value === name));
|
|
165
|
-
}).map((element) => createSlot({
|
|
166
|
-
format: element.dataset.format,
|
|
167
|
-
containingElement: element,
|
|
168
|
-
slot: element.dataset.slot,
|
|
169
|
-
context
|
|
170
|
-
})).filter((slot) => {
|
|
171
|
-
var _a;
|
|
172
|
-
return !((_a = context.getAll) == null ? void 0 : _a.call(context).some((activeSlot) => activeSlot.name.value === slot.name.value));
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
function createSlotManager({
|
|
176
|
-
initialSlots = [],
|
|
177
|
-
context
|
|
178
|
-
}) {
|
|
179
|
-
const scope = effectScope();
|
|
180
|
-
return scope.run(() => {
|
|
181
|
-
const slots = shallowReactive(/* @__PURE__ */ new Map());
|
|
182
|
-
watchEffect(() => {
|
|
183
|
-
var _a;
|
|
184
|
-
(_a = context.events) == null ? void 0 : _a.changeSlots.dispatch(Array.from(slots.values()));
|
|
185
|
-
});
|
|
186
|
-
function getAll() {
|
|
187
|
-
return Array.from(slots).map(([, slot]) => slot);
|
|
188
|
-
}
|
|
189
|
-
function add(options) {
|
|
190
|
-
var _a;
|
|
191
|
-
const slot = createSlot({
|
|
192
|
-
...options,
|
|
193
|
-
onDispose: onDispose2,
|
|
194
|
-
context
|
|
195
|
-
});
|
|
196
|
-
function onDispose2() {
|
|
197
|
-
var _a2;
|
|
198
|
-
slots.delete(slot.name.value);
|
|
199
|
-
logger.debug("Slot removed", {
|
|
200
|
-
slot,
|
|
201
|
-
slots: Array.from(slots)
|
|
202
|
-
});
|
|
203
|
-
(_a2 = context.events) == null ? void 0 : _a2.removeSlot.dispatch(slot);
|
|
204
|
-
}
|
|
205
|
-
slots.set(slot.name.value, slot);
|
|
206
|
-
watch(slot.name, (newName, previousName) => {
|
|
207
|
-
slots.set(newName, slot);
|
|
208
|
-
slots.delete(previousName);
|
|
209
|
-
});
|
|
210
|
-
logger.debug("Slot added", {
|
|
211
|
-
slot,
|
|
212
|
-
slots: Array.from(slots.values())
|
|
213
|
-
});
|
|
214
|
-
(_a = context.events) == null ? void 0 : _a.addSlot.dispatch(slot);
|
|
215
|
-
return slot;
|
|
216
|
-
}
|
|
217
|
-
async function findDomSlots$1() {
|
|
218
|
-
const domSlots = await findDomSlots(
|
|
219
|
-
context
|
|
220
|
-
);
|
|
221
|
-
for (const slot of domSlots)
|
|
222
|
-
slots.set(slot.name.value, slot);
|
|
223
|
-
return domSlots;
|
|
224
|
-
}
|
|
225
|
-
function get(name) {
|
|
226
|
-
return slots.get(name);
|
|
227
|
-
}
|
|
228
|
-
function dispose() {
|
|
229
|
-
for (const slot of slots.values())
|
|
230
|
-
slot.dispose();
|
|
231
|
-
slots.clear();
|
|
232
|
-
scope.stop();
|
|
233
|
-
}
|
|
234
|
-
for (const options of initialSlots) {
|
|
235
|
-
add({
|
|
236
|
-
...options,
|
|
237
|
-
lazyLoading: false
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
return {
|
|
241
|
-
getAll,
|
|
242
|
-
add,
|
|
243
|
-
findDomSlots: findDomSlots$1,
|
|
244
|
-
get,
|
|
245
|
-
dispose
|
|
246
|
-
};
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
function onTcfConsentChange(callback) {
|
|
250
|
-
var _a;
|
|
251
|
-
(_a = window.__tcfapi) == null ? void 0 : _a.call(window, "addEventListener", 2, callback);
|
|
252
|
-
return () => {
|
|
253
|
-
var _a2;
|
|
254
|
-
return (_a2 = window.__tcfapi) == null ? void 0 : _a2.call(window, "removeEventListener", 2, callback);
|
|
255
|
-
};
|
|
153
|
+
function addTrackingPixel(url) {
|
|
154
|
+
const img = document.createElement("img");
|
|
155
|
+
img.src = url.toString();
|
|
156
|
+
img.style.height = "1px";
|
|
157
|
+
img.style.width = "1px";
|
|
158
|
+
img.style.margin = "-1px";
|
|
159
|
+
img.style.border = "0";
|
|
160
|
+
img.style.position = "absolute";
|
|
161
|
+
img.style.top = "0";
|
|
162
|
+
return document.body.appendChild(img);
|
|
256
163
|
}
|
|
257
164
|
function createQueryDetector({
|
|
258
165
|
onChange,
|
|
@@ -365,54 +272,35 @@ function createLogger({
|
|
|
365
272
|
const logger = createLogger({
|
|
366
273
|
scope: "Adhese SDK"
|
|
367
274
|
});
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
parameters.set("re", btoa(document.referrer));
|
|
372
|
-
if (options.logUrl)
|
|
373
|
-
parameters.set("ur", btoa(window.location.href));
|
|
374
|
-
for (const [key, value] of Object.entries({
|
|
375
|
-
...options.parameters ?? {},
|
|
376
|
-
tl: options.consent ? "all" : "none",
|
|
377
|
-
dt: queryDetector.getQuery(),
|
|
378
|
-
br: queryDetector.getQuery(),
|
|
379
|
-
rn: Math.round(Math.random() * 1e4).toString()
|
|
380
|
-
}))
|
|
381
|
-
parameters.set(key, value);
|
|
382
|
-
return parameters;
|
|
275
|
+
const hookMap = /* @__PURE__ */ new Map();
|
|
276
|
+
function clearAllHooks() {
|
|
277
|
+
hookMap.clear();
|
|
383
278
|
}
|
|
384
|
-
function
|
|
385
|
-
if (mergedOptions.debug || window.location.search.includes("adhese_debug=true")) {
|
|
386
|
-
logger.setMinLogLevelThreshold("debug");
|
|
387
|
-
logger.debug("Debug logging enabled");
|
|
388
|
-
}
|
|
389
|
-
logger.debug("Created Adhese SDK instance", {
|
|
390
|
-
mergedOptions
|
|
391
|
-
});
|
|
392
|
-
}
|
|
393
|
-
function isPreviewMode() {
|
|
394
|
-
return window.location.search.includes("adhesePreviewCreativeId");
|
|
395
|
-
}
|
|
396
|
-
function createHook({
|
|
279
|
+
function createHook(name, {
|
|
397
280
|
onRun,
|
|
398
|
-
onAdd
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
const
|
|
402
|
-
|
|
403
|
-
for (const callback of
|
|
404
|
-
callback();
|
|
405
|
-
onRun == null ? void 0 : onRun(
|
|
406
|
-
|
|
281
|
+
onAdd
|
|
282
|
+
} = {}) {
|
|
283
|
+
hookMap.set(name, /* @__PURE__ */ new Set());
|
|
284
|
+
const run = async (arg) => {
|
|
285
|
+
let latestResult = arg;
|
|
286
|
+
for (const callback of hookMap.get(name) ?? [])
|
|
287
|
+
latestResult = await callback(latestResult) ?? latestResult;
|
|
288
|
+
onRun == null ? void 0 : onRun(hookMap.get(name));
|
|
289
|
+
return latestResult;
|
|
290
|
+
};
|
|
407
291
|
function add(callback) {
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
292
|
+
const hookSet = hookMap.get(name);
|
|
293
|
+
if (hookSet)
|
|
294
|
+
hookSet.add(callback);
|
|
295
|
+
else
|
|
296
|
+
hookMap.set(name, /* @__PURE__ */ new Set([callback]));
|
|
297
|
+
onAdd == null ? void 0 : onAdd(hookSet);
|
|
298
|
+
return () => {
|
|
299
|
+
var _a;
|
|
300
|
+
(_a = hookMap.get(name)) == null ? void 0 : _a.delete(callback);
|
|
301
|
+
};
|
|
414
302
|
}
|
|
415
|
-
return [run, add
|
|
303
|
+
return [run, add];
|
|
416
304
|
}
|
|
417
305
|
let resolveOnInitPromise = () => {
|
|
418
306
|
};
|
|
@@ -420,246 +308,313 @@ let isInit = false;
|
|
|
420
308
|
const waitOnInit = new Promise((resolve) => {
|
|
421
309
|
resolveOnInitPromise = resolve;
|
|
422
310
|
});
|
|
423
|
-
const [runOnInit, onInit
|
|
311
|
+
const [runOnInit, onInit] = createHook("onInit", {
|
|
424
312
|
onRun(callbacks) {
|
|
425
313
|
isInit = true;
|
|
426
314
|
resolveOnInitPromise();
|
|
427
315
|
logger.debug("Initialization completed");
|
|
428
|
-
callbacks.clear();
|
|
316
|
+
callbacks == null ? void 0 : callbacks.clear();
|
|
429
317
|
},
|
|
430
318
|
onAdd() {
|
|
431
319
|
if (isInit)
|
|
432
|
-
runOnInit();
|
|
320
|
+
runOnInit().catch(logger.error);
|
|
433
321
|
}
|
|
434
322
|
});
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
resolveOnDisposePromise();
|
|
445
|
-
logger.debug("Disposal completed");
|
|
446
|
-
callbacks.clear();
|
|
447
|
-
},
|
|
448
|
-
onAdd() {
|
|
449
|
-
if (isDisposed)
|
|
450
|
-
runOnDispose();
|
|
323
|
+
const [runOnRequest, onRequest] = createHook("onRequest");
|
|
324
|
+
const [runOnResponse, onResponse] = createHook("onResponse");
|
|
325
|
+
const numberLike = union([coerce.string().regex(/^\d+$/), literal("")]).transform((value) => value === "" ? void 0 : Number(value));
|
|
326
|
+
const booleanLike = union([coerce.boolean(), literal("")]);
|
|
327
|
+
const urlLike = union([coerce.string(), literal("")]).transform((value) => {
|
|
328
|
+
try {
|
|
329
|
+
return new URL(value);
|
|
330
|
+
} catch {
|
|
331
|
+
return void 0;
|
|
451
332
|
}
|
|
452
333
|
});
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
location: mergedOptions.location,
|
|
476
|
-
consent: mergedOptions.consent,
|
|
477
|
-
debug: mergedOptions.debug,
|
|
478
|
-
getAll,
|
|
479
|
-
get,
|
|
480
|
-
options: mergedOptions,
|
|
481
|
-
logger
|
|
334
|
+
const dateLike = union([coerce.string(), literal("")]).transform((value) => {
|
|
335
|
+
if (value === "")
|
|
336
|
+
return void 0;
|
|
337
|
+
const date = new Date(numberLike.safeParse(value).success ? Number(value) : value);
|
|
338
|
+
if (Number.isNaN(date.getTime()))
|
|
339
|
+
return void 0;
|
|
340
|
+
return date;
|
|
341
|
+
});
|
|
342
|
+
const cssValueLike = union([coerce.string(), literal(""), number()]).transform((value) => {
|
|
343
|
+
if (value === "" || value === 0 || value === "0")
|
|
344
|
+
return void 0;
|
|
345
|
+
if (numberLike.parse(value))
|
|
346
|
+
return `${numberLike.parse(value)}px`;
|
|
347
|
+
return String(value);
|
|
348
|
+
});
|
|
349
|
+
const isJson = string().transform((value, { addIssue }) => {
|
|
350
|
+
try {
|
|
351
|
+
return JSON.parse(value.replaceAll("'", '"'));
|
|
352
|
+
} catch (error) {
|
|
353
|
+
addIssue({
|
|
354
|
+
code: ZodIssueCode.custom,
|
|
355
|
+
message: `Invalid JSON: ${error.message}`
|
|
482
356
|
});
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
queries: mergedOptions.queries
|
|
357
|
+
return NEVER;
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
const isHtmlString = string().transform((value, { addIssue }) => {
|
|
361
|
+
var _a;
|
|
362
|
+
const htmlParser = new DOMParser();
|
|
363
|
+
try {
|
|
364
|
+
const html = htmlParser.parseFromString(value, "text/html");
|
|
365
|
+
if (((_a = html.body) == null ? void 0 : _a.children.length) === 0)
|
|
366
|
+
throw new Error("Invalid HTML");
|
|
367
|
+
return value;
|
|
368
|
+
} catch (error) {
|
|
369
|
+
addIssue({
|
|
370
|
+
code: ZodIssueCode.custom,
|
|
371
|
+
message: error.message
|
|
499
372
|
});
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
373
|
+
return NEVER;
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
const isJsonOrHtmlString = union([isJson, isHtmlString]);
|
|
377
|
+
const isJsonOrHtmlOptionalString = union([coerce.string(), isJsonOrHtmlString]).transform((value) => {
|
|
378
|
+
if (value === "")
|
|
379
|
+
return void 0;
|
|
380
|
+
return value;
|
|
381
|
+
}).optional();
|
|
382
|
+
const baseSchema = object({
|
|
383
|
+
adDuration: numberLike.optional(),
|
|
384
|
+
adFormat: string().optional(),
|
|
385
|
+
adType: string(),
|
|
386
|
+
additionalCreativeTracker: urlLike.optional(),
|
|
387
|
+
additionalViewableTracker: string().optional(),
|
|
388
|
+
adspaceEnd: dateLike.optional(),
|
|
389
|
+
adspaceId: string().optional(),
|
|
390
|
+
adspaceKey: string().optional(),
|
|
391
|
+
adspaceStart: dateLike.optional(),
|
|
392
|
+
advertiserId: string().optional(),
|
|
393
|
+
altText: string().optional(),
|
|
394
|
+
auctionable: booleanLike.optional(),
|
|
395
|
+
body: isJsonOrHtmlOptionalString,
|
|
396
|
+
clickTag: urlLike.optional(),
|
|
397
|
+
comment: string().optional(),
|
|
398
|
+
creativeName: string().optional(),
|
|
399
|
+
deliveryGroupId: string().optional(),
|
|
400
|
+
deliveryMultiples: string().optional(),
|
|
401
|
+
ext: string().optional(),
|
|
402
|
+
extension: object({
|
|
403
|
+
mediaType: string(),
|
|
404
|
+
prebid: unknown().optional()
|
|
405
|
+
}).optional(),
|
|
406
|
+
height: numberLike.optional(),
|
|
407
|
+
id: string(),
|
|
408
|
+
impressionCounter: urlLike.optional(),
|
|
409
|
+
libId: string().optional(),
|
|
410
|
+
orderId: string().optional(),
|
|
411
|
+
orderName: string().optional(),
|
|
412
|
+
orderProperty: string().optional(),
|
|
413
|
+
origin: union([literal("JERLICIA"), literal("DALE")]),
|
|
414
|
+
originData: unknown().optional(),
|
|
415
|
+
originInstance: string().optional(),
|
|
416
|
+
poolPath: urlLike.optional(),
|
|
417
|
+
preview: booleanLike.optional(),
|
|
418
|
+
priority: numberLike.optional(),
|
|
419
|
+
sfSrc: urlLike.optional(),
|
|
420
|
+
share: string().optional(),
|
|
421
|
+
// eslint-disable-next-line ts/naming-convention
|
|
422
|
+
slotID: string(),
|
|
423
|
+
slotName: string(),
|
|
424
|
+
swfSrc: urlLike.optional(),
|
|
425
|
+
tag: isJsonOrHtmlOptionalString,
|
|
426
|
+
tagUrl: urlLike.optional(),
|
|
427
|
+
timeStamp: dateLike.optional(),
|
|
428
|
+
trackedImpressionCounter: urlLike.optional(),
|
|
429
|
+
tracker: urlLike.optional(),
|
|
430
|
+
trackingUrl: urlLike.optional(),
|
|
431
|
+
url: urlLike.optional(),
|
|
432
|
+
viewableImpressionCounter: urlLike.optional(),
|
|
433
|
+
width: numberLike.optional(),
|
|
434
|
+
widthLarge: cssValueLike.optional()
|
|
435
|
+
});
|
|
436
|
+
const jerliciaSchema = object({
|
|
437
|
+
origin: literal("JERLICIA"),
|
|
438
|
+
tag: isJsonOrHtmlString
|
|
439
|
+
}).passthrough();
|
|
440
|
+
const daleSchema = object({
|
|
441
|
+
origin: literal("DALE"),
|
|
442
|
+
body: isJsonOrHtmlString
|
|
443
|
+
}).passthrough().transform(({ body, ...data }) => ({
|
|
444
|
+
...data,
|
|
445
|
+
tag: body
|
|
446
|
+
}));
|
|
447
|
+
const adResponseSchema = baseSchema.extend({
|
|
448
|
+
additionalCreatives: lazy(() => union([adResponseSchema.array(), string()]).optional())
|
|
449
|
+
});
|
|
450
|
+
const adSchema = adResponseSchema.transform(({
|
|
451
|
+
additionalCreatives,
|
|
452
|
+
...data
|
|
453
|
+
}) => {
|
|
454
|
+
const filteredValue = Object.fromEntries(
|
|
455
|
+
Object.entries(data).filter(([, value]) => Boolean(value) && JSON.stringify(value) !== "{}" && JSON.stringify(value) !== "[]")
|
|
456
|
+
);
|
|
457
|
+
return {
|
|
458
|
+
...filteredValue,
|
|
459
|
+
additionalCreatives: Array.isArray(additionalCreatives) ? additionalCreatives.map((creative) => adSchema.parse(creative)) : additionalCreatives
|
|
460
|
+
};
|
|
461
|
+
});
|
|
462
|
+
function parseResponse(response) {
|
|
463
|
+
const schemaMap = {
|
|
464
|
+
/* eslint-disable ts/naming-convention */
|
|
465
|
+
JERLICIA: jerliciaSchema,
|
|
466
|
+
DALE: daleSchema
|
|
467
|
+
/* eslint-enable ts/naming-convention */
|
|
468
|
+
};
|
|
469
|
+
const preParsed = adResponseSchema.array().parse(response);
|
|
470
|
+
return preParsed.map((item) => {
|
|
471
|
+
const schema = schemaMap[item.origin];
|
|
472
|
+
if (!schema)
|
|
473
|
+
return adSchema.parse(item);
|
|
474
|
+
return schema.parse(item);
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
async function requestPreviews(account) {
|
|
478
|
+
const previewObjects = getPreviewObjects();
|
|
479
|
+
const list = (await Promise.allSettled(previewObjects.filter((previewObject) => "adhesePreviewCreativeId" in previewObject).map(async (previewObject) => {
|
|
480
|
+
const endpoint = new URL(`https://${account}-preview.adhese.org/creatives/preview/json/tag.do`);
|
|
481
|
+
endpoint.searchParams.set(
|
|
482
|
+
"id",
|
|
483
|
+
previewObject.adhesePreviewCreativeId
|
|
484
|
+
);
|
|
485
|
+
const response = await fetch(endpoint.href, {
|
|
486
|
+
method: "GET",
|
|
487
|
+
headers: {
|
|
488
|
+
accept: "application/json"
|
|
549
489
|
}
|
|
550
|
-
|
|
490
|
+
});
|
|
491
|
+
if (!response.ok)
|
|
492
|
+
return Promise.reject(new Error(`Failed to request preview ad with ID: ${previewObject.adhesePreviewCreativeId}`));
|
|
493
|
+
return await response.json();
|
|
494
|
+
}))).filter((response) => {
|
|
495
|
+
if (response.status === "rejected") {
|
|
496
|
+
logger.error(response.reason);
|
|
497
|
+
return false;
|
|
551
498
|
}
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
499
|
+
return response.status === "fulfilled";
|
|
500
|
+
}).map((response) => response.value.map((item) => ({
|
|
501
|
+
...item,
|
|
502
|
+
preview: true
|
|
503
|
+
})));
|
|
504
|
+
return adSchema.array().parse(list.flat());
|
|
505
|
+
}
|
|
506
|
+
function getPreviewObjects() {
|
|
507
|
+
const currentUrl = new URL(window.location.href);
|
|
508
|
+
const previewObjects = [];
|
|
509
|
+
let currentObject = {};
|
|
510
|
+
for (const [key, value] of currentUrl.searchParams.entries()) {
|
|
511
|
+
if (key === "adhesePreviewCreativeId" && Object.keys(currentObject).length > 0) {
|
|
512
|
+
previewObjects.push(currentObject);
|
|
513
|
+
currentObject = {};
|
|
566
514
|
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
515
|
+
currentObject[key] = value;
|
|
516
|
+
}
|
|
517
|
+
if (Object.keys(currentObject).length > 0)
|
|
518
|
+
previewObjects.push(currentObject);
|
|
519
|
+
return previewObjects;
|
|
520
|
+
}
|
|
521
|
+
function requestWithPost({
|
|
522
|
+
context: { options: { host }, parameters },
|
|
523
|
+
...options
|
|
524
|
+
}) {
|
|
525
|
+
const payload = {
|
|
526
|
+
...options,
|
|
527
|
+
slots: options.slots.map((slot) => ({
|
|
528
|
+
slotname: toValue(slot.name),
|
|
529
|
+
parameters: parseParameters(slot.parameters)
|
|
530
|
+
})),
|
|
531
|
+
parameters: parameters && parseParameters(parameters)
|
|
532
|
+
};
|
|
533
|
+
return fetch(`${new URL(host).href}json`, {
|
|
534
|
+
method: "POST",
|
|
535
|
+
body: JSON.stringify(payload),
|
|
536
|
+
headers: {
|
|
537
|
+
// eslint-disable-next-line ts/naming-convention
|
|
538
|
+
"Content-Type": "application/json"
|
|
580
539
|
}
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
for (const ad of ads) {
|
|
590
|
-
const slot = slotManager.get(ad.slotName);
|
|
591
|
-
if (slot)
|
|
592
|
-
slot.ad.value = ad;
|
|
593
|
-
}
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
async function requestWithGet({ context, slots }) {
|
|
543
|
+
return fetch(new URL(`${context.options.host}/json/sl${slots.map((slot) => toValue(slot.name)).join("/sl")}`), {
|
|
544
|
+
method: "GET",
|
|
545
|
+
headers: {
|
|
546
|
+
// eslint-disable-next-line ts/naming-convention
|
|
547
|
+
"Content-Type": "application/json"
|
|
594
548
|
}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
function parseParameters(parameters) {
|
|
552
|
+
return Object.fromEntries(Array.from(parameters.entries()).filter(([key]) => {
|
|
553
|
+
if (key.length === 2)
|
|
554
|
+
return true;
|
|
555
|
+
logger.warn(`Invalid parameter key: ${key}. Key should be exactly 2 characters long. Key will be ignored.`);
|
|
556
|
+
return false;
|
|
557
|
+
}).map(([key, value]) => {
|
|
558
|
+
if (typeof value === "string")
|
|
559
|
+
return [key, filterSpecialChars(value)];
|
|
560
|
+
return [key, value.map(filterSpecialChars)];
|
|
561
|
+
}));
|
|
562
|
+
}
|
|
563
|
+
function filterSpecialChars(value) {
|
|
564
|
+
const specialRegex = /[^\p{L}\p{N}_]/gu;
|
|
565
|
+
return value.replaceAll(specialRegex, "_");
|
|
566
|
+
}
|
|
567
|
+
async function requestAds(requestOptions) {
|
|
568
|
+
var _a, _b, _c, _d, _e;
|
|
569
|
+
const options = await runOnRequest(requestOptions);
|
|
570
|
+
const { context } = options;
|
|
571
|
+
try {
|
|
572
|
+
(_a = context.events) == null ? void 0 : _a.requestAd.dispatch({
|
|
573
|
+
...options,
|
|
574
|
+
context
|
|
605
575
|
});
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
logger.
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
}
|
|
621
|
-
for (const plugin of mergedOptions.plugins)
|
|
622
|
-
plugin(context);
|
|
623
|
-
onInit(async () => {
|
|
624
|
-
var _a;
|
|
625
|
-
if ((slotManager.getAll().length ?? 0) > 0)
|
|
626
|
-
await fetchAndRenderAllSlots().catch(logger.error);
|
|
627
|
-
if (mergedOptions.findDomSlotsOnLoad)
|
|
628
|
-
await findDomSlots2();
|
|
629
|
-
if (mergedOptions.debug || window.location.search.includes("adhese_debug=true") || isPreviewMode())
|
|
630
|
-
(_a = context.events) == null ? void 0 : _a.debugChange.dispatch(true);
|
|
631
|
-
if (!scope.active)
|
|
632
|
-
dispose();
|
|
576
|
+
const [response, previews] = await Promise.all([((_b = context.options.requestType) == null ? void 0 : _b.toUpperCase()) === "POST" ? requestWithPost(options) : requestWithGet(options), requestPreviews(context.options.account)]);
|
|
577
|
+
logger.debug("Received response", response);
|
|
578
|
+
if (!response.ok)
|
|
579
|
+
throw new Error(`Failed to request ad: ${response.status} ${response.statusText}`);
|
|
580
|
+
const result = parseResponse(await response.json());
|
|
581
|
+
logger.debug("Parsed ad", result);
|
|
582
|
+
if (previews.length > 0)
|
|
583
|
+
logger.info(`Found ${previews.length} ${previews.length === 1 ? "preview" : "previews"}. Replacing ads in response with preview items`, previews);
|
|
584
|
+
const matchedPreviews = previews.map(({ slotName, ...preview }) => {
|
|
585
|
+
const partnerAd = result.find((ad) => ad.libId === preview.libId);
|
|
586
|
+
return {
|
|
587
|
+
slotName: `${(partnerAd == null ? void 0 : partnerAd.slotName) ?? slotName}`,
|
|
588
|
+
...preview
|
|
589
|
+
};
|
|
633
590
|
});
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
...
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
};
|
|
650
|
-
});
|
|
591
|
+
if (matchedPreviews.length > 0)
|
|
592
|
+
(_c = context.events) == null ? void 0 : _c.previewReceived.dispatch(matchedPreviews);
|
|
593
|
+
const mergedResult = await runOnResponse([
|
|
594
|
+
...result.filter((ad) => !previews.some((preview) => preview.libId === ad.libId)),
|
|
595
|
+
...matchedPreviews
|
|
596
|
+
]);
|
|
597
|
+
if (mergedResult.length === 0)
|
|
598
|
+
throw new Error("No ads found");
|
|
599
|
+
(_d = context.events) == null ? void 0 : _d.responseReceived.dispatch(mergedResult);
|
|
600
|
+
return mergedResult;
|
|
601
|
+
} catch (error) {
|
|
602
|
+
logger.error(String(error));
|
|
603
|
+
(_e = context.events) == null ? void 0 : _e.requestError.dispatch(error);
|
|
604
|
+
throw error;
|
|
605
|
+
}
|
|
651
606
|
}
|
|
652
|
-
function
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
return document.body.appendChild(img);
|
|
607
|
+
async function requestAd({
|
|
608
|
+
slot,
|
|
609
|
+
...options
|
|
610
|
+
}) {
|
|
611
|
+
const [ad] = await requestAds({
|
|
612
|
+
slots: [slot],
|
|
613
|
+
...options
|
|
614
|
+
});
|
|
615
|
+
return ad;
|
|
662
616
|
}
|
|
617
|
+
const [runOnRender, onRender] = createHook("onRender");
|
|
663
618
|
function useViewabilityObserver({ context, ad, name, element }) {
|
|
664
619
|
let timeoutId = null;
|
|
665
620
|
const {
|
|
@@ -840,10 +795,10 @@ function createSlot(options) {
|
|
|
840
795
|
var _a, _b;
|
|
841
796
|
await waitForDomLoad();
|
|
842
797
|
await waitOnInit;
|
|
843
|
-
|
|
844
|
-
if (
|
|
845
|
-
|
|
846
|
-
|
|
798
|
+
let renderAd = adToRender ?? ad.value ?? originalAd.value ?? await requestAd$1();
|
|
799
|
+
if (renderAd)
|
|
800
|
+
renderAd = ((_a = options.onBeforeRender) == null ? void 0 : _a.call(options, renderAd)) ?? renderAd;
|
|
801
|
+
renderAd = await runOnRender(renderAd);
|
|
847
802
|
if (!element.value) {
|
|
848
803
|
const error = `Could not create slot for format ${format.value}. No element found.`;
|
|
849
804
|
logger.error(error, options);
|
|
@@ -851,8 +806,8 @@ function createSlot(options) {
|
|
|
851
806
|
}
|
|
852
807
|
if (context.debug)
|
|
853
808
|
element.value.style.position = "relative";
|
|
854
|
-
if (context.safeFrame &&
|
|
855
|
-
const position = context.safeFrame.addPosition(
|
|
809
|
+
if (context.safeFrame && renderAd && renderMode === "iframe") {
|
|
810
|
+
const position = context.safeFrame.addPosition(renderAd, element.value);
|
|
856
811
|
await context.safeFrame.render(position);
|
|
857
812
|
} else {
|
|
858
813
|
renderFunctions[renderMode](renderAd, element.value);
|
|
@@ -891,323 +846,378 @@ function createSlot(options) {
|
|
|
891
846
|
scope.stop();
|
|
892
847
|
}
|
|
893
848
|
return {
|
|
894
|
-
location: context.location,
|
|
895
|
-
lazyLoading: options.lazyLoading ?? false,
|
|
896
|
-
slot,
|
|
897
|
-
parameters,
|
|
898
|
-
format,
|
|
899
|
-
name,
|
|
900
|
-
ad,
|
|
901
|
-
isViewabilityTracked,
|
|
902
|
-
isImpressionTracked,
|
|
903
|
-
render,
|
|
904
|
-
getElement,
|
|
849
|
+
location: context.location,
|
|
850
|
+
lazyLoading: options.lazyLoading ?? false,
|
|
851
|
+
slot,
|
|
852
|
+
parameters,
|
|
853
|
+
format,
|
|
854
|
+
name,
|
|
855
|
+
ad,
|
|
856
|
+
isViewabilityTracked,
|
|
857
|
+
isImpressionTracked,
|
|
858
|
+
render,
|
|
859
|
+
getElement,
|
|
860
|
+
dispose
|
|
861
|
+
};
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
function useDomLoaded() {
|
|
865
|
+
const isDomLoaded = ref(false);
|
|
866
|
+
onInit(async () => {
|
|
867
|
+
await waitForDomLoad();
|
|
868
|
+
isDomLoaded.value = true;
|
|
869
|
+
});
|
|
870
|
+
return isDomLoaded;
|
|
871
|
+
}
|
|
872
|
+
async function findDomSlots(context) {
|
|
873
|
+
await waitForDomLoad();
|
|
874
|
+
return Array.from(document.querySelectorAll(".adunit")).filter((element) => {
|
|
875
|
+
var _a;
|
|
876
|
+
if (!element.dataset.format)
|
|
877
|
+
return false;
|
|
878
|
+
const name = generateName(
|
|
879
|
+
context.location,
|
|
880
|
+
element.dataset.format,
|
|
881
|
+
element.dataset.slot
|
|
882
|
+
);
|
|
883
|
+
return !((_a = context.getAll) == null ? void 0 : _a.call(context).some((activeSlot) => activeSlot.name.value === name));
|
|
884
|
+
}).map((element) => createSlot({
|
|
885
|
+
format: element.dataset.format,
|
|
886
|
+
containingElement: element,
|
|
887
|
+
slot: element.dataset.slot,
|
|
888
|
+
context
|
|
889
|
+
})).filter((slot) => {
|
|
890
|
+
var _a;
|
|
891
|
+
return !((_a = context.getAll) == null ? void 0 : _a.call(context).some((activeSlot) => activeSlot.name.value === slot.name.value));
|
|
892
|
+
});
|
|
893
|
+
}
|
|
894
|
+
function createSlotManager({
|
|
895
|
+
initialSlots = [],
|
|
896
|
+
context
|
|
897
|
+
}) {
|
|
898
|
+
const scope = effectScope();
|
|
899
|
+
return scope.run(() => {
|
|
900
|
+
const slots = shallowReactive(/* @__PURE__ */ new Map());
|
|
901
|
+
watchEffect(() => {
|
|
902
|
+
var _a;
|
|
903
|
+
(_a = context.events) == null ? void 0 : _a.changeSlots.dispatch(Array.from(slots.values()));
|
|
904
|
+
});
|
|
905
|
+
function getAll() {
|
|
906
|
+
return Array.from(slots).map(([, slot]) => slot);
|
|
907
|
+
}
|
|
908
|
+
function add(options) {
|
|
909
|
+
var _a;
|
|
910
|
+
const slot = createSlot({
|
|
911
|
+
...options,
|
|
912
|
+
onDispose: onDispose2,
|
|
913
|
+
context
|
|
914
|
+
});
|
|
915
|
+
function onDispose2() {
|
|
916
|
+
var _a2;
|
|
917
|
+
slots.delete(slot.name.value);
|
|
918
|
+
logger.debug("Slot removed", {
|
|
919
|
+
slot,
|
|
920
|
+
slots: Array.from(slots)
|
|
921
|
+
});
|
|
922
|
+
(_a2 = context.events) == null ? void 0 : _a2.removeSlot.dispatch(slot);
|
|
923
|
+
}
|
|
924
|
+
slots.set(slot.name.value, slot);
|
|
925
|
+
watch(slot.name, (newName, previousName) => {
|
|
926
|
+
slots.set(newName, slot);
|
|
927
|
+
slots.delete(previousName);
|
|
928
|
+
});
|
|
929
|
+
logger.debug("Slot added", {
|
|
930
|
+
slot,
|
|
931
|
+
slots: Array.from(slots.values())
|
|
932
|
+
});
|
|
933
|
+
(_a = context.events) == null ? void 0 : _a.addSlot.dispatch(slot);
|
|
934
|
+
return slot;
|
|
935
|
+
}
|
|
936
|
+
async function findDomSlots$1() {
|
|
937
|
+
const domSlots = await findDomSlots(
|
|
938
|
+
context
|
|
939
|
+
);
|
|
940
|
+
for (const slot of domSlots)
|
|
941
|
+
slots.set(slot.name.value, slot);
|
|
942
|
+
return domSlots;
|
|
943
|
+
}
|
|
944
|
+
function get(name) {
|
|
945
|
+
return slots.get(name);
|
|
946
|
+
}
|
|
947
|
+
function dispose() {
|
|
948
|
+
for (const slot of slots.values())
|
|
949
|
+
slot.dispose();
|
|
950
|
+
slots.clear();
|
|
951
|
+
scope.stop();
|
|
952
|
+
}
|
|
953
|
+
for (const options of initialSlots) {
|
|
954
|
+
add({
|
|
955
|
+
...options,
|
|
956
|
+
lazyLoading: false
|
|
957
|
+
});
|
|
958
|
+
}
|
|
959
|
+
return {
|
|
960
|
+
getAll,
|
|
961
|
+
add,
|
|
962
|
+
findDomSlots: findDomSlots$1,
|
|
963
|
+
get,
|
|
905
964
|
dispose
|
|
906
965
|
};
|
|
907
966
|
});
|
|
908
967
|
}
|
|
909
|
-
function
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
968
|
+
function onTcfConsentChange(callback) {
|
|
969
|
+
var _a;
|
|
970
|
+
(_a = window.__tcfapi) == null ? void 0 : _a.call(window, "addEventListener", 2, callback);
|
|
971
|
+
return () => {
|
|
972
|
+
var _a2;
|
|
973
|
+
return (_a2 = window.__tcfapi) == null ? void 0 : _a2.call(window, "removeEventListener", 2, callback);
|
|
974
|
+
};
|
|
916
975
|
}
|
|
917
|
-
|
|
918
|
-
const
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
976
|
+
function createParameters(options, queryDetector) {
|
|
977
|
+
const parameters = /* @__PURE__ */ new Map();
|
|
978
|
+
if (options.logReferrer)
|
|
979
|
+
parameters.set("re", btoa(document.referrer));
|
|
980
|
+
if (options.logUrl)
|
|
981
|
+
parameters.set("ur", btoa(window.location.href));
|
|
982
|
+
for (const [key, value] of Object.entries({
|
|
983
|
+
...options.parameters ?? {},
|
|
984
|
+
tl: options.consent ? "all" : "none",
|
|
985
|
+
dt: queryDetector.getQuery(),
|
|
986
|
+
br: queryDetector.getQuery(),
|
|
987
|
+
rn: Math.round(Math.random() * 1e4).toString()
|
|
988
|
+
}))
|
|
989
|
+
parameters.set(key, value);
|
|
990
|
+
return parameters;
|
|
991
|
+
}
|
|
992
|
+
function setupLogging(mergedOptions) {
|
|
993
|
+
if (mergedOptions.debug || window.location.search.includes("adhese_debug=true")) {
|
|
994
|
+
logger.setMinLogLevelThreshold("debug");
|
|
995
|
+
logger.debug("Debug logging enabled");
|
|
924
996
|
}
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
try {
|
|
943
|
-
return JSON.parse(value.replaceAll("'", '"'));
|
|
944
|
-
} catch (error) {
|
|
945
|
-
addIssue({
|
|
946
|
-
code: ZodIssueCode.custom,
|
|
947
|
-
message: `Invalid JSON: ${error.message}`
|
|
948
|
-
});
|
|
949
|
-
return NEVER;
|
|
997
|
+
logger.debug("Created Adhese SDK instance", {
|
|
998
|
+
mergedOptions
|
|
999
|
+
});
|
|
1000
|
+
}
|
|
1001
|
+
function isPreviewMode() {
|
|
1002
|
+
return window.location.search.includes("adhesePreviewCreativeId");
|
|
1003
|
+
}
|
|
1004
|
+
let isDisposed = false;
|
|
1005
|
+
const [runOnDispose, onDispose] = createHook("onDispose", {
|
|
1006
|
+
onRun(callbacks) {
|
|
1007
|
+
isDisposed = true;
|
|
1008
|
+
logger.debug("Disposal completed");
|
|
1009
|
+
callbacks == null ? void 0 : callbacks.clear();
|
|
1010
|
+
},
|
|
1011
|
+
onAdd() {
|
|
1012
|
+
if (isDisposed)
|
|
1013
|
+
runOnDispose().catch(logger.error);
|
|
950
1014
|
}
|
|
951
1015
|
});
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
1016
|
+
function createAdhese(options) {
|
|
1017
|
+
const scope = effectScope();
|
|
1018
|
+
return scope.run(() => {
|
|
1019
|
+
const mergedOptions = {
|
|
1020
|
+
host: `https://ads-${options.account}.adhese.com`,
|
|
1021
|
+
poolHost: `https://pool-${options.account}.adhese.com`,
|
|
1022
|
+
location: "homepage",
|
|
1023
|
+
requestType: "POST",
|
|
1024
|
+
debug: false,
|
|
1025
|
+
initialSlots: [],
|
|
1026
|
+
findDomSlotsOnLoad: false,
|
|
1027
|
+
consent: false,
|
|
1028
|
+
logReferrer: true,
|
|
1029
|
+
logUrl: true,
|
|
1030
|
+
safeFrame: false,
|
|
1031
|
+
eagerRendering: false,
|
|
1032
|
+
viewabilityTracking: true,
|
|
1033
|
+
plugins: [],
|
|
1034
|
+
...options
|
|
1035
|
+
};
|
|
1036
|
+
setupLogging(mergedOptions);
|
|
1037
|
+
const context = reactive({
|
|
1038
|
+
location: mergedOptions.location,
|
|
1039
|
+
consent: mergedOptions.consent,
|
|
1040
|
+
debug: mergedOptions.debug,
|
|
1041
|
+
getAll,
|
|
1042
|
+
get,
|
|
1043
|
+
options: mergedOptions,
|
|
1044
|
+
logger,
|
|
1045
|
+
addSlot
|
|
964
1046
|
});
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
auctionable: booleanLike.optional(),
|
|
987
|
-
body: isJsonOrHtmlOptionalString,
|
|
988
|
-
clickTag: urlLike.optional(),
|
|
989
|
-
comment: string().optional(),
|
|
990
|
-
creativeName: string().optional(),
|
|
991
|
-
deliveryGroupId: string().optional(),
|
|
992
|
-
deliveryMultiples: string().optional(),
|
|
993
|
-
ext: string().optional(),
|
|
994
|
-
extension: object({
|
|
995
|
-
mediaType: string(),
|
|
996
|
-
prebid: unknown().optional()
|
|
997
|
-
}).optional(),
|
|
998
|
-
height: numberLike.optional(),
|
|
999
|
-
id: string(),
|
|
1000
|
-
impressionCounter: urlLike.optional(),
|
|
1001
|
-
libId: string().optional(),
|
|
1002
|
-
orderId: string().optional(),
|
|
1003
|
-
orderName: string().optional(),
|
|
1004
|
-
orderProperty: string().optional(),
|
|
1005
|
-
origin: union([literal("JERLICIA"), literal("DALE")]),
|
|
1006
|
-
originData: unknown().optional(),
|
|
1007
|
-
originInstance: string().optional(),
|
|
1008
|
-
poolPath: urlLike.optional(),
|
|
1009
|
-
preview: booleanLike.optional(),
|
|
1010
|
-
priority: numberLike.optional(),
|
|
1011
|
-
sfSrc: urlLike.optional(),
|
|
1012
|
-
share: string().optional(),
|
|
1013
|
-
// eslint-disable-next-line ts/naming-convention
|
|
1014
|
-
slotID: string(),
|
|
1015
|
-
slotName: string(),
|
|
1016
|
-
swfSrc: urlLike.optional(),
|
|
1017
|
-
tag: isJsonOrHtmlOptionalString,
|
|
1018
|
-
tagUrl: urlLike.optional(),
|
|
1019
|
-
timeStamp: dateLike.optional(),
|
|
1020
|
-
trackedImpressionCounter: urlLike.optional(),
|
|
1021
|
-
tracker: urlLike.optional(),
|
|
1022
|
-
trackingUrl: urlLike.optional(),
|
|
1023
|
-
url: urlLike.optional(),
|
|
1024
|
-
viewableImpressionCounter: urlLike.optional(),
|
|
1025
|
-
width: numberLike.optional(),
|
|
1026
|
-
widthLarge: cssValueLike.optional()
|
|
1027
|
-
});
|
|
1028
|
-
const jerliciaSchema = object({
|
|
1029
|
-
origin: literal("JERLICIA"),
|
|
1030
|
-
tag: isJsonOrHtmlString
|
|
1031
|
-
}).passthrough();
|
|
1032
|
-
const daleSchema = object({
|
|
1033
|
-
origin: literal("DALE"),
|
|
1034
|
-
body: isJsonOrHtmlString
|
|
1035
|
-
}).passthrough().transform(({ body, ...data }) => ({
|
|
1036
|
-
...data,
|
|
1037
|
-
tag: body
|
|
1038
|
-
}));
|
|
1039
|
-
const adResponseSchema = baseSchema.extend({
|
|
1040
|
-
additionalCreatives: lazy(() => union([adResponseSchema.array(), string()]).optional())
|
|
1041
|
-
});
|
|
1042
|
-
const adSchema = adResponseSchema.transform(({
|
|
1043
|
-
additionalCreatives,
|
|
1044
|
-
...data
|
|
1045
|
-
}) => {
|
|
1046
|
-
const filteredValue = Object.fromEntries(
|
|
1047
|
-
Object.entries(data).filter(([, value]) => Boolean(value) && JSON.stringify(value) !== "{}" && JSON.stringify(value) !== "[]")
|
|
1048
|
-
);
|
|
1049
|
-
return {
|
|
1050
|
-
...filteredValue,
|
|
1051
|
-
additionalCreatives: Array.isArray(additionalCreatives) ? additionalCreatives.map((creative) => adSchema.parse(creative)) : additionalCreatives
|
|
1052
|
-
};
|
|
1053
|
-
});
|
|
1054
|
-
function parseResponse(response) {
|
|
1055
|
-
const schemaMap = {
|
|
1056
|
-
/* eslint-disable ts/naming-convention */
|
|
1057
|
-
JERLICIA: jerliciaSchema,
|
|
1058
|
-
DALE: daleSchema
|
|
1059
|
-
/* eslint-enable ts/naming-convention */
|
|
1060
|
-
};
|
|
1061
|
-
const preParsed = adResponseSchema.array().parse(response);
|
|
1062
|
-
return preParsed.map((item) => {
|
|
1063
|
-
const schema = schemaMap[item.origin];
|
|
1064
|
-
if (!schema)
|
|
1065
|
-
return adSchema.parse(item);
|
|
1066
|
-
return schema.parse(item);
|
|
1067
|
-
});
|
|
1068
|
-
}
|
|
1069
|
-
async function requestPreviews(account) {
|
|
1070
|
-
const previewObjects = getPreviewObjects();
|
|
1071
|
-
const list = (await Promise.allSettled(previewObjects.filter((previewObject) => "adhesePreviewCreativeId" in previewObject).map(async (previewObject) => {
|
|
1072
|
-
const endpoint = new URL(`https://${account}-preview.adhese.org/creatives/preview/json/tag.do`);
|
|
1073
|
-
endpoint.searchParams.set(
|
|
1074
|
-
"id",
|
|
1075
|
-
previewObject.adhesePreviewCreativeId
|
|
1076
|
-
);
|
|
1077
|
-
const response = await fetch(endpoint.href, {
|
|
1078
|
-
method: "GET",
|
|
1079
|
-
headers: {
|
|
1080
|
-
accept: "application/json"
|
|
1081
|
-
}
|
|
1047
|
+
for (const [index, plugin] of mergedOptions.plugins.entries()) {
|
|
1048
|
+
plugin(context, {
|
|
1049
|
+
index
|
|
1050
|
+
});
|
|
1051
|
+
}
|
|
1052
|
+
context.events = createEventManager();
|
|
1053
|
+
context.safeFrame = options.safeFrame ? createSafeFrame({
|
|
1054
|
+
renderFile: `${mergedOptions.poolHost}/sf/r.html`,
|
|
1055
|
+
context
|
|
1056
|
+
}) : void 0;
|
|
1057
|
+
function getLocation() {
|
|
1058
|
+
return context.location;
|
|
1059
|
+
}
|
|
1060
|
+
function setLocation(newLocation) {
|
|
1061
|
+
var _a;
|
|
1062
|
+
context.location = newLocation;
|
|
1063
|
+
(_a = context.events) == null ? void 0 : _a.locationChange.dispatch(newLocation);
|
|
1064
|
+
}
|
|
1065
|
+
const queryDetector = createQueryDetector({
|
|
1066
|
+
onChange: onQueryChange,
|
|
1067
|
+
queries: mergedOptions.queries
|
|
1082
1068
|
});
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1069
|
+
context.parameters = createParameters(mergedOptions, queryDetector);
|
|
1070
|
+
watch(
|
|
1071
|
+
context.parameters,
|
|
1072
|
+
onParametersChange,
|
|
1073
|
+
{
|
|
1074
|
+
deep: true,
|
|
1075
|
+
immediate: true
|
|
1076
|
+
}
|
|
1077
|
+
);
|
|
1078
|
+
function onParametersChange() {
|
|
1079
|
+
var _a;
|
|
1080
|
+
if (context.parameters)
|
|
1081
|
+
(_a = context.events) == null ? void 0 : _a.parametersChange.dispatch(context.parameters);
|
|
1090
1082
|
}
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
}
|
|
1098
|
-
function getPreviewObjects() {
|
|
1099
|
-
const currentUrl = new URL(window.location.href);
|
|
1100
|
-
const previewObjects = [];
|
|
1101
|
-
let currentObject = {};
|
|
1102
|
-
for (const [key, value] of currentUrl.searchParams.entries()) {
|
|
1103
|
-
if (key === "adhesePreviewCreativeId" && Object.keys(currentObject).length > 0) {
|
|
1104
|
-
previewObjects.push(currentObject);
|
|
1105
|
-
currentObject = {};
|
|
1083
|
+
async function onQueryChange() {
|
|
1084
|
+
var _a, _b;
|
|
1085
|
+
const query = queryDetector.getQuery();
|
|
1086
|
+
(_a = context.parameters) == null ? void 0 : _a.set("dt", query);
|
|
1087
|
+
(_b = context.parameters) == null ? void 0 : _b.set("br", query);
|
|
1088
|
+
await fetchAndRenderAllSlots();
|
|
1106
1089
|
}
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
if (Object.keys(currentObject).length > 0)
|
|
1110
|
-
previewObjects.push(currentObject);
|
|
1111
|
-
return previewObjects;
|
|
1112
|
-
}
|
|
1113
|
-
function requestWithPost({
|
|
1114
|
-
context: { options: { host }, parameters },
|
|
1115
|
-
...options
|
|
1116
|
-
}) {
|
|
1117
|
-
const payload = {
|
|
1118
|
-
...options,
|
|
1119
|
-
slots: options.slots.map((slot) => ({
|
|
1120
|
-
slotname: toValue(slot.name),
|
|
1121
|
-
parameters: parseParameters(slot.parameters)
|
|
1122
|
-
})),
|
|
1123
|
-
parameters: parameters && parseParameters(parameters)
|
|
1124
|
-
};
|
|
1125
|
-
return fetch(`${new URL(host).href}json`, {
|
|
1126
|
-
method: "POST",
|
|
1127
|
-
body: JSON.stringify(payload),
|
|
1128
|
-
headers: {
|
|
1129
|
-
// eslint-disable-next-line ts/naming-convention
|
|
1130
|
-
"Content-Type": "application/json"
|
|
1090
|
+
function getConsent() {
|
|
1091
|
+
return context.consent;
|
|
1131
1092
|
}
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
headers: {
|
|
1138
|
-
// eslint-disable-next-line ts/naming-convention
|
|
1139
|
-
"Content-Type": "application/json"
|
|
1093
|
+
function setConsent(newConsent) {
|
|
1094
|
+
var _a, _b;
|
|
1095
|
+
(_a = context.parameters) == null ? void 0 : _a.set("tl", newConsent ? "all" : "none");
|
|
1096
|
+
context.consent = newConsent;
|
|
1097
|
+
(_b = context.events) == null ? void 0 : _b.consentChange.dispatch(newConsent);
|
|
1140
1098
|
}
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
function parseParameters(parameters) {
|
|
1144
|
-
return Object.fromEntries(Array.from(parameters.entries()).filter(([key]) => {
|
|
1145
|
-
if (key.length === 2)
|
|
1146
|
-
return true;
|
|
1147
|
-
logger.warn(`Invalid parameter key: ${key}. Key should be exactly 2 characters long. Key will be ignored.`);
|
|
1148
|
-
return false;
|
|
1149
|
-
}).map(([key, value]) => {
|
|
1150
|
-
if (typeof value === "string")
|
|
1151
|
-
return [key, filterSpecialChars(value)];
|
|
1152
|
-
return [key, value.map(filterSpecialChars)];
|
|
1153
|
-
}));
|
|
1154
|
-
}
|
|
1155
|
-
function filterSpecialChars(value) {
|
|
1156
|
-
const specialRegex = /[^\p{L}\p{N}_]/gu;
|
|
1157
|
-
return value.replaceAll(specialRegex, "_");
|
|
1158
|
-
}
|
|
1159
|
-
async function requestAds(options) {
|
|
1160
|
-
var _a, _b, _c, _d, _e;
|
|
1161
|
-
const { context } = options;
|
|
1162
|
-
try {
|
|
1163
|
-
(_a = context.events) == null ? void 0 : _a.requestAd.dispatch({
|
|
1164
|
-
...options,
|
|
1099
|
+
const slotManager = createSlotManager({
|
|
1100
|
+
initialSlots: mergedOptions.initialSlots,
|
|
1165
1101
|
context
|
|
1166
1102
|
});
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1103
|
+
function getAll() {
|
|
1104
|
+
return slotManager.getAll() ?? [];
|
|
1105
|
+
}
|
|
1106
|
+
function get(name) {
|
|
1107
|
+
return slotManager.get(name);
|
|
1108
|
+
}
|
|
1109
|
+
function addSlot(slotOptions) {
|
|
1110
|
+
if (!slotManager)
|
|
1111
|
+
throw new Error("Slot manager not initialized");
|
|
1112
|
+
return slotManager.add(slotOptions);
|
|
1113
|
+
}
|
|
1114
|
+
async function findDomSlots2() {
|
|
1115
|
+
const domSlots = (await slotManager.findDomSlots() ?? []).filter((slot) => !slot.lazyLoading);
|
|
1116
|
+
if (domSlots.length <= 0)
|
|
1117
|
+
return [];
|
|
1118
|
+
const ads = await requestAds({
|
|
1119
|
+
slots: domSlots,
|
|
1120
|
+
context
|
|
1121
|
+
});
|
|
1122
|
+
for (const ad of ads) {
|
|
1123
|
+
const slot = slotManager.get(ad.slotName);
|
|
1124
|
+
if (slot)
|
|
1125
|
+
slot.ad.value = ad;
|
|
1126
|
+
}
|
|
1127
|
+
return domSlots;
|
|
1128
|
+
}
|
|
1129
|
+
async function toggleDebug() {
|
|
1130
|
+
var _a, _b;
|
|
1131
|
+
context.debug = !context.debug;
|
|
1132
|
+
if (context.debug) {
|
|
1133
|
+
logger.setMinLogLevelThreshold("debug");
|
|
1134
|
+
logger.debug("Debug mode enabled");
|
|
1135
|
+
(_a = context.events) == null ? void 0 : _a.debugChange.dispatch(true);
|
|
1136
|
+
} else {
|
|
1137
|
+
logger.debug("Debug mode disabled");
|
|
1138
|
+
logger.setMinLogLevelThreshold("info");
|
|
1139
|
+
(_b = context.events) == null ? void 0 : _b.debugChange.dispatch(false);
|
|
1140
|
+
}
|
|
1141
|
+
return context.debug;
|
|
1142
|
+
}
|
|
1143
|
+
async function fetchAndRenderAllSlots() {
|
|
1144
|
+
const slots = (slotManager.getAll() ?? []).filter((slot) => !slot.lazyLoading);
|
|
1145
|
+
if (slots.length === 0)
|
|
1146
|
+
return;
|
|
1147
|
+
const ads = await requestAds({
|
|
1148
|
+
slots,
|
|
1149
|
+
context
|
|
1150
|
+
});
|
|
1151
|
+
for (const ad of ads) {
|
|
1152
|
+
const slot = slotManager.get(ad.slotName);
|
|
1153
|
+
if (slot)
|
|
1154
|
+
slot.ad.value = ad;
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
const disposeOnTcfConsentChange = onTcfConsentChange(async (data) => {
|
|
1158
|
+
var _a, _b;
|
|
1159
|
+
if (!data.tcString)
|
|
1160
|
+
return;
|
|
1161
|
+
logger.debug("TCF v2 consent data received", {
|
|
1162
|
+
data
|
|
1163
|
+
});
|
|
1164
|
+
(_a = context.parameters) == null ? void 0 : _a.set("xt", data.tcString);
|
|
1165
|
+
(_b = context.parameters) == null ? void 0 : _b.delete("tl");
|
|
1166
|
+
await fetchAndRenderAllSlots();
|
|
1181
1167
|
});
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1168
|
+
function dispose() {
|
|
1169
|
+
var _a, _b;
|
|
1170
|
+
queryDetector.dispose();
|
|
1171
|
+
slotManager.dispose();
|
|
1172
|
+
queryDetector.dispose();
|
|
1173
|
+
disposeOnTcfConsentChange();
|
|
1174
|
+
(_a = context.parameters) == null ? void 0 : _a.clear();
|
|
1175
|
+
logger.resetLogs();
|
|
1176
|
+
(_b = context.events) == null ? void 0 : _b.dispose();
|
|
1177
|
+
logger.info("Adhese instance disposed");
|
|
1178
|
+
runOnDispose().catch(logger.error);
|
|
1179
|
+
clearAllHooks();
|
|
1180
|
+
scope.stop();
|
|
1181
|
+
}
|
|
1182
|
+
onInit(async () => {
|
|
1183
|
+
var _a;
|
|
1184
|
+
if ((slotManager.getAll().length ?? 0) > 0)
|
|
1185
|
+
await fetchAndRenderAllSlots().catch(logger.error);
|
|
1186
|
+
if (mergedOptions.findDomSlotsOnLoad)
|
|
1187
|
+
await findDomSlots2();
|
|
1188
|
+
if (mergedOptions.debug || window.location.search.includes("adhese_debug=true") || isPreviewMode())
|
|
1189
|
+
(_a = context.events) == null ? void 0 : _a.debugChange.dispatch(true);
|
|
1190
|
+
if (!scope.active)
|
|
1191
|
+
dispose();
|
|
1192
|
+
});
|
|
1193
|
+
runOnInit().catch(logger.error);
|
|
1194
|
+
return {
|
|
1195
|
+
parameters: context.parameters,
|
|
1196
|
+
events: context.events,
|
|
1197
|
+
getLocation,
|
|
1198
|
+
setLocation,
|
|
1199
|
+
getConsent,
|
|
1200
|
+
setConsent,
|
|
1201
|
+
addSlot,
|
|
1202
|
+
findDomSlots: findDomSlots2,
|
|
1203
|
+
dispose,
|
|
1204
|
+
toggleDebug,
|
|
1205
|
+
get: slotManager.get,
|
|
1206
|
+
getAll: slotManager.getAll,
|
|
1207
|
+
context,
|
|
1208
|
+
options: mergedOptions
|
|
1209
|
+
};
|
|
1205
1210
|
});
|
|
1206
|
-
return ad;
|
|
1207
1211
|
}
|
|
1208
1212
|
export {
|
|
1209
1213
|
createAdhese,
|
|
1214
|
+
logger,
|
|
1210
1215
|
onDispose,
|
|
1211
|
-
onInit
|
|
1216
|
+
onInit,
|
|
1217
|
+
onRender,
|
|
1218
|
+
onRequest,
|
|
1219
|
+
onResponse,
|
|
1220
|
+
requestAd,
|
|
1221
|
+
requestAds
|
|
1212
1222
|
};
|
|
1213
1223
|
//# sourceMappingURL=index.js.map
|