@walkeros/web-source-cmp-usercentrics 4.6.1 → 4.7.0-next-1790187973605

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 CHANGED
@@ -1,5 +1,27 @@
1
1
  # @walkeros/web-source-cmp-usercentrics
2
2
 
3
+ ## 4.7.0-next-1790187973605
4
+
5
+ ### Patch Changes
6
+
7
+ - ef02916: The settings schema now lists `apiVersion` (`auto`, `v2` or `v3`) and
8
+ `v3EventName`, which the source already supported, so `walkeros validate` and
9
+ editors accept them.
10
+ - Updated dependencies [57788bc]
11
+ - Updated dependencies [2aebc53]
12
+ - Updated dependencies [f5a1cfd]
13
+ - Updated dependencies [ef02916]
14
+ - Updated dependencies [ef02916]
15
+ - Updated dependencies [2aebc53]
16
+ - Updated dependencies [f5a1cfd]
17
+ - Updated dependencies [f5a1cfd]
18
+ - Updated dependencies [2aebc53]
19
+ - Updated dependencies [8f8aea6]
20
+ - Updated dependencies [2aebc53]
21
+ - Updated dependencies [2aebc53]
22
+ - @walkeros/core@4.7.0-next-1790187973605
23
+ - @walkeros/collector@4.7.0-next-1790187973605
24
+
3
25
  ## 4.6.1
4
26
 
5
27
  ### Patch Changes
package/README.md CHANGED
@@ -7,8 +7,8 @@
7
7
  # @walkeros/web-source-cmp-usercentrics
8
8
 
9
9
  Integrates Usercentrics consent management with walkerOS using the official
10
- Usercentrics events and consent getters, mapping category or service consent
11
- state to walkerOS consent groups.
10
+ Usercentrics events and consent getters, mapping category consent state to
11
+ walkerOS consent groups.
12
12
 
