@owlmeans/consent 0.1.18-rc.2
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/build/.gitkeep +0 -0
- package/build/consts.d.ts +40 -0
- package/build/consts.d.ts.map +1 -0
- package/build/consts.js +65 -0
- package/build/consts.js.map +1 -0
- package/build/gtm.d.ts +39 -0
- package/build/gtm.d.ts.map +1 -0
- package/build/gtm.js +114 -0
- package/build/gtm.js.map +1 -0
- package/build/i18n/be.json +25 -0
- package/build/i18n/de.json +25 -0
- package/build/i18n/en.json +25 -0
- package/build/i18n/es.json +25 -0
- package/build/i18n/pl.json +25 -0
- package/build/i18n/ru.json +25 -0
- package/build/i18n/uk.json +25 -0
- package/build/i18n.d.ts +16 -0
- package/build/i18n.d.ts.map +1 -0
- package/build/i18n.js +28 -0
- package/build/i18n.js.map +1 -0
- package/build/index.d.ts +7 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +6 -0
- package/build/index.js.map +1 -0
- package/build/storage.d.ts +27 -0
- package/build/storage.d.ts.map +1 -0
- package/build/storage.js +86 -0
- package/build/storage.js.map +1 -0
- package/build/store.d.ts +16 -0
- package/build/store.d.ts.map +1 -0
- package/build/store.js +70 -0
- package/build/store.js.map +1 -0
- package/build/types.d.ts +77 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/package.json +33 -0
- package/src/consts.ts +75 -0
- package/src/gtm.ts +141 -0
- package/src/i18n/be.json +25 -0
- package/src/i18n/de.json +25 -0
- package/src/i18n/en.json +25 -0
- package/src/i18n/es.json +25 -0
- package/src/i18n/pl.json +25 -0
- package/src/i18n/ru.json +25 -0
- package/src/i18n/uk.json +25 -0
- package/src/i18n.ts +38 -0
- package/src/index.ts +6 -0
- package/src/storage.ts +96 -0
- package/src/store.ts +94 -0
- package/src/types.ts +83 -0
- package/tests/consent.spec.ts +208 -0
- package/tsconfig.json +11 -0
package/build/.gitkeep
ADDED
|
File without changes
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ConsentCategory } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Where a visitor's choice is stored.
|
|
4
|
+
*
|
|
5
|
+
* Unchanged from the widget this package generalises, and it must stay unchanged: owlmeans.com has
|
|
6
|
+
* visitors who have already chosen, and a new key would ask every one of them again.
|
|
7
|
+
*/
|
|
8
|
+
export declare const CONSENT_KEY = "site_cookie_consent";
|
|
9
|
+
export declare const CONSENT_COOKIE_DAYS = 365;
|
|
10
|
+
/**
|
|
11
|
+
* The stored record's shape version.
|
|
12
|
+
*
|
|
13
|
+
* A record with no version predates the explicit `essential` category, when essential storage was
|
|
14
|
+
* implicitly always on. Those records are migrated in place rather than discarded — the visitor
|
|
15
|
+
* made a decision, and re-asking would be a regression they experience as the site forgetting.
|
|
16
|
+
*/
|
|
17
|
+
export declare const CONSENT_SCHEMA_VERSION = 2;
|
|
18
|
+
/** Idempotence flag for the Consent Mode defaults. Fixed: a page may carry two bundles. */
|
|
19
|
+
export declare const CONSENT_SETUP_FLAG = "cookieConsentSetup";
|
|
20
|
+
export declare const CONSENT_ESSENTIAL = "essential";
|
|
21
|
+
export declare const CONSENT_ANALYTICS = "analytics";
|
|
22
|
+
export declare const CONSENT_MARKETING = "marketing";
|
|
23
|
+
export declare const CONSENT_LOCALES: readonly ['en', 'pl', 'ru', 'be', 'uk', 'es', 'de'];
|
|
24
|
+
export type ConsentLocale = (typeof CONSENT_LOCALES)[number];
|
|
25
|
+
/**
|
|
26
|
+
* The categories every OwlMeans surface starts with.
|
|
27
|
+
*
|
|
28
|
+
* Three, matching what owlmeans.com already asks — plus the essential row, which the original
|
|
29
|
+
* widget left implicit. Making it explicit is what lets a flow require an acknowledgement before
|
|
30
|
+
* it sets a session cookie, and what tells a visitor what is being stored regardless.
|
|
31
|
+
*/
|
|
32
|
+
export declare const DEFAULT_CONSENT_CATEGORIES: ConsentCategory[];
|
|
33
|
+
/**
|
|
34
|
+
* Every signal Consent Mode v2 knows, and what it defaults to before anyone has chosen.
|
|
35
|
+
*
|
|
36
|
+
* `security_storage` is granted by Google's own documented recommendation — it covers things like
|
|
37
|
+
* fraud prevention, which are strictly necessary. Everything else starts denied.
|
|
38
|
+
*/
|
|
39
|
+
export declare const CONSENT_SIGNAL_DEFAULTS: Record<string, 'granted' | 'denied'>;
|
|
40
|
+
//# sourceMappingURL=consts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD;;;;;GAKG;AACH,eAAO,MAAM,WAAW,wBAAwB,CAAA;AAEhD,eAAO,MAAM,mBAAmB,MAAM,CAAA;AAEtC;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,IAAI,CAAA;AAEvC,2FAA2F;AAC3F,eAAO,MAAM,kBAAkB,uBAAuB,CAAA;AAEtD,eAAO,MAAM,iBAAiB,cAAc,CAAA;AAC5C,eAAO,MAAM,iBAAiB,cAAc,CAAA;AAC5C,eAAO,MAAM,iBAAiB,cAAc,CAAA;AAE5C,eAAO,MAAM,eAAe,YAAI,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAU,CAAA;AAElF,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAA;AAE5D;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,EAAE,eAAe,EAmBvD,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAQxE,CAAA"}
|
package/build/consts.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a visitor's choice is stored.
|
|
3
|
+
*
|
|
4
|
+
* Unchanged from the widget this package generalises, and it must stay unchanged: owlmeans.com has
|
|
5
|
+
* visitors who have already chosen, and a new key would ask every one of them again.
|
|
6
|
+
*/
|
|
7
|
+
export const CONSENT_KEY = 'site_cookie_consent';
|
|
8
|
+
export const CONSENT_COOKIE_DAYS = 365;
|
|
9
|
+
/**
|
|
10
|
+
* The stored record's shape version.
|
|
11
|
+
*
|
|
12
|
+
* A record with no version predates the explicit `essential` category, when essential storage was
|
|
13
|
+
* implicitly always on. Those records are migrated in place rather than discarded — the visitor
|
|
14
|
+
* made a decision, and re-asking would be a regression they experience as the site forgetting.
|
|
15
|
+
*/
|
|
16
|
+
export const CONSENT_SCHEMA_VERSION = 2;
|
|
17
|
+
/** Idempotence flag for the Consent Mode defaults. Fixed: a page may carry two bundles. */
|
|
18
|
+
export const CONSENT_SETUP_FLAG = 'cookieConsentSetup';
|
|
19
|
+
export const CONSENT_ESSENTIAL = 'essential';
|
|
20
|
+
export const CONSENT_ANALYTICS = 'analytics';
|
|
21
|
+
export const CONSENT_MARKETING = 'marketing';
|
|
22
|
+
export const CONSENT_LOCALES = ['en', 'pl', 'ru', 'be', 'uk', 'es', 'de'];
|
|
23
|
+
/**
|
|
24
|
+
* The categories every OwlMeans surface starts with.
|
|
25
|
+
*
|
|
26
|
+
* Three, matching what owlmeans.com already asks — plus the essential row, which the original
|
|
27
|
+
* widget left implicit. Making it explicit is what lets a flow require an acknowledgement before
|
|
28
|
+
* it sets a session cookie, and what tells a visitor what is being stored regardless.
|
|
29
|
+
*/
|
|
30
|
+
export const DEFAULT_CONSENT_CATEGORIES = [
|
|
31
|
+
{
|
|
32
|
+
key: CONSENT_ESSENTIAL, required: true,
|
|
33
|
+
labelKey: 'essential', descriptionKey: 'essentialDesc',
|
|
34
|
+
globalVar: 'owlConsentEssential',
|
|
35
|
+
signals: ['security_storage', 'functionality_storage'],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
key: CONSENT_ANALYTICS,
|
|
39
|
+
labelKey: 'analytics', descriptionKey: 'analyticsDesc',
|
|
40
|
+
globalVar: 'owlConsentAnalytics',
|
|
41
|
+
signals: ['analytics_storage'],
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
key: CONSENT_MARKETING,
|
|
45
|
+
labelKey: 'marketing', descriptionKey: 'marketingDesc',
|
|
46
|
+
globalVar: 'owlConsentMarketing',
|
|
47
|
+
signals: ['ad_storage', 'ad_user_data', 'ad_personalization'],
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
/**
|
|
51
|
+
* Every signal Consent Mode v2 knows, and what it defaults to before anyone has chosen.
|
|
52
|
+
*
|
|
53
|
+
* `security_storage` is granted by Google's own documented recommendation — it covers things like
|
|
54
|
+
* fraud prevention, which are strictly necessary. Everything else starts denied.
|
|
55
|
+
*/
|
|
56
|
+
export const CONSENT_SIGNAL_DEFAULTS = {
|
|
57
|
+
ad_storage: 'denied',
|
|
58
|
+
ad_user_data: 'denied',
|
|
59
|
+
ad_personalization: 'denied',
|
|
60
|
+
analytics_storage: 'denied',
|
|
61
|
+
functionality_storage: 'denied',
|
|
62
|
+
personalization_storage: 'denied',
|
|
63
|
+
security_storage: 'granted',
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=consts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,qBAAqB,CAAA;AAEhD,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAA;AAEtC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAA;AAEvC,2FAA2F;AAC3F,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAA;AAEtD,MAAM,CAAC,MAAM,iBAAiB,GAAG,WAAW,CAAA;AAC5C,MAAM,CAAC,MAAM,iBAAiB,GAAG,WAAW,CAAA;AAC5C,MAAM,CAAC,MAAM,iBAAiB,GAAG,WAAW,CAAA;AAE5C,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAU,CAAA;AAIlF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAsB;IAC3D;QACE,GAAG,EAAE,iBAAiB,EAAE,QAAQ,EAAE,IAAI;QACtC,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe;QACtD,SAAS,EAAE,qBAAqB;QAChC,OAAO,EAAE,CAAC,kBAAkB,EAAE,uBAAuB,CAAC;KACvD;IACD;QACE,GAAG,EAAE,iBAAiB;QACtB,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe;QACtD,SAAS,EAAE,qBAAqB;QAChC,OAAO,EAAE,CAAC,mBAAmB,CAAC;KAC/B;IACD;QACE,GAAG,EAAE,iBAAiB;QACtB,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe;QACtD,SAAS,EAAE,qBAAqB;QAChC,OAAO,EAAE,CAAC,YAAY,EAAE,cAAc,EAAE,oBAAoB,CAAC;KAC9D;CACF,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAyC;IAC3E,UAAU,EAAE,QAAQ;IACpB,YAAY,EAAE,QAAQ;IACtB,kBAAkB,EAAE,QAAQ;IAC5B,iBAAiB,EAAE,QAAQ;IAC3B,qBAAqB,EAAE,QAAQ;IAC/B,uBAAuB,EAAE,QAAQ;IACjC,gBAAgB,EAAE,SAAS;CAC5B,CAAA"}
|
package/build/gtm.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ConsentCategory, ConsentOptions, ConsentRecord } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Push onto the tag-manager queue in the shape Google's own snippet uses.
|
|
4
|
+
*
|
|
5
|
+
* `arguments`, not an array literal. Both work with today's Consent API, but `arguments` is what
|
|
6
|
+
* `gtag.js` itself emits, and a page that carries both this and Google's snippet should not have
|
|
7
|
+
* two shapes in one queue.
|
|
8
|
+
*/
|
|
9
|
+
export declare function gtagConsent(..._args: unknown[]): void;
|
|
10
|
+
/** Every signal the configured categories drive, at its pre-consent value. */
|
|
11
|
+
export declare const consentDefaults: (categories?: ConsentCategory[]) => Record<string, 'granted' | 'denied'>;
|
|
12
|
+
/** Every signal, at the value this record implies. */
|
|
13
|
+
export declare const consentUpdate: (record: ConsentRecord, categories?: ConsentCategory[]) => Record<string, 'granted' | 'denied'>;
|
|
14
|
+
/**
|
|
15
|
+
* Declare what is denied, before any tag can act.
|
|
16
|
+
*
|
|
17
|
+
* Idempotent through a window flag, because the page may carry this call twice — once inline in
|
|
18
|
+
* the document head, once from whatever bundle mounts the dialog — and a second `default` after a
|
|
19
|
+
* tag has loaded is worse than none: it can widen what was already narrowed.
|
|
20
|
+
*/
|
|
21
|
+
export declare const pushConsentDefaults: (opts?: ConsentOptions) => void;
|
|
22
|
+
/**
|
|
23
|
+
* Apply a decision: globals first, then the signal update, then any per-category events.
|
|
24
|
+
*
|
|
25
|
+
* The order is load-bearing. A tag that fires on the update event reads the globals in the same
|
|
26
|
+
* turn, so writing them afterwards would let the first firing see the previous answer.
|
|
27
|
+
*/
|
|
28
|
+
export declare const applyConsent: (record: ConsentRecord, opts?: ConsentOptions) => void;
|
|
29
|
+
/**
|
|
30
|
+
* The inline script a document stamps ABOVE its tag-manager snippet.
|
|
31
|
+
*
|
|
32
|
+
* It exists because the defaults have to be on the queue before `gtm.js` loads, and a React bundle
|
|
33
|
+
* cannot be: by the time an island mounts, the container has been running for hundreds of
|
|
34
|
+
* milliseconds and has already decided what it may do. Emitting it from the HTML is the only
|
|
35
|
+
* ordering that holds — and it reads the stored record too, so a returning visitor's tags are not
|
|
36
|
+
* denied for the first paint of every page.
|
|
37
|
+
*/
|
|
38
|
+
export declare const consentBootstrapScript: (opts?: ConsentOptions) => string;
|
|
39
|
+
//# sourceMappingURL=gtm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gtm.d.ts","sourceRoot":"","sources":["../src/gtm.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAUhF;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAUrD;AAKD,8EAA8E;AAC9E,eAAO,MAAM,eAAe,gBACb,eAAe,EAAE,KAC7B,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAMrC,CAAA;AAED,sDAAsD;AACtD,eAAO,MAAM,aAAa,WAChB,aAAa,eAAe,eAAe,EAAE,KACpD,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAWrC,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,UAAW,cAAc,KAAG,IAO3D,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,WAAY,aAAa,SAAS,cAAc,KAAG,IAqB3E,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,UAAW,cAAc,KAAG,MAwB9D,CAAA"}
|
package/build/gtm.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { CONSENT_KEY, CONSENT_SETUP_FLAG, CONSENT_SIGNAL_DEFAULTS, DEFAULT_CONSENT_CATEGORIES, } from './consts.js';
|
|
2
|
+
const global = () => typeof window !== 'undefined' ? window : null;
|
|
3
|
+
/**
|
|
4
|
+
* Push onto the tag-manager queue in the shape Google's own snippet uses.
|
|
5
|
+
*
|
|
6
|
+
* `arguments`, not an array literal. Both work with today's Consent API, but `arguments` is what
|
|
7
|
+
* `gtag.js` itself emits, and a page that carries both this and Google's snippet should not have
|
|
8
|
+
* two shapes in one queue.
|
|
9
|
+
*/
|
|
10
|
+
export function gtagConsent(..._args) {
|
|
11
|
+
const win = global();
|
|
12
|
+
if (win == null) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
win.dataLayer = win.dataLayer ?? [];
|
|
16
|
+
// `arguments`, not `_args`. The rest parameter is only here to type the call sites; what goes on
|
|
17
|
+
// the queue must be the arguments object itself.
|
|
18
|
+
// eslint-disable-next-line prefer-rest-params
|
|
19
|
+
win.dataLayer.push(arguments);
|
|
20
|
+
}
|
|
21
|
+
const categoriesOf = (opts) => opts?.categories ?? DEFAULT_CONSENT_CATEGORIES;
|
|
22
|
+
/** Every signal the configured categories drive, at its pre-consent value. */
|
|
23
|
+
export const consentDefaults = (categories) => {
|
|
24
|
+
const used = new Set((categories ?? DEFAULT_CONSENT_CATEGORIES)
|
|
25
|
+
.flatMap(category => category.signals ?? []));
|
|
26
|
+
return Object.fromEntries(Object.entries(CONSENT_SIGNAL_DEFAULTS)
|
|
27
|
+
.filter(([signal]) => used.has(signal)));
|
|
28
|
+
};
|
|
29
|
+
/** Every signal, at the value this record implies. */
|
|
30
|
+
export const consentUpdate = (record, categories) => {
|
|
31
|
+
const update = {};
|
|
32
|
+
for (const category of categories ?? DEFAULT_CONSENT_CATEGORIES) {
|
|
33
|
+
const granted = category.required === true || record[category.key] === true;
|
|
34
|
+
for (const signal of category.signals ?? []) {
|
|
35
|
+
// A signal named by two categories is granted only when every one of them is.
|
|
36
|
+
update[signal] = granted && update[signal] !== 'denied' ? 'granted' : 'denied';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return update;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Declare what is denied, before any tag can act.
|
|
43
|
+
*
|
|
44
|
+
* Idempotent through a window flag, because the page may carry this call twice — once inline in
|
|
45
|
+
* the document head, once from whatever bundle mounts the dialog — and a second `default` after a
|
|
46
|
+
* tag has loaded is worse than none: it can widen what was already narrowed.
|
|
47
|
+
*/
|
|
48
|
+
export const pushConsentDefaults = (opts) => {
|
|
49
|
+
const win = global();
|
|
50
|
+
if (win == null || opts?.silent === true || win[CONSENT_SETUP_FLAG] === true) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
gtagConsent('consent', 'default', consentDefaults(categoriesOf(opts)));
|
|
54
|
+
win[CONSENT_SETUP_FLAG] = true;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Apply a decision: globals first, then the signal update, then any per-category events.
|
|
58
|
+
*
|
|
59
|
+
* The order is load-bearing. A tag that fires on the update event reads the globals in the same
|
|
60
|
+
* turn, so writing them afterwards would let the first firing see the previous answer.
|
|
61
|
+
*/
|
|
62
|
+
export const applyConsent = (record, opts) => {
|
|
63
|
+
const win = global();
|
|
64
|
+
if (win == null || opts?.silent === true) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const categories = categoriesOf(opts);
|
|
68
|
+
for (const category of categories) {
|
|
69
|
+
if (category.globalVar != null) {
|
|
70
|
+
win[category.globalVar] = category.required === true || record[category.key] === true;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
gtagConsent('consent', 'update', consentUpdate(record, categories));
|
|
74
|
+
for (const category of categories) {
|
|
75
|
+
if (category.event != null && (category.required === true || record[category.key] === true)) {
|
|
76
|
+
win.dataLayer = win.dataLayer ?? [];
|
|
77
|
+
win.dataLayer.push({ event: category.event });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* The inline script a document stamps ABOVE its tag-manager snippet.
|
|
83
|
+
*
|
|
84
|
+
* It exists because the defaults have to be on the queue before `gtm.js` loads, and a React bundle
|
|
85
|
+
* cannot be: by the time an island mounts, the container has been running for hundreds of
|
|
86
|
+
* milliseconds and has already decided what it may do. Emitting it from the HTML is the only
|
|
87
|
+
* ordering that holds — and it reads the stored record too, so a returning visitor's tags are not
|
|
88
|
+
* denied for the first paint of every page.
|
|
89
|
+
*/
|
|
90
|
+
export const consentBootstrapScript = (opts) => {
|
|
91
|
+
const defaults = JSON.stringify(consentDefaults(categoriesOf(opts)));
|
|
92
|
+
const categories = JSON.stringify(categoriesOf(opts).map(category => ({
|
|
93
|
+
key: category.key,
|
|
94
|
+
required: category.required === true,
|
|
95
|
+
signals: category.signals ?? [],
|
|
96
|
+
globalVar: category.globalVar ?? null,
|
|
97
|
+
})));
|
|
98
|
+
const storageKey = JSON.stringify(opts?.storageKey ?? CONSENT_KEY);
|
|
99
|
+
const flag = JSON.stringify(CONSENT_SETUP_FLAG);
|
|
100
|
+
return `(function(w,d){` +
|
|
101
|
+
`w.dataLayer=w.dataLayer||[];function g(){w.dataLayer.push(arguments)}` +
|
|
102
|
+
`if(w[${flag}])return;g('consent','default',${defaults});w[${flag}]=true;` +
|
|
103
|
+
`var raw=null;try{raw=w.localStorage.getItem(${storageKey})}catch(e){}` +
|
|
104
|
+
`if(!raw){var p=('; '+d.cookie).split('; '+${storageKey}+'=');` +
|
|
105
|
+
`if(p.length===2){raw=p.pop().split(';').shift()}}` +
|
|
106
|
+
`if(!raw)return;var r;try{r=JSON.parse(raw)}catch(e){return}` +
|
|
107
|
+
`var cs=${categories},u={};` +
|
|
108
|
+
`for(var i=0;i<cs.length;i++){var c=cs[i];var ok=c.required||r[c.key]===true;` +
|
|
109
|
+
`if(c.globalVar){w[c.globalVar]=ok}` +
|
|
110
|
+
`for(var j=0;j<c.signals.length;j++){var s=c.signals[j];` +
|
|
111
|
+
`u[s]=ok&&u[s]!=='denied'?'granted':'denied'}}` +
|
|
112
|
+
`g('consent','update',u)})(window,document)`;
|
|
113
|
+
};
|
|
114
|
+
//# sourceMappingURL=gtm.js.map
|
package/build/gtm.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gtm.js","sourceRoot":"","sources":["../src/gtm.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Налады файлаў cookie",
|
|
3
|
+
"description": "Мы выкарыстоўваем файлы cookie, каб палепшыць ваш досвед прагляду, паказваць персаналізаваную рэкламу ці змесціва і аналізаваць наш трафік. Націскаючы «Прыняць усе», вы пагаджаецеся на выкарыстанне файлаў cookie.",
|
|
4
|
+
"essential": "Неабходныя файлы cookie",
|
|
5
|
+
"essentialDesc": "Патрэбныя для працы сайта — уваход, бяспека і захаванне гэтых налад. Іх нельга адключыць.",
|
|
6
|
+
"analytics": "Аналітычныя файлы cookie",
|
|
7
|
+
"analyticsDesc": "Дапамагаюць нам паляпшаць наш вэб-сайт, збіраючы і паведамляючы інфармацыю пра яго выкарыстанне.",
|
|
8
|
+
"marketing": "Маркетынгавыя файлы cookie",
|
|
9
|
+
"marketingDesc": "Выкарыстоўваюцца для адсочвання наведвальнікаў на розных вэб-сайтах дзеля паказу актуальнай і цікавай рэкламы.",
|
|
10
|
+
"required": "Абавязкова",
|
|
11
|
+
"acceptAll": "Прыняць усе",
|
|
12
|
+
"acceptAndContinue": "Прыняць і працягнуць",
|
|
13
|
+
"savePreferences": "Захаваць налады",
|
|
14
|
+
"policyLink": "Палітыка файлаў cookie",
|
|
15
|
+
"openPreferences": "Налады файлаў cookie",
|
|
16
|
+
"close": "Закрыць",
|
|
17
|
+
"loginReason": "Уваход захоўвае сеансавы файл cookie. Прыміце неабходныя файлы cookie, каб працягнуць.",
|
|
18
|
+
"manage": "Змяніць налады",
|
|
19
|
+
"policyTitle": "Палітыка файлаў cookie",
|
|
20
|
+
"policyIntro": "Гэтая старонка апісвае файлы cookie і падобныя сховішчы, якія выкарыстоўвае гэтая праграма, і як імі кіраваць.",
|
|
21
|
+
"policyStorage": "Ваш выбар захоўваецца ў гэтым браўзеры пад ключом «{{key}}» — і ў лакальным сховішчы, і ў файле cookie.",
|
|
22
|
+
"policyRetention": "Запіс захоўваецца {{days}} дзён, пасля чаго мы спытаем зноў.",
|
|
23
|
+
"policyOperator": "Гэтая праграма належыць {{operator}}.",
|
|
24
|
+
"policyContact": "Азнаёмцеся з іх палітыкай прыватнасці і ўмовамі карыстання, каб даведацца, як яны апрацоўваюць вашы даныя."
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Cookie-Einstellungen",
|
|
3
|
+
"description": "Wir verwenden Cookies, um Ihr Surferlebnis zu verbessern, personalisierte Anzeigen oder Inhalte bereitzustellen und unseren Datenverkehr zu analysieren. Indem Sie auf „Alle akzeptieren\" klicken, stimmen Sie der Verwendung von Cookies zu.",
|
|
4
|
+
"essential": "Notwendige Cookies",
|
|
5
|
+
"essentialDesc": "Erforderlich, damit die Website funktioniert — Anmeldung, Sicherheit und das Speichern dieser Einstellungen. Sie lassen sich nicht abschalten.",
|
|
6
|
+
"analytics": "Analyse-Cookies",
|
|
7
|
+
"analyticsDesc": "Helfen uns, unsere Website zu verbessern, indem sie Informationen zur Nutzung sammeln und melden.",
|
|
8
|
+
"marketing": "Marketing-Cookies",
|
|
9
|
+
"marketingDesc": "Werden verwendet, um Besucher über Websites hinweg zu verfolgen und relevante, ansprechende Werbung anzuzeigen.",
|
|
10
|
+
"required": "Erforderlich",
|
|
11
|
+
"acceptAll": "Alle akzeptieren",
|
|
12
|
+
"acceptAndContinue": "Akzeptieren und fortfahren",
|
|
13
|
+
"savePreferences": "Einstellungen speichern",
|
|
14
|
+
"policyLink": "Cookie-Richtlinie",
|
|
15
|
+
"openPreferences": "Cookie-Einstellungen",
|
|
16
|
+
"close": "Schließen",
|
|
17
|
+
"loginReason": "Bei der Anmeldung wird ein Sitzungs-Cookie gespeichert. Akzeptieren Sie die notwendigen Cookies, um fortzufahren.",
|
|
18
|
+
"manage": "Einstellungen verwalten",
|
|
19
|
+
"policyTitle": "Cookie-Richtlinie",
|
|
20
|
+
"policyIntro": "Diese Seite beschreibt die Cookies und ähnliche Speicher, die diese Anwendung verwendet, und wie Sie sie steuern können.",
|
|
21
|
+
"policyStorage": "Ihre Auswahl wird in diesem Browser unter „{{key}}\" gespeichert — sowohl im lokalen Speicher als auch als Cookie.",
|
|
22
|
+
"policyRetention": "Der Eintrag wird {{days}} Tage aufbewahrt, danach werden Sie erneut gefragt.",
|
|
23
|
+
"policyOperator": "Diese Anwendung wird von {{operator}} betrieben.",
|
|
24
|
+
"policyContact": "Sehen Sie in deren Datenschutzerklärung und Bedingungen nach, wie Ihre Daten verarbeitet werden."
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Cookie Preferences",
|
|
3
|
+
"description": "We use cookies to enhance your browsing experience, serve personalized ads or content, and analyze our traffic. By clicking \"Accept All\", you consent to our use of cookies.",
|
|
4
|
+
"essential": "Essential Cookies",
|
|
5
|
+
"essentialDesc": "Required for the site to work — signing in, security and remembering these preferences. They cannot be switched off.",
|
|
6
|
+
"analytics": "Analytics Cookies",
|
|
7
|
+
"analyticsDesc": "Help us improve our website by collecting and reporting information on its usage.",
|
|
8
|
+
"marketing": "Marketing Cookies",
|
|
9
|
+
"marketingDesc": "Used to track visitors across websites to display relevant and engaging advertisements.",
|
|
10
|
+
"required": "Required",
|
|
11
|
+
"acceptAll": "Accept All",
|
|
12
|
+
"acceptAndContinue": "Accept & continue",
|
|
13
|
+
"savePreferences": "Save Preferences",
|
|
14
|
+
"policyLink": "Cookie Policy",
|
|
15
|
+
"openPreferences": "Cookie preferences",
|
|
16
|
+
"close": "Close",
|
|
17
|
+
"loginReason": "Signing in stores a session cookie. Accept essential cookies to continue.",
|
|
18
|
+
"manage": "Manage preferences",
|
|
19
|
+
"policyTitle": "Cookie Policy",
|
|
20
|
+
"policyIntro": "This page describes the cookies and similar storage this application uses, and how you can control them.",
|
|
21
|
+
"policyStorage": "Your choice is stored in this browser under \"{{key}}\", both in local storage and as a cookie.",
|
|
22
|
+
"policyRetention": "The record is kept for {{days}} days, after which you will be asked again.",
|
|
23
|
+
"policyOperator": "This application is operated by {{operator}}.",
|
|
24
|
+
"policyContact": "See their privacy policy and terms for how they handle your data."
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Preferencias de cookies",
|
|
3
|
+
"description": "Utilizamos cookies para mejorar tu experiencia de navegación, ofrecer anuncios o contenido personalizados y analizar nuestro tráfico. Al hacer clic en «Aceptar todo», aceptas nuestro uso de cookies.",
|
|
4
|
+
"essential": "Cookies esenciales",
|
|
5
|
+
"essentialDesc": "Necesarias para que el sitio funcione: inicio de sesión, seguridad y recordar estas preferencias. No se pueden desactivar.",
|
|
6
|
+
"analytics": "Cookies analíticas",
|
|
7
|
+
"analyticsDesc": "Nos ayudan a mejorar nuestro sitio web recopilando e informando sobre su uso.",
|
|
8
|
+
"marketing": "Cookies de marketing",
|
|
9
|
+
"marketingDesc": "Se utilizan para rastrear a los visitantes en distintos sitios web y mostrar anuncios relevantes y atractivos.",
|
|
10
|
+
"required": "Obligatorias",
|
|
11
|
+
"acceptAll": "Aceptar todo",
|
|
12
|
+
"acceptAndContinue": "Aceptar y continuar",
|
|
13
|
+
"savePreferences": "Guardar preferencias",
|
|
14
|
+
"policyLink": "Política de cookies",
|
|
15
|
+
"openPreferences": "Preferencias de cookies",
|
|
16
|
+
"close": "Cerrar",
|
|
17
|
+
"loginReason": "Iniciar sesión guarda una cookie de sesión. Acepta las cookies esenciales para continuar.",
|
|
18
|
+
"manage": "Gestionar preferencias",
|
|
19
|
+
"policyTitle": "Política de cookies",
|
|
20
|
+
"policyIntro": "Esta página describe las cookies y el almacenamiento similar que utiliza esta aplicación, y cómo puedes controlarlos.",
|
|
21
|
+
"policyStorage": "Tu elección se guarda en este navegador bajo «{{key}}», tanto en el almacenamiento local como en una cookie.",
|
|
22
|
+
"policyRetention": "El registro se conserva {{days}} días, tras los cuales se te preguntará de nuevo.",
|
|
23
|
+
"policyOperator": "Esta aplicación está gestionada por {{operator}}.",
|
|
24
|
+
"policyContact": "Consulta su política de privacidad y sus términos para saber cómo tratan tus datos."
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Preferencje dotyczące plików cookie",
|
|
3
|
+
"description": "Używamy plików cookie w celu ulepszenia Twojego doświadczenia podczas przeglądania, wyświetlania spersonalizowanych reklam lub treści oraz analizowania naszego ruchu. Klikając „Akceptuj wszystkie\", wyrażasz zgodę na używanie przez nas plików cookie.",
|
|
4
|
+
"essential": "Niezbędne pliki cookie",
|
|
5
|
+
"essentialDesc": "Wymagane do działania witryny — logowanie, bezpieczeństwo i zapamiętanie tych ustawień. Nie można ich wyłączyć.",
|
|
6
|
+
"analytics": "Analityczne pliki cookie",
|
|
7
|
+
"analyticsDesc": "Pomagają nam ulepszać naszą witrynę internetową, zbierając i raportując informacje o jej użytkowaniu.",
|
|
8
|
+
"marketing": "Marketingowe pliki cookie",
|
|
9
|
+
"marketingDesc": "Służą do śledzenia odwiedzających na różnych stronach internetowych w celu wyświetlania trafnych reklam, dostosowanych do konkretnego użytkownika.",
|
|
10
|
+
"required": "Wymagane",
|
|
11
|
+
"acceptAll": "Akceptuj wszystkie",
|
|
12
|
+
"acceptAndContinue": "Akceptuj i kontynuuj",
|
|
13
|
+
"savePreferences": "Zapisz preferencje",
|
|
14
|
+
"policyLink": "Polityka plików cookie",
|
|
15
|
+
"openPreferences": "Preferencje plików cookie",
|
|
16
|
+
"close": "Zamknij",
|
|
17
|
+
"loginReason": "Logowanie zapisuje plik cookie sesji. Zaakceptuj niezbędne pliki cookie, aby kontynuować.",
|
|
18
|
+
"manage": "Zarządzaj preferencjami",
|
|
19
|
+
"policyTitle": "Polityka plików cookie",
|
|
20
|
+
"policyIntro": "Ta strona opisuje pliki cookie i podobne mechanizmy przechowywania używane przez tę aplikację oraz sposób ich kontrolowania.",
|
|
21
|
+
"policyStorage": "Twój wybór jest zapisywany w tej przeglądarce pod kluczem „{{key}}\" — zarówno w pamięci lokalnej, jak i w pliku cookie.",
|
|
22
|
+
"policyRetention": "Zapis jest przechowywany przez {{days}} dni, po czym zapytamy ponownie.",
|
|
23
|
+
"policyOperator": "Tę aplikację prowadzi {{operator}}.",
|
|
24
|
+
"policyContact": "Zapoznaj się z ich polityką prywatności i regulaminem, aby dowiedzieć się, jak przetwarzają Twoje dane."
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Настройки файлов cookie",
|
|
3
|
+
"description": "Мы используем файлы cookie, чтобы улучшить ваш опыт просмотра, показывать персонализированную рекламу или контент и анализировать наш трафик. Нажимая «Принять все», вы соглашаетесь на использование файлов cookie.",
|
|
4
|
+
"essential": "Необходимые файлы cookie",
|
|
5
|
+
"essentialDesc": "Нужны для работы сайта — вход, безопасность и сохранение этих настроек. Их нельзя отключить.",
|
|
6
|
+
"analytics": "Аналитические файлы cookie",
|
|
7
|
+
"analyticsDesc": "Помогают нам улучшать наш сайт, собирая и предоставляя информацию о его использовании.",
|
|
8
|
+
"marketing": "Маркетинговые файлы cookie",
|
|
9
|
+
"marketingDesc": "Используются для отслеживания посетителей на разных сайтах для показа релевантной и интересной рекламы.",
|
|
10
|
+
"required": "Обязательно",
|
|
11
|
+
"acceptAll": "Принять все",
|
|
12
|
+
"acceptAndContinue": "Принять и продолжить",
|
|
13
|
+
"savePreferences": "Сохранить настройки",
|
|
14
|
+
"policyLink": "Политика использования файлов cookie",
|
|
15
|
+
"openPreferences": "Настройки файлов cookie",
|
|
16
|
+
"close": "Закрыть",
|
|
17
|
+
"loginReason": "Вход сохраняет сессионный файл cookie. Примите необходимые файлы cookie, чтобы продолжить.",
|
|
18
|
+
"manage": "Изменить настройки",
|
|
19
|
+
"policyTitle": "Политика использования файлов cookie",
|
|
20
|
+
"policyIntro": "На этой странице описаны файлы cookie и подобные хранилища, которые использует это приложение, и как ими управлять.",
|
|
21
|
+
"policyStorage": "Ваш выбор сохраняется в этом браузере под ключом «{{key}}» — и в локальном хранилище, и в файле cookie.",
|
|
22
|
+
"policyRetention": "Запись хранится {{days}} дней, после чего мы спросим снова.",
|
|
23
|
+
"policyOperator": "Это приложение принадлежит {{operator}}.",
|
|
24
|
+
"policyContact": "Ознакомьтесь с их политикой конфиденциальности и условиями использования, чтобы узнать, как они обрабатывают ваши данные."
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Налаштування файлів cookie",
|
|
3
|
+
"description": "Ми використовуємо файли cookie, щоб покращити ваш досвід перегляду, показувати персоналізовану рекламу чи вміст і аналізувати наш трафік. Натискаючи «Прийняти всі», ви погоджуєтеся на використання файлів cookie.",
|
|
4
|
+
"essential": "Необхідні файли cookie",
|
|
5
|
+
"essentialDesc": "Потрібні для роботи сайту — вхід, безпека та збереження цих налаштувань. Їх не можна вимкнути.",
|
|
6
|
+
"analytics": "Аналітичні файли cookie",
|
|
7
|
+
"analyticsDesc": "Допомагають нам покращувати наш вебсайт, збираючи та надаючи інформацію про його використання.",
|
|
8
|
+
"marketing": "Маркетингові файли cookie",
|
|
9
|
+
"marketingDesc": "Використовуються для відстеження відвідувачів на різних вебсайтах для показу релевантної та цікавої реклами.",
|
|
10
|
+
"required": "Обов'язково",
|
|
11
|
+
"acceptAll": "Прийняти всі",
|
|
12
|
+
"acceptAndContinue": "Прийняти й продовжити",
|
|
13
|
+
"savePreferences": "Зберегти налаштування",
|
|
14
|
+
"policyLink": "Політика щодо файлів cookie",
|
|
15
|
+
"openPreferences": "Налаштування файлів cookie",
|
|
16
|
+
"close": "Закрити",
|
|
17
|
+
"loginReason": "Вхід зберігає сеансовий файл cookie. Прийміть необхідні файли cookie, щоб продовжити.",
|
|
18
|
+
"manage": "Змінити налаштування",
|
|
19
|
+
"policyTitle": "Політика щодо файлів cookie",
|
|
20
|
+
"policyIntro": "Ця сторінка описує файли cookie та подібні сховища, які використовує цей застосунок, і як ними керувати.",
|
|
21
|
+
"policyStorage": "Ваш вибір зберігається в цьому браузері під ключем «{{key}}» — і в локальному сховищі, і у файлі cookie.",
|
|
22
|
+
"policyRetention": "Запис зберігається {{days}} днів, після чого ми запитаємо знову.",
|
|
23
|
+
"policyOperator": "Цей застосунок належить {{operator}}.",
|
|
24
|
+
"policyContact": "Ознайомтеся з їхньою політикою конфіденційності та умовами користування, щоб дізнатися, як вони обробляють ваші дані."
|
|
25
|
+
}
|
package/build/i18n.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ConsentLocale } from './consts.js';
|
|
2
|
+
/**
|
|
3
|
+
* The dialog's copy, in the box.
|
|
4
|
+
*
|
|
5
|
+
* Carried here rather than registered into an i18n framework because one of the three consumers is
|
|
6
|
+
* an Astro site with React islands and no OwlMeans i18n at all — and a consent dialog that renders
|
|
7
|
+
* raw keys is worse than no dialog. An application that HAS translations passes `translate` and
|
|
8
|
+
* overrides every one of these.
|
|
9
|
+
*/
|
|
10
|
+
export declare const DEFAULT_CONSENT_MESSAGES: Record<ConsentLocale, Record<string, string>>;
|
|
11
|
+
export declare const normalizeLocale: (locale?: string) => ConsentLocale;
|
|
12
|
+
/** `(key, defaultValue) => string`, the house shape, backed by the built-in bundle. */
|
|
13
|
+
export declare const defaultConsentTranslate: (locale?: string) => (key: string, defaultValue: string) => string;
|
|
14
|
+
/** Substitute `{{name}}` placeholders. Enough for the two the policy page needs. */
|
|
15
|
+
export declare const interpolate: (text: string, values: Record<string, string | number>) => string;
|
|
16
|
+
//# sourceMappingURL=i18n.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAUhD;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAElF,CAAA;AAED,eAAO,MAAM,eAAe,YAAa,MAAM,KAAG,aAIjD,CAAA;AAED,uFAAuF;AACvF,eAAO,MAAM,uBAAuB,YAAa,MAAM,WAC/C,MAAM,gBAAgB,MAAM,KAAG,MACqC,CAAA;AAE5E,oFAAoF;AACpF,eAAO,MAAM,WAAW,SAAU,MAAM,UAAU,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAAG,MAE5B,CAAA"}
|
package/build/i18n.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { CONSENT_LOCALES } from './consts.js';
|
|
2
|
+
import en from './i18n/en.json' with { type: 'json' };
|
|
3
|
+
import pl from './i18n/pl.json' with { type: 'json' };
|
|
4
|
+
import ru from './i18n/ru.json' with { type: 'json' };
|
|
5
|
+
import be from './i18n/be.json' with { type: 'json' };
|
|
6
|
+
import uk from './i18n/uk.json' with { type: 'json' };
|
|
7
|
+
import es from './i18n/es.json' with { type: 'json' };
|
|
8
|
+
import de from './i18n/de.json' with { type: 'json' };
|
|
9
|
+
/**
|
|
10
|
+
* The dialog's copy, in the box.
|
|
11
|
+
*
|
|
12
|
+
* Carried here rather than registered into an i18n framework because one of the three consumers is
|
|
13
|
+
* an Astro site with React islands and no OwlMeans i18n at all — and a consent dialog that renders
|
|
14
|
+
* raw keys is worse than no dialog. An application that HAS translations passes `translate` and
|
|
15
|
+
* overrides every one of these.
|
|
16
|
+
*/
|
|
17
|
+
export const DEFAULT_CONSENT_MESSAGES = {
|
|
18
|
+
en, pl, ru, be, uk, es, de,
|
|
19
|
+
};
|
|
20
|
+
export const normalizeLocale = (locale) => {
|
|
21
|
+
const base = (locale ?? 'en').toLowerCase().split('-')[0];
|
|
22
|
+
return CONSENT_LOCALES.includes(base) ? base : 'en';
|
|
23
|
+
};
|
|
24
|
+
/** `(key, defaultValue) => string`, the house shape, backed by the built-in bundle. */
|
|
25
|
+
export const defaultConsentTranslate = (locale) => (key, defaultValue) => DEFAULT_CONSENT_MESSAGES[normalizeLocale(locale)]?.[key] ?? defaultValue;
|
|
26
|
+
/** Substitute `{{name}}` placeholders. Enough for the two the policy page needs. */
|
|
27
|
+
export const interpolate = (text, values) => text.replace(/\{\{([a-z]+)\}\}/gi, (whole, name) => values[name] != null ? String(values[name]) : whole);
|
|
28
|
+
//# sourceMappingURL=i18n.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAG7C,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AAErD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAkD;IACrF,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;CAC3B,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAe,EAAiB,EAAE;IAChE,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IAEzD,OAAO,eAAe,CAAC,QAAQ,CAAC,IAAqB,CAAC,CAAC,CAAC,CAAC,IAAqB,CAAC,CAAC,CAAC,IAAI,CAAA;AACvF,CAAC,CAAA;AAED,uFAAuF;AACvF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,MAAe,EAAE,EAAE,CACzD,CAAC,GAAW,EAAE,YAAoB,EAAU,EAAE,CAC5C,wBAAwB,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,YAAY,CAAA;AAE5E,oFAAoF;AACpF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,MAAuC,EAAU,EAAE,CAC3F,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE,CACzD,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA"}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA"}
|
package/build/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ConsentOptions, ConsentRecord } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Bring a stored record up to the current shape.
|
|
4
|
+
*
|
|
5
|
+
* A record with no `v` was written before the essential category existed, when it was implicitly
|
|
6
|
+
* always granted. The visitor DID choose; upgrading in place honours that choice, where treating
|
|
7
|
+
* the record as unusable would re-prompt everyone who has ever visited.
|
|
8
|
+
*/
|
|
9
|
+
export declare const migrateConsent: (raw: ConsentRecord | null) => ConsentRecord | null;
|
|
10
|
+
/**
|
|
11
|
+
* What this browser has already chosen, or null.
|
|
12
|
+
*
|
|
13
|
+
* localStorage first and the cookie second, because that is the order the widget this generalises
|
|
14
|
+
* used and the two can disagree: a visitor who cleared site data but kept cookies still has an
|
|
15
|
+
* answer, and asking them again would be wrong.
|
|
16
|
+
*/
|
|
17
|
+
export declare const readConsent: (opts?: ConsentOptions) => ConsentRecord | null;
|
|
18
|
+
/**
|
|
19
|
+
* Record the choice in both places.
|
|
20
|
+
*
|
|
21
|
+
* Two stores rather than one because neither is reliable alone: localStorage is cleared by "clear
|
|
22
|
+
* site data" while the cookie survives it, and the cookie is refused where third-party storage is
|
|
23
|
+
* blocked while localStorage may not be.
|
|
24
|
+
*/
|
|
25
|
+
export declare const writeConsent: (record: ConsentRecord, opts?: ConsentOptions) => void;
|
|
26
|
+
export declare const clearConsent: (opts?: ConsentOptions) => void;
|
|
27
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAiB/D;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,QAAS,aAAa,GAAG,IAAI,KAAG,aAAa,GAAG,IAGH,CAAA;AAWxE;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,UAAW,cAAc,KAAG,aAAa,GAAG,IAQnE,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,WAAY,aAAa,SAAS,cAAc,KAAG,IAkB3E,CAAA;AAED,eAAO,MAAM,YAAY,UAAW,cAAc,KAAG,IAUpD,CAAA"}
|