@guardian/commercial-core 7.0.0 → 27.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.
Files changed (173) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +23 -34
  3. package/dist/cjs/ad-sizes.d.ts +150 -8
  4. package/dist/cjs/ad-sizes.js +137 -37
  5. package/dist/cjs/breakpoint.d.ts +8 -0
  6. package/dist/cjs/breakpoint.js +10 -0
  7. package/dist/cjs/constants/index.d.ts +1 -1
  8. package/dist/cjs/constants/index.js +2 -2
  9. package/dist/cjs/detect-ad-blocker.js +1 -2
  10. package/dist/cjs/event-timer.d.ts +60 -48
  11. package/dist/cjs/event-timer.js +149 -115
  12. package/dist/cjs/geo/country-code.d.ts +3 -0
  13. package/dist/cjs/geo/country-code.js +34 -0
  14. package/dist/cjs/geo/geo-utils.d.ts +11 -0
  15. package/dist/cjs/geo/geo-utils.js +31 -0
  16. package/dist/cjs/global.d.ts +58 -10
  17. package/dist/cjs/index.d.ts +9 -39
  18. package/dist/cjs/index.js +12 -67
  19. package/dist/cjs/send-commercial-metrics.d.ts +8 -2
  20. package/dist/cjs/send-commercial-metrics.js +51 -27
  21. package/dist/cjs/targeting/build-page-targeting.d.ts +4 -5
  22. package/dist/cjs/targeting/build-page-targeting.js +35 -7
  23. package/dist/cjs/targeting/content.d.ts +1 -1
  24. package/dist/cjs/targeting/content.js +1 -1
  25. package/dist/cjs/targeting/personalised.d.ts +2 -3
  26. package/dist/cjs/targeting/personalised.js +3 -3
  27. package/dist/cjs/targeting/pick-targeting-values.d.ts +1 -1
  28. package/dist/cjs/targeting/session.d.ts +2 -2
  29. package/dist/cjs/targeting/shared.d.ts +31 -20
  30. package/dist/cjs/targeting/shared.js +0 -30
  31. package/dist/cjs/targeting/teads-eligibility.d.ts +2 -0
  32. package/dist/cjs/targeting/teads-eligibility.js +20 -0
  33. package/dist/cjs/targeting/types.d.ts +6 -0
  34. package/dist/cjs/targeting/types.js +2 -0
  35. package/dist/cjs/targeting/viewport.d.ts +1 -1
  36. package/dist/cjs/targeting/youtube-ima.d.ts +4 -3
  37. package/dist/cjs/targeting/youtube-ima.js +7 -4
  38. package/dist/cjs/types.d.ts +399 -63
  39. package/dist/cjs/types.js +10 -0
  40. package/dist/esm/ad-sizes.d.ts +150 -8
  41. package/dist/esm/ad-sizes.js +135 -37
  42. package/dist/esm/breakpoint.d.ts +8 -0
  43. package/dist/esm/breakpoint.js +6 -0
  44. package/dist/esm/constants/index.d.ts +1 -1
  45. package/dist/esm/constants/index.js +1 -1
  46. package/dist/esm/event-timer.d.ts +60 -48
  47. package/dist/esm/event-timer.js +147 -115
  48. package/dist/esm/geo/country-code.d.ts +3 -0
  49. package/dist/esm/geo/country-code.js +31 -0
  50. package/dist/esm/geo/geo-utils.d.ts +11 -0
  51. package/dist/esm/geo/geo-utils.js +20 -0
  52. package/dist/esm/global.d.ts +58 -10
  53. package/dist/esm/global.js +0 -1
  54. package/dist/esm/index.d.ts +9 -39
  55. package/dist/esm/index.js +6 -31
  56. package/dist/esm/send-commercial-metrics.d.ts +8 -2
  57. package/dist/esm/send-commercial-metrics.js +48 -25
  58. package/dist/esm/targeting/build-page-targeting.d.ts +4 -5
  59. package/dist/esm/targeting/build-page-targeting.js +35 -7
  60. package/dist/esm/targeting/content.d.ts +1 -1
  61. package/dist/esm/targeting/content.js +1 -1
  62. package/dist/esm/targeting/personalised.d.ts +2 -3
  63. package/dist/esm/targeting/personalised.js +3 -3
  64. package/dist/esm/targeting/pick-targeting-values.d.ts +1 -1
  65. package/dist/esm/targeting/session.d.ts +2 -2
  66. package/dist/esm/targeting/shared.d.ts +31 -20
  67. package/dist/esm/targeting/shared.js +0 -30
  68. package/dist/esm/targeting/teads-eligibility.d.ts +2 -0
  69. package/dist/esm/targeting/teads-eligibility.js +17 -0
  70. package/dist/esm/targeting/types.d.ts +6 -0
  71. package/dist/esm/targeting/types.js +0 -0
  72. package/dist/esm/targeting/viewport.d.ts +1 -1
  73. package/dist/esm/targeting/youtube-ima.d.ts +4 -3
  74. package/dist/esm/targeting/youtube-ima.js +7 -4
  75. package/dist/esm/types.d.ts +399 -63
  76. package/dist/esm/types.js +10 -1
  77. package/package.json +64 -83
  78. package/dist/cjs/__vendor/a9-apstag.d.ts +0 -1
  79. package/dist/cjs/__vendor/a9-apstag.js +0 -34
  80. package/dist/cjs/__vendor/ipsos-mori.d.ts +0 -1
  81. package/dist/cjs/__vendor/ipsos-mori.js +0 -18
  82. package/dist/cjs/__vendor/launchpad.d.ts +0 -1
  83. package/dist/cjs/__vendor/launchpad.js +0 -25
  84. package/dist/cjs/__vendor/pubmatic.d.ts +0 -1
  85. package/dist/cjs/__vendor/pubmatic.js +0 -49
  86. package/dist/cjs/__vendor/twitter-script.d.ts +0 -1
  87. package/dist/cjs/__vendor/twitter-script.js +0 -26
  88. package/dist/cjs/create-ad-slot.d.ts +0 -17
  89. package/dist/cjs/create-ad-slot.js +0 -107
  90. package/dist/cjs/google-analytics.d.ts +0 -1
  91. package/dist/cjs/google-analytics.js +0 -14
  92. package/dist/cjs/lib/ab-localstorage.d.ts +0 -2
  93. package/dist/cjs/lib/ab-localstorage.js +0 -14
  94. package/dist/cjs/lib/breakpoint.d.ts +0 -4
  95. package/dist/cjs/lib/breakpoint.js +0 -5
  96. package/dist/cjs/lib/can-use-dom.d.ts +0 -2
  97. package/dist/cjs/lib/can-use-dom.js +0 -9
  98. package/dist/cjs/lib/construct-query.d.ts +0 -3
  99. package/dist/cjs/lib/construct-query.js +0 -12
  100. package/dist/cjs/messenger.d.ts +0 -97
  101. package/dist/cjs/messenger.js +0 -281
  102. package/dist/cjs/targeting/build-page-targeting-consentless.d.ts +0 -15
  103. package/dist/cjs/targeting/build-page-targeting-consentless.js +0 -46
  104. package/dist/cjs/targeting/youtube.d.ts +0 -13
  105. package/dist/cjs/targeting/youtube.js +0 -64
  106. package/dist/cjs/third-party-tags/ias.d.ts +0 -7
  107. package/dist/cjs/third-party-tags/ias.js +0 -14
  108. package/dist/cjs/third-party-tags/inizio.d.ts +0 -13
  109. package/dist/cjs/third-party-tags/inizio.js +0 -39
  110. package/dist/cjs/third-party-tags/permutive.d.ts +0 -6
  111. package/dist/cjs/third-party-tags/permutive.js +0 -13
  112. package/dist/cjs/third-party-tags/remarketing.d.ts +0 -7
  113. package/dist/cjs/third-party-tags/remarketing.js +0 -22
  114. package/dist/cjs/third-party-tags/twitter-uwt.d.ts +0 -7
  115. package/dist/cjs/third-party-tags/twitter-uwt.js +0 -15
  116. package/dist/cjs/track-gpc-signal.d.ts +0 -7
  117. package/dist/cjs/track-gpc-signal.js +0 -17
  118. package/dist/cjs/track-labs-container.d.ts +0 -7
  119. package/dist/cjs/track-labs-container.js +0 -35
  120. package/dist/cjs/track-scroll-depth.d.ts +0 -8
  121. package/dist/cjs/track-scroll-depth.js +0 -41
  122. package/dist/esm/__vendor/a9-apstag.d.ts +0 -1
  123. package/dist/esm/__vendor/a9-apstag.js +0 -30
  124. package/dist/esm/__vendor/ipsos-mori.d.ts +0 -1
  125. package/dist/esm/__vendor/ipsos-mori.js +0 -14
  126. package/dist/esm/__vendor/launchpad.d.ts +0 -1
  127. package/dist/esm/__vendor/launchpad.js +0 -21
  128. package/dist/esm/__vendor/pubmatic.d.ts +0 -1
  129. package/dist/esm/__vendor/pubmatic.js +0 -45
  130. package/dist/esm/__vendor/twitter-script.d.ts +0 -1
  131. package/dist/esm/__vendor/twitter-script.js +0 -22
  132. package/dist/esm/create-ad-slot.d.ts +0 -17
  133. package/dist/esm/create-ad-slot.js +0 -103
  134. package/dist/esm/google-analytics.d.ts +0 -1
  135. package/dist/esm/google-analytics.js +0 -10
  136. package/dist/esm/lib/ab-localstorage.d.ts +0 -2
  137. package/dist/esm/lib/ab-localstorage.js +0 -10
  138. package/dist/esm/lib/breakpoint.d.ts +0 -4
  139. package/dist/esm/lib/breakpoint.js +0 -2
  140. package/dist/esm/lib/can-use-dom.d.ts +0 -2
  141. package/dist/esm/lib/can-use-dom.js +0 -6
  142. package/dist/esm/lib/construct-query.d.ts +0 -3
  143. package/dist/esm/lib/construct-query.js +0 -9
  144. package/dist/esm/messenger.d.ts +0 -97
  145. package/dist/esm/messenger.js +0 -274
  146. package/dist/esm/targeting/build-page-targeting-consentless.d.ts +0 -15
  147. package/dist/esm/targeting/build-page-targeting-consentless.js +0 -43
  148. package/dist/esm/targeting/youtube.d.ts +0 -13
  149. package/dist/esm/targeting/youtube.js +0 -60
  150. package/dist/esm/third-party-tags/ias.d.ts +0 -7
  151. package/dist/esm/third-party-tags/ias.js +0 -10
  152. package/dist/esm/third-party-tags/inizio.d.ts +0 -13
  153. package/dist/esm/third-party-tags/inizio.js +0 -35
  154. package/dist/esm/third-party-tags/permutive.d.ts +0 -6
  155. package/dist/esm/third-party-tags/permutive.js +0 -9
  156. package/dist/esm/third-party-tags/remarketing.d.ts +0 -7
  157. package/dist/esm/third-party-tags/remarketing.js +0 -18
  158. package/dist/esm/third-party-tags/twitter-uwt.d.ts +0 -7
  159. package/dist/esm/third-party-tags/twitter-uwt.js +0 -11
  160. package/dist/esm/track-gpc-signal.d.ts +0 -7
  161. package/dist/esm/track-gpc-signal.js +0 -14
  162. package/dist/esm/track-labs-container.d.ts +0 -7
  163. package/dist/esm/track-labs-container.js +0 -32
  164. package/dist/esm/track-scroll-depth.d.ts +0 -8
  165. package/dist/esm/track-scroll-depth.js +0 -38
  166. /package/dist/cjs/constants/{adLabelHeight.d.ts → ad-label-height.d.ts} +0 -0
  167. /package/dist/cjs/constants/{adLabelHeight.js → ad-label-height.js} +0 -0
  168. /package/dist/cjs/{lib → geo}/get-locale.d.ts +0 -0
  169. /package/dist/cjs/{lib → geo}/get-locale.js +0 -0
  170. /package/dist/esm/constants/{adLabelHeight.d.ts → ad-label-height.d.ts} +0 -0
  171. /package/dist/esm/constants/{adLabelHeight.js → ad-label-height.js} +0 -0
  172. /package/dist/esm/{lib → geo}/get-locale.d.ts +0 -0
  173. /package/dist/esm/{lib → geo}/get-locale.js +0 -0
