@highfivve/ad-tag 5.8.15 → 5.8.18

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.
@@ -30,11 +30,24 @@ export const createLabelConfigService = (labelSizeConfig, extraLabels, window) =
30
30
  supportedLabels.push(label);
31
31
  }
32
32
  };
33
+ const isLabelConditionMet = (labelCondition) => {
34
+ if ('labelAll' in labelCondition) {
35
+ return labelCondition.labelAll.every(label => supportedLabels.includes(label));
36
+ }
37
+ if ('labelAny' in labelCondition) {
38
+ return labelCondition.labelAny.some(label => supportedLabels.includes(label));
39
+ }
40
+ if ('labelNone' in labelCondition) {
41
+ return labelCondition.labelNone.every(label => !supportedLabels.includes(label));
42
+ }
43
+ return false;
44
+ };
33
45
  return {
34
46
  filterSlot,
35
47
  getSupportedLabels,
36
48
  getDeviceLabel,
37
- addLabel
49
+ addLabel,
50
+ isLabelConditionMet
38
51
  };
39
52
  };
40
53
  export const getDeviceLabel = (window, runtimeConfig, labelSizeConfig, targeting) => {
@@ -3,162 +3,166 @@ import { UserActivityService } from './userActivityService';
3
3
  import { mkConfigureStep } from '../../adPipeline';
4
4
  import { isNotNull } from 'ad-tag/util/arrayUtils';
5
5
  import { isAdvertiserIncluded } from 'ad-tag/ads/isAdvertiserIncluded';
6
- export class AdReload {
7
- constructor() {
8
- this.name = 'moli-ad-reload';
9
- this.description = 'Moli implementation of an ad reload module.';
10
- this.moduleType = 'ad-reload';
11
- this.moduleConfig = null;
12
- this.defaultRefreshIntervalMs = 20000;
13
- this.reloadKeyValue = 'native-ad-reload';
14
- this.initialized = false;
15
- this.initialize = (context, config, slotsToMonitor, reloadAdSlotCallback) => {
16
- if (context.env__ === 'test') {
17
- context.logger__.info('AdReload', 'disabled in environment test');
18
- return;
19
- }
20
- if (this.initialized) {
21
- return;
22
- }
23
- context.logger__.debug('AdReload', 'initialize moli ad reload module');
24
- this.setupAdVisibilityService(config, context.window__, context.logger__);
25
- this.setupSlotRenderListener(config, slotsToMonitor, reloadAdSlotCallback, context.window__, context.logger__);
26
- this.initialized = true;
27
- };
28
- this.setupAdVisibilityService = (config, window, logger) => {
29
- this.adVisibilityService = new AdVisibilityService(new UserActivityService(window, config.userActivityLevelControl, logger), config.refreshIntervalMs ?? this.defaultRefreshIntervalMs, config.refreshIntervalMsOverrides ?? {}, false, !!config.disableAdVisibilityChecks, config.viewabilityOverrides ?? {}, window, logger);
30
- };
31
- this.setupSlotRenderListener = (config, slotsToMonitor, reloadAdSlotCallback, window, logger) => window.googletag.pubads().addEventListener('slotRenderEnded', renderEndedEvent => {
32
- const { slot: googleTagSlot, campaignId, advertiserId, companyIds, yieldGroupIds, isEmpty: slotIsEmpty } = renderEndedEvent;
33
- const slotDomId = googleTagSlot.getSlotElementId();
34
- const slotIsMonitored = slotsToMonitor.indexOf(slotDomId) > -1;
35
- const orderIdNotExcluded = !campaignId || config.excludeOrderIds.indexOf(campaignId) === -1;
36
- const orderIdIncluded = !!campaignId && config.includeOrderIds.indexOf(campaignId) > -1;
37
- const advertiserIdIncluded = isAdvertiserIncluded(renderEndedEvent, config.includeAdvertiserIds);
38
- const yieldGroupIdIncluded = !!yieldGroupIds && config.includeYieldGroupIds.some(id => yieldGroupIds.indexOf(id) > -1);
39
- const trackingSlotAllowed = !slotIsEmpty &&
40
- slotIsMonitored &&
41
- orderIdNotExcluded &&
42
- (orderIdIncluded || advertiserIdIncluded || yieldGroupIdIncluded);
43
- if (!trackingSlotAllowed) {
44
- this.logTrackingDisallowedReason(slotDomId, {
45
- slotIsEmpty,
46
- slotIsMonitored,
47
- orderIdNotExcluded,
48
- orderIdIncluded,
49
- advertiserIdIncluded,
50
- yieldGroupIdIncluded
51
- }, logger, yieldGroupIds, campaignId, advertiserId);
52
- }
53
- const slotAlreadyTracked = !!this.adVisibilityService?.isSlotTracked(slotDomId);
54
- if (trackingSlotAllowed) {
55
- this.adVisibilityService.trackSlot(googleTagSlot, reloadAdSlotCallback, advertiserId, companyIds);
56
- }
57
- else if (slotAlreadyTracked) {
58
- this.adVisibilityService.removeSlotTracking(googleTagSlot);
59
- }
60
- });
61
- this.reloadAdSlot = (config, ctx) => (googleTagSlot) => {
62
- const slotId = googleTagSlot.getSlotElementId();
63
- const moliSlot = ctx.config__.slots.find(moliSlot => moliSlot.domId === slotId);
64
- if (moliSlot && moliSlot.behaviour.loaded !== 'infinite') {
65
- ctx.logger__.debug('AdReload', 'fired slot reload', moliSlot.domId);
66
- const sizesOverride = this.maybeOptimizeSlotForCls(config, moliSlot, googleTagSlot, ctx.logger__, ctx.window__);
67
- googleTagSlot.setTargeting(this.reloadKeyValue, 'true');
68
- const getBucketAndLoadingBehaviour = () => {
69
- const bucketOverride = config.viewabilityOverrides?.[slotId]?.refreshBucket;
70
- if (bucketOverride === true) {
71
- const loaded = moliSlot.behaviour.loaded;
72
- const bucket = moliSlot.behaviour.bucket;
73
- const bucketName = typeof bucket === 'string'
74
- ? bucket
75
- : bucket?.[ctx.labelConfigService__.getDeviceLabel()];
76
- return bucketName && loaded !== 'infinite' ? { name: bucketName, loaded } : undefined;
77
- }
78
- };
79
- const bucket = getBucketAndLoadingBehaviour();
80
- if (bucket) {
81
- ctx.window__.moli
82
- .refreshBucket(bucket.name, { loaded: bucket.loaded })
83
- .then(result => ctx.logger__.debug('AdReload', `refreshBucket '${bucket.name}' result`, result))
84
- .catch(error => ctx.logger__.error('AdReload', `refreshBucket '${bucket.name}' failed`, error));
85
- }
86
- else {
87
- ctx.window__.moli
88
- .refreshAdSlot(slotId, {
89
- loaded: moliSlot.behaviour.loaded,
90
- ...(sizesOverride && { sizesOverride: sizesOverride })
91
- })
92
- .catch(error => ctx.logger__.error('AdReload', `refreshing ${slotId} failed`, error));
6
+ export const createAdReload = () => {
7
+ const name = 'moli-ad-reload';
8
+ const defaultRefreshIntervalMs = 20000;
9
+ const reloadKeyValue = 'native-ad-reload';
10
+ let initialized = false;
11
+ let moduleConfig = null;
12
+ let adVisibilityService;
13
+ const config__ = () => moduleConfig;
14
+ const isInitialized = () => initialized;
15
+ const configure__ = (mConfig) => {
16
+ if (mConfig?.adReload?.enabled) {
17
+ moduleConfig = mConfig.adReload;
18
+ }
19
+ };
20
+ const initSteps__ = () => [];
21
+ const setupAdVisibilityService = (config, window, logger) => {
22
+ adVisibilityService = new AdVisibilityService(new UserActivityService(window, config.userActivityLevelControl, logger), config.refreshIntervalMs ?? defaultRefreshIntervalMs, config.refreshIntervalMsOverrides ?? {}, false, !!config.disableAdVisibilityChecks, config.viewabilityOverrides ?? {}, window, logger);
23
+ };
24
+ const logTrackingDisallowedReason = (slotDomId, reasons, logger, yieldGroupIds, campaignId, advertiserId) => {
25
+ const { slotIsEmpty, slotIsMonitored, orderIdNotExcluded, orderIdIncluded, advertiserIdIncluded, yieldGroupIdIncluded } = reasons;
26
+ if (slotIsEmpty) {
27
+ logger.debug('AdReload', slotDomId, 'slot not tracked: reported empty');
28
+ }
29
+ if (!slotIsMonitored) {
30
+ logger.debug('AdReload', slotDomId, 'slot not tracked: excluded by DOM id');
31
+ }
32
+ if (!orderIdNotExcluded) {
33
+ logger.debug('AdReload', slotDomId, 'slot not tracked: excluded by order id', campaignId);
34
+ }
35
+ if (!(orderIdIncluded || advertiserIdIncluded || yieldGroupIdIncluded)) {
36
+ logger.debug('AdReload', slotDomId, 'slot not tracked: neither order id', campaignId, 'nor advertiser id', advertiserId, 'nor yieldGroup id', yieldGroupIds, 'included');
37
+ }
38
+ };
39
+ const maybeOptimizeSlotForCls = (config, moliSlot, googleTagSlot, logger, _window) => {
40
+ const slotDomId = moliSlot.domId;
41
+ if (config.optimizeClsScoreDomIds.indexOf(slotDomId) > -1) {
42
+ const slotDomElement = _window.document.getElementById(slotDomId);
43
+ if (slotDomElement && !!slotDomElement.style) {
44
+ const slotHeight = slotDomElement.scrollHeight;
45
+ slotDomElement.style.setProperty('height', `${slotHeight}px`);
46
+ const newSlotSizes = moliSlot.sizes.filter(size => size !== 'fluid' && size[1] <= slotHeight);
47
+ logger.debug('AdReload', `CLS optimization: slot ${slotDomId} received fixed height ${slotHeight}px`, 'new sizes:', newSlotSizes);
48
+ if (newSlotSizes.length < moliSlot.sizes.filter(size => size !== 'fluid').length) {
49
+ _window.googletag.destroySlots([googleTagSlot]);
93
50
  }
51
+ return newSlotSizes;
94
52
  }
95
- };
96
- this.maybeOptimizeSlotForCls = (config, moliSlot, googleTagSlot, logger, _window) => {
97
- const slotDomId = moliSlot.domId;
98
- if (config.optimizeClsScoreDomIds.indexOf(slotDomId) > -1) {
99
- const slotDomElement = _window.document.getElementById(slotDomId);
100
- if (slotDomElement && !!slotDomElement.style) {
101
- const slotHeight = slotDomElement.scrollHeight;
102
- slotDomElement.style.setProperty('height', `${slotHeight}px`);
103
- const newSlotSizes = moliSlot.sizes.filter(size => size !== 'fluid' && size[1] <= slotHeight);
104
- logger.debug('AdReload', `CLS optimization: slot ${slotDomId} received fixed height ${slotHeight}px`, 'new sizes:', newSlotSizes);
105
- if (newSlotSizes.length < moliSlot.sizes.filter(size => size !== 'fluid').length) {
106
- _window.googletag.destroySlots([googleTagSlot]);
107
- }
108
- return newSlotSizes;
53
+ logger.warn('AdReload', `CLS optimization: slot ${slotDomId} to be optimized but not found in DOM.`);
54
+ }
55
+ return moliSlot.sizes;
56
+ };
57
+ const reloadAdSlot = (config, ctx) => (googleTagSlot) => {
58
+ const slotId = googleTagSlot.getSlotElementId();
59
+ const moliSlot = ctx.config__.slots.find(moliSlot => moliSlot.domId === slotId);
60
+ if (moliSlot && moliSlot.behaviour.loaded !== 'infinite') {
61
+ ctx.logger__.debug('AdReload', 'fired slot reload', moliSlot.domId);
62
+ const sizesOverride = maybeOptimizeSlotForCls(config, moliSlot, googleTagSlot, ctx.logger__, ctx.window__);
63
+ googleTagSlot.setTargeting(reloadKeyValue, 'true');
64
+ const getBucketAndLoadingBehaviour = () => {
65
+ const bucketOverride = config.viewabilityOverrides?.[slotId]?.refreshBucket;
66
+ if (bucketOverride === true) {
67
+ const loaded = moliSlot.behaviour.loaded;
68
+ const bucket = moliSlot.behaviour.bucket;
69
+ const bucketName = typeof bucket === 'string'
70
+ ? bucket
71
+ : bucket?.[ctx.labelConfigService__.getDeviceLabel()];
72
+ return bucketName && loaded !== 'infinite' ? { name: bucketName, loaded } : undefined;
109
73
  }
110
- logger.warn('AdReload', `CLS optimization: slot ${slotDomId} to be optimized but not found in DOM.`);
111
- }
112
- return moliSlot.sizes;
113
- };
114
- this.logTrackingDisallowedReason = (slotDomId, reasons, logger, yieldGroupIds, campaignId, advertiserId) => {
115
- const { slotIsEmpty, slotIsMonitored, orderIdNotExcluded, orderIdIncluded, advertiserIdIncluded, yieldGroupIdIncluded } = reasons;
116
- if (slotIsEmpty) {
117
- logger.debug('AdReload', slotDomId, 'slot not tracked: reported empty');
118
- }
119
- if (!slotIsMonitored) {
120
- logger.debug('AdReload', slotDomId, 'slot not tracked: excluded by DOM id');
74
+ };
75
+ const bucket = getBucketAndLoadingBehaviour();
76
+ if (bucket) {
77
+ ctx.window__.moli
78
+ .refreshBucket(bucket.name, { loaded: bucket.loaded })
79
+ .then(result => ctx.logger__.debug('AdReload', `refreshBucket '${bucket.name}' result`, result))
80
+ .catch(error => ctx.logger__.error('AdReload', `refreshBucket '${bucket.name}' failed`, error));
121
81
  }
122
- if (!orderIdNotExcluded) {
123
- logger.debug('AdReload', slotDomId, 'slot not tracked: excluded by order id', campaignId);
124
- }
125
- if (!(orderIdIncluded || advertiserIdIncluded || yieldGroupIdIncluded)) {
126
- logger.debug('AdReload', slotDomId, 'slot not tracked: neither order id', campaignId, 'nor advertiser id', advertiserId, 'nor yieldGroup id', yieldGroupIds, 'included');
82
+ else {
83
+ ctx.window__.moli
84
+ .refreshAdSlot(slotId, {
85
+ loaded: moliSlot.behaviour.loaded,
86
+ ...(sizesOverride && { sizesOverride: sizesOverride })
87
+ })
88
+ .catch(error => ctx.logger__.error('AdReload', `refreshing ${slotId} failed`, error));
127
89
  }
128
- };
129
- }
130
- config__() {
131
- return this.moduleConfig;
132
- }
133
- isInitialized() {
134
- return this.initialized;
135
- }
136
- configure__(moduleConfig) {
137
- if (moduleConfig?.adReload?.enabled) {
138
- this.moduleConfig = moduleConfig.adReload;
139
90
  }
140
- }
141
- initSteps__() {
142
- return [];
143
- }
144
- configureSteps__() {
145
- const config = this.moduleConfig;
91
+ };
92
+ const setupSlotRenderListener = (config, slotsToMonitor, reloadAdSlotCallback, window, logger) => window.googletag.pubads().addEventListener('slotRenderEnded', renderEndedEvent => {
93
+ const { slot: googleTagSlot, campaignId, advertiserId, companyIds, yieldGroupIds, isEmpty: slotIsEmpty } = renderEndedEvent;
94
+ const slotDomId = googleTagSlot.getSlotElementId();
95
+ const slotIsMonitored = slotsToMonitor.indexOf(slotDomId) > -1;
96
+ const orderIdNotExcluded = !campaignId || config.excludeOrderIds.indexOf(campaignId) === -1;
97
+ const orderIdIncluded = !!campaignId && config.includeOrderIds.indexOf(campaignId) > -1;
98
+ const advertiserIdIncluded = isAdvertiserIncluded(renderEndedEvent, config.includeAdvertiserIds);
99
+ const yieldGroupIdIncluded = !!yieldGroupIds && config.includeYieldGroupIds.some(id => yieldGroupIds.indexOf(id) > -1);
100
+ const trackingSlotAllowed = !slotIsEmpty &&
101
+ slotIsMonitored &&
102
+ orderIdNotExcluded &&
103
+ (orderIdIncluded || advertiserIdIncluded || yieldGroupIdIncluded);
104
+ if (!trackingSlotAllowed) {
105
+ logTrackingDisallowedReason(slotDomId, {
106
+ slotIsEmpty,
107
+ slotIsMonitored,
108
+ orderIdNotExcluded,
109
+ orderIdIncluded,
110
+ advertiserIdIncluded,
111
+ yieldGroupIdIncluded
112
+ }, logger, yieldGroupIds, campaignId, advertiserId);
113
+ }
114
+ const slotAlreadyTracked = !!adVisibilityService?.isSlotTracked(slotDomId);
115
+ if (trackingSlotAllowed) {
116
+ adVisibilityService.trackSlot(googleTagSlot, reloadAdSlotCallback, advertiserId, companyIds);
117
+ }
118
+ else if (slotAlreadyTracked) {
119
+ adVisibilityService.removeSlotTracking(googleTagSlot);
120
+ }
121
+ });
122
+ const initialize = (context, config, slotsToMonitor, reloadAdSlotCallback) => {
123
+ if (context.env__ === 'test') {
124
+ context.logger__.info('AdReload', 'disabled in environment test');
125
+ return;
126
+ }
127
+ if (initialized) {
128
+ return;
129
+ }
130
+ context.logger__.debug('AdReload', 'initialize moli ad reload module');
131
+ setupAdVisibilityService(config, context.window__, context.logger__);
132
+ setupSlotRenderListener(config, slotsToMonitor, reloadAdSlotCallback, context.window__, context.logger__);
133
+ initialized = true;
134
+ };
135
+ const configureSteps__ = () => {
136
+ const config = moduleConfig;
146
137
  return config
147
138
  ? [
148
- mkConfigureStep(this.name, context => {
139
+ mkConfigureStep(name, context => {
149
140
  const slotsToMonitor = context.config__.slots
150
141
  .filter(slot => config.excludeAdSlotDomIds.indexOf(slot.domId) === -1)
151
142
  .map(slot => slot.domId)
152
143
  .filter(isNotNull);
153
- const reloadAdSlotCallback = this.reloadAdSlot(config, context);
144
+ const reloadAdSlotCallback = reloadAdSlot(config, context);
154
145
  context.logger__.debug('AdReload', 'monitoring slots', slotsToMonitor);
155
- this.initialize(context, config, slotsToMonitor, reloadAdSlotCallback);
146
+ initialize(context, config, slotsToMonitor, reloadAdSlotCallback);
156
147
  return Promise.resolve();
157
148
  })
158
149
  ]
159
150
  : [];
160
- }
161
- prepareRequestAdsSteps__() {
162
- return [];
163
- }
164
- }
151
+ };
152
+ const prepareRequestAdsSteps__ = () => [];
153
+ return {
154
+ name,
155
+ description: 'Moli implementation of an ad reload module.',
156
+ moduleType: 'ad-reload',
157
+ config__,
158
+ configure__,
159
+ initSteps__,
160
+ configureSteps__,
161
+ prepareRequestAdsSteps__,
162
+ isInitialized,
163
+ initialize,
164
+ get adVisibilityService() {
165
+ return adVisibilityService;
166
+ }
167
+ };
168
+ };
@@ -6,113 +6,86 @@ import { tcfapi } from 'ad-tag/types/tcfapi';
6
6
  var TCPurpose = tcfapi.responses.TCPurpose;
7
7
  import { toAdexListType, toAdexMapType, toAdexStringOrNumberType } from 'ad-tag/ads/modules/adex/adex-mapping';
8
8
  import { trackUtiqId } from 'ad-tag/ads/modules/adex/adexUtiq';
9
- export class AdexModule {
10
- constructor() {
11
- this.name = 'the-adex-dmp';
12
- this.description = 'Moli DMP module for The Adex.';
13
- this.moduleType = 'dmp';
14
- this.adexConfig = null;
15
- this.isLoaded = false;
16
- this.hasRequiredConsent = (tcData) => !tcData.gdprApplies ||
17
- (tcData.vendor.consents['44'] &&
18
- [
19
- TCPurpose.STORE_INFORMATION_ON_DEVICE,
20
- TCPurpose.SELECT_BASIC_ADS,
21
- TCPurpose.CREATE_PERSONALISED_ADS_PROFILE,
22
- TCPurpose.SELECT_PERSONALISED_ADS,
23
- TCPurpose.CREATE_PERSONALISED_CONTENT_PROFILE,
24
- TCPurpose.SELECT_PERSONALISED_CONTENT,
25
- TCPurpose.MEASURE_AD_PERFORMANCE,
26
- TCPurpose.MEASURE_CONTENT_PERFORMANCE,
27
- TCPurpose.APPLY_MARKET_RESEARCH,
28
- TCPurpose.DEVELOP_IMPROVE_PRODUCTS
29
- ].every(purpose => tcData.purpose.consents[purpose]));
30
- this.getOrInitAdexQueue = (_window) => {
31
- const adexWindow = _window;
32
- adexWindow._adexc = adexWindow._adexc || [];
33
- return adexWindow;
34
- };
35
- this.getAdexKeyValues = (context, config) => {
36
- const gamKeyValues = {
37
- ...context.config__.targeting?.keyValues,
38
- ...context.runtimeConfig__.keyValues
39
- };
40
- if (Object.keys(gamKeyValues).length > 0) {
41
- return config.mappingDefinitions
42
- .map(def => {
43
- switch (def.adexValueType) {
44
- case 'map':
45
- return toAdexMapType(gamKeyValues, def, context.logger__);
46
- case 'list':
47
- return toAdexListType(gamKeyValues, def, context.logger__);
48
- default:
49
- return toAdexStringOrNumberType(gamKeyValues, def, context.logger__);
50
- }
51
- })
52
- .filter(isNotNull);
53
- }
54
- };
55
- this.configureAdexC = (context, config) => {
56
- const adexWindow = this.getOrInitAdexQueue(context.window__);
57
- const adexKeyValues = this.getAdexKeyValues(context, config);
58
- if (!adexKeyValues) {
59
- context.logger__.warn('Adex DMP', 'targeting key/values are empty');
60
- }
61
- else {
62
- adexWindow._adexc.push([
63
- `/${config.adexCustomerId}/${config.adexTagId}/`,
64
- 'ut',
65
- '_kv',
66
- [
67
- adexKeyValues.reduce((aggregator, additionalKeyValue) => ({ ...aggregator, ...additionalKeyValue }), {}),
68
- config.spaMode ? 1 : 0
69
- ]
70
- ]);
71
- }
72
- if (config.enabledPartners?.includes('utiq')) {
73
- trackUtiqId(config, context.window__);
74
- }
75
- };
76
- }
77
- config__() {
78
- return this.adexConfig;
79
- }
80
- configure__(moduleConfig) {
9
+ export const createAdexModule = () => {
10
+ const name = 'the-adex-dmp';
11
+ let adexConfig = null;
12
+ let isLoaded = false;
13
+ const config__ = () => adexConfig;
14
+ const configure__ = (moduleConfig) => {
81
15
  if (moduleConfig?.adex && moduleConfig.adex.enabled) {
82
- this.adexConfig = moduleConfig.adex;
16
+ adexConfig = moduleConfig.adex;
83
17
  }
84
- }
85
- initSteps__() {
86
- const config = this.adexConfig;
87
- if (config) {
88
- return [mkInitStep('DMP module setup', context => this.track(context, config))];
18
+ };
19
+ const getOrInitAdexQueue = (_window) => {
20
+ const adexWindow = _window;
21
+ adexWindow._adexc = adexWindow._adexc || [];
22
+ return adexWindow;
23
+ };
24
+ const getAdexKeyValues = (context, config) => {
25
+ const gamKeyValues = {
26
+ ...context.config__.targeting?.keyValues,
27
+ ...context.runtimeConfig__.keyValues
28
+ };
29
+ if (Object.keys(gamKeyValues).length > 0) {
30
+ return config.mappingDefinitions
31
+ .map(def => {
32
+ switch (def.adexValueType) {
33
+ case 'map':
34
+ return toAdexMapType(gamKeyValues, def, context.logger__);
35
+ case 'list':
36
+ return toAdexListType(gamKeyValues, def, context.logger__);
37
+ default:
38
+ return toAdexStringOrNumberType(gamKeyValues, def, context.logger__);
39
+ }
40
+ })
41
+ .filter(isNotNull);
89
42
  }
90
- return [];
91
- }
92
- configureSteps__() {
93
- const config = this.adexConfig;
94
- if (config?.spaMode) {
95
- return [
96
- mkConfigureStep('DMP module setup', context => {
97
- this.configureAdexC(context, config);
98
- return Promise.resolve();
99
- })
100
- ];
43
+ };
44
+ const hasRequiredConsent = (tcData) => !tcData.gdprApplies ||
45
+ (tcData.vendor.consents['44'] &&
46
+ [
47
+ TCPurpose.STORE_INFORMATION_ON_DEVICE,
48
+ TCPurpose.SELECT_BASIC_ADS,
49
+ TCPurpose.CREATE_PERSONALISED_ADS_PROFILE,
50
+ TCPurpose.SELECT_PERSONALISED_ADS,
51
+ TCPurpose.CREATE_PERSONALISED_CONTENT_PROFILE,
52
+ TCPurpose.SELECT_PERSONALISED_CONTENT,
53
+ TCPurpose.MEASURE_AD_PERFORMANCE,
54
+ TCPurpose.MEASURE_CONTENT_PERFORMANCE,
55
+ TCPurpose.APPLY_MARKET_RESEARCH,
56
+ TCPurpose.DEVELOP_IMPROVE_PRODUCTS
57
+ ].every(purpose => tcData.purpose.consents[purpose]));
58
+ const configureAdexC = (context, config) => {
59
+ const adexWindow = getOrInitAdexQueue(context.window__);
60
+ const adexKeyValues = getAdexKeyValues(context, config);
61
+ if (!adexKeyValues) {
62
+ context.logger__.warn('Adex DMP', 'targeting key/values are empty');
101
63
  }
102
- return [];
103
- }
104
- track(context, adexConfig) {
105
- const { adexCustomerId, adexTagId, appConfig, appName } = adexConfig;
106
- this.configureAdexC(context, adexConfig);
107
- const adexKeyValues = this.getAdexKeyValues(context, adexConfig);
64
+ else {
65
+ adexWindow._adexc.push([
66
+ `/${config.adexCustomerId}/${config.adexTagId}/`,
67
+ 'ut',
68
+ '_kv',
69
+ [
70
+ adexKeyValues.reduce((aggregator, additionalKeyValue) => ({ ...aggregator, ...additionalKeyValue }), {}),
71
+ config.spaMode ? 1 : 0
72
+ ]
73
+ ]);
74
+ }
75
+ if (config.enabledPartners?.includes('utiq')) {
76
+ trackUtiqId(config, context.window__);
77
+ }
78
+ };
79
+ const track = (context, config) => {
80
+ const { adexCustomerId, adexTagId, appConfig, appName } = config;
81
+ configureAdexC(context, config);
82
+ const adexKeyValues = getAdexKeyValues(context, config);
108
83
  const gamKeyValues = {
109
84
  ...context.config__.targeting?.keyValues,
110
85
  ...context.runtimeConfig__.keyValues
111
86
  };
112
- if (this.hasRequiredConsent(context.tcData__) &&
113
- !this.isLoaded &&
114
- Object.keys(gamKeyValues).length > 0) {
115
- this.isLoaded = true;
87
+ if (hasRequiredConsent(context.tcData__) && !isLoaded && Object.keys(gamKeyValues).length > 0) {
88
+ isLoaded = true;
116
89
  const hasValidMobileKeyValues = isNotNull(appConfig) &&
117
90
  isNotNull(gamKeyValues[appConfig.advertiserIdKey]) &&
118
91
  (gamKeyValues[appConfig.clientTypeKey] === 'android' ||
@@ -127,7 +100,7 @@ export class AdexModule {
127
100
  else {
128
101
  context.assetLoaderService__
129
102
  .loadScript({
130
- name: this.name,
103
+ name,
131
104
  assetUrl: `https://dmp.theadex.com/d/${adexCustomerId}/${adexTagId}/s/adex.js`,
132
105
  loadMethod: AssetLoadMethod.TAG
133
106
  })
@@ -135,8 +108,37 @@ export class AdexModule {
135
108
  }
136
109
  }
137
110
  return Promise.resolve();
138
- }
139
- prepareRequestAdsSteps__() {
111
+ };
112
+ const initSteps__ = () => {
113
+ const config = adexConfig;
114
+ if (config) {
115
+ return [mkInitStep('DMP module setup', context => track(context, config))];
116
+ }
117
+ return [];
118
+ };
119
+ const configureSteps__ = () => {
120
+ const config = adexConfig;
121
+ if (config?.spaMode) {
122
+ return [
123
+ mkConfigureStep('DMP module setup', context => {
124
+ configureAdexC(context, config);
125
+ return Promise.resolve();
126
+ })
127
+ ];
128
+ }
140
129
  return [];
141
- }
142
- }
130
+ };
131
+ const prepareRequestAdsSteps__ = () => [];
132
+ return {
133
+ name,
134
+ description: 'Moli DMP module for The Adex.',
135
+ moduleType: 'dmp',
136
+ config__,
137
+ configure__,
138
+ initSteps__,
139
+ configureSteps__,
140
+ prepareRequestAdsSteps__,
141
+ track,
142
+ hasRequiredConsent
143
+ };
144
+ };