@guardian/commercial-core 4.11.1 → 4.13.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.
@@ -50,7 +50,7 @@ const adSlotConfigs = {
50
50
  const createAdSlotElement = (name, attrs, classes) => {
51
51
  const id = `${adSlotIdPrefix}${name}`;
52
52
  // 3562dc07-78e9-4507-b922-78b979d4c5cb
53
- if (window.guardian.config?.isDotcomRendering && name === 'top-above-nav') {
53
+ if (window.guardian.config.isDotcomRendering && name === 'top-above-nav') {
54
54
  // This is to prevent a problem that appeared with DCR.
55
55
  // We are simply making sure that if we are about to
56
56
  // introduce dfp-ad--top-above-nav then there isn't already one.
@@ -16,7 +16,7 @@ declare global {
16
16
  }>;
17
17
  guardian: {
18
18
  commercialTimer?: EventTimer;
19
- config?: GuardianWindowConfig;
19
+ config: GuardianWindowConfig;
20
20
  };
21
21
  ga: UniversalAnalytics.ga | null;
22
22
  readonly navigator: Navigator;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.trackEvent = void 0;
4
4
  const trackEvent = (timingCategory, timingVar, timingLabel) => {
5
5
  const { ga, guardian } = window;
6
- const trackerName = guardian.config?.googleAnalytics?.trackers.editorial;
6
+ const trackerName = guardian.config.googleAnalytics?.trackers.editorial;
7
7
  if (typeof ga !== 'function') {
8
8
  return;
9
9
  }
@@ -34,3 +34,5 @@ export { pickTargetingValues } from './targeting/pick-targeting-values';
34
34
  export { init as initMessenger } from './messenger';
35
35
  export type { RegisterListener, RegisterPersistentListener, RespondProxy, } from './messenger';
36
36
  export { postMessage } from './messenger/post-message';
37
+ export { buildPageTargeting } from './targeting/build-page-targeting';
38
+ export type { PageTargeting } from './targeting/build-page-targeting';
package/dist/cjs/index.js CHANGED
@@ -24,7 +24,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  return result;
25
25
  };
26
26
  Object.defineProperty(exports, "__esModule", { value: true });
27
- exports.postMessage = exports.initMessenger = exports.pickTargetingValues = exports.getViewportTargeting = exports.getSharedTargeting = exports.getSessionTargeting = exports.getPersonalisedTargeting = exports.getContentTargeting = exports.constants = exports.concatSizeMappings = exports.createAdSlot = exports.disabledAds = exports.buildAdsConfigWithConsent = exports.initTrackGpcSignal = exports.initTrackLabsContainer = exports.initTrackScrollDepth = exports.getPermutivePFPSegments = exports.getPermutiveSegments = exports.clearPermutiveSegments = exports.isAdBlockInUse = exports.isBreakpoint = exports.createAdSize = exports.slotSizeMappings = exports.getAdSize = exports.adSizes = exports.initCommercialMetrics = exports.bypassCommercialMetricsSampling = exports.EventTimer = exports.remarketing = exports.inizio = exports.twitter = exports.fbPixel = exports.permutive = exports.ias = void 0;
27
+ exports.buildPageTargeting = exports.postMessage = exports.initMessenger = exports.pickTargetingValues = exports.getViewportTargeting = exports.getSharedTargeting = exports.getSessionTargeting = exports.getPersonalisedTargeting = exports.getContentTargeting = exports.constants = exports.concatSizeMappings = exports.createAdSlot = exports.disabledAds = exports.buildAdsConfigWithConsent = exports.initTrackGpcSignal = exports.initTrackLabsContainer = exports.initTrackScrollDepth = exports.getPermutivePFPSegments = exports.getPermutiveSegments = exports.clearPermutiveSegments = exports.isAdBlockInUse = exports.isBreakpoint = exports.createAdSize = exports.slotSizeMappings = exports.getAdSize = exports.adSizes = exports.initCommercialMetrics = exports.bypassCommercialMetricsSampling = exports.EventTimer = exports.remarketing = exports.inizio = exports.twitter = exports.fbPixel = exports.permutive = exports.ias = void 0;
28
28
  var ias_1 = require("./third-party-tags/ias");
29
29
  Object.defineProperty(exports, "ias", { enumerable: true, get: function () { return ias_1.ias; } });
30
30
  var permutive_1 = require("./third-party-tags/permutive");
@@ -84,3 +84,5 @@ var messenger_1 = require("./messenger");
84
84
  Object.defineProperty(exports, "initMessenger", { enumerable: true, get: function () { return messenger_1.init; } });
85
85
  var post_message_1 = require("./messenger/post-message");
86
86
  Object.defineProperty(exports, "postMessage", { enumerable: true, get: function () { return post_message_1.postMessage; } });
87
+ var build_page_targeting_1 = require("./targeting/build-page-targeting");
88
+ Object.defineProperty(exports, "buildPageTargeting", { enumerable: true, get: function () { return build_page_targeting_1.buildPageTargeting; } });
@@ -0,0 +1,39 @@
1
+ import type { Participations } from '@guardian/ab-core';
2
+ import type { ConsentState } from '@guardian/consent-management-platform/dist/types';
3
+ import type { CountryCode } from '@guardian/libs';
4
+ import type { False, True } from '../types';
5
+ import type { AdManagerGroup, Frequency } from './personalised';
6
+ import type { SharedTargeting } from './shared';
7
+ declare type PartialWithNulls<T> = {
8
+ [P in keyof T]?: T[P] | null;
9
+ };
10
+ declare type TrueOrFalse = True | False;
11
+ declare type PageTargeting = PartialWithNulls<{
12
+ ab: string[];
13
+ af: 't';
14
+ amtgrp: AdManagerGroup;
15
+ at: string;
16
+ bp: 'mobile' | 'tablet' | 'desktop';
17
+ cc: CountryCode;
18
+ cmp_interaction: string;
19
+ consent_tcfv2: string;
20
+ dcre: TrueOrFalse;
21
+ fr: Frequency;
22
+ inskin: TrueOrFalse;
23
+ pa: TrueOrFalse;
24
+ permutive: string[];
25
+ pv: string;
26
+ rdp: string;
27
+ ref: string;
28
+ rp: 'dotcom-rendering' | 'dotcom-platform';
29
+ s: string;
30
+ sens: TrueOrFalse;
31
+ si: TrueOrFalse;
32
+ skinsize: 'l' | 's';
33
+ urlkw: string[];
34
+ vl: string;
35
+ [_: string]: string | string[];
36
+ } & SharedTargeting>;
37
+ declare const buildPageTargeting: (consentState: ConsentState, adFree: boolean, countryCode: CountryCode, clientSideParticipations: Participations) => PageTargeting;
38
+ export { buildPageTargeting };
39
+ export type { PageTargeting };
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildPageTargeting = void 0;
4
+ const consent_management_platform_1 = require("@guardian/consent-management-platform");
5
+ const libs_1 = require("@guardian/libs");
6
+ const content_1 = require("./content");
7
+ const personalised_1 = require("./personalised");
8
+ const session_1 = require("./session");
9
+ const shared_1 = require("./shared");
10
+ const viewport_1 = require("./viewport");
11
+ const filterEmptyValues = (pageTargets) => {
12
+ const filtered = {};
13
+ for (const key in pageTargets) {
14
+ const value = pageTargets[key];
15
+ if ((0, libs_1.isString)(value)) {
16
+ filtered[key] = value;
17
+ }
18
+ else if (Array.isArray(value) &&
19
+ value.length > 0 &&
20
+ value.every(libs_1.isString)) {
21
+ filtered[key] = value;
22
+ }
23
+ }
24
+ return filtered;
25
+ };
26
+ const buildPageTargeting = (consentState, adFree, countryCode, clientSideParticipations) => {
27
+ const { page, isDotcomRendering } = window.guardian.config;
28
+ const adFreeTargeting = adFree ? { af: 't' } : {};
29
+ const contentTargeting = (0, content_1.getContentTargeting)({
30
+ eligibleForDCR: isDotcomRendering,
31
+ path: `/${page.pageId}`,
32
+ renderingPlatform: isDotcomRendering
33
+ ? 'dotcom-rendering'
34
+ : 'dotcom-platform',
35
+ section: page.section,
36
+ sensitive: page.isSensitive,
37
+ videoLength: page.videoDuration,
38
+ });
39
+ const getReferrer = () => document.referrer || '';
40
+ const sessionTargeting = (0, session_1.getSessionTargeting)({
41
+ adTest: (0, libs_1.getCookie)({ name: 'adtest', shouldMemoize: true }),
42
+ countryCode,
43
+ isSignedIn: !!(0, libs_1.getCookie)({ name: 'GU_U' }),
44
+ pageViewId: window.guardian.config.ophan.pageViewId,
45
+ participations: {
46
+ clientSideParticipations,
47
+ serverSideParticipations: window.guardian.config.tests ?? {},
48
+ },
49
+ referrer: getReferrer(),
50
+ });
51
+ const getViewport = () => {
52
+ return {
53
+ width: window.innerWidth || document.body.clientWidth || 0,
54
+ height: window.innerHeight || document.body.clientHeight || 0,
55
+ };
56
+ };
57
+ const viewportTargeting = (0, viewport_1.getViewportTargeting)({
58
+ viewPortWidth: getViewport().width,
59
+ cmpBannerWillShow: !consent_management_platform_1.cmp.hasInitialised() || consent_management_platform_1.cmp.willShowPrivacyMessageSync(),
60
+ });
61
+ const sharedAdTargeting = page.sharedAdTargeting
62
+ ? (0, shared_1.getSharedTargeting)(page.sharedAdTargeting)
63
+ : {};
64
+ const personalisedTargeting = (0, personalised_1.getPersonalisedTargeting)(consentState);
65
+ const pageTargets = {
66
+ ...personalisedTargeting,
67
+ ...sharedAdTargeting,
68
+ ...adFreeTargeting,
69
+ ...contentTargeting,
70
+ ...sessionTargeting,
71
+ ...viewportTargeting,
72
+ };
73
+ // filter out empty values
74
+ const pageTargeting = filterEmptyValues(pageTargets);
75
+ return pageTargeting;
76
+ };
77
+ exports.buildPageTargeting = buildPageTargeting;
@@ -2,6 +2,7 @@ import type { ConsentState } from '@guardian/consent-management-platform/dist/ty
2
2
  import type { TCEventStatusCode } from '@guardian/consent-management-platform/dist/types/tcfv2';
3
3
  import type { False, NotApplicable, True } from '../types';
4
4
  declare const frequency: readonly ["0", "1", "2", "3", "4", "5", "6-9", "10-15", "16-19", "20-29", "30plus"];
5
+ declare type Frequency = typeof frequency[number];
5
6
  declare const adManagerGroups: readonly ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];
6
7
  declare type AdManagerGroup = typeof adManagerGroups[number];
7
8
  /**
@@ -46,7 +47,7 @@ declare type PersonalisedTargeting = {
46
47
  *
47
48
  * [gam]: https://admanager.google.com/59666047#inventory/custom_targeting/detail/custom_key_id=214647
48
49
  */
49
- fr: typeof frequency[number];
50
+ fr: Frequency;
50
51
  /**
51
52
  * **P**ersonalised **A**ds Consent – [see on Ad Manager][gam]
52
53
  *
@@ -76,4 +77,4 @@ declare type PersonalisedTargeting = {
76
77
  };
77
78
  declare const getPersonalisedTargeting: (state: ConsentState) => PersonalisedTargeting;
78
79
  export { getPersonalisedTargeting };
79
- export type { PersonalisedTargeting };
80
+ export type { PersonalisedTargeting, AdManagerGroup, Frequency };
@@ -23,7 +23,23 @@ export declare type GuardianAnalyticsConfig = {
23
23
  };
24
24
  export declare type GuardianWindowConfig = {
25
25
  googleAnalytics?: GuardianAnalyticsConfig;
26
- isDotcomRendering?: boolean;
26
+ isDotcomRendering: boolean;
27
+ ophan: {
28
+ pageViewId: string;
29
+ browserId?: string;
30
+ };
31
+ page: {
32
+ sharedAdTargeting?: Record<string, string | string[]>;
33
+ pageAdTargeting?: Record<string, string | string[]>;
34
+ isSensitive: boolean;
35
+ pageId: string;
36
+ section: string;
37
+ videoDuration: number;
38
+ };
39
+ tests?: {
40
+ [key: `${string}Control`]: 'control';
41
+ [key: `${string}Variant`]: 'variant';
42
+ };
27
43
  };
28
44
  export declare type GoogleTagParams = unknown;
29
45
  export declare type GoogleTrackConversionObject = {
@@ -47,7 +47,7 @@ const adSlotConfigs = {
47
47
  const createAdSlotElement = (name, attrs, classes) => {
48
48
  const id = `${adSlotIdPrefix}${name}`;
49
49
  // 3562dc07-78e9-4507-b922-78b979d4c5cb
50
- if (window.guardian.config?.isDotcomRendering && name === 'top-above-nav') {
50
+ if (window.guardian.config.isDotcomRendering && name === 'top-above-nav') {
51
51
  // This is to prevent a problem that appeared with DCR.
52
52
  // We are simply making sure that if we are about to
53
53
  // introduce dfp-ad--top-above-nav then there isn't already one.
@@ -16,7 +16,7 @@ declare global {
16
16
  }>;
17
17
  guardian: {
18
18
  commercialTimer?: EventTimer;
19
- config?: GuardianWindowConfig;
19
+ config: GuardianWindowConfig;
20
20
  };
21
21
  ga: UniversalAnalytics.ga | null;
22
22
  readonly navigator: Navigator;
@@ -1,6 +1,6 @@
1
1
  export const trackEvent = (timingCategory, timingVar, timingLabel) => {
2
2
  const { ga, guardian } = window;
3
- const trackerName = guardian.config?.googleAnalytics?.trackers.editorial;
3
+ const trackerName = guardian.config.googleAnalytics?.trackers.editorial;
4
4
  if (typeof ga !== 'function') {
5
5
  return;
6
6
  }
@@ -34,3 +34,5 @@ export { pickTargetingValues } from './targeting/pick-targeting-values';
34
34
  export { init as initMessenger } from './messenger';
35
35
  export type { RegisterListener, RegisterPersistentListener, RespondProxy, } from './messenger';
36
36
  export { postMessage } from './messenger/post-message';
37
+ export { buildPageTargeting } from './targeting/build-page-targeting';
38
+ export type { PageTargeting } from './targeting/build-page-targeting';
package/dist/esm/index.js CHANGED
@@ -26,3 +26,4 @@ export { getViewportTargeting } from './targeting/viewport';
26
26
  export { pickTargetingValues } from './targeting/pick-targeting-values';
27
27
  export { init as initMessenger } from './messenger';
28
28
  export { postMessage } from './messenger/post-message';
29
+ export { buildPageTargeting } from './targeting/build-page-targeting';
@@ -0,0 +1,39 @@
1
+ import type { Participations } from '@guardian/ab-core';
2
+ import type { ConsentState } from '@guardian/consent-management-platform/dist/types';
3
+ import type { CountryCode } from '@guardian/libs';
4
+ import type { False, True } from '../types';
5
+ import type { AdManagerGroup, Frequency } from './personalised';
6
+ import type { SharedTargeting } from './shared';
7
+ declare type PartialWithNulls<T> = {
8
+ [P in keyof T]?: T[P] | null;
9
+ };
10
+ declare type TrueOrFalse = True | False;
11
+ declare type PageTargeting = PartialWithNulls<{
12
+ ab: string[];
13
+ af: 't';
14
+ amtgrp: AdManagerGroup;
15
+ at: string;
16
+ bp: 'mobile' | 'tablet' | 'desktop';
17
+ cc: CountryCode;
18
+ cmp_interaction: string;
19
+ consent_tcfv2: string;
20
+ dcre: TrueOrFalse;
21
+ fr: Frequency;
22
+ inskin: TrueOrFalse;
23
+ pa: TrueOrFalse;
24
+ permutive: string[];
25
+ pv: string;
26
+ rdp: string;
27
+ ref: string;
28
+ rp: 'dotcom-rendering' | 'dotcom-platform';
29
+ s: string;
30
+ sens: TrueOrFalse;
31
+ si: TrueOrFalse;
32
+ skinsize: 'l' | 's';
33
+ urlkw: string[];
34
+ vl: string;
35
+ [_: string]: string | string[];
36
+ } & SharedTargeting>;
37
+ declare const buildPageTargeting: (consentState: ConsentState, adFree: boolean, countryCode: CountryCode, clientSideParticipations: Participations) => PageTargeting;
38
+ export { buildPageTargeting };
39
+ export type { PageTargeting };
@@ -0,0 +1,74 @@
1
+ import { cmp } from '@guardian/consent-management-platform';
2
+ import { getCookie, isString } from '@guardian/libs';
3
+ import { getContentTargeting } from './content';
4
+ import { getPersonalisedTargeting } from './personalised';
5
+ import { getSessionTargeting } from './session';
6
+ import { getSharedTargeting } from './shared';
7
+ import { getViewportTargeting } from './viewport';
8
+ const filterEmptyValues = (pageTargets) => {
9
+ const filtered = {};
10
+ for (const key in pageTargets) {
11
+ const value = pageTargets[key];
12
+ if (isString(value)) {
13
+ filtered[key] = value;
14
+ }
15
+ else if (Array.isArray(value) &&
16
+ value.length > 0 &&
17
+ value.every(isString)) {
18
+ filtered[key] = value;
19
+ }
20
+ }
21
+ return filtered;
22
+ };
23
+ const buildPageTargeting = (consentState, adFree, countryCode, clientSideParticipations) => {
24
+ const { page, isDotcomRendering } = window.guardian.config;
25
+ const adFreeTargeting = adFree ? { af: 't' } : {};
26
+ const contentTargeting = getContentTargeting({
27
+ eligibleForDCR: isDotcomRendering,
28
+ path: `/${page.pageId}`,
29
+ renderingPlatform: isDotcomRendering
30
+ ? 'dotcom-rendering'
31
+ : 'dotcom-platform',
32
+ section: page.section,
33
+ sensitive: page.isSensitive,
34
+ videoLength: page.videoDuration,
35
+ });
36
+ const getReferrer = () => document.referrer || '';
37
+ const sessionTargeting = getSessionTargeting({
38
+ adTest: getCookie({ name: 'adtest', shouldMemoize: true }),
39
+ countryCode,
40
+ isSignedIn: !!getCookie({ name: 'GU_U' }),
41
+ pageViewId: window.guardian.config.ophan.pageViewId,
42
+ participations: {
43
+ clientSideParticipations,
44
+ serverSideParticipations: window.guardian.config.tests ?? {},
45
+ },
46
+ referrer: getReferrer(),
47
+ });
48
+ const getViewport = () => {
49
+ return {
50
+ width: window.innerWidth || document.body.clientWidth || 0,
51
+ height: window.innerHeight || document.body.clientHeight || 0,
52
+ };
53
+ };
54
+ const viewportTargeting = getViewportTargeting({
55
+ viewPortWidth: getViewport().width,
56
+ cmpBannerWillShow: !cmp.hasInitialised() || cmp.willShowPrivacyMessageSync(),
57
+ });
58
+ const sharedAdTargeting = page.sharedAdTargeting
59
+ ? getSharedTargeting(page.sharedAdTargeting)
60
+ : {};
61
+ const personalisedTargeting = getPersonalisedTargeting(consentState);
62
+ const pageTargets = {
63
+ ...personalisedTargeting,
64
+ ...sharedAdTargeting,
65
+ ...adFreeTargeting,
66
+ ...contentTargeting,
67
+ ...sessionTargeting,
68
+ ...viewportTargeting,
69
+ };
70
+ // filter out empty values
71
+ const pageTargeting = filterEmptyValues(pageTargets);
72
+ return pageTargeting;
73
+ };
74
+ export { buildPageTargeting };
@@ -2,6 +2,7 @@ import type { ConsentState } from '@guardian/consent-management-platform/dist/ty
2
2
  import type { TCEventStatusCode } from '@guardian/consent-management-platform/dist/types/tcfv2';
3
3
  import type { False, NotApplicable, True } from '../types';
4
4
  declare const frequency: readonly ["0", "1", "2", "3", "4", "5", "6-9", "10-15", "16-19", "20-29", "30plus"];
5
+ declare type Frequency = typeof frequency[number];
5
6
  declare const adManagerGroups: readonly ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];
6
7
  declare type AdManagerGroup = typeof adManagerGroups[number];
7
8
  /**
@@ -46,7 +47,7 @@ declare type PersonalisedTargeting = {
46
47
  *
47
48
  * [gam]: https://admanager.google.com/59666047#inventory/custom_targeting/detail/custom_key_id=214647
48
49
  */
49
- fr: typeof frequency[number];
50
+ fr: Frequency;
50
51
  /**
51
52
  * **P**ersonalised **A**ds Consent – [see on Ad Manager][gam]
52
53
  *
@@ -76,4 +77,4 @@ declare type PersonalisedTargeting = {
76
77
  };
77
78
  declare const getPersonalisedTargeting: (state: ConsentState) => PersonalisedTargeting;
78
79
  export { getPersonalisedTargeting };
79
- export type { PersonalisedTargeting };
80
+ export type { PersonalisedTargeting, AdManagerGroup, Frequency };
@@ -23,7 +23,23 @@ export declare type GuardianAnalyticsConfig = {
23
23
  };
24
24
  export declare type GuardianWindowConfig = {
25
25
  googleAnalytics?: GuardianAnalyticsConfig;
26
- isDotcomRendering?: boolean;
26
+ isDotcomRendering: boolean;
27
+ ophan: {
28
+ pageViewId: string;
29
+ browserId?: string;
30
+ };
31
+ page: {
32
+ sharedAdTargeting?: Record<string, string | string[]>;
33
+ pageAdTargeting?: Record<string, string | string[]>;
34
+ isSensitive: boolean;
35
+ pageId: string;
36
+ section: string;
37
+ videoDuration: number;
38
+ };
39
+ tests?: {
40
+ [key: `${string}Control`]: 'control';
41
+ [key: `${string}Variant`]: 'variant';
42
+ };
27
43
  };
28
44
  export declare type GoogleTagParams = unknown;
29
45
  export declare type GoogleTrackConversionObject = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guardian/commercial-core",
3
- "version": "4.11.1",
3
+ "version": "4.13.0",
4
4
  "description": "Guardian advertising business logic",
5
5
  "homepage": "https://github.com/guardian/commercial-core#readme",
6
6
  "bugs": {