@@ -1,24 +1,75 @@
1
- import { trackEvent } from './google-analytics';
2
- class Event {
3
- constructor(name, mark) {
4
- this.name = name;
5
- this.ts = mark.startTime;
1
+ import { log } from '@guardian/libs';
2
+ const supportsPerformanceAPI = () => typeof window !== 'undefined' &&
3
+ typeof window.performance !== 'undefined' &&
4
+ typeof window.performance.mark === 'function';
5
+ // Events will be logged using the performance API for all slots, but only these slots will be tracked as commercial metrics and sent to the data lake
6
+ const trackedSlots = [
7
+ 'top-above-nav',
8
+ 'inline1',
9
+ 'inline2',
10
+ 'fronts-banner-1',
11
+ 'fronts-banner-2',
12
+ ];
13
+ // marks that we want to save as commercial metrics
14
+ const slotMarks = [
15
+ 'slotReady',
16
+ 'adRenderStart',
17
+ 'prebidStart',
18
+ 'adOnPage',
19
+ 'viewable',
20
+ ];
21
+ // measures that we want to save as commercial metrics
22
+ const slotMeasures = [
23
+ 'adRender',
24
+ 'defineSlot',
25
+ 'prepareSlot',
26
+ 'prebid',
27
+ 'fetchAd',
28
+ ];
29
+ const pageMarks = ['commercialStart', 'commercialModulesLoaded'];
30
+ // measures that we want to save as commercial metrics
31
+ const pageMeasures = ['commercialBoot', 'googletagInit'];
32
+ // all marks, including the measure start and end marks
33
+ const allSlotMarks = [
34
+ ...slotMarks,
35
+ ...slotMeasures.map((measure) => `${measure}Start`),
36
+ ...slotMeasures.map((measure) => `${measure}End`),
37
+ ];
38
+ const externalMarks = [
39
+ 'cmp-init',
40
+ 'cmp-ui-displayed',
41
+ 'cmp-got-consent',
42
+ ];
43
+ const shouldSave = (name) => {
44
+ let [origin, type] = name.split('_');
45
+ if (!type) {
46
+ type = origin;
47
+ origin = 'page';
6
48
  }
7
- }
49
+ const shouldSaveMark = (trackedSlots.includes(origin) &&
50
+ slotMarks.includes(type)) ||
51
+ (origin === 'page' && pageMarks.includes(type));
52
+ const shouldSaveMeasure = (trackedSlots.includes(origin) &&
53
+ slotMeasures.includes(type)) ||
54
+ (origin === 'page' && pageMeasures.includes(type));
55
+ return shouldSaveMark || shouldSaveMeasure;
56
+ };
8
57
  class EventTimer {
58
+ _marks;
59
+ _measures;
60
+ properties;
9
61
  /**
10
62
  * Initialise the EventTimer class on page.
11
63
  * Returns the singleton instance of the EventTimer class and binds
12
64
  * to window.guardian.commercialTimer. If it's been previously
13
65
  * initialised and bound it returns the original instance
14
66
  * Note: We save to window.guardian.commercialTimer because
15
- * different bundles (DCR / DCP) can use commercial core, and we want
67
+ * different bundles (DCR / DCP) can use commercial, and we want
16
68
  * all timer events saved to a single instance per-page
17
69
  * @returns {EventTimer} Instance of EventTimer
18
70
  */
19
71
  static init() {
20
- var _a;
21
- return ((_a = window.guardian).commercialTimer || (_a.commercialTimer = new EventTimer()));
72
+ return (window.guardian.commercialTimer ??= new EventTimer());
22
73
  }
23
74
  /**
24
75
  * Just a helper method to access the singleton instance of EventTimer.
@@ -28,68 +79,42 @@ class EventTimer {
28
79
  return this.init();
29
80
  }
30
81
  /**
31
- * Returns all commercial timers. CMP-related timers are not tracked
32
- * by EventTimer so they need to be concatenated to EventTimer's private events array.
82
+ * These are marks that are not triggered by commercial but we are interested in
83
+ * tracking their performance. For example, CMP-related events.
84
+ **/
85
+ get _externalMarks() {
86
+ if (!supportsPerformanceAPI()) {
87
+ return new Map();
88
+ }
89
+ return externalMarks.reduce((map, mark) => {
90
+ const entries = window.performance.getEntriesByName(mark);
91
+ if (entries.length && entries[0]) {
92
+ map.set(mark, entries[0]);
93
+ }
94
+ return map;
95
+ }, new Map());
96
+ }
97
+ /**
98
+ * Returns all performance marks that should be saved as commercial metrics.
33
99
  */
34
- get events() {
35
- return typeof window.performance !== 'undefined' &&
36
- 'getEntriesByName' in window.performance
37
- ? [
38
- ...this._events,
39
- ...EventTimer._externallyDefinedEventNames
40
- .map((eventName) => {
41
- const entry = window.performance.getEntriesByName(eventName)[0];
42
- return entry
43
- ? new Event(eventName, entry)
44
- : undefined;
45
- })
46
- .filter((entry) => entry instanceof Event),
47
- ]
48
- : this._events;
100
+ get marks() {
101
+ return [...this._marks, ...this._externalMarks].map(([name, timer]) => ({
102
+ name,
103
+ ts: timer.startTime,
104
+ }));
105
+ }
106
+ /**
107
+ * Returns all performance measures that should be saved as commercial metrics.
108
+ */
109
+ get measures() {
110
+ return [...this._measures].map(([name, measure]) => ({
111
+ name,
112
+ duration: measure.duration,
113
+ }));
49
114
  }
50
115
  constructor() {
51
- this._events = [];
52
- this.startTS = window.performance.now();
53
- this.triggers = {
54
- first: {
55
- slotReady: false,
56
- prebidStart: false,
57
- prebidEnd: false,
58
- slotInitialised: false,
59
- adOnPage: false,
60
- },
61
- 'top-above-nav': {
62
- slotReady: false,
63
- prebidStart: false,
64
- prebidEnd: false,
65
- slotInitialised: false,
66
- adOnPage: false,
67
- },
68
- page: {
69
- commercialStart: false,
70
- commercialExtraModulesLoaded: false,
71
- commercialBaseModulesLoaded: false,
72
- commercialModulesLoaded: false,
73
- },
74
- };
75
- this.gaConfig = {
76
- logEvents: [
77
- {
78
- timingVariable: 'slotReady',
79
- },
80
- {
81
- timingVariable: 'slotInitialised',
82
- },
83
- {
84
- timingVariable: 'commercialStart',
85
- timingLabel: 'Commercial start parse time',
86
- },
87
- {
88
- timingVariable: 'commercialModulesLoaded',
89
- timingLabel: 'Commercial end parse time',
90
- },
91
- ],
92
- };
116
+ this._marks = new Map();
117
+ this._measures = new Map();
93
118
  this.properties = {};
94
119
  if (window.navigator.connection) {
95
120
  this.properties.type = window.navigator.connection.type;
@@ -99,7 +124,7 @@ class EventTimer {
99
124
  }
100
125
  }
101
126
  /**
102
- * Adds an event timer property
127
+ * Adds a non timer measurement
103
128
  *
104
129
  * @param {string} name - the property's name
105
130
  * @param value - the property's value
@@ -108,60 +133,67 @@ class EventTimer {
108
133
  this.properties[name] = value;
109
134
  }
110
135
  /**
111
- * Creates a new performance mark
112
- * For slot events also ensures each TYPE of event event is marked only once for 'first'
113
- * (the first time that event is triggered for ANY slot) and once for topAboveNav
136
+ * Creates a new performance mark, and if the mark ends with 'End' it will
137
+ * create a performance measure between the start and end marks.
138
+ *
139
+ * Marks can be triggered multiple times, but we only save the first
140
+ * instance of a mark, as things like ad refreshes can trigger the same mark.
114
141
  *
115
- * @param {string} eventName - The short name applied to the mark
116
- * @param {origin} [origin=page] - Either 'page' (default) or the name of the slot
142
+ * More info on the performance API:
143
+ * https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark
144
+ * https://developer.mozilla.org/en-US/docs/Web/API/Performance/measure
145
+ *
146
+ * @todo more strict typing for eventName and origin
147
+ * @param eventName The short name applied to the mark
148
+ * @param origin - Either 'page' (default) or the name of the slot
117
149
  */
118
- trigger(eventName, origin = 'page') {
119
- const TRACKED_SLOT_NAME = 'top-above-nav';
120
- if (origin === 'page' &&
121
- !this.triggers.page[eventName]) {
122
- this.mark(eventName);
123
- this.trackInGA(eventName);
124
- this.triggers.page[eventName] = true;
150
+ mark(eventName, origin = 'page') {
151
+ let name = eventName;
152
+ if (allSlotMarks.includes(eventName) && origin !== 'page') {
153
+ name = `${origin}_${name}`;
154
+ }
155
+ if (!!this._marks.get(name) || !supportsPerformanceAPI()) {
125
156
  return;
126
157
  }
127
- if (!this.triggers.first[eventName]) {
128
- const trackLabel = `first-${eventName}`;
129
- this.mark(trackLabel);
130
- this.trackInGA(eventName, trackLabel);
131
- this.triggers.first[eventName] = true;
158
+ const mark = window.performance.mark(name);
159
+ if (
160
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- browser support is patchy
161
+ typeof mark?.startTime === 'number' &&
162
+ // we only want to save the marks that are related to certain slots or the page
163
+ shouldSave(name)) {
164
+ this._marks.set(name, mark);
132
165
  }
133
- if (origin === TRACKED_SLOT_NAME) {
134
- if (!this.triggers[TRACKED_SLOT_NAME][eventName]) {
135
- const trackLabel = `${TRACKED_SLOT_NAME}-${eventName}`;
136
- this.mark(trackLabel);
137
- this.trackInGA(eventName, trackLabel);
138
- this.triggers[TRACKED_SLOT_NAME][eventName] = true;
139
- }
166
+ if (name.endsWith('End')) {
167
+ this.measure(name);
140
168
  }
141
169
  }
142
- mark(name) {
143
- const longName = `gu.commercial.${name}`;
144
- if (typeof window.performance !== 'undefined' &&
145
- 'mark' in window.performance &&
146
- typeof window.performance.mark === 'function') {
147
- const mark = window.performance.mark(longName);
148
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- browser support is patchy
149
- if (typeof mark?.startTime === 'number') {
150
- this._events.push(new Event(name, mark));
170
+ /**
171
+ * Creates a performance measure given the name of the end marks.
172
+ * The start mark is inferred from the end mark.
173
+ *
174
+ * @param endMark - The name of the mark that ends the measure
175
+ **/
176
+ measure(endMark) {
177
+ const startMark = endMark.replace('End', 'Start');
178
+ const measureName = endMark.replace('End', '');
179
+ const startMarkExists = window.performance.getEntriesByName(startMark).length > 0;
180
+ if (startMarkExists) {
181
+ try {
182
+ const measure = window.performance.measure(measureName, startMark, endMark);
183
+ // we only want to save the measures that are related to certain slots or the page
184
+ if (measure && shouldSave(measureName)) {
185
+ this._measures.set(measureName, measure);
186
+ }
187
+ }
188
+ catch (e) {
189
+ log('commercial', `error measuring ${measureName}`, e);
151
190
  }
152
- }
153
- }
154
- trackInGA(eventName, label = '') {
155
- const gaEvent = this.gaConfig.logEvents.find((e) => e.timingVariable === eventName);
156
- if (gaEvent) {
157
- const labelToUse = gaEvent.timingLabel ?? label;
158
- trackEvent('Commercial Events', gaEvent.timingVariable, labelToUse);
159
191
  }
160
192
  }
161
193
  }
162
- EventTimer._externallyDefinedEventNames = [
163
- 'cmp-init',
164
- 'cmp-ui-displayed',
165
- 'cmp-got-consent',
166
- ];
167
- export { EventTimer };
194
+ const _ = {
195
+ slotMarks,
196
+ slotMeasures,
197
+ trackedSlots,
198
+ };
199
+ export { EventTimer, _, supportsPerformanceAPI };
@@ -0,0 +1,3 @@
1
+ import type { CountryCode } from '@guardian/libs';
2
+ declare const getCountryCode: () => CountryCode;
3
+ export { getCountryCode };
@@ -0,0 +1,31 @@
1
+ import { getCookie, isString, storage } from '@guardian/libs';
2
+ const editionToCountryCodeMap = {
3
+ UK: 'GB',
4
+ US: 'US',
5
+ AU: 'AU',
6
+ };
7
+ const editionToCountryCode = (editionKey = 'UK') => editionToCountryCodeMap[editionKey];
8
+ const countryCookieName = 'GU_geo_country';
9
+ const countryOverrideName = 'gu.geo.override';
10
+ let locale;
11
+ /*
12
+ This method can be used as a non async way of getting the country code
13
+ after init has been called. Returning locale should cover all/most
14
+ of the cases but if a race condition happen or the cookie is not set,
15
+ we keep fallbacks to cookie or geo from edition.
16
+ */
17
+ const getCountryCode = () => {
18
+ const pageEdition = window.guardian.config.page.edition;
19
+ const maybeCountryOverride = storage.local.get(countryOverrideName);
20
+ const countryOverride = isString(maybeCountryOverride)
21
+ ? maybeCountryOverride
22
+ : null;
23
+ return (locale ??
24
+ countryOverride ??
25
+ getCookie({
26
+ name: countryCookieName,
27
+ shouldMemoize: true,
28
+ }) ??
29
+ editionToCountryCode(pageEdition));
30
+ };
31
+ export { getCountryCode };
@@ -0,0 +1,11 @@
1
+ export declare const isInUk: () => boolean;
2
+ export declare const isInUsa: () => boolean;
3
+ export declare const isInCanada: () => boolean;
4
+ export declare const isInAustralia: () => boolean;
5
+ export declare const isInNewZealand: () => boolean;
6
+ export declare const isInUsOrCa: () => boolean;
7
+ export declare const isInAuOrNz: () => boolean;
8
+ export declare const isInRow: () => boolean;
9
+ export declare const _: {
10
+ resetModule: () => void;
11
+ };
@@ -0,0 +1,20 @@
1
+ import { getCountryCode } from './country-code';
2
+ // cache the users location so we only have to look it up once
3
+ let geo;
4
+ const currentGeoLocation = () => {
5
+ geo = geo ?? getCountryCode();
6
+ return geo;
7
+ };
8
+ export const isInUk = () => currentGeoLocation() === 'GB';
9
+ export const isInUsa = () => currentGeoLocation() === 'US';
10
+ export const isInCanada = () => currentGeoLocation() === 'CA';
11
+ export const isInAustralia = () => currentGeoLocation() === 'AU';
12
+ export const isInNewZealand = () => currentGeoLocation() === 'NZ';
13
+ export const isInUsOrCa = () => isInUsa() || isInCanada();
14
+ export const isInAuOrNz = () => isInAustralia() || isInNewZealand();
15
+ export const isInRow = () => !isInUk() && !isInUsOrCa() && !isInAuOrNz();
16
+ export const _ = {
17
+ resetModule: () => {
18
+ geo = undefined;
19
+ },
20
+ };
@@ -1,23 +1,71 @@
1
- /// <reference types="google.analytics" />
2
- import type { GoogleTagParams, GoogleTrackConversionObject, GuardianWindowConfig, NetworkInformation } from './types';
3
- import type { EventTimer } from '.';
1
+ import type { EventTimer } from './event-timer';
2
+ import type { AdBlockers, Apstag, ArticleCounts, ComscoreGlobals, Confiant, Config, DfpEnv, FetchBidResponse, GoogleTagParams, GoogleTrackConversionObject, HeaderNotification, IasPET, NetworkInformation, NSdkInstance, Ophan, OptOutAdSlot, OptOutInitializeOptions, Permutive, SafeFrameAPI, TeadsAnalytics, Trac } from './types';
4
3
  declare global {
5
4
  interface Navigator {
6
5
  readonly connection?: NetworkInformation;
6
+ readonly cookieDeprecationLabel?: {
7
+ getValue: () => Promise<string>;
8
+ };
7
9
  }
8
10
  interface Window {
11
+ guardian: {
12
+ ophan?: Ophan;
13
+ config: Config;
14
+ queue: Array<() => Promise<void>>;
15
+ mustardCut?: boolean;
16
+ polyfilled?: boolean;
17
+ adBlockers: AdBlockers;
18
+ css: {
19
+ onLoad: () => void;
20
+ loaded: boolean;
21
+ };
22
+ articleCounts?: ArticleCounts;
23
+ commercial?: {
24
+ dfpEnv?: DfpEnv;
25
+ a9WinningBids?: FetchBidResponse[];
26
+ };
27
+ notificationEventHistory?: HeaderNotification[][];
28
+ commercialTimer?: EventTimer;
29
+ offlineCount?: number;
30
+ modules: {
31
+ sentry?: {
32
+ reportError?: (error: Error, feature: string, tags?: Record<string, string>, extras?: Record<string, unknown>) => void;
33
+ };
34
+ };
35
+ };
36
+ ootag: {
37
+ queue: Array<() => void>;
38
+ initializeOo: (o: OptOutInitializeOptions) => void;
39
+ addParameter: (key: string, value: string | string[]) => void;
40
+ addParameterForSlot: (slotId: string, key: string, value: string | string[]) => void;
41
+ defineSlot: (o: OptOutAdSlot) => void;
42
+ makeRequests: () => void;
43
+ refreshSlot: (slotId: string) => void;
44
+ refreshAllSlots: () => void;
45
+ logger: (...args: unknown[]) => void;
46
+ };
47
+ readonly navigator: Navigator;
48
+ confiant?: Confiant;
49
+ apstag?: Apstag;
50
+ permutive?: Permutive;
51
+ _comscore?: ComscoreGlobals[];
52
+ __iasPET?: IasPET;
53
+ teads_analytics?: TeadsAnalytics;
54
+ $sf: SafeFrameAPI;
55
+ conf: unknown;
56
+ NOLCMB: {
57
+ getInstance: (apid: string) => NSdkInstance;
58
+ };
59
+ nol_t: (pvar: {
60
+ cid: string;
61
+ content: string;
62
+ server: string;
63
+ }) => Trac;
9
64
  google_trackConversion?: (arg0: GoogleTrackConversionObject) => void;
10
65
  google_tag_params?: GoogleTagParams;
11
66
  _brandmetrics?: Array<{
12
67
  cmd: string;
13
68
  val: Record<string, unknown>;
14
69
  }>;
15
- guardian: {
16
- commercialTimer?: EventTimer;
17
- config: GuardianWindowConfig;
18
- offlineCount?: number;
19
- };
20
- ga: UniversalAnalytics.ga | null;
21
- readonly navigator: Navigator;
22
70
  }
23
71
  }
@@ -1 +0,0 @@
1
- export {};
@@ -1,43 +1,13 @@
1
- export { ias } from './third-party-tags/ias';
2
- export { permutive } from './third-party-tags/permutive';
3
- export { twitter } from './third-party-tags/twitter-uwt';
4
- export { inizio } from './third-party-tags/inizio';
5
- export { remarketing } from './third-party-tags/remarketing';
6
- export { EventTimer } from './event-timer';
7
- export { bypassCommercialMetricsSampling, initCommercialMetrics, } from './send-commercial-metrics';
8
- export type { ThirdPartyTag } from './types';
9
- export { adSizes, createAdSize, getAdSize, outstreamSizes, slotSizeMappings, standardAdSizes, } from './ad-sizes';
10
- export { isBreakpoint } from './lib/breakpoint';
11
- export type { Breakpoint } from './lib/breakpoint';
12
- export type { SizeKeys, AdSizeString, AdSize, SizeMapping, SlotSizeMappings, SlotName, } from './ad-sizes';
13
1
  export { isAdBlockInUse } from './detect-ad-blocker';
14
- export { clearPermutiveSegments, getPermutiveSegments, getPermutivePFPSegments, } from './permutive';
15
- export { initTrackScrollDepth } from './track-scroll-depth';
16
- export { initTrackLabsContainer } from './track-labs-container';
17
- export { initTrackGpcSignal } from './track-gpc-signal';
18
- export { buildAdsConfigWithConsent, disabledAds } from './targeting/youtube';
19
- export { createAdSlot, concatSizeMappings } from './create-ad-slot';
20
- export type { AdsConfig, AdsConfigBasic, AdsConfigDisabled, AdTargetingBuilder, CustomParams, } from './types';
2
+ export { EventTimer } from './event-timer';
3
+ export { adSizes } from './ad-sizes';
21
4
  export * as constants from './constants';
22
- export type { ContentTargeting } from './targeting/content';
23
- export { getContentTargeting } from './targeting/content';
24
- export type { PersonalisedTargeting } from './targeting/personalised';
25
- export { getPersonalisedTargeting } from './targeting/personalised';
26
- export type { SessionTargeting } from './targeting/session';
27
- export { getSessionTargeting } from './targeting/session';
28
- export type { SharedTargeting } from './targeting/shared';
29
- export { getSharedTargeting } from './targeting/shared';
30
- export type { ViewportTargeting } from './targeting/viewport';
31
- export { getViewportTargeting } from './targeting/viewport';
32
- export { pickTargetingValues } from './targeting/pick-targeting-values';
33
- export { init as initMessenger } from './messenger';
34
- export type { RegisterListener, RegisterPersistentListener, RespondProxy, } from './messenger';
35
- export { postMessage } from './messenger/post-message';
5
+ export { bypassCommercialMetricsSampling, initCommercialMetrics, } from './send-commercial-metrics';
36
6
  export { buildPageTargeting } from './targeting/build-page-targeting';
37
- export { buildPageTargetingConsentless } from './targeting/build-page-targeting-consentless';
38
- export type { PageTargeting } from './targeting/build-page-targeting';
39
- export { a9Apstag } from './__vendor/a9-apstag';
40
- export { ipsosMoriStub } from './__vendor/ipsos-mori';
41
- export { launchpad } from './__vendor/launchpad';
42
- export { pubmatic } from './__vendor/pubmatic';
7
+ export { postMessage } from './messenger/post-message';
43
8
  export { buildImaAdTagUrl } from './targeting/youtube-ima';
9
+ export { getPermutivePFPSegments } from './permutive';
10
+ export { isEligibleForTeads } from './targeting/teads-eligibility';
11
+ export type { AdSize, SizeMapping, SlotName } from './ad-sizes';
12
+ export type { PageTargeting } from './targeting/build-page-targeting';
13
+ export type { AdsConfigDisabled, AdsConfigUSNATorAus, AdsConfigTCFV2, } from './types';
package/dist/esm/index.js CHANGED
@@ -1,35 +1,10 @@
1
- /* istanbul ignore file -- there's no point check this for test coverage */
2
- export { ias } from './third-party-tags/ias';
3
- export { permutive } from './third-party-tags/permutive';
4
- export { twitter } from './third-party-tags/twitter-uwt';
5
- export { inizio } from './third-party-tags/inizio';
6
- export { remarketing } from './third-party-tags/remarketing';
1
+ export { isAdBlockInUse } from './detect-ad-blocker';
7
2
  export { EventTimer } from './event-timer';
3
+ export { adSizes } from './ad-sizes';
4
+ export * as constants from './constants';
8
5
  export { bypassCommercialMetricsSampling, initCommercialMetrics, } from './send-commercial-metrics';
9
- export { adSizes, createAdSize, getAdSize, outstreamSizes, slotSizeMappings, standardAdSizes, } from './ad-sizes';
10
- export { isBreakpoint } from './lib/breakpoint';
11
- export { isAdBlockInUse } from './detect-ad-blocker';
12
- export { clearPermutiveSegments, getPermutiveSegments, getPermutivePFPSegments, } from './permutive';
13
- export { initTrackScrollDepth } from './track-scroll-depth';
14
- export { initTrackLabsContainer } from './track-labs-container';
15
- export { initTrackGpcSignal } from './track-gpc-signal';
16
- export { buildAdsConfigWithConsent, disabledAds } from './targeting/youtube';
17
- export { createAdSlot, concatSizeMappings } from './create-ad-slot';
18
- import * as constants_1 from './constants';
19
- export { constants_1 as constants };
20
- export { getContentTargeting } from './targeting/content';
21
- export { getPersonalisedTargeting } from './targeting/personalised';
22
- export { getSessionTargeting } from './targeting/session';
23
- export { getSharedTargeting } from './targeting/shared';
24
- export { getViewportTargeting } from './targeting/viewport';
25
- export { pickTargetingValues } from './targeting/pick-targeting-values';
26
- export { init as initMessenger } from './messenger';
27
- export { postMessage } from './messenger/post-message';
28
6
  export { buildPageTargeting } from './targeting/build-page-targeting';
29
- export { buildPageTargetingConsentless } from './targeting/build-page-targeting-consentless';
30
- /* -- Vendor JavaScript -- */
31
- export { a9Apstag } from './__vendor/a9-apstag';
32
- export { ipsosMoriStub } from './__vendor/ipsos-mori';
33
- export { launchpad } from './__vendor/launchpad';
34
- export { pubmatic } from './__vendor/pubmatic';
7
+ export { postMessage } from './messenger/post-message';
35
8
  export { buildImaAdTagUrl } from './targeting/youtube-ima';
9
+ export { getPermutivePFPSegments } from './permutive';
10
+ export { isEligibleForTeads } from './targeting/teads-eligibility';
@@ -11,6 +11,10 @@ type TimedEvent = {
11
11
  name: string;
12
12
  ts: number;
13
13
  };
14
+ type DurationEvent = {
15
+ name: string;
16
+ duration: number;
17
+ };
14
18
  type EventProperties = {
15
19
  type?: ConnectionType;
16
20
  downlink?: number;
@@ -20,6 +24,7 @@ declare enum Endpoints {
20
24
  CODE = "//performance-events.code.dev-guardianapis.com/commercial-metrics",
21
25
  PROD = "//performance-events.guardianapis.com/commercial-metrics"
22
26
  }
27
+ declare const checkConsent: () => Promise<boolean>;
23
28
  /**
24
29
  * A method to asynchronously send metrics after initialization.
25
30
  */
@@ -33,6 +38,7 @@ interface InitCommercialMetricsArgs {
33
38
  }
34
39
  /**
35
40
  * A method to initialise metrics.
41
+ * Note: this is initialised in the frontend/DCR bundles, not the commercial bundle.
36
42
  * @param init.pageViewId - identifies the page view. Usually available on `guardian.config.ophan.pageViewId`. Defaults to `null`
37
43
  * @param init.browserId - identifies the browser. Usually available via `getCookie({ name: 'bwid' })`. Defaults to `null`
38
44
  * @param init.isDev - used to determine whether to use CODE or PROD endpoints.
@@ -44,9 +50,9 @@ export declare const _: {
44
50
  Endpoints: typeof Endpoints;
45
51
  setEndpoint: (isDev: boolean) => Endpoints;
46
52
  mapEventTimerPropertiesToString: (properties: Array<[string, string | number]>) => Property[];
47
- roundTimeStamp: (events: TimedEvent[]) => Metric[];
53
+ roundTimeStamp: (events: TimedEvent[], measures: DurationEvent[]) => Metric[];
48
54
  transformToObjectEntries: (eventTimerProperties: EventProperties) => Array<[string, string | number | undefined]>;
49
55
  reset: () => void;
50
56
  };
51
57
  export type { Property, TimedEvent, Metric };
52
- export { bypassCommercialMetricsSampling, initCommercialMetrics };
58
+ export { bypassCommercialMetricsSampling, initCommercialMetrics, checkConsent };