@phantomstudios/ft-lib 0.5.0-rc9 → 0.5.1

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.
@@ -14,7 +14,7 @@ jobs:
14
14
 
15
15
  strategy:
16
16
  matrix:
17
- node-version: [18.x, 20.x, 22.x]
17
+ node-version: [20.x, 22.x, 24.x]
18
18
 
19
19
  steps:
20
20
  - uses: actions/checkout@v1
@@ -13,7 +13,7 @@ jobs:
13
13
 
14
14
  strategy:
15
15
  matrix:
16
- node-version: [18.x, 20.x, 22.x]
16
+ node-version: [20.x, 22.x, 24.x]
17
17
 
18
18
  steps:
19
19
  - uses: actions/checkout@v1
@@ -43,7 +43,7 @@ jobs:
43
43
  - uses: actions/checkout@v2
44
44
  - uses: actions/setup-node@v1
45
45
  with:
46
- node-version: 22
46
+ node-version: 24
47
47
  registry-url: https://registry.npmjs.org/
48
48
  - run: npm ci
49
49
  - run: npm publish --access=public
package/.nvmrc CHANGED
@@ -1 +1 @@
1
- v18.18.0
1
+ v24
@@ -0,0 +1,19 @@
1
+ export declare class consentMonitor {
2
+ protected _consent: boolean;
3
+ protected _devHosts: string[];
4
+ protected _isDevEnvironment: boolean;
5
+ protected _hostname: string;
6
+ protected _isInitialized: boolean;
7
+ constructor(hostname?: string, devHosts?: string[] | string);
8
+ get consent(): boolean;
9
+ get devHosts(): string[] | string;
10
+ get isDevEnvironment(): boolean;
11
+ get isInitialized(): boolean;
12
+ getCookieValue: (name: string) => string;
13
+ init: () => void;
14
+ cookieConsentTest: () => void;
15
+ setDevCookieHandler: () => void;
16
+ permutiveConsentOn: () => void;
17
+ permutiveConsentOff: () => void;
18
+ }
19
+ //# sourceMappingURL=index-old.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-old.d.ts","sourceRoot":"","sources":["../../src/consentMonitor/index-old.ts"],"names":[],"mappings":"AAKA,qBAAa,cAAc;IACzB,SAAS,CAAC,QAAQ,UAAS;IAC3B,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC;IAC9B,SAAS,CAAC,iBAAiB,UAAS;IACpC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,cAAc,UAAS;gBAErB,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM;IAc3D,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,QAAQ,IAAI,MAAM,EAAE,GAAG,MAAM,CAEhC;IAED,IAAI,gBAAgB,IAAI,OAAO,CAE9B;IAED,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED,cAAc,GAAI,MAAM,MAAM,YACgD;IAE9E,IAAI,aASF;IAEF,iBAAiB,aA6Bf;IAEF,mBAAmB,aAkBjB;IAEF,kBAAkB,aAMhB;IAEF,mBAAmB,aAGjB;CACH"}
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.consentMonitor = void 0;
7
+ var debug_1 = __importDefault(require("debug"));
8
+ var debug = (0, debug_1.default)("@phantomstudios/ft-lib");
9
+ var DEFAULT_DEV_HOSTS = ["localhost", "phq", ".app", "preview"];
10
+ var consentMonitor = /** @class */ (function () {
11
+ function consentMonitor(hostname, devHosts) {
12
+ var _this = this;
13
+ this._consent = false;
14
+ this._isDevEnvironment = false;
15
+ this._isInitialized = false;
16
+ this.getCookieValue = function (name) { var _a; return ((_a = document.cookie.match("(^|;)\\s*" + name + "\\s*=\\s*([^;]+)")) === null || _a === void 0 ? void 0 : _a.pop()) || ""; };
17
+ this.init = function () {
18
+ _this.cookieConsentTest();
19
+ setInterval(_this.cookieConsentTest, 3000);
20
+ //Simulate cookie consent behaviour in non-prod environments
21
+ _this._devHosts.map(function (devHost) {
22
+ return _this._hostname.includes(devHost) && _this.setDevCookieHandler();
23
+ });
24
+ };
25
+ this.cookieConsentTest = function () {
26
+ if (window.permutive) {
27
+ if (!_this._isInitialized) {
28
+ if (_this.getCookieValue("FTConsent").includes("behaviouraladsOnsite%3Aon")) {
29
+ _this.permutiveConsentOn();
30
+ }
31
+ else {
32
+ _this.permutiveConsentOff();
33
+ }
34
+ _this._isInitialized = true;
35
+ }
36
+ else if (_this.getCookieValue("FTConsent").includes("behaviouraladsOnsite%3Aon") &&
37
+ !_this.consent) {
38
+ debug("setting permutive tracking consent: on");
39
+ _this.permutiveConsentOn();
40
+ }
41
+ else if (!_this.getCookieValue("FTConsent").includes("behaviouraladsOnsite%3Aon") &&
42
+ _this.consent) {
43
+ debug("setting permutive tracking consent: off");
44
+ _this.permutiveConsentOff();
45
+ }
46
+ }
47
+ };
48
+ this.setDevCookieHandler = function () {
49
+ _this._isDevEnvironment = true;
50
+ debug("setting development environment from host match");
51
+ var oCookieMessage = document.getElementsByClassName("o-cookie-message")[0];
52
+ if (oCookieMessage) {
53
+ var onCookieMessageAct_1 = function () {
54
+ debug("setting development FT consent cookies");
55
+ document.cookie = "FTConsent=behaviouraladsOnsite%3Aon";
56
+ document.cookie = "FTCookieConsentGDPR=true";
57
+ oCookieMessage.removeEventListener("oCookieMessage.act", onCookieMessageAct_1, false);
58
+ };
59
+ oCookieMessage.addEventListener("oCookieMessage.act", onCookieMessageAct_1);
60
+ }
61
+ };
62
+ this.permutiveConsentOn = function () {
63
+ window.permutive.consent({
64
+ opt_in: true,
65
+ token: "behaviouraladsOnsite:on",
66
+ });
67
+ _this._consent = true;
68
+ };
69
+ this.permutiveConsentOff = function () {
70
+ window.permutive.consent({ opt_in: false });
71
+ _this._consent = false;
72
+ };
73
+ if (Array.isArray(devHosts)) {
74
+ this._devHosts = devHosts.concat(DEFAULT_DEV_HOSTS);
75
+ }
76
+ else if (devHosts === undefined) {
77
+ this._devHosts = DEFAULT_DEV_HOSTS;
78
+ }
79
+ else {
80
+ this._devHosts = DEFAULT_DEV_HOSTS;
81
+ this._devHosts.push(devHosts);
82
+ }
83
+ this._hostname = hostname || window.location.hostname;
84
+ this.init();
85
+ }
86
+ Object.defineProperty(consentMonitor.prototype, "consent", {
87
+ get: function () {
88
+ return this._consent;
89
+ },
90
+ enumerable: false,
91
+ configurable: true
92
+ });
93
+ Object.defineProperty(consentMonitor.prototype, "devHosts", {
94
+ get: function () {
95
+ return this._devHosts;
96
+ },
97
+ enumerable: false,
98
+ configurable: true
99
+ });
100
+ Object.defineProperty(consentMonitor.prototype, "isDevEnvironment", {
101
+ get: function () {
102
+ return this._isDevEnvironment;
103
+ },
104
+ enumerable: false,
105
+ configurable: true
106
+ });
107
+ Object.defineProperty(consentMonitor.prototype, "isInitialized", {
108
+ get: function () {
109
+ return this._isInitialized;
110
+ },
111
+ enumerable: false,
112
+ configurable: true
113
+ });
114
+ return consentMonitor;
115
+ }());
116
+ exports.consentMonitor = consentMonitor;
117
+ //# sourceMappingURL=index-old.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-old.js","sourceRoot":"","sources":["../../src/consentMonitor/index-old.ts"],"names":[],"mappings":"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"}
@@ -3,15 +3,19 @@ export declare class ConsentMonitor {
3
3
  private _devHosts;
4
4
  private _isDevEnvironment;
5
5
  private _isInitialized;
6
+ private _hostname;
6
7
  get consent(): boolean;
7
8
  get devHosts(): string[];
8
9
  get isDevEnvironment(): boolean;
9
10
  get isInitialized(): boolean;
10
11
  get userHasConsented(): boolean;
12
+ getCookieValue: (name: string) => string;
11
13
  constructor(hostname?: string, devHosts?: string[] | string);
12
14
  private attachCmpListeners;
13
15
  private enablePermutive;
14
16
  private disablePermutive;
17
+ cookieConsentTest: () => void;
18
+ setDevConsentCookies: () => void;
15
19
  }
