@guardian/commercial-core 0.0.0-beta-20250716121613

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 (111) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +45 -0
  3. package/dist/cjs/ad-sizes.d.ts +202 -0
  4. package/dist/cjs/ad-sizes.js +400 -0
  5. package/dist/cjs/breakpoint.d.ts +8 -0
  6. package/dist/cjs/breakpoint.js +10 -0
  7. package/dist/cjs/constants/ad-label-height.d.ts +4 -0
  8. package/dist/cjs/constants/ad-label-height.js +7 -0
  9. package/dist/cjs/constants/index.d.ts +3 -0
  10. package/dist/cjs/constants/index.js +9 -0
  11. package/dist/cjs/constants/prebid-timeout.d.ts +4 -0
  12. package/dist/cjs/constants/prebid-timeout.js +7 -0
  13. package/dist/cjs/constants/top-above-nav-height.d.ts +10 -0
  14. package/dist/cjs/constants/top-above-nav-height.js +48 -0
  15. package/dist/cjs/detect-ad-blocker.d.ts +12 -0
  16. package/dist/cjs/detect-ad-blocker.js +61 -0
  17. package/dist/cjs/event-timer.d.ts +103 -0
  18. package/dist/cjs/event-timer.js +204 -0
  19. package/dist/cjs/geo/country-code.d.ts +3 -0
  20. package/dist/cjs/geo/country-code.js +34 -0
  21. package/dist/cjs/geo/geo-utils.d.ts +11 -0
  22. package/dist/cjs/geo/geo-utils.js +31 -0
  23. package/dist/cjs/geo/get-locale.d.ts +8 -0
  24. package/dist/cjs/geo/get-locale.js +43 -0
  25. package/dist/cjs/global.d.ts +71 -0
  26. package/dist/cjs/global.js +2 -0
  27. package/dist/cjs/index.d.ts +13 -0
  28. package/dist/cjs/index.js +46 -0
  29. package/dist/cjs/messenger/post-message.d.ts +1 -0
  30. package/dist/cjs/messenger/post-message.js +7 -0
  31. package/dist/cjs/permutive.d.ts +9 -0
  32. package/dist/cjs/permutive.js +38 -0
  33. package/dist/cjs/send-commercial-metrics.d.ts +58 -0
  34. package/dist/cjs/send-commercial-metrics.js +209 -0
  35. package/dist/cjs/targeting/build-page-targeting.d.ts +47 -0
  36. package/dist/cjs/targeting/build-page-targeting.js +112 -0
  37. package/dist/cjs/targeting/content.d.ts +87 -0
  38. package/dist/cjs/targeting/content.js +76 -0
  39. package/dist/cjs/targeting/personalised.d.ts +83 -0
  40. package/dist/cjs/targeting/personalised.js +140 -0
  41. package/dist/cjs/targeting/pick-targeting-values.d.ts +25 -0
  42. package/dist/cjs/targeting/pick-targeting-values.js +47 -0
  43. package/dist/cjs/targeting/session.d.ts +111 -0
  44. package/dist/cjs/targeting/session.js +61 -0
  45. package/dist/cjs/targeting/shared.d.ts +156 -0
  46. package/dist/cjs/targeting/shared.js +28 -0
  47. package/dist/cjs/targeting/teads-eligibility.d.ts +2 -0
  48. package/dist/cjs/targeting/teads-eligibility.js +20 -0
  49. package/dist/cjs/targeting/types.d.ts +6 -0
  50. package/dist/cjs/targeting/types.js +2 -0
  51. package/dist/cjs/targeting/viewport.d.ts +48 -0
  52. package/dist/cjs/targeting/viewport.js +22 -0
  53. package/dist/cjs/targeting/youtube-ima.d.ts +12 -0
  54. package/dist/cjs/targeting/youtube-ima.js +76 -0
  55. package/dist/cjs/types.d.ts +426 -0
  56. package/dist/cjs/types.js +12 -0
  57. package/dist/esm/ad-sizes.d.ts +202 -0
  58. package/dist/esm/ad-sizes.js +390 -0
  59. package/dist/esm/breakpoint.d.ts +8 -0
  60. package/dist/esm/breakpoint.js +6 -0
  61. package/dist/esm/constants/ad-label-height.d.ts +4 -0
  62. package/dist/esm/constants/ad-label-height.js +4 -0
  63. package/dist/esm/constants/index.d.ts +3 -0
  64. package/dist/esm/constants/index.js +3 -0
  65. package/dist/esm/constants/prebid-timeout.d.ts +4 -0
  66. package/dist/esm/constants/prebid-timeout.js +4 -0
  67. package/dist/esm/constants/top-above-nav-height.d.ts +10 -0
  68. package/dist/esm/constants/top-above-nav-height.js +45 -0
  69. package/dist/esm/detect-ad-blocker.d.ts +12 -0
  70. package/dist/esm/detect-ad-blocker.js +58 -0
  71. package/dist/esm/event-timer.d.ts +103 -0
  72. package/dist/esm/event-timer.js +199 -0
  73. package/dist/esm/geo/country-code.d.ts +3 -0
  74. package/dist/esm/geo/country-code.js +31 -0
  75. package/dist/esm/geo/geo-utils.d.ts +11 -0
  76. package/dist/esm/geo/geo-utils.js +20 -0
  77. package/dist/esm/geo/get-locale.d.ts +8 -0
  78. package/dist/esm/geo/get-locale.js +38 -0
  79. package/dist/esm/global.d.ts +71 -0
  80. package/dist/esm/global.js +0 -0
  81. package/dist/esm/index.d.ts +13 -0
  82. package/dist/esm/index.js +10 -0
  83. package/dist/esm/messenger/post-message.d.ts +1 -0
  84. package/dist/esm/messenger/post-message.js +3 -0
  85. package/dist/esm/permutive.d.ts +9 -0
  86. package/dist/esm/permutive.js +33 -0
  87. package/dist/esm/send-commercial-metrics.d.ts +58 -0
  88. package/dist/esm/send-commercial-metrics.js +204 -0
  89. package/dist/esm/targeting/build-page-targeting.d.ts +47 -0
  90. package/dist/esm/targeting/build-page-targeting.js +108 -0
  91. package/dist/esm/targeting/content.d.ts +87 -0
  92. package/dist/esm/targeting/content.js +73 -0
  93. package/dist/esm/targeting/personalised.d.ts +83 -0
  94. package/dist/esm/targeting/personalised.js +137 -0
  95. package/dist/esm/targeting/pick-targeting-values.d.ts +25 -0
  96. package/dist/esm/targeting/pick-targeting-values.js +43 -0
  97. package/dist/esm/targeting/session.d.ts +111 -0
  98. package/dist/esm/targeting/session.js +57 -0
  99. package/dist/esm/targeting/shared.d.ts +156 -0
  100. package/dist/esm/targeting/shared.js +25 -0
  101. package/dist/esm/targeting/teads-eligibility.d.ts +2 -0
  102. package/dist/esm/targeting/teads-eligibility.js +17 -0
  103. package/dist/esm/targeting/types.d.ts +6 -0
  104. package/dist/esm/targeting/types.js +0 -0
  105. package/dist/esm/targeting/viewport.d.ts +48 -0
  106. package/dist/esm/targeting/viewport.js +19 -0
  107. package/dist/esm/targeting/youtube-ima.d.ts +12 -0
  108. package/dist/esm/targeting/youtube-ima.js +73 -0
  109. package/dist/esm/types.d.ts +426 -0
  110. package/dist/esm/types.js +10 -0
  111. package/package.json +65 -0
