@modernconsent/core 0.0.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,144 @@
1
+ # @modernconsent/core
2
+
3
+ Lightweight consent engine for the web. Manages consent state, cookie persistence, GDPR audit trails and event emission — without any UI.
4
+
5
+ Part of the [ModernConsent](https://github.com/kschnekenburger/modern-consent) project.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @modernconsent/core
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import {
17
+ consentState,
18
+ hasAnswered,
19
+ servicesList,
20
+ setConsent,
21
+ acceptAll,
22
+ denyAll,
23
+ emitter,
24
+ } from '@modernconsent/core';
25
+
26
+ // Read reactive state
27
+ consentState.get(); // { 'google-analytics': true, 'meta-pixel': false }
28
+ hasAnswered.get(); // true
29
+ servicesList.get(); // [{ id, name, description, category, loaded, requireConsent }]
30
+
31
+ // Mutate consent
32
+ setConsent('google-analytics', true);
33
+ acceptAll();
34
+ denyAll();
35
+
36
+ // Subscribe to changes
37
+ const unsub = consentState.subscribe(state => {
38
+ console.log('Consent changed:', state);
39
+ });
40
+
41
+ // Listen to events
42
+ emitter.on('consent:update', data => {
43
+ console.log(data.vendor, data.status); // 'google-analytics', 'granted'
44
+ });
45
+
46
+ emitter.on('consent:saved', data => {
47
+ console.log(data.consentId, data.timestamp, data.consent);
48
+ });
49
+ ```
50
+
51
+ ## Configuration
52
+
53
+ All options are passed via `window.modernConsent('config', { ... })`:
54
+
55
+ | Option | Type | Default | Description |
56
+ | ------------------- | ----------------------- | -------------------- | ------------------------------------------------------------------------- |
57
+ | `cookieName` | `string` | `'mc_consent_state'` | Name of the consent cookie |
58
+ | `cookieDomain` | `string` | — | Domain scope (e.g. `.example.com`) |
59
+ | `consentMode` | `boolean` | `false` | Enable Google Consent Mode v2 |
60
+ | `consentVersion` | `string` | — | Version for GDPR audit. Changing it re-prompts the user |
61
+ | `consentOnly` | `boolean` | `false` | Consent-only mode — no vendor `init()` calls. For Tag Manager integration |
62
+ | `pushDataLayer` | `boolean` | `false` | Push events to `window.dataLayer` (GTM) |
63
+ | `displayMode` | `'vendor' \| 'purpose'` | `'vendor'` | How the widget displays controls |
64
+ | `functionalPurpose` | `boolean` | `false` | Show mandatory "Site operation" block |
65
+
66
+ ## Consent-Only Mode
67
+
68
+ For GTM / TagCommander users who manage scripts externally:
69
+
70
+ ```javascript
71
+ window.modernConsent('config', {
72
+ consentOnly: true,
73
+ pushDataLayer: true, // optional, for GTM native triggers
74
+ });
75
+ ```
76
+
77
+ Integration points:
78
+
79
+ ```javascript
80
+ // Read state
81
+ window.modernConsent.getConsent();
82
+
83
+ // Listen to changes
84
+ window.modernConsent.on('consent:update', e => {
85
+ console.log(e.vendor, e.status);
86
+ });
87
+
88
+ // consentLayer (always active)
89
+ window.consentLayer;
90
+
91
+ // dataLayer (opt-in)
92
+ window.dataLayer;
93
+ ```
94
+
95
+ ## Cookie Format
96
+
97
+ ```json
98
+ {
99
+ "consent": { "google-analytics": true, "meta-pixel": false },
100
+ "answered": true,
101
+ "timestamp": 1711468800000,
102
+ "version": "v1",
103
+ "consentId": "550e8400-e29b-41d4-a716-446655440000"
104
+ }
105
+ ```
106
+
107
+ ## Public API
108
+
109
+ | Method | Returns | Description |
110
+ | --------------------- | -------------- | ---------------------- |
111
+ | `('config', options)` | — | Merge configuration |
112
+ | `('vendor', vendor)` | — | Register a vendor |
113
+ | `.openPanel()` | — | Open the consent panel |
114
+ | `.getConsent()` | `ConsentState` | Current consent state |
115
+ | `.on(event, cb)` | `() => void` | Subscribe to events |
116
+
117
+ ## Stores
118
+
119
+ Reactive stores with pub/sub pattern:
120
+
121
+ ```typescript
122
+ import { consentState, hasAnswered, servicesList, isPanelOpen } from '@modernconsent/core';
123
+
124
+ // Read
125
+ consentState.get();
126
+
127
+ // Write
128
+ consentState.set({ 'my-vendor': true });
129
+
130
+ // Subscribe (fires immediately with current value)
131
+ const unsub = consentState.subscribe(value => { ... });
132
+ unsub(); // cleanup
133
+ ```
134
+
135
+ ## Related Packages
136
+
137
+ | Package | Description |
138
+ | -------------------------------------------------------------------------------- | ----------------------------------------- |
139
+ | [`@modernconsent/widget`](https://www.npmjs.com/package/@modernconsent/widget) | Web Component UI (banner + details panel) |
140
+ | [`@modernconsent/vendors`](https://www.npmjs.com/package/@modernconsent/vendors) | 24 built-in vendor modules |
141
+
142
+ ## License
143
+
144
+ MIT
@@ -0,0 +1,44 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
21
+
22
+ // src/resolver.ts
23
+ var _resolvers = [];
24
+ function addResolver(resolver) {
25
+ _resolvers.push(resolver);
26
+ return () => {
27
+ const idx = _resolvers.indexOf(resolver);
28
+ if (idx !== -1) _resolvers.splice(idx, 1);
29
+ };
30
+ }
31
+ function resolveVendor(name) {
32
+ for (let i = _resolvers.length - 1; i >= 0; i--) {
33
+ const result = _resolvers[i](name);
34
+ if (result) return result;
35
+ }
36
+ return void 0;
37
+ }
38
+ function __resetResolvers() {
39
+ _resolvers.length = 0;
40
+ }
41
+
42
+ export { __publicField, __resetResolvers, __spreadProps, __spreadValues, addResolver, resolveVendor };
43
+ //# sourceMappingURL=chunk-ENHZCUQ7.js.map
44
+ //# sourceMappingURL=chunk-ENHZCUQ7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/resolver.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AASA,IAAM,aAA+B,EAAC;AAS/B,SAAS,YAAY,QAAA,EAAsC;AAChE,EAAA,UAAA,CAAW,KAAK,QAAQ,CAAA;AACxB,EAAA,OAAO,MAAM;AACX,IAAA,MAAM,GAAA,GAAM,UAAA,CAAW,OAAA,CAAQ,QAAQ,CAAA;AACvC,IAAA,IAAI,GAAA,KAAQ,EAAA,EAAI,UAAA,CAAW,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,EAC1C,CAAA;AACF;AAMO,SAAS,cAAc,IAAA,EAAwC;AACpE,EAAA,KAAA,IAAS,IAAI,UAAA,CAAW,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC/C,IAAA,MAAM,MAAA,GAAS,UAAA,CAAW,CAAC,CAAA,CAAE,IAAI,CAAA;AACjC,IAAA,IAAI,QAAQ,OAAO,MAAA;AAAA,EACrB;AACA,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,gBAAA,GAAyB;AACvC,EAAA,UAAA,CAAW,MAAA,GAAS,CAAA;AACtB","file":"chunk-ENHZCUQ7.js","sourcesContent":["// core/src/resolver.ts\nimport type { VendorLoader } from './registry';\n\n/**\n * A resolver maps a vendor name to a loader function.\n * Return `undefined` to pass resolution to the next resolver in the chain.\n */\nexport type VendorResolver = (name: string) => VendorLoader | undefined;\n\nconst _resolvers: VendorResolver[] = [];\n\n/**\n * Register a vendor resolver. Resolvers are tried in LIFO order\n * (last registered = highest priority), following the convention\n * from Vite/Rollup where later plugins override earlier ones.\n *\n * @returns A cleanup function that removes this resolver from the chain.\n */\nexport function addResolver(resolver: VendorResolver): () => void {\n _resolvers.push(resolver);\n return () => {\n const idx = _resolvers.indexOf(resolver);\n if (idx !== -1) _resolvers.splice(idx, 1);\n };\n}\n\n/**\n * Resolve a vendor name to a loader by walking the resolver chain (LIFO).\n * Returns `undefined` if no resolver can handle the name.\n */\nexport function resolveVendor(name: string): VendorLoader | undefined {\n for (let i = _resolvers.length - 1; i >= 0; i--) {\n const result = _resolvers[i](name);\n if (result) return result;\n }\n return undefined;\n}\n\n/** @internal — test helper only */\nexport function __resetResolvers(): void {\n _resolvers.length = 0;\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { m as ConfigCommand, q as ConsentEventMap, C as ConsentState, l as McCommand, M as McConfig, k as McVendor, S as ServiceMetadata, a as Store, V as Vendor, n as VendorCommand, j as VendorConfig, g as VendorLoader, e as activateService, b as addResolver, f as clearVendorArtifacts, c as consentState, p as emitter, h as hasAnswered, t as initMcLayer, i as isPanelOpen, o as openPanel, d as registerService, r as resolveVendor, s as servicesList } from './resolver-CKoWIVlu.js';
1
+ export { m as ConfigCommand, q as ConsentEventMap, C as ConsentState, l as McCommand, M as McConfig, k as McVendor, S as ServiceMetadata, a as Store, V as Vendor, n as VendorCommand, j as VendorConfig, g as VendorLoader, e as activateService, b as addResolver, f as clearVendorArtifacts, c as consentState, p as emitter, h as hasAnswered, t as initMcLayer, i as isPanelOpen, o as openPanel, d as registerService, r as resolveVendor, s as servicesList } from './resolver-CssVkauA.js';
2
2
 
3
3
  declare global {
4
4
  interface Window {
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
- import { addResolver, resolveVendor } from './chunk-UZ3JLA4T.js';
2
- export { addResolver, resolveVendor } from './chunk-UZ3JLA4T.js';
1
+ import { __publicField, addResolver, __spreadValues, resolveVendor, __spreadProps } from './chunk-ENHZCUQ7.js';
2
+ export { addResolver, resolveVendor } from './chunk-ENHZCUQ7.js';
3
3
 
4
4
  // src/utils/store.ts
5
5
  var Store = class {
6
- value;
7
- subscribers = /* @__PURE__ */ new Set();
8
6
  constructor(initialValue) {
7
+ __publicField(this, "value");
8
+ __publicField(this, "subscribers", /* @__PURE__ */ new Set());
9
9
  this.value = initialValue;
10
10
  }
11
11
  get() {
@@ -82,9 +82,9 @@ var isPanelOpen = new Store(false);
82
82
  var openPanel = () => isPanelOpen.set(true);
83
83
  var _cookieUnsubs = [];
84
84
  var initState = (config) => {
85
- const cookieName = config?.cookieName || DEFAULT_STORAGE_KEY;
86
- const cookieDomain = config?.cookieDomain;
87
- const consentVersion = config?.consentVersion;
85
+ const cookieName = (config == null ? void 0 : config.cookieName) || DEFAULT_STORAGE_KEY;
86
+ const cookieDomain = config == null ? void 0 : config.cookieDomain;
87
+ const consentVersion = config == null ? void 0 : config.consentVersion;
88
88
  let initialData = { consent: {}, answered: false };
89
89
  if (typeof window !== "undefined") {
90
90
  const stored = getCookie(cookieName);
@@ -128,11 +128,12 @@ var loaders = /* @__PURE__ */ new Map();
128
128
  var loadedVendors = /* @__PURE__ */ new Map();
129
129
  var vendorsConfig = /* @__PURE__ */ new Map();
130
130
  function clearVendorArtifacts(id) {
131
+ var _a;
131
132
  const vendor = loadedVendors.get(id);
132
- if (!vendor?.artifacts) return;
133
+ if (!(vendor == null ? void 0 : vendor.artifacts)) return;
133
134
  const config = vendorsConfig.get(id);
134
135
  const cookieNames = typeof vendor.artifacts === "function" ? vendor.artifacts(config) : vendor.artifacts;
135
- const domain = window._modernConsentConfig?.cookieDomain;
136
+ const domain = (_a = window._modernConsentConfig) == null ? void 0 : _a.cookieDomain;
136
137
  cookieNames.forEach((name) => {
137
138
  document.cookie = `${name}=; max-age=0; path=/`;
138
139
  if (domain) {
@@ -150,11 +151,16 @@ function registerService(args) {
150
151
  if (config !== void 0) {
151
152
  vendorsConfig.set(id, config);
152
153
  }
153
- if (vendor?.setup) {
154
- vendor.setup(config);
154
+ if (vendor == null ? void 0 : vendor.setup) {
155
+ try {
156
+ vendor.setup(config);
157
+ } catch (err) {
158
+ console.error(`[modern-consent] setup() failed for "${id}":`, err);
159
+ }
155
160
  }
156
- if (vendor?.link && vendor.link.length > 0) {
161
+ if ((vendor == null ? void 0 : vendor.link) && vendor.link.length > 0) {
157
162
  vendor.link.forEach((link) => {
163
+ var _a;
158
164
  if (link.condition && !link.condition({ vendorConfig: config, consentConfig: window._modernConsentConfig })) {
159
165
  return;
160
166
  }
@@ -163,7 +169,7 @@ function registerService(args) {
163
169
  registerService({
164
170
  id: link.vendor,
165
171
  category,
166
- config: link.config ?? {},
172
+ config: (_a = link.config) != null ? _a : {},
167
173
  loader: linkedLoader
168
174
  });
169
175
  } else {
@@ -208,6 +214,7 @@ function checkAutoActivation(id) {
208
214
  }
209
215
  }
210
216
  async function activateService(id) {
217
+ var _a, _b;
211
218
  if (typeof window === "undefined") return;
212
219
  let vendor = loadedVendors.get(id);
213
220
  if (!vendor) {
@@ -219,17 +226,17 @@ async function activateService(id) {
219
226
  }
220
227
  }
221
228
  if (!vendor) return;
222
- const isSoft = window._modernConsentConfig?.consentOnly === true;
229
+ const isSoft = ((_a = window._modernConsentConfig) == null ? void 0 : _a.consentOnly) === true;
223
230
  const list = servicesList.get();
224
231
  const meta = list.find((s) => s.id === id);
225
232
  if (!isSoft && vendor.init && meta && !meta.loaded) {
226
233
  vendor.init(vendorsConfig.get(id));
227
- servicesList.update((l) => l.map((s) => s.id === id ? { ...s, loaded: true } : s));
228
- vendor.event?.forEach((ev) => {
234
+ servicesList.update((l) => l.map((s) => s.id === id ? __spreadProps(__spreadValues({}, s), { loaded: true }) : s));
235
+ (_b = vendor.event) == null ? void 0 : _b.forEach((ev) => {
229
236
  if (ev.name === "onAccept") {
230
237
  try {
231
238
  ev.callback();
232
- } catch {
239
+ } catch (e) {
233
240
  }
234
241
  }
235
242
  });
@@ -238,7 +245,7 @@ async function activateService(id) {
238
245
  setTimeout(() => {
239
246
  document.querySelectorAll(vendor.domSelector).forEach((el) => {
240
247
  const htmlElement = el;
241
- if (htmlElement.dataset.loaded !== "true" && vendor?.render) {
248
+ if (htmlElement.dataset.loaded !== "true" && (vendor == null ? void 0 : vendor.render)) {
242
249
  htmlElement.innerHTML = vendor.render(htmlElement.dataset);
243
250
  htmlElement.dataset.loaded = "true";
244
251
  htmlElement.classList.remove("mc-placeholder-pending");
@@ -250,20 +257,27 @@ async function activateService(id) {
250
257
 
251
258
  // src/emitter.ts
252
259
  var ConsentEmitter = class {
253
- listeners = /* @__PURE__ */ new Map();
260
+ constructor() {
261
+ __publicField(this, "listeners", /* @__PURE__ */ new Map());
262
+ }
254
263
  on(event, cb) {
255
264
  if (!this.listeners.has(event)) this.listeners.set(event, /* @__PURE__ */ new Set());
256
265
  this.listeners.get(event).add(cb);
257
- return () => this.listeners.get(event)?.delete(cb);
266
+ return () => {
267
+ var _a;
268
+ return (_a = this.listeners.get(event)) == null ? void 0 : _a.delete(cb);
269
+ };
258
270
  }
259
271
  off(event, cb) {
260
- this.listeners.get(event)?.delete(cb);
272
+ var _a;
273
+ (_a = this.listeners.get(event)) == null ? void 0 : _a.delete(cb);
261
274
  }
262
275
  emit(event, data) {
263
- this.listeners.get(event)?.forEach((cb) => {
276
+ var _a;
277
+ (_a = this.listeners.get(event)) == null ? void 0 : _a.forEach((cb) => {
264
278
  try {
265
279
  cb(data);
266
- } catch {
280
+ } catch (e) {
267
281
  }
268
282
  });
269
283
  }
@@ -272,6 +286,7 @@ var emitter = new ConsentEmitter();
272
286
 
273
287
  // src/consent.ts
274
288
  function pushConsentEvent(consent) {
289
+ var _a;
275
290
  if (typeof window === "undefined") return;
276
291
  const event = {
277
292
  event: "consent_update",
@@ -279,22 +294,24 @@ function pushConsentEvent(consent) {
279
294
  };
280
295
  window.consentLayer = window.consentLayer || [];
281
296
  window.consentLayer.push(event);
282
- if (window._modernConsentConfig?.pushDataLayer) {
297
+ if ((_a = window._modernConsentConfig) == null ? void 0 : _a.pushDataLayer) {
283
298
  window.dataLayer = window.dataLayer || [];
284
299
  window.dataLayer.push(event);
285
300
  }
286
301
  }
287
302
  function emitConsentSaved(consent) {
303
+ var _a;
288
304
  emitter.emit("consent:saved", {
289
305
  consentId: generateUUID(),
290
306
  timestamp: Date.now(),
291
- version: typeof window !== "undefined" ? window._modernConsentConfig?.consentVersion : void 0,
307
+ version: typeof window !== "undefined" ? (_a = window._modernConsentConfig) == null ? void 0 : _a.consentVersion : void 0,
292
308
  consent
293
309
  });
294
310
  }
295
311
  function setConsent(id, allowed) {
296
- const wasPreviouslyLoaded = servicesList.get().find((s) => s.id === id)?.loaded ?? false;
297
- consentState.update((s) => ({ ...s, [id]: allowed }));
312
+ var _a, _b, _c;
313
+ const wasPreviouslyLoaded = (_b = (_a = servicesList.get().find((s) => s.id === id)) == null ? void 0 : _a.loaded) != null ? _b : false;
314
+ consentState.update((s) => __spreadProps(__spreadValues({}, s), { [id]: allowed }));
298
315
  hasAnswered.set(true);
299
316
  emitter.emit("consent:update", {
300
317
  vendor: id,
@@ -309,7 +326,7 @@ function setConsent(id, allowed) {
309
326
  }
310
327
  if (wasPreviouslyLoaded) {
311
328
  clearVendorArtifacts(id);
312
- const isConsentOnly = typeof window !== "undefined" && window._modernConsentConfig?.consentOnly === true;
329
+ const isConsentOnly = typeof window !== "undefined" && ((_c = window._modernConsentConfig) == null ? void 0 : _c.consentOnly) === true;
313
330
  if (!isConsentOnly && typeof window !== "undefined") window.location.reload();
314
331
  }
315
332
  }
@@ -330,6 +347,7 @@ function acceptAll() {
330
347
  emitConsentSaved(updates);
331
348
  }
332
349
  function denyAll() {
350
+ var _a;
333
351
  const list = servicesList.get();
334
352
  const updates = {};
335
353
  let needsReload = false;
@@ -346,7 +364,7 @@ function denyAll() {
346
364
  });
347
365
  pushConsentEvent(updates);
348
366
  emitConsentSaved(updates);
349
- const isConsentOnly = typeof window !== "undefined" && window._modernConsentConfig?.consentOnly === true;
367
+ const isConsentOnly = typeof window !== "undefined" && ((_a = window._modernConsentConfig) == null ? void 0 : _a.consentOnly) === true;
350
368
  if (needsReload && !isConsentOnly && typeof window !== "undefined") {
351
369
  window.location.reload();
352
370
  }
@@ -367,9 +385,9 @@ function handleVendor(event) {
367
385
  artifacts
368
386
  } = event;
369
387
  let loader;
370
- if (init ?? setup) {
388
+ if (init != null ? init : setup) {
371
389
  loader = async () => ({
372
- name: label ?? name,
390
+ name: label != null ? label : name,
373
391
  description,
374
392
  category,
375
393
  requireConsent,
@@ -396,7 +414,8 @@ function initMcLayer() {
396
414
  w._modernConsentConfig = {};
397
415
  addResolver((_name) => {
398
416
  return async () => {
399
- const cdnBase = w._modernConsentConfig?.cdnBase;
417
+ var _a, _b;
418
+ const cdnBase = (_a = w._modernConsentConfig) == null ? void 0 : _a.cdnBase;
400
419
  if (!cdnBase) {
401
420
  throw new Error(
402
421
  `[modern-consent] Vendor "${_name}" not found. Configure cdnBase to enable CDN loading, or provide an inline init().`
@@ -407,7 +426,7 @@ function initMcLayer() {
407
426
  /* @vite-ignore */
408
427
  url
409
428
  );
410
- return mod.default ?? mod;
429
+ return (_b = mod.default) != null ? _b : mod;
411
430
  };
412
431
  });
413
432
  existingQueue.forEach((args) => {
@@ -417,7 +436,7 @@ function initMcLayer() {
417
436
  return;
418
437
  }
419
438
  if (command === "config") {
420
- w._modernConsentConfig = { ...w._modernConsentConfig, ...payload };
439
+ w._modernConsentConfig = __spreadValues(__spreadValues({}, w._modernConsentConfig), payload);
421
440
  return;
422
441
  }
423
442
  handleVendor(payload);
@@ -432,7 +451,7 @@ function initMcLayer() {
432
451
  if (command === "vendor") {
433
452
  handleVendor(payload);
434
453
  } else if (command === "config") {
435
- w._modernConsentConfig = { ...w._modernConsentConfig, ...payload };
454
+ w._modernConsentConfig = __spreadValues(__spreadValues({}, w._modernConsentConfig), payload);
436
455
  }
437
456
  if (!Array.isArray(w.mcLayer)) w.mcLayer = [];
438
457
  w.mcLayer.push(args);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/store.ts","../src/utils/uuid.ts","../src/state.ts","../src/registry.ts","../src/emitter.ts","../src/consent.ts","../src/layer.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export type Subscriber<T> = (value: T) => void;\nexport type Unsubscriber = () => void;\n\nexport class Store<T> {\n private value: T;\n private subscribers: Set<Subscriber<T>> = new Set();\n\n constructor(initialValue: T) {\n this.value = initialValue;\n }\n\n get(): T {\n return this.value;\n }\n\n set(newValue: T): void {\n if (this.value !== newValue) {\n this.value = newValue;\n this.notify();\n }\n }\n\n update(updater: (value: T) => T): void {\n this.set(updater(this.value));\n }\n\n subscribe(callback: Subscriber<T>): Unsubscriber {\n this.subscribers.add(callback);\n callback(this.value); // Appel immédiat\n return () => this.subscribers.delete(callback);\n }\n\n private notify(): void {\n this.subscribers.forEach(cb => cb(this.value));\n }\n}\n","function manualUUIDv4(): string {\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n // Set version 4 (0100) and variant 10xx bits per RFC 4122\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n const hex = Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');\n return [\n hex.slice(0, 8),\n hex.slice(8, 12),\n hex.slice(12, 16),\n hex.slice(16, 20),\n hex.slice(20),\n ].join('-');\n}\n\nexport const generateUUID = (): string =>\n typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'\n ? crypto.randomUUID()\n : manualUUIDv4();\n","// core/src/state.ts\nimport { Store } from './utils/store';\nimport { generateUUID } from './utils/uuid';\n\nexport interface ConsentState {\n [serviceId: string]: boolean;\n}\n\nexport interface ServiceMetadata {\n id: string;\n name: string;\n description: string;\n category: string;\n /** Human-readable label for the purpose/category in 'purpose' displayMode. */\n purposeLabel?: string | Record<string, string>;\n /** Optional description for the purpose/category in 'purpose' displayMode. */\n purposeDescription?: string | Record<string, string>;\n loaded: boolean;\n requireConsent: boolean;\n}\n\ninterface StoredState {\n consent: ConsentState;\n answered: boolean;\n /** Unix timestamp (ms) of when consent was last given — for GDPR audit trail. */\n timestamp?: number;\n /** Version of the consent banner at the time of consent. */\n version?: string;\n /** Unique identifier per consent action — for GDPR audit trail. */\n consentId?: string;\n}\n\nconst DEFAULT_STORAGE_KEY = 'mc_consent_state';\n\ninterface CookieOptions {\n days?: number;\n path?: string;\n domain?: string;\n sameSite?: 'Lax' | 'Strict' | 'None';\n secure?: boolean;\n}\n\nfunction escapeCookieName(name: string): string {\n return name.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nconst getCookie = (name: string): string | null => {\n if (typeof document === 'undefined') return null;\n const match = document.cookie.match(new RegExp(`(?:^|; )${escapeCookieName(name)}=([^;]*)`));\n return match ? decodeURIComponent(match[1]) : null;\n};\n\nconst setCookie = (name: string, value: string, options: CookieOptions = {}) => {\n if (typeof document === 'undefined') return;\n\n const { days = 365, path = '/', domain, sameSite = 'Lax', secure = false } = options;\n\n const expires = new Date();\n expires.setDate(expires.getDate() + days);\n\n let cookieString =\n `${name}=${encodeURIComponent(value)};` +\n `expires=${expires.toUTCString()};` +\n `path=${path};` +\n `SameSite=${sameSite}`;\n\n if (domain) {\n const hostname = typeof window !== 'undefined' ? window.location.hostname : '';\n if (hostname && !hostname.endsWith(domain.replace(/^\\./, ''))) {\n console.warn(\n `[modern-consent] cookieDomain \"${domain}\" does not match current hostname \"${hostname}\". ` +\n `The cookie will be silently rejected by the browser. ` +\n `Remove cookieDomain for local development.`,\n );\n }\n cookieString += `;domain=${domain}`;\n }\n if (secure || sameSite === 'None') cookieString += `;Secure`;\n\n document.cookie = cookieString;\n};\n\nexport const consentState = new Store<ConsentState>({});\nexport const hasAnswered = new Store<boolean>(false);\nexport const servicesList = new Store<ServiceMetadata[]>([]);\nexport const isPanelOpen = new Store<boolean>(false);\nexport const openPanel = () => isPanelOpen.set(true);\n\n// Tracked so that calling initState multiple times never stacks duplicate subscribers\nlet _cookieUnsubs: (() => void)[] = [];\n\nexport const initState = (config: any) => {\n const cookieName: string = config?.cookieName || DEFAULT_STORAGE_KEY;\n const cookieDomain: string | undefined = config?.cookieDomain;\n const consentVersion: string | undefined = config?.consentVersion;\n\n let initialData: StoredState = { consent: {}, answered: false };\n\n if (typeof window !== 'undefined') {\n const stored = getCookie(cookieName);\n if (stored) {\n try {\n initialData = JSON.parse(stored) as StoredState;\n } catch (e) {\n console.error('[modern-consent] Error parsing consent cookie', e);\n }\n }\n }\n\n consentState.set(initialData.consent || {});\n hasAnswered.set(initialData.answered || false);\n\n // Re-prompt when consentVersion changes (GDPR: policy update invalidates prior consent)\n if (initialData.answered && consentVersion && initialData.version !== consentVersion) {\n hasAnswered.set(false);\n isPanelOpen.set(true);\n }\n\n if (typeof window !== 'undefined') {\n // Clean up previous subscriptions before creating new ones\n _cookieUnsubs.forEach(fn => fn());\n _cookieUnsubs = [];\n\n const saveToCookie = () => {\n const state: StoredState = {\n consent: consentState.get(),\n answered: hasAnswered.get(),\n timestamp: Date.now(),\n version: consentVersion,\n consentId: generateUUID(),\n };\n setCookie(cookieName, JSON.stringify(state), {\n domain: cookieDomain,\n secure: window.location.protocol === 'https:',\n });\n };\n\n _cookieUnsubs.push(consentState.subscribe(saveToCookie));\n _cookieUnsubs.push(hasAnswered.subscribe(saveToCookie));\n }\n};\n","import { consentState, hasAnswered, isPanelOpen, servicesList } from './state';\nimport { resolveVendor } from './resolver';\nimport type { McConfig } from './layer';\n\ndeclare global {\n interface Window {\n _modernConsentConfig: McConfig;\n }\n}\n\nexport type VendorConfig = unknown;\n\nexport interface Vendor<TConfig = void> {\n name: string;\n description: string;\n category: string;\n /**\n * Human-readable label for the purpose/category in 'purpose' displayMode.\n * Can be a string or a Record<lang, string> for i18n support.\n * @example purposeLabel: { fr: \"Mesure d'audience\", en: \"Audience measurement\" }\n */\n purposeLabel?: string | Record<string, string>;\n /**\n * Description for the purpose/category in 'purpose' displayMode.\n * Can be a string or a Record<lang, string> for i18n support.\n */\n purposeDescription?: string | Record<string, string>;\n setup?: (config: TConfig) => void;\n domSelector?: string;\n init?: (config: TConfig) => void;\n /** Cookie names set by this vendor — cleared when consent is revoked. */\n artifacts?: string[] | ((config: TConfig) => string[]);\n render?: (dataset: DOMStringMap) => string;\n requireConsent: boolean;\n event?: {\n name: string;\n callback: () => void;\n }[];\n link?: {\n vendor: string;\n /** Config passed to the linked vendor. Defaults to {} if omitted. */\n config?: VendorConfig;\n condition: (params: { vendorConfig: any; consentConfig: any }) => boolean;\n }[];\n}\n\nexport type VendorLoader = () => Promise<Vendor<any>>;\n\nconst loaders = new Map<string, VendorLoader>();\nconst loadedVendors = new Map<string, Vendor<VendorConfig>>();\nconst vendorsConfig = new Map<string, VendorConfig>();\n\n// Re-export resolveVendor from resolver.ts for backward compatibility\nexport { resolveVendor } from './resolver';\n\n/** @internal — test helper only */\nexport function __resetRegistry() {\n loaders.clear();\n loadedVendors.clear();\n vendorsConfig.clear();\n}\n\n/**\n * Clears all cookies declared in vendor.artifacts.\n * Called before reload or on denyAll to clean up vendor-set cookies.\n */\nexport function clearVendorArtifacts(id: string): void {\n const vendor = loadedVendors.get(id);\n if (!vendor?.artifacts) return;\n\n const config = vendorsConfig.get(id);\n const cookieNames =\n typeof vendor.artifacts === 'function' ? vendor.artifacts(config) : vendor.artifacts;\n\n const domain = window._modernConsentConfig?.cookieDomain;\n\n cookieNames.forEach(name => {\n document.cookie = `${name}=; max-age=0; path=/`;\n if (domain) {\n document.cookie = `${name}=; max-age=0; path=/; domain=${domain}`;\n }\n });\n}\n\nexport function registerService(args: {\n id: string;\n category: string;\n loader: VendorLoader;\n config: VendorConfig;\n}) {\n const { id, category, loader, config = {} } = args;\n\n // Prevent double-registration for the same service id\n if (loaders.has(id)) return;\n loaders.set(id, loader);\n\n loader()\n .then((module: any) => {\n const vendor: Vendor<any> = module.default || module;\n loadedVendors.set(id, vendor);\n if (config !== undefined) {\n vendorsConfig.set(id, config);\n }\n\n if (vendor?.setup) {\n vendor.setup(config);\n }\n\n if (vendor?.link && vendor.link.length > 0) {\n vendor.link.forEach(link => {\n if (\n link.condition &&\n !link.condition({ vendorConfig: config, consentConfig: window._modernConsentConfig })\n ) {\n return;\n }\n const linkedLoader = resolveVendor(link.vendor);\n if (linkedLoader) {\n registerService({\n id: link.vendor,\n category,\n config: link.config ?? {},\n loader: linkedLoader,\n });\n } else {\n console.warn(`[modern-consent] Dependency \"${link.vendor}\" not found for \"${id}\"`);\n }\n });\n }\n\n servicesList.update(list => {\n if (list.some(s => s.id === id)) return list;\n return [\n ...list,\n {\n id,\n name: vendor.name,\n description: vendor.description,\n category: vendor.category,\n purposeLabel: vendor.purposeLabel,\n purposeDescription: vendor.purposeDescription,\n loaded: false,\n requireConsent: vendor.requireConsent,\n },\n ];\n });\n\n checkAutoActivation(id);\n })\n .catch(err => {\n console.error(`[modern-consent] Failed to load vendor \"${id}\":`, err);\n });\n}\n\n/**\n * Vérifie si on doit activer le service ou ouvrir le panel (nouveau service détecté)\n */\nfunction checkAutoActivation(id: string) {\n const vendor = loadedVendors.get(id);\n\n // Services that don't require consent activate immediately\n if (vendor && !vendor.requireConsent) {\n activateService(id);\n return;\n }\n\n const currentConsent = consentState.get();\n const answered = hasAnswered.get();\n\n if (answered && currentConsent[id] === undefined) {\n isPanelOpen.set(true);\n }\n\n if (currentConsent[id]) {\n activateService(id);\n }\n}\n\n/**\n * Active le service (Script + DOM)\n */\nexport async function activateService(id: string) {\n if (typeof window === 'undefined') return;\n\n let vendor = loadedVendors.get(id);\n\n if (!vendor) {\n const loader = loaders.get(id);\n if (loader) {\n const module: any = await loader();\n vendor = module.default || module;\n if (vendor) loadedVendors.set(id, vendor);\n }\n }\n\n if (!vendor) return;\n\n const isSoft = window._modernConsentConfig?.consentOnly === true;\n const list = servicesList.get();\n const meta = list.find(s => s.id === id);\n\n if (!isSoft && vendor.init && meta && !meta.loaded) {\n vendor.init(vendorsConfig.get(id));\n servicesList.update(l => l.map(s => (s.id === id ? { ...s, loaded: true } : s)));\n\n // Trigger onAccept events after successful activation\n vendor.event?.forEach(ev => {\n if (ev.name === 'onAccept') {\n try {\n ev.callback();\n } catch {\n /* don't let event errors break activation */\n }\n }\n });\n }\n\n if (!isSoft && vendor.domSelector && vendor.render) {\n setTimeout(() => {\n document.querySelectorAll(vendor!.domSelector!).forEach(el => {\n const htmlElement = el as HTMLElement;\n if (htmlElement.dataset.loaded !== 'true' && vendor?.render) {\n htmlElement.innerHTML = vendor.render(htmlElement.dataset);\n htmlElement.dataset.loaded = 'true';\n htmlElement.classList.remove('mc-placeholder-pending');\n }\n });\n }, 50);\n }\n}\n","import type { ConsentState } from './state';\n\nexport type ConsentEventMap = {\n 'consent:update': { vendor: string; status: 'granted' | 'denied'; gcm?: Record<string, boolean> };\n 'consent:saved': {\n consentId: string;\n timestamp: number;\n version?: string;\n consent: ConsentState;\n };\n};\n\ntype Listener<T> = (data: T) => void;\n\nclass ConsentEmitter {\n private listeners = new Map<string, Set<Listener<any>>>();\n\n on<K extends keyof ConsentEventMap>(event: K, cb: Listener<ConsentEventMap[K]>): () => void {\n if (!this.listeners.has(event)) this.listeners.set(event, new Set());\n this.listeners.get(event)!.add(cb);\n return () => this.listeners.get(event)?.delete(cb);\n }\n\n off<K extends keyof ConsentEventMap>(event: K, cb: Listener<ConsentEventMap[K]>): void {\n this.listeners.get(event)?.delete(cb);\n }\n\n emit<K extends keyof ConsentEventMap>(event: K, data: ConsentEventMap[K]): void {\n this.listeners.get(event)?.forEach(cb => {\n try {\n cb(data);\n } catch {\n /* don't let listener errors break the core */\n }\n });\n }\n}\n\nexport const emitter = new ConsentEmitter();\n","import { servicesList, consentState, hasAnswered, isPanelOpen } from './state';\nimport type { ConsentState } from './state';\nimport { activateService, clearVendorArtifacts } from './registry';\nimport { emitter } from './emitter';\nimport { generateUUID } from './utils/uuid';\n\ndeclare global {\n interface Window {\n consentLayer: any[];\n dataLayer: any[];\n }\n}\n\n/**\n * Always pushes consent state to `window.consentLayer` (TMS-agnostic).\n * Optionally pushes to `window.dataLayer` when `pushDataLayer` is enabled (GTM convenience).\n */\nfunction pushConsentEvent(consent: ConsentState) {\n if (typeof window === 'undefined') return;\n\n const event = {\n event: 'consent_update',\n consent_state: consent,\n };\n\n // consentLayer — always active, TMS-agnostic\n window.consentLayer = window.consentLayer || [];\n window.consentLayer.push(event);\n\n // dataLayer — opt-in for GTM native triggers\n if (window._modernConsentConfig?.pushDataLayer) {\n window.dataLayer = window.dataLayer || [];\n window.dataLayer.push(event);\n }\n}\n\nfunction emitConsentSaved(consent: ConsentState) {\n emitter.emit('consent:saved', {\n consentId: generateUUID(),\n timestamp: Date.now(),\n version:\n typeof window !== 'undefined' ? window._modernConsentConfig?.consentVersion : undefined,\n consent,\n });\n}\n\nexport function setConsent(id: string, allowed: boolean) {\n // Check before updating state whether this service was actively running\n const wasPreviouslyLoaded = servicesList.get().find(s => s.id === id)?.loaded ?? false;\n\n consentState.update(s => ({ ...s, [id]: allowed }));\n hasAnswered.set(true);\n\n emitter.emit('consent:update', {\n vendor: id,\n status: allowed ? 'granted' : 'denied',\n });\n\n const updatedConsent = consentState.get();\n pushConsentEvent(updatedConsent);\n emitConsentSaved(updatedConsent);\n\n if (allowed) {\n activateService(id);\n return;\n }\n\n // Only clean up and reload if the service was actively running\n if (wasPreviouslyLoaded) {\n clearVendorArtifacts(id);\n const isConsentOnly =\n typeof window !== 'undefined' && window._modernConsentConfig?.consentOnly === true;\n if (!isConsentOnly && typeof window !== 'undefined') window.location.reload();\n }\n}\n\nexport function acceptAll() {\n const list = servicesList.get();\n const updates: Record<string, boolean> = {};\n\n list.forEach(s => {\n updates[s.id] = true;\n activateService(s.id);\n });\n\n consentState.set(updates);\n hasAnswered.set(true);\n isPanelOpen.set(false);\n\n list.forEach(s => {\n emitter.emit('consent:update', { vendor: s.id, status: 'granted' });\n });\n\n pushConsentEvent(updates);\n emitConsentSaved(updates);\n}\n\nexport function denyAll() {\n const list = servicesList.get();\n const updates: Record<string, boolean> = {};\n let needsReload = false;\n\n list.forEach(s => {\n updates[s.id] = false;\n clearVendorArtifacts(s.id);\n if (s.loaded) needsReload = true;\n });\n\n consentState.set(updates);\n hasAnswered.set(true);\n isPanelOpen.set(false);\n\n list.forEach(s => {\n emitter.emit('consent:update', { vendor: s.id, status: 'denied' });\n });\n\n pushConsentEvent(updates);\n emitConsentSaved(updates);\n\n // Reload only if at least one vendor was actively running —\n // clears vendor scripts from memory after cookie cleanup.\n const isConsentOnly =\n typeof window !== 'undefined' && window._modernConsentConfig?.consentOnly === true;\n if (needsReload && !isConsentOnly && typeof window !== 'undefined') {\n window.location.reload();\n }\n}\n","import { registerService } from './registry';\nimport { addResolver, resolveVendor } from './resolver';\nimport { consentState, initState, isPanelOpen } from './state';\nimport type { ConsentState } from './state';\nimport type { Vendor } from './registry';\nimport { emitter } from './emitter';\n\n/**\n * Command can add in config\n */\nconst validCommands = ['config', 'vendor'] as const;\n\nexport interface McConfig {\n cookieDomain?: string;\n cookieName?: string;\n consentMode?: boolean;\n /** Version string embedded in the stored consent — used for GDPR audit trails. */\n consentVersion?: string;\n /**\n * Base URL where vendor JS files are hosted.\n * Used by the CDN bundle to lazy-load vendors on demand.\n *\n * @example 'https://cdn.monsite.com/mc-vendors'\n * → window.modernConsent('vendor', { name: 'google-analytics' })\n * → fetches https://cdn.monsite.com/mc-vendors/google-analytics.js\n */\n cdnBase?: string;\n /**\n * In Consent-Only mode, the CMP only manages consent decisions + cookie storage.\n * Vendors are never initialized (no call to init()).\n * Use this to manage vendor scripts externally via a Tag Manager (GTM, TagCommander, etc.).\n *\n * Consent changes are always pushed to `window.consentLayer`.\n * Enable `pushDataLayer` to also push to `window.dataLayer` for native GTM triggers.\n */\n consentOnly?: boolean;\n /**\n * When true, consent changes are also pushed to `window.dataLayer` for native\n * GTM trigger support. Disabled by default — GTM users should enable this.\n */\n pushDataLayer?: boolean;\n /**\n * How the details panel displays consent controls:\n * - 'vendor' (default): individual toggle per vendor, grouped by category\n * - 'purpose': toggle per category/purpose, vendors listed as info below\n */\n displayMode?: 'vendor' | 'purpose';\n /**\n * Custom labels for each purpose/category in 'purpose' displayMode.\n * Keys must match the vendor `category` values.\n *\n * @example\n * purposes: {\n * analytics: { label: \"Analyse de session et mesure d'audience\" },\n * Publicité: { label: \"Ciblage Marketing\" },\n * }\n */\n purposes?: Record<\n string,\n {\n /** Human-readable label displayed as the purpose title. */\n label: string;\n /** Optional description shown below the purpose title. */\n description?: string;\n }\n >;\n /**\n * When true, displays a \"Functional / Site operation\" mandatory purpose block\n * at the top of the details panel. This is a visual-only block with no toggle —\n * it informs the user that essential cookies are always active.\n */\n functionalPurpose?: boolean;\n}\n\nexport interface McVendor {\n /**\n * Built-in vendor name (e.g. 'google-analytics') when using npm with\n * built-in loaders, OR a unique ID when providing an inline init().\n */\n name: string;\n /**\n * Category for this vendor (e.g. 'analytics', 'marketing').\n * Optional for built-in vendors — they define their own category.\n * Required for inline vendors (defaults to 'other' if omitted).\n */\n category?: string;\n config?: Record<string, any>;\n\n // --- Inline vendor definition (CDN users / custom vendors) ---\n /** Human-readable label shown in the consent UI. Defaults to `name`. */\n label?: string;\n /** Short description shown in the consent UI. */\n description?: string;\n /** Whether the user must explicitly consent before this vendor activates. @default true */\n requireConsent?: boolean;\n /** Called immediately at page load (e.g. set consent defaults). */\n setup?: (config?: Record<string, any>) => void;\n /** Called when consent is granted. Inject scripts, pixels, etc. here. */\n init?: (config?: Record<string, any>) => void;\n /** Cookie names written by this vendor — cleared when consent is revoked. */\n artifacts?: string[];\n}\n\nexport type ConfigCommand = ['config', McConfig];\nexport type VendorCommand = ['vendor', McVendor];\nexport type McCommand = ConfigCommand | VendorCommand;\n\ntype McAPI = {\n (...args: McCommand): void;\n openPanel: () => void;\n getConsent: () => ConsentState;\n on: typeof emitter.on;\n};\n\ndeclare global {\n interface Window {\n _modernConsentConfig: McConfig;\n mcLayer: McCommand[];\n modernConsent: McAPI;\n }\n}\n\nfunction handleVendor(event: McVendor) {\n const {\n name,\n label,\n description = '',\n category = 'other',\n config = {},\n requireConsent = true,\n setup,\n init,\n artifacts,\n } = event;\n\n let loader: import('./registry').VendorLoader;\n\n if (init ?? setup) {\n // Inline vendor — CDN users provide their own implementation.\n loader = async () => ({\n name: label ?? name,\n description,\n category,\n requireConsent,\n setup,\n init,\n artifacts,\n });\n } else {\n // Look up via the resolver chain (builtin, CDN, or user-registered resolvers).\n const resolved = resolveVendor(name);\n if (!resolved) {\n console.warn(\n `[modern-consent] Unknown vendor \"${name}\". ` +\n `Provide an init() function to define a custom vendor.`,\n );\n return;\n }\n loader = resolved;\n }\n\n registerService({ id: name, category, config, loader });\n}\n\n/**\n * Initialise window.mcLayer et traite la queue éventuelle.\n */\nexport function initMcLayer() {\n if (typeof window === 'undefined') return;\n\n const w = window;\n const existingQueue = Array.isArray(w.mcLayer) ? [...w.mcLayer] : [];\n\n w._modernConsentConfig = {};\n\n // CDN resolver — lowest priority (registered first = LIFO lowest).\n // Returns a loader for any name; cdnBase is checked lazily at activation time.\n addResolver(_name => {\n return async () => {\n const cdnBase = w._modernConsentConfig?.cdnBase;\n if (!cdnBase) {\n throw new Error(\n `[modern-consent] Vendor \"${_name}\" not found. ` +\n `Configure cdnBase to enable CDN loading, or provide an inline init().`,\n );\n }\n const url = `${cdnBase.replace(/\\/$/, '')}/${_name}.js`;\n const mod = await import(/* @vite-ignore */ url);\n return (mod.default ?? mod) as Vendor<any>;\n };\n });\n\n // Process the existing queue — config commands accumulate before vendors are registered\n existingQueue.forEach((args: McCommand) => {\n const [command, payload] = args;\n\n if (!validCommands.includes(command as any)) {\n console.warn(`[modern-consent] \"${command}\" is not a valid command`);\n return;\n }\n\n if (command === 'config') {\n w._modernConsentConfig = { ...w._modernConsentConfig, ...(payload as McConfig) };\n return;\n }\n\n handleVendor(payload as McVendor);\n });\n\n // State is initialised once after config is fully resolved from the queue\n initState(w._modernConsentConfig);\n\n // Live API\n const apiFn = (...args: McCommand) => {\n const [command, payload] = args;\n\n if (!validCommands.includes(command as any)) {\n console.warn(`[modern-consent] \"${command}\" is not a valid command`);\n return;\n }\n\n if (command === 'vendor') {\n handleVendor(payload as McVendor);\n } else if (command === 'config') {\n w._modernConsentConfig = { ...w._modernConsentConfig, ...(payload as McConfig) };\n }\n\n if (!Array.isArray(w.mcLayer)) w.mcLayer = [];\n w.mcLayer.push(args);\n };\n\n w.modernConsent = Object.assign(apiFn, {\n openPanel: () => isPanelOpen.set(true),\n getConsent: () => consentState.get(),\n on: emitter.on.bind(emitter),\n });\n}\n","export type { ConsentState, ServiceMetadata } from './state.ts';\n\nexport { Store } from './utils/store';\n\nexport { consentState, hasAnswered, servicesList, isPanelOpen, openPanel } from './state';\n\n// Vendor Resolution\nexport { addResolver, resolveVendor } from './resolver';\n\nexport {\n registerService,\n activateService,\n clearVendorArtifacts,\n type Vendor,\n type VendorLoader,\n type VendorConfig,\n} from './registry';\n\nexport { setConsent, acceptAll, denyAll } from './consent';\n\nexport type { McConfig, McVendor, McCommand, ConfigCommand, VendorCommand } from './layer';\n\nexport { emitter, type ConsentEventMap } from './emitter';\nexport { generateUUID } from './utils/uuid';\nexport { initMcLayer } from './layer';\n\nimport { initMcLayer } from './layer';\n\nif (typeof window !== 'undefined') {\n initMcLayer();\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/store.ts","../src/utils/uuid.ts","../src/state.ts","../src/registry.ts","../src/emitter.ts","../src/consent.ts","../src/layer.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export type Subscriber<T> = (value: T) => void;\nexport type Unsubscriber = () => void;\n\nexport class Store<T> {\n private value: T;\n private subscribers: Set<Subscriber<T>> = new Set();\n\n constructor(initialValue: T) {\n this.value = initialValue;\n }\n\n get(): T {\n return this.value;\n }\n\n set(newValue: T): void {\n if (this.value !== newValue) {\n this.value = newValue;\n this.notify();\n }\n }\n\n update(updater: (value: T) => T): void {\n this.set(updater(this.value));\n }\n\n subscribe(callback: Subscriber<T>): Unsubscriber {\n this.subscribers.add(callback);\n callback(this.value); // Appel immédiat\n return () => this.subscribers.delete(callback);\n }\n\n private notify(): void {\n this.subscribers.forEach(cb => cb(this.value));\n }\n}\n","function manualUUIDv4(): string {\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n // Set version 4 (0100) and variant 10xx bits per RFC 4122\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n const hex = Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');\n return [\n hex.slice(0, 8),\n hex.slice(8, 12),\n hex.slice(12, 16),\n hex.slice(16, 20),\n hex.slice(20),\n ].join('-');\n}\n\nexport const generateUUID = (): string =>\n typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'\n ? crypto.randomUUID()\n : manualUUIDv4();\n","// core/src/state.ts\nimport { Store } from './utils/store';\nimport { generateUUID } from './utils/uuid';\n\nexport interface ConsentState {\n [serviceId: string]: boolean;\n}\n\nexport interface ServiceMetadata {\n id: string;\n name: string;\n description: string;\n category: string;\n /** Human-readable label for the purpose/category in 'purpose' displayMode. */\n purposeLabel?: string | Record<string, string>;\n /** Optional description for the purpose/category in 'purpose' displayMode. */\n purposeDescription?: string | Record<string, string>;\n loaded: boolean;\n requireConsent: boolean;\n}\n\ninterface StoredState {\n consent: ConsentState;\n answered: boolean;\n /** Unix timestamp (ms) of when consent was last given — for GDPR audit trail. */\n timestamp?: number;\n /** Version of the consent banner at the time of consent. */\n version?: string;\n /** Unique identifier per consent action — for GDPR audit trail. */\n consentId?: string;\n}\n\nconst DEFAULT_STORAGE_KEY = 'mc_consent_state';\n\ninterface CookieOptions {\n days?: number;\n path?: string;\n domain?: string;\n sameSite?: 'Lax' | 'Strict' | 'None';\n secure?: boolean;\n}\n\nfunction escapeCookieName(name: string): string {\n return name.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nconst getCookie = (name: string): string | null => {\n if (typeof document === 'undefined') return null;\n const match = document.cookie.match(new RegExp(`(?:^|; )${escapeCookieName(name)}=([^;]*)`));\n return match ? decodeURIComponent(match[1]) : null;\n};\n\nconst setCookie = (name: string, value: string, options: CookieOptions = {}) => {\n if (typeof document === 'undefined') return;\n\n const { days = 365, path = '/', domain, sameSite = 'Lax', secure = false } = options;\n\n const expires = new Date();\n expires.setDate(expires.getDate() + days);\n\n let cookieString =\n `${name}=${encodeURIComponent(value)};` +\n `expires=${expires.toUTCString()};` +\n `path=${path};` +\n `SameSite=${sameSite}`;\n\n if (domain) {\n const hostname = typeof window !== 'undefined' ? window.location.hostname : '';\n if (hostname && !hostname.endsWith(domain.replace(/^\\./, ''))) {\n console.warn(\n `[modern-consent] cookieDomain \"${domain}\" does not match current hostname \"${hostname}\". ` +\n `The cookie will be silently rejected by the browser. ` +\n `Remove cookieDomain for local development.`,\n );\n }\n cookieString += `;domain=${domain}`;\n }\n if (secure || sameSite === 'None') cookieString += `;Secure`;\n\n document.cookie = cookieString;\n};\n\nexport const consentState = new Store<ConsentState>({});\nexport const hasAnswered = new Store<boolean>(false);\nexport const servicesList = new Store<ServiceMetadata[]>([]);\nexport const isPanelOpen = new Store<boolean>(false);\nexport const openPanel = () => isPanelOpen.set(true);\n\n// Tracked so that calling initState multiple times never stacks duplicate subscribers\nlet _cookieUnsubs: (() => void)[] = [];\n\nexport const initState = (\n config: Pick<import('./layer').McConfig, 'cookieName' | 'cookieDomain' | 'consentVersion'>,\n) => {\n const cookieName: string = config?.cookieName || DEFAULT_STORAGE_KEY;\n const cookieDomain: string | undefined = config?.cookieDomain;\n const consentVersion: string | undefined = config?.consentVersion;\n\n let initialData: StoredState = { consent: {}, answered: false };\n\n if (typeof window !== 'undefined') {\n const stored = getCookie(cookieName);\n if (stored) {\n try {\n initialData = JSON.parse(stored) as StoredState;\n } catch (e) {\n console.error('[modern-consent] Error parsing consent cookie', e);\n }\n }\n }\n\n consentState.set(initialData.consent || {});\n hasAnswered.set(initialData.answered || false);\n\n // Re-prompt when consentVersion changes (GDPR: policy update invalidates prior consent)\n if (initialData.answered && consentVersion && initialData.version !== consentVersion) {\n hasAnswered.set(false);\n isPanelOpen.set(true);\n }\n\n if (typeof window !== 'undefined') {\n // Clean up previous subscriptions before creating new ones\n _cookieUnsubs.forEach(fn => fn());\n _cookieUnsubs = [];\n\n const saveToCookie = () => {\n const state: StoredState = {\n consent: consentState.get(),\n answered: hasAnswered.get(),\n timestamp: Date.now(),\n version: consentVersion,\n consentId: generateUUID(),\n };\n setCookie(cookieName, JSON.stringify(state), {\n domain: cookieDomain,\n secure: window.location.protocol === 'https:',\n });\n };\n\n _cookieUnsubs.push(consentState.subscribe(saveToCookie));\n _cookieUnsubs.push(hasAnswered.subscribe(saveToCookie));\n }\n};\n","import { consentState, hasAnswered, isPanelOpen, servicesList } from './state';\nimport { resolveVendor } from './resolver';\nimport type { McConfig } from './layer';\n\ndeclare global {\n interface Window {\n _modernConsentConfig: McConfig;\n }\n}\n\nexport type VendorConfig = unknown;\n\nexport interface Vendor<TConfig = void> {\n name: string;\n description: string;\n category: string;\n /**\n * Human-readable label for the purpose/category in 'purpose' displayMode.\n * Can be a string or a Record<lang, string> for i18n support.\n * @example purposeLabel: { fr: \"Mesure d'audience\", en: \"Audience measurement\" }\n */\n purposeLabel?: string | Record<string, string>;\n /**\n * Description for the purpose/category in 'purpose' displayMode.\n * Can be a string or a Record<lang, string> for i18n support.\n */\n purposeDescription?: string | Record<string, string>;\n setup?: (config: TConfig) => void;\n domSelector?: string;\n init?: (config: TConfig) => void;\n /** Cookie names set by this vendor — cleared when consent is revoked. */\n artifacts?: string[] | ((config: TConfig) => string[]);\n render?: (dataset: DOMStringMap) => string;\n requireConsent: boolean;\n event?: {\n name: string;\n callback: () => void;\n }[];\n link?: {\n vendor: string;\n /** Config passed to the linked vendor. Defaults to {} if omitted. */\n config?: VendorConfig;\n condition: (params: { vendorConfig: any; consentConfig: any }) => boolean;\n }[];\n}\n\nexport type VendorLoader = () => Promise<Vendor<any>>;\n\nconst loaders = new Map<string, VendorLoader>();\nconst loadedVendors = new Map<string, Vendor<VendorConfig>>();\nconst vendorsConfig = new Map<string, VendorConfig>();\n\n// Re-export resolveVendor from resolver.ts for backward compatibility\nexport { resolveVendor } from './resolver';\n\n/** @internal — test helper only */\nexport function __resetRegistry() {\n loaders.clear();\n loadedVendors.clear();\n vendorsConfig.clear();\n}\n\n/**\n * Clears all cookies declared in vendor.artifacts.\n * Called before reload or on denyAll to clean up vendor-set cookies.\n */\nexport function clearVendorArtifacts(id: string): void {\n const vendor = loadedVendors.get(id);\n if (!vendor?.artifacts) return;\n\n const config = vendorsConfig.get(id);\n const cookieNames =\n typeof vendor.artifacts === 'function' ? vendor.artifacts(config) : vendor.artifacts;\n\n const domain = window._modernConsentConfig?.cookieDomain;\n\n cookieNames.forEach(name => {\n document.cookie = `${name}=; max-age=0; path=/`;\n if (domain) {\n document.cookie = `${name}=; max-age=0; path=/; domain=${domain}`;\n }\n });\n}\n\nexport function registerService(args: {\n id: string;\n category: string;\n loader: VendorLoader;\n config: VendorConfig;\n}) {\n const { id, category, loader, config = {} } = args;\n\n // Prevent double-registration for the same service id\n if (loaders.has(id)) return;\n loaders.set(id, loader);\n\n loader()\n .then((module: any) => {\n const vendor: Vendor<any> = module.default || module;\n loadedVendors.set(id, vendor);\n if (config !== undefined) {\n vendorsConfig.set(id, config);\n }\n\n if (vendor?.setup) {\n try {\n vendor.setup(config);\n } catch (err) {\n console.error(`[modern-consent] setup() failed for \"${id}\":`, err);\n }\n }\n\n if (vendor?.link && vendor.link.length > 0) {\n vendor.link.forEach(link => {\n if (\n link.condition &&\n !link.condition({ vendorConfig: config, consentConfig: window._modernConsentConfig })\n ) {\n return;\n }\n const linkedLoader = resolveVendor(link.vendor);\n if (linkedLoader) {\n registerService({\n id: link.vendor,\n category,\n config: link.config ?? {},\n loader: linkedLoader,\n });\n } else {\n console.warn(`[modern-consent] Dependency \"${link.vendor}\" not found for \"${id}\"`);\n }\n });\n }\n\n servicesList.update(list => {\n if (list.some(s => s.id === id)) return list;\n return [\n ...list,\n {\n id,\n name: vendor.name,\n description: vendor.description,\n category: vendor.category,\n purposeLabel: vendor.purposeLabel,\n purposeDescription: vendor.purposeDescription,\n loaded: false,\n requireConsent: vendor.requireConsent,\n },\n ];\n });\n\n checkAutoActivation(id);\n })\n .catch(err => {\n console.error(`[modern-consent] Failed to load vendor \"${id}\":`, err);\n });\n}\n\n/**\n * Check if the service should auto-activate or if the panel should open (new service detected).\n */\nfunction checkAutoActivation(id: string) {\n const vendor = loadedVendors.get(id);\n\n // Services that don't require consent activate immediately\n if (vendor && !vendor.requireConsent) {\n activateService(id);\n return;\n }\n\n const currentConsent = consentState.get();\n const answered = hasAnswered.get();\n\n if (answered && currentConsent[id] === undefined) {\n isPanelOpen.set(true);\n }\n\n if (currentConsent[id]) {\n activateService(id);\n }\n}\n\n/**\n * Activate the service (script injection + DOM rendering).\n */\nexport async function activateService(id: string) {\n if (typeof window === 'undefined') return;\n\n let vendor = loadedVendors.get(id);\n\n if (!vendor) {\n const loader = loaders.get(id);\n if (loader) {\n const module: any = await loader();\n vendor = module.default || module;\n if (vendor) loadedVendors.set(id, vendor);\n }\n }\n\n if (!vendor) return;\n\n const isSoft = window._modernConsentConfig?.consentOnly === true;\n const list = servicesList.get();\n const meta = list.find(s => s.id === id);\n\n if (!isSoft && vendor.init && meta && !meta.loaded) {\n vendor.init(vendorsConfig.get(id));\n servicesList.update(l => l.map(s => (s.id === id ? { ...s, loaded: true } : s)));\n\n // Trigger onAccept events after successful activation\n vendor.event?.forEach(ev => {\n if (ev.name === 'onAccept') {\n try {\n ev.callback();\n } catch {\n /* don't let event errors break activation */\n }\n }\n });\n }\n\n if (!isSoft && vendor.domSelector && vendor.render) {\n setTimeout(() => {\n document.querySelectorAll(vendor!.domSelector!).forEach(el => {\n const htmlElement = el as HTMLElement;\n if (htmlElement.dataset.loaded !== 'true' && vendor?.render) {\n htmlElement.innerHTML = vendor.render(htmlElement.dataset);\n htmlElement.dataset.loaded = 'true';\n htmlElement.classList.remove('mc-placeholder-pending');\n }\n });\n }, 50);\n }\n}\n","import type { ConsentState } from './state';\n\nexport type ConsentEventMap = {\n 'consent:update': { vendor: string; status: 'granted' | 'denied'; gcm?: Record<string, boolean> };\n 'consent:saved': {\n consentId: string;\n timestamp: number;\n version?: string;\n consent: ConsentState;\n };\n};\n\ntype Listener<T> = (data: T) => void;\n\nclass ConsentEmitter {\n private listeners = new Map<string, Set<Listener<any>>>();\n\n on<K extends keyof ConsentEventMap>(event: K, cb: Listener<ConsentEventMap[K]>): () => void {\n if (!this.listeners.has(event)) this.listeners.set(event, new Set());\n this.listeners.get(event)!.add(cb);\n return () => this.listeners.get(event)?.delete(cb);\n }\n\n off<K extends keyof ConsentEventMap>(event: K, cb: Listener<ConsentEventMap[K]>): void {\n this.listeners.get(event)?.delete(cb);\n }\n\n emit<K extends keyof ConsentEventMap>(event: K, data: ConsentEventMap[K]): void {\n this.listeners.get(event)?.forEach(cb => {\n try {\n cb(data);\n } catch {\n /* don't let listener errors break the core */\n }\n });\n }\n}\n\nexport const emitter = new ConsentEmitter();\n","import { servicesList, consentState, hasAnswered, isPanelOpen } from './state';\nimport type { ConsentState } from './state';\nimport { activateService, clearVendorArtifacts } from './registry';\nimport { emitter } from './emitter';\nimport { generateUUID } from './utils/uuid';\n\ndeclare global {\n interface Window {\n consentLayer: any[];\n dataLayer: any[];\n }\n}\n\n/**\n * Always pushes consent state to `window.consentLayer` (TMS-agnostic).\n * Optionally pushes to `window.dataLayer` when `pushDataLayer` is enabled (GTM convenience).\n */\nfunction pushConsentEvent(consent: ConsentState) {\n if (typeof window === 'undefined') return;\n\n const event = {\n event: 'consent_update',\n consent_state: consent,\n };\n\n // consentLayer — always active, TMS-agnostic\n window.consentLayer = window.consentLayer || [];\n window.consentLayer.push(event);\n\n // dataLayer — opt-in for GTM native triggers\n if (window._modernConsentConfig?.pushDataLayer) {\n window.dataLayer = window.dataLayer || [];\n window.dataLayer.push(event);\n }\n}\n\nfunction emitConsentSaved(consent: ConsentState) {\n emitter.emit('consent:saved', {\n consentId: generateUUID(),\n timestamp: Date.now(),\n version:\n typeof window !== 'undefined' ? window._modernConsentConfig?.consentVersion : undefined,\n consent,\n });\n}\n\nexport function setConsent(id: string, allowed: boolean) {\n // Check before updating state whether this service was actively running\n const wasPreviouslyLoaded = servicesList.get().find(s => s.id === id)?.loaded ?? false;\n\n consentState.update(s => ({ ...s, [id]: allowed }));\n hasAnswered.set(true);\n\n emitter.emit('consent:update', {\n vendor: id,\n status: allowed ? 'granted' : 'denied',\n });\n\n const updatedConsent = consentState.get();\n pushConsentEvent(updatedConsent);\n emitConsentSaved(updatedConsent);\n\n if (allowed) {\n activateService(id);\n return;\n }\n\n // Only clean up and reload if the service was actively running\n if (wasPreviouslyLoaded) {\n clearVendorArtifacts(id);\n const isConsentOnly =\n typeof window !== 'undefined' && window._modernConsentConfig?.consentOnly === true;\n if (!isConsentOnly && typeof window !== 'undefined') window.location.reload();\n }\n}\n\nexport function acceptAll() {\n const list = servicesList.get();\n const updates: Record<string, boolean> = {};\n\n list.forEach(s => {\n updates[s.id] = true;\n activateService(s.id);\n });\n\n consentState.set(updates);\n hasAnswered.set(true);\n isPanelOpen.set(false);\n\n list.forEach(s => {\n emitter.emit('consent:update', { vendor: s.id, status: 'granted' });\n });\n\n pushConsentEvent(updates);\n emitConsentSaved(updates);\n}\n\nexport function denyAll() {\n const list = servicesList.get();\n const updates: Record<string, boolean> = {};\n let needsReload = false;\n\n list.forEach(s => {\n updates[s.id] = false;\n clearVendorArtifacts(s.id);\n if (s.loaded) needsReload = true;\n });\n\n consentState.set(updates);\n hasAnswered.set(true);\n isPanelOpen.set(false);\n\n list.forEach(s => {\n emitter.emit('consent:update', { vendor: s.id, status: 'denied' });\n });\n\n pushConsentEvent(updates);\n emitConsentSaved(updates);\n\n // Reload only if at least one vendor was actively running —\n // clears vendor scripts from memory after cookie cleanup.\n const isConsentOnly =\n typeof window !== 'undefined' && window._modernConsentConfig?.consentOnly === true;\n if (needsReload && !isConsentOnly && typeof window !== 'undefined') {\n window.location.reload();\n }\n}\n","import { registerService } from './registry';\nimport { addResolver, resolveVendor } from './resolver';\nimport { consentState, initState, isPanelOpen } from './state';\nimport type { ConsentState } from './state';\nimport type { Vendor } from './registry';\nimport { emitter } from './emitter';\n\n/**\n * Command can add in config\n */\nconst validCommands = ['config', 'vendor'] as const;\n\nexport interface McConfig {\n cookieDomain?: string;\n cookieName?: string;\n consentMode?: boolean;\n /** Version string embedded in the stored consent — used for GDPR audit trails. */\n consentVersion?: string;\n /**\n * Base URL where vendor JS files are hosted.\n * Used by the CDN bundle to lazy-load vendors on demand.\n *\n * @example 'https://cdn.monsite.com/mc-vendors'\n * → window.modernConsent('vendor', { name: 'google-analytics' })\n * → fetches https://cdn.monsite.com/mc-vendors/google-analytics.js\n */\n cdnBase?: string;\n /**\n * In Consent-Only mode, the CMP only manages consent decisions + cookie storage.\n * Vendors are never initialized (no call to init()).\n * Use this to manage vendor scripts externally via a Tag Manager (GTM, TagCommander, etc.).\n *\n * Consent changes are always pushed to `window.consentLayer`.\n * Enable `pushDataLayer` to also push to `window.dataLayer` for native GTM triggers.\n */\n consentOnly?: boolean;\n /**\n * When true, consent changes are also pushed to `window.dataLayer` for native\n * GTM trigger support. Disabled by default — GTM users should enable this.\n */\n pushDataLayer?: boolean;\n /**\n * How the details panel displays consent controls:\n * - 'vendor' (default): individual toggle per vendor, grouped by category\n * - 'purpose': toggle per category/purpose, vendors listed as info below\n */\n displayMode?: 'vendor' | 'purpose';\n /**\n * Custom labels for each purpose/category in 'purpose' displayMode.\n * Keys must match the vendor `category` values.\n *\n * @example\n * purposes: {\n * analytics: { label: \"Analyse de session et mesure d'audience\" },\n * Publicité: { label: \"Ciblage Marketing\" },\n * }\n */\n purposes?: Record<\n string,\n {\n /** Human-readable label displayed as the purpose title. */\n label: string;\n /** Optional description shown below the purpose title. */\n description?: string;\n }\n >;\n /**\n * When true, displays a \"Functional / Site operation\" mandatory purpose block\n * at the top of the details panel. This is a visual-only block with no toggle —\n * it informs the user that essential cookies are always active.\n */\n functionalPurpose?: boolean;\n}\n\nexport interface McVendor {\n /**\n * Built-in vendor name (e.g. 'google-analytics') when using npm with\n * built-in loaders, OR a unique ID when providing an inline init().\n */\n name: string;\n /**\n * Category for this vendor (e.g. 'analytics', 'marketing').\n * Optional for built-in vendors — they define their own category.\n * Required for inline vendors (defaults to 'other' if omitted).\n */\n category?: string;\n config?: Record<string, any>;\n\n // --- Inline vendor definition (CDN users / custom vendors) ---\n /** Human-readable label shown in the consent UI. Defaults to `name`. */\n label?: string;\n /** Short description shown in the consent UI. */\n description?: string;\n /** Whether the user must explicitly consent before this vendor activates. @default true */\n requireConsent?: boolean;\n /** Called immediately at page load (e.g. set consent defaults). */\n setup?: (config?: Record<string, any>) => void;\n /** Called when consent is granted. Inject scripts, pixels, etc. here. */\n init?: (config?: Record<string, any>) => void;\n /** Cookie names written by this vendor — cleared when consent is revoked. */\n artifacts?: string[];\n}\n\nexport type ConfigCommand = ['config', McConfig];\nexport type VendorCommand = ['vendor', McVendor];\nexport type McCommand = ConfigCommand | VendorCommand;\n\ntype McAPI = {\n (...args: McCommand): void;\n openPanel: () => void;\n getConsent: () => ConsentState;\n on: typeof emitter.on;\n};\n\ndeclare global {\n interface Window {\n _modernConsentConfig: McConfig;\n mcLayer: McCommand[];\n modernConsent: McAPI;\n }\n}\n\nfunction handleVendor(event: McVendor) {\n const {\n name,\n label,\n description = '',\n category = 'other',\n config = {},\n requireConsent = true,\n setup,\n init,\n artifacts,\n } = event;\n\n let loader: import('./registry').VendorLoader;\n\n if (init ?? setup) {\n // Inline vendor — CDN users provide their own implementation.\n loader = async () => ({\n name: label ?? name,\n description,\n category,\n requireConsent,\n setup,\n init,\n artifacts,\n });\n } else {\n // Look up via the resolver chain (builtin, CDN, or user-registered resolvers).\n const resolved = resolveVendor(name);\n if (!resolved) {\n console.warn(\n `[modern-consent] Unknown vendor \"${name}\". ` +\n `Provide an init() function to define a custom vendor.`,\n );\n return;\n }\n loader = resolved;\n }\n\n registerService({ id: name, category, config, loader });\n}\n\n/**\n * Initialise window.mcLayer et traite la queue éventuelle.\n */\nexport function initMcLayer() {\n if (typeof window === 'undefined') return;\n\n const w = window;\n const existingQueue = Array.isArray(w.mcLayer) ? [...w.mcLayer] : [];\n\n w._modernConsentConfig = {};\n\n // CDN resolver — lowest priority (registered first = LIFO lowest).\n // Returns a loader for any name; cdnBase is checked lazily at activation time.\n addResolver(_name => {\n return async () => {\n const cdnBase = w._modernConsentConfig?.cdnBase;\n if (!cdnBase) {\n throw new Error(\n `[modern-consent] Vendor \"${_name}\" not found. ` +\n `Configure cdnBase to enable CDN loading, or provide an inline init().`,\n );\n }\n const url = `${cdnBase.replace(/\\/$/, '')}/${_name}.js`;\n const mod = await import(/* @vite-ignore */ url);\n return (mod.default ?? mod) as Vendor<any>;\n };\n });\n\n // Process the existing queue — config commands accumulate before vendors are registered\n existingQueue.forEach((args: McCommand) => {\n const [command, payload] = args;\n\n if (!validCommands.includes(command as any)) {\n console.warn(`[modern-consent] \"${command}\" is not a valid command`);\n return;\n }\n\n if (command === 'config') {\n w._modernConsentConfig = { ...w._modernConsentConfig, ...(payload as McConfig) };\n return;\n }\n\n handleVendor(payload as McVendor);\n });\n\n // State is initialised once after config is fully resolved from the queue\n initState(w._modernConsentConfig);\n\n // Live API\n const apiFn = (...args: McCommand) => {\n const [command, payload] = args;\n\n if (!validCommands.includes(command as any)) {\n console.warn(`[modern-consent] \"${command}\" is not a valid command`);\n return;\n }\n\n if (command === 'vendor') {\n handleVendor(payload as McVendor);\n } else if (command === 'config') {\n w._modernConsentConfig = { ...w._modernConsentConfig, ...(payload as McConfig) };\n }\n\n if (!Array.isArray(w.mcLayer)) w.mcLayer = [];\n w.mcLayer.push(args);\n };\n\n w.modernConsent = Object.assign(apiFn, {\n openPanel: () => isPanelOpen.set(true),\n getConsent: () => consentState.get(),\n on: emitter.on.bind(emitter),\n });\n}\n","export type { ConsentState, ServiceMetadata } from './state.ts';\n\nexport { Store } from './utils/store';\n\nexport { consentState, hasAnswered, servicesList, isPanelOpen, openPanel } from './state';\n\n// Vendor Resolution\nexport { addResolver, resolveVendor } from './resolver';\n\nexport {\n registerService,\n activateService,\n clearVendorArtifacts,\n type Vendor,\n type VendorLoader,\n type VendorConfig,\n} from './registry';\n\nexport { setConsent, acceptAll, denyAll } from './consent';\n\nexport type { McConfig, McVendor, McCommand, ConfigCommand, VendorCommand } from './layer';\n\nexport { emitter, type ConsentEventMap } from './emitter';\nexport { generateUUID } from './utils/uuid';\nexport { initMcLayer } from './layer';\n\nimport { initMcLayer } from './layer';\n\nif (typeof window !== 'undefined') {\n initMcLayer();\n}\n"]}