16
20
  export { ConsentMonitor as consentMonitor };
17
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/consentMonitor/index.ts"],"names":[],"mappings":"AA+BA,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,cAAc,CAAS;IAE/B,IAAW,OAAO,IAAI,OAAO,CAE5B;IACD,IAAW,QAAQ,IAAI,MAAM,EAAE,CAE9B;IACD,IAAW,gBAAgB,IAAI,OAAO,CAErC;IACD,IAAW,aAAa,IAAI,OAAO,CAElC;IAED,IAAW,gBAAgB,IAAI,OAAO,CAErC;gBAEW,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM;IAgC3D,OAAO,CAAC,kBAAkB;IAsB1B,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,gBAAgB;CAMzB;AAED,OAAO,EAAE,cAAc,IAAI,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/consentMonitor/index.ts"],"names":[],"mappings":"AA+BA,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,SAAS,CAAS;IAE1B,IAAW,OAAO,IAAI,OAAO,CAE5B;IACD,IAAW,QAAQ,IAAI,MAAM,EAAE,CAE9B;IACD,IAAW,gBAAgB,IAAI,OAAO,CAErC;IACD,IAAW,aAAa,IAAI,OAAO,CAElC;IAED,IAAW,gBAAgB,IAAI,OAAO,CAErC;IAED,cAAc,GAAI,MAAM,MAAM,YACgD;gBAElE,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM;IAiC3D,OAAO,CAAC,kBAAkB;IAiC1B,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,gBAAgB;IAQxB,iBAAiB,aAcf;IAEF,oBAAoB,aAMlB;CACH;AAED,OAAO,EAAE,cAAc,IAAI,cAAc,EAAE,CAAC"}
@@ -26,6 +26,32 @@ var ConsentMonitor = /** @class */ (function () {
26
26
  this._consent = false;
27
27
  this._isDevEnvironment = false;
28
28
  this._isInitialized = false;
29
+ this.getCookieValue = function (name) { var _a; return ((_a = document.cookie.match("(^|;)\\s*" + name + "\\s*=\\s*([^;]+)")) === null || _a === void 0 ? void 0 : _a.pop()) || ""; };
30
+ //check for FTConsent - cookiesOnSite to trigger custom consent_update event for GTM tags (banner updated)
31
+ this.cookieConsentTest = function () {
32
+ if (!_this._isInitialized || !window || !window.dataLayer)
33
+ return;
34
+ if (_this.getCookieValue("FTConsent").includes("cookiesOnsite%3Aon")) {
35
+ //send consent_update event
36
+ window.dataLayer.push({
37
+ event: "consent_update",
38
+ consent: true,
39
+ });
40
+ }
41
+ else {
42
+ window.dataLayer.push({
43
+ event: "consent_update",
44
+ consent: false,
45
+ });
46
+ }
47
+ };
48
+ this.setDevConsentCookies = function () {
49
+ _this._isDevEnvironment = true;
50
+ debug("setting development FT consent cookies");
51
+ document.cookie =
52
+ "FTConsent=behaviouraladsOnsite%3Aon%2CcookiesOnsite%3Aon%2CpermutiveadsOnsite%3Aon";
53
+ document.cookie = "FTCookieConsentGDPR=true";
54
+ };
29
55
  if (Array.isArray(devHosts)) {
30
56
  this._devHosts = __spreadArray(__spreadArray([], devHosts, true), DEFAULT_DEV_HOSTS, true);
31
57
  }
@@ -35,14 +61,14 @@ var ConsentMonitor = /** @class */ (function () {
35
61
  else {
36
62
  this._devHosts = __spreadArray(__spreadArray([], DEFAULT_DEV_HOSTS, true), [devHosts], false);
37
63
  }
38
- var hostToCheck = hostname !== null && hostname !== void 0 ? hostname : window.location.hostname;
64
+ this._hostname = hostname || window.location.hostname;
39
65
  this._isDevEnvironment = this._devHosts.some(function (h) {
40
- return hostToCheck.includes(h);
66
+ return _this._hostname.includes(h);
41
67
  });
42
68
  (0, loadFtCmp_1.loadFtCmpScript)()
43
69
  .then(function () {
44
70
  _this.attachCmpListeners();
45
- var propertyConfig = window.location.hostname.endsWith("ft.com")
71
+ var propertyConfig = window.location.hostname.endsWith(".ft.com")
46
72
  ? cmp_client_1.properties["FT_DOTCOM_PROD"]
47
73
  : cmp_client_1.properties["FT_DOTCOM_TEST"];
48
74
  // initialize CMP
@@ -108,6 +134,14 @@ var ConsentMonitor = /** @class */ (function () {
108
134
  _this.enablePermutive();
109
135
  else if (typeId === CMP_CHOICE_REJECT_ALL)
110
136
  _this.disablePermutive();
137
+ //Simulate cookie consent behaviour in non-prod environments as banner does not set cookies in non .ft.com domains
138
+ _this._devHosts.map(function (devHost) {
139
+ return _this._hostname.includes(devHost) &&
140
+ typeId === CMP_CHOICE_ACCEPT_ALL &&
141
+ _this.setDevConsentCookies();
142
+ });
143
+ // banner updated - check new cookie value to fire consent_update event
144
+ setTimeout(_this.cookieConsentTest, 3000);
111
145
  };
112
146
  (_b = (_a = window._sp_).addEventListener) === null || _b === void 0 ? void 0 : _b.call(_a, "onConsentReady", onReady);
113
147
  (_e = (_d = window._sp_).addEventListener) === null || _e === void 0 ? void 0 : _e.call(_d, "onMessageChoiceSelect", onChoice);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/consentMonitor/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/consentMonitor/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@phantomstudios/ft-lib",
3
3
  "description": "A collection of Javascript UI & tracking utils for FT sites",
4
- "version": "0.5.0-rc9",
4
+ "version": "0.5.1",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
7
7
  "homepage": "https://github.com/phantomstudios/ft-lib#readme",
@@ -41,19 +41,19 @@
41
41
  "@eslint/compat": "^1.2.9",
42
42
  "@eslint/eslintrc": "^3.3.1",
43
43
  "@eslint/js": "^9.25.1",
44
- "@financial-times/cmp-client": "^6.1.2",
44
+ "@financial-times/cmp-client": "^6.2.0",
45
45
  "@financial-times/o-footer": "^9.2.10",
46
46
  "@financial-times/o-header": "^11.2.0",
47
47
  "@financial-times/o-tracking": "^4.9.0",
48
48
  "@financial-times/o-viewport": "^5.1.2",
49
49
  "@types/debug": "^4.1.7",
50
- "@types/jest": "^29.5.14",
50
+ "@types/jest": "^30.0.0",
51
51
  "@types/youtube": "^0.1.0",
52
52
  "@types/yup": "^0.32.0",
53
53
  "@typescript-eslint/eslint-plugin": "^8.31.1",
54
54
  "@typescript-eslint/parser": "^8.31.1",
55
55
  "babel-eslint": "^10.1.0",
56
- "babel-jest": "^29.7.0",
56
+ "babel-jest": "^30.2.0",
57
57
  "debug": "^4.3.2",
58
58
  "eslint": "^9.25.1",
59
59
  "eslint-config-prettier": "^10.1.2",
@@ -62,8 +62,8 @@
62
62
  "eslint-plugin-react": "^7.23.2",
63
63
  "eslint-plugin-react-hooks": "^5.2.0",
64
64
  "globals": "^16.0.0",
65
- "jest": "^29.7.0",
66
- "jest-environment-jsdom": "^29.7.0",
65
+ "jest": "^30.2.0",
66
+ "jest-environment-jsdom": "^30.2.0",
67
67
  "npm-run-all": "^4.1.5",
68
68
  "prettier": "^3.5.3",
69
69
  "set-value": ">=4.0.1",
@@ -34,6 +34,7 @@ export class ConsentMonitor {
34
34
  private _devHosts: string[];
35
35
  private _isDevEnvironment = false;
36
36
  private _isInitialized = false;
37
+ private _hostname: string;
37
38
 
38
39
  public get consent(): boolean {
39
40
  return this._consent;
@@ -52,6 +53,9 @@ export class ConsentMonitor {
52
53
  return this._consent;
53
54
  }
54
55
 
56
+ getCookieValue = (name: string) =>
57
+ document.cookie.match("(^|;)\\s*" + name + "\\s*=\\s*([^;]+)")?.pop() || "";
58
+
55
59
  constructor(hostname?: string, devHosts?: string[] | string) {
56
60
  if (Array.isArray(devHosts)) {
57
61
  this._devHosts = [...devHosts, ...DEFAULT_DEV_HOSTS];
@@ -61,16 +65,17 @@ export class ConsentMonitor {
61
65
  this._devHosts = [...DEFAULT_DEV_HOSTS, devHosts];
62
66
  }
63
67
 
64
- const hostToCheck = hostname ?? window.location.hostname;
68
+ this._hostname = hostname || window.location.hostname;
69
+
65
70
  this._isDevEnvironment = this._devHosts.some((h) =>
66
- hostToCheck.includes(h),
71
+ this._hostname.includes(h),
67
72
  );
68
73
 
69
74
  loadFtCmpScript()
70
75
  .then(() => {
71
76
  this.attachCmpListeners();
72
77
 
73
- const propertyConfig = window.location.hostname.endsWith("ft.com")
78
+ const propertyConfig = window.location.hostname.endsWith(".ft.com")
74
79
  ? properties["FT_DOTCOM_PROD"]
75
80
  : properties["FT_DOTCOM_TEST"];
76
81
 
@@ -99,6 +104,17 @@ export class ConsentMonitor {
99
104
  debug("onMessageChoiceSelect:", typeId);
100
105
  if (typeId === CMP_CHOICE_ACCEPT_ALL) this.enablePermutive();
101
106
  else if (typeId === CMP_CHOICE_REJECT_ALL) this.disablePermutive();
107
+
108
+ //Simulate cookie consent behaviour in non-prod environments as banner does not set cookies in non .ft.com domains
109
+ this._devHosts.map(
110
+ (devHost) =>
111
+ this._hostname.includes(devHost) &&
112
+ typeId === CMP_CHOICE_ACCEPT_ALL &&
113
+ this.setDevConsentCookies(),
114
+ );
115
+
116
+ // banner updated - check new cookie value to fire consent_update event
117
+ setTimeout(this.cookieConsentTest, 3000);
102
118
  };
103
119
 
104
120
  window._sp_.addEventListener?.("onConsentReady", onReady);
@@ -122,6 +138,31 @@ export class ConsentMonitor {
122
138
  window.permutive?.consent({ opt_in: false });
123
139
  this._consent = false;
124
140
  }
141
+
142
+ //check for FTConsent - cookiesOnSite to trigger custom consent_update event for GTM tags (banner updated)
143
+ cookieConsentTest = () => {
144
+ if (!this._isInitialized || !window || !window.dataLayer) return;
145
+ if (this.getCookieValue("FTConsent").includes("cookiesOnsite%3Aon")) {
146
+ //send consent_update event
147
+ window.dataLayer.push({
148
+ event: "consent_update",
149
+ consent: true,
150
+ });
151
+ } else {
152
+ window.dataLayer.push({
153
+ event: "consent_update",
154
+ consent: false,
155
+ });
156
+ }
157
+ };
158
+
159
+ setDevConsentCookies = () => {
160
+ this._isDevEnvironment = true;
161
+ debug("setting development FT consent cookies");
162
+ document.cookie =
163
+ "FTConsent=behaviouraladsOnsite%3Aon%2CcookiesOnsite%3Aon%2CpermutiveadsOnsite%3Aon";
164
+ document.cookie = "FTCookieConsentGDPR=true";
165
+ };
125
166
  }
126
167
 
127
168
  export { ConsentMonitor as consentMonitor };
@@ -6,18 +6,8 @@ import * as cmpLoader from "../src/cmp/loadFtCmp";
6
6
  import { ConsentMonitor, consentMonitor } from "../src/consentMonitor";
7
7
  import { permutiveVideoUtils } from "../src/permutiveVideoUtils";
8
8
 
9
- let windowSpy: jest.SpyInstance;
10
-
11
9
  jest.spyOn(cmpLoader, "loadFtCmpScript").mockResolvedValue(undefined);
12
10
 
13
- beforeEach(() => {
14
- windowSpy = jest.spyOn(window, "window", "get");
15
- });
16
-
17
- afterEach(() => {
18
- windowSpy.mockRestore();
19
- });
20
-
21
11
  describe("consentMonitor", () => {
22
12
  it("can be initiated", () => {
23
13
  const obj = new consentMonitor();
@@ -54,7 +44,7 @@ describe("consentMonitor", () => {
54
44
  const permutiveVideoTracker = new permutiveVideoUtils(
55
45
  "FT-Campaign",
56
46
  "video title",
57
- "videoID"
47
+ "videoID",
58
48
  );
59
49
  expect(permutiveVideoTracker.remainingProgress).toEqual([
60
50
  0, 0.25, 0.5, 0.75, 1,