@walkeros/web-source-cmp-usercentrics 4.2.0 → 4.2.1-next-1781526381392
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/CHANGELOG.md +14 -0
- package/README.md +36 -3
- package/dist/dev.d.mts +69 -50
- package/dist/dev.d.ts +69 -50
- package/dist/dev.js +1 -1
- package/dist/dev.js.map +1 -1
- package/dist/dev.mjs +1 -1
- package/dist/dev.mjs.map +1 -1
- package/dist/examples/index.d.mts +65 -43
- package/dist/examples/index.d.ts +65 -43
- package/dist/examples/index.js +101 -180
- package/dist/examples/index.mjs +97 -172
- package/dist/index.browser.js +1 -1
- package/dist/index.d.mts +25 -16
- package/dist/index.d.ts +25 -16
- package/dist/index.es5.js +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/walkerOS.json +439 -140
- package/package.json +3 -3
package/dist/index.browser.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var SourceUsercentrics=(()=>{var e=Object.defineProperty,t=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,
|
|
1
|
+
"use strict";var SourceUsercentrics=(()=>{var e=Object.defineProperty,t=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,r={};((t,n)=>{for(var o in n)e(t,o,{get:n[o],enumerable:!0})})(r,{SourceUsercentrics:()=>g,default:()=>_,sourceUsercentrics:()=>f});var i=["action","event","type","ucCategory"];function c(e,t,n){e[t]=(void 0===e[t]||Boolean(e[t]))&&n}function s(e,t){const n={};var o;return e.ucCategory&&(o=e.ucCategory,Object.values(o).every(e=>"boolean"==typeof e))?Object.entries(e.ucCategory).forEach(([e,o])=>{var r,i;if("boolean"!=typeof o)return;const s=null!=(i=null==(r=t.categoryMap)?void 0:r[e])?i:e;c(n,s,o)}):(e.ucCategory&&Object.entries(e.ucCategory).forEach(([e,o])=>{var r,i;if("boolean"==typeof o){const s=null!=(i=null==(r=t.categoryMap)?void 0:r[e])?i:e;c(n,s,o)}}),Object.entries(e).forEach(([e,t])=>{if(i.includes(e))return;if("boolean"!=typeof t)return;const o=e.toLowerCase().replace(/ /g,"_");c(n,o,t)})),n}var a=new Set(["ACCEPT_ALL","DENY_ALL","SAVE"]);function l(e){const t={};return e.forEach(e=>{var n,o;const r=e.categorySlug,i=null!=(o=null==(n=e.consent)?void 0:n.status)&&o;t[r]=(void 0===t[r]||t[r])&&i}),t}function u(e){return e.some(e=>{var t;return(null!=(t=e.consent.history)?t:[]).some(e=>{var t;return"explicit"===(null==(t=e.type)?void 0:t.toLowerCase())})})}function v(e){const{window:t,elb:n,settings:o,logger:r}=e,i=()=>{var e;const i=t.UC_UI;if(!(null==(e=null==i?void 0:i.isInitialized)?void 0:e.call(i))||!i.getServicesBaseInfo)return;const c=i.getServicesBaseInfo();if(!c.length)return;const a=function(e){const t={event:"consent_status",type:u(e)?"explicit":"implicit",ucCategory:l(e)};return e.forEach(e=>{e.name&&(t[e.name]=e.consent.status)}),t}(c);if(r.debug("consent read",a),o.explicitOnly&&"explicit"!==a.type)return;const v=s(a,o);Object.keys(v).length>0&&n("walker consent",v)},c=()=>i(),v=e=>{const t=e.detail;(null==t?void 0:t.type)&&a.has(t.type)&&i()};return t.addEventListener("UC_UI_INITIALIZED",c),t.addEventListener("UC_UI_CMP_EVENT",v),i(),()=>{t.removeEventListener("UC_UI_INITIALIZED",c),t.removeEventListener("UC_UI_CMP_EVENT",v)}}var p=new Set(["ACCEPT_ALL","DENY_ALL","SAVE"]);async function y(e){var t;const{window:n,elb:o,settings:r,logger:i}=e,c=null!=(t=r.v3EventName)?t:"UC_UI_CMP_EVENT",a=async e=>{const t=function(e){const t={};return Object.entries(e.categories).forEach(([e,n])=>{t[e]="ALL_ACCEPTED"===n.state}),{event:"consent_status",type:"EXPLICIT"===e.consent.type?"explicit":"implicit",ucCategory:t}}(await e.getConsentDetails());if(i.debug("event received",t),r.explicitOnly&&"explicit"!==t.type)return;const n=s(t,r);Object.keys(n).length>0&&o("walker consent",n)},l=e=>{const t=n.__ucCmp;if(!t)return;const o=e.detail;(null==o?void 0:o.type)&&p.has(o.type)&&a(t).catch(()=>{})};n.addEventListener(c,l);const u=()=>{const e=n.__ucCmp;e&&a(e).catch(()=>{})};n.addEventListener("UC_UI_INITIALIZED",u);const v=n.__ucCmp;if(v)try{await v.isInitialized()&&await a(v)}catch(e){i.warn("v3 static consent read failed",e)}return()=>{n.removeEventListener(c,l),n.removeEventListener("UC_UI_INITIALIZED",u)}}var d,g={},f=async e=>{var t,n,o,r,i,c,s,a,l;const{config:u,env:p}=e,{elb:d,logger:g}=p,f=null!=(t=p.window)?t:void 0!==globalThis.window?globalThis.window:void 0,_={categoryMap:null!=(o=null==(n=null==u?void 0:u.settings)?void 0:n.categoryMap)?o:{},explicitOnly:null==(i=null==(r=null==u?void 0:u.settings)?void 0:r.explicitOnly)||i,apiVersion:null!=(s=null==(c=null==u?void 0:u.settings)?void 0:c.apiVersion)?s:"auto",v3EventName:null!=(l=null==(a=null==u?void 0:u.settings)?void 0:a.v3EventName)?l:"UC_UI_CMP_EVENT"},E=[];return{type:"usercentrics",config:{settings:_},push:d,init:async()=>{var e;if(!f)return;const t={window:f,elb:d,settings:_,logger:g},n=null!=(e=_.apiVersion)?e:"auto";"v2"===n?E.push(v(t)):"v3"===n||f.__ucCmp?E.push(await y(t)):f.UC_UI?E.push(v(t)):(E.push(v(t)),E.push(await y(t)))},destroy:async()=>{E.forEach(e=>e())}}},_=f;return d=r,((r,i,c,s)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let a of n(i))o.call(r,a)||a===c||e(r,a,{get:()=>i[a],enumerable:!(s=t(i,a))||s.enumerable});return r})(e({},"__esModule",{value:!0}),d)})();
|
package/dist/index.d.mts
CHANGED
|
@@ -29,9 +29,20 @@ interface UsercentricsEventDetail {
|
|
|
29
29
|
declare global {
|
|
30
30
|
interface WindowEventMap {
|
|
31
31
|
ucEvent: CustomEvent<UsercentricsEventDetail>;
|
|
32
|
+
UC_UI_INITIALIZED: Event;
|
|
32
33
|
UC_UI_CMP_EVENT: CustomEvent<UsercentricsV3CmpEventDetail>;
|
|
33
34
|
}
|
|
34
35
|
}
|
|
36
|
+
/** Usercentrics CONSENT_TYPE values (history entry type / V3 consent type). */
|
|
37
|
+
type UsercentricsConsentType = 'explicit' | 'implicit';
|
|
38
|
+
/** A single entry in a V2 service's consent history (getServicesBaseInfo). */
|
|
39
|
+
interface UsercentricsV2ConsentHistoryEntry {
|
|
40
|
+
type: UsercentricsConsentType;
|
|
41
|
+
status: boolean;
|
|
42
|
+
/** CONSENT_ACTION, e.g. 'onAcceptAllServices' | 'onInitialPageLoad'. Not read for the gate. */
|
|
43
|
+
action?: string;
|
|
44
|
+
timestamp?: number;
|
|
45
|
+
}
|
|
35
46
|
/**
|
|
36
47
|
* Usercentrics V2 service info shape returned by `UC_UI.getServicesBaseInfo()`.
|
|
37
48
|
* Only the fields we use are typed - minimal surface, not a full V2 API mirror.
|
|
@@ -39,9 +50,13 @@ declare global {
|
|
|
39
50
|
interface UsercentricsV2Service {
|
|
40
51
|
/** Category slug: 'essential' | 'functional' | 'marketing' | custom */
|
|
41
52
|
categorySlug: string;
|
|
53
|
+
/** Service display name (used for service-level consent keys) */
|
|
54
|
+
name?: string;
|
|
42
55
|
/** Consent state for this service */
|
|
43
56
|
consent: {
|
|
44
57
|
status: boolean;
|
|
58
|
+
/** Consent decision history; an 'explicit' entry proves a real user decision. */
|
|
59
|
+
history?: UsercentricsV2ConsentHistoryEntry[];
|
|
45
60
|
};
|
|
46
61
|
}
|
|
47
62
|
/**
|
|
@@ -53,6 +68,7 @@ interface UsercentricsV2Service {
|
|
|
53
68
|
interface UsercentricsV2Api {
|
|
54
69
|
isInitialized?: () => boolean;
|
|
55
70
|
getServicesBaseInfo?: () => UsercentricsV2Service[];
|
|
71
|
+
getServicesFullInfo?: () => Promise<UsercentricsV2Service[]>;
|
|
56
72
|
areAllConsentsAccepted?: () => boolean;
|
|
57
73
|
}
|
|
58
74
|
/**
|
|
@@ -99,8 +115,9 @@ interface UsercentricsV3Api {
|
|
|
99
115
|
* `source: 'CMP'` + a decision `type` tells us a user action has been taken.
|
|
100
116
|
*/
|
|
101
117
|
interface UsercentricsV3CmpEventDetail {
|
|
102
|
-
source?: string;
|
|
118
|
+
source?: 'none' | 'button' | 'first' | 'second' | 'embeddings' | '__ucCmp' | string;
|
|
103
119
|
type?: string;
|
|
120
|
+
abTestVariant?: string;
|
|
104
121
|
}
|
|
105
122
|
declare global {
|
|
106
123
|
interface Window {
|
|
@@ -122,14 +139,6 @@ declare global {
|
|
|
122
139
|
* Settings for Usercentrics source
|
|
123
140
|
*/
|
|
124
141
|
interface Settings {
|
|
125
|
-
/**
|
|
126
|
-
* Window event name to listen for.
|
|
127
|
-
* Configured in Usercentrics admin under Implementation > Data Layer & Events.
|
|
128
|
-
* Can also be set to 'UC_SDK_EVENT' for the built-in Browser SDK event.
|
|
129
|
-
*
|
|
130
|
-
* Default: 'ucEvent'
|
|
131
|
-
*/
|
|
132
|
-
eventName?: string;
|
|
133
142
|
/**
|
|
134
143
|
* Map Usercentrics categories to walkerOS consent groups.
|
|
135
144
|
* Keys: Usercentrics category names (from ucCategory)
|
|
@@ -144,11 +153,10 @@ interface Settings {
|
|
|
144
153
|
*/
|
|
145
154
|
categoryMap?: Record<string, string>;
|
|
146
155
|
/**
|
|
147
|
-
* Only
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
* Default: true
|
|
156
|
+
* Only publish when the user has actively decided. V3: consent.type ===
|
|
157
|
+
* EXPLICIT. V2: an EXPLICIT entry exists in service consent history.
|
|
158
|
+
* Implicit/default page-load states are suppressed. Set false to publish any
|
|
159
|
+
* consent snapshot including implicit. Default: true.
|
|
152
160
|
*/
|
|
153
161
|
explicitOnly?: boolean;
|
|
154
162
|
/**
|
|
@@ -209,8 +217,10 @@ type index_Mapping = Mapping;
|
|
|
209
217
|
type index_Push = Push;
|
|
210
218
|
type index_Settings = Settings;
|
|
211
219
|
type index_Types = Types;
|
|
220
|
+
type index_UsercentricsConsentType = UsercentricsConsentType;
|
|
212
221
|
type index_UsercentricsEventDetail = UsercentricsEventDetail;
|
|
213
222
|
type index_UsercentricsV2Api = UsercentricsV2Api;
|
|
223
|
+
type index_UsercentricsV2ConsentHistoryEntry = UsercentricsV2ConsentHistoryEntry;
|
|
214
224
|
type index_UsercentricsV2Service = UsercentricsV2Service;
|
|
215
225
|
type index_UsercentricsV3Api = UsercentricsV3Api;
|
|
216
226
|
type index_UsercentricsV3CategoryData = UsercentricsV3CategoryData;
|
|
@@ -219,7 +229,7 @@ type index_UsercentricsV3CmpEventDetail = UsercentricsV3CmpEventDetail;
|
|
|
219
229
|
type index_UsercentricsV3ConsentData = UsercentricsV3ConsentData;
|
|
220
230
|
type index_UsercentricsV3ConsentDetails = UsercentricsV3ConsentDetails;
|
|
221
231
|
declare namespace index {
|
|
222
|
-
export type { index_Config as Config, index_Env as Env, index_InitSettings as InitSettings, index_Mapping as Mapping, index_Push as Push, index_Settings as Settings, index_Types as Types, index_UsercentricsEventDetail as UsercentricsEventDetail, index_UsercentricsV2Api as UsercentricsV2Api, index_UsercentricsV2Service as UsercentricsV2Service, index_UsercentricsV3Api as UsercentricsV3Api, index_UsercentricsV3CategoryData as UsercentricsV3CategoryData, index_UsercentricsV3CategoryState as UsercentricsV3CategoryState, index_UsercentricsV3CmpEventDetail as UsercentricsV3CmpEventDetail, index_UsercentricsV3ConsentData as UsercentricsV3ConsentData, index_UsercentricsV3ConsentDetails as UsercentricsV3ConsentDetails };
|
|
232
|
+
export type { index_Config as Config, index_Env as Env, index_InitSettings as InitSettings, index_Mapping as Mapping, index_Push as Push, index_Settings as Settings, index_Types as Types, index_UsercentricsConsentType as UsercentricsConsentType, index_UsercentricsEventDetail as UsercentricsEventDetail, index_UsercentricsV2Api as UsercentricsV2Api, index_UsercentricsV2ConsentHistoryEntry as UsercentricsV2ConsentHistoryEntry, index_UsercentricsV2Service as UsercentricsV2Service, index_UsercentricsV3Api as UsercentricsV3Api, index_UsercentricsV3CategoryData as UsercentricsV3CategoryData, index_UsercentricsV3CategoryState as UsercentricsV3CategoryState, index_UsercentricsV3CmpEventDetail as UsercentricsV3CmpEventDetail, index_UsercentricsV3ConsentData as UsercentricsV3ConsentData, index_UsercentricsV3ConsentDetails as UsercentricsV3ConsentDetails };
|
|
223
233
|
}
|
|
224
234
|
|
|
225
235
|
/**
|
|
@@ -240,7 +250,6 @@ declare namespace index {
|
|
|
240
250
|
* code: sourceUsercentrics,
|
|
241
251
|
* config: {
|
|
242
252
|
* settings: {
|
|
243
|
-
* eventName: 'ucEvent',
|
|
244
253
|
* categoryMap: {
|
|
245
254
|
* essential: 'functional',
|
|
246
255
|
* functional: 'functional',
|
package/dist/index.d.ts
CHANGED
|
@@ -29,9 +29,20 @@ interface UsercentricsEventDetail {
|
|
|
29
29
|
declare global {
|
|
30
30
|
interface WindowEventMap {
|
|
31
31
|
ucEvent: CustomEvent<UsercentricsEventDetail>;
|
|
32
|
+
UC_UI_INITIALIZED: Event;
|
|
32
33
|
UC_UI_CMP_EVENT: CustomEvent<UsercentricsV3CmpEventDetail>;
|
|
33
34
|
}
|
|
34
35
|
}
|
|
36
|
+
/** Usercentrics CONSENT_TYPE values (history entry type / V3 consent type). */
|
|
37
|
+
type UsercentricsConsentType = 'explicit' | 'implicit';
|
|
38
|
+
/** A single entry in a V2 service's consent history (getServicesBaseInfo). */
|
|
39
|
+
interface UsercentricsV2ConsentHistoryEntry {
|
|
40
|
+
type: UsercentricsConsentType;
|
|
41
|
+
status: boolean;
|
|
42
|
+
/** CONSENT_ACTION, e.g. 'onAcceptAllServices' | 'onInitialPageLoad'. Not read for the gate. */
|
|
43
|
+
action?: string;
|
|
44
|
+
timestamp?: number;
|
|
45
|
+
}
|
|
35
46
|
/**
|
|
36
47
|
* Usercentrics V2 service info shape returned by `UC_UI.getServicesBaseInfo()`.
|
|
37
48
|
* Only the fields we use are typed - minimal surface, not a full V2 API mirror.
|
|
@@ -39,9 +50,13 @@ declare global {
|
|
|
39
50
|
interface UsercentricsV2Service {
|
|
40
51
|
/** Category slug: 'essential' | 'functional' | 'marketing' | custom */
|
|
41
52
|
categorySlug: string;
|
|
53
|
+
/** Service display name (used for service-level consent keys) */
|
|
54
|
+
name?: string;
|
|
42
55
|
/** Consent state for this service */
|
|
43
56
|
consent: {
|
|
44
57
|
status: boolean;
|
|
58
|
+
/** Consent decision history; an 'explicit' entry proves a real user decision. */
|
|
59
|
+
history?: UsercentricsV2ConsentHistoryEntry[];
|
|
45
60
|
};
|
|
46
61
|
}
|
|
47
62
|
/**
|
|
@@ -53,6 +68,7 @@ interface UsercentricsV2Service {
|
|
|
53
68
|
interface UsercentricsV2Api {
|
|
54
69
|
isInitialized?: () => boolean;
|
|
55
70
|
getServicesBaseInfo?: () => UsercentricsV2Service[];
|
|
71
|
+
getServicesFullInfo?: () => Promise<UsercentricsV2Service[]>;
|
|
56
72
|
areAllConsentsAccepted?: () => boolean;
|
|
57
73
|
}
|
|
58
74
|
/**
|
|
@@ -99,8 +115,9 @@ interface UsercentricsV3Api {
|
|
|
99
115
|
* `source: 'CMP'` + a decision `type` tells us a user action has been taken.
|
|
100
116
|
*/
|
|
101
117
|
interface UsercentricsV3CmpEventDetail {
|
|
102
|
-
source?: string;
|
|
118
|
+
source?: 'none' | 'button' | 'first' | 'second' | 'embeddings' | '__ucCmp' | string;
|
|
103
119
|
type?: string;
|
|
120
|
+
abTestVariant?: string;
|
|
104
121
|
}
|
|
105
122
|
declare global {
|
|
106
123
|
interface Window {
|
|
@@ -122,14 +139,6 @@ declare global {
|
|
|
122
139
|
* Settings for Usercentrics source
|
|
123
140
|
*/
|
|
124
141
|
interface Settings {
|
|
125
|
-
/**
|
|
126
|
-
* Window event name to listen for.
|
|
127
|
-
* Configured in Usercentrics admin under Implementation > Data Layer & Events.
|
|
128
|
-
* Can also be set to 'UC_SDK_EVENT' for the built-in Browser SDK event.
|
|
129
|
-
*
|
|
130
|
-
* Default: 'ucEvent'
|
|
131
|
-
*/
|
|
132
|
-
eventName?: string;
|
|
133
142
|
/**
|
|
134
143
|
* Map Usercentrics categories to walkerOS consent groups.
|
|
135
144
|
* Keys: Usercentrics category names (from ucCategory)
|
|
@@ -144,11 +153,10 @@ interface Settings {
|
|
|
144
153
|
*/
|
|
145
154
|
categoryMap?: Record<string, string>;
|
|
146
155
|
/**
|
|
147
|
-
* Only
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
* Default: true
|
|
156
|
+
* Only publish when the user has actively decided. V3: consent.type ===
|
|
157
|
+
* EXPLICIT. V2: an EXPLICIT entry exists in service consent history.
|
|
158
|
+
* Implicit/default page-load states are suppressed. Set false to publish any
|
|
159
|
+
* consent snapshot including implicit. Default: true.
|
|
152
160
|
*/
|
|
153
161
|
explicitOnly?: boolean;
|
|
154
162
|
/**
|
|
@@ -209,8 +217,10 @@ type index_Mapping = Mapping;
|
|
|
209
217
|
type index_Push = Push;
|
|
210
218
|
type index_Settings = Settings;
|
|
211
219
|
type index_Types = Types;
|
|
220
|
+
type index_UsercentricsConsentType = UsercentricsConsentType;
|
|
212
221
|
type index_UsercentricsEventDetail = UsercentricsEventDetail;
|
|
213
222
|
type index_UsercentricsV2Api = UsercentricsV2Api;
|
|
223
|
+
type index_UsercentricsV2ConsentHistoryEntry = UsercentricsV2ConsentHistoryEntry;
|
|
214
224
|
type index_UsercentricsV2Service = UsercentricsV2Service;
|
|
215
225
|
type index_UsercentricsV3Api = UsercentricsV3Api;
|
|
216
226
|
type index_UsercentricsV3CategoryData = UsercentricsV3CategoryData;
|
|
@@ -219,7 +229,7 @@ type index_UsercentricsV3CmpEventDetail = UsercentricsV3CmpEventDetail;
|
|
|
219
229
|
type index_UsercentricsV3ConsentData = UsercentricsV3ConsentData;
|
|
220
230
|
type index_UsercentricsV3ConsentDetails = UsercentricsV3ConsentDetails;
|
|
221
231
|
declare namespace index {
|
|
222
|
-
export type { index_Config as Config, index_Env as Env, index_InitSettings as InitSettings, index_Mapping as Mapping, index_Push as Push, index_Settings as Settings, index_Types as Types, index_UsercentricsEventDetail as UsercentricsEventDetail, index_UsercentricsV2Api as UsercentricsV2Api, index_UsercentricsV2Service as UsercentricsV2Service, index_UsercentricsV3Api as UsercentricsV3Api, index_UsercentricsV3CategoryData as UsercentricsV3CategoryData, index_UsercentricsV3CategoryState as UsercentricsV3CategoryState, index_UsercentricsV3CmpEventDetail as UsercentricsV3CmpEventDetail, index_UsercentricsV3ConsentData as UsercentricsV3ConsentData, index_UsercentricsV3ConsentDetails as UsercentricsV3ConsentDetails };
|
|
232
|
+
export type { index_Config as Config, index_Env as Env, index_InitSettings as InitSettings, index_Mapping as Mapping, index_Push as Push, index_Settings as Settings, index_Types as Types, index_UsercentricsConsentType as UsercentricsConsentType, index_UsercentricsEventDetail as UsercentricsEventDetail, index_UsercentricsV2Api as UsercentricsV2Api, index_UsercentricsV2ConsentHistoryEntry as UsercentricsV2ConsentHistoryEntry, index_UsercentricsV2Service as UsercentricsV2Service, index_UsercentricsV3Api as UsercentricsV3Api, index_UsercentricsV3CategoryData as UsercentricsV3CategoryData, index_UsercentricsV3CategoryState as UsercentricsV3CategoryState, index_UsercentricsV3CmpEventDetail as UsercentricsV3CmpEventDetail, index_UsercentricsV3ConsentData as UsercentricsV3ConsentData, index_UsercentricsV3ConsentDetails as UsercentricsV3ConsentDetails };
|
|
223
233
|
}
|
|
224
234
|
|
|
225
235
|
/**
|
|
@@ -240,7 +250,6 @@ declare namespace index {
|
|
|
240
250
|
* code: sourceUsercentrics,
|
|
241
251
|
* config: {
|
|
242
252
|
* settings: {
|
|
243
|
-
* eventName: 'ucEvent',
|
|
244
253
|
* categoryMap: {
|
|
245
254
|
* essential: 'functional',
|
|
246
255
|
* functional: 'functional',
|
package/dist/index.es5.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";function _array_like_to_array(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function _array_with_holes(e){if(Array.isArray(e))return e}function asyncGeneratorStep(e,t,n,r,o,a,i){try{var u=e[a](i),
|
|
1
|
+
"use strict";function _array_like_to_array(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function _array_with_holes(e){if(Array.isArray(e))return e}function asyncGeneratorStep(e,t,n,r,o,a,i){try{var u=e[a](i),c=u.value}catch(e){return void n(e)}u.done?t(c):Promise.resolve(c).then(r,o)}function _async_to_generator(e){return function(){var t=this,n=arguments;return new Promise(function(r,o){var a=e.apply(t,n);function i(e){asyncGeneratorStep(a,r,o,i,u,"next",e)}function u(e){asyncGeneratorStep(a,r,o,i,u,"throw",e)}i(void 0)})}}function _iterable_to_array_limit(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,a=[],i=!0,u=!1;try{for(n=n.call(e);!(i=(r=n.next()).done)&&(a.push(r.value),!t||a.length!==t);i=!0);}catch(e){u=!0,o=e}finally{try{i||null==n.return||n.return()}finally{if(u)throw o}}return a}}function _non_iterable_rest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _sliced_to_array(e,t){return _array_with_holes(e)||_iterable_to_array_limit(e,t)||_unsupported_iterable_to_array(e,t)||_non_iterable_rest()}function _type_of(e){return e&&"undefined"!=typeof Symbol&&e.constructor===Symbol?"symbol":typeof e}function _unsupported_iterable_to_array(e,t){if(e){if("string"==typeof e)return _array_like_to_array(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(n):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_array_like_to_array(e,t):void 0}}function _ts_generator(e,t){var n,r,o,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},i=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),u=Object.defineProperty;return u(i,"next",{value:c(0)}),u(i,"throw",{value:c(1)}),u(i,"return",{value:c(2)}),"function"==typeof Symbol&&u(i,Symbol.iterator,{value:function(){return this}}),i;function c(u){return function(c){return function(u){if(n)throw new TypeError("Generator is already executing.");for(;i&&(i=0,u[0]&&(a=0)),a;)try{if(n=1,r&&(o=2&u[0]?r.return:u[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,u[1])).done)return o;switch(r=0,o&&(u=[2&u[0],o.value]),u[0]){case 0:case 1:o=u;break;case 4:return a.label++,{value:u[1],done:!1};case 5:a.label++,r=u[1],u=[0];continue;case 7:u=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==u[0]&&2!==u[0])){a=0;continue}if(3===u[0]&&(!o||u[1]>o[0]&&u[1]<o[3])){a.label=u[1];break}if(6===u[0]&&a.label<o[1]){a.label=o[1],o=u;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(u);break}o[2]&&a.ops.pop(),a.trys.pop();continue}u=t.call(e,a)}catch(e){u=[6,e],r=0}finally{n=o=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,c])}}}var SourceUsercentrics=function(){var e=function(e,t,n){e[t]=(void 0===e[t]||Boolean(e[t]))&&n},t=function(t,n){var r,o={};return t.ucCategory&&(r=t.ucCategory,Object.values(r).every(function(e){return"boolean"==typeof e}))?Object.entries(t.ucCategory).forEach(function(t){var r,a,i=_sliced_to_array(t,2),u=i[0],c=i[1];if("boolean"==typeof c){var l=null!==(r=null===(a=n.categoryMap)||void 0===a?void 0:a[u])&&void 0!==r?r:u;e(o,l,c)}}):(t.ucCategory&&Object.entries(t.ucCategory).forEach(function(t){var r=_sliced_to_array(t,2),a=r[0],i=r[1];if("boolean"==typeof i){var u,c,l=null!==(u=null===(c=n.categoryMap)||void 0===c?void 0:c[a])&&void 0!==u?u:a;e(o,l,i)}}),Object.entries(t).forEach(function(t){var n=_sliced_to_array(t,2),r=n[0],a=n[1];if(!_.includes(r)&&"boolean"==typeof a){var i=r.toLowerCase().replace(/ /g,"_");e(o,i,a)}})),o},n=function(e){var t={};return e.forEach(function(e){var n,r,o=e.categorySlug,a=null!==(n=null===(r=e.consent)||void 0===r?void 0:r.status)&&void 0!==n&&n;t[o]=(void 0===t[o]||t[o])&&a}),t},r=function(e){return e.some(function(e){var t;return(null!==(t=e.consent.history)&&void 0!==t?t:[]).some(function(e){var t;return"explicit"===(null===(t=e.type)||void 0===t?void 0:t.toLowerCase())})})},o=function(e){var o=e.window,a=e.elb,i=e.settings,u=e.logger,c=function(){var e,c=o.UC_UI;if((null==c||null===(e=c.isInitialized)||void 0===e?void 0:e.call(c))&&c.getServicesBaseInfo){var l=c.getServicesBaseInfo();if(l.length){var s=function(e){var t={event:"consent_status",type:r(e)?"explicit":"implicit",ucCategory:n(e)};return e.forEach(function(e){e.name&&(t[e.name]=e.consent.status)}),t}(l);if(u.debug("consent read",s),!i.explicitOnly||"explicit"===s.type){var f=t(s,i);Object.keys(f).length>0&&a("walker consent",f)}}}},l=function(){return c()},s=function(e){var t=e.detail;(null==t?void 0:t.type)&&v.has(t.type)&&c()};return o.addEventListener("UC_UI_INITIALIZED",l),o.addEventListener("UC_UI_CMP_EVENT",s),c(),function(){o.removeEventListener("UC_UI_INITIALIZED",l),o.removeEventListener("UC_UI_CMP_EVENT",s)}},a=function(e){return _async_to_generator(function(){var n,r,o,a,i,u,c,l,s,f,_;return _ts_generator(this,function(v){switch(v.label){case 0:if(r=e.window,o=e.elb,a=e.settings,i=e.logger,u=null!==(n=a.v3EventName)&&void 0!==n?n:y,c=function(e){return _async_to_generator(function(){var n,r,u;return _ts_generator(this,function(c){switch(c.label){case 0:return[4,e.getConsentDetails()];case 1:return n=c.sent(),r=function(e){var t={};return Object.entries(e.categories).forEach(function(e){var n=_sliced_to_array(e,2),r=n[0],o=n[1];t[r]="ALL_ACCEPTED"===o.state}),{event:"consent_status",type:"EXPLICIT"===e.consent.type?"explicit":"implicit",ucCategory:t}}(n),i.debug("event received",r),a.explicitOnly&&"explicit"!==r.type?[2]:(u=t(r,a),Object.keys(u).length>0&&o("walker consent",u),[2])}})})()},l=function(e){var t=r.__ucCmp;if(t){var n=e.detail;(null==n?void 0:n.type)&&p.has(n.type)&&c(t).catch(function(){})}},r.addEventListener(u,l),s=function(){var e=r.__ucCmp;e&&c(e).catch(function(){})},r.addEventListener("UC_UI_INITIALIZED",s),!(f=r.__ucCmp))return[3,6];v.label=1;case 1:return v.trys.push([1,5,,6]),[4,f.isInitialized()];case 2:return v.sent()?[4,c(f)]:[3,4];case 3:v.sent(),v.label=4;case 4:return[3,6];case 5:return _=v.sent(),i.warn("v3 static consent read failed",_),[3,6];case 6:return[2,function(){r.removeEventListener(u,l),r.removeEventListener("UC_UI_INITIALIZED",s)}]}})})()},i=Object.defineProperty,u=Object.getOwnPropertyDescriptor,c=Object.getOwnPropertyNames,l=Object.prototype.hasOwnProperty,s={};!function(e,t){for(var n in t)i(e,n,{get:t[n],enumerable:!0})}(s,{SourceUsercentrics:function(){return d},default:function(){return g},sourceUsercentrics:function(){return b}});var f,_=["action","event","type","ucCategory"],v=new Set(["ACCEPT_ALL","DENY_ALL","SAVE"]),y="UC_UI_CMP_EVENT",p=new Set(["ACCEPT_ALL","DENY_ALL","SAVE"]),d={},b=function(e){return _async_to_generator(function(){var t,n,r,i,u,c,l,s,f,_,v,y,p,d,b,g,h;return _ts_generator(this,function(m){return _=e.config,v=e.env,y=v.elb,p=v.logger,d=null!==(t=v.window)&&void 0!==t?t:void 0!==globalThis.window?globalThis.window:void 0,b={categoryMap:null!==(n=null==_||null===(c=_.settings)||void 0===c?void 0:c.categoryMap)&&void 0!==n?n:{},explicitOnly:null===(r=null==_||null===(l=_.settings)||void 0===l?void 0:l.explicitOnly)||void 0===r||r,apiVersion:null!==(i=null==_||null===(s=_.settings)||void 0===s?void 0:s.apiVersion)&&void 0!==i?i:"auto",v3EventName:null!==(u=null==_||null===(f=_.settings)||void 0===f?void 0:f.v3EventName)&&void 0!==u?u:"UC_UI_CMP_EVENT"},g=[],h=function(){return _async_to_generator(function(){var e,t,n,r,i,u;return _ts_generator(this,function(c){switch(c.label){case 0:return d?(t={window:d,elb:y,settings:b,logger:p},"v2"!==(n=null!==(e=b.apiVersion)&&void 0!==e?e:"auto")?[3,1]:(g.push(o(t)),[3,8])):[2];case 1:return"v3"!==n?[3,3]:(r=g.push,[4,a(t)]);case 2:return r.apply(g,[c.sent()]),[3,8];case 3:return d.__ucCmp?(i=g.push,[4,a(t)]):[3,5];case 4:return i.apply(g,[c.sent()]),[3,8];case 5:return d.UC_UI?(g.push(o(t)),[3,8]):[3,6];case 6:return g.push(o(t)),u=g.push,[4,a(t)];case 7:u.apply(g,[c.sent()]),c.label=8;case 8:return[2]}})})()},[2,{type:"usercentrics",config:{settings:b},push:y,init:h,destroy:function(){return _async_to_generator(function(){return _ts_generator(this,function(e){return g.forEach(function(e){return e()}),[2]})})()}}]})})()},g=b;return f=s,function(e,t,n,r){if(t&&"object"===(void 0===t?"undefined":_type_of(t))||"function"==typeof t){var o=!0,a=!1,s=void 0;try{for(var f,_=function(){var o=f.value;l.call(e,o)||o===n||i(e,o,{get:function(){return t[o]},enumerable:!(r=u(t,o))||r.enumerable})},v=c(t)[Symbol.iterator]();!(o=(f=v.next()).done);o=!0)_()}catch(e){a=!0,s=e}finally{try{o||null==v.return||v.return()}finally{if(a)throw s}}}return e}(i({},"__esModule",{value:!0}),f)}();
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,
|
|
1
|
+
"use strict";var e,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,r=Object.prototype.hasOwnProperty,i={};((e,n)=>{for(var o in n)t(e,o,{get:n[o],enumerable:!0})})(i,{SourceUsercentrics:()=>g,default:()=>_,sourceUsercentrics:()=>f}),module.exports=(e=i,((e,i,c,s)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let a of o(i))r.call(e,a)||a===c||t(e,a,{get:()=>i[a],enumerable:!(s=n(i,a))||s.enumerable});return e})(t({},"__esModule",{value:!0}),e));var c=["action","event","type","ucCategory"];function s(e,t,n){e[t]=(void 0===e[t]||Boolean(e[t]))&&n}function a(e,t){const n={};var o;return e.ucCategory&&(o=e.ucCategory,Object.values(o).every(e=>"boolean"==typeof e))?Object.entries(e.ucCategory).forEach(([e,o])=>{var r,i;if("boolean"!=typeof o)return;const c=null!=(i=null==(r=t.categoryMap)?void 0:r[e])?i:e;s(n,c,o)}):(e.ucCategory&&Object.entries(e.ucCategory).forEach(([e,o])=>{var r,i;if("boolean"==typeof o){const c=null!=(i=null==(r=t.categoryMap)?void 0:r[e])?i:e;s(n,c,o)}}),Object.entries(e).forEach(([e,t])=>{if(c.includes(e))return;if("boolean"!=typeof t)return;const o=e.toLowerCase().replace(/ /g,"_");s(n,o,t)})),n}var l=new Set(["ACCEPT_ALL","DENY_ALL","SAVE"]);function u(e){const t={};return e.forEach(e=>{var n,o;const r=e.categorySlug,i=null!=(o=null==(n=e.consent)?void 0:n.status)&&o;t[r]=(void 0===t[r]||t[r])&&i}),t}function v(e){return e.some(e=>{var t;return(null!=(t=e.consent.history)?t:[]).some(e=>{var t;return"explicit"===(null==(t=e.type)?void 0:t.toLowerCase())})})}function p(e){const{window:t,elb:n,settings:o,logger:r}=e,i=()=>{var e;const i=t.UC_UI;if(!(null==(e=null==i?void 0:i.isInitialized)?void 0:e.call(i))||!i.getServicesBaseInfo)return;const c=i.getServicesBaseInfo();if(!c.length)return;const s=function(e){const t={event:"consent_status",type:v(e)?"explicit":"implicit",ucCategory:u(e)};return e.forEach(e=>{e.name&&(t[e.name]=e.consent.status)}),t}(c);if(r.debug("consent read",s),o.explicitOnly&&"explicit"!==s.type)return;const l=a(s,o);Object.keys(l).length>0&&n("walker consent",l)},c=()=>i(),s=e=>{const t=e.detail;(null==t?void 0:t.type)&&l.has(t.type)&&i()};return t.addEventListener("UC_UI_INITIALIZED",c),t.addEventListener("UC_UI_CMP_EVENT",s),i(),()=>{t.removeEventListener("UC_UI_INITIALIZED",c),t.removeEventListener("UC_UI_CMP_EVENT",s)}}var y=new Set(["ACCEPT_ALL","DENY_ALL","SAVE"]);async function d(e){var t;const{window:n,elb:o,settings:r,logger:i}=e,c=null!=(t=r.v3EventName)?t:"UC_UI_CMP_EVENT",s=async e=>{const t=function(e){const t={};return Object.entries(e.categories).forEach(([e,n])=>{t[e]="ALL_ACCEPTED"===n.state}),{event:"consent_status",type:"EXPLICIT"===e.consent.type?"explicit":"implicit",ucCategory:t}}(await e.getConsentDetails());if(i.debug("event received",t),r.explicitOnly&&"explicit"!==t.type)return;const n=a(t,r);Object.keys(n).length>0&&o("walker consent",n)},l=e=>{const t=n.__ucCmp;if(!t)return;const o=e.detail;(null==o?void 0:o.type)&&y.has(o.type)&&s(t).catch(()=>{})};n.addEventListener(c,l);const u=()=>{const e=n.__ucCmp;e&&s(e).catch(()=>{})};n.addEventListener("UC_UI_INITIALIZED",u);const v=n.__ucCmp;if(v)try{await v.isInitialized()&&await s(v)}catch(e){i.warn("v3 static consent read failed",e)}return()=>{n.removeEventListener(c,l),n.removeEventListener("UC_UI_INITIALIZED",u)}}var g={},f=async e=>{var t,n,o,r,i,c,s,a,l;const{config:u,env:v}=e,{elb:y,logger:g}=v,f=null!=(t=v.window)?t:void 0!==globalThis.window?globalThis.window:void 0,_={categoryMap:null!=(o=null==(n=null==u?void 0:u.settings)?void 0:n.categoryMap)?o:{},explicitOnly:null==(i=null==(r=null==u?void 0:u.settings)?void 0:r.explicitOnly)||i,apiVersion:null!=(s=null==(c=null==u?void 0:u.settings)?void 0:c.apiVersion)?s:"auto",v3EventName:null!=(l=null==(a=null==u?void 0:u.settings)?void 0:a.v3EventName)?l:"UC_UI_CMP_EVENT"},E=[];return{type:"usercentrics",config:{settings:_},push:y,init:async()=>{var e;if(!f)return;const t={window:f,elb:y,settings:_,logger:g},n=null!=(e=_.apiVersion)?e:"auto";"v2"===n?E.push(p(t)):"v3"===n||f.__ucCmp?E.push(await d(t)):f.UC_UI?E.push(p(t)):(E.push(p(t)),E.push(await d(t)))},destroy:async()=>{E.forEach(e=>e())}}},_=f;//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/lib/parseConsent.ts","../src/lib/v2.ts","../src/lib/v3.ts","../src/types/index.ts"],"sourcesContent":["import type { Source } from '@walkeros/core';\nimport type { Types, Settings } from './types';\nimport { setupV2Adapter } from './lib/v2';\nimport { setupV3Adapter } from './lib/v3';\n\n// Export types for external usage\nexport * as SourceUsercentrics from './types';\n\n/**\n * Usercentrics consent management source for walkerOS.\n *\n * Listens to Usercentrics CMP events and translates consent states to\n * walkerOS consent commands. Supports both the legacy V2 API\n * (`window.UC_UI` + `ucEvent`) and the current V3 API\n * (`window.__ucCmp` + `UC_UI_CMP_EVENT`).\n *\n * @example\n * ```typescript\n * import { sourceUsercentrics } from '@walkeros/web-source-cmp-usercentrics';\n *\n * await startFlow({\n * sources: {\n * consent: {\n * code: sourceUsercentrics,\n * config: {\n * settings: {\n * eventName: 'ucEvent',\n * categoryMap: {\n * essential: 'functional',\n * functional: 'functional',\n * marketing: 'marketing',\n * },\n * },\n * },\n * },\n * },\n * });\n * ```\n */\nexport const sourceUsercentrics: Source.Init<Types> = async (context) => {\n const { config, env } = context;\n const { elb, logger } = env;\n\n // Resolve window with fallback to globalThis\n const actualWindow =\n env.window ??\n (typeof globalThis.window !== 'undefined' ? globalThis.window : undefined);\n\n // Merge user settings with defaults so adapters always see a fully-resolved Settings\n const settings: Settings = {\n eventName: config?.settings?.eventName ?? 'ucEvent',\n categoryMap: config?.settings?.categoryMap ?? {},\n explicitOnly: config?.settings?.explicitOnly ?? true,\n apiVersion: config?.settings?.apiVersion ?? 'auto',\n v3EventName: config?.settings?.v3EventName ?? 'UC_UI_CMP_EVENT',\n };\n\n const fullConfig: Source.Config<Types> = { settings };\n const cleanups: Array<() => void> = [];\n\n // Attach the CMP listeners and perform the static consent read. Deferred to\n // init() (Pass 2 of initSources) so the factory (Pass 1) stays side-effect\n // free: no listener registration and, critically, no `elb('walker consent')`\n // emit during construction. Emitting from the factory races source merge\n // order and can leave a later `require:[\"consent\"]` source parked.\n const init = async (): Promise<void> => {\n if (!actualWindow) return;\n\n const adapterCtx = { window: actualWindow, elb, settings, logger };\n const apiVersion = settings.apiVersion ?? 'auto';\n\n if (apiVersion === 'v2') {\n cleanups.push(setupV2Adapter(adapterCtx));\n } else if (apiVersion === 'v3') {\n cleanups.push(await setupV3Adapter(adapterCtx));\n } else {\n // auto: detect which API is present\n if (actualWindow.__ucCmp) {\n cleanups.push(await setupV3Adapter(adapterCtx));\n } else if (actualWindow.UC_UI) {\n cleanups.push(setupV2Adapter(adapterCtx));\n } else {\n // Neither loaded yet — attach both listeners so whichever loads later is caught.\n cleanups.push(setupV2Adapter(adapterCtx));\n cleanups.push(await setupV3Adapter(adapterCtx));\n }\n }\n };\n\n return {\n type: 'usercentrics',\n config: fullConfig,\n push: elb,\n init,\n destroy: async () => {\n cleanups.forEach((fn) => fn());\n },\n };\n};\n\nexport default sourceUsercentrics;\n","import type { WalkerOS } from '@walkeros/core';\nimport type { UsercentricsEventDetail, Settings } from '../types';\n\n/** Reserved keys in event.detail that are not service names */\nexport const RESERVED_KEYS = ['action', 'event', 'type', 'ucCategory'];\n\n/**\n * Determine if ucCategory represents group-level consent.\n * Group-level: all values are booleans.\n * Service-level: some values are non-boolean (e.g., 'partial').\n */\nexport function isGroupLevel(\n ucCategory: Record<string, boolean | unknown>,\n): boolean {\n return Object.values(ucCategory).every((val) => typeof val === 'boolean');\n}\n\n/**\n * Merge an incoming consent signal into the accumulating state using strict\n * AND semantics: absent key initialises from the incoming value; present key\n * becomes `true` only if both existing and incoming are `true`. Any single\n * `false` anywhere in the merge chain revokes consent for that key.\n *\n * This matches the consent rule of thumb: any deny signal denies. Permissive\n * (OR) and \"last-wins\" semantics are both unsafe for a privacy primitive.\n */\nfunction mergeConsent(\n state: WalkerOS.Consent,\n key: string,\n value: boolean,\n): void {\n state[key] = state[key] === undefined ? value : Boolean(state[key]) && value;\n}\n\n/**\n * Parse consent from Usercentrics event detail.\n *\n * Group-level: ucCategory values are all booleans → use them directly.\n * Service-level: ucCategory has non-booleans → mix boolean ucCategory entries\n * with top-level service keys from event.detail.\n *\n * categoryMap is applied in both modes to ucCategory boolean entries.\n * Strict AND: if multiple source categories map to the same target group,\n * the target is `true` only when ALL contributing sources are `true`.\n */\nexport function parseConsent(\n detail: UsercentricsEventDetail,\n settings: Settings,\n): WalkerOS.Consent {\n const state: WalkerOS.Consent = {};\n\n if (detail.ucCategory && isGroupLevel(detail.ucCategory)) {\n Object.entries(detail.ucCategory).forEach(([category, value]) => {\n if (typeof value !== 'boolean') return;\n const mapped = settings.categoryMap?.[category] ?? category;\n mergeConsent(state, mapped, value);\n });\n } else {\n if (detail.ucCategory) {\n Object.entries(detail.ucCategory).forEach(([key, value]) => {\n if (typeof value === 'boolean') {\n const mapped = settings.categoryMap?.[key] ?? key;\n mergeConsent(state, mapped, value);\n }\n });\n }\n\n Object.entries(detail).forEach(([key, value]) => {\n if (RESERVED_KEYS.includes(key)) return;\n if (typeof value !== 'boolean') return;\n const normalized = key.toLowerCase().replace(/ /g, '_');\n mergeConsent(state, normalized, value);\n });\n }\n\n return state;\n}\n","import type { Elb, Logger } from '@walkeros/core';\nimport type {\n Settings,\n UsercentricsEventDetail,\n UsercentricsV2Service,\n} from '../types';\nimport { parseConsent } from './parseConsent';\n\nexport interface V2AdapterContext {\n window: Window & typeof globalThis;\n elb: Elb.Fn;\n settings: Settings;\n logger: Logger.Instance;\n}\n\n/**\n * Aggregate V2 service array into a group-level ucCategory object using strict\n * AND logic. A category is `true` only if EVERY service in that category is\n * accepted. Any single denied service denies the whole category — this\n * matches the consent rule of thumb: any deny signal denies.\n */\nfunction aggregateByCategory(\n services: UsercentricsV2Service[],\n): Record<string, boolean> {\n const categories: Record<string, boolean> = {};\n services.forEach((service) => {\n const category = service.categorySlug;\n const status = service.consent?.status ?? false;\n categories[category] =\n categories[category] === undefined\n ? status\n : categories[category] && status;\n });\n return categories;\n}\n\n/**\n * Build a synthetic UsercentricsEventDetail from the V2 static API.\n * Marked as 'implicit' because UC_UI.isInitialized() === true does NOT prove\n * the read was user-initiated — it only proves the SDK has finished loading.\n * With settings.explicitOnly = true (the default), consumers correctly drop\n * this detail. Set explicitOnly = false to surface the static snapshot.\n */\nfunction buildDetailFromStatic(\n services: UsercentricsV2Service[],\n): UsercentricsEventDetail {\n return {\n event: 'consent_status',\n type: 'implicit',\n ucCategory: aggregateByCategory(services),\n };\n}\n\n/**\n * Set up the V2 adapter: listens on the configured event AND performs a\n * static read if UC_UI is already initialized.\n *\n * Returns a cleanup function that removes the event listener.\n */\nexport function setupV2Adapter(ctx: V2AdapterContext): () => void {\n const { window: win, elb, settings, logger } = ctx;\n const eventName = settings.eventName ?? 'ucEvent';\n\n const handleDetail = (detail: UsercentricsEventDetail) => {\n logger.debug('event received', detail);\n\n if (detail.event !== 'consent_status') return;\n if (settings.explicitOnly && detail.type?.toLowerCase() !== 'explicit')\n return;\n\n const state = parseConsent(detail, settings);\n if (Object.keys(state).length > 0) {\n elb('walker consent', state);\n }\n };\n\n const listener = (e: Event) => {\n const custom = e as CustomEvent<UsercentricsEventDetail>;\n if (custom.detail) handleDetail(custom.detail);\n };\n win.addEventListener(eventName, listener);\n\n // Static check: if UC_UI is already initialized, read current consent now.\n const api = win.UC_UI;\n if (api?.isInitialized?.() && api.getServicesBaseInfo) {\n const services = api.getServicesBaseInfo();\n if (services.length > 0) {\n handleDetail(buildDetailFromStatic(services));\n }\n }\n\n return () => {\n win.removeEventListener(eventName, listener);\n };\n}\n","import type { Elb, Logger } from '@walkeros/core';\nimport type {\n Settings,\n UsercentricsEventDetail,\n UsercentricsV3Api,\n UsercentricsV3CategoryState,\n UsercentricsV3CmpEventDetail,\n UsercentricsV3ConsentDetails,\n} from '../types';\nimport { parseConsent } from './parseConsent';\n\nexport interface V3AdapterContext {\n window: Window & typeof globalThis;\n elb: Elb.Fn;\n settings: Settings;\n logger: Logger.Instance;\n}\n\nconst V3_DEFAULT_EVENT_NAME = 'UC_UI_CMP_EVENT';\n\n/**\n * V3 CMP event types that represent a user consent decision. Presentation\n * events like `CMP_SHOWN` or `UI_INITIALIZED` must NOT trigger a consent\n * publish — they carry no user decision.\n */\nconst V3_DECISION_TYPES: ReadonlySet<string> = new Set([\n 'ACCEPT_ALL',\n 'DENY_ALL',\n 'SAVE',\n]);\n\n/**\n * Map a V3 CategoryData.state value to a walkerOS boolean using strict\n * semantics: only fully-accepted categories are `true`. Any partial or\n * denied state (including future/unknown states) resolves to `false`.\n *\n * This matches the consent rule of thumb: any deny signal denies.\n */\nfunction categoryStateToBoolean(state: UsercentricsV3CategoryState): boolean {\n return state === 'ALL_ACCEPTED';\n}\n\n/**\n * Build a synthetic UsercentricsEventDetail from V3 ConsentDetails.\n * Translates V3's structured consent state into the shape parseConsent expects.\n */\nfunction buildDetailFromV3(\n details: UsercentricsV3ConsentDetails,\n): UsercentricsEventDetail {\n const ucCategory: Record<string, boolean> = {};\n Object.entries(details.categories).forEach(([slug, category]) => {\n ucCategory[slug] = categoryStateToBoolean(category.state);\n });\n\n return {\n event: 'consent_status',\n type: details.consent.type === 'EXPLICIT' ? 'explicit' : 'implicit',\n ucCategory,\n };\n}\n\n/**\n * Set up the V3 adapter: registers a listener on the V3 consent event AND\n * (if __ucCmp is already initialized) performs a static read.\n *\n * Both paths re-fetch getConsentDetails() because the event payload does\n * not include consent state.\n *\n * Returns a cleanup function that removes the event listener.\n */\nexport async function setupV3Adapter(\n ctx: V3AdapterContext,\n): Promise<() => void> {\n const { window: win, elb, settings, logger } = ctx;\n const eventName = settings.v3EventName ?? V3_DEFAULT_EVENT_NAME;\n\n const publishConsent = async (cmp: UsercentricsV3Api): Promise<void> => {\n const details = await cmp.getConsentDetails();\n const detail = buildDetailFromV3(details);\n logger.debug('event received', detail);\n\n if (settings.explicitOnly && detail.type !== 'explicit') return;\n\n const state = parseConsent(detail, settings);\n if (Object.keys(state).length > 0) {\n elb('walker consent', state);\n }\n };\n\n const listener = (event: Event): void => {\n const cmp = win.__ucCmp;\n if (!cmp) return;\n const custom = event as CustomEvent<UsercentricsV3CmpEventDetail>;\n const detail = custom.detail;\n // Filter to decision events only: the CMP emits a broad set of events\n // (CMP_SHOWN, UI_INITIALIZED, VIEW_CHANGED, …) on this bus. Without\n // filtering, every view toggle would re-publish consent.\n if (!detail || detail.source !== 'CMP') return;\n if (!detail.type || !V3_DECISION_TYPES.has(detail.type)) return;\n publishConsent(cmp).catch(() => {\n // Swallow — a failed V3 fetch should not break the page.\n });\n };\n win.addEventListener(eventName, listener);\n\n // Static check: if __ucCmp is already initialized, fetch now.\n // Wrapped in try/catch so transient API failures during setup don't\n // reject setupV3Adapter() and tear down the whole flow — the listener\n // stays registered and will pick up the next real event.\n const cmp = win.__ucCmp;\n if (cmp) {\n try {\n const initialized = await cmp.isInitialized();\n if (initialized) {\n await publishConsent(cmp);\n }\n } catch (err) {\n logger.warn('v3 static consent read failed', err);\n }\n }\n\n return () => {\n win.removeEventListener(eventName, listener);\n };\n}\n","import type { Source, Elb } from '@walkeros/core';\n\ndeclare module '@walkeros/core' {\n interface SourceMap {\n usercentrics: { type: 'usercentrics'; platform?: 'web' };\n }\n}\n\n/**\n * Usercentrics consent event detail structure.\n *\n * Fired as event.detail on the configured window event (e.g. 'ucEvent').\n * Contains both category-level (ucCategory) and service-level consent.\n */\nexport interface UsercentricsEventDetail {\n /** Always 'consent_status' for consent events */\n event: string;\n /** 'explicit' when user actively chose, 'implicit' for page-load defaults (casing may vary) */\n type: string;\n /** Action taken: 'onAcceptAllServices', 'onDenyAllServices', 'onUpdateServices' */\n action?: string;\n /** Category-level consent booleans (e.g. { marketing: true, functional: false }) */\n ucCategory?: Record<string, boolean | unknown>;\n /** Service-level consent as top-level keys (e.g. 'Google Analytics': true) */\n [service: string]: unknown;\n}\n\ndeclare global {\n interface WindowEventMap {\n ucEvent: CustomEvent<UsercentricsEventDetail>;\n UC_UI_CMP_EVENT: CustomEvent<UsercentricsV3CmpEventDetail>;\n }\n}\n\n/**\n * Usercentrics V2 service info shape returned by `UC_UI.getServicesBaseInfo()`.\n * Only the fields we use are typed - minimal surface, not a full V2 API mirror.\n */\nexport interface UsercentricsV2Service {\n /** Category slug: 'essential' | 'functional' | 'marketing' | custom */\n categorySlug: string;\n /** Consent state for this service */\n consent: {\n status: boolean;\n };\n}\n\n/**\n * Usercentrics V2 window API (`window.UC_UI`).\n *\n * Methods are synchronous (unlike V3). All methods are optional because\n * Usercentrics does not guarantee every deployment exposes every method.\n */\nexport interface UsercentricsV2Api {\n isInitialized?: () => boolean;\n getServicesBaseInfo?: () => UsercentricsV2Service[];\n areAllConsentsAccepted?: () => boolean;\n}\n\n/**\n * Usercentrics V3 category state. The SDK may add future states; we handle\n * unknowns conservatively as non-accepting.\n */\nexport type UsercentricsV3CategoryState =\n | 'ALL_ACCEPTED'\n | 'ALL_DENIED'\n | 'SOME_ACCEPTED'\n | 'NO_STATE'\n | string;\n\n/**\n * Minimal V3 CategoryData - only fields the adapter reads.\n */\nexport interface UsercentricsV3CategoryData {\n state: UsercentricsV3CategoryState;\n name: string;\n}\n\n/**\n * Minimal V3 ConsentData - only the `type` field is used to distinguish\n * explicit vs implicit consent. Other fields (status, version, etc.) exist on\n * the real SDK but are not read by this adapter.\n */\nexport interface UsercentricsV3ConsentData {\n type: 'EXPLICIT' | 'IMPLICIT' | string;\n}\n\n/**\n * Minimal V3 ConsentDetails - only the fields the adapter reads.\n * The real SDK also exposes `services`, but the adapter currently operates\n * at category level only.\n */\nexport interface UsercentricsV3ConsentDetails {\n consent: UsercentricsV3ConsentData;\n categories: Record<string, UsercentricsV3CategoryData>;\n}\n\n/**\n * Usercentrics V3 window API (`window.__ucCmp`).\n *\n * Only the methods this adapter calls are typed - the real SDK surface is\n * much wider but we intentionally keep this narrow.\n */\nexport interface UsercentricsV3Api {\n isInitialized: () => Promise<boolean>;\n getConsentDetails: () => Promise<UsercentricsV3ConsentDetails>;\n}\n\n/**\n * V3 CMP event detail. Fired on `UC_UI_CMP_EVENT` (or custom name).\n * `source: 'CMP'` + a decision `type` tells us a user action has been taken.\n */\nexport interface UsercentricsV3CmpEventDetail {\n source?: string;\n type?: string;\n}\n\ndeclare global {\n interface Window {\n /**\n * Usercentrics V2 CMP API. Attached once the V2 Browser SDK is\n * initialized. Optional because the SDK loads asynchronously - guard\n * with a truthiness check before access.\n */\n UC_UI?: UsercentricsV2Api;\n /**\n * Usercentrics V3 CMP API. Attached once the V3 Browser SDK is\n * initialized. Optional because the SDK loads asynchronously - guard\n * with a truthiness check before access.\n */\n __ucCmp?: UsercentricsV3Api;\n }\n}\n\n/**\n * Settings for Usercentrics source\n */\nexport interface Settings {\n /**\n * Window event name to listen for.\n * Configured in Usercentrics admin under Implementation > Data Layer & Events.\n * Can also be set to 'UC_SDK_EVENT' for the built-in Browser SDK event.\n *\n * Default: 'ucEvent'\n */\n eventName?: string;\n\n /**\n * Map Usercentrics categories to walkerOS consent groups.\n * Keys: Usercentrics category names (from ucCategory)\n * Values: walkerOS consent group names\n *\n * Applied in both group-level and service-level consent modes.\n * When multiple source categories map to the same group, strict AND logic\n * applies: ALL contributing source categories must be true for the target\n * group to be true. Any single false denies consent.\n *\n * Default: {} (pass through category names as-is)\n */\n categoryMap?: Record<string, string>;\n\n /**\n * Only process explicit consent (user made a choice).\n * When true: Ignores events where type !== 'explicit'\n * When false: Processes any consent_status event including implicit/defaults\n *\n * Default: true\n */\n explicitOnly?: boolean;\n\n /**\n * Which Usercentrics API to target.\n * - 'auto' (default): detect at init. If `window.__ucCmp` is present, use V3.\n * If only `window.UC_UI` is present, use V2. If neither is present yet,\n * register listeners for both so late-loading CMPs are still caught.\n * - 'v2': force legacy `window.UC_UI` path.\n * - 'v3': force current `window.__ucCmp` path.\n */\n apiVersion?: 'auto' | 'v2' | 'v3';\n\n /**\n * V3 window event name to listen for consent changes.\n *\n * Usercentrics V3 hardcodes its built-in event names (`UC_UI_CMP_EVENT`,\n * `UC_UI_INITIALIZED`, `UC_UI_VIEW_CHANGED`, `UC_CONSENT`) - they cannot be\n * renamed. However, the Usercentrics admin dashboard (Implementation >\n * Data Layer & Events) lets admins configure an ADDITIONAL custom window\n * event. Use this setting to point at that custom event name if\n * configured; otherwise leave as default.\n *\n * Default: 'UC_UI_CMP_EVENT'\n */\n v3EventName?: string;\n}\n\n/**\n * User input settings (all optional)\n */\nexport type InitSettings = Partial<Settings>;\n\n/**\n * No mapping configuration for this source\n */\nexport interface Mapping {}\n\n/**\n * Push function type - uses elb for consent commands\n */\nexport type Push = Elb.Fn;\n\n/**\n * Environment interface for Usercentrics source\n */\nexport interface Env extends Source.BaseEnv {\n window?: Window & typeof globalThis;\n}\n\n/**\n * Types bundle for Usercentrics source\n */\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\n/**\n * Config type alias\n */\nexport type Config = Source.Config<Types>;\n"],"mappings":"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","names":["_a","cmp","_a"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/lib/parseConsent.ts","../src/lib/v2.ts","../src/lib/v3.ts","../src/types/index.ts"],"sourcesContent":["import type { Source } from '@walkeros/core';\nimport type { Types, Settings } from './types';\nimport { setupV2Adapter } from './lib/v2';\nimport { setupV3Adapter } from './lib/v3';\n\n// Export types for external usage\nexport * as SourceUsercentrics from './types';\n\n/**\n * Usercentrics consent management source for walkerOS.\n *\n * Listens to Usercentrics CMP events and translates consent states to\n * walkerOS consent commands. Supports both the legacy V2 API\n * (`window.UC_UI` + `ucEvent`) and the current V3 API\n * (`window.__ucCmp` + `UC_UI_CMP_EVENT`).\n *\n * @example\n * ```typescript\n * import { sourceUsercentrics } from '@walkeros/web-source-cmp-usercentrics';\n *\n * await startFlow({\n * sources: {\n * consent: {\n * code: sourceUsercentrics,\n * config: {\n * settings: {\n * categoryMap: {\n * essential: 'functional',\n * functional: 'functional',\n * marketing: 'marketing',\n * },\n * },\n * },\n * },\n * },\n * });\n * ```\n */\nexport const sourceUsercentrics: Source.Init<Types> = async (context) => {\n const { config, env } = context;\n const { elb, logger } = env;\n\n // Resolve window with fallback to globalThis\n const actualWindow =\n env.window ??\n (typeof globalThis.window !== 'undefined' ? globalThis.window : undefined);\n\n // Merge user settings with defaults so adapters always see a fully-resolved Settings\n const settings: Settings = {\n categoryMap: config?.settings?.categoryMap ?? {},\n explicitOnly: config?.settings?.explicitOnly ?? true,\n apiVersion: config?.settings?.apiVersion ?? 'auto',\n v3EventName: config?.settings?.v3EventName ?? 'UC_UI_CMP_EVENT',\n };\n\n const fullConfig: Source.Config<Types> = { settings };\n const cleanups: Array<() => void> = [];\n\n // Attach the CMP listeners and perform the static consent read. Deferred to\n // init() (Pass 2 of initSources) so the factory (Pass 1) stays side-effect\n // free: no listener registration and, critically, no `elb('walker consent')`\n // emit during construction. Emitting from the factory races source merge\n // order and can leave a later `require:[\"consent\"]` source parked.\n const init = async (): Promise<void> => {\n if (!actualWindow) return;\n\n const adapterCtx = { window: actualWindow, elb, settings, logger };\n const apiVersion = settings.apiVersion ?? 'auto';\n\n if (apiVersion === 'v2') {\n cleanups.push(setupV2Adapter(adapterCtx));\n } else if (apiVersion === 'v3') {\n cleanups.push(await setupV3Adapter(adapterCtx));\n } else {\n // auto: detect which API is present\n if (actualWindow.__ucCmp) {\n cleanups.push(await setupV3Adapter(adapterCtx));\n } else if (actualWindow.UC_UI) {\n cleanups.push(setupV2Adapter(adapterCtx));\n } else {\n // Neither loaded yet — attach both listeners so whichever loads later is caught.\n cleanups.push(setupV2Adapter(adapterCtx));\n cleanups.push(await setupV3Adapter(adapterCtx));\n }\n }\n };\n\n return {\n type: 'usercentrics',\n config: fullConfig,\n push: elb,\n init,\n destroy: async () => {\n cleanups.forEach((fn) => fn());\n },\n };\n};\n\nexport default sourceUsercentrics;\n","import type { WalkerOS } from '@walkeros/core';\nimport type { UsercentricsEventDetail, Settings } from '../types';\n\n/** Reserved keys in event.detail that are not service names */\nexport const RESERVED_KEYS = ['action', 'event', 'type', 'ucCategory'];\n\n/**\n * Determine if ucCategory represents group-level consent.\n * Group-level: all values are booleans.\n * Service-level: some values are non-boolean (e.g., 'partial').\n */\nexport function isGroupLevel(\n ucCategory: Record<string, boolean | unknown>,\n): boolean {\n return Object.values(ucCategory).every((val) => typeof val === 'boolean');\n}\n\n/**\n * Merge an incoming consent signal into the accumulating state using strict\n * AND semantics: absent key initialises from the incoming value; present key\n * becomes `true` only if both existing and incoming are `true`. Any single\n * `false` anywhere in the merge chain revokes consent for that key.\n *\n * This matches the consent rule of thumb: any deny signal denies. Permissive\n * (OR) and \"last-wins\" semantics are both unsafe for a privacy primitive.\n */\nfunction mergeConsent(\n state: WalkerOS.Consent,\n key: string,\n value: boolean,\n): void {\n state[key] = state[key] === undefined ? value : Boolean(state[key]) && value;\n}\n\n/**\n * Parse consent from Usercentrics event detail.\n *\n * Group-level: ucCategory values are all booleans → use them directly.\n * Service-level: ucCategory has non-booleans → mix boolean ucCategory entries\n * with top-level service keys from event.detail.\n *\n * categoryMap is applied in both modes to ucCategory boolean entries.\n * Strict AND: if multiple source categories map to the same target group,\n * the target is `true` only when ALL contributing sources are `true`.\n */\nexport function parseConsent(\n detail: UsercentricsEventDetail,\n settings: Settings,\n): WalkerOS.Consent {\n const state: WalkerOS.Consent = {};\n\n if (detail.ucCategory && isGroupLevel(detail.ucCategory)) {\n Object.entries(detail.ucCategory).forEach(([category, value]) => {\n if (typeof value !== 'boolean') return;\n const mapped = settings.categoryMap?.[category] ?? category;\n mergeConsent(state, mapped, value);\n });\n } else {\n if (detail.ucCategory) {\n Object.entries(detail.ucCategory).forEach(([key, value]) => {\n if (typeof value === 'boolean') {\n const mapped = settings.categoryMap?.[key] ?? key;\n mergeConsent(state, mapped, value);\n }\n });\n }\n\n Object.entries(detail).forEach(([key, value]) => {\n if (RESERVED_KEYS.includes(key)) return;\n if (typeof value !== 'boolean') return;\n const normalized = key.toLowerCase().replace(/ /g, '_');\n mergeConsent(state, normalized, value);\n });\n }\n\n return state;\n}\n","import type { Elb, Logger } from '@walkeros/core';\nimport type {\n Settings,\n UsercentricsEventDetail,\n UsercentricsV2Service,\n UsercentricsV3CmpEventDetail,\n} from '../types';\nimport { parseConsent } from './parseConsent';\n\nexport interface V2AdapterContext {\n window: Window & typeof globalThis;\n elb: Elb.Fn;\n settings: Settings;\n logger: Logger.Instance;\n}\n\n/**\n * V3 CMP event `type` values that signal a real user decision. Other event\n * types (e.g. CMP_SHOWN, VIEW_CHANGED) carry no consent decision and are\n * ignored so the adapter only re-reads after an actual choice.\n */\nconst V2_DECISION_TYPES: ReadonlySet<string> = new Set([\n 'ACCEPT_ALL',\n 'DENY_ALL',\n 'SAVE',\n]);\n\n/**\n * Aggregate V2 service array into a group-level ucCategory object using strict\n * AND logic. A category is `true` only if EVERY service in that category is\n * accepted. Any single denied service denies the whole category — this\n * matches the consent rule of thumb: any deny signal denies.\n */\nfunction aggregateByCategory(\n services: UsercentricsV2Service[],\n): Record<string, boolean> {\n const categories: Record<string, boolean> = {};\n services.forEach((service) => {\n const category = service.categorySlug;\n const status = service.consent?.status ?? false;\n categories[category] =\n categories[category] === undefined\n ? status\n : categories[category] && status;\n });\n return categories;\n}\n\n/**\n * Whether any service carries an `explicit` entry in its consent history. An\n * explicit entry is Usercentrics' own proof that the user actively decided\n * (vs an implicit page-load default), so it correctly surfaces returning\n * visitors whose stored decision was explicit.\n */\nexport function hasExplicitDecision(\n services: UsercentricsV2Service[],\n): boolean {\n return services.some((s) =>\n (s.consent.history ?? []).some((h) => h.type?.toLowerCase() === 'explicit'),\n );\n}\n\n/**\n * Build a synthetic UsercentricsEventDetail from the V2 services array. The\n * `type` is derived from Usercentrics' own consent history: `explicit` when any\n * service records an explicit decision, `implicit` otherwise. Per-service name\n * keys are surfaced so parseConsent can map service-level consent.\n */\nexport function buildDetailFromServices(\n services: UsercentricsV2Service[],\n): UsercentricsEventDetail {\n const detail: UsercentricsEventDetail = {\n event: 'consent_status',\n type: hasExplicitDecision(services) ? 'explicit' : 'implicit',\n ucCategory: aggregateByCategory(services),\n };\n services.forEach((s) => {\n if (s.name) detail[s.name] = s.consent.status;\n });\n return detail;\n}\n\n/**\n * Set up the V2 adapter using Usercentrics' official events and getter.\n *\n * A single gated `read()` is reused by all triggers: the official\n * `UC_UI_INITIALIZED` lifecycle event, the official `UC_UI_CMP_EVENT` decision\n * events (filtered to real decisions), and a static read at setup time for the\n * common case where the CMP is already initialized when the source runs.\n *\n * Returns a cleanup function that removes both event listeners.\n */\nexport function setupV2Adapter(ctx: V2AdapterContext): () => void {\n const { window: win, elb, settings, logger } = ctx;\n\n const read = (): void => {\n const api = win.UC_UI;\n if (!api?.isInitialized?.() || !api.getServicesBaseInfo) return;\n const services = api.getServicesBaseInfo();\n if (!services.length) return;\n const detail = buildDetailFromServices(services);\n logger.debug('consent read', detail);\n if (settings.explicitOnly && detail.type !== 'explicit') return;\n const state = parseConsent(detail, settings);\n if (Object.keys(state).length > 0) elb('walker consent', state);\n };\n\n const onInitialized = (): void => read();\n const onCmpEvent = (e: Event): void => {\n const detail = (e as CustomEvent<UsercentricsV3CmpEventDetail>).detail;\n if (!detail?.type || !V2_DECISION_TYPES.has(detail.type)) return;\n read();\n };\n\n win.addEventListener('UC_UI_INITIALIZED', onInitialized);\n win.addEventListener('UC_UI_CMP_EVENT', onCmpEvent);\n\n read(); // static read: CMP already initialized when source runs\n\n return () => {\n win.removeEventListener('UC_UI_INITIALIZED', onInitialized);\n win.removeEventListener('UC_UI_CMP_EVENT', onCmpEvent);\n };\n}\n","import type { Elb, Logger } from '@walkeros/core';\nimport type {\n Settings,\n UsercentricsEventDetail,\n UsercentricsV3Api,\n UsercentricsV3CategoryState,\n UsercentricsV3CmpEventDetail,\n UsercentricsV3ConsentDetails,\n} from '../types';\nimport { parseConsent } from './parseConsent';\n\nexport interface V3AdapterContext {\n window: Window & typeof globalThis;\n elb: Elb.Fn;\n settings: Settings;\n logger: Logger.Instance;\n}\n\nconst V3_DEFAULT_EVENT_NAME = 'UC_UI_CMP_EVENT';\n\n/**\n * V3 CMP event types that represent a user consent decision. Presentation\n * events like `CMP_SHOWN` or `UI_INITIALIZED` must NOT trigger a consent\n * publish — they carry no user decision.\n */\nconst V3_DECISION_TYPES: ReadonlySet<string> = new Set([\n 'ACCEPT_ALL',\n 'DENY_ALL',\n 'SAVE',\n]);\n\n/**\n * Map a V3 CategoryData.state value to a walkerOS boolean using strict\n * semantics: only fully-accepted categories are `true`. Any partial or\n * denied state (including future/unknown states) resolves to `false`.\n *\n * This matches the consent rule of thumb: any deny signal denies.\n */\nfunction categoryStateToBoolean(state: UsercentricsV3CategoryState): boolean {\n return state === 'ALL_ACCEPTED';\n}\n\n/**\n * Build a synthetic UsercentricsEventDetail from V3 ConsentDetails.\n * Translates V3's structured consent state into the shape parseConsent expects.\n */\nfunction buildDetailFromV3(\n details: UsercentricsV3ConsentDetails,\n): UsercentricsEventDetail {\n const ucCategory: Record<string, boolean> = {};\n Object.entries(details.categories).forEach(([slug, category]) => {\n ucCategory[slug] = categoryStateToBoolean(category.state);\n });\n\n return {\n event: 'consent_status',\n type: details.consent.type === 'EXPLICIT' ? 'explicit' : 'implicit',\n ucCategory,\n };\n}\n\n/**\n * Set up the V3 adapter: registers a listener on the V3 consent event AND\n * (if __ucCmp is already initialized) performs a static read.\n *\n * Both paths re-fetch getConsentDetails() because the event payload does\n * not include consent state.\n *\n * Returns a cleanup function that removes the event listener.\n */\nexport async function setupV3Adapter(\n ctx: V3AdapterContext,\n): Promise<() => void> {\n const { window: win, elb, settings, logger } = ctx;\n const eventName = settings.v3EventName ?? V3_DEFAULT_EVENT_NAME;\n\n const publishConsent = async (cmp: UsercentricsV3Api): Promise<void> => {\n const details = await cmp.getConsentDetails();\n const detail = buildDetailFromV3(details);\n logger.debug('event received', detail);\n\n if (settings.explicitOnly && detail.type !== 'explicit') return;\n\n const state = parseConsent(detail, settings);\n if (Object.keys(state).length > 0) {\n elb('walker consent', state);\n }\n };\n\n const listener = (event: Event): void => {\n const cmp = win.__ucCmp;\n if (!cmp) return;\n const detail = (event as CustomEvent<UsercentricsV3CmpEventDetail>).detail;\n // Filter to decision events only: the CMP emits a broad set of events\n // (CMP_SHOWN, UI_INITIALIZED, VIEW_CHANGED, …) on this bus. Without\n // filtering, every view toggle would re-publish consent. The decision\n // `type` is the only reliable signal; `detail.source` is one of\n // none|button|first|second|embeddings|__ucCmp and must NOT be gated on.\n if (!detail?.type || !V3_DECISION_TYPES.has(detail.type)) return;\n publishConsent(cmp).catch(() => {\n // Swallow — a failed V3 fetch should not break the page.\n });\n };\n win.addEventListener(eventName, listener);\n\n // When the source loads BEFORE __ucCmp, no UC_UI_CMP_EVENT fires for a\n // choice made in a prior session. UC_UI_INITIALIZED signals the CMP is ready,\n // so perform the static read then to publish any already-made decision.\n const onInitialized = (): void => {\n const cmp = win.__ucCmp;\n if (cmp) publishConsent(cmp).catch(() => {});\n };\n win.addEventListener('UC_UI_INITIALIZED', onInitialized);\n\n // Static check: if __ucCmp is already initialized, fetch now.\n // Wrapped in try/catch so transient API failures during setup don't\n // reject setupV3Adapter() and tear down the whole flow — the listener\n // stays registered and will pick up the next real event.\n const cmp = win.__ucCmp;\n if (cmp) {\n try {\n const initialized = await cmp.isInitialized();\n if (initialized) {\n await publishConsent(cmp);\n }\n } catch (err) {\n logger.warn('v3 static consent read failed', err);\n }\n }\n\n return () => {\n win.removeEventListener(eventName, listener);\n win.removeEventListener('UC_UI_INITIALIZED', onInitialized);\n };\n}\n","import type { Source, Elb } from '@walkeros/core';\n\ndeclare module '@walkeros/core' {\n interface SourceMap {\n usercentrics: { type: 'usercentrics'; platform?: 'web' };\n }\n}\n\n/**\n * Usercentrics consent event detail structure.\n *\n * Fired as event.detail on the configured window event (e.g. 'ucEvent').\n * Contains both category-level (ucCategory) and service-level consent.\n */\nexport interface UsercentricsEventDetail {\n /** Always 'consent_status' for consent events */\n event: string;\n /** 'explicit' when user actively chose, 'implicit' for page-load defaults (casing may vary) */\n type: string;\n /** Action taken: 'onAcceptAllServices', 'onDenyAllServices', 'onUpdateServices' */\n action?: string;\n /** Category-level consent booleans (e.g. { marketing: true, functional: false }) */\n ucCategory?: Record<string, boolean | unknown>;\n /** Service-level consent as top-level keys (e.g. 'Google Analytics': true) */\n [service: string]: unknown;\n}\n\ndeclare global {\n interface WindowEventMap {\n ucEvent: CustomEvent<UsercentricsEventDetail>;\n UC_UI_INITIALIZED: Event;\n UC_UI_CMP_EVENT: CustomEvent<UsercentricsV3CmpEventDetail>;\n }\n}\n\n/** Usercentrics CONSENT_TYPE values (history entry type / V3 consent type). */\nexport type UsercentricsConsentType = 'explicit' | 'implicit';\n\n/** A single entry in a V2 service's consent history (getServicesBaseInfo). */\nexport interface UsercentricsV2ConsentHistoryEntry {\n type: UsercentricsConsentType;\n status: boolean;\n /** CONSENT_ACTION, e.g. 'onAcceptAllServices' | 'onInitialPageLoad'. Not read for the gate. */\n action?: string;\n timestamp?: number;\n}\n\n/**\n * Usercentrics V2 service info shape returned by `UC_UI.getServicesBaseInfo()`.\n * Only the fields we use are typed - minimal surface, not a full V2 API mirror.\n */\nexport interface UsercentricsV2Service {\n /** Category slug: 'essential' | 'functional' | 'marketing' | custom */\n categorySlug: string;\n /** Service display name (used for service-level consent keys) */\n name?: string;\n /** Consent state for this service */\n consent: {\n status: boolean;\n /** Consent decision history; an 'explicit' entry proves a real user decision. */\n history?: UsercentricsV2ConsentHistoryEntry[];\n };\n}\n\n/**\n * Usercentrics V2 window API (`window.UC_UI`).\n *\n * Methods are synchronous (unlike V3). All methods are optional because\n * Usercentrics does not guarantee every deployment exposes every method.\n */\nexport interface UsercentricsV2Api {\n isInitialized?: () => boolean;\n getServicesBaseInfo?: () => UsercentricsV2Service[];\n getServicesFullInfo?: () => Promise<UsercentricsV2Service[]>;\n areAllConsentsAccepted?: () => boolean;\n}\n\n/**\n * Usercentrics V3 category state. The SDK may add future states; we handle\n * unknowns conservatively as non-accepting.\n */\nexport type UsercentricsV3CategoryState =\n | 'ALL_ACCEPTED'\n | 'ALL_DENIED'\n | 'SOME_ACCEPTED'\n | 'NO_STATE'\n | string;\n\n/**\n * Minimal V3 CategoryData - only fields the adapter reads.\n */\nexport interface UsercentricsV3CategoryData {\n state: UsercentricsV3CategoryState;\n name: string;\n}\n\n/**\n * Minimal V3 ConsentData - only the `type` field is used to distinguish\n * explicit vs implicit consent. Other fields (status, version, etc.) exist on\n * the real SDK but are not read by this adapter.\n */\nexport interface UsercentricsV3ConsentData {\n type: 'EXPLICIT' | 'IMPLICIT' | string;\n}\n\n/**\n * Minimal V3 ConsentDetails - only the fields the adapter reads.\n * The real SDK also exposes `services`, but the adapter currently operates\n * at category level only.\n */\nexport interface UsercentricsV3ConsentDetails {\n consent: UsercentricsV3ConsentData;\n categories: Record<string, UsercentricsV3CategoryData>;\n}\n\n/**\n * Usercentrics V3 window API (`window.__ucCmp`).\n *\n * Only the methods this adapter calls are typed - the real SDK surface is\n * much wider but we intentionally keep this narrow.\n */\nexport interface UsercentricsV3Api {\n isInitialized: () => Promise<boolean>;\n getConsentDetails: () => Promise<UsercentricsV3ConsentDetails>;\n}\n\n/**\n * V3 CMP event detail. Fired on `UC_UI_CMP_EVENT` (or custom name).\n * `source: 'CMP'` + a decision `type` tells us a user action has been taken.\n */\nexport interface UsercentricsV3CmpEventDetail {\n source?:\n | 'none'\n | 'button'\n | 'first'\n | 'second'\n | 'embeddings'\n | '__ucCmp'\n | string;\n type?: string;\n abTestVariant?: string;\n}\n\ndeclare global {\n interface Window {\n /**\n * Usercentrics V2 CMP API. Attached once the V2 Browser SDK is\n * initialized. Optional because the SDK loads asynchronously - guard\n * with a truthiness check before access.\n */\n UC_UI?: UsercentricsV2Api;\n /**\n * Usercentrics V3 CMP API. Attached once the V3 Browser SDK is\n * initialized. Optional because the SDK loads asynchronously - guard\n * with a truthiness check before access.\n */\n __ucCmp?: UsercentricsV3Api;\n }\n}\n\n/**\n * Settings for Usercentrics source\n */\nexport interface Settings {\n /**\n * Map Usercentrics categories to walkerOS consent groups.\n * Keys: Usercentrics category names (from ucCategory)\n * Values: walkerOS consent group names\n *\n * Applied in both group-level and service-level consent modes.\n * When multiple source categories map to the same group, strict AND logic\n * applies: ALL contributing source categories must be true for the target\n * group to be true. Any single false denies consent.\n *\n * Default: {} (pass through category names as-is)\n */\n categoryMap?: Record<string, string>;\n\n /**\n * Only publish when the user has actively decided. V3: consent.type ===\n * EXPLICIT. V2: an EXPLICIT entry exists in service consent history.\n * Implicit/default page-load states are suppressed. Set false to publish any\n * consent snapshot including implicit. Default: true.\n */\n explicitOnly?: boolean;\n\n /**\n * Which Usercentrics API to target.\n * - 'auto' (default): detect at init. If `window.__ucCmp` is present, use V3.\n * If only `window.UC_UI` is present, use V2. If neither is present yet,\n * register listeners for both so late-loading CMPs are still caught.\n * - 'v2': force legacy `window.UC_UI` path.\n * - 'v3': force current `window.__ucCmp` path.\n */\n apiVersion?: 'auto' | 'v2' | 'v3';\n\n /**\n * V3 window event name to listen for consent changes.\n *\n * Usercentrics V3 hardcodes its built-in event names (`UC_UI_CMP_EVENT`,\n * `UC_UI_INITIALIZED`, `UC_UI_VIEW_CHANGED`, `UC_CONSENT`) - they cannot be\n * renamed. However, the Usercentrics admin dashboard (Implementation >\n * Data Layer & Events) lets admins configure an ADDITIONAL custom window\n * event. Use this setting to point at that custom event name if\n * configured; otherwise leave as default.\n *\n * Default: 'UC_UI_CMP_EVENT'\n */\n v3EventName?: string;\n}\n\n/**\n * User input settings (all optional)\n */\nexport type InitSettings = Partial<Settings>;\n\n/**\n * No mapping configuration for this source\n */\nexport interface Mapping {}\n\n/**\n * Push function type - uses elb for consent commands\n */\nexport type Push = Elb.Fn;\n\n/**\n * Environment interface for Usercentrics source\n */\nexport interface Env extends Source.BaseEnv {\n window?: Window & typeof globalThis;\n}\n\n/**\n * Types bundle for Usercentrics source\n */\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\n/**\n * Config type alias\n */\nexport type Config = Source.Config<Types>;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACIO,IAAM,gBAAgB,CAAC,UAAU,SAAS,QAAQ,YAAY;AAO9D,SAAS,aACd,YACS;AACT,SAAO,OAAO,OAAO,UAAU,EAAE,MAAM,CAAC,QAAQ,OAAO,QAAQ,SAAS;AAC1E;AAWA,SAAS,aACP,OACA,KACA,OACM;AACN,QAAM,GAAG,IAAI,MAAM,GAAG,MAAM,SAAY,QAAQ,QAAQ,MAAM,GAAG,CAAC,KAAK;AACzE;AAaO,SAAS,aACd,QACA,UACkB;AAClB,QAAM,QAA0B,CAAC;AAEjC,MAAI,OAAO,cAAc,aAAa,OAAO,UAAU,GAAG;AACxD,WAAO,QAAQ,OAAO,UAAU,EAAE,QAAQ,CAAC,CAAC,UAAU,KAAK,MAAM;AApDrE;AAqDM,UAAI,OAAO,UAAU,UAAW;AAChC,YAAM,UAAS,oBAAS,gBAAT,mBAAuB,cAAvB,YAAoC;AACnD,mBAAa,OAAO,QAAQ,KAAK;AAAA,IACnC,CAAC;AAAA,EACH,OAAO;AACL,QAAI,OAAO,YAAY;AACrB,aAAO,QAAQ,OAAO,UAAU,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AA3DlE;AA4DQ,YAAI,OAAO,UAAU,WAAW;AAC9B,gBAAM,UAAS,oBAAS,gBAAT,mBAAuB,SAAvB,YAA+B;AAC9C,uBAAa,OAAO,QAAQ,KAAK;AAAA,QACnC;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAC/C,UAAI,cAAc,SAAS,GAAG,EAAG;AACjC,UAAI,OAAO,UAAU,UAAW;AAChC,YAAM,aAAa,IAAI,YAAY,EAAE,QAAQ,MAAM,GAAG;AACtD,mBAAa,OAAO,YAAY,KAAK;AAAA,IACvC,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;ACvDA,IAAM,oBAAyC,oBAAI,IAAI;AAAA,EACrD;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAQD,SAAS,oBACP,UACyB;AACzB,QAAM,aAAsC,CAAC;AAC7C,WAAS,QAAQ,CAAC,YAAY;AArChC;AAsCI,UAAM,WAAW,QAAQ;AACzB,UAAM,UAAS,mBAAQ,YAAR,mBAAiB,WAAjB,YAA2B;AAC1C,eAAW,QAAQ,IACjB,WAAW,QAAQ,MAAM,SACrB,SACA,WAAW,QAAQ,KAAK;AAAA,EAChC,CAAC;AACD,SAAO;AACT;AAQO,SAAS,oBACd,UACS;AACT,SAAO,SAAS;AAAA,IAAK,CAAC,MAAG;AAzD3B;AA0DK,sBAAE,QAAQ,YAAV,YAAqB,CAAC,GAAG,KAAK,CAAC,MAAG;AA1DvC,YAAAA;AA0D0C,iBAAAA,MAAA,EAAE,SAAF,gBAAAA,IAAQ,mBAAkB;AAAA,OAAU;AAAA;AAAA,EAC5E;AACF;AAQO,SAAS,wBACd,UACyB;AACzB,QAAM,SAAkC;AAAA,IACtC,OAAO;AAAA,IACP,MAAM,oBAAoB,QAAQ,IAAI,aAAa;AAAA,IACnD,YAAY,oBAAoB,QAAQ;AAAA,EAC1C;AACA,WAAS,QAAQ,CAAC,MAAM;AACtB,QAAI,EAAE,KAAM,QAAO,EAAE,IAAI,IAAI,EAAE,QAAQ;AAAA,EACzC,CAAC;AACD,SAAO;AACT;AAYO,SAAS,eAAe,KAAmC;AAChE,QAAM,EAAE,QAAQ,KAAK,KAAK,UAAU,OAAO,IAAI;AAE/C,QAAM,OAAO,MAAY;AA/F3B;AAgGI,UAAM,MAAM,IAAI;AAChB,QAAI,GAAC,gCAAK,kBAAL,iCAA0B,CAAC,IAAI,oBAAqB;AACzD,UAAM,WAAW,IAAI,oBAAoB;AACzC,QAAI,CAAC,SAAS,OAAQ;AACtB,UAAM,SAAS,wBAAwB,QAAQ;AAC/C,WAAO,MAAM,gBAAgB,MAAM;AACnC,QAAI,SAAS,gBAAgB,OAAO,SAAS,WAAY;AACzD,UAAM,QAAQ,aAAa,QAAQ,QAAQ;AAC3C,QAAI,OAAO,KAAK,KAAK,EAAE,SAAS,EAAG,KAAI,kBAAkB,KAAK;AAAA,EAChE;AAEA,QAAM,gBAAgB,MAAY,KAAK;AACvC,QAAM,aAAa,CAAC,MAAmB;AACrC,UAAM,SAAU,EAAgD;AAChE,QAAI,EAAC,iCAAQ,SAAQ,CAAC,kBAAkB,IAAI,OAAO,IAAI,EAAG;AAC1D,SAAK;AAAA,EACP;AAEA,MAAI,iBAAiB,qBAAqB,aAAa;AACvD,MAAI,iBAAiB,mBAAmB,UAAU;AAElD,OAAK;AAEL,SAAO,MAAM;AACX,QAAI,oBAAoB,qBAAqB,aAAa;AAC1D,QAAI,oBAAoB,mBAAmB,UAAU;AAAA,EACvD;AACF;;;ACzGA,IAAM,wBAAwB;AAO9B,IAAM,oBAAyC,oBAAI,IAAI;AAAA,EACrD;AAAA,EACA;AAAA,EACA;AACF,CAAC;AASD,SAAS,uBAAuB,OAA6C;AAC3E,SAAO,UAAU;AACnB;AAMA,SAAS,kBACP,SACyB;AACzB,QAAM,aAAsC,CAAC;AAC7C,SAAO,QAAQ,QAAQ,UAAU,EAAE,QAAQ,CAAC,CAAC,MAAM,QAAQ,MAAM;AAC/D,eAAW,IAAI,IAAI,uBAAuB,SAAS,KAAK;AAAA,EAC1D,CAAC;AAED,SAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM,QAAQ,QAAQ,SAAS,aAAa,aAAa;AAAA,IACzD;AAAA,EACF;AACF;AAWA,eAAsB,eACpB,KACqB;AAxEvB;AAyEE,QAAM,EAAE,QAAQ,KAAK,KAAK,UAAU,OAAO,IAAI;AAC/C,QAAM,aAAY,cAAS,gBAAT,YAAwB;AAE1C,QAAM,iBAAiB,OAAOC,SAA0C;AACtE,UAAM,UAAU,MAAMA,KAAI,kBAAkB;AAC5C,UAAM,SAAS,kBAAkB,OAAO;AACxC,WAAO,MAAM,kBAAkB,MAAM;AAErC,QAAI,SAAS,gBAAgB,OAAO,SAAS,WAAY;AAEzD,UAAM,QAAQ,aAAa,QAAQ,QAAQ;AAC3C,QAAI,OAAO,KAAK,KAAK,EAAE,SAAS,GAAG;AACjC,UAAI,kBAAkB,KAAK;AAAA,IAC7B;AAAA,EACF;AAEA,QAAM,WAAW,CAAC,UAAuB;AACvC,UAAMA,OAAM,IAAI;AAChB,QAAI,CAACA,KAAK;AACV,UAAM,SAAU,MAAoD;AAMpE,QAAI,EAAC,iCAAQ,SAAQ,CAAC,kBAAkB,IAAI,OAAO,IAAI,EAAG;AAC1D,mBAAeA,IAAG,EAAE,MAAM,MAAM;AAAA,IAEhC,CAAC;AAAA,EACH;AACA,MAAI,iBAAiB,WAAW,QAAQ;AAKxC,QAAM,gBAAgB,MAAY;AAChC,UAAMA,OAAM,IAAI;AAChB,QAAIA,KAAK,gBAAeA,IAAG,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EAC7C;AACA,MAAI,iBAAiB,qBAAqB,aAAa;AAMvD,QAAM,MAAM,IAAI;AAChB,MAAI,KAAK;AACP,QAAI;AACF,YAAM,cAAc,MAAM,IAAI,cAAc;AAC5C,UAAI,aAAa;AACf,cAAM,eAAe,GAAG;AAAA,MAC1B;AAAA,IACF,SAAS,KAAK;AACZ,aAAO,KAAK,iCAAiC,GAAG;AAAA,IAClD;AAAA,EACF;AAEA,SAAO,MAAM;AACX,QAAI,oBAAoB,WAAW,QAAQ;AAC3C,QAAI,oBAAoB,qBAAqB,aAAa;AAAA,EAC5D;AACF;;;ACtIA;;;AJsCO,IAAM,qBAAyC,OAAO,YAAY;AAtCzE;AAuCE,QAAM,EAAE,QAAQ,IAAI,IAAI;AACxB,QAAM,EAAE,KAAK,OAAO,IAAI;AAGxB,QAAM,gBACJ,SAAI,WAAJ,YACC,OAAO,WAAW,WAAW,cAAc,WAAW,SAAS;AAGlE,QAAM,WAAqB;AAAA,IACzB,cAAa,4CAAQ,aAAR,mBAAkB,gBAAlB,YAAiC,CAAC;AAAA,IAC/C,eAAc,4CAAQ,aAAR,mBAAkB,iBAAlB,YAAkC;AAAA,IAChD,aAAY,4CAAQ,aAAR,mBAAkB,eAAlB,YAAgC;AAAA,IAC5C,cAAa,4CAAQ,aAAR,mBAAkB,gBAAlB,YAAiC;AAAA,EAChD;AAEA,QAAM,aAAmC,EAAE,SAAS;AACpD,QAAM,WAA8B,CAAC;AAOrC,QAAM,OAAO,YAA2B;AA/D1C,QAAAC;AAgEI,QAAI,CAAC,aAAc;AAEnB,UAAM,aAAa,EAAE,QAAQ,cAAc,KAAK,UAAU,OAAO;AACjE,UAAM,cAAaA,MAAA,SAAS,eAAT,OAAAA,MAAuB;AAE1C,QAAI,eAAe,MAAM;AACvB,eAAS,KAAK,eAAe,UAAU,CAAC;AAAA,IAC1C,WAAW,eAAe,MAAM;AAC9B,eAAS,KAAK,MAAM,eAAe,UAAU,CAAC;AAAA,IAChD,OAAO;AAEL,UAAI,aAAa,SAAS;AACxB,iBAAS,KAAK,MAAM,eAAe,UAAU,CAAC;AAAA,MAChD,WAAW,aAAa,OAAO;AAC7B,iBAAS,KAAK,eAAe,UAAU,CAAC;AAAA,MAC1C,OAAO;AAEL,iBAAS,KAAK,eAAe,UAAU,CAAC;AACxC,iBAAS,KAAK,MAAM,eAAe,UAAU,CAAC;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,MAAM;AAAA,IACN;AAAA,IACA,SAAS,YAAY;AACnB,eAAS,QAAQ,CAAC,OAAO,GAAG,CAAC;AAAA,IAC/B;AAAA,EACF;AACF;AAEA,IAAO,gBAAQ;","names":["_a","cmp","_a"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=["action","event","type","ucCategory"];function t(e,t,n){e[t]=(void 0===e[t]||Boolean(e[t]))&&n}function n(n,o){const i={};var
|
|
1
|
+
var e=["action","event","type","ucCategory"];function t(e,t,n){e[t]=(void 0===e[t]||Boolean(e[t]))&&n}function n(n,o){const i={};var r;return n.ucCategory&&(r=n.ucCategory,Object.values(r).every(e=>"boolean"==typeof e))?Object.entries(n.ucCategory).forEach(([e,n])=>{var r,s;if("boolean"!=typeof n)return;const c=null!=(s=null==(r=o.categoryMap)?void 0:r[e])?s:e;t(i,c,n)}):(n.ucCategory&&Object.entries(n.ucCategory).forEach(([e,n])=>{var r,s;if("boolean"==typeof n){const c=null!=(s=null==(r=o.categoryMap)?void 0:r[e])?s:e;t(i,c,n)}}),Object.entries(n).forEach(([n,o])=>{if(e.includes(n))return;if("boolean"!=typeof o)return;const r=n.toLowerCase().replace(/ /g,"_");t(i,r,o)})),i}var o=new Set(["ACCEPT_ALL","DENY_ALL","SAVE"]);function i(e){const t={};return e.forEach(e=>{var n,o;const i=e.categorySlug,r=null!=(o=null==(n=e.consent)?void 0:n.status)&&o;t[i]=(void 0===t[i]||t[i])&&r}),t}function r(e){return e.some(e=>{var t;return(null!=(t=e.consent.history)?t:[]).some(e=>{var t;return"explicit"===(null==(t=e.type)?void 0:t.toLowerCase())})})}function s(e){const{window:t,elb:s,settings:c,logger:a}=e,l=()=>{var e;const o=t.UC_UI;if(!(null==(e=null==o?void 0:o.isInitialized)?void 0:e.call(o))||!o.getServicesBaseInfo)return;const l=o.getServicesBaseInfo();if(!l.length)return;const u=function(e){const t={event:"consent_status",type:r(e)?"explicit":"implicit",ucCategory:i(e)};return e.forEach(e=>{e.name&&(t[e.name]=e.consent.status)}),t}(l);if(a.debug("consent read",u),c.explicitOnly&&"explicit"!==u.type)return;const v=n(u,c);Object.keys(v).length>0&&s("walker consent",v)},u=()=>l(),v=e=>{const t=e.detail;(null==t?void 0:t.type)&&o.has(t.type)&&l()};return t.addEventListener("UC_UI_INITIALIZED",u),t.addEventListener("UC_UI_CMP_EVENT",v),l(),()=>{t.removeEventListener("UC_UI_INITIALIZED",u),t.removeEventListener("UC_UI_CMP_EVENT",v)}}var c=new Set(["ACCEPT_ALL","DENY_ALL","SAVE"]);async function a(e){var t;const{window:o,elb:i,settings:r,logger:s}=e,a=null!=(t=r.v3EventName)?t:"UC_UI_CMP_EVENT",l=async e=>{const t=function(e){const t={};return Object.entries(e.categories).forEach(([e,n])=>{t[e]="ALL_ACCEPTED"===n.state}),{event:"consent_status",type:"EXPLICIT"===e.consent.type?"explicit":"implicit",ucCategory:t}}(await e.getConsentDetails());if(s.debug("event received",t),r.explicitOnly&&"explicit"!==t.type)return;const o=n(t,r);Object.keys(o).length>0&&i("walker consent",o)},u=e=>{const t=o.__ucCmp;if(!t)return;const n=e.detail;(null==n?void 0:n.type)&&c.has(n.type)&&l(t).catch(()=>{})};o.addEventListener(a,u);const v=()=>{const e=o.__ucCmp;e&&l(e).catch(()=>{})};o.addEventListener("UC_UI_INITIALIZED",v);const d=o.__ucCmp;if(d)try{await d.isInitialized()&&await l(d)}catch(e){s.warn("v3 static consent read failed",e)}return()=>{o.removeEventListener(a,u),o.removeEventListener("UC_UI_INITIALIZED",v)}}var l={},u=async e=>{var t,n,o,i,r,c,l,u,v;const{config:d,env:p}=e,{elb:g,logger:y}=p,E=null!=(t=p.window)?t:void 0!==globalThis.window?globalThis.window:void 0,_={categoryMap:null!=(o=null==(n=null==d?void 0:d.settings)?void 0:n.categoryMap)?o:{},explicitOnly:null==(r=null==(i=null==d?void 0:d.settings)?void 0:i.explicitOnly)||r,apiVersion:null!=(l=null==(c=null==d?void 0:d.settings)?void 0:c.apiVersion)?l:"auto",v3EventName:null!=(v=null==(u=null==d?void 0:d.settings)?void 0:u.v3EventName)?v:"UC_UI_CMP_EVENT"},f=[];return{type:"usercentrics",config:{settings:_},push:g,init:async()=>{var e;if(!E)return;const t={window:E,elb:g,settings:_,logger:y},n=null!=(e=_.apiVersion)?e:"auto";"v2"===n?f.push(s(t)):"v3"===n||E.__ucCmp?f.push(await a(t)):E.UC_UI?f.push(s(t)):(f.push(s(t)),f.push(await a(t)))},destroy:async()=>{f.forEach(e=>e())}}},v=u;export{l as SourceUsercentrics,v as default,u as sourceUsercentrics};//# sourceMappingURL=index.mjs.map
|