@guardian/commercial-core 29.3.0 → 30.1.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 (53) hide show
  1. package/dist/cjs/ad-sizes.d.ts +1 -1
  2. package/dist/cjs/ad-sizes.js +1 -1
  3. package/dist/cjs/constants/index.d.ts +3 -3
  4. package/dist/cjs/constants/index.js +3 -3
  5. package/dist/cjs/email-hash.d.ts +3 -1
  6. package/dist/cjs/email-hash.js +17 -6
  7. package/dist/cjs/event-timer.d.ts +1 -1
  8. package/dist/cjs/geo/geo-utils.js +1 -1
  9. package/dist/cjs/global.d.ts +2 -2
  10. package/dist/cjs/index.d.ts +14 -14
  11. package/dist/cjs/index.js +13 -13
  12. package/dist/cjs/send-commercial-metrics.d.ts +1 -1
  13. package/dist/cjs/send-commercial-metrics.js +1 -1
  14. package/dist/cjs/targeting/build-page-targeting.d.ts +18 -6
  15. package/dist/cjs/targeting/build-page-targeting.js +9 -8
  16. package/dist/cjs/targeting/content.d.ts +2 -2
  17. package/dist/cjs/targeting/personalised.d.ts +1 -1
  18. package/dist/cjs/targeting/personalised.js +1 -1
  19. package/dist/cjs/targeting/session.d.ts +12 -2
  20. package/dist/cjs/targeting/session.js +5 -1
  21. package/dist/cjs/targeting/shared.js +1 -1
  22. package/dist/cjs/targeting/teads-eligibility.js +3 -1
  23. package/dist/cjs/targeting/viewport.d.ts +1 -1
  24. package/dist/cjs/targeting/youtube-ima.d.ts +1 -1
  25. package/dist/cjs/targeting/youtube-ima.js +1 -1
  26. package/dist/cjs/types.d.ts +3 -2
  27. package/dist/esm/ad-sizes.d.ts +1 -1
  28. package/dist/esm/ad-sizes.js +1 -1
  29. package/dist/esm/constants/index.d.ts +3 -3
  30. package/dist/esm/constants/index.js +3 -3
  31. package/dist/esm/email-hash.d.ts +3 -1
  32. package/dist/esm/email-hash.js +17 -5
  33. package/dist/esm/event-timer.d.ts +1 -1
  34. package/dist/esm/geo/geo-utils.js +1 -1
  35. package/dist/esm/global.d.ts +2 -2
  36. package/dist/esm/index.d.ts +14 -14
  37. package/dist/esm/index.js +11 -11
  38. package/dist/esm/send-commercial-metrics.d.ts +1 -1
  39. package/dist/esm/send-commercial-metrics.js +1 -1
  40. package/dist/esm/targeting/build-page-targeting.d.ts +18 -6
  41. package/dist/esm/targeting/build-page-targeting.js +9 -8
  42. package/dist/esm/targeting/content.d.ts +2 -2
  43. package/dist/esm/targeting/personalised.d.ts +1 -1
  44. package/dist/esm/targeting/personalised.js +1 -1
  45. package/dist/esm/targeting/session.d.ts +12 -2
  46. package/dist/esm/targeting/session.js +5 -1
  47. package/dist/esm/targeting/shared.js +1 -1
  48. package/dist/esm/targeting/teads-eligibility.js +3 -1
  49. package/dist/esm/targeting/viewport.d.ts +1 -1
  50. package/dist/esm/targeting/youtube-ima.d.ts +1 -1
  51. package/dist/esm/targeting/youtube-ima.js +1 -1
  52. package/dist/esm/types.d.ts +3 -2
  53. package/package.json +12 -10
@@ -1,4 +1,4 @@
1
- import type { Breakpoint } from './breakpoint';
1
+ import type { Breakpoint } from './breakpoint.js';
2
2
  type AdSizeString = 'fluid' | `${number},${number}`;