@@ -0,0 +1,103 @@
1
+ import type { ConnectionType } from './types';
2
+ declare const supportsPerformanceAPI: () => boolean;
3
+ interface EventTimerProperties {
4
+ type?: ConnectionType;
5
+ downlink?: number;
6
+ effectiveType?: string;
7
+ adSlotsInline?: number;
8
+ adSlotsTotal?: number;
9
+ /** the height of the page / the viewport height */
10
+ pageHeightVH?: number;
11
+ gpcSignal?: number;
12
+ /** distance in percentage of viewport height at which ads are lazy loaded */
13
+ lazyLoadMarginPercent?: number;
14
+ hasLabsContainer?: boolean;
15
+ labsUrl?: string;
16
+ /** Record whether we've detected an ad blocker. This is intentionally
17
+ * distinct from the property we pass into commercial metrics, and in the
18
+ * future _could_ be removed in favour of this property */
19
+ detectedAdBlocker?: boolean;
20
+ /** Record whether we've shown the adblock as message */
21
+ didDisplayAdBlockAsk?: boolean;
22
+ /** creative ID of a video interscroller for video reporting metrics */
23
+ videoInterscrollerCreativeId?: number | null | undefined;
24
+ /** percentage progress of video interscroller on page unload */
25
+ videoInterscrollerPercentageProgress?: number;
26
+ }
27
+ declare class EventTimer {
28
+ private _marks;
29
+ private _measures;
30
+ properties: EventTimerProperties;
31
+ /**
32
+ * Initialise the EventTimer class on page.
33
+ * Returns the singleton instance of the EventTimer class and binds
34
+ * to window.guardian.commercialTimer. If it's been previously
35
+ * initialised and bound it returns the original instance
36
+ * Note: We save to window.guardian.commercialTimer because
37
+ * different bundles (DCR / DCP) can use commercial, and we want
38
+ * all timer events saved to a single instance per-page
39
+ * @returns {EventTimer} Instance of EventTimer
40
+ */
41
+ static init(): EventTimer;
42
+ /**
43
+ * Just a helper method to access the singleton instance of EventTimer.
44
+ * Typical use case is EventTimer.get().trigger
45
+ */
46
+ static get(): EventTimer;
47
+ /**
48
+ * These are marks that are not triggered by commercial but we are interested in
49
+ * tracking their performance. For example, CMP-related events.
50
+ **/
51
+ private get _externalMarks();
52
+ /**
53
+ * Returns all performance marks that should be saved as commercial metrics.
54
+ */
55
+ get marks(): {
56
+ name: string;
57
+ ts: number;
58
+ }[];
59
+ /**
60
+ * Returns all performance measures that should be saved as commercial metrics.
61
+ */
62
+ get measures(): {
63
+ name: string;
64
+ duration: number;
65
+ }[];
66
+ private constructor();
67
+ /**
68
+ * Adds a non timer measurement
69
+ *
70
+ * @param {string} name - the property's name
71
+ * @param value - the property's value
72
+ */
73
+ setProperty<T extends keyof EventTimerProperties>(name: T, value: EventTimerProperties[T]): void;
74
+ /**
75
+ * Creates a new performance mark, and if the mark ends with 'End' it will
76
+ * create a performance measure between the start and end marks.
77
+ *
78
+ * Marks can be triggered multiple times, but we only save the first
79
+ * instance of a mark, as things like ad refreshes can trigger the same mark.
80
+ *
81
+ * More info on the performance API:
82
+ * https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark
83
+ * https://developer.mozilla.org/en-US/docs/Web/API/Performance/measure
84
+ *
85
+ * @todo more strict typing for eventName and origin
86
+ * @param eventName The short name applied to the mark
87
+ * @param origin - Either 'page' (default) or the name of the slot
88
+ */
89
+ mark(eventName: string, origin?: string): void;
90
+ /**
91
+ * Creates a performance measure given the name of the end marks.
92
+ * The start mark is inferred from the end mark.
93
+ *
94
+ * @param endMark - The name of the mark that ends the measure
95
+ **/
96
+ private measure;
97
+ }
98
+ declare const _: {
99
+ slotMarks: readonly ["slotReady", "adRenderStart", "prebidStart", "adOnPage", "viewable"];
100
+ slotMeasures: readonly ["adRender", "defineSlot", "prepareSlot", "prebid", "fetchAd"];
101
+ trackedSlots: readonly ["top-above-nav", "inline1", "inline2", "fronts-banner-1", "fronts-banner-2"];
102
+ };
103
+ export { EventTimer, _, supportsPerformanceAPI };
@@ -0,0 +1,204 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.supportsPerformanceAPI = exports._ = exports.EventTimer = void 0;
4
+ const libs_1 = require("@guardian/libs");
5
+ const supportsPerformanceAPI = () => typeof window !== 'undefined' &&
6
+ typeof window.performance !== 'undefined' &&
7
+ typeof window.performance.mark === 'function';
8
+ exports.supportsPerformanceAPI = supportsPerformanceAPI;
9
+ // 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
10
+ const trackedSlots = [
11
+ 'top-above-nav',
12
+ 'inline1',
13
+ 'inline2',
14
+ 'fronts-banner-1',
15
+ 'fronts-banner-2',
16
+ ];
17
+ // marks that we want to save as commercial metrics
18
+ const slotMarks = [
19
+ 'slotReady',
20
+ 'adRenderStart',
21
+ 'prebidStart',
22
+ 'adOnPage',
23
+ 'viewable',
24
+ ];
25
+ // measures that we want to save as commercial metrics
26
+ const slotMeasures = [
27
+ 'adRender',
28
+ 'defineSlot',
29
+ 'prepareSlot',
30
+ 'prebid',
31
+ 'fetchAd',
32
+ ];
33
+ const pageMarks = ['commercialStart', 'commercialModulesLoaded'];
34
+ // measures that we want to save as commercial metrics
35
+ const pageMeasures = ['commercialBoot', 'googletagInit'];
36
+ // all marks, including the measure start and end marks
37
+ const allSlotMarks = [
38
+ ...slotMarks,
39
+ ...slotMeasures.map((measure) => `${measure}Start`),
40
+ ...slotMeasures.map((measure) => `${measure}End`),
41
+ ];
42
+ const externalMarks = [
43
+ 'cmp-init',
44
+ 'cmp-ui-displayed',
45
+ 'cmp-got-consent',
46
+ ];
47
+ const shouldSave = (name) => {
48
+ let [origin, type] = name.split('_');
49
+ if (!type) {
50
+ type = origin;
51
+ origin = 'page';
52
+ }
53
+ const shouldSaveMark = (trackedSlots.includes(origin) &&
54
+ slotMarks.includes(type)) ||
55
+ (origin === 'page' && pageMarks.includes(type));
56
+ const shouldSaveMeasure = (trackedSlots.includes(origin) &&
57
+ slotMeasures.includes(type)) ||
58
+ (origin === 'page' && pageMeasures.includes(type));
59
+ return shouldSaveMark || shouldSaveMeasure;
60
+ };
61
+ class EventTimer {
62
+ _marks;
63
+ _measures;
64
+ properties;
65
+ /**
66
+ * Initialise the EventTimer class on page.
67
+ * Returns the singleton instance of the EventTimer class and binds
68
+ * to window.guardian.commercialTimer. If it's been previously
69
+ * initialised and bound it returns the original instance
70
+ * Note: We save to window.guardian.commercialTimer because
71
+ * different bundles (DCR / DCP) can use commercial, and we want
72
+ * all timer events saved to a single instance per-page
73
+ * @returns {EventTimer} Instance of EventTimer
74
+ */
75
+ static init() {
76
+ return (window.guardian.commercialTimer ??= new EventTimer());
77
+ }
78
+ /**
79
+ * Just a helper method to access the singleton instance of EventTimer.
80
+ * Typical use case is EventTimer.get().trigger
81
+ */
82
+ static get() {
83
+ return this.init();
84
+ }
85
+ /**
86
+ * These are marks that are not triggered by commercial but we are interested in
87
+ * tracking their performance. For example, CMP-related events.
88
+ **/
89
+ get _externalMarks() {
90
+ if (!supportsPerformanceAPI()) {
91
+ return new Map();
92
+ }
93
+ return externalMarks.reduce((map, mark) => {
94
+ const entries = window.performance.getEntriesByName(mark);
95
+ if (entries.length && entries[0]) {
96
+ map.set(mark, entries[0]);
97
+ }
98
+ return map;
99
+ }, new Map());
100
+ }
101
+ /**
102
+ * Returns all performance marks that should be saved as commercial metrics.
103
+ */
104
+ get marks() {
105
+ return [...this._marks, ...this._externalMarks].map(([name, timer]) => ({
106
+ name,
107
+ ts: timer.startTime,
108
+ }));
109
+ }
110
+ /**
111
+ * Returns all performance measures that should be saved as commercial metrics.
112
+ */
113
+ get measures() {
114
+ return [...this._measures].map(([name, measure]) => ({
115
+ name,
116
+ duration: measure.duration,
117
+ }));
118
+ }
119
+ constructor() {
120
+ this._marks = new Map();
121
+ this._measures = new Map();
122
+ this.properties = {};
123
+ if (window.navigator.connection) {
124
+ this.properties.type = window.navigator.connection.type;
125
+ this.properties.downlink = window.navigator.connection.downlink;
126
+ this.properties.effectiveType =
127
+ window.navigator.connection.effectiveType;
128
+ }
129
+ }
130
+ /**
131
+ * Adds a non timer measurement
132
+ *
133
+ * @param {string} name - the property's name
134
+ * @param value - the property's value
135
+ */
136
+ setProperty(name, value) {
137
+ this.properties[name] = value;
138
+ }
139
+ /**
140
+ * Creates a new performance mark, and if the mark ends with 'End' it will
141
+ * create a performance measure between the start and end marks.
142
+ *
143
+ * Marks can be triggered multiple times, but we only save the first
144
+ * instance of a mark, as things like ad refreshes can trigger the same mark.
145
+ *
146
+ * More info on the performance API:
147
+ * https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark
148
+ * https://developer.mozilla.org/en-US/docs/Web/API/Performance/measure
149
+ *
150
+ * @todo more strict typing for eventName and origin
151
+ * @param eventName The short name applied to the mark
152
+ * @param origin - Either 'page' (default) or the name of the slot
153
+ */
154
+ mark(eventName, origin = 'page') {
155
+ let name = eventName;
156
+ if (allSlotMarks.includes(eventName) && origin !== 'page') {
157
+ name = `${origin}_${name}`;
158
+ }
159
+ if (!!this._marks.get(name) || !supportsPerformanceAPI()) {
160
+ return;
161
+ }
162
+ const mark = window.performance.mark(name);
163
+ if (
164
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- browser support is patchy
165
+ typeof mark?.startTime === 'number' &&
166
+ // we only want to save the marks that are related to certain slots or the page
167
+ shouldSave(name)) {
168
+ this._marks.set(name, mark);
169
+ }
170
+ if (name.endsWith('End')) {
171
+ this.measure(name);
172
+ }
173
+ }
174
+ /**
175
+ * Creates a performance measure given the name of the end marks.
176
+ * The start mark is inferred from the end mark.
177
+ *
178
+ * @param endMark - The name of the mark that ends the measure
179
+ **/
180
+ measure(endMark) {
181
+ const startMark = endMark.replace('End', 'Start');
182
+ const measureName = endMark.replace('End', '');
183
+ const startMarkExists = window.performance.getEntriesByName(startMark).length > 0;
184
+ if (startMarkExists) {
185
+ try {
186
+ const measure = window.performance.measure(measureName, startMark, endMark);
187
+ // we only want to save the measures that are related to certain slots or the page
188
+ if (measure && shouldSave(measureName)) {
189
+ this._measures.set(measureName, measure);
190
+ }
191
+ }
192
+ catch (e) {
193
+ (0, libs_1.log)('commercial', `error measuring ${measureName}`, e);
194
+ }
195
+ }
196
+ }
197
+ }
198
+ exports.EventTimer = EventTimer;
199
+ const _ = {
200
+ slotMarks,
201
+ slotMeasures,
202
+ trackedSlots,
203
+ };
204
+ exports._ = _;
@@ -0,0 +1,3 @@
1
+ import type { CountryCode } from '@guardian/libs';
2
+ declare const getCountryCode: () => CountryCode;
3
+ export { getCountryCode };
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCountryCode = void 0;
4
+ const libs_1 = require("@guardian/libs");
5
+ const editionToCountryCodeMap = {
6
+ UK: 'GB',
7
+ US: 'US',
8
+ AU: 'AU',
9
+ };
10
+ const editionToCountryCode = (editionKey = 'UK') => editionToCountryCodeMap[editionKey];
11
+ const countryCookieName = 'GU_geo_country';
12
+ const countryOverrideName = 'gu.geo.override';
13
+ let locale;
14
+ /*
15
+ This method can be used as a non async way of getting the country code
16
+ after init has been called. Returning locale should cover all/most
17
+ of the cases but if a race condition happen or the cookie is not set,
18
+ we keep fallbacks to cookie or geo from edition.
19
+ */
20
+ const getCountryCode = () => {
21
+ const pageEdition = window.guardian.config.page.edition;
22
+ const maybeCountryOverride = libs_1.storage.local.get(countryOverrideName);
23
+ const countryOverride = (0, libs_1.isString)(maybeCountryOverride)
24
+ ? maybeCountryOverride
25
+ : null;
26
+ return (locale ??
27
+ countryOverride ??
28
+ (0, libs_1.getCookie)({
29
+ name: countryCookieName,
30
+ shouldMemoize: true,
31
+ }) ??
32
+ editionToCountryCode(pageEdition));
33
+ };
34
+ exports.getCountryCode = 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,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports._ = exports.isInRow = exports.isInAuOrNz = exports.isInUsOrCa = exports.isInNewZealand = exports.isInAustralia = exports.isInCanada = exports.isInUsa = exports.isInUk = void 0;
4
+ const country_code_1 = require("./country-code");
5
+ // cache the users location so we only have to look it up once
6
+ let geo;
7
+ const currentGeoLocation = () => {
8
+ geo = geo ?? (0, country_code_1.getCountryCode)();
9
+ return geo;
10
+ };
11
+ const isInUk = () => currentGeoLocation() === 'GB';
12
+ exports.isInUk = isInUk;
13
+ const isInUsa = () => currentGeoLocation() === 'US';
14
+ exports.isInUsa = isInUsa;
15
+ const isInCanada = () => currentGeoLocation() === 'CA';
16
+ exports.isInCanada = isInCanada;
17
+ const isInAustralia = () => currentGeoLocation() === 'AU';
18
+ exports.isInAustralia = isInAustralia;
19
+ const isInNewZealand = () => currentGeoLocation() === 'NZ';
20
+ exports.isInNewZealand = isInNewZealand;
21
+ const isInUsOrCa = () => (0, exports.isInUsa)() || (0, exports.isInCanada)();
22
+ exports.isInUsOrCa = isInUsOrCa;
23
+ const isInAuOrNz = () => (0, exports.isInAustralia)() || (0, exports.isInNewZealand)();
24
+ exports.isInAuOrNz = isInAuOrNz;
25
+ const isInRow = () => !(0, exports.isInUk)() && !(0, exports.isInUsOrCa)() && !(0, exports.isInAuOrNz)();
26
+ exports.isInRow = isInRow;
27
+ exports._ = {
28
+ resetModule: () => {
29
+ geo = undefined;
30
+ },
31
+ };
@@ -0,0 +1,8 @@
1
+ import type { CountryCode } from '@guardian/libs';
2
+ export declare const __resetCachedValue: () => void;
3
+ /**
4
+ * Fetches the user's current location as an ISO 3166-1 alpha-2 string e.g. 'GB', 'AU' etc
5
+ * Note: This has been copied from guardian-libs and made syncronous by ommiting the call to
6
+ * the geolocation API
7
+ */
8
+ export declare const getLocale: () => CountryCode;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getLocale = exports.__resetCachedValue = void 0;
4
+ const libs_1 = require("@guardian/libs");
5
+ const KEY = 'GU_geo_country';
6
+ const KEY_OVERRIDE = 'gu.geo.override';
7
+ const COUNTRY_REGEX = /^[A-Z]{2}$/;
8
+ // best guess that we have a valid code, without actually shipping the entire list
9
+ const isValidCountryCode = (country) => (0, libs_1.isString)(country) && COUNTRY_REGEX.test(country);
10
+ // we'll cache any successful lookups so we only have to do this once
11
+ let locale;
12
+ const editionToGeolocationMap = {
13
+ UK: 'GB',
14
+ US: 'US',
15
+ AU: 'AU',
16
+ };
17
+ const editionToGeolocation = (editionKey) => editionToGeolocationMap[editionKey];
18
+ // just used for tests
19
+ const __resetCachedValue = () => (locale = undefined);
20
+ exports.__resetCachedValue = __resetCachedValue;
21
+ /**
22
+ * Fetches the user's current location as an ISO 3166-1 alpha-2 string e.g. 'GB', 'AU' etc
23
+ * Note: This has been copied from guardian-libs and made syncronous by ommiting the call to
24
+ * the geolocation API
25
+ */
26
+ const getLocale = () => {
27
+ if (locale)
28
+ return locale;
29
+ // return overridden geo from localStorage, used for changing geo only for development purposes
30
+ const geoOverride = libs_1.storage.local.get(KEY_OVERRIDE);
31
+ if (isValidCountryCode(geoOverride)) {
32
+ return (locale = geoOverride);
33
+ }
34
+ // return locale from cookie if it exists
35
+ const stored = (0, libs_1.getCookie)({ name: KEY });
36
+ if (stored && isValidCountryCode(stored)) {
37
+ return (locale = stored);
38
+ }
39
+ // return locale from edition
40
+ const editionCountryCode = editionToGeolocation(window.guardian.config.page.edition);
41
+ return (locale = editionCountryCode);
42
+ };
43
+ exports.getLocale = getLocale;
@@ -0,0 +1,71 @@
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';
3
+ declare global {
4
+ interface Navigator {
5
+ readonly connection?: NetworkInformation;
6
+ readonly cookieDeprecationLabel?: {
7
+ getValue: () => Promise<string>;
8
+ };
9
+ }
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;
64
+ google_trackConversion?: (arg0: GoogleTrackConversionObject) => void;
65
+ google_tag_params?: GoogleTagParams;
66
+ _brandmetrics?: Array<{
67
+ cmd: string;
68
+ val: Record<string, unknown>;
69
+ }>;
70
+ }
71
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,13 @@
1
+ export { isAdBlockInUse } from './detect-ad-blocker';
2
+ export { EventTimer } from './event-timer';
3
+ export { adSizes } from './ad-sizes';
4
+ export * as constants from './constants';
5
+ export { bypassCommercialMetricsSampling, initCommercialMetrics, } from './send-commercial-metrics';
6
+ export { buildPageTargeting } from './targeting/build-page-targeting';
7
+ export { postMessage } from './messenger/post-message';
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';
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.isEligibleForTeads = exports.getPermutivePFPSegments = exports.buildImaAdTagUrl = exports.buildPageTargeting = exports.initCommercialMetrics = exports.bypassCommercialMetricsSampling = exports.constants = exports.adSizes = exports.EventTimer = exports.isAdBlockInUse = void 0;
27
+ var detect_ad_blocker_1 = require("./detect-ad-blocker");
28
+ Object.defineProperty(exports, "isAdBlockInUse", { enumerable: true, get: function () { return detect_ad_blocker_1.isAdBlockInUse; } });
29
+ var event_timer_1 = require("./event-timer");
30
+ Object.defineProperty(exports, "EventTimer", { enumerable: true, get: function () { return event_timer_1.EventTimer; } });
31
+ var ad_sizes_1 = require("./ad-sizes");
32
+ Object.defineProperty(exports, "adSizes", { enumerable: true, get: function () { return ad_sizes_1.adSizes; } });
33
+ exports.constants = __importStar(require("./constants"));
34
+ var send_commercial_metrics_1 = require("./send-commercial-metrics");
35
+ Object.defineProperty(exports, "bypassCommercialMetricsSampling", { enumerable: true, get: function () { return send_commercial_metrics_1.bypassCommercialMetricsSampling; } });
36
+ Object.defineProperty(exports, "initCommercialMetrics", { enumerable: true, get: function () { return send_commercial_metrics_1.initCommercialMetrics; } });
37
+ var build_page_targeting_1 = require("./targeting/build-page-targeting");
38
+ Object.defineProperty(exports, "buildPageTargeting", { enumerable: true, get: function () { return build_page_targeting_1.buildPageTargeting; } });
39
+ var post_message_1 = require("./messenger/post-message");
40
+ Object.defineProperty(exports, "postMessage", { enumerable: true, get: function () { return post_message_1.postMessage; } });
41
+ var youtube_ima_1 = require("./targeting/youtube-ima");
42
+ Object.defineProperty(exports, "buildImaAdTagUrl", { enumerable: true, get: function () { return youtube_ima_1.buildImaAdTagUrl; } });
43
+ var permutive_1 = require("./permutive");
44
+ Object.defineProperty(exports, "getPermutivePFPSegments", { enumerable: true, get: function () { return permutive_1.getPermutivePFPSegments; } });
45
+ var teads_eligibility_1 = require("./targeting/teads-eligibility");
46
+ Object.defineProperty(exports, "isEligibleForTeads", { enumerable: true, get: function () { return teads_eligibility_1.isEligibleForTeads; } });
@@ -0,0 +1 @@
1
+ export declare const postMessage: (message: Record<string, unknown>, target: MessageEventSource, targetOrigin?: string) => void;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.postMessage = void 0;
4
+ const postMessage = (message, target, targetOrigin = '*') => {
5
+ target.postMessage(JSON.stringify(message), { targetOrigin });
6
+ };
7
+ exports.postMessage = postMessage;
@@ -0,0 +1,9 @@
1
+ declare const getPermutiveSegments: () => string[];
2
+ declare const getPermutivePFPSegments: () => string[];
3
+ declare const clearPermutiveSegments: () => void;
4
+ export declare const _: {
5
+ PERMUTIVE_KEY: string;
6
+ PERMUTIVE_PFP_KEY: string;
7
+ getSegments: (key: string) => string[];
8
+ };
9
+ export { getPermutiveSegments, getPermutivePFPSegments, clearPermutiveSegments, };
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.clearPermutiveSegments = exports.getPermutivePFPSegments = exports.getPermutiveSegments = exports._ = void 0;
4
+ const libs_1 = require("@guardian/libs");
5
+ const PERMUTIVE_KEY = `_papns`;
6
+ const PERMUTIVE_PFP_KEY = `_pdfps`;
7
+ const getSegments = (key) => {
8
+ try {
9
+ const rawSegments = libs_1.storage.local.getRaw(key);
10
+ const segments = rawSegments
11
+ ? JSON.parse(rawSegments)
12
+ : null;
13
+ if (!Array.isArray(segments))
14
+ return [];
15
+ return segments
16
+ .slice(0, 250)
17
+ .map((s) => Number.parseInt(s, 10))
18
+ .filter((n) => typeof n === 'number' && !Number.isNaN(n))
19
+ .map(String);
20
+ }
21
+ catch (err) {
22
+ return [];
23
+ }
24
+ };
25
+ const getPermutiveSegments = () => getSegments(PERMUTIVE_KEY);
26
+ exports.getPermutiveSegments = getPermutiveSegments;
27
+ const getPermutivePFPSegments = () => getSegments(PERMUTIVE_PFP_KEY);
28
+ exports.getPermutivePFPSegments = getPermutivePFPSegments;
29
+ const clearPermutiveSegments = () => {
30
+ libs_1.storage.local.remove(PERMUTIVE_KEY);
31
+ libs_1.storage.local.remove(PERMUTIVE_PFP_KEY);
32
+ };
33
+ exports.clearPermutiveSegments = clearPermutiveSegments;
34
+ exports._ = {
35
+ PERMUTIVE_KEY,
36
+ PERMUTIVE_PFP_KEY,
37
+ getSegments,
38
+ };