@phantomstudios/ft-lib 0.5.2-rc8 → 0.5.2-rc9
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/lib/cmp/vendorConsent.d.ts +1 -17
- package/lib/cmp/vendorConsent.d.ts.map +1 -1
- package/lib/cmp/vendorConsent.js +82 -31
- package/lib/cmp/vendorConsent.js.map +1 -1
- package/package.json +1 -1
- package/src/cmp/vendorConsent.ts +99 -61
- package/src/types.d.ts +28 -1
|
@@ -1,25 +1,9 @@
|
|
|
1
|
-
declare global {
|
|
2
|
-
interface Window {
|
|
3
|
-
__tcfapi?: (command: string, version: number, callback: (tcData: TCFData | null, success: boolean) => void, parameter?: any) => void;
|
|
4
|
-
}
|
|
5
|
-
}
|
|
6
|
-
interface TCFData {
|
|
7
|
-
eventStatus: "tcloaded" | "useractioncomplete" | "cmpuishown";
|
|
8
|
-
listenerId: number;
|
|
9
|
-
purpose?: {
|
|
10
|
-
consents?: Record<number, boolean>;
|
|
11
|
-
};
|
|
12
|
-
vendor?: {
|
|
13
|
-
consents?: Record<number, boolean>;
|
|
14
|
-
};
|
|
15
|
-
gdprApplies?: boolean | undefined;
|
|
16
|
-
}
|
|
17
1
|
export interface VendorConsentResults {
|
|
18
2
|
brandmetrics: boolean;
|
|
19
3
|
linkedIn: boolean;
|
|
20
4
|
purpose1: boolean;
|
|
21
5
|
gdprApplies: boolean;
|
|
6
|
+
usnatApplies?: boolean;
|
|
22
7
|
}
|
|
23
8
|
export declare function initVendorConsentListener(onConsentUpdate: (results: VendorConsentResults) => void): void;
|
|
24
|
-
export {};
|
|
25
9
|
//# sourceMappingURL=vendorConsent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vendorConsent.d.ts","sourceRoot":"","sources":["../../src/cmp/vendorConsent.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vendorConsent.d.ts","sourceRoot":"","sources":["../../src/cmp/vendorConsent.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,yBAAyB,CACvC,eAAe,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,GACvD,IAAI,CAqDN"}
|
package/lib/cmp/vendorConsent.js
CHANGED
|
@@ -2,38 +2,89 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.initVendorConsentListener = initVendorConsentListener;
|
|
4
4
|
function initVendorConsentListener(onConsentUpdate) {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
// --- Path 1: Check TCF API First ---
|
|
6
|
+
if (typeof window.__tcfapi === "function") {
|
|
7
|
+
window.__tcfapi("addEventListener", 2, function (tcData, success) {
|
|
8
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
9
|
+
if (!success || !tcData)
|
|
10
|
+
return;
|
|
11
|
+
var isConsentReady = tcData.eventStatus === "tcloaded" ||
|
|
12
|
+
tcData.eventStatus === "useractioncomplete";
|
|
13
|
+
if (isConsentReady) {
|
|
14
|
+
// If GDPR actually applies, process TCF consents (Opt-In model)
|
|
15
|
+
if (tcData.gdprApplies !== false) {
|
|
16
|
+
var results = {
|
|
17
|
+
brandmetrics: ((_b = (_a = tcData.vendor) === null || _a === void 0 ? void 0 : _a.consents) === null || _b === void 0 ? void 0 : _b[422]) === true,
|
|
18
|
+
linkedIn: ((_d = (_c = tcData.vendor) === null || _c === void 0 ? void 0 : _c.consents) === null || _d === void 0 ? void 0 : _d[804]) === true,
|
|
19
|
+
purpose1: ((_f = (_e = tcData.purpose) === null || _e === void 0 ? void 0 : _e.consents) === null || _f === void 0 ? void 0 : _f[1]) === true,
|
|
20
|
+
gdprApplies: true,
|
|
21
|
+
usnatApplies: false,
|
|
22
|
+
};
|
|
23
|
+
onConsentUpdate(results);
|
|
24
|
+
// Clean up TCF listener
|
|
25
|
+
if (typeof tcData.listenerId === "number") {
|
|
26
|
+
(_g = window.__tcfapi) === null || _g === void 0 ? void 0 : _g.call(window, "removeEventListener", 2, function () { }, tcData.listenerId);
|
|
27
|
+
}
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
// --- Path 2: TCF explicitly returned gdprApplies: false -> Fall back to USNat ---
|
|
31
|
+
evaluateUSNatConsent(onConsentUpdate);
|
|
32
|
+
// Clean up TCF listener since GDPR does not apply
|
|
33
|
+
if (typeof tcData.listenerId === "number") {
|
|
34
|
+
(_h = window.__tcfapi) === null || _h === void 0 ? void 0 : _h.call(window, "removeEventListener", 2, function () { }, tcData.listenerId);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
// If __tcfapi doesn't exist at all, try evaluating USNat directly
|
|
41
|
+
evaluateUSNatConsent(onConsentUpdate);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Helper to evaluate USNat / US Privacy consent (Opt-Out model)
|
|
46
|
+
*/
|
|
47
|
+
function evaluateUSNatConsent(onConsentUpdate) {
|
|
48
|
+
var _a, _b;
|
|
49
|
+
// Option A: Preferred Sourcepoint SDK method
|
|
50
|
+
if (typeof ((_b = (_a = window._sp_) === null || _a === void 0 ? void 0 : _a.usnat) === null || _b === void 0 ? void 0 : _b.getUserConsents) === "function") {
|
|
51
|
+
window._sp_.usnat.getUserConsents(function (consents) {
|
|
52
|
+
// US Privacy is OPT-OUT by default.
|
|
53
|
+
// If the user has NOT opted out, consent is considered granted for all vendors/purposes.
|
|
54
|
+
var isOptedOut = (consents === null || consents === void 0 ? void 0 : consents.optedOut) === true ||
|
|
55
|
+
(Array.isArray(consents === null || consents === void 0 ? void 0 : consents.rejectedCategories) &&
|
|
56
|
+
consents.rejectedCategories.length > 0);
|
|
57
|
+
var isConsented = !isOptedOut;
|
|
58
|
+
onConsentUpdate({
|
|
59
|
+
brandmetrics: isConsented,
|
|
60
|
+
linkedIn: isConsented,
|
|
61
|
+
purpose1: isConsented,
|
|
62
|
+
gdprApplies: false,
|
|
63
|
+
usnatApplies: true,
|
|
64
|
+
});
|
|
65
|
+
});
|
|
7
66
|
return;
|
|
8
67
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
var
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// Trigger your callback handler with the updated states
|
|
31
|
-
onConsentUpdate(results);
|
|
32
|
-
// Clean up listener after handling the event
|
|
33
|
-
if (typeof tcData.listenerId === "number") {
|
|
34
|
-
(_g = window.__tcfapi) === null || _g === void 0 ? void 0 : _g.call(window, "removeEventListener", 2, function () { }, tcData.listenerId);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
});
|
|
68
|
+
// Option B: Fallback to GPP standard API
|
|
69
|
+
if (typeof window.__gpp === "function") {
|
|
70
|
+
window.__gpp("getGPPData", function (gppData, success) {
|
|
71
|
+
var _a;
|
|
72
|
+
if (!success || !gppData)
|
|
73
|
+
return;
|
|
74
|
+
var usnat = (_a = gppData.parsedSections) === null || _a === void 0 ? void 0 : _a.usnat;
|
|
75
|
+
// GPP USNat spec: 1 = Opted Out / Yes
|
|
76
|
+
var isOptedOut = (usnat === null || usnat === void 0 ? void 0 : usnat.SharingOptOut) === 1 ||
|
|
77
|
+
(usnat === null || usnat === void 0 ? void 0 : usnat.TargetedAdvertisingOptOut) === 1 ||
|
|
78
|
+
(usnat === null || usnat === void 0 ? void 0 : usnat.SaleOptOut) === 1;
|
|
79
|
+
var isConsented = !isOptedOut;
|
|
80
|
+
onConsentUpdate({
|
|
81
|
+
brandmetrics: isConsented,
|
|
82
|
+
linkedIn: isConsented,
|
|
83
|
+
purpose1: isConsented,
|
|
84
|
+
gdprApplies: false,
|
|
85
|
+
usnatApplies: true,
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
}
|
|
38
89
|
}
|
|
39
90
|
//# sourceMappingURL=vendorConsent.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vendorConsent.js","sourceRoot":"","sources":["../../src/cmp/vendorConsent.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"vendorConsent.js","sourceRoot":"","sources":["../../src/cmp/vendorConsent.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.2-
|
|
4
|
+
"version": "0.5.2-rc9",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
7
7
|
"homepage": "https://github.com/phantomstudios/ft-lib#readme",
|
package/src/cmp/vendorConsent.ts
CHANGED
|
@@ -1,81 +1,119 @@
|
|
|
1
|
-
// 1. Declare Global Window Types for TCF API
|
|
2
|
-
declare global {
|
|
3
|
-
interface Window {
|
|
4
|
-
__tcfapi?: (
|
|
5
|
-
command: string,
|
|
6
|
-
version: number,
|
|
7
|
-
callback: (tcData: TCFData | null, success: boolean) => void,
|
|
8
|
-
parameter?: any,
|
|
9
|
-
) => void;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
interface TCFData {
|
|
14
|
-
eventStatus: "tcloaded" | "useractioncomplete" | "cmpuishown";
|
|
15
|
-
listenerId: number;
|
|
16
|
-
purpose?: {
|
|
17
|
-
consents?: Record<number, boolean>;
|
|
18
|
-
};
|
|
19
|
-
vendor?: {
|
|
20
|
-
consents?: Record<number, boolean>;
|
|
21
|
-
};
|
|
22
|
-
gdprApplies?: boolean | undefined;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
1
|
export interface VendorConsentResults {
|
|
26
2
|
brandmetrics: boolean;
|
|
27
3
|
linkedIn: boolean;
|
|
28
4
|
purpose1: boolean;
|
|
29
5
|
gdprApplies: boolean;
|
|
6
|
+
usnatApplies?: boolean;
|
|
30
7
|
}
|
|
31
8
|
|
|
32
9
|
export function initVendorConsentListener(
|
|
33
10
|
onConsentUpdate: (results: VendorConsentResults) => void,
|
|
34
11
|
): void {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
12
|
+
// --- Path 1: Check TCF API First ---
|
|
13
|
+
if (typeof window.__tcfapi === "function") {
|
|
14
|
+
window.__tcfapi("addEventListener", 2, (tcData, success) => {
|
|
15
|
+
if (!success || !tcData) return;
|
|
39
16
|
|
|
40
|
-
|
|
41
|
-
|
|
17
|
+
const isConsentReady =
|
|
18
|
+
tcData.eventStatus === "tcloaded" ||
|
|
19
|
+
tcData.eventStatus === "useractioncomplete";
|
|
42
20
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
21
|
+
if (isConsentReady) {
|
|
22
|
+
// If GDPR actually applies, process TCF consents (Opt-In model)
|
|
23
|
+
if (tcData.gdprApplies !== false) {
|
|
24
|
+
const results: VendorConsentResults = {
|
|
25
|
+
brandmetrics: tcData.vendor?.consents?.[422] === true,
|
|
26
|
+
linkedIn: tcData.vendor?.consents?.[804] === true,
|
|
27
|
+
purpose1: tcData.purpose?.consents?.[1] === true,
|
|
28
|
+
gdprApplies: true,
|
|
29
|
+
usnatApplies: false,
|
|
30
|
+
};
|
|
47
31
|
|
|
48
|
-
|
|
49
|
-
// Brandmetrics (IAB Vendor ID: 422)
|
|
50
|
-
const brandmetrics = tcData.vendor?.consents?.[422] === true;
|
|
32
|
+
onConsentUpdate(results);
|
|
51
33
|
|
|
52
|
-
|
|
53
|
-
|
|
34
|
+
// Clean up TCF listener
|
|
35
|
+
if (typeof tcData.listenerId === "number") {
|
|
36
|
+
window.__tcfapi?.(
|
|
37
|
+
"removeEventListener",
|
|
38
|
+
2,
|
|
39
|
+
() => {},
|
|
40
|
+
tcData.listenerId,
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
54
45
|
|
|
55
|
-
|
|
56
|
-
|
|
46
|
+
// --- Path 2: TCF explicitly returned gdprApplies: false -> Fall back to USNat ---
|
|
47
|
+
evaluateUSNatConsent(onConsentUpdate);
|
|
57
48
|
|
|
58
|
-
|
|
49
|
+
// Clean up TCF listener since GDPR does not apply
|
|
50
|
+
if (typeof tcData.listenerId === "number") {
|
|
51
|
+
window.__tcfapi?.(
|
|
52
|
+
"removeEventListener",
|
|
53
|
+
2,
|
|
54
|
+
() => {},
|
|
55
|
+
tcData.listenerId,
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
} else {
|
|
61
|
+
// If __tcfapi doesn't exist at all, try evaluating USNat directly
|
|
62
|
+
evaluateUSNatConsent(onConsentUpdate);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
59
65
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Helper to evaluate USNat / US Privacy consent (Opt-Out model)
|
|
68
|
+
*/
|
|
69
|
+
function evaluateUSNatConsent(
|
|
70
|
+
onConsentUpdate: (results: VendorConsentResults) => void,
|
|
71
|
+
): void {
|
|
72
|
+
// Option A: Preferred Sourcepoint SDK method
|
|
73
|
+
if (typeof window._sp_?.usnat?.getUserConsents === "function") {
|
|
74
|
+
window._sp_.usnat.getUserConsents((consents) => {
|
|
75
|
+
// US Privacy is OPT-OUT by default.
|
|
76
|
+
// If the user has NOT opted out, consent is considered granted for all vendors/purposes.
|
|
77
|
+
const isOptedOut =
|
|
78
|
+
consents?.optedOut === true ||
|
|
79
|
+
(Array.isArray(consents?.rejectedCategories) &&
|
|
80
|
+
consents.rejectedCategories.length > 0);
|
|
66
81
|
|
|
67
|
-
|
|
68
|
-
onConsentUpdate(results);
|
|
82
|
+
const isConsented = !isOptedOut;
|
|
69
83
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
onConsentUpdate({
|
|
85
|
+
brandmetrics: isConsented,
|
|
86
|
+
linkedIn: isConsented,
|
|
87
|
+
purpose1: isConsented,
|
|
88
|
+
gdprApplies: false,
|
|
89
|
+
usnatApplies: true,
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Option B: Fallback to GPP standard API
|
|
96
|
+
if (typeof window.__gpp === "function") {
|
|
97
|
+
window.__gpp("getGPPData", (gppData: any, success: boolean) => {
|
|
98
|
+
if (!success || !gppData) return;
|
|
99
|
+
|
|
100
|
+
const usnat = gppData.parsedSections?.usnat;
|
|
101
|
+
|
|
102
|
+
// GPP USNat spec: 1 = Opted Out / Yes
|
|
103
|
+
const isOptedOut =
|
|
104
|
+
usnat?.SharingOptOut === 1 ||
|
|
105
|
+
usnat?.TargetedAdvertisingOptOut === 1 ||
|
|
106
|
+
usnat?.SaleOptOut === 1;
|
|
107
|
+
|
|
108
|
+
const isConsented = !isOptedOut;
|
|
109
|
+
|
|
110
|
+
onConsentUpdate({
|
|
111
|
+
brandmetrics: isConsented,
|
|
112
|
+
linkedIn: isConsented,
|
|
113
|
+
purpose1: isConsented,
|
|
114
|
+
gdprApplies: false,
|
|
115
|
+
usnatApplies: true,
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
}
|
|
81
119
|
}
|
package/src/types.d.ts
CHANGED
|
@@ -15,17 +15,44 @@ declare module "@financial-times/cmp-client" {
|
|
|
15
15
|
propertyConfig?: any;
|
|
16
16
|
}): Promise<void>;
|
|
17
17
|
}
|
|
18
|
+
|
|
19
|
+
interface TCFData {
|
|
20
|
+
eventStatus: "tcloaded" | "useractioncomplete" | "cmpuishown";
|
|
21
|
+
listenerId: number;
|
|
22
|
+
purpose?: {
|
|
23
|
+
consents?: Record<number, boolean>;
|
|
24
|
+
};
|
|
25
|
+
vendor?: {
|
|
26
|
+
consents?: Record<number, boolean>;
|
|
27
|
+
};
|
|
28
|
+
gdprApplies?: boolean | undefined;
|
|
29
|
+
}
|
|
18
30
|
interface SourcepointCmpAPI {
|
|
19
31
|
queue?: Array<() => void>;
|
|
20
32
|
addEventListener?: (
|
|
21
33
|
eventName: string,
|
|
22
|
-
|
|
23
34
|
callback: (...args: any[]) => void,
|
|
24
35
|
) => void;
|
|
36
|
+
usnat?: {
|
|
37
|
+
getUserConsents: (callback: (consents: any) => void) => void;
|
|
38
|
+
};
|
|
25
39
|
}
|
|
40
|
+
|
|
26
41
|
interface Window {
|
|
27
42
|
_sp_: SourcepointCmpAPI;
|
|
28
43
|
_sp_queue?: Array<() => void>;
|
|
44
|
+
__tcfapi?: (
|
|
45
|
+
command: string,
|
|
46
|
+
version: number,
|
|
47
|
+
callback: (tcData: TCFData | null, success: boolean) => void,
|
|
48
|
+
parameter?: any,
|
|
49
|
+
) => void;
|
|
50
|
+
__gpp?: (
|
|
51
|
+
command: string,
|
|
52
|
+
callback?: (data: any, success: boolean) => void,
|
|
53
|
+
parameter?: any,
|
|
54
|
+
) => void;
|
|
55
|
+
|
|
29
56
|
dataLayer: any;
|
|
30
57
|
gtag: any;
|
|
31
58
|
permutive: {
|