@financial-times/cmp-client 3.4.0-beta.2 → 3.5.0-beta.2
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/README.md +28 -6
- package/dist/index.cjs +8 -3
- package/dist/index.js +8 -3
- package/dist/scripts/cmp-static.js +1 -1
- package/dist/src/__tests__/index.test.d.ts +2 -0
- package/dist/src/__tests__/index.test.d.ts.map +1 -0
- package/dist/src/client.d.ts +1 -1
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/consent-ready/index.d.ts.map +1 -1
- package/dist/src/consent-ready/utils/__fixtures__/helpers.d.ts +1 -0
- package/dist/src/consent-ready/utils/__fixtures__/helpers.d.ts.map +1 -1
- package/package.json +1 -1
- package/typings/types.d.ts +1 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# CMP Client
|
|
2
2
|
|
|
3
|
-
A client-side
|
|
3
|
+
A client-side library to help you add a CMP (currently provided by Sourcepoint) to your application.
|
|
4
4
|
|
|
5
5
|
<details>
|
|
6
6
|
<summary>How it works</summary>
|
|
@@ -13,13 +13,31 @@ A client-side package to help you add a CMP (currently provided by Sourcepoint)
|
|
|
13
13
|
|
|
14
14
|
## Installation
|
|
15
15
|
|
|
16
|
-
Install
|
|
16
|
+
Install as a \<script> tag (**recommended**):
|
|
17
|
+
|
|
18
|
+
```copy
|
|
19
|
+
<script async src="https://consent-notice.ft.com/cmp.js"></script>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Install the library from NPM:
|
|
17
23
|
|
|
18
24
|
```copy
|
|
19
25
|
npm install @financial-times/cmp-client
|
|
20
26
|
```
|
|
21
27
|
|
|
22
|
-
##
|
|
28
|
+
## Using the script tag
|
|
29
|
+
|
|
30
|
+
The `src` attribute of the `script` tag points to an immediately invoked function expression (IIFE) that sets up the CMP client on the host page. When the CMP client is installed this way, no additional work needs to be done.
|
|
31
|
+
|
|
32
|
+
The primary benefit of using this integration method is that your users will automatically get new updates to the CMP client as soon as they are available, as opposed to requiring a version bump and application release. However, for this method to work successfully, the host page must be one of our [registered properties](#available-properties-constantly-being-updated). Please reach out to the Ads & Privacy team if you are not sure or you would like to register a property.
|
|
33
|
+
|
|
34
|
+
By default the source link integrates the latest version of the CMP client. If you would like to pin a different version, you can append a `version` query parameter to the source link as follows:
|
|
35
|
+
|
|
36
|
+
```copy
|
|
37
|
+
<script async src="https://consent-notice.ft.com/cmp.js?version=4.0.0"></script>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Using the NPM package
|
|
23
41
|
|
|
24
42
|
> [!Note]
|
|
25
43
|
> We will be adding new properties (i.e. websites under FT group) and their configs as we start rolling out.
|
|
@@ -124,6 +142,10 @@ if (flagsClient.get("adsDisableInternalCMP")) {
|
|
|
124
142
|
<td><code>useConsentStore</code> (boolean)</td>
|
|
125
143
|
<td>Specifies whether the user's consent record should also be backed by the Single Consent Store. Properties like Specialist titles will need to explicitly set this to <code>false</code> as <code>true</code> is the default behavior</td>
|
|
126
144
|
</tr>
|
|
145
|
+
<tr>
|
|
146
|
+
<td><code>disableFTCookies</code> (boolean)</td>
|
|
147
|
+
<td>Specifies whether the user's consent record should be saved to FT Cookies. Properties like Specialist titles that don't utilize FT cookies will need to explicitly set this to <code>true</code> as <code>false</code> is the default behavior</td>
|
|
148
|
+
</tr>
|
|
127
149
|
<tr>
|
|
128
150
|
<td><code>events</code> (object)</td>
|
|
129
151
|
<td>Used internally to define handlers for events emitted by the Vendor-supplied CMP module. See notes on "Responding to CMP events" below for details on how to define custom event handlers</td>
|
|
@@ -224,7 +246,7 @@ If everything's working then you'll see the CMP Module log its lifecycle events
|
|
|
224
246
|
This can easily happen when you've made a previous consent choice and the CMP is now picking it up from local storage. For this reason we recommend running in an incognito window during development.
|
|
225
247
|
|
|
226
248
|
> [!Note]
|
|
227
|
-
> Please ensure that your app always uses the latest version of the CMP Client
|
|
249
|
+
> Please ensure that your app always uses the latest version of the CMP Client library.
|
|
228
250
|
>
|
|
229
251
|
> You can check the version your live app is using by running the following in the browser console:
|
|
230
252
|
>
|
|
@@ -244,6 +266,6 @@ npm run dev -w src/examples/cmp-client
|
|
|
244
266
|
|
|
245
267
|
Visit https://localhost:5173 (see setup details in `src/examples/cmp-client`) to interact with the banner and see how cookies are set accordingly
|
|
246
268
|
|
|
247
|
-
|
|
269
|
+
#### Resources
|
|
248
270
|
|
|
249
|
-
|
|
271
|
+
For a detailed deep-dive (internal only) of how the static deployment process works, the design is [documented here](https://financialtimes.atlassian.net/wiki/spaces/ADS/pages/8293711881/How+the+CMP+static+loader+works). If you need to be granted access, please reach out to the Ads & Privacy team.
|
package/dist/index.cjs
CHANGED
|
@@ -438,6 +438,9 @@ async function saveConsent(consentEndpoint, payload) {
|
|
|
438
438
|
}
|
|
439
439
|
function consentReadyHandlerFn(props) {
|
|
440
440
|
return async function consentReadyHandler(legislation, _consentUUID, consentString, consentMeta) {
|
|
441
|
+
if (props.disableFTCookies) {
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
441
444
|
const activeLegislation = consentMeta.applies ? legislation : "gdpr";
|
|
442
445
|
if (activeLegislation !== legislation || !consentString) {
|
|
443
446
|
return;
|
|
@@ -617,7 +620,7 @@ function setupPmTracking(trackingProps, cmpBaseEndpoint) {
|
|
|
617
620
|
false
|
|
618
621
|
);
|
|
619
622
|
}
|
|
620
|
-
const version = "3.
|
|
623
|
+
const version = "3.5.0-beta.2";
|
|
621
624
|
async function initSourcepointCmp({
|
|
622
625
|
propertyConfig = FT_DOTCOM_PROD,
|
|
623
626
|
userId,
|
|
@@ -626,7 +629,8 @@ async function initSourcepointCmp({
|
|
|
626
629
|
cookieDomain = FT_COOKIE_DOMAIN,
|
|
627
630
|
formOfWordsId = SOURCEPOINT_FOW_ID,
|
|
628
631
|
useConsentStore = true,
|
|
629
|
-
trackingContext = {}
|
|
632
|
+
trackingContext = {},
|
|
633
|
+
disableFTCookies = false
|
|
630
634
|
} = {}) {
|
|
631
635
|
if (typeof window === "undefined") {
|
|
632
636
|
console.error("The CMP client can only be initialised in a browser context");
|
|
@@ -664,7 +668,8 @@ async function initSourcepointCmp({
|
|
|
664
668
|
consentProxyHost,
|
|
665
669
|
cookieDomain,
|
|
666
670
|
formOfWordsId,
|
|
667
|
-
useConsentStore
|
|
671
|
+
useConsentStore,
|
|
672
|
+
disableFTCookies
|
|
668
673
|
})
|
|
669
674
|
);
|
|
670
675
|
});
|
package/dist/index.js
CHANGED
|
@@ -436,6 +436,9 @@ async function saveConsent(consentEndpoint, payload) {
|
|
|
436
436
|
}
|
|
437
437
|
function consentReadyHandlerFn(props) {
|
|
438
438
|
return async function consentReadyHandler(legislation, _consentUUID, consentString, consentMeta) {
|
|
439
|
+
if (props.disableFTCookies) {
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
439
442
|
const activeLegislation = consentMeta.applies ? legislation : "gdpr";
|
|
440
443
|
if (activeLegislation !== legislation || !consentString) {
|
|
441
444
|
return;
|
|
@@ -615,7 +618,7 @@ function setupPmTracking(trackingProps, cmpBaseEndpoint) {
|
|
|
615
618
|
false
|
|
616
619
|
);
|
|
617
620
|
}
|
|
618
|
-
const version = "3.
|
|
621
|
+
const version = "3.5.0-beta.2";
|
|
619
622
|
async function initSourcepointCmp({
|
|
620
623
|
propertyConfig = FT_DOTCOM_PROD,
|
|
621
624
|
userId,
|
|
@@ -624,7 +627,8 @@ async function initSourcepointCmp({
|
|
|
624
627
|
cookieDomain = FT_COOKIE_DOMAIN,
|
|
625
628
|
formOfWordsId = SOURCEPOINT_FOW_ID,
|
|
626
629
|
useConsentStore = true,
|
|
627
|
-
trackingContext = {}
|
|
630
|
+
trackingContext = {},
|
|
631
|
+
disableFTCookies = false
|
|
628
632
|
} = {}) {
|
|
629
633
|
if (typeof window === "undefined") {
|
|
630
634
|
console.error("The CMP client can only be initialised in a browser context");
|
|
@@ -662,7 +666,8 @@ async function initSourcepointCmp({
|
|
|
662
666
|
consentProxyHost,
|
|
663
667
|
cookieDomain,
|
|
664
668
|
formOfWordsId,
|
|
665
|
-
useConsentStore
|
|
669
|
+
useConsentStore,
|
|
670
|
+
disableFTCookies
|
|
666
671
|
})
|
|
667
672
|
);
|
|
668
673
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(){"use strict";const S=(e,{credentials:n="omit"}={})=>fetch(`https://session-next.ft.com${e}`,{credentials:n,useCorsProxy:!0}).then(t=>t.ok?t.json():t.text().then(o=>{throw new Error(`Next session responded with "${o}" (${t.status})`)})).catch(t=>{document.body.dispatchEvent(new CustomEvent("oErrors.log",{bubbles:!0,detail:{error:t,info:{component:"next-session-client"}}}))});let d={};const m=(e,n)=>{if(typeof e=="object"){d=e;return}if(typeof e=="string"&&typeof n=="string"){d[e]=n;return}if(typeof e=="string"&&typeof n>"u")return d[e]||null;if(typeof e>"u"&&typeof n>"u")return d;throw new Error("Invalid arguments")};m.clear=()=>{d={}};const l={},T=()=>{const[,e]=/FTSession_s=([^;]+)/.exec(document.cookie)||[];return e},k=()=>{const e=m("uuid");if(e)return Promise.resolve({uuid:e});const n=T();return n?(l.uuid||(l.uuid=S(`/sessions/s/${n}`).then(({uuid:t}={})=>(delete l.uuid,t&&m("uuid",t),{uuid:t}))),l.uuid):Promise.resolve({uuid:void 0})},h="sourcepoint-cmp",P="FTPINK",N="FTConsent",M="sourcepointCmp/VngD.XycZut.595cp9fWdp5XYP9vlFvk",L=".ft.com",A="https://consent.ft.com",v={permutiveAds:{purposes:[2,4,8,9],iabVendors:[361],customVendors:[],specialFeatures:[]},demographicAds:{purposes:[3,4,7,9,10],iabVendors:[],customVendors:[],specialFeatures:[]},behaviouralAds:{purposes:[2,4,8,9],iabVendors:[],customVendors:[],specialFeatures:[]},programmaticAds:{purposes:[2],iabVendors:[],customVendors:[],specialFeatures:[]},personalisedMarketing:{purposes:[1,4,8,9,10],iabVendors:[],customVendors:[],specialFeatures:[]}},C=Object.keys(v),u={joinHref:!0,gdpr:{},ccpa:{}},I={...u,accountId:1906,baseEndpoint:"https://consent-manager.ft.com",propertyHref:"https://local.ft.com",_clientOptions:{privacyManagerId:827767,manageCookiesLinkOverride:"ft.com/preferences/manage-cookies"}},_={...u,accountId:1906,baseEndpoint:"https://consent-manager.ft.com",propertyId:31642,_clientOptions:{privacyManagerId:827767,manageCookiesLinkOverride:"ft.com/preferences/manage-cookies",rootDomain:"ft.com"}},D={...u,accountId:1906,baseEndpoint:"https://consent-manager.pwmnet.com",propertyId:33414,_clientOptions:{rootDomain:"pwmnet.com"}},R={...u,accountId:1906,baseEndpoint:"https://consent-manager.fdiintelligence.com",propertyId:34061,_clientOptions:{rootDomain:"fdiintelligence.com"}},F={...u,accountId:1906,baseEndpoint:"https://consent-manager.thebanker.com",propertyId:34060,_clientOptions:{rootDomain:"thebanker.com"}},V={...u,accountId:1906,baseEndpoint:"https://consent-manager.bankingriskandregulation.com",propertyId:34059,_clientOptions:{rootDomain:"bankingriskandregulation.com"}},j={...u,accountId:1906,baseEndpoint:"https://consent-manager.sustainableviews.com",propertyId:34058,_clientOptions:{rootDomain:"sustainableviews.com"}},H={...u,accountId:1906,baseEndpoint:"https://consent-manager.ftadviser.com",propertyId:33416,_clientOptions:{rootDomain:"ftadviser.com"}},U={...u,accountId:1906,baseEndpoint:"https://consent-manager.investorschronicle.co.uk",propertyId:33415,_clientOptions:{rootDomain:"investorschronicle.co.uk"}},x={...u,accountId:1906,baseEndpoint:"https://cdn.privacy-mgmt.com",propertyId:33947,_clientOptions:{rootDomain:"ignitesasia.com"}},$={...u,accountId:1906,baseEndpoint:"https://cdn.privacy-mgmt.com",propertyId:33946,_clientOptions:{rootDomain:"igniteseurope.com"}},q=Object.freeze(Object.defineProperty({__proto__:null,FT_DOTCOM_PROD:_,FT_DOTCOM_TEST:I,MM_IGNITES_ASIA:x,MM_IGNITES_EUROPE:$,SP_BANKING_RR:V,SP_FDI_INTELLIGENCE:R,SP_FT_ADVISER:H,SP_INVESTORS_CHRONICLE:U,SP_PWMNET:D,SP_SUSTAINABLE_VIEWS:j,SP_THE_BANKER:F},Symbol.toStringTag,{value:"Module"}));function E(e,n){const t=document.createElement("script");return t.dataset.cmpScript=e,t.innerHTML=n,t}function G(e){const n=document.createElement("script");return n.src=e,n}const W={cmpFrames:"https://consent-manager.ft.com/unified/wrapperMessagingWithoutDetection.js"},w={tcfStub:'"use strict";function _typeof(t){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}!function(){var t=function(){var t,e,o=[],n=window,r=n;for(;r;){try{if(r.frames.__tcfapiLocator){t=r;break}}catch(t){}if(r===n.top)break;r=r.parent}t||(!function t(){var e=n.document,o=!!n.frames.__tcfapiLocator;if(!o)if(e.body){var r=e.createElement("iframe");r.style.cssText="display:none",r.name="__tcfapiLocator",r.title = "__tcfapiLocator",e.body.appendChild(r)}else setTimeout(t,5);return!o}(),n.__tcfapi=function(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];if(!n.length)return o;"setGdprApplies"===n[0]?n.length>3&&2===parseInt(n[1],10)&&"boolean"==typeof n[3]&&(e=n[3],"function"==typeof n[2]&&n[2]("set",!0)):"ping"===n[0]?"function"==typeof n[2]&&n[2]({gdprApplies:e,cmpLoaded:!1,cmpStatus:"stub"}):o.push(n)},n.addEventListener("message",(function(t){var e="string"==typeof t.data,o={};if(e)try{o=JSON.parse(t.data)}catch(t){}else o=t.data;var n="object"===_typeof(o)&&null!==o?o.__tcfapiCall:null;n&&window.__tcfapi(n.command,n.version,(function(o,r){var a={__tcfapiReturn:{returnValue:o,success:r,callId:n.callId}};t&&t.source&&t.source.postMessage&&t.source.postMessage(e?JSON.stringify(a):a,"*")}),n.parameter)}),!1))};"undefined"!=typeof module?module.exports=t:t()}();',uspStub:'"use strict";(function () { var e = false; var c = window; var t = document; function r() { if (!c.frames["__uspapiLocator"]) { if (t.body) { var a = t.body; var e = t.createElement("iframe"); e.style.cssText = "display:none"; e.name = "__uspapiLocator"; e.title = "__uspapiLocator";a.appendChild(e) } else { setTimeout(r, 5) } } } r(); function p() { var a = arguments; __uspapi.a = __uspapi.a || []; if (!a.length) { return __uspapi.a } else if (a[0] === "ping") { a[2]({ gdprAppliesGlobally: e, cmpLoaded: false }, true) } else { __uspapi.a.push([].slice.apply(a)) } } function l(t) { var r = typeof t.data === "string"; try { var a = r ? JSON.parse(t.data) : t.data; if (a.__cmpCall) { var n = a.__cmpCall; c.__uspapi(n.command, n.parameter, function (a, e) { var c = { __cmpReturn: { returnValue: a, success: e, callId: n.callId } }; t.source.postMessage(r ? JSON.stringify(c) : c, "*") }) } } catch (a) { } } if (typeof __uspapi !== "function") { c.__uspapi = p; __uspapi.msgHandler = l; c.addEventListener("message", l, false) } })();'};function K(){const e=document.createDocumentFragment();return e.appendChild(E("tcf",w.tcfStub)),e.appendChild(E("usp",w.uspStub)),e.appendChild(G(W.cmpFrames)),e}function B(e){const{_clientOptions:n,...t}=e;window._sp_={config:t},window._sp_queue??(window._sp_queue=[]),document.head.appendChild(K())}function J(e,n,{formOfWordsId:t,cookieDomain:o}){const r=Object.keys(e).reduce((a,i)=>(a[i]={onsite:{status:e[i],lbi:!1,source:h,fow:t}},a),{});return n?{setConsentCookie:!0,formOfWordsId:t,consentSource:h,cookieDomain:o,data:r}:{data:r,cookieDomain:o}}function X(e,{purpose:n,vendor:t,specialFeatureOptins:o}){const s=v[e],r=s.purposes.every(c=>(n==null?void 0:n.consents[c])||(n==null?void 0:n.legitimateInterests[c])),a=s.iabVendors.every(c=>(t==null?void 0:t.consents[c])||(t==null?void 0:t.legitimateInterests[c])),i=s.specialFeatures.every(c=>(o==null?void 0:o[c])===!0);return r&&a&&i}function Y(e){const n=(e==null?void 0:e[2])==="N",t={};for(const o of C)t[o]=n;return t}async function z(){const e=await new Promise((t,o)=>{var s;try{(s=window.__tcfapi)==null||s.call(window,"addEventListener",2,t)}catch(r){o(r)}}),n={};for(const t of C)n[t]=X(t,e);return n}async function Z(e,n){return e==="ccpa"?Y(n):await z()}function Q(){const n=Object.fromEntries(document.cookie.split("; ").map(o=>o.split("=")))[N];if(!n)return{};const t=decodeURIComponent(n);return Object.fromEntries(t.split(",").map(o=>{const[s,r]=o.split(":");return[s,r==="on"]}))}function ee(e,n){return Object.keys(e).some(o=>{const s=`${o.toLowerCase()}Onsite`;return e[o]!==n[s]})}function te({userId:e,useConsentStore:n}){return!!e&&n===!0}function ne(e,n){return e?`${n.consentProxyHost}/__consent/consent-record/${P}/${n.userId}`:`${n.consentProxyHost}/__consent/consent-record-cookie?cookieDomain=${n.cookieDomain}`}async function oe(e,n){try{const t=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n),credentials:"include"});t.ok||console.error("Unable to save consent preferences",t.status)}catch(t){console.error("An error occurred while saving consent",t)}}function se(e){return async function(t,o,s,r){const a=r.applies?t:"gdpr";if(a!==t||!s)return;const i=await Z(a,s);if(!ee(i,Q()))return;const p=te(e),ve=ne(p,e),Ce=J(i,p,e);await oe(ve,Ce),document.dispatchEvent(new CustomEvent("oCookieMessage.act",{bubbles:!0}))}}const g="cookie-message",re="manage-cookies";let y=Object.freeze({activeComponent:g,messageId:0,privacyManagerId:0});function ce(e){return typeof e=="object"&&e!==null&&e.constructor===Object&&Object.prototype.toString.call(e)==="[object Object]"}const ae=()=>({...y}),b=e=>{if(!ce(e)){console.error("Invalid state changes");return}y={...y,...e}},ie=["adsDisableInternalCMP","pwm.cmp","messageSlotBottom"];function ue(e,n){const t=pe(e.flags);window._sp_queue=window._sp_queue??[],window._sp_queue.push(()=>{var o,s;for(const[r,a]of Object.entries(le))(s=(o=window._sp_).addEventListener)==null||s.call(o,r,a({...e,flags:t}))}),fe({...e,flags:t},n)}function pe(e){const n={};return typeof e=="object"&&ie.forEach(t=>{Object.prototype.hasOwnProperty.call(e,t)&&(n[t]=e[t])}),n}function de(e){if(!e)return;const n=document.body,t=new CustomEvent("oTracking.event",{bubbles:!0,cancelable:!0,detail:e.detail});n.dispatchEvent(t)}function f({trackingProps:e,action:n,triggerAction:t}){let o;const s=ae(),{product:r,app:a,flags:i}=e;s.activeComponent===g?o=s.messageId:o=s.privacyManagerId;const c={detail:{component:{id:o,name:s.activeComponent,type:"overlay",subtype:"cmp"},category:"component",action:n,...t&&{trigger_action:t},...r&&{product:r},...a&&{app:a},custom:[{cookie_toggle_flag:i}],url:window.document.location.href||null}};de(c)}const le={onMessageChoiceSelect:e=>(n,t,o)=>{const r={11:"accept_all",12:"manage_cookies",13:"reject_all"}[o];r&&f({trackingProps:e,action:"click",triggerAction:r})},onMessageReady:e=>()=>{f({trackingProps:e,action:"view"})},onMessageReceiveData:()=>(e,n)=>{const{messageId:t}=n;t&&b({messageId:t})},onError:e=>(n,t)=>{f({trackingProps:e,action:"error",triggerAction:t})},onPMCancel:()=>()=>{b({activeComponent:g})}};function fe(e,n){window.addEventListener("message",function(t){if(t.origin!==n)return;const o={1:"save_and_close",11:"accept_all",13:"reject_all"},{data:{fromPM:s,actionType:r,messageId:a="0"}={}}=t;s&&(+a&&b({activeComponent:re,privacyManagerId:+a}),!(!r||!o[r])&&f({trackingProps:e,action:"click",triggerAction:o[r]}))},!1)}const me="3.4.0-beta.2";async function _e({propertyConfig:e=_,userId:n,useFTSession:t=!0,consentProxyHost:o=A,cookieDomain:s=L,formOfWordsId:r=M,useConsentStore:a=!0,trackingContext:i={}}={}){if(typeof window>"u"){console.error("The CMP client can only be initialised in a browser context");return}if(window.FT_CMP_CLIENT_VERSION=me,!n&&t)try{const c=await k();n=c==null?void 0:c.uuid}catch(c){console.error(c)}if(!(e!=null&&e.accountId))throw new Error("Please pass a valid property config");n&&(e.authId=n),e.events&&(console.warn("[cmp-client] Passing an events map in the config is not supported and will be ignored. Please use window._sp_.addEventListener() to listen for events"),delete e.events),B(e),window._sp_queue.push(()=>{var c,p;(p=(c=window._sp_)==null?void 0:c.addEventListener)==null||p.call(c,"onConsentReady",se({userId:n,consentProxyHost:o,cookieDomain:s,formOfWordsId:r,useConsentStore:a}))}),ue(i,e.baseEndpoint)}function ge(e=_){const{privacyManagerId:n,manageCookiesLinkOverride:t,manageCookiesSelector:o}=e._clientOptions||{},s=document.querySelector(o??"#site-footer");s&&t?s.addEventListener("click",r=>{var i,c,p;const a=r.target.closest("a");(i=a==null?void 0:a.getAttribute("href"))!=null&&i.endsWith(t)&&(r.preventDefault(),(p=(c=window._sp_)==null?void 0:c.gdpr)==null||p.loadPrivacyManagerModal(n))}):console.warn("No footer found for",o)}function ye(e,n){if(!n||Number.isFinite(parseFloat(n))||!e.endsWith(n))return!1;const t=e.indexOf(n),o=e[t-1];return o==="."||o===void 0}function be(e){if(!e)throw new Error("Invalid hostname provided");let t=Object.values(q).find(o=>{var r;const s=(r=o._clientOptions)==null?void 0:r.rootDomain;return s&&ye(e,s)});return t??(t=I),t}const he=new URL(window.location.href).hostname,O=be(he);_e({propertyConfig:O}),ge(O)})();
|
|
1
|
+
(function(){"use strict";const T=(e,{credentials:n="omit"}={})=>fetch(`https://session-next.ft.com${e}`,{credentials:n,useCorsProxy:!0}).then(t=>t.ok?t.json():t.text().then(o=>{throw new Error(`Next session responded with "${o}" (${t.status})`)})).catch(t=>{document.body.dispatchEvent(new CustomEvent("oErrors.log",{bubbles:!0,detail:{error:t,info:{component:"next-session-client"}}}))});let d={};const _=(e,n)=>{if(typeof e=="object"){d=e;return}if(typeof e=="string"&&typeof n=="string"){d[e]=n;return}if(typeof e=="string"&&typeof n>"u")return d[e]||null;if(typeof e>"u"&&typeof n>"u")return d;throw new Error("Invalid arguments")};_.clear=()=>{d={}};const l={},k=()=>{const[,e]=/FTSession_s=([^;]+)/.exec(document.cookie)||[];return e},P=()=>{const e=_("uuid");if(e)return Promise.resolve({uuid:e});const n=k();return n?(l.uuid||(l.uuid=T(`/sessions/s/${n}`).then(({uuid:t}={})=>(delete l.uuid,t&&_("uuid",t),{uuid:t}))),l.uuid):Promise.resolve({uuid:void 0})},h="sourcepoint-cmp",N="FTPINK",M="FTConsent",L="sourcepointCmp/VngD.XycZut.595cp9fWdp5XYP9vlFvk",A=".ft.com",D="https://consent.ft.com",v={permutiveAds:{purposes:[2,4,8,9],iabVendors:[361],customVendors:[],specialFeatures:[]},demographicAds:{purposes:[3,4,7,9,10],iabVendors:[],customVendors:[],specialFeatures:[]},behaviouralAds:{purposes:[2,4,8,9],iabVendors:[],customVendors:[],specialFeatures:[]},programmaticAds:{purposes:[2],iabVendors:[],customVendors:[],specialFeatures:[]},personalisedMarketing:{purposes:[1,4,8,9,10],iabVendors:[],customVendors:[],specialFeatures:[]}},I=Object.keys(v),p={joinHref:!0,gdpr:{},ccpa:{}},E={...p,accountId:1906,baseEndpoint:"https://consent-manager.ft.com",propertyHref:"https://local.ft.com",_clientOptions:{privacyManagerId:827767,manageCookiesLinkOverride:"ft.com/preferences/manage-cookies"}},g={...p,accountId:1906,baseEndpoint:"https://consent-manager.ft.com",propertyId:31642,_clientOptions:{privacyManagerId:827767,manageCookiesLinkOverride:"ft.com/preferences/manage-cookies",rootDomain:"ft.com"}},R={...p,accountId:1906,baseEndpoint:"https://consent-manager.pwmnet.com",propertyId:33414,_clientOptions:{rootDomain:"pwmnet.com"}},F={...p,accountId:1906,baseEndpoint:"https://consent-manager.fdiintelligence.com",propertyId:34061,_clientOptions:{rootDomain:"fdiintelligence.com"}},V={...p,accountId:1906,baseEndpoint:"https://consent-manager.thebanker.com",propertyId:34060,_clientOptions:{rootDomain:"thebanker.com"}},j={...p,accountId:1906,baseEndpoint:"https://consent-manager.bankingriskandregulation.com",propertyId:34059,_clientOptions:{rootDomain:"bankingriskandregulation.com"}},H={...p,accountId:1906,baseEndpoint:"https://consent-manager.sustainableviews.com",propertyId:34058,_clientOptions:{rootDomain:"sustainableviews.com"}},U={...p,accountId:1906,baseEndpoint:"https://consent-manager.ftadviser.com",propertyId:33416,_clientOptions:{rootDomain:"ftadviser.com"}},x={...p,accountId:1906,baseEndpoint:"https://consent-manager.investorschronicle.co.uk",propertyId:33415,_clientOptions:{rootDomain:"investorschronicle.co.uk"}},$={...p,accountId:1906,baseEndpoint:"https://cdn.privacy-mgmt.com",propertyId:33947,_clientOptions:{rootDomain:"ignitesasia.com"}},q={...p,accountId:1906,baseEndpoint:"https://cdn.privacy-mgmt.com",propertyId:33946,_clientOptions:{rootDomain:"igniteseurope.com"}},G=Object.freeze(Object.defineProperty({__proto__:null,FT_DOTCOM_PROD:g,FT_DOTCOM_TEST:E,MM_IGNITES_ASIA:$,MM_IGNITES_EUROPE:q,SP_BANKING_RR:j,SP_FDI_INTELLIGENCE:F,SP_FT_ADVISER:U,SP_INVESTORS_CHRONICLE:x,SP_PWMNET:R,SP_SUSTAINABLE_VIEWS:H,SP_THE_BANKER:V},Symbol.toStringTag,{value:"Module"}));function w(e,n){const t=document.createElement("script");return t.dataset.cmpScript=e,t.innerHTML=n,t}function W(e){const n=document.createElement("script");return n.src=e,n}const K={cmpFrames:"https://consent-manager.ft.com/unified/wrapperMessagingWithoutDetection.js"},O={tcfStub:'"use strict";function _typeof(t){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}!function(){var t=function(){var t,e,o=[],n=window,r=n;for(;r;){try{if(r.frames.__tcfapiLocator){t=r;break}}catch(t){}if(r===n.top)break;r=r.parent}t||(!function t(){var e=n.document,o=!!n.frames.__tcfapiLocator;if(!o)if(e.body){var r=e.createElement("iframe");r.style.cssText="display:none",r.name="__tcfapiLocator",r.title = "__tcfapiLocator",e.body.appendChild(r)}else setTimeout(t,5);return!o}(),n.__tcfapi=function(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];if(!n.length)return o;"setGdprApplies"===n[0]?n.length>3&&2===parseInt(n[1],10)&&"boolean"==typeof n[3]&&(e=n[3],"function"==typeof n[2]&&n[2]("set",!0)):"ping"===n[0]?"function"==typeof n[2]&&n[2]({gdprApplies:e,cmpLoaded:!1,cmpStatus:"stub"}):o.push(n)},n.addEventListener("message",(function(t){var e="string"==typeof t.data,o={};if(e)try{o=JSON.parse(t.data)}catch(t){}else o=t.data;var n="object"===_typeof(o)&&null!==o?o.__tcfapiCall:null;n&&window.__tcfapi(n.command,n.version,(function(o,r){var a={__tcfapiReturn:{returnValue:o,success:r,callId:n.callId}};t&&t.source&&t.source.postMessage&&t.source.postMessage(e?JSON.stringify(a):a,"*")}),n.parameter)}),!1))};"undefined"!=typeof module?module.exports=t:t()}();',uspStub:'"use strict";(function () { var e = false; var c = window; var t = document; function r() { if (!c.frames["__uspapiLocator"]) { if (t.body) { var a = t.body; var e = t.createElement("iframe"); e.style.cssText = "display:none"; e.name = "__uspapiLocator"; e.title = "__uspapiLocator";a.appendChild(e) } else { setTimeout(r, 5) } } } r(); function p() { var a = arguments; __uspapi.a = __uspapi.a || []; if (!a.length) { return __uspapi.a } else if (a[0] === "ping") { a[2]({ gdprAppliesGlobally: e, cmpLoaded: false }, true) } else { __uspapi.a.push([].slice.apply(a)) } } function l(t) { var r = typeof t.data === "string"; try { var a = r ? JSON.parse(t.data) : t.data; if (a.__cmpCall) { var n = a.__cmpCall; c.__uspapi(n.command, n.parameter, function (a, e) { var c = { __cmpReturn: { returnValue: a, success: e, callId: n.callId } }; t.source.postMessage(r ? JSON.stringify(c) : c, "*") }) } } catch (a) { } } if (typeof __uspapi !== "function") { c.__uspapi = p; __uspapi.msgHandler = l; c.addEventListener("message", l, false) } })();'};function B(){const e=document.createDocumentFragment();return e.appendChild(w("tcf",O.tcfStub)),e.appendChild(w("usp",O.uspStub)),e.appendChild(W(K.cmpFrames)),e}function J(e){const{_clientOptions:n,...t}=e;window._sp_={config:t},window._sp_queue??(window._sp_queue=[]),document.head.appendChild(B())}function X(e,n,{formOfWordsId:t,cookieDomain:o}){const r=Object.keys(e).reduce((c,u)=>(c[u]={onsite:{status:e[u],lbi:!1,source:h,fow:t}},c),{});return n?{setConsentCookie:!0,formOfWordsId:t,consentSource:h,cookieDomain:o,data:r}:{data:r,cookieDomain:o}}function Y(e,{purpose:n,vendor:t,specialFeatureOptins:o}){const s=v[e],r=s.purposes.every(i=>(n==null?void 0:n.consents[i])||(n==null?void 0:n.legitimateInterests[i])),c=s.iabVendors.every(i=>(t==null?void 0:t.consents[i])||(t==null?void 0:t.legitimateInterests[i])),u=s.specialFeatures.every(i=>(o==null?void 0:o[i])===!0);return r&&c&&u}function z(e){const n=(e==null?void 0:e[2])==="N",t={};for(const o of I)t[o]=n;return t}async function Z(){const e=await new Promise((t,o)=>{var s;try{(s=window.__tcfapi)==null||s.call(window,"addEventListener",2,t)}catch(r){o(r)}}),n={};for(const t of I)n[t]=Y(t,e);return n}async function Q(e,n){return e==="ccpa"?z(n):await Z()}function ee(){const n=Object.fromEntries(document.cookie.split("; ").map(o=>o.split("=")))[M];if(!n)return{};const t=decodeURIComponent(n);return Object.fromEntries(t.split(",").map(o=>{const[s,r]=o.split(":");return[s,r==="on"]}))}function te(e,n){return Object.keys(e).some(o=>{const s=`${o.toLowerCase()}Onsite`;return e[o]!==n[s]})}function ne({userId:e,useConsentStore:n}){return!!e&&n===!0}function oe(e,n){return e?`${n.consentProxyHost}/__consent/consent-record/${N}/${n.userId}`:`${n.consentProxyHost}/__consent/consent-record-cookie?cookieDomain=${n.cookieDomain}`}async function se(e,n){try{const t=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n),credentials:"include"});t.ok||console.error("Unable to save consent preferences",t.status)}catch(t){console.error("An error occurred while saving consent",t)}}function re(e){return async function(t,o,s,r){if(e.disableFTCookies)return;const c=r.applies?t:"gdpr";if(c!==t||!s)return;const u=await Q(c,s);if(!te(u,ee()))return;const a=ne(e),m=oe(a,e),ve=X(u,a,e);await se(m,ve),document.dispatchEvent(new CustomEvent("oCookieMessage.act",{bubbles:!0}))}}const y="cookie-message",ce="manage-cookies";let b=Object.freeze({activeComponent:y,messageId:0,privacyManagerId:0});function ae(e){return typeof e=="object"&&e!==null&&e.constructor===Object&&Object.prototype.toString.call(e)==="[object Object]"}const ie=()=>({...b}),C=e=>{if(!ae(e)){console.error("Invalid state changes");return}b={...b,...e}},ue=["adsDisableInternalCMP","pwm.cmp","messageSlotBottom"];function pe(e,n){const t=de(e.flags);window._sp_queue=window._sp_queue??[],window._sp_queue.push(()=>{var o,s;for(const[r,c]of Object.entries(fe))(s=(o=window._sp_).addEventListener)==null||s.call(o,r,c({...e,flags:t}))}),me({...e,flags:t},n)}function de(e){const n={};return typeof e=="object"&&ue.forEach(t=>{Object.prototype.hasOwnProperty.call(e,t)&&(n[t]=e[t])}),n}function le(e){if(!e)return;const n=document.body,t=new CustomEvent("oTracking.event",{bubbles:!0,cancelable:!0,detail:e.detail});n.dispatchEvent(t)}function f({trackingProps:e,action:n,triggerAction:t}){let o;const s=ie(),{product:r,app:c,flags:u}=e;s.activeComponent===y?o=s.messageId:o=s.privacyManagerId;const i={detail:{component:{id:o,name:s.activeComponent,type:"overlay",subtype:"cmp"},category:"component",action:n,...t&&{trigger_action:t},...r&&{product:r},...c&&{app:c},custom:[{cookie_toggle_flag:u}],url:window.document.location.href||null}};le(i)}const fe={onMessageChoiceSelect:e=>(n,t,o)=>{const r={11:"accept_all",12:"manage_cookies",13:"reject_all"}[o];r&&f({trackingProps:e,action:"click",triggerAction:r})},onMessageReady:e=>()=>{f({trackingProps:e,action:"view"})},onMessageReceiveData:()=>(e,n)=>{const{messageId:t}=n;t&&C({messageId:t})},onError:e=>(n,t)=>{f({trackingProps:e,action:"error",triggerAction:t})},onPMCancel:()=>()=>{C({activeComponent:y})}};function me(e,n){window.addEventListener("message",function(t){if(t.origin!==n)return;const o={1:"save_and_close",11:"accept_all",13:"reject_all"},{data:{fromPM:s,actionType:r,messageId:c="0"}={}}=t;s&&(+c&&C({activeComponent:ce,privacyManagerId:+c}),!(!r||!o[r])&&f({trackingProps:e,action:"click",triggerAction:o[r]}))},!1)}const _e="3.5.0-beta.2";async function ge({propertyConfig:e=g,userId:n,useFTSession:t=!0,consentProxyHost:o=D,cookieDomain:s=A,formOfWordsId:r=L,useConsentStore:c=!0,trackingContext:u={},disableFTCookies:i=!1}={}){if(typeof window>"u"){console.error("The CMP client can only be initialised in a browser context");return}if(window.FT_CMP_CLIENT_VERSION=_e,!n&&t)try{const a=await P();n=a==null?void 0:a.uuid}catch(a){console.error(a)}if(!(e!=null&&e.accountId))throw new Error("Please pass a valid property config");n&&(e.authId=n),e.events&&(console.warn("[cmp-client] Passing an events map in the config is not supported and will be ignored. Please use window._sp_.addEventListener() to listen for events"),delete e.events),J(e),window._sp_queue.push(()=>{var a,m;(m=(a=window._sp_)==null?void 0:a.addEventListener)==null||m.call(a,"onConsentReady",re({userId:n,consentProxyHost:o,cookieDomain:s,formOfWordsId:r,useConsentStore:c,disableFTCookies:i}))}),pe(u,e.baseEndpoint)}function ye(e=g){const{privacyManagerId:n,manageCookiesLinkOverride:t,manageCookiesSelector:o}=e._clientOptions||{},s=document.querySelector(o??"#site-footer");s&&t?s.addEventListener("click",r=>{var u,i,a;const c=r.target.closest("a");(u=c==null?void 0:c.getAttribute("href"))!=null&&u.endsWith(t)&&(r.preventDefault(),(a=(i=window._sp_)==null?void 0:i.gdpr)==null||a.loadPrivacyManagerModal(n))}):console.warn("No footer found for",o)}function be(e,n){if(!n||Number.isFinite(parseFloat(n))||!e.endsWith(n))return!1;const t=e.indexOf(n),o=e[t-1];return o==="."||o===void 0}function Ce(e){if(!e)throw new Error("Invalid hostname provided");let t=Object.values(G).find(o=>{var r;const s=(r=o._clientOptions)==null?void 0:r.rootDomain;return s&&be(e,s)});return t??(t=E),t}const he=new URL(window.location.href).hostname,S=Ce(he);ge({propertyConfig:S}),ye(S)})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/index.test.ts"],"names":[],"mappings":""}
|
package/dist/src/client.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { CMPInitOptions } from "../typings/types.d.ts";
|
|
2
|
-
export declare function initSourcepointCmp({ propertyConfig, userId, useFTSession, consentProxyHost, cookieDomain, formOfWordsId, useConsentStore, trackingContext, }?: CMPInitOptions): Promise<void>;
|
|
2
|
+
export declare function initSourcepointCmp({ propertyConfig, userId, useFTSession, consentProxyHost, cookieDomain, formOfWordsId, useConsentStore, trackingContext, disableFTCookies, }?: CMPInitOptions): Promise<void>;
|
|
3
3
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/src/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAW5D,wBAAsB,kBAAkB,CAAC,EACvC,cAA+B,EAC/B,MAAM,EACN,YAAmB,EACnB,gBAAwC,EACxC,YAA+B,EAC/B,aAAkC,EAClC,eAAsB,EACtB,eAAoB,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAW5D,wBAAsB,kBAAkB,CAAC,EACvC,cAA+B,EAC/B,MAAM,EACN,YAAmB,EACnB,gBAAwC,EACxC,YAA+B,EAC/B,aAAkC,EAClC,eAAsB,EACtB,eAAoB,EACpB,gBAAwB,GACzB,GAAE,cAAmB,iBAiDrB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/consent-ready/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AA8B/E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,iBAAiB,iBAE7C,MAAM,gBACL,MAAM,iBACL,MAAM,eACR;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/consent-ready/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AA8B/E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,iBAAiB,iBAE7C,MAAM,gBACL,MAAM,iBACL,MAAM,eACR;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,mBA0BrC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../../src/consent-ready/utils/__fixtures__/helpers.ts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,CAAC,QAAQ,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;;;EA4BzE"}
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../../src/consent-ready/utils/__fixtures__/helpers.ts"],"names":[],"mappings":"AAEA,wBAAgB,SAAS,CAAC,gBAAgB,EAAE,OAAO,QAKlD;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;;;EA4BzE"}
|
package/package.json
CHANGED