@consenti/ui 0.4.0 → 0.6.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 +46 -2
- package/dist/angular.d.cts +27 -3
- package/dist/angular.d.ts +27 -3
- package/dist/index.d.ts +27 -3
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/react.d.cts +27 -3
- package/dist/react.d.ts +27 -3
- package/dist/vue.d.cts +27 -3
- package/dist/vue.d.ts +27 -3
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -183,14 +183,17 @@ const widget = new ConsentiSetup({
|
|
|
183
183
|
|
|
184
184
|
// Client-side geo resolver (used only when api.enabled = false)
|
|
185
185
|
// 'default' → browser timezone + navigator.language heuristic (built-in, zero deps)
|
|
186
|
-
// WidgetCountryResolverFn → custom async function: () => Promise<{ country, region, confidence }>
|
|
186
|
+
// WidgetCountryResolverFn → custom async function: ({ timezone, language, languages, locale }) => Promise<{ country, region, confidence }>
|
|
187
187
|
geoDataProvider: 'default',
|
|
188
188
|
|
|
189
189
|
// Only meaningful when api.enabled = false (ignored, with a warning, otherwise — the server
|
|
190
190
|
// resolves the group in that mode). Only overrides country→group mapping; country/region
|
|
191
191
|
// detection above always uses the embedded geo data.
|
|
192
192
|
// 'default' → embedded map (default) | a URL string (fetched; the browser's own HTTP cache
|
|
193
|
-
// honors whatever Cache-Control/ETag the response sends) | an inline ComplianceMapData object
|
|
193
|
+
// honors whatever Cache-Control/ETag the response sends) | an inline ComplianceMapData object.
|
|
194
|
+
// A country the map doesn't list falls back to the embedded mapping, unless the document sets
|
|
195
|
+
// `override: true` — then it gets the strictest group ('opt-in'). Unlike the server, an omitted
|
|
196
|
+
// `override` is NOT true here: widget maps have always merged over the embedded mapping.
|
|
194
197
|
complianceMap: 'default',
|
|
195
198
|
|
|
196
199
|
// TCF (IAB Transparency & Consent Framework) client stub (optional) — see "TCF" section below
|
|
@@ -272,6 +275,47 @@ profileOverride: {
|
|
|
272
275
|
no-op (same as omitting the key), the latter merges an empty object onto the existing category,
|
|
273
276
|
changing nothing. Only an explicit `null` removes it.
|
|
274
277
|
|
|
278
|
+
#### Replacing a whole map: `'*': null`
|
|
279
|
+
|
|
280
|
+
Removing entries one by one doesn't scale when you want to *replace* a map: every built-in
|
|
281
|
+
profile uses different button ids (`reject-optional`, `save-choices`, `manage-preferences`, …),
|
|
282
|
+
and there are three `buttons` maps (`mainBanner`, `gpcBanner`, `preferenceModal`). Use the
|
|
283
|
+
wildcard key `'*': null` to delete **every key of the base map that your override doesn't name**:
|
|
284
|
+
|
|
285
|
+
```ts
|
|
286
|
+
profileOverride: {
|
|
287
|
+
mainBanner: {
|
|
288
|
+
buttons: {
|
|
289
|
+
'*': null, // drop all other built-in buttons
|
|
290
|
+
'accept-all': { text: 'Allow all' }, // kept — only its text changes
|
|
291
|
+
'my-button': { text: 'Custom', style: 'secondary', action: 'custom', cookies: '!' },
|
|
292
|
+
},
|
|
293
|
+
},
|
|
294
|
+
preferenceModal: {
|
|
295
|
+
buttons: { '*': null, 'my-save': { text: 'Save', style: 'primary', action: 'submit' } },
|
|
296
|
+
categories: { '*': null, necessary: {}, analytics: {} }, // keep only these two categories
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
- Keys you **name** are kept and merged onto their base value (so `'accept-all': { text }` keeps
|
|
302
|
+
its `style`/`action`/`cookies`); keys you **don't name** are deleted; new keys are added.
|
|
303
|
+
- It works per map, so you choose which surfaces to replace — leave `gpcBanner` alone and it keeps
|
|
304
|
+
its built-in buttons.
|
|
305
|
+
- `'*': null` alone empties the map. It works on any keyed map (`cookies` too), and under
|
|
306
|
+
`complianceGroupsOverride` and `widget.setProfile()`.
|
|
307
|
+
- `'*'` is reserved in these maps and can't be used as a button/category id.
|
|
308
|
+
- `widget.setProfile()` patches are replayed in order on the resolved profile (rather than being
|
|
309
|
+
folded together first), so `null` and `'*': null` deletes in a later `setProfile()` call are
|
|
310
|
+
honoured even after an earlier override.
|
|
311
|
+
|
|
312
|
+
> **Compliance:** refusing must be as easy as accepting (GDPR Art. 7(3); CNIL/EDPB cookie-banner
|
|
313
|
+
> guidance). If, after overrides, a `mainBanner`/`gpcBanner` has an "accept all" button
|
|
314
|
+
> (`cookies: '*'`) but no reject (`cookies: '!'`) or `manage` button, the widget logs a
|
|
315
|
+
> `console.warn`. Warnings are hidden by default — enable them with `verbose: true` or
|
|
316
|
+
> `core: { console: ['warning'] }`. Keep a reject or manage path when
|
|
317
|
+
> you replace the built-in buttons.
|
|
318
|
+
|
|
275
319
|
---
|
|
276
320
|
|
|
277
321
|
## Compliance Groups
|
package/dist/angular.d.cts
CHANGED
|
@@ -64,6 +64,10 @@ type ComplianceType = 'auto' | ComplianceGroupId | (string & {}) | Symbol;
|
|
|
64
64
|
|
|
65
65
|
interface ComplianceMapData {
|
|
66
66
|
version: string;
|
|
67
|
+
/** `true` (default): this map replaces the embedded one entirely, so only the countries listed here
|
|
68
|
+
* resolve (server side). `false`: `countries` is merged over the embedded map — a listed country
|
|
69
|
+
* replaces its embedded entry wholesale, every unlisted country keeps its built-in mapping. */
|
|
70
|
+
override?: boolean;
|
|
67
71
|
countries: Record<string, CountryComplianceEntry>;
|
|
68
72
|
}
|
|
69
73
|
interface CountryComplianceEntry {
|
|
@@ -83,6 +87,9 @@ interface ConsentDbRecord {
|
|
|
83
87
|
tenantId: string;
|
|
84
88
|
visitorId: string;
|
|
85
89
|
profileId: string;
|
|
90
|
+
/** The profile's `version` when this consent was last given — with `profileId`, pins the exact
|
|
91
|
+
* on-disk snapshot (the banner text the visitor saw). Absent on records from before it was tracked. */
|
|
92
|
+
profileVersion?: number;
|
|
86
93
|
locale: string;
|
|
87
94
|
consentJson: ConsentValue;
|
|
88
95
|
gpcDetected: boolean;
|
|
@@ -281,7 +288,12 @@ interface ResolvedProfile {
|
|
|
281
288
|
/** Apply WCAG 2.1 AA accessibility enhancements to the widget. */
|
|
282
289
|
enhanceAccessibility?: boolean;
|
|
283
290
|
}
|
|
284
|
-
type WidgetCountryResolverFn = (
|
|
291
|
+
type WidgetCountryResolverFn = (hints: {
|
|
292
|
+
timezone: string;
|
|
293
|
+
language: string;
|
|
294
|
+
languages: string[];
|
|
295
|
+
locale: string;
|
|
296
|
+
}) => Promise<{
|
|
285
297
|
country: string | null;
|
|
286
298
|
region: string | null;
|
|
287
299
|
confidence: number;
|
|
@@ -340,8 +352,11 @@ interface ComplianceWidgetConfig {
|
|
|
340
352
|
* document from (the browser's own HTTP cache honors whatever `Cache-Control`/`ETag` the
|
|
341
353
|
* response sends — no custom caching here), or an inline operator-supplied `ComplianceMapData`
|
|
342
354
|
* object. Invalid data from either a URL or an object logs a warning and falls back to
|
|
343
|
-
* `'default'`. Only overrides the country→group mapping — country/region detection itself
|
|
344
|
-
*
|
|
355
|
+
* `'default'`. Only overrides the country→group mapping — country/region detection itself always
|
|
356
|
+
* uses the embedded geo data. A country the map doesn't list falls back to the embedded mapping
|
|
357
|
+
* unless the document sets `override: true` (then it gets the strictest group, `'opt-in'`).
|
|
358
|
+
* Unlike the server, an omitted `override` is NOT `true` here: widget maps have always merged
|
|
359
|
+
* over the embedded mapping, and that stays the default. */
|
|
345
360
|
complianceMap?: 'default' | string | ComplianceMapData;
|
|
346
361
|
tcf?: TcfWidgetConfig;
|
|
347
362
|
gpp?: GppWidgetConfig;
|
|
@@ -622,6 +637,7 @@ declare class ConsentiSetup implements ConsentiWidgetAPI {
|
|
|
622
637
|
private initializing;
|
|
623
638
|
private profile;
|
|
624
639
|
private resolvedBase;
|
|
640
|
+
private profilePatches;
|
|
625
641
|
/** cookieId → Category lookup, rebuilt whenever `profile` changes. Avoids rescanning categories on every consent action. */
|
|
626
642
|
private categoryIndex;
|
|
627
643
|
/** Watchers created by the declarative `data-consenti-*` DOM scan — destroyed alongside the widget since they have no other owner. */
|
|
@@ -677,6 +693,14 @@ declare class ConsentiSetup implements ConsentiWidgetAPI {
|
|
|
677
693
|
* cookies per compliance group (built-in or custom) without authoring a separate profile for
|
|
678
694
|
* each one. Applied before `profileOverride`, which still always wins as the final catch-all. */
|
|
679
695
|
private applyComplianceGroupOverride;
|
|
696
|
+
/**
|
|
697
|
+
* Applied in order: compliance-group override → `config.profileOverride` → each `setProfile()`
|
|
698
|
+
* patch. The `setProfile()` patches are kept as a list and replayed, not folded into one
|
|
699
|
+
* object, because folding runs `deepMerge` patch-onto-patch, which consumes `null`/`'*': null`
|
|
700
|
+
* delete markers before they ever reach the profile they were meant to delete from.
|
|
701
|
+
*/
|
|
702
|
+
private applyProfileOverrides;
|
|
703
|
+
private warnIfAcceptOnly;
|
|
680
704
|
/**
|
|
681
705
|
* Whether `window.__tcfapi`/`window.__gpp` should stay uninstalled because the corresponding
|
|
682
706
|
* server-side registration (`compliance.tcf`/`compliance.gpp`) is unconfirmed (cmpId/cmpVersion
|
package/dist/angular.d.ts
CHANGED
|
@@ -64,6 +64,10 @@ type ComplianceType = 'auto' | ComplianceGroupId | (string & {}) | Symbol;
|
|
|
64
64
|
|
|
65
65
|
interface ComplianceMapData {
|
|
66
66
|
version: string;
|
|
67
|
+
/** `true` (default): this map replaces the embedded one entirely, so only the countries listed here
|
|
68
|
+
* resolve (server side). `false`: `countries` is merged over the embedded map — a listed country
|
|
69
|
+
* replaces its embedded entry wholesale, every unlisted country keeps its built-in mapping. */
|
|
70
|
+
override?: boolean;
|
|
67
71
|
countries: Record<string, CountryComplianceEntry>;
|
|
68
72
|
}
|
|
69
73
|
interface CountryComplianceEntry {
|
|
@@ -83,6 +87,9 @@ interface ConsentDbRecord {
|
|
|
83
87
|
tenantId: string;
|
|
84
88
|
visitorId: string;
|
|
85
89
|
profileId: string;
|
|
90
|
+
/** The profile's `version` when this consent was last given — with `profileId`, pins the exact
|
|
91
|
+
* on-disk snapshot (the banner text the visitor saw). Absent on records from before it was tracked. */
|
|
92
|
+
profileVersion?: number;
|
|
86
93
|
locale: string;
|
|
87
94
|
consentJson: ConsentValue;
|
|
88
95
|
gpcDetected: boolean;
|
|
@@ -281,7 +288,12 @@ interface ResolvedProfile {
|
|
|
281
288
|
/** Apply WCAG 2.1 AA accessibility enhancements to the widget. */
|
|
282
289
|
enhanceAccessibility?: boolean;
|
|
283
290
|
}
|
|
284
|
-
type WidgetCountryResolverFn = (
|
|
291
|
+
type WidgetCountryResolverFn = (hints: {
|
|
292
|
+
timezone: string;
|
|
293
|
+
language: string;
|
|
294
|
+
languages: string[];
|
|
295
|
+
locale: string;
|
|
296
|
+
}) => Promise<{
|
|
285
297
|
country: string | null;
|
|
286
298
|
region: string | null;
|
|
287
299
|
confidence: number;
|
|
@@ -340,8 +352,11 @@ interface ComplianceWidgetConfig {
|
|
|
340
352
|
* document from (the browser's own HTTP cache honors whatever `Cache-Control`/`ETag` the
|
|
341
353
|
* response sends — no custom caching here), or an inline operator-supplied `ComplianceMapData`
|
|
342
354
|
* object. Invalid data from either a URL or an object logs a warning and falls back to
|
|
343
|
-
* `'default'`. Only overrides the country→group mapping — country/region detection itself
|
|
344
|
-
*
|
|
355
|
+
* `'default'`. Only overrides the country→group mapping — country/region detection itself always
|
|
356
|
+
* uses the embedded geo data. A country the map doesn't list falls back to the embedded mapping
|
|
357
|
+
* unless the document sets `override: true` (then it gets the strictest group, `'opt-in'`).
|
|
358
|
+
* Unlike the server, an omitted `override` is NOT `true` here: widget maps have always merged
|
|
359
|
+
* over the embedded mapping, and that stays the default. */
|
|
345
360
|
complianceMap?: 'default' | string | ComplianceMapData;
|
|
346
361
|
tcf?: TcfWidgetConfig;
|
|
347
362
|
gpp?: GppWidgetConfig;
|
|
@@ -622,6 +637,7 @@ declare class ConsentiSetup implements ConsentiWidgetAPI {
|
|
|
622
637
|
private initializing;
|
|
623
638
|
private profile;
|
|
624
639
|
private resolvedBase;
|
|
640
|
+
private profilePatches;
|
|
625
641
|
/** cookieId → Category lookup, rebuilt whenever `profile` changes. Avoids rescanning categories on every consent action. */
|
|
626
642
|
private categoryIndex;
|
|
627
643
|
/** Watchers created by the declarative `data-consenti-*` DOM scan — destroyed alongside the widget since they have no other owner. */
|
|
@@ -677,6 +693,14 @@ declare class ConsentiSetup implements ConsentiWidgetAPI {
|
|
|
677
693
|
* cookies per compliance group (built-in or custom) without authoring a separate profile for
|
|
678
694
|
* each one. Applied before `profileOverride`, which still always wins as the final catch-all. */
|
|
679
695
|
private applyComplianceGroupOverride;
|
|
696
|
+
/**
|
|
697
|
+
* Applied in order: compliance-group override → `config.profileOverride` → each `setProfile()`
|
|
698
|
+
* patch. The `setProfile()` patches are kept as a list and replayed, not folded into one
|
|
699
|
+
* object, because folding runs `deepMerge` patch-onto-patch, which consumes `null`/`'*': null`
|
|
700
|
+
* delete markers before they ever reach the profile they were meant to delete from.
|
|
701
|
+
*/
|
|
702
|
+
private applyProfileOverrides;
|
|
703
|
+
private warnIfAcceptOnly;
|
|
680
704
|
/**
|
|
681
705
|
* Whether `window.__tcfapi`/`window.__gpp` should stay uninstalled because the corresponding
|
|
682
706
|
* server-side registration (`compliance.tcf`/`compliance.gpp`) is unconfirmed (cmpId/cmpVersion
|
package/dist/index.d.ts
CHANGED
|
@@ -64,6 +64,10 @@ type ComplianceType = 'auto' | ComplianceGroupId | (string & {}) | Symbol;
|
|
|
64
64
|
|
|
65
65
|
interface ComplianceMapData {
|
|
66
66
|
version: string;
|
|
67
|
+
/** `true` (default): this map replaces the embedded one entirely, so only the countries listed here
|
|
68
|
+
* resolve (server side). `false`: `countries` is merged over the embedded map — a listed country
|
|
69
|
+
* replaces its embedded entry wholesale, every unlisted country keeps its built-in mapping. */
|
|
70
|
+
override?: boolean;
|
|
67
71
|
countries: Record<string, CountryComplianceEntry>;
|
|
68
72
|
}
|
|
69
73
|
interface CountryComplianceEntry {
|
|
@@ -83,6 +87,9 @@ interface ConsentDbRecord {
|
|
|
83
87
|
tenantId: string;
|
|
84
88
|
visitorId: string;
|
|
85
89
|
profileId: string;
|
|
90
|
+
/** The profile's `version` when this consent was last given — with `profileId`, pins the exact
|
|
91
|
+
* on-disk snapshot (the banner text the visitor saw). Absent on records from before it was tracked. */
|
|
92
|
+
profileVersion?: number;
|
|
86
93
|
locale: string;
|
|
87
94
|
consentJson: ConsentValue;
|
|
88
95
|
gpcDetected: boolean;
|
|
@@ -401,7 +408,12 @@ interface ResolvedProfile {
|
|
|
401
408
|
/** Apply WCAG 2.1 AA accessibility enhancements to the widget. */
|
|
402
409
|
enhanceAccessibility?: boolean;
|
|
403
410
|
}
|
|
404
|
-
type WidgetCountryResolverFn = (
|
|
411
|
+
type WidgetCountryResolverFn = (hints: {
|
|
412
|
+
timezone: string;
|
|
413
|
+
language: string;
|
|
414
|
+
languages: string[];
|
|
415
|
+
locale: string;
|
|
416
|
+
}) => Promise<{
|
|
405
417
|
country: string | null;
|
|
406
418
|
region: string | null;
|
|
407
419
|
confidence: number;
|
|
@@ -460,8 +472,11 @@ interface ComplianceWidgetConfig {
|
|
|
460
472
|
* document from (the browser's own HTTP cache honors whatever `Cache-Control`/`ETag` the
|
|
461
473
|
* response sends — no custom caching here), or an inline operator-supplied `ComplianceMapData`
|
|
462
474
|
* object. Invalid data from either a URL or an object logs a warning and falls back to
|
|
463
|
-
* `'default'`. Only overrides the country→group mapping — country/region detection itself
|
|
464
|
-
*
|
|
475
|
+
* `'default'`. Only overrides the country→group mapping — country/region detection itself always
|
|
476
|
+
* uses the embedded geo data. A country the map doesn't list falls back to the embedded mapping
|
|
477
|
+
* unless the document sets `override: true` (then it gets the strictest group, `'opt-in'`).
|
|
478
|
+
* Unlike the server, an omitted `override` is NOT `true` here: widget maps have always merged
|
|
479
|
+
* over the embedded mapping, and that stays the default. */
|
|
465
480
|
complianceMap?: 'default' | string | ComplianceMapData;
|
|
466
481
|
tcf?: TcfWidgetConfig;
|
|
467
482
|
gpp?: GppWidgetConfig;
|
|
@@ -789,6 +804,7 @@ declare class ConsentiSetup implements ConsentiWidgetAPI {
|
|
|
789
804
|
private initializing;
|
|
790
805
|
private profile;
|
|
791
806
|
private resolvedBase;
|
|
807
|
+
private profilePatches;
|
|
792
808
|
/** cookieId → Category lookup, rebuilt whenever `profile` changes. Avoids rescanning categories on every consent action. */
|
|
793
809
|
private categoryIndex;
|
|
794
810
|
/** Watchers created by the declarative `data-consenti-*` DOM scan — destroyed alongside the widget since they have no other owner. */
|
|
@@ -844,6 +860,14 @@ declare class ConsentiSetup implements ConsentiWidgetAPI {
|
|
|
844
860
|
* cookies per compliance group (built-in or custom) without authoring a separate profile for
|
|
845
861
|
* each one. Applied before `profileOverride`, which still always wins as the final catch-all. */
|
|
846
862
|
private applyComplianceGroupOverride;
|
|
863
|
+
/**
|
|
864
|
+
* Applied in order: compliance-group override → `config.profileOverride` → each `setProfile()`
|
|
865
|
+
* patch. The `setProfile()` patches are kept as a list and replayed, not folded into one
|
|
866
|
+
* object, because folding runs `deepMerge` patch-onto-patch, which consumes `null`/`'*': null`
|
|
867
|
+
* delete markers before they ever reach the profile they were meant to delete from.
|
|
868
|
+
*/
|
|
869
|
+
private applyProfileOverrides;
|
|
870
|
+
private warnIfAcceptOnly;
|
|
847
871
|
/**
|
|
848
872
|
* Whether `window.__tcfapi`/`window.__gpp` should stay uninstalled because the corresponding
|
|
849
873
|
* server-side registration (`compliance.tcf`/`compliance.gpp`) is unconfirmed (cmpId/cmpVersion
|