@guardian/commercial-core 0.0.0-beta-20250716123536 → 0.0.0-beta-20251023093018
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.
- package/dist/cjs/ad-sizes.d.ts +1 -4
- package/dist/cjs/ad-sizes.js +0 -3
- package/dist/cjs/geo/country-code.js +1 -3
- package/dist/cjs/global.d.ts +7 -1
- package/dist/cjs/index.js +17 -7
- package/dist/cjs/targeting/build-page-targeting.d.ts +3 -1
- package/dist/cjs/targeting/build-page-targeting.js +4 -1
- package/dist/cjs/targeting/session.d.ts +16 -2
- package/dist/cjs/targeting/session.js +18 -4
- package/dist/cjs/targeting/shared.d.ts +2 -1
- package/dist/cjs/targeting/shared.js +5 -1
- package/dist/cjs/types.d.ts +8 -3
- package/dist/esm/ad-sizes.d.ts +1 -4
- package/dist/esm/ad-sizes.js +0 -3
- package/dist/esm/geo/country-code.js +1 -3
- package/dist/esm/global.d.ts +7 -1
- package/dist/esm/targeting/build-page-targeting.d.ts +3 -1
- package/dist/esm/targeting/build-page-targeting.js +4 -2
- package/dist/esm/targeting/session.d.ts +16 -2
- package/dist/esm/targeting/session.js +18 -4
- package/dist/esm/targeting/shared.d.ts +2 -1
- package/dist/esm/targeting/shared.js +4 -1
- package/dist/esm/types.d.ts +8 -3
- package/package.json +11 -10
package/dist/cjs/ad-sizes.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ declare class AdSize extends Array<number> {
|
|
|
28
28
|
get height(): number;
|
|
29
29
|
}
|
|
30
30
|
type SizeKeys = '160x600' | '300x1050' | '300x250' | '300x600' | '728x90' | '970x250' | 'billboard' | 'cascade' | 'empty' | 'fabric' | 'fluid' | 'googleCard' | 'halfPage' | 'leaderboard' | 'merchandising' | 'merchandisingHigh' | 'merchandisingHighAdFeature' | 'mobilesticky' | 'mpu' | 'outOfPage' | 'outstreamDesktop' | 'outstreamGoogleDesktop' | 'outstreamMobile' | 'portrait' | 'portraitInterstitial' | 'pubmaticInterscroller' | 'skyscraper' | 'sponsorLogo';
|
|
31
|
-
type SlotName = 'article-end' | '
|
|
31
|
+
type SlotName = 'article-end' | 'comments-expanded' | 'comments' | 'crossword-banner-mobile' | 'exclusion' | 'external' | 'fronts-banner' | 'inline' | 'liveblog-top' | 'merchandising-high' | 'merchandising' | 'mobile-sticky' | 'football-right' | 'mostpop' | 'right' | 'sponsor-logo' | 'survey' | 'top-above-nav' | 'interactive';
|
|
32
32
|
type SizeMapping = Partial<Record<Breakpoint, readonly AdSize[]>>;
|
|
33
33
|
type SlotSizeMappings = Record<SlotName, SizeMapping>;
|
|
34
34
|
declare const createAdSize: (width: number, height: number) => AdSize;
|
|
@@ -139,9 +139,6 @@ declare const slotSizeMappings: {
|
|
|
139
139
|
readonly survey: {
|
|
140
140
|
readonly desktop: readonly [AdSize];
|
|
141
141
|
};
|
|
142
|
-
readonly carrot: {
|
|
143
|
-
readonly mobile: readonly [AdSize];
|
|
144
|
-
};
|
|
145
142
|
readonly 'mobile-sticky': {
|
|
146
143
|
readonly mobile: readonly [AdSize, AdSize, AdSize];
|
|
147
144
|
};
|
package/dist/cjs/ad-sizes.js
CHANGED
|
@@ -10,7 +10,6 @@ const editionToCountryCodeMap = {
|
|
|
10
10
|
const editionToCountryCode = (editionKey = 'UK') => editionToCountryCodeMap[editionKey];
|
|
11
11
|
const countryCookieName = 'GU_geo_country';
|
|
12
12
|
const countryOverrideName = 'gu.geo.override';
|
|
13
|
-
let locale;
|
|
14
13
|
/*
|
|
15
14
|
This method can be used as a non async way of getting the country code
|
|
16
15
|
after init has been called. Returning locale should cover all/most
|
|
@@ -23,8 +22,7 @@ const getCountryCode = () => {
|
|
|
23
22
|
const countryOverride = (0, libs_1.isString)(maybeCountryOverride)
|
|
24
23
|
? maybeCountryOverride
|
|
25
24
|
: null;
|
|
26
|
-
return (
|
|
27
|
-
countryOverride ??
|
|
25
|
+
return (countryOverride ??
|
|
28
26
|
(0, libs_1.getCookie)({
|
|
29
27
|
name: countryCookieName,
|
|
30
28
|
shouldMemoize: true,
|
package/dist/cjs/global.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
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';
|
|
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';
|
|
3
3
|
declare global {
|
|
4
4
|
interface Navigator {
|
|
5
5
|
readonly connection?: NetworkInformation;
|
|
@@ -31,6 +31,11 @@ declare global {
|
|
|
31
31
|
sentry?: {
|
|
32
32
|
reportError?: (error: Error, feature: string, tags?: Record<string, string>, extras?: Record<string, unknown>) => void;
|
|
33
33
|
};
|
|
34
|
+
abTests?: {
|
|
35
|
+
getParticipations: () => Record<string, string>;
|
|
36
|
+
isUserInTest: (testId: string) => boolean;
|
|
37
|
+
isUserInTestGroup: (testId: string, variantId: string) => boolean;
|
|
38
|
+
};
|
|
34
39
|
};
|
|
35
40
|
};
|
|
36
41
|
ootag: {
|
|
@@ -67,5 +72,6 @@ declare global {
|
|
|
67
72
|
cmd: string;
|
|
68
73
|
val: Record<string, unknown>;
|
|
69
74
|
}>;
|
|
75
|
+
admiral?: Admiral;
|
|
70
76
|
}
|
|
71
77
|
}
|
package/dist/cjs/index.js
CHANGED
|
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
36
|
exports.isEligibleForTeads = exports.getPermutivePFPSegments = exports.buildImaAdTagUrl = exports.buildPageTargeting = exports.initCommercialMetrics = exports.bypassCommercialMetricsSampling = exports.constants = exports.adSizes = exports.EventTimer = exports.isAdBlockInUse = void 0;
|
|
27
37
|
var detect_ad_blocker_1 = require("./detect-ad-blocker");
|
|
@@ -2,6 +2,7 @@ import type { Participations } from '@guardian/ab-core';
|
|
|
2
2
|
import type { ConsentState, CountryCode } from '@guardian/libs';
|
|
3
3
|
import type { AdManagerGroup, Frequency } from './personalised';
|
|
4
4
|
import type { SharedTargeting } from './shared';
|
|
5
|
+
import { getLocalHour } from './shared';
|
|
5
6
|
import type { TrueOrFalse } from './types';
|
|
6
7
|
type PartialWithNulls<T> = {
|
|
7
8
|
[P in keyof T]?: T[P] | null;
|
|
@@ -13,6 +14,7 @@ type PageTargeting = PartialWithNulls<{
|
|
|
13
14
|
at: string;
|
|
14
15
|
bp: 'mobile' | 'tablet' | 'desktop';
|
|
15
16
|
cc: CountryCode;
|
|
17
|
+
lh: string;
|
|
16
18
|
cmp_interaction: string;
|
|
17
19
|
consent_tcfv2: string;
|
|
18
20
|
dcre: TrueOrFalse;
|
|
@@ -43,5 +45,5 @@ type BuildPageTargetingParams = {
|
|
|
43
45
|
youtube?: boolean;
|
|
44
46
|
};
|
|
45
47
|
declare const buildPageTargeting: ({ adFree, clientSideParticipations, consentState, isSignedIn, youtube, }: BuildPageTargetingParams) => Record<string, string | string[]>;
|
|
46
|
-
export { buildPageTargeting, filterValues };
|
|
48
|
+
export { buildPageTargeting, filterValues, getLocalHour };
|
|
47
49
|
export type { PageTargeting };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.filterValues = exports.buildPageTargeting = void 0;
|
|
3
|
+
exports.getLocalHour = exports.filterValues = exports.buildPageTargeting = void 0;
|
|
4
4
|
const libs_1 = require("@guardian/libs");
|
|
5
5
|
const event_timer_1 = require("../event-timer");
|
|
6
6
|
const get_locale_1 = require("../geo/get-locale");
|
|
@@ -8,6 +8,7 @@ const content_1 = require("./content");
|
|
|
8
8
|
const personalised_1 = require("./personalised");
|
|
9
9
|
const session_1 = require("./session");
|
|
10
10
|
const shared_1 = require("./shared");
|
|
11
|
+
Object.defineProperty(exports, "getLocalHour", { enumerable: true, get: function () { return shared_1.getLocalHour; } });
|
|
11
12
|
const viewport_1 = require("./viewport");
|
|
12
13
|
const filterValues = (pageTargets) => {
|
|
13
14
|
const filtered = {};
|
|
@@ -70,11 +71,13 @@ const buildPageTargeting = ({ adFree, clientSideParticipations, consentState, is
|
|
|
70
71
|
const sessionTargeting = (0, session_1.getSessionTargeting)({
|
|
71
72
|
adTest: (0, libs_1.getCookie)({ name: 'adtest', shouldMemoize: true }),
|
|
72
73
|
countryCode: (0, get_locale_1.getLocale)(),
|
|
74
|
+
localHour: (0, shared_1.getLocalHour)(),
|
|
73
75
|
isSignedIn,
|
|
74
76
|
pageViewId: window.guardian.config.ophan.pageViewId,
|
|
75
77
|
participations: {
|
|
76
78
|
clientSideParticipations,
|
|
77
79
|
serverSideParticipations: window.guardian.config.tests ?? {},
|
|
80
|
+
betaAbTestParticipations: window.guardian.modules.abTests?.getParticipations() ?? {},
|
|
78
81
|
},
|
|
79
82
|
referrer,
|
|
80
83
|
});
|
|
@@ -53,6 +53,14 @@ type SessionTargeting = {
|
|
|
53
53
|
* [gam]: https://admanager.google.com/59666047#inventory/custom_targeting/detail/custom_key_id=11703293
|
|
54
54
|
*/
|
|
55
55
|
cc: CountryCode;
|
|
56
|
+
/**
|
|
57
|
+
* **L**ocal **H**our - [see on Ad Manager][gam]
|
|
58
|
+
*
|
|
59
|
+
* Type: _Dynamic_
|
|
60
|
+
*
|
|
61
|
+
* [gam]: https://admanager.google.com/59666047#inventory/custom_targeting/detail/custom_key_id=17299564
|
|
62
|
+
*/
|
|
63
|
+
lh: string;
|
|
56
64
|
/**
|
|
57
65
|
* Ophan **P**age **V**iew id – [see on Ad Manager][gam]
|
|
58
66
|
*
|
|
@@ -96,16 +104,22 @@ type AllParticipations = {
|
|
|
96
104
|
[key: `${string}Control`]: 'control';
|
|
97
105
|
[key: `${string}Variant`]: 'variant';
|
|
98
106
|
};
|
|
107
|
+
betaAbTestParticipations: Record<string, string>;
|
|
99
108
|
};
|
|
100
|
-
|
|
109
|
+
/**
|
|
110
|
+
* @todo drop old client/server side participations and rename to just `abTestsParticipations` once
|
|
111
|
+
* all tests have been migrated to the new AB testing platform
|
|
112
|
+
*/
|
|
113
|
+
declare const experimentsTargeting: ({ clientSideParticipations, serverSideParticipations, betaAbTestParticipations, }: AllParticipations) => SessionTargeting["ab"];
|
|
101
114
|
type Session = {
|
|
102
115
|
adTest: SessionTargeting['at'];
|
|
103
116
|
countryCode: CountryCode;
|
|
117
|
+
localHour: string;
|
|
104
118
|
isSignedIn: boolean;
|
|
105
119
|
pageViewId: SessionTargeting['pv'];
|
|
106
120
|
participations: AllParticipations;
|
|
107
121
|
referrer: string;
|
|
108
122
|
};
|
|
109
|
-
declare const getSessionTargeting: ({ adTest, countryCode, isSignedIn, pageViewId, participations, referrer, }: Session) => SessionTargeting;
|
|
123
|
+
declare const getSessionTargeting: ({ adTest, countryCode, localHour, isSignedIn, pageViewId, participations, referrer, }: Session) => SessionTargeting;
|
|
110
124
|
export type { SessionTargeting, AllParticipations };
|
|
111
125
|
export { getSessionTargeting, experimentsTargeting };
|
|
@@ -28,7 +28,11 @@ const getReferrer = (referrer) => {
|
|
|
28
28
|
const matchedRef = referrers.find((referrerType) => referrer.includes(referrerType.match)) ?? null;
|
|
29
29
|
return matchedRef ? matchedRef.id : null;
|
|
30
30
|
};
|
|
31
|
-
|
|
31
|
+
/**
|
|
32
|
+
* @todo drop old client/server side participations and rename to just `abTestsParticipations` once
|
|
33
|
+
* all tests have been migrated to the new AB testing platform
|
|
34
|
+
*/
|
|
35
|
+
const experimentsTargeting = ({ clientSideParticipations, serverSideParticipations, betaAbTestParticipations, }) => {
|
|
32
36
|
const testToParams = (testName, variant) => {
|
|
33
37
|
if (variant === 'notintest')
|
|
34
38
|
return null;
|
|
@@ -44,16 +48,26 @@ const experimentsTargeting = ({ clientSideParticipations, serverSideParticipatio
|
|
|
44
48
|
const serverSideExperiments = Object.entries(serverSideParticipations)
|
|
45
49
|
.map((test) => testToParams(...test))
|
|
46
50
|
.filter(libs_1.isString);
|
|
47
|
-
|
|
51
|
+
const betaAbTests = Object.entries(betaAbTestParticipations)
|
|
52
|
+
.map((test) => {
|
|
53
|
+
const [name, variant] = test;
|
|
54
|
+
return testToParams(name, variant);
|
|
55
|
+
})
|
|
56
|
+
.filter(libs_1.isString);
|
|
57
|
+
if (clientSideExperiment.length +
|
|
58
|
+
serverSideExperiments.length +
|
|
59
|
+
betaAbTests.length ===
|
|
60
|
+
0) {
|
|
48
61
|
return null;
|
|
49
62
|
}
|
|
50
|
-
return [...clientSideExperiment, ...serverSideExperiments];
|
|
63
|
+
return [...clientSideExperiment, ...serverSideExperiments, ...betaAbTests];
|
|
51
64
|
};
|
|
52
65
|
exports.experimentsTargeting = experimentsTargeting;
|
|
53
|
-
const getSessionTargeting = ({ adTest, countryCode, isSignedIn, pageViewId, participations, referrer, }) => ({
|
|
66
|
+
const getSessionTargeting = ({ adTest, countryCode, localHour, isSignedIn, pageViewId, participations, referrer, }) => ({
|
|
54
67
|
ab: experimentsTargeting(participations),
|
|
55
68
|
at: adTest,
|
|
56
69
|
cc: countryCode,
|
|
70
|
+
lh: localHour,
|
|
57
71
|
pv: pageViewId,
|
|
58
72
|
ref: getReferrer(referrer),
|
|
59
73
|
si: isSignedIn ? 't' : 'f',
|
|
@@ -145,6 +145,7 @@ type SharedTargeting = {
|
|
|
145
145
|
*/
|
|
146
146
|
url: `/${string}`;
|
|
147
147
|
};
|
|
148
|
+
declare const getLocalHour: () => string;
|
|
148
149
|
/**
|
|
149
150
|
* What goes in comes out
|
|
150
151
|
*/
|
|
@@ -153,4 +154,4 @@ export declare const _: {
|
|
|
153
154
|
getSurgingParam: (surging: number) => SharedTargeting["su"];
|
|
154
155
|
};
|
|
155
156
|
export type { SharedTargeting };
|
|
156
|
-
export { getSharedTargeting };
|
|
157
|
+
export { getSharedTargeting, getLocalHour };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getSharedTargeting = exports._ = void 0;
|
|
3
|
+
exports.getLocalHour = exports.getSharedTargeting = exports._ = void 0;
|
|
4
4
|
const pick_targeting_values_1 = require("./pick-targeting-values");
|
|
5
5
|
const surges = {
|
|
6
6
|
0: '0',
|
|
@@ -18,6 +18,10 @@ const getSurgingParam = (surging) => {
|
|
|
18
18
|
return thresholds.filter((n) => n <= surging).map((s) => surges[s]);
|
|
19
19
|
};
|
|
20
20
|
/* -- Targeting -- */
|
|
21
|
+
const getLocalHour = () => {
|
|
22
|
+
return new Date().getHours().toString();
|
|
23
|
+
};
|
|
24
|
+
exports.getLocalHour = getLocalHour;
|
|
21
25
|
/**
|
|
22
26
|
* What goes in comes out
|
|
23
27
|
*/
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { EventPayload } from '@guardian/ophan-tracker-js';
|
|
1
2
|
import type { AdSize, SizeMapping } from './ad-sizes';
|
|
2
3
|
import type { PageTargeting } from './targeting/build-page-targeting';
|
|
3
4
|
import 'googletag';
|
|
@@ -5,11 +6,11 @@ type HeaderBiddingSize = AdSize;
|
|
|
5
6
|
interface Advert {
|
|
6
7
|
id: string;
|
|
7
8
|
node: HTMLElement;
|
|
8
|
-
prebidAdUnit: string;
|
|
9
9
|
sizes: SizeMapping;
|
|
10
10
|
headerBiddingSizes: HeaderBiddingSize[] | null;
|
|
11
11
|
size: AdSize | 'fluid' | null;
|
|
12
12
|
slot: googletag.Slot;
|
|
13
|
+
gpid: string | undefined;
|
|
13
14
|
isEmpty: boolean | null;
|
|
14
15
|
isRendered: boolean;
|
|
15
16
|
shouldRefresh: boolean;
|
|
@@ -41,7 +42,7 @@ interface NetworkInformation extends EventTarget {
|
|
|
41
42
|
readonly downlink?: number;
|
|
42
43
|
readonly effectiveType?: string;
|
|
43
44
|
}
|
|
44
|
-
type OphanRecordFunction = (event:
|
|
45
|
+
type OphanRecordFunction = (event: EventPayload & {
|
|
45
46
|
/**
|
|
46
47
|
* the experiences key will override previously set values.
|
|
47
48
|
* Use `recordExperiences` instead.
|
|
@@ -424,4 +425,8 @@ type GoogleTrackConversionObject = {
|
|
|
424
425
|
google_custom_params: GoogleTagParams;
|
|
425
426
|
google_remarketing_only: boolean;
|
|
426
427
|
};
|
|
427
|
-
|
|
428
|
+
type AdmiralEvent = Record<string, unknown>;
|
|
429
|
+
type AdmiralCallback = (event: AdmiralEvent) => void;
|
|
430
|
+
type AdmiralArg = string | AdmiralCallback;
|
|
431
|
+
type Admiral = (...args: AdmiralArg[]) => void;
|
|
432
|
+
export type { Advert, DfpEnv, ConnectionType, NetworkInformation, OphanRecordFunction, Indices, Edition, AdsConfigDisabled, AdsConfigEnabled, AdsConfigBasic, AdsConfigUSNATorAus, AdsConfigTCFV2, AdsConfig, AdTargetingBuilder, Ophan, Config, AdBlockers, ArticleCounts, FetchBidResponse, HeaderNotification, OptOutInitializeOptions, OptOutAdSlot, Confiant, Permutive, Apstag, ComscoreGlobals, IasPET, TeadsAnalytics, SafeFrameAPI, NSdkInstance, Trac, GoogleTagParams, GoogleTrackConversionObject, Admiral, AdmiralEvent, };
|
package/dist/esm/ad-sizes.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ declare class AdSize extends Array<number> {
|
|
|
28
28
|
get height(): number;
|
|
29
29
|
}
|
|
30
30
|
type SizeKeys = '160x600' | '300x1050' | '300x250' | '300x600' | '728x90' | '970x250' | 'billboard' | 'cascade' | 'empty' | 'fabric' | 'fluid' | 'googleCard' | 'halfPage' | 'leaderboard' | 'merchandising' | 'merchandisingHigh' | 'merchandisingHighAdFeature' | 'mobilesticky' | 'mpu' | 'outOfPage' | 'outstreamDesktop' | 'outstreamGoogleDesktop' | 'outstreamMobile' | 'portrait' | 'portraitInterstitial' | 'pubmaticInterscroller' | 'skyscraper' | 'sponsorLogo';
|
|
31
|
-
type SlotName = 'article-end' | '
|
|
31
|
+
type SlotName = 'article-end' | 'comments-expanded' | 'comments' | 'crossword-banner-mobile' | 'exclusion' | 'external' | 'fronts-banner' | 'inline' | 'liveblog-top' | 'merchandising-high' | 'merchandising' | 'mobile-sticky' | 'football-right' | 'mostpop' | 'right' | 'sponsor-logo' | 'survey' | 'top-above-nav' | 'interactive';
|
|
32
32
|
type SizeMapping = Partial<Record<Breakpoint, readonly AdSize[]>>;
|
|
33
33
|
type SlotSizeMappings = Record<SlotName, SizeMapping>;
|
|
34
34
|
declare const createAdSize: (width: number, height: number) => AdSize;
|
|
@@ -139,9 +139,6 @@ declare const slotSizeMappings: {
|
|
|
139
139
|
readonly survey: {
|
|
140
140
|
readonly desktop: readonly [AdSize];
|
|
141
141
|
};
|
|
142
|
-
readonly carrot: {
|
|
143
|
-
readonly mobile: readonly [AdSize];
|
|
144
|
-
};
|
|
145
142
|
readonly 'mobile-sticky': {
|
|
146
143
|
readonly mobile: readonly [AdSize, AdSize, AdSize];
|
|
147
144
|
};
|
package/dist/esm/ad-sizes.js
CHANGED
|
@@ -7,7 +7,6 @@ const editionToCountryCodeMap = {
|
|
|
7
7
|
const editionToCountryCode = (editionKey = 'UK') => editionToCountryCodeMap[editionKey];
|
|
8
8
|
const countryCookieName = 'GU_geo_country';
|
|
9
9
|
const countryOverrideName = 'gu.geo.override';
|
|
10
|
-
let locale;
|
|
11
10
|
/*
|
|
12
11
|
This method can be used as a non async way of getting the country code
|
|
13
12
|
after init has been called. Returning locale should cover all/most
|
|
@@ -20,8 +19,7 @@ const getCountryCode = () => {
|
|
|
20
19
|
const countryOverride = isString(maybeCountryOverride)
|
|
21
20
|
? maybeCountryOverride
|
|
22
21
|
: null;
|
|
23
|
-
return (
|
|
24
|
-
countryOverride ??
|
|
22
|
+
return (countryOverride ??
|
|
25
23
|
getCookie({
|
|
26
24
|
name: countryCookieName,
|
|
27
25
|
shouldMemoize: true,
|
package/dist/esm/global.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
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';
|
|
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';
|
|
3
3
|
declare global {
|
|
4
4
|
interface Navigator {
|
|
5
5
|
readonly connection?: NetworkInformation;
|
|
@@ -31,6 +31,11 @@ declare global {
|
|
|
31
31
|
sentry?: {
|
|
32
32
|
reportError?: (error: Error, feature: string, tags?: Record<string, string>, extras?: Record<string, unknown>) => void;
|
|
33
33
|
};
|
|
34
|
+
abTests?: {
|
|
35
|
+
getParticipations: () => Record<string, string>;
|
|
36
|
+
isUserInTest: (testId: string) => boolean;
|
|
37
|
+
isUserInTestGroup: (testId: string, variantId: string) => boolean;
|
|
38
|
+
};
|
|
34
39
|
};
|
|
35
40
|
};
|
|
36
41
|
ootag: {
|
|
@@ -67,5 +72,6 @@ declare global {
|
|
|
67
72
|
cmd: string;
|
|
68
73
|
val: Record<string, unknown>;
|
|
69
74
|
}>;
|
|
75
|
+
admiral?: Admiral;
|
|
70
76
|
}
|
|
71
77
|
}
|
|
@@ -2,6 +2,7 @@ import type { Participations } from '@guardian/ab-core';
|
|
|
2
2
|
import type { ConsentState, CountryCode } from '@guardian/libs';
|
|
3
3
|
import type { AdManagerGroup, Frequency } from './personalised';
|
|
4
4
|
import type { SharedTargeting } from './shared';
|
|
5
|
+
import { getLocalHour } from './shared';
|
|
5
6
|
import type { TrueOrFalse } from './types';
|
|
6
7
|
type PartialWithNulls<T> = {
|
|
7
8
|
[P in keyof T]?: T[P] | null;
|
|
@@ -13,6 +14,7 @@ type PageTargeting = PartialWithNulls<{
|
|
|
13
14
|
at: string;
|
|
14
15
|
bp: 'mobile' | 'tablet' | 'desktop';
|
|
15
16
|
cc: CountryCode;
|
|
17
|
+
lh: string;
|
|
16
18
|
cmp_interaction: string;
|
|
17
19
|
consent_tcfv2: string;
|
|
18
20
|
dcre: TrueOrFalse;
|
|
@@ -43,5 +45,5 @@ type BuildPageTargetingParams = {
|
|
|
43
45
|
youtube?: boolean;
|
|
44
46
|
};
|
|
45
47
|
declare const buildPageTargeting: ({ adFree, clientSideParticipations, consentState, isSignedIn, youtube, }: BuildPageTargetingParams) => Record<string, string | string[]>;
|
|
46
|
-
export { buildPageTargeting, filterValues };
|
|
48
|
+
export { buildPageTargeting, filterValues, getLocalHour };
|
|
47
49
|
export type { PageTargeting };
|
|
@@ -4,7 +4,7 @@ import { getLocale } from '../geo/get-locale';
|
|
|
4
4
|
import { getContentTargeting } from './content';
|
|
5
5
|
import { getPersonalisedTargeting } from './personalised';
|
|
6
6
|
import { getSessionTargeting } from './session';
|
|
7
|
-
import { getSharedTargeting } from './shared';
|
|
7
|
+
import { getLocalHour, getSharedTargeting } from './shared';
|
|
8
8
|
import { getViewportTargeting } from './viewport';
|
|
9
9
|
const filterValues = (pageTargets) => {
|
|
10
10
|
const filtered = {};
|
|
@@ -66,11 +66,13 @@ const buildPageTargeting = ({ adFree, clientSideParticipations, consentState, is
|
|
|
66
66
|
const sessionTargeting = getSessionTargeting({
|
|
67
67
|
adTest: getCookie({ name: 'adtest', shouldMemoize: true }),
|
|
68
68
|
countryCode: getLocale(),
|
|
69
|
+
localHour: getLocalHour(),
|
|
69
70
|
isSignedIn,
|
|
70
71
|
pageViewId: window.guardian.config.ophan.pageViewId,
|
|
71
72
|
participations: {
|
|
72
73
|
clientSideParticipations,
|
|
73
74
|
serverSideParticipations: window.guardian.config.tests ?? {},
|
|
75
|
+
betaAbTestParticipations: window.guardian.modules.abTests?.getParticipations() ?? {},
|
|
74
76
|
},
|
|
75
77
|
referrer,
|
|
76
78
|
});
|
|
@@ -105,4 +107,4 @@ const buildPageTargeting = ({ adFree, clientSideParticipations, consentState, is
|
|
|
105
107
|
const pageTargeting = filterValues(pageTargets);
|
|
106
108
|
return pageTargeting;
|
|
107
109
|
};
|
|
108
|
-
export { buildPageTargeting, filterValues };
|
|
110
|
+
export { buildPageTargeting, filterValues, getLocalHour };
|
|
@@ -53,6 +53,14 @@ type SessionTargeting = {
|
|
|
53
53
|
* [gam]: https://admanager.google.com/59666047#inventory/custom_targeting/detail/custom_key_id=11703293
|
|
54
54
|
*/
|
|
55
55
|
cc: CountryCode;
|
|
56
|
+
/**
|
|
57
|
+
* **L**ocal **H**our - [see on Ad Manager][gam]
|
|
58
|
+
*
|
|
59
|
+
* Type: _Dynamic_
|
|
60
|
+
*
|
|
61
|
+
* [gam]: https://admanager.google.com/59666047#inventory/custom_targeting/detail/custom_key_id=17299564
|
|
62
|
+
*/
|
|
63
|
+
lh: string;
|
|
56
64
|
/**
|
|
57
65
|
* Ophan **P**age **V**iew id – [see on Ad Manager][gam]
|
|
58
66
|
*
|
|
@@ -96,16 +104,22 @@ type AllParticipations = {
|
|
|
96
104
|
[key: `${string}Control`]: 'control';
|
|
97
105
|
[key: `${string}Variant`]: 'variant';
|
|
98
106
|
};
|
|
107
|
+
betaAbTestParticipations: Record<string, string>;
|
|
99
108
|
};
|
|
100
|
-
|
|
109
|
+
/**
|
|
110
|
+
* @todo drop old client/server side participations and rename to just `abTestsParticipations` once
|
|
111
|
+
* all tests have been migrated to the new AB testing platform
|
|
112
|
+
*/
|
|
113
|
+
declare const experimentsTargeting: ({ clientSideParticipations, serverSideParticipations, betaAbTestParticipations, }: AllParticipations) => SessionTargeting["ab"];
|
|
101
114
|
type Session = {
|
|
102
115
|
adTest: SessionTargeting['at'];
|
|
103
116
|
countryCode: CountryCode;
|
|
117
|
+
localHour: string;
|
|
104
118
|
isSignedIn: boolean;
|
|
105
119
|
pageViewId: SessionTargeting['pv'];
|
|
106
120
|
participations: AllParticipations;
|
|
107
121
|
referrer: string;
|
|
108
122
|
};
|
|
109
|
-
declare const getSessionTargeting: ({ adTest, countryCode, isSignedIn, pageViewId, participations, referrer, }: Session) => SessionTargeting;
|
|
123
|
+
declare const getSessionTargeting: ({ adTest, countryCode, localHour, isSignedIn, pageViewId, participations, referrer, }: Session) => SessionTargeting;
|
|
110
124
|
export type { SessionTargeting, AllParticipations };
|
|
111
125
|
export { getSessionTargeting, experimentsTargeting };
|
|
@@ -25,7 +25,11 @@ const getReferrer = (referrer) => {
|
|
|
25
25
|
const matchedRef = referrers.find((referrerType) => referrer.includes(referrerType.match)) ?? null;
|
|
26
26
|
return matchedRef ? matchedRef.id : null;
|
|
27
27
|
};
|
|
28
|
-
|
|
28
|
+
/**
|
|
29
|
+
* @todo drop old client/server side participations and rename to just `abTestsParticipations` once
|
|
30
|
+
* all tests have been migrated to the new AB testing platform
|
|
31
|
+
*/
|
|
32
|
+
const experimentsTargeting = ({ clientSideParticipations, serverSideParticipations, betaAbTestParticipations, }) => {
|
|
29
33
|
const testToParams = (testName, variant) => {
|
|
30
34
|
if (variant === 'notintest')
|
|
31
35
|
return null;
|
|
@@ -41,15 +45,25 @@ const experimentsTargeting = ({ clientSideParticipations, serverSideParticipatio
|
|
|
41
45
|
const serverSideExperiments = Object.entries(serverSideParticipations)
|
|
42
46
|
.map((test) => testToParams(...test))
|
|
43
47
|
.filter(isString);
|
|
44
|
-
|
|
48
|
+
const betaAbTests = Object.entries(betaAbTestParticipations)
|
|
49
|
+
.map((test) => {
|
|
50
|
+
const [name, variant] = test;
|
|
51
|
+
return testToParams(name, variant);
|
|
52
|
+
})
|
|
53
|
+
.filter(isString);
|
|
54
|
+
if (clientSideExperiment.length +
|
|
55
|
+
serverSideExperiments.length +
|
|
56
|
+
betaAbTests.length ===
|
|
57
|
+
0) {
|
|
45
58
|
return null;
|
|
46
59
|
}
|
|
47
|
-
return [...clientSideExperiment, ...serverSideExperiments];
|
|
60
|
+
return [...clientSideExperiment, ...serverSideExperiments, ...betaAbTests];
|
|
48
61
|
};
|
|
49
|
-
const getSessionTargeting = ({ adTest, countryCode, isSignedIn, pageViewId, participations, referrer, }) => ({
|
|
62
|
+
const getSessionTargeting = ({ adTest, countryCode, localHour, isSignedIn, pageViewId, participations, referrer, }) => ({
|
|
50
63
|
ab: experimentsTargeting(participations),
|
|
51
64
|
at: adTest,
|
|
52
65
|
cc: countryCode,
|
|
66
|
+
lh: localHour,
|
|
53
67
|
pv: pageViewId,
|
|
54
68
|
ref: getReferrer(referrer),
|
|
55
69
|
si: isSignedIn ? 't' : 'f',
|
|
@@ -145,6 +145,7 @@ type SharedTargeting = {
|
|
|
145
145
|
*/
|
|
146
146
|
url: `/${string}`;
|
|
147
147
|
};
|
|
148
|
+
declare const getLocalHour: () => string;
|
|
148
149
|
/**
|
|
149
150
|
* What goes in comes out
|
|
150
151
|
*/
|
|
@@ -153,4 +154,4 @@ export declare const _: {
|
|
|
153
154
|
getSurgingParam: (surging: number) => SharedTargeting["su"];
|
|
154
155
|
};
|
|
155
156
|
export type { SharedTargeting };
|
|
156
|
-
export { getSharedTargeting };
|
|
157
|
+
export { getSharedTargeting, getLocalHour };
|
|
@@ -15,6 +15,9 @@ const getSurgingParam = (surging) => {
|
|
|
15
15
|
return thresholds.filter((n) => n <= surging).map((s) => surges[s]);
|
|
16
16
|
};
|
|
17
17
|
/* -- Targeting -- */
|
|
18
|
+
const getLocalHour = () => {
|
|
19
|
+
return new Date().getHours().toString();
|
|
20
|
+
};
|
|
18
21
|
/**
|
|
19
22
|
* What goes in comes out
|
|
20
23
|
*/
|
|
@@ -22,4 +25,4 @@ const getSharedTargeting = (shared) => pickTargetingValues(shared);
|
|
|
22
25
|
export const _ = {
|
|
23
26
|
getSurgingParam,
|
|
24
27
|
};
|
|
25
|
-
export { getSharedTargeting };
|
|
28
|
+
export { getSharedTargeting, getLocalHour };
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { EventPayload } from '@guardian/ophan-tracker-js';
|
|
1
2
|
import type { AdSize, SizeMapping } from './ad-sizes';
|
|
2
3
|
import type { PageTargeting } from './targeting/build-page-targeting';
|
|
3
4
|
import 'googletag';
|
|
@@ -5,11 +6,11 @@ type HeaderBiddingSize = AdSize;
|
|
|
5
6
|
interface Advert {
|
|
6
7
|
id: string;
|
|
7
8
|
node: HTMLElement;
|
|
8
|
-
prebidAdUnit: string;
|
|
9
9
|
sizes: SizeMapping;
|
|
10
10
|
headerBiddingSizes: HeaderBiddingSize[] | null;
|
|
11
11
|
size: AdSize | 'fluid' | null;
|
|
12
12
|
slot: googletag.Slot;
|
|
13
|
+
gpid: string | undefined;
|
|
13
14
|
isEmpty: boolean | null;
|
|
14
15
|
isRendered: boolean;
|
|
15
16
|
shouldRefresh: boolean;
|
|
@@ -41,7 +42,7 @@ interface NetworkInformation extends EventTarget {
|
|
|
41
42
|
readonly downlink?: number;
|
|
42
43
|
readonly effectiveType?: string;
|
|
43
44
|
}
|
|
44
|
-
type OphanRecordFunction = (event:
|
|
45
|
+
type OphanRecordFunction = (event: EventPayload & {
|
|
45
46
|
/**
|
|
46
47
|
* the experiences key will override previously set values.
|
|
47
48
|
* Use `recordExperiences` instead.
|
|
@@ -424,4 +425,8 @@ type GoogleTrackConversionObject = {
|
|
|
424
425
|
google_custom_params: GoogleTagParams;
|
|
425
426
|
google_remarketing_only: boolean;
|
|
426
427
|
};
|
|
427
|
-
|
|
428
|
+
type AdmiralEvent = Record<string, unknown>;
|
|
429
|
+
type AdmiralCallback = (event: AdmiralEvent) => void;
|
|
430
|
+
type AdmiralArg = string | AdmiralCallback;
|
|
431
|
+
type Admiral = (...args: AdmiralArg[]) => void;
|
|
432
|
+
export type { Advert, DfpEnv, ConnectionType, NetworkInformation, OphanRecordFunction, Indices, Edition, AdsConfigDisabled, AdsConfigEnabled, AdsConfigBasic, AdsConfigUSNATorAus, AdsConfigTCFV2, AdsConfig, AdTargetingBuilder, Ophan, Config, AdBlockers, ArticleCounts, FetchBidResponse, HeaderNotification, OptOutInitializeOptions, OptOutAdSlot, Confiant, Permutive, Apstag, ComscoreGlobals, IasPET, TeadsAnalytics, SafeFrameAPI, NSdkInstance, Trac, GoogleTagParams, GoogleTrackConversionObject, Admiral, AdmiralEvent, };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@guardian/commercial-core",
|
|
3
|
-
"version": "0.0.0-beta-
|
|
3
|
+
"version": "0.0.0-beta-20251023093018",
|
|
4
4
|
"description": "Guardian advertising business logic",
|
|
5
5
|
"homepage": "https://github.com/guardian/commercial#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -30,23 +30,24 @@
|
|
|
30
30
|
"./package.json": "./package.json"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"@guardian/ab-core": "8.0.1",
|
|
34
|
-
"@guardian/libs": "
|
|
33
|
+
"@guardian/ab-core": "^8.0.1",
|
|
34
|
+
"@guardian/libs": "^26.0.0"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@guardian/ab-core": "8.0.1",
|
|
38
|
-
"@guardian/libs": "
|
|
38
|
+
"@guardian/libs": "26.0.0",
|
|
39
39
|
"@types/googletag": "~3.3.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@
|
|
43
|
-
"typescript": "5.5.4",
|
|
42
|
+
"@guardian/ophan-tracker-js": "2.6.1",
|
|
44
43
|
"@types/jest": "30.0.0",
|
|
45
|
-
"
|
|
46
|
-
"jest
|
|
44
|
+
"@types/node": "24.7.2",
|
|
45
|
+
"jest": "^30.2.0",
|
|
46
|
+
"jest-environment-jsdom": "^30.2.0",
|
|
47
47
|
"jest-environment-jsdom-global": "~4.0.0",
|
|
48
|
-
"ts-jest": "^29.
|
|
49
|
-
"
|
|
48
|
+
"ts-jest": "^29.4.4",
|
|
49
|
+
"typescript": "5.9.3",
|
|
50
|
+
"type-fest": "^4.41.0"
|
|
50
51
|
},
|
|
51
52
|
"publishConfig": {
|
|
52
53
|
"access": "public"
|