13
13
  [Documentation](https://www.walkeros.io/docs/sources/web/cmps/usercentrics)
14
14
  •
@@ -66,9 +66,8 @@ implicit first-visit defaults.
66
66
  ## Settings
67
67
 
68
68
  `explicitOnly` (default `true`) is the cross-version gate for "the user has
69
- actively decided," applied identically for V2 and V3. There is no configurable
70
- data-layer event setting: the `eventName` setting has been removed, and the
71
- source listens to the always-emitted official events.
69
+ actively decided," applied identically for V2 and V3. The source listens to the
70
+ official Usercentrics events, so no data-layer event setup is needed.
72
71
 
73
72
  ## Documentation
74
73
 
package/dist/dev.d.mts CHANGED
@@ -232,16 +232,17 @@ declare namespace step {
232
232
  export { step_categoryMapOverride as categoryMapOverride, step_consentChange as consentChange, step_firstVisitImplicit as firstVisitImplicit, step_fullConsent as fullConsent, step_minimalConsent as minimalConsent, step_returningVisitor as returningVisitor };
233
233
  }
234
234
 
235
- interface UsercentricsContent {
236
- event: string;
237
- type: string;
238
- action?: string;
239
- ucCategory?: Record<string, boolean | unknown>;
240
- [service: string]: unknown;
241
- }
242
- declare const createTrigger: Trigger.CreateFn<UsercentricsContent, void>;
243
- /** Dispatches ucEvent CustomEvent after source init (post-init trigger). */
244
- declare const trigger: (input: unknown, env: Record<string, unknown>) => void | (() => void);
235
+ /**
236
+ * `content` is what `window.UC_UI.getServicesBaseInfo()` returns. The
237
+ * `dispatch` option picks the official path the source reacts to:
238
+ * - 'init' (default): UC_UI is attached before the source runs, so the
239
+ * static read at init publishes the snapshot.
240
+ * - 'cmp': UC_UI is attached after init, then a `UC_UI_CMP_EVENT`
241
+ * ACCEPT_ALL decision makes the source re-read and publish.
242
+ */
243
+ declare const createTrigger: Trigger.CreateFn<UsercentricsV2Service[], void>;
244
+ /** Attaches the services as the V2 `UC_UI` API before source init. */
245
+ declare const trigger: (input: unknown, env: Record<string, unknown>) => void;
245
246
 
246
247
  declare const index$1_createMockElbFn: typeof createMockElbFn;
247
248
  declare const index$1_createTrigger: typeof createTrigger;
@@ -266,6 +267,12 @@ declare namespace index$1 {
266
267
  declare const SettingsSchema: z.ZodObject<{
267
268
  categoryMap: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
268
269
  explicitOnly: z.ZodOptional<z.ZodBoolean>;
270
+ apiVersion: z.ZodOptional<z.ZodEnum<{
271
+ auto: "auto";
272
+ v2: "v2";
273
+ v3: "v3";
274
+ }>>;
275
+ v3EventName: z.ZodOptional<z.ZodString>;
269
276
  }, z.core.$strip>;
270
277
  type Settings = z.infer<typeof SettingsSchema>;
271
278
 
package/dist/dev.d.ts CHANGED
@@ -232,16 +232,17 @@ declare namespace step {
232
232
  export { step_categoryMapOverride as categoryMapOverride, step_consentChange as consentChange, step_firstVisitImplicit as firstVisitImplicit, step_fullConsent as fullConsent, step_minimalConsent as minimalConsent, step_returningVisitor as returningVisitor };
233
233
  }
234
234
 
235
- interface UsercentricsContent {
236
- event: string;
237
- type: string;
238
- action?: string;
239
- ucCategory?: Record<string, boolean | unknown>;
240
- [service: string]: unknown;
241
- }
242
- declare const createTrigger: Trigger.CreateFn<UsercentricsContent, void>;
243
- /** Dispatches ucEvent CustomEvent after source init (post-init trigger). */
244
- declare const trigger: (input: unknown, env: Record<string, unknown>) => void | (() => void);
235
+ /**
236
+ * `content` is what `window.UC_UI.getServicesBaseInfo()` returns. The
237
+ * `dispatch` option picks the official path the source reacts to:
238
+ * - 'init' (default): UC_UI is attached before the source runs, so the
239
+ * static read at init publishes the snapshot.
240
+ * - 'cmp': UC_UI is attached after init, then a `UC_UI_CMP_EVENT`
241
+ * ACCEPT_ALL decision makes the source re-read and publish.
242
+ */
243
+ declare const createTrigger: Trigger.CreateFn<UsercentricsV2Service[], void>;
244
+ /** Attaches the services as the V2 `UC_UI` API before source init. */
245
+ declare const trigger: (input: unknown, env: Record<string, unknown>) => void;
245
246
 
246
247
  declare const index$1_createMockElbFn: typeof createMockElbFn;
247
248
  declare const index$1_createTrigger: typeof createTrigger;
@@ -266,6 +267,12 @@ declare namespace index$1 {
266
267
  declare const SettingsSchema: z.ZodObject<{
267
268
  categoryMap: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
268
269
  explicitOnly: z.ZodOptional<z.ZodBoolean>;
270
+ apiVersion: z.ZodOptional<z.ZodEnum<{
271
+ auto: "auto";
272
+ v2: "v2";
273
+ v3: "v3";
274
+ }>>;
275
+ v3EventName: z.ZodOptional<z.ZodString>;
269
276
  }, z.core.$strip>;
270
277
  type Settings = z.infer<typeof SettingsSchema>;
271
278
 
package/dist/dev.js CHANGED
@@ -1 +1 @@
1
- "use strict";var t,e=Object.defineProperty,i=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,n=Object.prototype.hasOwnProperty,o=(t,i)=>{for(var s in i)e(t,s,{get:i[s],enumerable:!0})},a={};o(a,{examples:()=>r,schemas:()=>j}),module.exports=(t=a,((t,o,a,r)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let c of s(o))n.call(t,c)||c===a||e(t,c,{get:()=>o[c],enumerable:!(r=i(o,c))||r.enumerable});return t})(e({},"__esModule",{value:!0}),t));var r={};o(r,{createMockElbFn:()=>f,createTrigger:()=>P,fullConsentCustomMapped:()=>m,fullConsentMapped:()=>g,minimalConsentMapped:()=>d,noopLogger:()=>v,partialConsentMapped:()=>y,servicesFirstVisitImplicit:()=>u,servicesFullExplicit:()=>c,servicesMinimalExplicit:()=>l,servicesPartialExplicit:()=>p,step:()=>w,trigger:()=>O});var c=[{categorySlug:"essential",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"functional",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"marketing",consent:{status:!0,history:[{type:"explicit",status:!0}]}}],l=[{categorySlug:"essential",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"functional",consent:{status:!1,history:[{type:"explicit",status:!1}]}},{categorySlug:"marketing",consent:{status:!1,history:[{type:"explicit",status:!1}]}}],p=[{categorySlug:"essential",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"functional",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"marketing",consent:{status:!1,history:[{type:"explicit",status:!1}]}}],u=[{categorySlug:"essential",consent:{status:!0,history:[{type:"implicit",status:!0}]}},{categorySlug:"functional",consent:{status:!1,history:[{type:"implicit",status:!1}]}},{categorySlug:"marketing",consent:{status:!1,history:[{type:"implicit",status:!1}]}}],g={essential:!0,functional:!0,marketing:!0},y={essential:!0,functional:!0,marketing:!1},d={essential:!0,functional:!1,marketing:!1},m={functional:!0,analytics:!0,marketing:!0},h=()=>{},f=()=>()=>Promise.resolve({ok:!0}),v={error:h,warn:h,info:h,debug:h,throw:t=>{throw"string"==typeof t?new Error(t):t},json:h,scope:()=>v},w={};o(w,{categoryMapOverride:()=>M,consentChange:()=>x,firstVisitImplicit:()=>S,fullConsent:()=>b,minimalConsent:()=>k,returningVisitor:()=>C});var b={title:"Full consent",description:"Usercentrics reports every category accepted via an explicit decision; the source emits a walker consent command granting essential, functional, and marketing.",trigger:{type:"consent",options:{dispatch:"init"}},in:c,out:[["elb","walker consent",g]]},k={title:"Minimal consent",description:'A "Deny all" explicit decision leaves only essential granted; functional and marketing are emitted as false.',trigger:{type:"consent",options:{dispatch:"init"}},in:l,out:[["elb","walker consent",d]]},C={title:"Returning visitor static read",description:"When the CMP is already initialized with a stored explicit decision, the static read at init re-publishes that choice without any further event.",trigger:{type:"consent",options:{dispatch:"init"}},in:p,out:[["elb","walker consent",{essential:!0,functional:!0,marketing:!1}]]},S={title:"First visit implicit (suppressed)",description:"A first-visit snapshot carrying only implicit history is suppressed by the default explicitOnly gate, so no consent command is emitted.",trigger:{type:"consent",options:{dispatch:"init"}},in:u,out:[]},x={title:"Consent change via CMP event",description:"An ACCEPT_ALL decision fires UC_UI_CMP_EVENT; the source re-reads the services and emits the updated consent.",trigger:{type:"consent",options:{dispatch:"cmp"}},in:c,out:[["elb","walker consent",g]]},M={title:"Category map override",description:"A custom categoryMap remaps essential to functional and functional to analytics before emitting the walker consent command.",trigger:{type:"consent",options:{dispatch:"init"}},in:c,mapping:{settings:{categoryMap:{essential:"functional",functional:"analytics"}}},out:[["elb","walker consent",m]]},E=require("@walkeros/collector"),P=async t=>{let e;return{get flow(){return e},trigger:(i,s)=>async i=>{var n;if(!e){const i=await(0,E.startFlow)({...t,run:null==(n=t.run)||n});e={collector:i.collector,elb:i.elb}}const o=(null==s?void 0:s.eventName)||"ucEvent";window.dispatchEvent(new CustomEvent(o,{detail:i}))}}},O=(t,e)=>{if(t&&"object"==typeof t)return()=>{e.window.dispatchEvent(new CustomEvent("ucEvent",{detail:t}))}},j={};o(j,{SettingsSchema:()=>A,settings:()=>F});var I=require("@walkeros/core/dev"),z=require("@walkeros/core/dev"),A=z.z.object({categoryMap:z.z.record(z.z.string(),z.z.string()).describe("Map the CMP's consent categories (keys) to walkerOS consent groups (values).").optional(),explicitOnly:z.z.boolean().describe("Only publish when the user has actively decided (V3: consent.type EXPLICIT; V2: an EXPLICIT entry in service consent history). Implicit/default page-load states are suppressed. Set false to publish any snapshot including implicit. Default: true.").optional()}).meta({id:"UsercentricsSettings",title:"Settings",description:"Settings for the Usercentrics CMP source."}),F=(0,I.zodToSchema)(A);//# sourceMappingURL=dev.js.map
1
+ "use strict";var t,e=Object.defineProperty,i=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,n=Object.prototype.hasOwnProperty,o=(t,i)=>{for(var s in i)e(t,s,{get:i[s],enumerable:!0})},a={};o(a,{examples:()=>r,schemas:()=>U}),module.exports=(t=a,((t,o,a,r)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let c of s(o))n.call(t,c)||c===a||e(t,c,{get:()=>o[c],enumerable:!(r=i(o,c))||r.enumerable});return t})(e({},"__esModule",{value:!0}),t));var r={};o(r,{createMockElbFn:()=>f,createTrigger:()=>I,fullConsentCustomMapped:()=>h,fullConsentMapped:()=>g,minimalConsentMapped:()=>y,noopLogger:()=>v,partialConsentMapped:()=>d,servicesFirstVisitImplicit:()=>u,servicesFullExplicit:()=>c,servicesMinimalExplicit:()=>l,servicesPartialExplicit:()=>p,step:()=>w,trigger:()=>P});var c=[{categorySlug:"essential",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"functional",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"marketing",consent:{status:!0,history:[{type:"explicit",status:!0}]}}],l=[{categorySlug:"essential",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"functional",consent:{status:!1,history:[{type:"explicit",status:!1}]}},{categorySlug:"marketing",consent:{status:!1,history:[{type:"explicit",status:!1}]}}],p=[{categorySlug:"essential",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"functional",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"marketing",consent:{status:!1,history:[{type:"explicit",status:!1}]}}],u=[{categorySlug:"essential",consent:{status:!0,history:[{type:"implicit",status:!0}]}},{categorySlug:"functional",consent:{status:!1,history:[{type:"implicit",status:!1}]}},{categorySlug:"marketing",consent:{status:!1,history:[{type:"implicit",status:!1}]}}],g={essential:!0,functional:!0,marketing:!0},d={essential:!0,functional:!0,marketing:!1},y={essential:!0,functional:!1,marketing:!1},h={functional:!0,analytics:!0,marketing:!0},m=()=>{},f=()=>()=>Promise.resolve({ok:!0}),v={error:m,warn:m,info:m,debug:m,throw:t=>{throw"string"==typeof t?new Error(t):t},json:m,scope:()=>v},w={};o(w,{categoryMapOverride:()=>S,consentChange:()=>_,firstVisitImplicit:()=>E,fullConsent:()=>C,minimalConsent:()=>b,returningVisitor:()=>k});var C={title:"Full consent",description:"Usercentrics reports every category accepted via an explicit decision; the source emits a walker consent command granting essential, functional, and marketing.",trigger:{type:"consent",options:{dispatch:"init"}},in:c,out:[["elb","walker consent",g]]},b={title:"Minimal consent",description:'A "Deny all" explicit decision leaves only essential granted; functional and marketing are emitted as false.',trigger:{type:"consent",options:{dispatch:"init"}},in:l,out:[["elb","walker consent",y]]},k={title:"Returning visitor static read",description:"When the CMP is already initialized with a stored explicit decision, the static read at init re-publishes that choice without any further event.",trigger:{type:"consent",options:{dispatch:"init"}},in:p,out:[["elb","walker consent",{essential:!0,functional:!0,marketing:!1}]]},E={title:"First visit implicit (suppressed)",description:"A first-visit snapshot carrying only implicit history is suppressed by the default explicitOnly gate, so no consent command is emitted.",trigger:{type:"consent",options:{dispatch:"init"}},in:u,out:[]},_={title:"Consent change via CMP event",description:"An ACCEPT_ALL decision fires UC_UI_CMP_EVENT; the source re-reads the services and emits the updated consent.",trigger:{type:"consent",options:{dispatch:"cmp"}},in:c,out:[["elb","walker consent",g]]},S={title:"Category map override",description:"A custom categoryMap remaps essential to functional and functional to analytics before emitting the walker consent command.",trigger:{type:"consent",options:{dispatch:"init"}},in:c,mapping:{settings:{categoryMap:{essential:"functional",functional:"analytics"}}},out:[["elb","walker consent",h]]},M=require("@walkeros/collector"),I=async t=>{let e;return{get flow(){return e},trigger:(i,s)=>async i=>{var n;const o=s&&"object"==typeof s&&"dispatch"in s&&"cmp"===s.dispatch?"cmp":"init",a={isInitialized:()=>!0,getServicesBaseInfo:()=>i};if("init"===o&&(window.UC_UI=a),!e){const i=await(0,M.startFlow)({...t,run:null==(n=t.run)||n});e={collector:i.collector,elb:i.elb}}"cmp"===o&&(window.UC_UI=a,window.dispatchEvent(new CustomEvent("UC_UI_CMP_EVENT",{detail:{source:"button",type:"ACCEPT_ALL"}})))}}},P=(t,e)=>{const i=e.window;var s;Array.isArray(t)&&("object"==typeof(s=i)&&null!==s&&"addEventListener"in s)&&(i.UC_UI={isInitialized:()=>!0,getServicesBaseInfo:()=>t})};var U={};o(U,{SettingsSchema:()=>V,settings:()=>O});var x=require("@walkeros/core/dev"),A=require("@walkeros/core/dev"),V=A.z.object({categoryMap:A.z.record(A.z.string(),A.z.string()).describe("Map the CMP's consent categories (keys) to walkerOS consent groups (values).").optional(),explicitOnly:A.z.boolean().describe("Only publish when the user has actively decided (V3: consent.type EXPLICIT; V2: an EXPLICIT entry in service consent history). Implicit/default page-load states are suppressed. Set false to publish any snapshot including implicit. Default: true.").optional(),apiVersion:A.z.enum(["auto","v2","v3"]).describe("Which Usercentrics API to use. 'auto' uses V3 (window.__ucCmp) when present, else V2 (window.UC_UI), and listens for both while neither is loaded. Default: 'auto'.").optional(),v3EventName:A.z.string().describe("Window event the V3 adapter listens to for consent decisions, replacing UC_UI_CMP_EVENT. Only events whose detail.type is ACCEPT_ALL, DENY_ALL or SAVE are processed. Default: 'UC_UI_CMP_EVENT'.").optional()}).meta({id:"UsercentricsSettings",title:"Settings",description:"Settings for the Usercentrics CMP source."}),O=(0,x.zodToSchema)(V);//# sourceMappingURL=dev.js.map
package/dist/dev.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/dev.ts","../src/examples/index.ts","../src/examples/inputs.ts","../src/examples/outputs.ts","../src/examples/env.ts","../src/examples/step.ts","../src/examples/trigger.ts","../src/schemas/index.ts","../src/schemas/settings.ts"],"sourcesContent":["/**\n * Development exports for testing and tooling.\n */\nexport * as examples from './examples';\nexport * as schemas from './schemas';\n","export * from './inputs';\nexport * from './outputs';\nexport * from './env';\nexport * as step from './step';\nexport { createTrigger, trigger } from './trigger';\n","import type { UsercentricsV2Service } from '../types';\n\n/**\n * Example Usercentrics V2 service inputs.\n *\n * These mirror the shape returned by `window.UC_UI.getServicesBaseInfo()`:\n * an array of services, each carrying a `categorySlug`, optional display\n * `name`, and a `consent` block with the current `status` plus a decision\n * `history`. The adapter derives the explicit/implicit gate from whether any\n * history entry is `explicit`, and aggregates services into group-level\n * consent via strict AND per `categorySlug`.\n */\n\n/**\n * Full consent - every category accepted via an explicit decision\n * (user clicked \"Accept all\").\n */\nexport const servicesFullExplicit: UsercentricsV2Service[] = [\n {\n categorySlug: 'essential',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'functional',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'marketing',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n];\n\n/**\n * Minimal consent - only essential accepted, others denied via an explicit\n * decision (user clicked \"Deny all\").\n */\nexport const servicesMinimalExplicit: UsercentricsV2Service[] = [\n {\n categorySlug: 'essential',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'functional',\n consent: { status: false, history: [{ type: 'explicit', status: false }] },\n },\n {\n categorySlug: 'marketing',\n consent: { status: false, history: [{ type: 'explicit', status: false }] },\n },\n];\n\n/**\n * Partial consent - essential and functional accepted, marketing denied,\n * all via an explicit decision (user saved a custom selection).\n */\nexport const servicesPartialExplicit: UsercentricsV2Service[] = [\n {\n categorySlug: 'essential',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'functional',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'marketing',\n consent: { status: false, history: [{ type: 'explicit', status: false }] },\n },\n];\n\n/**\n * First-visit implicit state - the CMP reports page-load defaults with only\n * implicit history. The default `explicitOnly` gate suppresses this, so no\n * consent command is emitted.\n */\nexport const servicesFirstVisitImplicit: UsercentricsV2Service[] = [\n {\n categorySlug: 'essential',\n consent: { status: true, history: [{ type: 'implicit', status: true }] },\n },\n {\n categorySlug: 'functional',\n consent: { status: false, history: [{ type: 'implicit', status: false }] },\n },\n {\n categorySlug: 'marketing',\n consent: { status: false, history: [{ type: 'implicit', status: false }] },\n },\n];\n","import type { WalkerOS } from '@walkeros/core';\n\n/**\n * Expected walkerOS consent outputs.\n *\n * These represent the consent state emitted via `elb('walker consent', state)`\n * after the V2 adapter aggregates `getServicesBaseInfo()` into group-level\n * consent (no category mapping configured: pass-through by `categorySlug`).\n */\n\n/**\n * Full consent - all categories granted.\n */\nexport const fullConsentMapped: WalkerOS.Consent = {\n essential: true,\n functional: true,\n marketing: true,\n};\n\n/**\n * Partial consent - essential and functional granted, marketing denied.\n */\nexport const partialConsentMapped: WalkerOS.Consent = {\n essential: true,\n functional: true,\n marketing: false,\n};\n\n/**\n * Minimal consent - only essential granted.\n */\nexport const minimalConsentMapped: WalkerOS.Consent = {\n essential: true,\n functional: false,\n marketing: false,\n};\n\n/**\n * Full consent with a custom category mapping applied\n * (essential->functional, functional->analytics).\n */\nexport const fullConsentCustomMapped: WalkerOS.Consent = {\n functional: true,\n analytics: true,\n marketing: true,\n};\n","import type { Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for Usercentrics source testing.\n */\n\nconst noop = () => {};\n\n/**\n * Create a properly typed elb/push function mock\n */\nexport const createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n/**\n * Simple no-op logger for demo purposes\n */\nexport const noopLogger: Logger.Instance = {\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noop,\n scope: () => noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\nimport {\n servicesFullExplicit,\n servicesMinimalExplicit,\n servicesPartialExplicit,\n servicesFirstVisitImplicit,\n} from './inputs';\nimport {\n fullConsentMapped,\n minimalConsentMapped,\n fullConsentCustomMapped,\n} from './outputs';\n\n/**\n * Step examples for the Usercentrics V2 path.\n *\n * `in` is the array returned by `window.UC_UI.getServicesBaseInfo()`. The test\n * runner attaches it as the V2 API, then drives the official trigger named in\n * `trigger.options.dispatch`:\n * - 'init' (default): UC_UI is present when the source runs, so the static\n * read at init emits the snapshot (also the `UC_UI_INITIALIZED` path).\n * - 'cmp': UC_UI is attached only after init, then a `UC_UI_CMP_EVENT`\n * decision (ACCEPT_ALL) re-reads and emits — the consent-change path.\n */\n\nexport const fullConsent: Flow.StepExample = {\n title: 'Full consent',\n description:\n 'Usercentrics reports every category accepted via an explicit decision; the source emits a walker consent command granting essential, functional, and marketing.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesFullExplicit,\n out: [['elb', 'walker consent', fullConsentMapped]],\n};\n\nexport const minimalConsent: Flow.StepExample = {\n title: 'Minimal consent',\n description:\n 'A \"Deny all\" explicit decision leaves only essential granted; functional and marketing are emitted as false.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesMinimalExplicit,\n out: [['elb', 'walker consent', minimalConsentMapped]],\n};\n\nexport const returningVisitor: Flow.StepExample = {\n title: 'Returning visitor static read',\n description:\n 'When the CMP is already initialized with a stored explicit decision, the static read at init re-publishes that choice without any further event.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesPartialExplicit,\n out: [\n [\n 'elb',\n 'walker consent',\n {\n essential: true,\n functional: true,\n marketing: false,\n },\n ],\n ],\n};\n\nexport const firstVisitImplicit: Flow.StepExample = {\n title: 'First visit implicit (suppressed)',\n description:\n 'A first-visit snapshot carrying only implicit history is suppressed by the default explicitOnly gate, so no consent command is emitted.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesFirstVisitImplicit,\n out: [],\n};\n\nexport const consentChange: Flow.StepExample = {\n title: 'Consent change via CMP event',\n description:\n 'An ACCEPT_ALL decision fires UC_UI_CMP_EVENT; the source re-reads the services and emits the updated consent.',\n trigger: { type: 'consent', options: { dispatch: 'cmp' } },\n in: servicesFullExplicit,\n out: [['elb', 'walker consent', fullConsentMapped]],\n};\n\nexport const categoryMapOverride: Flow.StepExample = {\n title: 'Category map override',\n description:\n 'A custom categoryMap remaps essential to functional and functional to analytics before emitting the walker consent command.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesFullExplicit,\n mapping: {\n settings: {\n categoryMap: { essential: 'functional', functional: 'analytics' },\n },\n },\n out: [['elb', 'walker consent', fullConsentCustomMapped]],\n};\n","import type { Trigger, Collector } from '@walkeros/core';\nimport { startFlow } from '@walkeros/collector';\n\ninterface UsercentricsContent {\n event: string;\n type: string;\n action?: string;\n ucCategory?: Record<string, boolean | unknown>;\n [service: string]: unknown;\n}\n\nconst createTrigger: Trigger.CreateFn<UsercentricsContent, void> = async (\n config: Collector.InitConfig,\n) => {\n let flow: Trigger.FlowHandle | undefined;\n\n const trigger: Trigger.Fn<UsercentricsContent, void> =\n (type?: string, opts?: unknown) => async (content: UsercentricsContent) => {\n // Lazy startFlow — source registers ucEvent listener during init\n if (!flow) {\n const result = await startFlow({ ...config, run: config.run ?? true });\n flow = { collector: result.collector, elb: result.elb };\n }\n\n // Dispatch the CMP event — source's listener catches it\n const eventName =\n (opts as { eventName?: string })?.eventName || 'ucEvent';\n window.dispatchEvent(new CustomEvent(eventName, { detail: content }));\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\n/** Dispatches ucEvent CustomEvent after source init (post-init trigger). */\nconst trigger = (\n input: unknown,\n env: Record<string, unknown>,\n): void | (() => void) => {\n if (!input || typeof input !== 'object') return;\n return () => {\n (env.window as Window).dispatchEvent(\n new CustomEvent('ucEvent', { detail: input }),\n );\n };\n};\n\nexport { createTrigger, trigger };\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Usercentrics source settings schema\n */\nexport const SettingsSchema = z\n .object({\n categoryMap: z\n .record(z.string(), z.string())\n .describe(\n \"Map the CMP's consent categories (keys) to walkerOS consent groups (values).\",\n )\n .optional(),\n\n explicitOnly: z\n .boolean()\n .describe(\n 'Only publish when the user has actively decided (V3: consent.type EXPLICIT; V2: an EXPLICIT entry in service consent history). Implicit/default page-load states are suppressed. Set false to publish any snapshot including implicit. Default: true.',\n )\n .optional(),\n })\n .meta({\n id: 'UsercentricsSettings',\n title: 'Settings',\n description: 'Settings for the Usercentrics CMP source.',\n });\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n"],"mappings":"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","names":["trigger","import_dev"]}
1
+ {"version":3,"sources":["../src/dev.ts","../src/examples/index.ts","../src/examples/inputs.ts","../src/examples/outputs.ts","../src/examples/env.ts","../src/examples/step.ts","../src/examples/trigger.ts","../src/schemas/index.ts","../src/schemas/settings.ts"],"sourcesContent":["/**\n * Development exports for testing and tooling.\n */\nexport * as examples from './examples';\nexport * as schemas from './schemas';\n","export * from './inputs';\nexport * from './outputs';\nexport * from './env';\nexport * as step from './step';\nexport { createTrigger, trigger } from './trigger';\n","import type { UsercentricsV2Service } from '../types';\n\n/**\n * Example Usercentrics V2 service inputs.\n *\n * These mirror the shape returned by `window.UC_UI.getServicesBaseInfo()`:\n * an array of services, each carrying a `categorySlug`, optional display\n * `name`, and a `consent` block with the current `status` plus a decision\n * `history`. The adapter derives the explicit/implicit gate from whether any\n * history entry is `explicit`, and aggregates services into group-level\n * consent via strict AND per `categorySlug`.\n */\n\n/**\n * Full consent - every category accepted via an explicit decision\n * (user clicked \"Accept all\").\n */\nexport const servicesFullExplicit: UsercentricsV2Service[] = [\n {\n categorySlug: 'essential',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'functional',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'marketing',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n];\n\n/**\n * Minimal consent - only essential accepted, others denied via an explicit\n * decision (user clicked \"Deny all\").\n */\nexport const servicesMinimalExplicit: UsercentricsV2Service[] = [\n {\n categorySlug: 'essential',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'functional',\n consent: { status: false, history: [{ type: 'explicit', status: false }] },\n },\n {\n categorySlug: 'marketing',\n consent: { status: false, history: [{ type: 'explicit', status: false }] },\n },\n];\n\n/**\n * Partial consent - essential and functional accepted, marketing denied,\n * all via an explicit decision (user saved a custom selection).\n */\nexport const servicesPartialExplicit: UsercentricsV2Service[] = [\n {\n categorySlug: 'essential',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'functional',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'marketing',\n consent: { status: false, history: [{ type: 'explicit', status: false }] },\n },\n];\n\n/**\n * First-visit implicit state - the CMP reports page-load defaults with only\n * implicit history. The default `explicitOnly` gate suppresses this, so no\n * consent command is emitted.\n */\nexport const servicesFirstVisitImplicit: UsercentricsV2Service[] = [\n {\n categorySlug: 'essential',\n consent: { status: true, history: [{ type: 'implicit', status: true }] },\n },\n {\n categorySlug: 'functional',\n consent: { status: false, history: [{ type: 'implicit', status: false }] },\n },\n {\n categorySlug: 'marketing',\n consent: { status: false, history: [{ type: 'implicit', status: false }] },\n },\n];\n","import type { WalkerOS } from '@walkeros/core';\n\n/**\n * Expected walkerOS consent outputs.\n *\n * These represent the consent state emitted via `elb('walker consent', state)`\n * after the V2 adapter aggregates `getServicesBaseInfo()` into group-level\n * consent (no category mapping configured: pass-through by `categorySlug`).\n */\n\n/**\n * Full consent - all categories granted.\n */\nexport const fullConsentMapped: WalkerOS.Consent = {\n essential: true,\n functional: true,\n marketing: true,\n};\n\n/**\n * Partial consent - essential and functional granted, marketing denied.\n */\nexport const partialConsentMapped: WalkerOS.Consent = {\n essential: true,\n functional: true,\n marketing: false,\n};\n\n/**\n * Minimal consent - only essential granted.\n */\nexport const minimalConsentMapped: WalkerOS.Consent = {\n essential: true,\n functional: false,\n marketing: false,\n};\n\n/**\n * Full consent with a custom category mapping applied\n * (essential->functional, functional->analytics).\n */\nexport const fullConsentCustomMapped: WalkerOS.Consent = {\n functional: true,\n analytics: true,\n marketing: true,\n};\n","import type { Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for Usercentrics source testing.\n */\n\nconst noop = () => {};\n\n/**\n * Create a properly typed elb/push function mock\n */\nexport const createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n/**\n * Simple no-op logger for demo purposes\n */\nexport const noopLogger: Logger.Instance = {\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noop,\n scope: () => noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\nimport {\n servicesFullExplicit,\n servicesMinimalExplicit,\n servicesPartialExplicit,\n servicesFirstVisitImplicit,\n} from './inputs';\nimport {\n fullConsentMapped,\n minimalConsentMapped,\n fullConsentCustomMapped,\n} from './outputs';\n\n/**\n * Step examples for the Usercentrics V2 path.\n *\n * `in` is the array returned by `window.UC_UI.getServicesBaseInfo()`. The test\n * runner attaches it as the V2 API, then drives the official trigger named in\n * `trigger.options.dispatch`:\n * - 'init' (default): UC_UI is present when the source runs, so the static\n * read at init emits the snapshot (also the `UC_UI_INITIALIZED` path).\n * - 'cmp': UC_UI is attached only after init, then a `UC_UI_CMP_EVENT`\n * decision (ACCEPT_ALL) re-reads and emits — the consent-change path.\n */\n\nexport const fullConsent: Flow.StepExample = {\n title: 'Full consent',\n description:\n 'Usercentrics reports every category accepted via an explicit decision; the source emits a walker consent command granting essential, functional, and marketing.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesFullExplicit,\n out: [['elb', 'walker consent', fullConsentMapped]],\n};\n\nexport const minimalConsent: Flow.StepExample = {\n title: 'Minimal consent',\n description:\n 'A \"Deny all\" explicit decision leaves only essential granted; functional and marketing are emitted as false.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesMinimalExplicit,\n out: [['elb', 'walker consent', minimalConsentMapped]],\n};\n\nexport const returningVisitor: Flow.StepExample = {\n title: 'Returning visitor static read',\n description:\n 'When the CMP is already initialized with a stored explicit decision, the static read at init re-publishes that choice without any further event.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesPartialExplicit,\n out: [\n [\n 'elb',\n 'walker consent',\n {\n essential: true,\n functional: true,\n marketing: false,\n },\n ],\n ],\n};\n\nexport const firstVisitImplicit: Flow.StepExample = {\n title: 'First visit implicit (suppressed)',\n description:\n 'A first-visit snapshot carrying only implicit history is suppressed by the default explicitOnly gate, so no consent command is emitted.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesFirstVisitImplicit,\n out: [],\n};\n\nexport const consentChange: Flow.StepExample = {\n title: 'Consent change via CMP event',\n description:\n 'An ACCEPT_ALL decision fires UC_UI_CMP_EVENT; the source re-reads the services and emits the updated consent.',\n trigger: { type: 'consent', options: { dispatch: 'cmp' } },\n in: servicesFullExplicit,\n out: [['elb', 'walker consent', fullConsentMapped]],\n};\n\nexport const categoryMapOverride: Flow.StepExample = {\n title: 'Category map override',\n description:\n 'A custom categoryMap remaps essential to functional and functional to analytics before emitting the walker consent command.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesFullExplicit,\n mapping: {\n settings: {\n categoryMap: { essential: 'functional', functional: 'analytics' },\n },\n },\n out: [['elb', 'walker consent', fullConsentCustomMapped]],\n};\n","import type { Trigger, Collector } from '@walkeros/core';\nimport { startFlow } from '@walkeros/collector';\nimport type { UsercentricsV2Api, UsercentricsV2Service } from '../types';\n\n/**\n * `content` is what `window.UC_UI.getServicesBaseInfo()` returns. The\n * `dispatch` option picks the official path the source reacts to:\n * - 'init' (default): UC_UI is attached before the source runs, so the\n * static read at init publishes the snapshot.\n * - 'cmp': UC_UI is attached after init, then a `UC_UI_CMP_EVENT`\n * ACCEPT_ALL decision makes the source re-read and publish.\n */\nconst createTrigger: Trigger.CreateFn<UsercentricsV2Service[], void> = async (\n config: Collector.InitConfig,\n) => {\n let flow: Trigger.FlowHandle | undefined;\n\n const trigger: Trigger.Fn<UsercentricsV2Service[], void> =\n (_type?: string, opts?: unknown) =>\n async (content: UsercentricsV2Service[]) => {\n const dispatch =\n opts &&\n typeof opts === 'object' &&\n 'dispatch' in opts &&\n opts.dispatch === 'cmp'\n ? 'cmp'\n : 'init';\n const ucUi: UsercentricsV2Api = {\n isInitialized: () => true,\n getServicesBaseInfo: () => content,\n };\n\n if (dispatch === 'init') window.UC_UI = ucUi;\n\n // Lazy startFlow: the source attaches its listeners and does the\n // static read during init.\n if (!flow) {\n const result = await startFlow({ ...config, run: config.run ?? true });\n flow = { collector: result.collector, elb: result.elb };\n }\n\n if (dispatch === 'cmp') {\n window.UC_UI = ucUi;\n window.dispatchEvent(\n new CustomEvent('UC_UI_CMP_EVENT', {\n detail: { source: 'button', type: 'ACCEPT_ALL' },\n }),\n );\n }\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\n/** Attaches the services as the V2 `UC_UI` API before source init. */\nconst trigger = (input: unknown, env: Record<string, unknown>): void => {\n const win = env.window;\n if (!Array.isArray(input) || !isWindow(win)) return;\n win.UC_UI = {\n isInitialized: () => true,\n getServicesBaseInfo: () => input,\n };\n};\n\nfunction isWindow(value: unknown): value is Window {\n return (\n typeof value === 'object' && value !== null && 'addEventListener' in value\n );\n}\n\nexport { createTrigger, trigger };\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Usercentrics source settings schema\n */\nexport const SettingsSchema = z\n .object({\n categoryMap: z\n .record(z.string(), z.string())\n .describe(\n \"Map the CMP's consent categories (keys) to walkerOS consent groups (values).\",\n )\n .optional(),\n\n explicitOnly: z\n .boolean()\n .describe(\n 'Only publish when the user has actively decided (V3: consent.type EXPLICIT; V2: an EXPLICIT entry in service consent history). Implicit/default page-load states are suppressed. Set false to publish any snapshot including implicit. Default: true.',\n )\n .optional(),\n\n apiVersion: z\n .enum(['auto', 'v2', 'v3'])\n .describe(\n \"Which Usercentrics API to use. 'auto' uses V3 (window.__ucCmp) when present, else V2 (window.UC_UI), and listens for both while neither is loaded. Default: 'auto'.\",\n )\n .optional(),\n\n v3EventName: z\n .string()\n .describe(\n \"Window event the V3 adapter listens to for consent decisions, replacing UC_UI_CMP_EVENT. Only events whose detail.type is ACCEPT_ALL, DENY_ALL or SAVE are processed. Default: 'UC_UI_CMP_EVENT'.\",\n )\n .optional(),\n })\n .meta({\n id: 'UsercentricsSettings',\n title: 'Settings',\n description: 'Settings for the Usercentrics CMP source.',\n });\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n"],"mappings":"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","names":["trigger","import_dev"]}
package/dist/dev.mjs CHANGED
@@ -1 +1 @@
1
- var t=Object.defineProperty,e=(e,i)=>{for(var s in i)t(e,s,{get:i[s],enumerable:!0})},i={};e(i,{createMockElbFn:()=>g,createTrigger:()=>b,fullConsentCustomMapped:()=>p,fullConsentMapped:()=>r,minimalConsentMapped:()=>l,noopLogger:()=>y,partialConsentMapped:()=>c,servicesFirstVisitImplicit:()=>o,servicesFullExplicit:()=>s,servicesMinimalExplicit:()=>n,servicesPartialExplicit:()=>a,step:()=>d,trigger:()=>x});var s=[{categorySlug:"essential",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"functional",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"marketing",consent:{status:!0,history:[{type:"explicit",status:!0}]}}],n=[{categorySlug:"essential",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"functional",consent:{status:!1,history:[{type:"explicit",status:!1}]}},{categorySlug:"marketing",consent:{status:!1,history:[{type:"explicit",status:!1}]}}],a=[{categorySlug:"essential",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"functional",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"marketing",consent:{status:!1,history:[{type:"explicit",status:!1}]}}],o=[{categorySlug:"essential",consent:{status:!0,history:[{type:"implicit",status:!0}]}},{categorySlug:"functional",consent:{status:!1,history:[{type:"implicit",status:!1}]}},{categorySlug:"marketing",consent:{status:!1,history:[{type:"implicit",status:!1}]}}],r={essential:!0,functional:!0,marketing:!0},c={essential:!0,functional:!0,marketing:!1},l={essential:!0,functional:!1,marketing:!1},p={functional:!0,analytics:!0,marketing:!0},u=()=>{},g=()=>()=>Promise.resolve({ok:!0}),y={error:u,warn:u,info:u,debug:u,throw:t=>{throw"string"==typeof t?new Error(t):t},json:u,scope:()=>y},d={};e(d,{categoryMapOverride:()=>k,consentChange:()=>w,firstVisitImplicit:()=>v,fullConsent:()=>m,minimalConsent:()=>h,returningVisitor:()=>f});var m={title:"Full consent",description:"Usercentrics reports every category accepted via an explicit decision; the source emits a walker consent command granting essential, functional, and marketing.",trigger:{type:"consent",options:{dispatch:"init"}},in:s,out:[["elb","walker consent",r]]},h={title:"Minimal consent",description:'A "Deny all" explicit decision leaves only essential granted; functional and marketing are emitted as false.',trigger:{type:"consent",options:{dispatch:"init"}},in:n,out:[["elb","walker consent",l]]},f={title:"Returning visitor static read",description:"When the CMP is already initialized with a stored explicit decision, the static read at init re-publishes that choice without any further event.",trigger:{type:"consent",options:{dispatch:"init"}},in:a,out:[["elb","walker consent",{essential:!0,functional:!0,marketing:!1}]]},v={title:"First visit implicit (suppressed)",description:"A first-visit snapshot carrying only implicit history is suppressed by the default explicitOnly gate, so no consent command is emitted.",trigger:{type:"consent",options:{dispatch:"init"}},in:o,out:[]},w={title:"Consent change via CMP event",description:"An ACCEPT_ALL decision fires UC_UI_CMP_EVENT; the source re-reads the services and emits the updated consent.",trigger:{type:"consent",options:{dispatch:"cmp"}},in:s,out:[["elb","walker consent",r]]},k={title:"Category map override",description:"A custom categoryMap remaps essential to functional and functional to analytics before emitting the walker consent command.",trigger:{type:"consent",options:{dispatch:"init"}},in:s,mapping:{settings:{categoryMap:{essential:"functional",functional:"analytics"}}},out:[["elb","walker consent",p]]};import{startFlow as C}from"@walkeros/collector";var b=async t=>{let e;return{get flow(){return e},trigger:(i,s)=>async i=>{var n;if(!e){const i=await C({...t,run:null==(n=t.run)||n});e={collector:i.collector,elb:i.elb}}const a=(null==s?void 0:s.eventName)||"ucEvent";window.dispatchEvent(new CustomEvent(a,{detail:i}))}}},x=(t,e)=>{if(t&&"object"==typeof t)return()=>{e.window.dispatchEvent(new CustomEvent("ucEvent",{detail:t}))}},S={};e(S,{SettingsSchema:()=>P,settings:()=>I});import{zodToSchema as M}from"@walkeros/core/dev";import{z as E}from"@walkeros/core/dev";var P=E.object({categoryMap:E.record(E.string(),E.string()).describe("Map the CMP's consent categories (keys) to walkerOS consent groups (values).").optional(),explicitOnly:E.boolean().describe("Only publish when the user has actively decided (V3: consent.type EXPLICIT; V2: an EXPLICIT entry in service consent history). Implicit/default page-load states are suppressed. Set false to publish any snapshot including implicit. Default: true.").optional()}).meta({id:"UsercentricsSettings",title:"Settings",description:"Settings for the Usercentrics CMP source."}),I=M(P);export{i as examples,S as schemas};//# sourceMappingURL=dev.mjs.map
1
+ var t=Object.defineProperty,e=(e,i)=>{for(var s in i)t(e,s,{get:i[s],enumerable:!0})},i={};e(i,{createMockElbFn:()=>g,createTrigger:()=>k,fullConsentCustomMapped:()=>p,fullConsentMapped:()=>r,minimalConsentMapped:()=>l,noopLogger:()=>d,partialConsentMapped:()=>c,servicesFirstVisitImplicit:()=>a,servicesFullExplicit:()=>s,servicesMinimalExplicit:()=>n,servicesPartialExplicit:()=>o,step:()=>y,trigger:()=>E});var s=[{categorySlug:"essential",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"functional",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"marketing",consent:{status:!0,history:[{type:"explicit",status:!0}]}}],n=[{categorySlug:"essential",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"functional",consent:{status:!1,history:[{type:"explicit",status:!1}]}},{categorySlug:"marketing",consent:{status:!1,history:[{type:"explicit",status:!1}]}}],o=[{categorySlug:"essential",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"functional",consent:{status:!0,history:[{type:"explicit",status:!0}]}},{categorySlug:"marketing",consent:{status:!1,history:[{type:"explicit",status:!1}]}}],a=[{categorySlug:"essential",consent:{status:!0,history:[{type:"implicit",status:!0}]}},{categorySlug:"functional",consent:{status:!1,history:[{type:"implicit",status:!1}]}},{categorySlug:"marketing",consent:{status:!1,history:[{type:"implicit",status:!1}]}}],r={essential:!0,functional:!0,marketing:!0},c={essential:!0,functional:!0,marketing:!1},l={essential:!0,functional:!1,marketing:!1},p={functional:!0,analytics:!0,marketing:!0},u=()=>{},g=()=>()=>Promise.resolve({ok:!0}),d={error:u,warn:u,info:u,debug:u,throw:t=>{throw"string"==typeof t?new Error(t):t},json:u,scope:()=>d},y={};e(y,{categoryMapOverride:()=>C,consentChange:()=>w,firstVisitImplicit:()=>v,fullConsent:()=>m,minimalConsent:()=>h,returningVisitor:()=>f});var m={title:"Full consent",description:"Usercentrics reports every category accepted via an explicit decision; the source emits a walker consent command granting essential, functional, and marketing.",trigger:{type:"consent",options:{dispatch:"init"}},in:s,out:[["elb","walker consent",r]]},h={title:"Minimal consent",description:'A "Deny all" explicit decision leaves only essential granted; functional and marketing are emitted as false.',trigger:{type:"consent",options:{dispatch:"init"}},in:n,out:[["elb","walker consent",l]]},f={title:"Returning visitor static read",description:"When the CMP is already initialized with a stored explicit decision, the static read at init re-publishes that choice without any further event.",trigger:{type:"consent",options:{dispatch:"init"}},in:o,out:[["elb","walker consent",{essential:!0,functional:!0,marketing:!1}]]},v={title:"First visit implicit (suppressed)",description:"A first-visit snapshot carrying only implicit history is suppressed by the default explicitOnly gate, so no consent command is emitted.",trigger:{type:"consent",options:{dispatch:"init"}},in:a,out:[]},w={title:"Consent change via CMP event",description:"An ACCEPT_ALL decision fires UC_UI_CMP_EVENT; the source re-reads the services and emits the updated consent.",trigger:{type:"consent",options:{dispatch:"cmp"}},in:s,out:[["elb","walker consent",r]]},C={title:"Category map override",description:"A custom categoryMap remaps essential to functional and functional to analytics before emitting the walker consent command.",trigger:{type:"consent",options:{dispatch:"init"}},in:s,mapping:{settings:{categoryMap:{essential:"functional",functional:"analytics"}}},out:[["elb","walker consent",p]]};import{startFlow as b}from"@walkeros/collector";var k=async t=>{let e;return{get flow(){return e},trigger:(i,s)=>async i=>{var n;const o=s&&"object"==typeof s&&"dispatch"in s&&"cmp"===s.dispatch?"cmp":"init",a={isInitialized:()=>!0,getServicesBaseInfo:()=>i};if("init"===o&&(window.UC_UI=a),!e){const i=await b({...t,run:null==(n=t.run)||n});e={collector:i.collector,elb:i.elb}}"cmp"===o&&(window.UC_UI=a,window.dispatchEvent(new CustomEvent("UC_UI_CMP_EVENT",{detail:{source:"button",type:"ACCEPT_ALL"}})))}}},E=(t,e)=>{const i=e.window;var s;Array.isArray(t)&&("object"==typeof(s=i)&&null!==s&&"addEventListener"in s)&&(i.UC_UI={isInitialized:()=>!0,getServicesBaseInfo:()=>t})};var S={};e(S,{SettingsSchema:()=>M,settings:()=>U});import{zodToSchema as _}from"@walkeros/core/dev";import{z as I}from"@walkeros/core/dev";var M=I.object({categoryMap:I.record(I.string(),I.string()).describe("Map the CMP's consent categories (keys) to walkerOS consent groups (values).").optional(),explicitOnly:I.boolean().describe("Only publish when the user has actively decided (V3: consent.type EXPLICIT; V2: an EXPLICIT entry in service consent history). Implicit/default page-load states are suppressed. Set false to publish any snapshot including implicit. Default: true.").optional(),apiVersion:I.enum(["auto","v2","v3"]).describe("Which Usercentrics API to use. 'auto' uses V3 (window.__ucCmp) when present, else V2 (window.UC_UI), and listens for both while neither is loaded. Default: 'auto'.").optional(),v3EventName:I.string().describe("Window event the V3 adapter listens to for consent decisions, replacing UC_UI_CMP_EVENT. Only events whose detail.type is ACCEPT_ALL, DENY_ALL or SAVE are processed. Default: 'UC_UI_CMP_EVENT'.").optional()}).meta({id:"UsercentricsSettings",title:"Settings",description:"Settings for the Usercentrics CMP source."}),U=_(M);export{i as examples,S as schemas};//# sourceMappingURL=dev.mjs.map
package/dist/dev.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/examples/index.ts","../src/examples/inputs.ts","../src/examples/outputs.ts","../src/examples/env.ts","../src/examples/step.ts","../src/examples/trigger.ts","../src/schemas/index.ts","../src/schemas/settings.ts"],"sourcesContent":["export * from './inputs';\nexport * from './outputs';\nexport * from './env';\nexport * as step from './step';\nexport { createTrigger, trigger } from './trigger';\n","import type { UsercentricsV2Service } from '../types';\n\n/**\n * Example Usercentrics V2 service inputs.\n *\n * These mirror the shape returned by `window.UC_UI.getServicesBaseInfo()`:\n * an array of services, each carrying a `categorySlug`, optional display\n * `name`, and a `consent` block with the current `status` plus a decision\n * `history`. The adapter derives the explicit/implicit gate from whether any\n * history entry is `explicit`, and aggregates services into group-level\n * consent via strict AND per `categorySlug`.\n */\n\n/**\n * Full consent - every category accepted via an explicit decision\n * (user clicked \"Accept all\").\n */\nexport const servicesFullExplicit: UsercentricsV2Service[] = [\n {\n categorySlug: 'essential',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'functional',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'marketing',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n];\n\n/**\n * Minimal consent - only essential accepted, others denied via an explicit\n * decision (user clicked \"Deny all\").\n */\nexport const servicesMinimalExplicit: UsercentricsV2Service[] = [\n {\n categorySlug: 'essential',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'functional',\n consent: { status: false, history: [{ type: 'explicit', status: false }] },\n },\n {\n categorySlug: 'marketing',\n consent: { status: false, history: [{ type: 'explicit', status: false }] },\n },\n];\n\n/**\n * Partial consent - essential and functional accepted, marketing denied,\n * all via an explicit decision (user saved a custom selection).\n */\nexport const servicesPartialExplicit: UsercentricsV2Service[] = [\n {\n categorySlug: 'essential',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'functional',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'marketing',\n consent: { status: false, history: [{ type: 'explicit', status: false }] },\n },\n];\n\n/**\n * First-visit implicit state - the CMP reports page-load defaults with only\n * implicit history. The default `explicitOnly` gate suppresses this, so no\n * consent command is emitted.\n */\nexport const servicesFirstVisitImplicit: UsercentricsV2Service[] = [\n {\n categorySlug: 'essential',\n consent: { status: true, history: [{ type: 'implicit', status: true }] },\n },\n {\n categorySlug: 'functional',\n consent: { status: false, history: [{ type: 'implicit', status: false }] },\n },\n {\n categorySlug: 'marketing',\n consent: { status: false, history: [{ type: 'implicit', status: false }] },\n },\n];\n","import type { WalkerOS } from '@walkeros/core';\n\n/**\n * Expected walkerOS consent outputs.\n *\n * These represent the consent state emitted via `elb('walker consent', state)`\n * after the V2 adapter aggregates `getServicesBaseInfo()` into group-level\n * consent (no category mapping configured: pass-through by `categorySlug`).\n */\n\n/**\n * Full consent - all categories granted.\n */\nexport const fullConsentMapped: WalkerOS.Consent = {\n essential: true,\n functional: true,\n marketing: true,\n};\n\n/**\n * Partial consent - essential and functional granted, marketing denied.\n */\nexport const partialConsentMapped: WalkerOS.Consent = {\n essential: true,\n functional: true,\n marketing: false,\n};\n\n/**\n * Minimal consent - only essential granted.\n */\nexport const minimalConsentMapped: WalkerOS.Consent = {\n essential: true,\n functional: false,\n marketing: false,\n};\n\n/**\n * Full consent with a custom category mapping applied\n * (essential->functional, functional->analytics).\n */\nexport const fullConsentCustomMapped: WalkerOS.Consent = {\n functional: true,\n analytics: true,\n marketing: true,\n};\n","import type { Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for Usercentrics source testing.\n */\n\nconst noop = () => {};\n\n/**\n * Create a properly typed elb/push function mock\n */\nexport const createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n/**\n * Simple no-op logger for demo purposes\n */\nexport const noopLogger: Logger.Instance = {\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noop,\n scope: () => noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\nimport {\n servicesFullExplicit,\n servicesMinimalExplicit,\n servicesPartialExplicit,\n servicesFirstVisitImplicit,\n} from './inputs';\nimport {\n fullConsentMapped,\n minimalConsentMapped,\n fullConsentCustomMapped,\n} from './outputs';\n\n/**\n * Step examples for the Usercentrics V2 path.\n *\n * `in` is the array returned by `window.UC_UI.getServicesBaseInfo()`. The test\n * runner attaches it as the V2 API, then drives the official trigger named in\n * `trigger.options.dispatch`:\n * - 'init' (default): UC_UI is present when the source runs, so the static\n * read at init emits the snapshot (also the `UC_UI_INITIALIZED` path).\n * - 'cmp': UC_UI is attached only after init, then a `UC_UI_CMP_EVENT`\n * decision (ACCEPT_ALL) re-reads and emits — the consent-change path.\n */\n\nexport const fullConsent: Flow.StepExample = {\n title: 'Full consent',\n description:\n 'Usercentrics reports every category accepted via an explicit decision; the source emits a walker consent command granting essential, functional, and marketing.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesFullExplicit,\n out: [['elb', 'walker consent', fullConsentMapped]],\n};\n\nexport const minimalConsent: Flow.StepExample = {\n title: 'Minimal consent',\n description:\n 'A \"Deny all\" explicit decision leaves only essential granted; functional and marketing are emitted as false.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesMinimalExplicit,\n out: [['elb', 'walker consent', minimalConsentMapped]],\n};\n\nexport const returningVisitor: Flow.StepExample = {\n title: 'Returning visitor static read',\n description:\n 'When the CMP is already initialized with a stored explicit decision, the static read at init re-publishes that choice without any further event.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesPartialExplicit,\n out: [\n [\n 'elb',\n 'walker consent',\n {\n essential: true,\n functional: true,\n marketing: false,\n },\n ],\n ],\n};\n\nexport const firstVisitImplicit: Flow.StepExample = {\n title: 'First visit implicit (suppressed)',\n description:\n 'A first-visit snapshot carrying only implicit history is suppressed by the default explicitOnly gate, so no consent command is emitted.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesFirstVisitImplicit,\n out: [],\n};\n\nexport const consentChange: Flow.StepExample = {\n title: 'Consent change via CMP event',\n description:\n 'An ACCEPT_ALL decision fires UC_UI_CMP_EVENT; the source re-reads the services and emits the updated consent.',\n trigger: { type: 'consent', options: { dispatch: 'cmp' } },\n in: servicesFullExplicit,\n out: [['elb', 'walker consent', fullConsentMapped]],\n};\n\nexport const categoryMapOverride: Flow.StepExample = {\n title: 'Category map override',\n description:\n 'A custom categoryMap remaps essential to functional and functional to analytics before emitting the walker consent command.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesFullExplicit,\n mapping: {\n settings: {\n categoryMap: { essential: 'functional', functional: 'analytics' },\n },\n },\n out: [['elb', 'walker consent', fullConsentCustomMapped]],\n};\n","import type { Trigger, Collector } from '@walkeros/core';\nimport { startFlow } from '@walkeros/collector';\n\ninterface UsercentricsContent {\n event: string;\n type: string;\n action?: string;\n ucCategory?: Record<string, boolean | unknown>;\n [service: string]: unknown;\n}\n\nconst createTrigger: Trigger.CreateFn<UsercentricsContent, void> = async (\n config: Collector.InitConfig,\n) => {\n let flow: Trigger.FlowHandle | undefined;\n\n const trigger: Trigger.Fn<UsercentricsContent, void> =\n (type?: string, opts?: unknown) => async (content: UsercentricsContent) => {\n // Lazy startFlow — source registers ucEvent listener during init\n if (!flow) {\n const result = await startFlow({ ...config, run: config.run ?? true });\n flow = { collector: result.collector, elb: result.elb };\n }\n\n // Dispatch the CMP event — source's listener catches it\n const eventName =\n (opts as { eventName?: string })?.eventName || 'ucEvent';\n window.dispatchEvent(new CustomEvent(eventName, { detail: content }));\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\n/** Dispatches ucEvent CustomEvent after source init (post-init trigger). */\nconst trigger = (\n input: unknown,\n env: Record<string, unknown>,\n): void | (() => void) => {\n if (!input || typeof input !== 'object') return;\n return () => {\n (env.window as Window).dispatchEvent(\n new CustomEvent('ucEvent', { detail: input }),\n );\n };\n};\n\nexport { createTrigger, trigger };\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Usercentrics source settings schema\n */\nexport const SettingsSchema = z\n .object({\n categoryMap: z\n .record(z.string(), z.string())\n .describe(\n \"Map the CMP's consent categories (keys) to walkerOS consent groups (values).\",\n )\n .optional(),\n\n explicitOnly: z\n .boolean()\n .describe(\n 'Only publish when the user has actively decided (V3: consent.type EXPLICIT; V2: an EXPLICIT entry in service consent history). Implicit/default page-load states are suppressed. Set false to publish any snapshot including implicit. Default: true.',\n )\n .optional(),\n })\n .meta({\n id: 'UsercentricsSettings',\n title: 'Settings',\n description: 'Settings for the Usercentrics CMP source.',\n });\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n"],"mappings":"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","names":["trigger"]}
1
+ {"version":3,"sources":["../src/examples/index.ts","../src/examples/inputs.ts","../src/examples/outputs.ts","../src/examples/env.ts","../src/examples/step.ts","../src/examples/trigger.ts","../src/schemas/index.ts","../src/schemas/settings.ts"],"sourcesContent":["export * from './inputs';\nexport * from './outputs';\nexport * from './env';\nexport * as step from './step';\nexport { createTrigger, trigger } from './trigger';\n","import type { UsercentricsV2Service } from '../types';\n\n/**\n * Example Usercentrics V2 service inputs.\n *\n * These mirror the shape returned by `window.UC_UI.getServicesBaseInfo()`:\n * an array of services, each carrying a `categorySlug`, optional display\n * `name`, and a `consent` block with the current `status` plus a decision\n * `history`. The adapter derives the explicit/implicit gate from whether any\n * history entry is `explicit`, and aggregates services into group-level\n * consent via strict AND per `categorySlug`.\n */\n\n/**\n * Full consent - every category accepted via an explicit decision\n * (user clicked \"Accept all\").\n */\nexport const servicesFullExplicit: UsercentricsV2Service[] = [\n {\n categorySlug: 'essential',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'functional',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'marketing',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n];\n\n/**\n * Minimal consent - only essential accepted, others denied via an explicit\n * decision (user clicked \"Deny all\").\n */\nexport const servicesMinimalExplicit: UsercentricsV2Service[] = [\n {\n categorySlug: 'essential',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'functional',\n consent: { status: false, history: [{ type: 'explicit', status: false }] },\n },\n {\n categorySlug: 'marketing',\n consent: { status: false, history: [{ type: 'explicit', status: false }] },\n },\n];\n\n/**\n * Partial consent - essential and functional accepted, marketing denied,\n * all via an explicit decision (user saved a custom selection).\n */\nexport const servicesPartialExplicit: UsercentricsV2Service[] = [\n {\n categorySlug: 'essential',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'functional',\n consent: { status: true, history: [{ type: 'explicit', status: true }] },\n },\n {\n categorySlug: 'marketing',\n consent: { status: false, history: [{ type: 'explicit', status: false }] },\n },\n];\n\n/**\n * First-visit implicit state - the CMP reports page-load defaults with only\n * implicit history. The default `explicitOnly` gate suppresses this, so no\n * consent command is emitted.\n */\nexport const servicesFirstVisitImplicit: UsercentricsV2Service[] = [\n {\n categorySlug: 'essential',\n consent: { status: true, history: [{ type: 'implicit', status: true }] },\n },\n {\n categorySlug: 'functional',\n consent: { status: false, history: [{ type: 'implicit', status: false }] },\n },\n {\n categorySlug: 'marketing',\n consent: { status: false, history: [{ type: 'implicit', status: false }] },\n },\n];\n","import type { WalkerOS } from '@walkeros/core';\n\n/**\n * Expected walkerOS consent outputs.\n *\n * These represent the consent state emitted via `elb('walker consent', state)`\n * after the V2 adapter aggregates `getServicesBaseInfo()` into group-level\n * consent (no category mapping configured: pass-through by `categorySlug`).\n */\n\n/**\n * Full consent - all categories granted.\n */\nexport const fullConsentMapped: WalkerOS.Consent = {\n essential: true,\n functional: true,\n marketing: true,\n};\n\n/**\n * Partial consent - essential and functional granted, marketing denied.\n */\nexport const partialConsentMapped: WalkerOS.Consent = {\n essential: true,\n functional: true,\n marketing: false,\n};\n\n/**\n * Minimal consent - only essential granted.\n */\nexport const minimalConsentMapped: WalkerOS.Consent = {\n essential: true,\n functional: false,\n marketing: false,\n};\n\n/**\n * Full consent with a custom category mapping applied\n * (essential->functional, functional->analytics).\n */\nexport const fullConsentCustomMapped: WalkerOS.Consent = {\n functional: true,\n analytics: true,\n marketing: true,\n};\n","import type { Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for Usercentrics source testing.\n */\n\nconst noop = () => {};\n\n/**\n * Create a properly typed elb/push function mock\n */\nexport const createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n/**\n * Simple no-op logger for demo purposes\n */\nexport const noopLogger: Logger.Instance = {\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noop,\n scope: () => noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\nimport {\n servicesFullExplicit,\n servicesMinimalExplicit,\n servicesPartialExplicit,\n servicesFirstVisitImplicit,\n} from './inputs';\nimport {\n fullConsentMapped,\n minimalConsentMapped,\n fullConsentCustomMapped,\n} from './outputs';\n\n/**\n * Step examples for the Usercentrics V2 path.\n *\n * `in` is the array returned by `window.UC_UI.getServicesBaseInfo()`. The test\n * runner attaches it as the V2 API, then drives the official trigger named in\n * `trigger.options.dispatch`:\n * - 'init' (default): UC_UI is present when the source runs, so the static\n * read at init emits the snapshot (also the `UC_UI_INITIALIZED` path).\n * - 'cmp': UC_UI is attached only after init, then a `UC_UI_CMP_EVENT`\n * decision (ACCEPT_ALL) re-reads and emits — the consent-change path.\n */\n\nexport const fullConsent: Flow.StepExample = {\n title: 'Full consent',\n description:\n 'Usercentrics reports every category accepted via an explicit decision; the source emits a walker consent command granting essential, functional, and marketing.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesFullExplicit,\n out: [['elb', 'walker consent', fullConsentMapped]],\n};\n\nexport const minimalConsent: Flow.StepExample = {\n title: 'Minimal consent',\n description:\n 'A \"Deny all\" explicit decision leaves only essential granted; functional and marketing are emitted as false.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesMinimalExplicit,\n out: [['elb', 'walker consent', minimalConsentMapped]],\n};\n\nexport const returningVisitor: Flow.StepExample = {\n title: 'Returning visitor static read',\n description:\n 'When the CMP is already initialized with a stored explicit decision, the static read at init re-publishes that choice without any further event.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesPartialExplicit,\n out: [\n [\n 'elb',\n 'walker consent',\n {\n essential: true,\n functional: true,\n marketing: false,\n },\n ],\n ],\n};\n\nexport const firstVisitImplicit: Flow.StepExample = {\n title: 'First visit implicit (suppressed)',\n description:\n 'A first-visit snapshot carrying only implicit history is suppressed by the default explicitOnly gate, so no consent command is emitted.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesFirstVisitImplicit,\n out: [],\n};\n\nexport const consentChange: Flow.StepExample = {\n title: 'Consent change via CMP event',\n description:\n 'An ACCEPT_ALL decision fires UC_UI_CMP_EVENT; the source re-reads the services and emits the updated consent.',\n trigger: { type: 'consent', options: { dispatch: 'cmp' } },\n in: servicesFullExplicit,\n out: [['elb', 'walker consent', fullConsentMapped]],\n};\n\nexport const categoryMapOverride: Flow.StepExample = {\n title: 'Category map override',\n description:\n 'A custom categoryMap remaps essential to functional and functional to analytics before emitting the walker consent command.',\n trigger: { type: 'consent', options: { dispatch: 'init' } },\n in: servicesFullExplicit,\n mapping: {\n settings: {\n categoryMap: { essential: 'functional', functional: 'analytics' },\n },\n },\n out: [['elb', 'walker consent', fullConsentCustomMapped]],\n};\n","import type { Trigger, Collector } from '@walkeros/core';\nimport { startFlow } from '@walkeros/collector';\nimport type { UsercentricsV2Api, UsercentricsV2Service } from '../types';\n\n/**\n * `content` is what `window.UC_UI.getServicesBaseInfo()` returns. The\n * `dispatch` option picks the official path the source reacts to:\n * - 'init' (default): UC_UI is attached before the source runs, so the\n * static read at init publishes the snapshot.\n * - 'cmp': UC_UI is attached after init, then a `UC_UI_CMP_EVENT`\n * ACCEPT_ALL decision makes the source re-read and publish.\n */\nconst createTrigger: Trigger.CreateFn<UsercentricsV2Service[], void> = async (\n config: Collector.InitConfig,\n) => {\n let flow: Trigger.FlowHandle | undefined;\n\n const trigger: Trigger.Fn<UsercentricsV2Service[], void> =\n (_type?: string, opts?: unknown) =>\n async (content: UsercentricsV2Service[]) => {\n const dispatch =\n opts &&\n typeof opts === 'object' &&\n 'dispatch' in opts &&\n opts.dispatch === 'cmp'\n ? 'cmp'\n : 'init';\n const ucUi: UsercentricsV2Api = {\n isInitialized: () => true,\n getServicesBaseInfo: () => content,\n };\n\n if (dispatch === 'init') window.UC_UI = ucUi;\n\n // Lazy startFlow: the source attaches its listeners and does the\n // static read during init.\n if (!flow) {\n const result = await startFlow({ ...config, run: config.run ?? true });\n flow = { collector: result.collector, elb: result.elb };\n }\n\n if (dispatch === 'cmp') {\n window.UC_UI = ucUi;\n window.dispatchEvent(\n new CustomEvent('UC_UI_CMP_EVENT', {\n detail: { source: 'button', type: 'ACCEPT_ALL' },\n }),\n );\n }\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\n/** Attaches the services as the V2 `UC_UI` API before source init. */\nconst trigger = (input: unknown, env: Record<string, unknown>): void => {\n const win = env.window;\n if (!Array.isArray(input) || !isWindow(win)) return;\n win.UC_UI = {\n isInitialized: () => true,\n getServicesBaseInfo: () => input,\n };\n};\n\nfunction isWindow(value: unknown): value is Window {\n return (\n typeof value === 'object' && value !== null && 'addEventListener' in value\n );\n}\n\nexport { createTrigger, trigger };\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Usercentrics source settings schema\n */\nexport const SettingsSchema = z\n .object({\n categoryMap: z\n .record(z.string(), z.string())\n .describe(\n \"Map the CMP's consent categories (keys) to walkerOS consent groups (values).\",\n )\n .optional(),\n\n explicitOnly: z\n .boolean()\n .describe(\n 'Only publish when the user has actively decided (V3: consent.type EXPLICIT; V2: an EXPLICIT entry in service consent history). Implicit/default page-load states are suppressed. Set false to publish any snapshot including implicit. Default: true.',\n )\n .optional(),\n\n apiVersion: z\n .enum(['auto', 'v2', 'v3'])\n .describe(\n \"Which Usercentrics API to use. 'auto' uses V3 (window.__ucCmp) when present, else V2 (window.UC_UI), and listens for both while neither is loaded. Default: 'auto'.\",\n )\n .optional(),\n\n v3EventName: z\n .string()\n .describe(\n \"Window event the V3 adapter listens to for consent decisions, replacing UC_UI_CMP_EVENT. Only events whose detail.type is ACCEPT_ALL, DENY_ALL or SAVE are processed. Default: 'UC_UI_CMP_EVENT'.\",\n )\n .optional(),\n })\n .meta({\n id: 'UsercentricsSettings',\n title: 'Settings',\n description: 'Settings for the Usercentrics CMP source.',\n });\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n"],"mappings":"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","names":["trigger"]}
@@ -230,15 +230,16 @@ declare namespace step {
230
230
  export { step_categoryMapOverride as categoryMapOverride, step_consentChange as consentChange, step_firstVisitImplicit as firstVisitImplicit, step_fullConsent as fullConsent, step_minimalConsent as minimalConsent, step_returningVisitor as returningVisitor };
231
231
  }
232
232
 
233
- interface UsercentricsContent {
234
- event: string;
235
- type: string;
236
- action?: string;
237
- ucCategory?: Record<string, boolean | unknown>;
238
- [service: string]: unknown;
239
- }
240
- declare const createTrigger: Trigger.CreateFn<UsercentricsContent, void>;
241
- /** Dispatches ucEvent CustomEvent after source init (post-init trigger). */
242
- declare const trigger: (input: unknown, env: Record<string, unknown>) => void | (() => void);
233
+ /**
234
+ * `content` is what `window.UC_UI.getServicesBaseInfo()` returns. The
235
+ * `dispatch` option picks the official path the source reacts to:
236
+ * - 'init' (default): UC_UI is attached before the source runs, so the
237
+ * static read at init publishes the snapshot.
238
+ * - 'cmp': UC_UI is attached after init, then a `UC_UI_CMP_EVENT`
239
+ * ACCEPT_ALL decision makes the source re-read and publish.
240
+ */
241
+ declare const createTrigger: Trigger.CreateFn<UsercentricsV2Service[], void>;
242
+ /** Attaches the services as the V2 `UC_UI` API before source init. */
243
+ declare const trigger: (input: unknown, env: Record<string, unknown>) => void;
243
244
 
244
245
  export { createMockElbFn, createTrigger, fullConsentCustomMapped, fullConsentMapped, minimalConsentMapped, noopLogger, partialConsentMapped, servicesFirstVisitImplicit, servicesFullExplicit, servicesMinimalExplicit, servicesPartialExplicit, step, trigger };
@@ -230,15 +230,16 @@ declare namespace step {
230
230
  export { step_categoryMapOverride as categoryMapOverride, step_consentChange as consentChange, step_firstVisitImplicit as firstVisitImplicit, step_fullConsent as fullConsent, step_minimalConsent as minimalConsent, step_returningVisitor as returningVisitor };
231
231
  }
232
232
 
233
- interface UsercentricsContent {
234
- event: string;
235
- type: string;
236
- action?: string;
237
- ucCategory?: Record<string, boolean | unknown>;
238
- [service: string]: unknown;
239
- }
240
- declare const createTrigger: Trigger.CreateFn<UsercentricsContent, void>;
241
- /** Dispatches ucEvent CustomEvent after source init (post-init trigger). */
242
- declare const trigger: (input: unknown, env: Record<string, unknown>) => void | (() => void);
233
+ /**
234
+ * `content` is what `window.UC_UI.getServicesBaseInfo()` returns. The
235
+ * `dispatch` option picks the official path the source reacts to:
236
+ * - 'init' (default): UC_UI is attached before the source runs, so the
237
+ * static read at init publishes the snapshot.
238
+ * - 'cmp': UC_UI is attached after init, then a `UC_UI_CMP_EVENT`
239
+ * ACCEPT_ALL decision makes the source re-read and publish.
240
+ */
241
+ declare const createTrigger: Trigger.CreateFn<UsercentricsV2Service[], void>;
242
+ /** Attaches the services as the V2 `UC_UI` API before source init. */
243
+ declare const trigger: (input: unknown, env: Record<string, unknown>) => void;
243
244
 
244
245
  export { createMockElbFn, createTrigger, fullConsentCustomMapped, fullConsentMapped, minimalConsentMapped, noopLogger, partialConsentMapped, servicesFirstVisitImplicit, servicesFullExplicit, servicesMinimalExplicit, servicesPartialExplicit, step, trigger };
@@ -209,14 +209,26 @@ var categoryMapOverride = {
209
209
  var import_collector = require("@walkeros/collector");
210
210
  var createTrigger = async (config) => {
211
211
  let flow;
212
- const trigger2 = (type, opts) => async (content) => {
212
+ const trigger2 = (_type, opts) => async (content) => {
213
213
  var _a;
214
+ const dispatch = opts && typeof opts === "object" && "dispatch" in opts && opts.dispatch === "cmp" ? "cmp" : "init";
215
+ const ucUi = {
216
+ isInitialized: () => true,
217
+ getServicesBaseInfo: () => content
218
+ };
219
+ if (dispatch === "init") window.UC_UI = ucUi;
214
220
  if (!flow) {
215
221
  const result = await (0, import_collector.startFlow)({ ...config, run: (_a = config.run) != null ? _a : true });
216
222
  flow = { collector: result.collector, elb: result.elb };
217
223
  }
218
- const eventName = (opts == null ? void 0 : opts.eventName) || "ucEvent";
219
- window.dispatchEvent(new CustomEvent(eventName, { detail: content }));
224
+ if (dispatch === "cmp") {
225
+ window.UC_UI = ucUi;
226
+ window.dispatchEvent(
227
+ new CustomEvent("UC_UI_CMP_EVENT", {
228
+ detail: { source: "button", type: "ACCEPT_ALL" }
229
+ })
230
+ );
231
+ }
220
232
  };
221
233
  return {
222
234
  get flow() {
@@ -226,13 +238,16 @@ var createTrigger = async (config) => {
226
238
  };
227
239
  };
228
240
  var trigger = (input, env) => {
229
- if (!input || typeof input !== "object") return;
230
- return () => {
231
- env.window.dispatchEvent(
232
- new CustomEvent("ucEvent", { detail: input })
233
- );
241
+ const win = env.window;
242
+ if (!Array.isArray(input) || !isWindow(win)) return;
243
+ win.UC_UI = {
244
+ isInitialized: () => true,
245
+ getServicesBaseInfo: () => input
234
246
  };
235
247
  };
248
+ function isWindow(value) {
249
+ return typeof value === "object" && value !== null && "addEventListener" in value;
250
+ }
236
251
  // Annotate the CommonJS export names for ESM import in node:
237
252
  0 && (module.exports = {
238
253
  createMockElbFn,
@@ -177,14 +177,26 @@ var categoryMapOverride = {
177
177
  import { startFlow } from "@walkeros/collector";
178
178
  var createTrigger = async (config) => {
179
179
  let flow;
180
- const trigger2 = (type, opts) => async (content) => {
180
+ const trigger2 = (_type, opts) => async (content) => {
181
181
  var _a;
182
+ const dispatch = opts && typeof opts === "object" && "dispatch" in opts && opts.dispatch === "cmp" ? "cmp" : "init";
183
+ const ucUi = {
184
+ isInitialized: () => true,
185
+ getServicesBaseInfo: () => content
186
+ };
187
+ if (dispatch === "init") window.UC_UI = ucUi;
182
188
  if (!flow) {
183
189
  const result = await startFlow({ ...config, run: (_a = config.run) != null ? _a : true });
184
190
  flow = { collector: result.collector, elb: result.elb };
185
191
  }
186
- const eventName = (opts == null ? void 0 : opts.eventName) || "ucEvent";
187
- window.dispatchEvent(new CustomEvent(eventName, { detail: content }));
192
+ if (dispatch === "cmp") {
193
+ window.UC_UI = ucUi;
194
+ window.dispatchEvent(
195
+ new CustomEvent("UC_UI_CMP_EVENT", {
196
+ detail: { source: "button", type: "ACCEPT_ALL" }
197
+ })
198
+ );
199
+ }
188
200
  };
189
201
  return {
190
202
  get flow() {
@@ -194,13 +206,16 @@ var createTrigger = async (config) => {
194
206
  };
195
207
  };
196
208
  var trigger = (input, env) => {
197
- if (!input || typeof input !== "object") return;
198
- return () => {
199
- env.window.dispatchEvent(
200
- new CustomEvent("ucEvent", { detail: input })
201
- );
209
+ const win = env.window;
210
+ if (!Array.isArray(input) || !isWindow(win)) return;
211
+ win.UC_UI = {
212
+ isInitialized: () => true,
213
+ getServicesBaseInfo: () => input
202
214
  };
203
215
  };
216
+ function isWindow(value) {
217
+ return typeof value === "object" && value !== null && "addEventListener" in value;
218
+ }
204
219
  export {
205
220
  createMockElbFn,
206
221
  createTrigger,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$meta": {
3
3
  "package": "@walkeros/web-source-cmp-usercentrics",
4
- "version": "4.6.1",
4
+ "version": "4.7.0-next-1790187973605",
5
5
  "type": "source",
6
6
  "platform": [
7
7
  "web"
@@ -28,6 +28,19 @@
28
28
  "explicitOnly": {
29
29
  "type": "boolean",
30
30
  "description": "Only publish when the user has actively decided (V3: consent.type EXPLICIT; V2: an EXPLICIT entry in service consent history). Implicit/default page-load states are suppressed. Set false to publish any snapshot including implicit. Default: true."
31
+ },
32
+ "apiVersion": {
33
+ "type": "string",
34
+ "enum": [
35
+ "auto",
36
+ "v2",
37
+ "v3"
38
+ ],
39
+ "description": "Which Usercentrics API to use. 'auto' uses V3 (window.__ucCmp) when present, else V2 (window.UC_UI), and listens for both while neither is loaded. Default: 'auto'."
40
+ },
41
+ "v3EventName": {
42
+ "type": "string",
43
+ "description": "Window event the V3 adapter listens to for consent decisions, replacing UC_UI_CMP_EVENT. Only events whose detail.type is ACCEPT_ALL, DENY_ALL or SAVE are processed. Default: 'UC_UI_CMP_EVENT'."
31
44
  }
32
45
  },
33
46
  "additionalProperties": false,
@@ -40,7 +53,7 @@
40
53
  "$code": "()=>()=>Promise.resolve({ok:!0})"
41
54
  },
42
55
  "createTrigger": {
43
- "$code": "async t=>{let e;return{get flow(){return e},trigger:(i,s)=>async i=>{var n;if(!e){const i=await C({...t,run:null==(n=t.run)||n});e={collector:i.collector,elb:i.elb}}const a=(null==s?void 0:s.eventName)||\"ucEvent\";window.dispatchEvent(new CustomEvent(a,{detail:i}))}}}"
56
+ "$code": "async t=>{let e;return{get flow(){return e},trigger:(i,s)=>async i=>{var n;const o=s&&\"object\"==typeof s&&\"dispatch\"in s&&\"cmp\"===s.dispatch?\"cmp\":\"init\",a={isInitialized:()=>!0,getServicesBaseInfo:()=>i};if(\"init\"===o&&(window.UC_UI=a),!e){const i=await b({...t,run:null==(n=t.run)||n});e={collector:i.collector,elb:i.elb}}\"cmp\"===o&&(window.UC_UI=a,window.dispatchEvent(new CustomEvent(\"UC_UI_CMP_EVENT\",{detail:{source:\"button\",type:\"ACCEPT_ALL\"}})))}}}"
44
57
  },
45
58
  "fullConsentCustomMapped": {
46
59
  "functional": true,
@@ -77,7 +90,7 @@
77
90
  "$code": "()=>{}"
78
91
  },
79
92
  "scope": {
80
- "$code": "()=>y"
93
+ "$code": "()=>d"
81
94
  }
82
95
  },
83
96
  "partialConsentMapped": {
@@ -592,7 +605,7 @@
592
605
  }
593
606
  },
594
607
  "trigger": {
595
- "$code": "(t,e)=>{if(t&&\"object\"==typeof t)return()=>{e.window.dispatchEvent(new CustomEvent(\"ucEvent\",{detail:t}))}}"
608
+ "$code": "(t,e)=>{const i=e.window;var s;Array.isArray(t)&&(\"object\"==typeof(s=i)&&null!==s&&\"addEventListener\"in s)&&(i.UC_UI={isInitialized:()=>!0,getServicesBaseInfo:()=>t})}"
596
609
  }
597
610
  }
598
611
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@walkeros/web-source-cmp-usercentrics",
3
3
  "description": "Usercentrics consent management source for walkerOS",
4
- "version": "4.6.1",
4
+ "version": "4.7.0-next-1790187973605",
5
5
  "license": "MIT",
6
6
  "walkerOS": {
7
7
  "type": "source",
@@ -46,8 +46,8 @@
46
46
  "update": "npx npm-check-updates -u && npm update"
47
47
  },
48
48
  "dependencies": {
49
- "@walkeros/collector": "4.6.1",
50
- "@walkeros/core": "4.6.1"
49
+ "@walkeros/collector": "4.7.0-next-1790187973605",
50
+ "@walkeros/core": "4.7.0-next-1790187973605"
51
51
  },
52
52
  "repository": {
53
53
  "url": "git+https://github.com/elbwalker/walkerOS.git",