3
3
  /**
4
4
  * Store ad sizes in a way that is compatible with google-tag but also accessible via
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.findAppliedSizesForBreakpoint = exports.createAdSize = exports.slotSizeMappings = exports.getAdSize = exports.outstreamSizes = exports.standardAdSizes = exports.adSizes = exports.AdSize = exports._ = void 0;
4
- const breakpoint_1 = require("./breakpoint");
4
+ const breakpoint_1 = require("./breakpoint.js");
5
5
  /**
6
6
  * Store ad sizes in a way that is compatible with google-tag but also accessible via
7
7
  * more semantic `width`/`height` properties and keep things readonly.
@@ -1,3 +1,3 @@
1
- export { AD_LABEL_HEIGHT } from './ad-label-height';
2
- export { PREBID_TIMEOUT } from './prebid-timeout';
3
- export { TOP_ABOVE_NAV_HEIGHT } from './top-above-nav-height';
1
+ export { AD_LABEL_HEIGHT } from './ad-label-height.js';
2
+ export { PREBID_TIMEOUT } from './prebid-timeout.js';
3
+ export { TOP_ABOVE_NAV_HEIGHT } from './top-above-nav-height.js';
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TOP_ABOVE_NAV_HEIGHT = exports.PREBID_TIMEOUT = exports.AD_LABEL_HEIGHT = void 0;
4
- var ad_label_height_1 = require("./ad-label-height");
4
+ var ad_label_height_1 = require("./ad-label-height.js");
5
5
  Object.defineProperty(exports, "AD_LABEL_HEIGHT", { enumerable: true, get: function () { return ad_label_height_1.AD_LABEL_HEIGHT; } });
6
- var prebid_timeout_1 = require("./prebid-timeout");
6
+ var prebid_timeout_1 = require("./prebid-timeout.js");
7
7
  Object.defineProperty(exports, "PREBID_TIMEOUT", { enumerable: true, get: function () { return prebid_timeout_1.PREBID_TIMEOUT; } });
8
- var top_above_nav_height_1 = require("./top-above-nav-height");
8
+ var top_above_nav_height_1 = require("./top-above-nav-height.js");
9
9
  Object.defineProperty(exports, "TOP_ABOVE_NAV_HEIGHT", { enumerable: true, get: function () { return top_above_nav_height_1.TOP_ABOVE_NAV_HEIGHT; } });
@@ -1 +1,3 @@
1
- export declare function hashEmail(email: string): Promise<string>;
1
+ type HashClient = 'id5' | 'uid2' | 'euid';
2
+ declare function hashEmailForClient(email: string, client: HashClient): Promise<string>;
3
+ export { hashEmailForClient };
@@ -1,16 +1,27 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hashEmail = hashEmail;
4
- async function sha256(string) {
5
- const utf8 = new TextEncoder().encode(string);
6
- const hashBuffer = await crypto.subtle.digest('SHA-256', utf8);
3
+ exports.hashEmailForClient = hashEmailForClient;
4
+ function toHex(hashBuffer) {
7
5
  const hashArray = Array.from(new Uint8Array(hashBuffer));
8
6
  const hashHex = hashArray
9
7
  .map((bytes) => bytes.toString(16).padStart(2, '0'))
10
8
  .join('');
11
9
  return hashHex;
12
10
  }
13
- function hashEmail(email) {
11
+ function toBase64(hashBuffer) {
12
+ const hashBytes = new Uint8Array(hashBuffer);
13
+ const base64Hash = btoa(String.fromCharCode(...hashBytes));
14
+ return base64Hash;
15
+ }
16
+ async function hashEmailForClient(email, client) {
14
17
  const normalisedEmail = email.trim().toLowerCase();
15
- return sha256(normalisedEmail);
18
+ const utf8 = new TextEncoder().encode(normalisedEmail);
19
+ const hashBuffer = await crypto.subtle.digest('SHA-256', utf8);
20
+ switch (client) {
21
+ case 'id5':
22
+ return toHex(hashBuffer);
23
+ case 'uid2':
24
+ case 'euid':
25
+ return toBase64(hashBuffer);
26
+ }
16
27
  }
@@ -1,4 +1,4 @@
1
- import type { ConnectionType } from './types';
1
+ import type { ConnectionType } from './types.js';
2
2
  declare const supportsPerformanceAPI: () => boolean;
3
3
  interface EventTimerProperties {
4
4
  type?: ConnectionType;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
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");
4
+ const country_code_1 = require("./country-code.js");
5
5
  // cache the users location so we only have to look it up once
6
6
  let geo;
7
7
  const currentGeoLocation = () => {
@@ -1,5 +1,5 @@
1
- import type { EventTimer } from './event-timer';
2
- import type { AdBlockers, Admiral, Apstag, ArticleCounts, ComscoreGlobals, Confiant, Config, DfpEnv, FetchBidResponse, GoogleTagParams, GoogleTrackConversionObject, HeaderNotification, IasPET, NetworkInformation, NSdkInstance, Ophan, OptOutAdSlot, OptOutInitializeOptions, Permutive, SafeFrameAPI, TeadsAnalytics, Trac } from './types';
1
+ import type { EventTimer } from './event-timer.js';
2
+ import type { AdBlockers, Admiral, Apstag, ArticleCounts, ComscoreGlobals, Confiant, Config, DfpEnv, FetchBidResponse, GoogleTagParams, GoogleTrackConversionObject, HeaderNotification, IasPET, NetworkInformation, NSdkInstance, Ophan, OptOutAdSlot, OptOutInitializeOptions, Permutive, SafeFrameAPI, TeadsAnalytics, Trac } from './types.js';
3
3
  declare global {
4
4
  interface Navigator {
5
5
  readonly connection?: NetworkInformation;
@@ -1,14 +1,14 @@
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 { hashEmail } from './email-hash';
12
- export type { AdSize, SizeMapping, SlotName } from './ad-sizes';
13
- export type { PageTargeting } from './targeting/build-page-targeting';
14
- export type { AdsConfigDisabled, AdsConfigUSNATorAus, AdsConfigTCFV2, } from './types';
1
+ export { isAdBlockInUse } from './detect-ad-blocker.js';
2
+ export { EventTimer } from './event-timer.js';
3
+ export { adSizes } from './ad-sizes.js';
4
+ export * as constants from './constants/index.js';
5
+ export { bypassCommercialMetricsSampling, initCommercialMetrics, } from './send-commercial-metrics.js';
6
+ export { buildPageTargeting } from './targeting/build-page-targeting.js';
7
+ export { postMessage } from './messenger/post-message.js';
8
+ export { buildImaAdTagUrl } from './targeting/youtube-ima.js';
9
+ export { getPermutivePFPSegments } from './permutive.js';
10
+ export { isEligibleForTeads } from './targeting/teads-eligibility.js';
11
+ export { hashEmailForClient } from './email-hash.js';
12
+ export type { AdSize, SizeMapping, SlotName } from './ad-sizes.js';
13
+ export type { PageTargeting } from './targeting/build-page-targeting.js';
14
+ export type { AdsConfigDisabled, AdsConfigUSNATorAus, AdsConfigTCFV2, } from './types.js';
package/dist/cjs/index.js CHANGED
@@ -33,26 +33,26 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.hashEmail = exports.isEligibleForTeads = exports.getPermutivePFPSegments = exports.buildImaAdTagUrl = exports.buildPageTargeting = exports.initCommercialMetrics = exports.bypassCommercialMetricsSampling = exports.constants = exports.adSizes = exports.EventTimer = exports.isAdBlockInUse = void 0;
37
- var detect_ad_blocker_1 = require("./detect-ad-blocker");
36
+ exports.hashEmailForClient = exports.isEligibleForTeads = exports.getPermutivePFPSegments = exports.buildImaAdTagUrl = exports.buildPageTargeting = exports.initCommercialMetrics = exports.bypassCommercialMetricsSampling = exports.constants = exports.adSizes = exports.EventTimer = exports.isAdBlockInUse = void 0;
37
+ var detect_ad_blocker_1 = require("./detect-ad-blocker.js");
38
38
  Object.defineProperty(exports, "isAdBlockInUse", { enumerable: true, get: function () { return detect_ad_blocker_1.isAdBlockInUse; } });
39
- var event_timer_1 = require("./event-timer");
39
+ var event_timer_1 = require("./event-timer.js");
40
40
  Object.defineProperty(exports, "EventTimer", { enumerable: true, get: function () { return event_timer_1.EventTimer; } });
41
- var ad_sizes_1 = require("./ad-sizes");
41
+ var ad_sizes_1 = require("./ad-sizes.js");
42
42
  Object.defineProperty(exports, "adSizes", { enumerable: true, get: function () { return ad_sizes_1.adSizes; } });
43
- exports.constants = __importStar(require("./constants"));
44
- var send_commercial_metrics_1 = require("./send-commercial-metrics");
43
+ exports.constants = __importStar(require("./constants/index.js"));
44
+ var send_commercial_metrics_1 = require("./send-commercial-metrics.js");
45
45
  Object.defineProperty(exports, "bypassCommercialMetricsSampling", { enumerable: true, get: function () { return send_commercial_metrics_1.bypassCommercialMetricsSampling; } });
46
46
  Object.defineProperty(exports, "initCommercialMetrics", { enumerable: true, get: function () { return send_commercial_metrics_1.initCommercialMetrics; } });
47
- var build_page_targeting_1 = require("./targeting/build-page-targeting");
47
+ var build_page_targeting_1 = require("./targeting/build-page-targeting.js");
48
48
  Object.defineProperty(exports, "buildPageTargeting", { enumerable: true, get: function () { return build_page_targeting_1.buildPageTargeting; } });
49
- var post_message_1 = require("./messenger/post-message");
49
+ var post_message_1 = require("./messenger/post-message.js");
50
50
  Object.defineProperty(exports, "postMessage", { enumerable: true, get: function () { return post_message_1.postMessage; } });
51
- var youtube_ima_1 = require("./targeting/youtube-ima");
51
+ var youtube_ima_1 = require("./targeting/youtube-ima.js");
52
52
  Object.defineProperty(exports, "buildImaAdTagUrl", { enumerable: true, get: function () { return youtube_ima_1.buildImaAdTagUrl; } });
53
- var permutive_1 = require("./permutive");
53
+ var permutive_1 = require("./permutive.js");
54
54
  Object.defineProperty(exports, "getPermutivePFPSegments", { enumerable: true, get: function () { return permutive_1.getPermutivePFPSegments; } });
55
- var teads_eligibility_1 = require("./targeting/teads-eligibility");
55
+ var teads_eligibility_1 = require("./targeting/teads-eligibility.js");
56
56
  Object.defineProperty(exports, "isEligibleForTeads", { enumerable: true, get: function () { return teads_eligibility_1.isEligibleForTeads; } });
57
- var email_hash_1 = require("./email-hash");
58
- Object.defineProperty(exports, "hashEmail", { enumerable: true, get: function () { return email_hash_1.hashEmail; } });
57
+ var email_hash_1 = require("./email-hash.js");
58
+ Object.defineProperty(exports, "hashEmailForClient", { enumerable: true, get: function () { return email_hash_1.hashEmailForClient; } });
@@ -1,4 +1,4 @@
1
- import type { ConnectionType } from './types';
1
+ import type { ConnectionType } from './types.js';
2
2
  type Metric = {
3
3
  name: string;
4
4
  value: number;
@@ -4,7 +4,7 @@ exports.checkConsent = exports._ = void 0;
4
4
  exports.bypassCommercialMetricsSampling = bypassCommercialMetricsSampling;
5
5
  exports.initCommercialMetrics = initCommercialMetrics;
6
6
  const libs_1 = require("@guardian/libs");
7
- const event_timer_1 = require("./event-timer");
7
+ const event_timer_1 = require("./event-timer.js");
8
8
  var Endpoints;
9
9
  (function (Endpoints) {
10
10
  Endpoints["CODE"] = "//performance-events.code.dev-guardianapis.com/commercial-metrics";
@@ -1,9 +1,9 @@
1
1
  import type { Participations } from '@guardian/ab-core';
2
2
  import type { ConsentState, CountryCode } from '@guardian/libs';
3
- import type { AdManagerGroup, Frequency } from './personalised';
4
- import type { SharedTargeting } from './shared';
5
- import { getLocalHour } from './shared';
6
- import type { TrueOrFalse } from './types';
3
+ import type { AdManagerGroup, Frequency } from './personalised.js';
4
+ import type { SharedTargeting } from './shared.js';
5
+ import { getLocalHour } from './shared.js';
6
+ import type { TrueOrFalse } from './types.js';
7
7
  type PartialWithNulls<T> = {
8
8
  [P in keyof T]?: T[P] | null;
9
9
  };
@@ -30,6 +30,7 @@ type PageTargeting = PartialWithNulls<{
30
30
  s: string;
31
31
  sens: TrueOrFalse;
32
32
  si: TrueOrFalse;
33
+ idp: string[];
33
34
  skinsize: 'l' | 's';
34
35
  urlkw: string[];
35
36
  vl: string;
@@ -37,13 +38,24 @@ type PageTargeting = PartialWithNulls<{
37
38
  [_: string]: string | string[];
38
39
  } & SharedTargeting>;
39
40
  declare const filterValues: (pageTargets: Record<string, unknown>) => Record<string, string | string[]>;
41
+ type UserId = {
42
+ name: string;
43
+ params?: Record<string, string | number>;
44
+ storage?: {
45
+ type: 'cookie' | 'html5';
46
+ name: string;
47
+ expires: number;
48
+ refreshInSeconds?: number;
49
+ };
50
+ };
40
51
  type BuildPageTargetingParams = {
41
52
  adFree: boolean;
42
53
  clientSideParticipations: Participations;
43
54
  consentState: ConsentState;
44
55
  isSignedIn?: boolean;
45
56
  youtube?: boolean;
57
+ idProviders?: UserId[];
46
58
  };
47
- declare const buildPageTargeting: ({ adFree, clientSideParticipations, consentState, isSignedIn, youtube, }: BuildPageTargetingParams) => Record<string, string | string[]>;
59
+ declare const buildPageTargeting: ({ adFree, clientSideParticipations, consentState, isSignedIn, youtube, idProviders, }: BuildPageTargetingParams) => Record<string, string | string[]>;
48
60
  export { buildPageTargeting, filterValues, getLocalHour };
49
- export type { PageTargeting };
61
+ export type { UserId, PageTargeting };
@@ -2,14 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getLocalHour = exports.filterValues = exports.buildPageTargeting = void 0;
4
4
  const libs_1 = require("@guardian/libs");
5
- const event_timer_1 = require("../event-timer");
6
- const get_locale_1 = require("../geo/get-locale");
7
- const content_1 = require("./content");
8
- const personalised_1 = require("./personalised");
9
- const session_1 = require("./session");
10
- const shared_1 = require("./shared");
5
+ const event_timer_1 = require("../event-timer.js");
6
+ const get_locale_1 = require("../geo/get-locale.js");
7
+ const content_1 = require("./content.js");
8
+ const personalised_1 = require("./personalised.js");
9
+ const session_1 = require("./session.js");
10
+ const shared_1 = require("./shared.js");
11
11
  Object.defineProperty(exports, "getLocalHour", { enumerable: true, get: function () { return shared_1.getLocalHour; } });
12
- const viewport_1 = require("./viewport");
12
+ const viewport_1 = require("./viewport.js");
13
13
  const filterValues = (pageTargets) => {
14
14
  const filtered = {};
15
15
  for (const key in pageTargets) {
@@ -49,7 +49,7 @@ const isFirstVisit = (referrer) => {
49
49
  }
50
50
  return !referrerMatchesHost(referrer);
51
51
  };
52
- const buildPageTargeting = ({ adFree, clientSideParticipations, consentState, isSignedIn = false, youtube = false, }) => {
52
+ const buildPageTargeting = ({ adFree, clientSideParticipations, consentState, isSignedIn = false, youtube = false, idProviders = [], }) => {
53
53
  const { page, isDotcomRendering } = window.guardian.config;
54
54
  const adFreeTargeting = adFree ? { af: 't' } : {};
55
55
  const sharedAdTargeting = page.sharedAdTargeting
@@ -80,6 +80,7 @@ const buildPageTargeting = ({ adFree, clientSideParticipations, consentState, is
80
80
  betaAbTestParticipations: window.guardian.modules.abTests?.getParticipations() ?? {},
81
81
  },
82
82
  referrer,
83
+ idProviders,
83
84
  });
84
85
  const getViewport = () => {
85
86
  return {
@@ -1,5 +1,5 @@
1
- import type { SharedTargeting } from './shared';
2
- import type { False, True } from './types';
1
+ import type { SharedTargeting } from './shared.js';
2
+ import type { False, True } from './types.js';
3
3
  declare const videoLengths: readonly ["25", "30", "60", "90", "120", "150", "180", "210", "240", "270", "300"];
4
4
  /**
5
5
  * Content Targeting comes from the server
@@ -1,5 +1,5 @@
1
1
  import type { ConsentState, TCEventStatusCode } from '@guardian/libs';
2
- import type { False, NotApplicable, True } from './types';
2
+ import type { False, NotApplicable, True } from './types.js';
3
3
  declare const frequency: readonly ["0", "1", "2", "3", "4", "5", "6-9", "10-15", "16-19", "20-29", "30plus"];
4
4
  type Frequency = (typeof frequency)[number];
5
5
  declare const adManagerGroups: readonly ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getPersonalisedTargeting = void 0;
4
4
  const libs_1 = require("@guardian/libs");
5
- const permutive_1 = require("../permutive");
5
+ const permutive_1 = require("../permutive.js");
6
6
  /* -- Types -- */