@@ -1,37 +1,3 @@
1
- type Subscriber<T> = (value: T) => void;
2
- type Unsubscriber = () => void;
3
- declare class Store<T> {
4
- private value;
5
- private subscribers;
6
- constructor(initialValue: T);
7
- get(): T;
8
- set(newValue: T): void;
9
- update(updater: (value: T) => T): void;
10
- subscribe(callback: Subscriber<T>): Unsubscriber;
11
- private notify;
12
- }
13
-
14
- interface ConsentState {
15
- [serviceId: string]: boolean;
16
- }
17
- interface ServiceMetadata {
18
- id: string;
19
- name: string;
20
- description: string;
21
- category: string;
22
- /** Human-readable label for the purpose/category in 'purpose' displayMode. */
23
- purposeLabel?: string | Record<string, string>;
24
- /** Optional description for the purpose/category in 'purpose' displayMode. */
25
- purposeDescription?: string | Record<string, string>;
26
- loaded: boolean;
27
- requireConsent: boolean;
28
- }
29
- declare const consentState: Store<ConsentState>;
30
- declare const hasAnswered: Store<boolean>;
31
- declare const servicesList: Store<ServiceMetadata[]>;
32
- declare const isPanelOpen: Store<boolean>;
33
- declare const openPanel: () => void;
34
-
35
1
  type ConsentEventMap = {
36
2
  'consent:update': {
37
3
  vendor: string;
@@ -159,6 +125,40 @@ declare global {
159
125
  */
160
126
  declare function initMcLayer(): void;
161
127
 
128
+ type Subscriber<T> = (value: T) => void;
129
+ type Unsubscriber = () => void;
130
+ declare class Store<T> {
131
+ private value;
132
+ private subscribers;
133
+ constructor(initialValue: T);
134
+ get(): T;
135
+ set(newValue: T): void;
136
+ update(updater: (value: T) => T): void;
137
+ subscribe(callback: Subscriber<T>): Unsubscriber;
138
+ private notify;
139
+ }
140
+
141
+ interface ConsentState {
142
+ [serviceId: string]: boolean;
143
+ }
144
+ interface ServiceMetadata {
145
+ id: string;
146
+ name: string;
147
+ description: string;
148
+ category: string;
149
+ /** Human-readable label for the purpose/category in 'purpose' displayMode. */
150
+ purposeLabel?: string | Record<string, string>;
151
+ /** Optional description for the purpose/category in 'purpose' displayMode. */
152
+ purposeDescription?: string | Record<string, string>;
153
+ loaded: boolean;
154
+ requireConsent: boolean;
155
+ }
156
+ declare const consentState: Store<ConsentState>;
157
+ declare const hasAnswered: Store<boolean>;
158
+ declare const servicesList: Store<ServiceMetadata[]>;
159
+ declare const isPanelOpen: Store<boolean>;
160
+ declare const openPanel: () => void;
161
+
162
162
  declare global {
163
163
  interface Window {
164
164
  _modernConsentConfig: McConfig;
@@ -215,7 +215,7 @@ declare function registerService(args: {
215
215
  config: VendorConfig;
216
216
  }): void;
217
217
  /**
218
- * Active le service (Script + DOM)
218
+ * Activate the service (script injection + DOM rendering).
219
219
  */
220
220
  declare function activateService(id: string): Promise<void>;
221
221
 
@@ -1 +1 @@
1
- export { u as VendorResolver, _ as __resetResolvers, b as addResolver, r as resolveVendor } from './resolver-CKoWIVlu.js';
1
+ export { u as VendorResolver, _ as __resetResolvers, b as addResolver, r as resolveVendor } from './resolver-CssVkauA.js';
package/dist/resolver.js CHANGED
@@ -1,3 +1,3 @@
1
- export { __resetResolvers, addResolver, resolveVendor } from './chunk-UZ3JLA4T.js';
1
+ export { __resetResolvers, addResolver, resolveVendor } from './chunk-ENHZCUQ7.js';
2
2
  //# sourceMappingURL=resolver.js.map
3
3
  //# sourceMappingURL=resolver.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modernconsent/core",
3
- "version": "0.0.1",
3
+ "version": "1.0.0",
4
4
  "description": "A modern, lightweight consent management library",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,23 +0,0 @@
1
- // src/resolver.ts
2
- var _resolvers = [];
3
- function addResolver(resolver) {
4
- _resolvers.push(resolver);
5
- return () => {
6
- const idx = _resolvers.indexOf(resolver);
7
- if (idx !== -1) _resolvers.splice(idx, 1);
8
- };
9
- }
10
- function resolveVendor(name) {
11
- for (let i = _resolvers.length - 1; i >= 0; i--) {
12
- const result = _resolvers[i](name);
13
- if (result) return result;
14
- }
15
- return void 0;
16
- }
17
- function __resetResolvers() {
18
- _resolvers.length = 0;
19
- }
20
-
21
- export { __resetResolvers, addResolver, resolveVendor };
22
- //# sourceMappingURL=chunk-UZ3JLA4T.js.map
23
- //# sourceMappingURL=chunk-UZ3JLA4T.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/resolver.ts"],"names":[],"mappings":";AASA,IAAM,aAA+B,EAAC;AAS/B,SAAS,YAAY,QAAA,EAAsC;AAChE,EAAA,UAAA,CAAW,KAAK,QAAQ,CAAA;AACxB,EAAA,OAAO,MAAM;AACX,IAAA,MAAM,GAAA,GAAM,UAAA,CAAW,OAAA,CAAQ,QAAQ,CAAA;AACvC,IAAA,IAAI,GAAA,KAAQ,EAAA,EAAI,UAAA,CAAW,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,EAC1C,CAAA;AACF;AAMO,SAAS,cAAc,IAAA,EAAwC;AACpE,EAAA,KAAA,IAAS,IAAI,UAAA,CAAW,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC/C,IAAA,MAAM,MAAA,GAAS,UAAA,CAAW,CAAC,CAAA,CAAE,IAAI,CAAA;AACjC,IAAA,IAAI,QAAQ,OAAO,MAAA;AAAA,EACrB;AACA,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,gBAAA,GAAyB;AACvC,EAAA,UAAA,CAAW,MAAA,GAAS,CAAA;AACtB","file":"chunk-UZ3JLA4T.js","sourcesContent":["// core/src/resolver.ts\nimport type { VendorLoader } from './registry';\n\n/**\n * A resolver maps a vendor name to a loader function.\n * Return `undefined` to pass resolution to the next resolver in the chain.\n */\nexport type VendorResolver = (name: string) => VendorLoader | undefined;\n\nconst _resolvers: VendorResolver[] = [];\n\n/**\n * Register a vendor resolver. Resolvers are tried in LIFO order\n * (last registered = highest priority), following the convention\n * from Vite/Rollup where later plugins override earlier ones.\n *\n * @returns A cleanup function that removes this resolver from the chain.\n */\nexport function addResolver(resolver: VendorResolver): () => void {\n _resolvers.push(resolver);\n return () => {\n const idx = _resolvers.indexOf(resolver);\n if (idx !== -1) _resolvers.splice(idx, 1);\n };\n}\n\n/**\n * Resolve a vendor name to a loader by walking the resolver chain (LIFO).\n * Returns `undefined` if no resolver can handle the name.\n */\nexport function resolveVendor(name: string): VendorLoader | undefined {\n for (let i = _resolvers.length - 1; i >= 0; i--) {\n const result = _resolvers[i](name);\n if (result) return result;\n }\n return undefined;\n}\n\n/** @internal — test helper only */\nexport function __resetResolvers(): void {\n _resolvers.length = 0;\n}\n"]}