7
7
  const frequency = [
8
8
  '0',
@@ -1,6 +1,7 @@
1
1
  import type { Participations } from '@guardian/ab-core';
2
2
  import type { CountryCode } from '@guardian/libs';
3
- import type { False, True } from './types';
3
+ import type { UserId } from '../targeting/build-page-targeting.js';
4
+ import type { False, True } from './types.js';
4
5
  declare const referrers: readonly [{
5
6
  readonly id: "facebook";
6
7
  readonly match: "facebook.com";
@@ -97,6 +98,14 @@ type SessionTargeting = {
97
98
  * [gam]: https://admanager.google.com/59666047#inventory/custom_targeting/detail/custom_key_id=215727
98
99
  */
99
100
  si: True | False;
101
+ /**
102
+ * **I**d **P**roviders – [see on Ad Manager][gam]
103
+ *
104
+ * Denote which id providers have been integrated.
105
+ *
106
+ * [gam]: To be added
107
+ */
108
+ idp: string[] | null;
100
109
  };
101
110
  type AllParticipations = {
102
111
  clientSideParticipations: Participations;
@@ -119,7 +128,8 @@ type Session = {
119
128
  pageViewId: SessionTargeting['pv'];
120
129
  participations: AllParticipations;
121
130
  referrer: string;
131
+ idProviders: UserId[];
122
132
  };
123
- declare const getSessionTargeting: ({ adTest, countryCode, localHour, isSignedIn, pageViewId, participations, referrer, }: Session) => SessionTargeting;
133
+ declare const getSessionTargeting: ({ adTest, countryCode, localHour, isSignedIn, pageViewId, participations, referrer, idProviders, }: Session) => SessionTargeting;
124
134
  export type { SessionTargeting, AllParticipations };
125
135
  export { getSessionTargeting, experimentsTargeting };
@@ -63,7 +63,10 @@ const experimentsTargeting = ({ clientSideParticipations, serverSideParticipatio
63
63
  return [...clientSideExperiment, ...serverSideExperiments, ...betaAbTests];
64
64
  };
65
65
  exports.experimentsTargeting = experimentsTargeting;
66
- const getSessionTargeting = ({ adTest, countryCode, localHour, isSignedIn, pageViewId, participations, referrer, }) => ({
66
+ const getIdProviders = (userIds) => {
67
+ return userIds.map((id) => id.name);
68
+ };
69
+ const getSessionTargeting = ({ adTest, countryCode, localHour, isSignedIn, pageViewId, participations, referrer, idProviders, }) => ({
67
70
  ab: experimentsTargeting(participations),
68
71
  at: adTest,
69
72
  cc: countryCode,
@@ -71,5 +74,6 @@ const getSessionTargeting = ({ adTest, countryCode, localHour, isSignedIn, pageV
71
74
  pv: pageViewId,
72
75
  ref: getReferrer(referrer),
73
76
  si: isSignedIn ? 't' : 'f',
77
+ idp: getIdProviders(idProviders),
74
78
  });
75
79
  exports.getSessionTargeting = getSessionTargeting;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getLocalHour = exports.getSharedTargeting = exports._ = void 0;
4
- const pick_targeting_values_1 = require("./pick-targeting-values");
4
+ const pick_targeting_values_1 = require("./pick-targeting-values.js");
5
5
  const surges = {
6
6
  0: '0',
7
7
  50: '5',
@@ -5,7 +5,9 @@ const allowedContentTypes = ['Article', 'LiveBlog'];
5
5
  const isEligibleForTeads = (slotId) => {
6
6
  const { contentType, isSensitive } = window.guardian.config.page;
7
7
  // This IAS value is returned when a page is thought to contain content which is not brand safe
8
- const iasKw = window.googletag.getConfig('targeting').targeting?.['ias-kw'];
8
+ const iasKw =
9
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- the googletag.getConfig function may not exist if googletag has been shimmed by an adblocker
10
+ window.googletag.getConfig?.('targeting').targeting?.['ias-kw'];
9
11
  const iasKwArray = Array.isArray(iasKw) ? iasKw : iasKw ? [iasKw] : [];
10
12
  const isBrandSafe = !iasKwArray.includes('IAS_16425_KW');
11
13
  if (slotId === 'dfp-ad--inline1' &&
@@ -1,4 +1,4 @@
1
- import type { False, True } from './types';
1
+ import type { False, True } from './types.js';
2
2
  /**
3
3
  * Viewport Targeting
4
4
  *
@@ -1,6 +1,6 @@
1
1
  import type { Participations } from '@guardian/ab-core';
2
2
  import type { ConsentState } from '@guardian/libs';
3
- import type { CustomParams } from './types';
3
+ import type { CustomParams } from './types.js';
4
4
  type BuildImaAdTagUrl = {
5
5
  adUnit: string;
6
6
  customParams: CustomParams;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildImaAdTagUrl = void 0;
4
4
  const libs_1 = require("@guardian/libs");
5
- const build_page_targeting_1 = require("./build-page-targeting");
5
+ const build_page_targeting_1 = require("./build-page-targeting.js");
6
6
  /**
7
7
  * @param {Record<string, MaybeArray<string|number|boolean>>
8
8
  * Follows https://support.google.com/admanager/answer/1080597
@@ -1,6 +1,6 @@
1
1
  import type { EventPayload } from '@guardian/ophan-tracker-js';
2
- import type { AdSize, SizeMapping } from './ad-sizes';
3
- import type { PageTargeting } from './targeting/build-page-targeting';
2
+ import type { AdSize, SizeMapping } from './ad-sizes.js';
3
+ import type { PageTargeting } from './targeting/build-page-targeting.js';
4
4
  import 'googletag';
5
5
  type HeaderBiddingSize = AdSize;
6
6
  interface Advert {
@@ -326,6 +326,7 @@ type ApstagInitConfig = {
326
326
  adServer?: string;
327
327
  bidTimeout?: number;
328
328
  blockedBidders?: string[];
329
+ useSafeFrames?: boolean;
329
330
  };
330
331
  interface A9AdUnitInterface {
331
332
  slotID: string;
@@ -1,4 +1,4 @@
1
- import type { Breakpoint } from './breakpoint';
1
+ import type { Breakpoint } from './breakpoint.js';
2
2
  type AdSizeString = 'fluid' | `${number},${number}`;
3
3
  /**
4
4
  * Store ad sizes in a way that is compatible with google-tag but also accessible via
@@ -1,4 +1,4 @@
1
- import { breakpoints, isBreakpoint } from './breakpoint';
1
+ import { breakpoints, isBreakpoint } from './breakpoint.js';
2
2
  /**
3
3
  * Store ad sizes in a way that is compatible with google-tag but also accessible via
4
4
  * more semantic `width`/`height` properties and keep things readonly.
@@ -1,3 +1,3 @@
1
- export { AD_LABEL_HEIGHT } from './ad-label-height';
2
- export { PREBID_TIMEOUT } from './prebid-timeout';
3
- export { TOP_ABOVE_NAV_HEIGHT } from './top-above-nav-height';
1
+ export { AD_LABEL_HEIGHT } from './ad-label-height.js';
2
+ export { PREBID_TIMEOUT } from './prebid-timeout.js';
3
+ export { TOP_ABOVE_NAV_HEIGHT } from './top-above-nav-height.js';
@@ -1,3 +1,3 @@
1
- export { AD_LABEL_HEIGHT } from './ad-label-height';
2
- export { PREBID_TIMEOUT } from './prebid-timeout';
3
- export { TOP_ABOVE_NAV_HEIGHT } from './top-above-nav-height';
1
+ export { AD_LABEL_HEIGHT } from './ad-label-height.js';
2
+ export { PREBID_TIMEOUT } from './prebid-timeout.js';
3
+ export { TOP_ABOVE_NAV_HEIGHT } from './top-above-nav-height.js';
@@ -1 +1,3 @@
1
- export declare function hashEmail(email: string): Promise<string>;
1
+ type HashClient = 'id5' | 'uid2' | 'euid';
2
+ declare function hashEmailForClient(email: string, client: HashClient): Promise<string>;
3
+ export { hashEmailForClient };
@@ -1,13 +1,25 @@
1
- async function sha256(string) {
2
- const utf8 = new TextEncoder().encode(string);
3
- const hashBuffer = await crypto.subtle.digest('SHA-256', utf8);
1
+ function toHex(hashBuffer) {
4
2
  const hashArray = Array.from(new Uint8Array(hashBuffer));
5
3
  const hashHex = hashArray
6
4
  .map((bytes) => bytes.toString(16).padStart(2, '0'))
7
5
  .join('');
8
6
  return hashHex;
9
7
  }
10
- export function hashEmail(email) {
8
+ function toBase64(hashBuffer) {
9
+ const hashBytes = new Uint8Array(hashBuffer);
10
+ const base64Hash = btoa(String.fromCharCode(...hashBytes));
11
+ return base64Hash;
12
+ }
13
+ async function hashEmailForClient(email, client) {
11
14
  const normalisedEmail = email.trim().toLowerCase();
12
- return sha256(normalisedEmail);
15
+ const utf8 = new TextEncoder().encode(normalisedEmail);
16
+ const hashBuffer = await crypto.subtle.digest('SHA-256', utf8);
17
+ switch (client) {
18
+ case 'id5':
19
+ return toHex(hashBuffer);
20
+ case 'uid2':
21
+ case 'euid':
22
+ return toBase64(hashBuffer);
23
+ }
13
24
  }
25
+ export { hashEmailForClient };
@@ -1,4 +1,4 @@
1
- import type { ConnectionType } from './types';
1
+ import type { ConnectionType } from './types.js';
2
2
  declare const supportsPerformanceAPI: () => boolean;
3
3
  interface EventTimerProperties {
4
4
  type?: ConnectionType;
@@ -1,4 +1,4 @@
1
- import { getCountryCode } from './country-code';
1
+ import { getCountryCode } from './country-code.js';
2
2
  // cache the users location so we only have to look it up once
3
3
  let geo;
4
4
  const currentGeoLocation = () => {
@@ -1,5 +1,5 @@
1
- import type { EventTimer } from './event-timer';
2
- import type { AdBlockers, Admiral, Apstag, ArticleCounts, ComscoreGlobals, Confiant, Config, DfpEnv, FetchBidResponse, GoogleTagParams, GoogleTrackConversionObject, HeaderNotification, IasPET, NetworkInformation, NSdkInstance, Ophan, OptOutAdSlot, OptOutInitializeOptions, Permutive, SafeFrameAPI, TeadsAnalytics, Trac } from './types';
1
+ import type { EventTimer } from './event-timer.js';
2
+ import type { AdBlockers, Admiral, Apstag, ArticleCounts, ComscoreGlobals, Confiant, Config, DfpEnv, FetchBidResponse, GoogleTagParams, GoogleTrackConversionObject, HeaderNotification, IasPET, NetworkInformation, NSdkInstance, Ophan, OptOutAdSlot, OptOutInitializeOptions, Permutive, SafeFrameAPI, TeadsAnalytics, Trac } from './types.js';
3
3
  declare global {
4
4
  interface Navigator {
5
5
  readonly connection?: NetworkInformation;
@@ -1,14 +1,14 @@
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 { hashEmail } from './email-hash';
12
- export type { AdSize, SizeMapping, SlotName } from './ad-sizes';
13
- export type { PageTargeting } from './targeting/build-page-targeting';
14
- export type { AdsConfigDisabled, AdsConfigUSNATorAus, AdsConfigTCFV2, } from './types';
1
+ export { isAdBlockInUse } from './detect-ad-blocker.js';
2
+ export { EventTimer } from './event-timer.js';
3
+ export { adSizes } from './ad-sizes.js';
4
+ export * as constants from './constants/index.js';
5
+ export { bypassCommercialMetricsSampling, initCommercialMetrics, } from './send-commercial-metrics.js';
6
+ export { buildPageTargeting } from './targeting/build-page-targeting.js';
7
+ export { postMessage } from './messenger/post-message.js';
8
+ export { buildImaAdTagUrl } from './targeting/youtube-ima.js';
9
+ export { getPermutivePFPSegments } from './permutive.js';
10
+ export { isEligibleForTeads } from './targeting/teads-eligibility.js';
11
+ export { hashEmailForClient } from './email-hash.js';
12
+ export type { AdSize, SizeMapping, SlotName } from './ad-sizes.js';
13
+ export type { PageTargeting } from './targeting/build-page-targeting.js';
14
+ export type { AdsConfigDisabled, AdsConfigUSNATorAus, AdsConfigTCFV2, } from './types.js';
package/dist/esm/index.js CHANGED
@@ -1,11 +1,11 @@
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 { hashEmail } from './email-hash';
1
+ export { isAdBlockInUse } from './detect-ad-blocker.js';
2
+ export { EventTimer } from './event-timer.js';
3
+ export { adSizes } from './ad-sizes.js';
4
+ export * as constants from './constants/index.js';
5
+ export { bypassCommercialMetricsSampling, initCommercialMetrics, } from './send-commercial-metrics.js';
6
+ export { buildPageTargeting } from './targeting/build-page-targeting.js';
7
+ export { postMessage } from './messenger/post-message.js';
8
+ export { buildImaAdTagUrl } from './targeting/youtube-ima.js';
9
+ export { getPermutivePFPSegments } from './permutive.js';
10
+ export { isEligibleForTeads } from './targeting/teads-eligibility.js';
11
+ export { hashEmailForClient } from './email-hash.js';
@@ -1,4 +1,4 @@
1
- import type { ConnectionType } from './types';
1
+ import type { ConnectionType } from './types.js';
2
2
  type Metric = {
3
3
  name: string;
4
4
  value: number;
@@ -1,5 +1,5 @@
1
1
  import { getMeasures, isNonNullable, log, onConsent } from '@guardian/libs';
2
- import { EventTimer } from './event-timer';
2
+ import { EventTimer } from './event-timer.js';
3
3
  var Endpoints;
4
4
  (function (Endpoints) {
5
5
  Endpoints["CODE"] = "//performance-events.code.dev-guardianapis.com/commercial-metrics";
@@ -1,9 +1,9 @@
1
1
  import type { Participations } from '@guardian/ab-core';
2
2
  import type { ConsentState, CountryCode } from '@guardian/libs';
3
- import type { AdManagerGroup, Frequency } from './personalised';
4
- import type { SharedTargeting } from './shared';
5
- import { getLocalHour } from './shared';
6
- import type { TrueOrFalse } from './types';
3
+ import type { AdManagerGroup, Frequency } from './personalised.js';
4
+ import type { SharedTargeting } from './shared.js';
5
+ import { getLocalHour } from './shared.js';
6
+ import type { TrueOrFalse } from './types.js';
7
7
  type PartialWithNulls<T> = {
8
8
  [P in keyof T]?: T[P] | null;
9
9
  };
@@ -30,6 +30,7 @@ type PageTargeting = PartialWithNulls<{
30
30
  s: string;
31
31
  sens: TrueOrFalse;
32
32
  si: TrueOrFalse;
33
+ idp: string[];
33
34
  skinsize: 'l' | 's';
34
35
  urlkw: string[];
35
36
  vl: string;
@@ -37,13 +38,24 @@ type PageTargeting = PartialWithNulls<{
37
38
  [_: string]: string | string[];
38
39
  } & SharedTargeting>;
39
40
  declare const filterValues: (pageTargets: Record<string, unknown>) => Record<string, string | string[]>;
41
+ type UserId = {
42
+ name: string;
43
+ params?: Record<string, string | number>;
44
+ storage?: {
45
+ type: 'cookie' | 'html5';
46
+ name: string;
47
+ expires: number;
48
+ refreshInSeconds?: number;
49
+ };
50
+ };
40
51
  type BuildPageTargetingParams = {
41
52
  adFree: boolean;
42
53
  clientSideParticipations: Participations;
43
54
  consentState: ConsentState;
44
55
  isSignedIn?: boolean;
45
56
  youtube?: boolean;
57
+ idProviders?: UserId[];
46
58
  };
47
- declare const buildPageTargeting: ({ adFree, clientSideParticipations, consentState, isSignedIn, youtube, }: BuildPageTargetingParams) => Record<string, string | string[]>;
59
+ declare const buildPageTargeting: ({ adFree, clientSideParticipations, consentState, isSignedIn, youtube, idProviders, }: BuildPageTargetingParams) => Record<string, string | string[]>;
48
60
  export { buildPageTargeting, filterValues, getLocalHour };
49
- export type { PageTargeting };
61
+ export type { UserId, PageTargeting };
@@ -1,11 +1,11 @@
1
1
  import { cmp, getConsentFor, getCookie, isString } from '@guardian/libs';
2
- import { supportsPerformanceAPI } from '../event-timer';
3
- import { getLocale } from '../geo/get-locale';
4
- import { getContentTargeting } from './content';
5
- import { getPersonalisedTargeting } from './personalised';
6
- import { getSessionTargeting } from './session';
7
- import { getLocalHour, getSharedTargeting } from './shared';
8
- import { getViewportTargeting } from './viewport';
2
+ import { supportsPerformanceAPI } from '../event-timer.js';
3
+ import { getLocale } from '../geo/get-locale.js';
4
+ import { getContentTargeting } from './content.js';
5
+ import { getPersonalisedTargeting } from './personalised.js';
6
+ import { getSessionTargeting } from './session.js';
7
+ import { getLocalHour, getSharedTargeting } from './shared.js';
8
+ import { getViewportTargeting } from './viewport.js';
9
9
  const filterValues = (pageTargets) => {
10
10
  const filtered = {};
11
11
  for (const key in pageTargets) {
@@ -44,7 +44,7 @@ const isFirstVisit = (referrer) => {
44
44
  }
45
45
  return !referrerMatchesHost(referrer);
46
46
  };
47
- const buildPageTargeting = ({ adFree, clientSideParticipations, consentState, isSignedIn = false, youtube = false, }) => {
47
+ const buildPageTargeting = ({ adFree, clientSideParticipations, consentState, isSignedIn = false, youtube = false, idProviders = [], }) => {
48
48
  const { page, isDotcomRendering } = window.guardian.config;
49
49
  const adFreeTargeting = adFree ? { af: 't' } : {};
50
50
  const sharedAdTargeting = page.sharedAdTargeting
@@ -75,6 +75,7 @@ const buildPageTargeting = ({ adFree, clientSideParticipations, consentState, is
75
75
  betaAbTestParticipations: window.guardian.modules.abTests?.getParticipations() ?? {},
76
76
  },
77
77
  referrer,
78
+ idProviders,
78
79
  });
79
80
  const getViewport = () => {
80
81
  return {
@@ -1,5 +1,5 @@
1
- import type { SharedTargeting } from './shared';
2
- import type { False, True } from './types';
1
+ import type { SharedTargeting } from './shared.js';
2
+ import type { False, True } from './types.js';
3
3
  declare const videoLengths: readonly ["25", "30", "60", "90", "120", "150", "180", "210", "240", "270", "300"];
4
4
  /**
5
5
  * Content Targeting comes from the server
@@ -1,5 +1,5 @@
1
1
  import type { ConsentState, TCEventStatusCode } from '@guardian/libs';
2
- import type { False, NotApplicable, True } from './types';
2
+ import type { False, NotApplicable, True } from './types.js';
3
3
  declare const frequency: readonly ["0", "1", "2", "3", "4", "5", "6-9", "10-15", "16-19", "20-29", "30plus"];
4
4
  type Frequency = (typeof frequency)[number];
5
5
  declare const adManagerGroups: readonly ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];
@@ -1,5 +1,5 @@
1
1
  import { storage } from '@guardian/libs';
2
- import { clearPermutiveSegments, getPermutivePFPSegments, getPermutiveSegments, } from '../permutive';
2
+ import { clearPermutiveSegments, getPermutivePFPSegments, getPermutiveSegments, } from '../permutive.js';
3
3
  /* -- Types -- */
4
4
  const frequency = [
5
5
  '0',
@@ -1,6 +1,7 @@
1
1
  import type { Participations } from '@guardian/ab-core';
2
2
  import type { CountryCode } from '@guardian/libs';
3
- import type { False, True } from './types';
3
+ import type { UserId } from '../targeting/build-page-targeting.js';
4
+ import type { False, True } from './types.js';
4
5
  declare const referrers: readonly [{
5
6
  readonly id: "facebook";
6
7
  readonly match: "facebook.com";
@@ -97,6 +98,14 @@ type SessionTargeting = {
97
98
  * [gam]: https://admanager.google.com/59666047#inventory/custom_targeting/detail/custom_key_id=215727
98
99
  */
99
100
  si: True | False;
101
+ /**
102
+ * **I**d **P**roviders – [see on Ad Manager][gam]
103
+ *
104
+ * Denote which id providers have been integrated.
105
+ *
106
+ * [gam]: To be added
107
+ */
108
+ idp: string[] | null;
100
109
  };
101
110
  type AllParticipations = {
102
111
  clientSideParticipations: Participations;
@@ -119,7 +128,8 @@ type Session = {
119
128
  pageViewId: SessionTargeting['pv'];
120
129
  participations: AllParticipations;
121
130
  referrer: string;
131
+ idProviders: UserId[];
122
132
  };
123
- declare const getSessionTargeting: ({ adTest, countryCode, localHour, isSignedIn, pageViewId, participations, referrer, }: Session) => SessionTargeting;
133
+ declare const getSessionTargeting: ({ adTest, countryCode, localHour, isSignedIn, pageViewId, participations, referrer, idProviders, }: Session) => SessionTargeting;
124
134
  export type { SessionTargeting, AllParticipations };
125
135
  export { getSessionTargeting, experimentsTargeting };
@@ -59,7 +59,10 @@ const experimentsTargeting = ({ clientSideParticipations, serverSideParticipatio
59
59
  }
60
60
  return [...clientSideExperiment, ...serverSideExperiments, ...betaAbTests];
61
61
  };
62
- const getSessionTargeting = ({ adTest, countryCode, localHour, isSignedIn, pageViewId, participations, referrer, }) => ({
62
+ const getIdProviders = (userIds) => {
63
+ return userIds.map((id) => id.name);
64
+ };
65
+ const getSessionTargeting = ({ adTest, countryCode, localHour, isSignedIn, pageViewId, participations, referrer, idProviders, }) => ({
63
66
  ab: experimentsTargeting(participations),
64
67
  at: adTest,
65
68
  cc: countryCode,
@@ -67,5 +70,6 @@ const getSessionTargeting = ({ adTest, countryCode, localHour, isSignedIn, pageV
67
70
  pv: pageViewId,
68
71
  ref: getReferrer(referrer),
69
72
  si: isSignedIn ? 't' : 'f',
73
+ idp: getIdProviders(idProviders),
70
74
  });
71
75
  export { getSessionTargeting, experimentsTargeting };
@@ -1,4 +1,4 @@
1
- import { pickTargetingValues } from './pick-targeting-values';
1
+ import { pickTargetingValues } from './pick-targeting-values.js';
2
2
  const surges = {
3
3
  0: '0',
4
4
  50: '5',
@@ -2,7 +2,9 @@ const allowedContentTypes = ['Article', 'LiveBlog'];
2
2
  const isEligibleForTeads = (slotId) => {
3
3
  const { contentType, isSensitive } = window.guardian.config.page;
4
4
  // This IAS value is returned when a page is thought to contain content which is not brand safe
5
- const iasKw = window.googletag.getConfig('targeting').targeting?.['ias-kw'];
5
+ const iasKw =
6
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- the googletag.getConfig function may not exist if googletag has been shimmed by an adblocker
7
+ window.googletag.getConfig?.('targeting').targeting?.['ias-kw'];
6
8
  const iasKwArray = Array.isArray(iasKw) ? iasKw : iasKw ? [iasKw] : [];
7
9
  const isBrandSafe = !iasKwArray.includes('IAS_16425_KW');
8
10
  if (slotId === 'dfp-ad--inline1' &&
@@ -1,4 +1,4 @@
1
- import type { False, True } from './types';
1
+ import type { False, True } from './types.js';
2
2
  /**
3
3
  * Viewport Targeting
4
4
  *
@@ -1,6 +1,6 @@
1
1
  import type { Participations } from '@guardian/ab-core';
2
2
  import type { ConsentState } from '@guardian/libs';
3
- import type { CustomParams } from './types';
3
+ import type { CustomParams } from './types.js';
4
4
  type BuildImaAdTagUrl = {
5
5
  adUnit: string;
6
6
  customParams: CustomParams;
@@ -1,5 +1,5 @@
1
1
  import { log } from '@guardian/libs';
2
- import { buildPageTargeting, filterValues } from './build-page-targeting';
2
+ import { buildPageTargeting, filterValues } from './build-page-targeting.js';
3
3
  /**
4
4
  * @param {Record<string, MaybeArray<string|number|boolean>>
5
5
  * Follows https://support.google.com/admanager/answer/1080597
@@ -1,6 +1,6 @@
1
1
  import type { EventPayload } from '@guardian/ophan-tracker-js';
2
- import type { AdSize, SizeMapping } from './ad-sizes';
3
- import type { PageTargeting } from './targeting/build-page-targeting';
2
+ import type { AdSize, SizeMapping } from './ad-sizes.js';
3
+ import type { PageTargeting } from './targeting/build-page-targeting.js';
4
4
  import 'googletag';
5
5
  type HeaderBiddingSize = AdSize;
6
6
  interface Advert {
@@ -326,6 +326,7 @@ type ApstagInitConfig = {
326
326
  adServer?: string;
327
327
  bidTimeout?: number;
328
328
  blockedBidders?: string[];
329
+ useSafeFrames?: boolean;
329
330
  };
330
331
  interface A9AdUnitInterface {
331
332
  slotID: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guardian/commercial-core",
3
- "version": "29.3.0",
3
+ "version": "30.1.0",
4
4
  "description": "Guardian advertising business logic",
5
5
  "homepage": "https://github.com/guardian/commercial#readme",
6
6
  "bugs": {
@@ -17,6 +17,7 @@
17
17
  ],
18
18
  "main": "dist/cjs/index.js",
19
19
  "module": "dist/esm/index.js",
20
+ "type": "module",
20
21
  "exports": {
21
22
  ".": {
22
23
  "import": "./dist/esm/index.js",
@@ -31,22 +32,23 @@
31
32
  "./package.json": "./package.json"
32
33
  },
33
34
  "peerDependencies": {
34
- "@guardian/ab-core": "^8.0.1",
35
- "@guardian/libs": "^26.0.0"
35
+ "@guardian/ab-core": "^9.0.0",
36
+ "@guardian/libs": "^27.0.0"
36
37
  },
37
38
  "dependencies": {
38
- "@guardian/ab-core": "8.0.1",
39
- "@guardian/libs": "26.0.1"
39
+ "@guardian/ab-core": "9.0.0",
40
+ "@guardian/libs": "27.0.0"
40
41
  },
41
42
  "devDependencies": {
42
- "@guardian/ophan-tracker-js": "2.6.1",
43
+ "@guardian/ophan-tracker-js": "2.6.3",
44
+ "@types/google-publisher-tag": "~1.20251117.0",
43
45
  "@types/jest": "30.0.0",
44
- "@types/node": "24.7.2",
45
- "@types/google-publisher-tag": "~1.20250811.1",
46
+ "@types/node": "24.10.1",
46
47
  "jest": "^30.2.0",
47
48
  "jest-environment-jsdom": "^30.2.0",
48
49
  "jest-environment-jsdom-global": "~4.0.0",
49
- "ts-jest": "^29.4.4",
50
+ "ts-jest": "^29.4.6",
51
+ "tsc-alias": "1.8.16",
50
52
  "type-fest": "^4.41.0",
51
53
  "typescript": "5.9.3"
52
54
  },
@@ -56,7 +58,7 @@
56
58
  "scripts": {
57
59
  "build": "pnpm run --parallel --aggregate-output /^build:.*/",
58
60
  "clean": "rm -rf dist",
59
- "build:esm": "tsc --outDir ./dist/esm --project ./tsconfig.esm.json",
61
+ "build:esm": "tsc --outDir ./dist/esm --project ./tsconfig.esm.json && tsc-alias --project ./tsconfig.esm.json",
60
62
  "build:cjs": "tsc --outDir ./dist/cjs --project ./tsconfig.cjs.json",
61
63
  "lint": "eslint .",
62
64
  "prettier:check": "prettier . --check --cache",