@owlmeans/consent 0.1.18-rc.8 → 0.1.18
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 +229 -0
- package/build/consts.d.ts +84 -23
- package/build/consts.d.ts.map +1 -1
- package/build/consts.js +110 -29
- package/build/consts.js.map +1 -1
- package/build/consts.local.d.ts +12 -0
- package/build/consts.local.d.ts.map +1 -0
- package/build/consts.local.js +12 -0
- package/build/consts.local.js.map +1 -0
- package/build/geo/types.d.ts +47 -0
- package/build/geo/types.d.ts.map +1 -0
- package/build/geo/types.js +2 -0
- package/build/geo/types.js.map +1 -0
- package/build/geo.d.ts +4 -0
- package/build/geo.d.ts.map +1 -0
- package/build/geo.js +96 -0
- package/build/geo.js.map +1 -0
- package/build/gtobserver/types.d.ts +75 -0
- package/build/gtobserver/types.d.ts.map +1 -0
- package/build/gtobserver/types.js +2 -0
- package/build/gtobserver/types.js.map +1 -0
- package/build/gtobserver.d.ts +7 -0
- package/build/gtobserver.d.ts.map +1 -0
- package/build/gtobserver.js +142 -0
- package/build/gtobserver.js.map +1 -0
- package/build/i18n/be.json +9 -4
- package/build/i18n/de.json +9 -4
- package/build/i18n/en.json +9 -4
- package/build/i18n/es.json +9 -4
- package/build/i18n/fr.json +9 -4
- package/build/i18n/pl.json +9 -4
- package/build/i18n/ru.json +9 -4
- package/build/i18n/types.d.ts +11 -0
- package/build/i18n/types.d.ts.map +1 -0
- package/build/i18n/types.js +2 -0
- package/build/i18n/types.js.map +1 -0
- package/build/i18n/uk.json +9 -4
- package/build/i18n.d.ts +4 -14
- package/build/i18n.d.ts.map +1 -1
- package/build/i18n.js +12 -27
- package/build/i18n.js.map +1 -1
- package/build/index.d.ts +13 -6
- package/build/index.d.ts.map +1 -1
- package/build/index.js +5 -4
- package/build/index.js.map +1 -1
- package/build/linker/types.d.ts +59 -0
- package/build/linker/types.d.ts.map +1 -0
- package/build/linker/types.js +2 -0
- package/build/linker/types.js.map +1 -0
- package/build/linker.d.ts +5 -76
- package/build/linker.d.ts.map +1 -1
- package/build/linker.js +290 -339
- package/build/linker.js.map +1 -1
- package/build/plugins/types.d.ts +42 -0
- package/build/plugins/types.d.ts.map +1 -0
- package/build/plugins/types.js +2 -0
- package/build/plugins/types.js.map +1 -0
- package/build/plugins.d.ts +4 -69
- package/build/plugins.d.ts.map +1 -1
- package/build/plugins.js +73 -62
- package/build/plugins.js.map +1 -1
- package/build/storage/types.d.ts +31 -0
- package/build/storage/types.d.ts.map +1 -0
- package/build/storage/types.js +2 -0
- package/build/storage/types.js.map +1 -0
- package/build/storage.d.ts +6 -22
- package/build/storage.d.ts.map +1 -1
- package/build/storage.js +72 -81
- package/build/storage.js.map +1 -1
- package/build/store.d.ts +2 -2
- package/build/store.d.ts.map +1 -1
- package/build/store.js +116 -67
- package/build/store.js.map +1 -1
- package/build/types.d.ts +147 -26
- package/build/types.d.ts.map +1 -1
- package/build/types.local.d.ts +9 -0
- package/build/types.local.d.ts.map +1 -0
- package/build/types.local.js +2 -0
- package/build/types.local.js.map +1 -0
- package/package.json +3 -3
- package/src/consts.local.ts +16 -0
- package/src/consts.ts +126 -34
- package/src/geo/types.ts +49 -0
- package/src/geo.ts +122 -0
- package/src/gtobserver/types.ts +73 -0
- package/src/gtobserver.ts +182 -0
- package/src/i18n/be.json +9 -4
- package/src/i18n/de.json +9 -4
- package/src/i18n/en.json +9 -4
- package/src/i18n/es.json +9 -4
- package/src/i18n/fr.json +9 -4
- package/src/i18n/pl.json +9 -4
- package/src/i18n/ru.json +9 -4
- package/src/i18n/types.ts +11 -0
- package/src/i18n/uk.json +9 -4
- package/src/i18n.ts +20 -32
- package/src/index.ts +13 -13
- package/src/linker/types.ts +59 -0
- package/src/linker.ts +301 -364
- package/src/plugins/types.ts +42 -0
- package/src/plugins.ts +82 -106
- package/src/storage/types.ts +31 -0
- package/src/storage.ts +75 -77
- package/src/store.ts +122 -69
- package/src/types.local.ts +9 -0
- package/src/types.ts +153 -25
- package/tests/consent.spec.ts +26 -28
- package/tests/geo.spec.ts +474 -0
- package/tests/linker.spec.ts +144 -309
- package/tests/tracking.spec.ts +14 -14
- package/build/functional.d.ts +0 -35
- package/build/functional.d.ts.map +0 -1
- package/build/functional.js +0 -67
- package/build/functional.js.map +0 -1
- package/build/gtm.d.ts +0 -72
- package/build/gtm.d.ts.map +0 -1
- package/build/gtm.js +0 -182
- package/build/gtm.js.map +0 -1
- package/src/functional.ts +0 -73
- package/src/gtm.ts +0 -220
package/README.md
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# @owlmeans/consent
|
|
2
|
+
|
|
3
|
+
The framework-free core of OwlMeans cookie consent: the category model, dual localStorage/cookie
|
|
4
|
+
storage with in-place migration, the observable document-level `consentStore`, Google Consent Mode
|
|
5
|
+
v2 signalling with the inline head scripts that must run before a tag manager loads, the built-in
|
|
6
|
+
dialog copy in eight languages, and cross-domain consent through decorated links. It has **zero
|
|
7
|
+
runtime dependencies**, so an Astro island or a plain script can load it. An app uses it directly
|
|
8
|
+
to stamp the head snippet, read a decision outside React, or gate a loader. It renders nothing — the
|
|
9
|
+
dialog, the re-open button and the cookie-policy page are `@owlmeans/web-consent` (or
|
|
10
|
+
`@owlmeans/web-panel/consent` bound to OwlMeans i18n), and the Google tag snippet itself is
|
|
11
|
+
`@owlmeans/web-gtm`. Per-person marketing preferences on the server are `@owlmeans/marketing-consent`,
|
|
12
|
+
not this package.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
bun add @owlmeans/consent@^0.1.18
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Concepts
|
|
21
|
+
|
|
22
|
+
- **Category** — a `ConsentCategory`: a stable `key`, label/description keys, an optional
|
|
23
|
+
`globalVar` written on `window`, the Consent Mode `signals` it drives and an optional `dataLayer`
|
|
24
|
+
`event`. The defaults are `essential` (required), `analytics` and `marketing`.
|
|
25
|
+
- **Required category** — always granted and rendered locked: disclosure, not a question.
|
|
26
|
+
- **Record** — a `ConsentRecord` `{ v?, [categoryKey]: boolean }`, stored under
|
|
27
|
+
`site_cookie_consent` in both localStorage and a 365-day `SameSite=Lax` cookie, localStorage read
|
|
28
|
+
first. A record without `v` is migrated in place (`essential: true`, `v: 2`), never discarded.
|
|
29
|
+
- **Store** — `consentStore`, a module singleton: consent belongs to the document, not to a
|
|
30
|
+
component tree, and is reachable from click handlers and non-React code.
|
|
31
|
+
- **Ordering rule** — `consent/default` must be on `window.dataLayer` before the tag manager loads,
|
|
32
|
+
so it is pushed by an inline script stamped above the snippet, not by a bundle.
|
|
33
|
+
- **Plugin** — a `ConsentPlugin` that can `adopt` a decision or a language from outside storage,
|
|
34
|
+
`decorate` outgoing URLs and disclose `domains`. `consentLinkHelper.consentLinker()` is the one
|
|
35
|
+
built-in plugin.
|
|
36
|
+
- **Interface language** — strictly necessary storage (`owlmeans-lng`); no category governs it.
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
40
|
+
### Start the store and read the decision
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { consentStore, CONSENT_ANALYTICS } from '@owlmeans/consent'
|
|
44
|
+
|
|
45
|
+
consentStore.init() // push defaults, read + migrate, apply, open when nothing is stored
|
|
46
|
+
|
|
47
|
+
const unsubscribe = consentStore.subscribe(state => {
|
|
48
|
+
if (state.open) {
|
|
49
|
+
showDialog(state.reason) // 'initial' | 'reopen' | 'login' | custom
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
if (consentStore.granted(CONSENT_ANALYTICS)) {
|
|
54
|
+
startAnalytics()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
consentStore.save({ essential: true, analytics: true, marketing: false })
|
|
58
|
+
consentStore.acceptAll()
|
|
59
|
+
consentStore.open('reopen') // e.g. from a footer link
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`useConsent()` in `@owlmeans/web-consent` calls `init` on mount; a host that mounts neither the
|
|
63
|
+
dialog nor a tag loader calls it once itself, with the same options everything else receives.
|
|
64
|
+
|
|
65
|
+
### Stamp the head snippet above the tag manager
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { consentModeHelper } from '@owlmeans/consent'
|
|
69
|
+
|
|
70
|
+
const bootstrap = consentModeHelper.consentBootstrapScript() // defaults + the stored record
|
|
71
|
+
|
|
72
|
+
// Withhold a loader until tracking is granted (now or by a later CONSENT_EVENT)
|
|
73
|
+
const gated = consentModeHelper.consentGateScript(loaderIife)
|
|
74
|
+
|
|
75
|
+
// Escaping `</script` / `<!--` in the composed inline script is the caller's job
|
|
76
|
+
const head = `<script>${bootstrap};${gated}</script>`
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Custom categories
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { DEFAULT_CONSENT_CATEGORIES, consentStore } from '@owlmeans/consent'
|
|
83
|
+
import type { ConsentCategory } from '@owlmeans/consent'
|
|
84
|
+
|
|
85
|
+
const categories: ConsentCategory[] = [
|
|
86
|
+
...DEFAULT_CONSENT_CATEGORIES.filter(category => category.key !== 'marketing'),
|
|
87
|
+
{ key: 'chat', labelKey: 'chat', descriptionKey: 'chatDesc', globalVar: 'owlConsentChat' },
|
|
88
|
+
]
|
|
89
|
+
|
|
90
|
+
consentStore.init({ categories })
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Share a decision across first-party domains
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
import { consentLinkHelper, consentStore } from '@owlmeans/consent'
|
|
97
|
+
|
|
98
|
+
const linker = {
|
|
99
|
+
domains: ['owlmeans.com', 'app.example.com'],
|
|
100
|
+
language: { supported: ['en', 'pl', 'de'] }, // omit `supported` on a send-only site
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
consentStore.init({ linker }) // registers consentLinker, adopts, writes the language, strips `owlcc`
|
|
104
|
+
|
|
105
|
+
// For a page that must adopt before any bundle (and before its i18n reads storage)
|
|
106
|
+
const fragment = consentLinkHelper.consentLinkerScript({ linker })
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Ask only where the law requires it
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { consentPluginHelper, consentStore } from '@owlmeans/consent'
|
|
113
|
+
|
|
114
|
+
// Cloudflare mode: a same-origin GET of /cdn-cgi/trace, `loc=` decides
|
|
115
|
+
consentStore.init({ geo: { cloudflare: true } })
|
|
116
|
+
|
|
117
|
+
// …or a locator of your own — one async method that resolves the country or throws
|
|
118
|
+
consentPluginHelper.registerConsentPlugin({
|
|
119
|
+
alias: 'my-geo', locate: async () => ({ country: await myCountryLookup() }),
|
|
120
|
+
})
|
|
121
|
+
consentStore.init({ geo: {} })
|
|
122
|
+
|
|
123
|
+
await consentStore.settled() // the state once the lookup is over
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
A visitor located in `CONSENT_REQUIRED_COUNTRIES` (or `geo.countries`) is asked; anyone else gets an
|
|
127
|
+
automatic decision (`auto: <unix s>` on the record) — every category, or only the required ones
|
|
128
|
+
under Global Privacy Control; a visitor nobody can locate is asked. An automatic decision is trusted
|
|
129
|
+
for `CONSENT_AUTO_MAX_AGE` (one hour) and then re-checked silently; an explicit decision always wins.
|
|
130
|
+
|
|
131
|
+
### Built-in copy
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
import { consentI18nHelper } from '@owlmeans/consent'
|
|
135
|
+
|
|
136
|
+
const t = consentI18nHelper.defaultConsentTranslate('pl-PL') // falls back to 'en'
|
|
137
|
+
t('analytics', 'Analytics')
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## API
|
|
141
|
+
|
|
142
|
+
### Store and helpers
|
|
143
|
+
|
|
144
|
+
| Symbol | Kind | Purpose |
|
|
145
|
+
|---|---|---|
|
|
146
|
+
| `consentStore`, `makeConsentStore()` | store | `get`, `subscribe`, `init(opts?)`, `save(record)`, `acceptAll`, `open(reason?)`, `close`, `granted(key)`, `options()`, `settled()` |
|
|
147
|
+
| `consentStorageHelper`, `createConsentStorageHelper()` | helper | `migrateConsent`, `readConsent`, `writeConsent`, `clearConsent` |
|
|
148
|
+
| `consentModeHelper`, `createConsentModeHelper()` | helper | `gtagConsent`, `consentDefaults`, `consentUpdate`, `pushConsentDefaults`, `applyConsent`, `trackingGranted`, `consentBootstrapScript`, `consentGateScript` |
|
|
149
|
+
| `consentLinkHelper`, `createConsentLinkHelper()` | helper | `encodeConsentLink`, `decodeConsentLink`, `writeConsentLanguage`, `consentLinker`, `stripConsentLinkParam`, `consentLinkerScript` |
|
|
150
|
+
| `consentPluginHelper`, `createConsentPluginHelper()` | helper | `registerConsentPlugin`, `unregisterConsentPlugin`, `consentPlugins`, `decorateConsentUrl`, `consentDomains`, `adoptConsent`, `adoptConsentLanguage`, `startConsentPlugins`, `locateConsent` |
|
|
151
|
+
| `consentGeoHelper`, `createConsentGeoHelper()` | helper | `enabled`, `parseTrace`, `cloudflareLocator`, `requiresConsent`, `decide`, `privacySignal`, `automaticRecord`, `autoState` |
|
|
152
|
+
| `consentI18nHelper`, `createConsentI18nHelper()` | helper | `normalizeLocale`, `defaultConsentTranslate`, `interpolate` |
|
|
153
|
+
|
|
154
|
+
Deprecated top-level wrappers (`compat:factory-refactor`) remain exported: `readConsent`,
|
|
155
|
+
`writeConsent`, `clearConsent`, `openConsent`, `isConsented`, `consentBootstrapScript`,
|
|
156
|
+
`defaultConsentTranslate`, `decorateConsentUrl`, `encodeConsentLink`, `consentLinkerScript`. New code
|
|
157
|
+
calls the helper members.
|
|
158
|
+
|
|
159
|
+
### Constants
|
|
160
|
+
|
|
161
|
+
| Symbol | Value / purpose |
|
|
162
|
+
|---|---|
|
|
163
|
+
| `CONSENT_KEY` | `'site_cookie_consent'` — storage key, must not change |
|
|
164
|
+
| `CONSENT_COOKIE_DAYS` | `365` |
|
|
165
|
+
| `CONSENT_SCHEMA_VERSION` | `2` — stored record shape |
|
|
166
|
+
| `CONSENT_SETUP_FLAG` | `'cookieConsentSetup'` — window flag making `pushConsentDefaults` idempotent |
|
|
167
|
+
| `CONSENT_EVENT` | `'owlmeans:consent'` — dispatched by `applyConsent`, `detail.record` |
|
|
168
|
+
| `CONSENT_ESSENTIAL`, `CONSENT_ANALYTICS`, `CONSENT_MARKETING` | default category keys |
|
|
169
|
+
| `CONSENT_LANGUAGE_KEY` | `'owlmeans-lng'` — the interface-language storage key |
|
|
170
|
+
| `CONSENT_LOCALES` | `en pl ru be uk es de fr` |
|
|
171
|
+
| `DEFAULT_CONSENT_MESSAGES` | built-in dialog copy per locale |
|
|
172
|
+
| `DEFAULT_CONSENT_CATEGORIES` | `essential` (required), `analytics`, `marketing` |
|
|
173
|
+
| `CONSENT_SIGNAL_DEFAULTS` | every Consent Mode v2 signal `denied`, except `security_storage` `granted` |
|
|
174
|
+
| `CONSENT_LINK_PARAM`, `CONSENT_LINK_MAX_AGE`, `CONSENT_LINK_SKEW` | `'owlcc'`, `300` s, `60` s |
|
|
175
|
+
| `CONSENT_REQUIRED_COUNTRIES` | where a located visitor is asked — the union of `CONSENT_COUNTRIES_GDPR`, `CONSENT_COUNTRIES_ALIGNED`, `CONSENT_COUNTRIES_OPT_IN` |
|
|
176
|
+
| `CONSENT_GEO_UNKNOWN` | codes that name no country (`XX`, `T1`, …) — asked |
|
|
177
|
+
| `CONSENT_TRACE_PATH`, `CONSENT_GEO_TIMEOUT` | `'/cdn-cgi/trace'`, `2500` ms |
|
|
178
|
+
| `CONSENT_AUTO_MAX_AGE` | `3600` s — how long an automatic decision is trusted |
|
|
179
|
+
| `CONSENT_IDLE_STATE` | the frozen pre-init state and server snapshot |
|
|
180
|
+
| `CONSENT_STATE_ATTRIBUTE` | `'data-consent'` on `<html>`: `locating`, `open`, `decided`, `idle` |
|
|
181
|
+
|
|
182
|
+
### Types
|
|
183
|
+
|
|
184
|
+
| Symbol | Purpose |
|
|
185
|
+
|---|---|
|
|
186
|
+
| `ConsentSignal` | the Consent Mode v2 signal names |
|
|
187
|
+
| `ConsentCategory`, `ConsentRecord`, `ConsentService` | category, stored decision, disclosed third-party service |
|
|
188
|
+
| `ConsentOptions` | `categories?`, `storageKey?`, `cookieDays?`, `cookieDomain?`, `silent?`, `linker?`, `geo?` |
|
|
189
|
+
| `ConsentGeoOptions`, `ConsentCloudflareOptions`, `ConsentGeoPlugin`, `ConsentGeoLocation`, `ConsentLocating` | the geo gate: `cloudflare?`, `countries?`, `timeout?`; a locator plugin; its answer; the lookup phase |
|
|
190
|
+
| `ConsentGeoHelper`, `ConsentGeoVerdict`, `ConsentAutoState` | the geo helper's interface, `'ask' \| 'auto'`, `'fresh' \| 'stale'` |
|
|
191
|
+
| `ConsentLinkerOptions`, `ConsentLinkerLanguage` | `domains`, `param?`, `maxAge?`, `language?`; `supported?`, `storageKey?` |
|
|
192
|
+
| `ConsentState`, `ConsentReason`, `ConsentListener`, `ConsentStore` | store state and contract |
|
|
193
|
+
| `ConsentLocale`, `ConsentLinkPayload`, `ConsentPlugin` | locale union, decoded `owlcc` payload, plugin seam |
|
|
194
|
+
| `ConsentModeHelper`, `ConsentStorageHelper`, `ConsentLinkHelper`, `ConsentPluginHelper`, `ConsentI18nHelper` | helper interfaces |
|
|
195
|
+
|
|
196
|
+
## Cross-domain linking rules
|
|
197
|
+
|
|
198
|
+
`consentLinker().adopt` accepts a decorated link only when the payload decodes with the current
|
|
199
|
+
version, the referrer host is a listed domain, the timestamp is within `maxAge` (and at most 60 s in
|
|
200
|
+
the future), and every local optional category is present. It runs only when the document has no
|
|
201
|
+
stored record. The parameter is stripped from the visible URL whether or not it was adopted. Links
|
|
202
|
+
with `rel="noreferrer"` are never decorated.
|
|
203
|
+
|
|
204
|
+
## Common pitfalls
|
|
205
|
+
|
|
206
|
+
- Stamp `consentBootstrapScript()` inline above the tag-manager snippet; pushing defaults from a
|
|
207
|
+
React bundle is too late.
|
|
208
|
+
- `silent: true` suppresses runtime pushes only — the stamped bootstrap string still pushes.
|
|
209
|
+
- Do not set `cookieDomain` on an existing site: it orphans the host-only cookie and re-asks every
|
|
210
|
+
visitor. Do not change `CONSENT_KEY` for the same reason.
|
|
211
|
+
- Never present the required category as a choice, and never word a login gate as consent to
|
|
212
|
+
essential cookies.
|
|
213
|
+
- Consent Mode speaks on `window.dataLayer` only; a tag on another queue never hears it.
|
|
214
|
+
- Neither `consentBootstrapScript`, `consentGateScript` nor the composed result is HTML-escaped by
|
|
215
|
+
this package beyond JSON-encoding its own values.
|
|
216
|
+
- Release both ends of a linked domain pair together: a receiver that asks about a category the
|
|
217
|
+
sender dropped refuses the link.
|
|
218
|
+
|
|
219
|
+
The `consent` skill covers the category model, storage migration, the ordering rule, gated loading,
|
|
220
|
+
the plugin seam and language linking in depth.
|
|
221
|
+
|
|
222
|
+
## Related packages
|
|
223
|
+
|
|
224
|
+
- [`@owlmeans/web-consent`](../web-consent) — the React dialog, re-open button, `CookiePolicy` and `useConsent`
|
|
225
|
+
- [`@owlmeans/web-gtm`](../web-gtm) — Google tag head snippet, CSP hosts and Google service disclosure
|
|
226
|
+
- [`@owlmeans/web-panel`](../web-panel) — `/consent` subpath bound to OwlMeans i18n and the panel menu
|
|
227
|
+
- [`@owlmeans/astro`](../astro) — `owlHeadScripts` for Astro sites, legal-page suppression
|
|
228
|
+
- [`@owlmeans/web-marketing-consent`](../web-marketing-consent) — bridges marketing preferences into `consentStore.save`
|
|
229
|
+
- [`@owlmeans/client-i18n`](../client-i18n) — reads the `owlmeans-lng` language choice this package may write
|
package/build/consts.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ConsentCategory } from './types.js';
|
|
1
|
+
import type { ConsentCategory, ConsentLocale, ConsentState } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Where a visitor's choice is stored.
|
|
4
4
|
*
|
|
@@ -28,39 +28,33 @@ export declare const CONSENT_SETUP_FLAG = "cookieConsentSetup";
|
|
|
28
28
|
*/
|
|
29
29
|
export declare const CONSENT_EVENT = "owlmeans:consent";
|
|
30
30
|
export declare const CONSENT_ESSENTIAL = "essential";
|
|
31
|
-
export declare const CONSENT_FUNCTIONAL = "functional";
|
|
32
31
|
export declare const CONSENT_ANALYTICS = "analytics";
|
|
33
32
|
export declare const CONSENT_MARKETING = "marketing";
|
|
34
|
-
/**
|
|
35
|
-
* The DOM event the store dispatches on `window` when a language that arrived with a link (or an
|
|
36
|
-
* explicit choice made before the visitor answered the dialog) has just become storable — the
|
|
37
|
-
* visitor granted functional storage — so the application can switch to it now instead of at the
|
|
38
|
-
* next load. `detail: { language }`. An application that resolves its language from storage at
|
|
39
|
-
* start-up (`@owlmeans/client-i18n`) listens for it.
|
|
40
|
-
*/
|
|
41
|
-
export declare const CONSENT_LANGUAGE_EVENT = "owlmeans:language";
|
|
42
|
-
/**
|
|
43
|
-
* The `window` property the inline `<head>` fragment leaves a carried language on when it may not
|
|
44
|
-
* store it yet (no decision, or functional not granted): memory only, never storage. The store
|
|
45
|
-
* picks it up at `init` and writes it if — and only if — the visitor later grants functional storage
|
|
46
|
-
* in this page's life. Fixed for the same reason `CONSENT_SETUP_FLAG` is: two bundles, one page.
|
|
47
|
-
*/
|
|
48
|
-
export declare const CONSENT_PENDING_LANGUAGE = "cookieConsentPendingLanguage";
|
|
49
33
|
/**
|
|
50
34
|
* Where an application persists an explicit interface-language choice — `@owlmeans/client-i18n`'s
|
|
51
|
-
* `owlmeans-lng`.
|
|
52
|
-
*
|
|
35
|
+
* `owlmeans-lng`. The interface language is strictly necessary storage (the visitor asked for it by
|
|
36
|
+
* choosing it), so it is written whatever the cookie decision says and no category governs it.
|
|
37
|
+
* Repeated here rather than imported: this package has no runtime dependencies, and the linker's
|
|
38
|
+
* language part has to run in an inline `<head>` script, before any bundle exists.
|
|
53
39
|
*/
|
|
54
40
|
export declare const CONSENT_LANGUAGE_KEY = "owlmeans-lng";
|
|
55
|
-
export declare const CONSENT_LOCALES: readonly [
|
|
56
|
-
|
|
41
|
+
export declare const CONSENT_LOCALES: readonly ["en", "pl", "ru", "be", "uk", "es", "de", "fr"];
|
|
42
|
+
/**
|
|
43
|
+
* The dialog's copy, in the box.
|
|
44
|
+
*
|
|
45
|
+
* Carried here rather than registered into an i18n framework because one of the three consumers is
|
|
46
|
+
* an Astro site with React islands and no OwlMeans i18n at all — and a consent dialog that renders
|
|
47
|
+
* raw keys is worse than no dialog. An application that HAS translations passes `translate` and
|
|
48
|
+
* overrides every one of these.
|
|
49
|
+
*/
|
|
50
|
+
export declare const DEFAULT_CONSENT_MESSAGES: Record<ConsentLocale, Record<string, string>>;
|
|
57
51
|
/**
|
|
58
52
|
* The categories every OwlMeans surface starts with.
|
|
59
53
|
*
|
|
60
54
|
* What owlmeans.com already asked (analytics, marketing) plus the essential row, which the original
|
|
61
55
|
* widget left implicit — making it explicit is what lets a flow require an acknowledgement before
|
|
62
|
-
* it sets a session cookie, and what tells a visitor what is being stored regardless
|
|
63
|
-
*
|
|
56
|
+
* it sets a session cookie, and what tells a visitor what is being stored regardless: the consent
|
|
57
|
+
* record itself and the interface language the visitor picked.
|
|
64
58
|
*/
|
|
65
59
|
export declare const DEFAULT_CONSENT_CATEGORIES: ConsentCategory[];
|
|
66
60
|
/**
|
|
@@ -70,4 +64,71 @@ export declare const DEFAULT_CONSENT_CATEGORIES: ConsentCategory[];
|
|
|
70
64
|
* fraud prevention, which are strictly necessary. Everything else starts denied.
|
|
71
65
|
*/
|
|
72
66
|
export declare const CONSENT_SIGNAL_DEFAULTS: Record<string, 'granted' | 'denied'>;
|
|
67
|
+
/** The URL parameter a decorated link carries the decision in, absent an override. */
|
|
68
|
+
export declare const CONSENT_LINK_PARAM = "owlcc";
|
|
69
|
+
/** How old a decorated link's timestamp may be and still be trusted, in seconds, absent an override. */
|
|
70
|
+
export declare const CONSENT_LINK_MAX_AGE = 300;
|
|
71
|
+
/** Clock skew allowed the OTHER way — a timestamp up to this far in the future is still trusted. */
|
|
72
|
+
export declare const CONSENT_LINK_SKEW = 60;
|
|
73
|
+
/**
|
|
74
|
+
* Where prior consent for non-essential cookies is the law: the EU and EEA (ePrivacy Art. 5(3) with
|
|
75
|
+
* the GDPR), including the parts of member states that carry an ISO code of their own — Åland and
|
|
76
|
+
* the French outermost regions (French Guiana, Guadeloupe, Martinique, Réunion, Mayotte,
|
|
77
|
+
* Saint-Martin). The Canary Islands, Azores, Madeira, Ceuta and Melilla report their state's code.
|
|
78
|
+
* Greece is `GR`, as Cloudflare and every ISO feed spell it.
|
|
79
|
+
*/
|
|
80
|
+
export declare const CONSENT_COUNTRIES_GDPR: readonly string[];
|
|
81
|
+
/**
|
|
82
|
+
* Jurisdictions outside the EEA whose rule for cookies is the same prior opt-in, by statute or by
|
|
83
|
+
* the regulator's guidance (2026):
|
|
84
|
+
*
|
|
85
|
+
* - the United Kingdom (PECR — the 2025 Data (Use and Access) Act exempts some first-party
|
|
86
|
+
* analytics, advertising still needs consent), the Crown Dependencies and Gibraltar;
|
|
87
|
+
* - Switzerland (FDPIC guidelines, 2025: explicit consent for tracking and profiling);
|
|
88
|
+
* - Andorra, Monaco, San Marino and the Vatican; Türkiye (KVKK cookie guide); Serbia (ZZPL and the
|
|
89
|
+
* electronic-communications law); Albania, Bosnia and Herzegovina, Montenegro, North Macedonia,
|
|
90
|
+
* Kosovo, Moldova, Georgia and Ukraine (GDPR-modelled laws);
|
|
91
|
+
* - territories under a member state's regulator but outside the EU: the Faroe Islands and
|
|
92
|
+
* Greenland (Denmark); Saint-Barthélemy, Saint-Pierre-et-Miquelon, New Caledonia, French
|
|
93
|
+
* Polynesia, Wallis and Futuna (France); the Caribbean Netherlands.
|
|
94
|
+
*/
|
|
95
|
+
export declare const CONSENT_COUNTRIES_ALIGNED: readonly string[];
|
|
96
|
+
/**
|
|
97
|
+
* Prior opt-in regimes elsewhere (2026): Brazil (LGPD, ANPD cookie guide), Canada (Québec's Law 25
|
|
98
|
+
* — the country is the finest grain a CDN reports, so all of Canada), China (PIPL), South Korea
|
|
99
|
+
* (PIPA), Nigeria (NDPA), Saudi Arabia (PDPL), Thailand (PDPA), Vietnam (PDPL 2026).
|
|
100
|
+
*
|
|
101
|
+
* Deliberately absent: India (the DPDP Act's consent rules apply from mid-2027 — add `IN` then),
|
|
102
|
+
* and the notice-or-opt-out regimes — the United States, Japan, Australia, Singapore. South
|
|
103
|
+
* Africa's POPIA is read both ways by the guides and is left out until its regulator says more.
|
|
104
|
+
*/
|
|
105
|
+
export declare const CONSENT_COUNTRIES_OPT_IN: readonly string[];
|
|
106
|
+
/**
|
|
107
|
+
* Every country where a located visitor is ASKED (`ConsentGeoOptions.countries` replaces it). A
|
|
108
|
+
* visitor located anywhere else gets an automatic decision; one who cannot be located is asked.
|
|
109
|
+
*/
|
|
110
|
+
export declare const CONSENT_REQUIRED_COUNTRIES: readonly string[];
|
|
111
|
+
/**
|
|
112
|
+
* Codes that name no country: Cloudflare's `XX` (no data) and `T1` (Tor), the retired MaxMind
|
|
113
|
+
* pseudo-codes (`A1` anonymous proxy, `A2` satellite, `O1` other) and the continent buckets some
|
|
114
|
+
* feeds fall back to (`EU`, `AP`), plus `ZZ` (unknown). A visitor reported with one is asked.
|
|
115
|
+
*/
|
|
116
|
+
export declare const CONSENT_GEO_UNKNOWN: readonly string[];
|
|
117
|
+
/** Cloudflare's trace endpoint — served by the edge on every proxied host, `loc=` among its lines. */
|
|
118
|
+
export declare const CONSENT_TRACE_PATH = "/cdn-cgi/trace";
|
|
119
|
+
/** How long locating may take before the visitor is asked anyway, in ms. */
|
|
120
|
+
export declare const CONSENT_GEO_TIMEOUT = 2500;
|
|
121
|
+
/**
|
|
122
|
+
* How long an automatic decision is trusted, in seconds. Older, it counts as undecided — in the
|
|
123
|
+
* head scripts as much as in the store — until the visitor is located again, so a grant derived in
|
|
124
|
+
* one country never reaches a page opened an hour later in another.
|
|
125
|
+
*/
|
|
126
|
+
export declare const CONSENT_AUTO_MAX_AGE = 3600;
|
|
127
|
+
/** The state of a store nobody has initialised — and the only server-side snapshot. */
|
|
128
|
+
export declare const CONSENT_IDLE_STATE: ConsentState;
|
|
129
|
+
/**
|
|
130
|
+
* The attribute on `<html>` that mirrors the consent phase: `locating`, `open`, `decided` or `idle`.
|
|
131
|
+
* Absent until the store first runs. A test waits on it, and a stylesheet may key on it.
|
|
132
|
+
*/
|
|
133
|
+
export declare const CONSENT_STATE_ATTRIBUTE = "data-consent";
|
|
73
134
|
//# sourceMappingURL=consts.d.ts.map
|
package/build/consts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAW9E;;;;;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;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,qBAAqB,CAAA;AAE/C,eAAO,MAAM,iBAAiB,cAAc,CAAA;AAC5C,eAAO,MAAM,iBAAiB,cAAc,CAAA;AAC5C,eAAO,MAAM,iBAAiB,cAAc,CAAA;AAE5C;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,iBAAiB,CAAA;AAElD,eAAO,MAAM,eAAe,2DAA+F,CAAA;AAE3H;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAElF,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,EAAE,eAAe,EAmBvD,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAQxE,CAAA;AAED,sFAAsF;AACtF,eAAO,MAAM,kBAAkB,UAAU,CAAA;AAEzC,wGAAwG;AACxG,eAAO,MAAM,oBAAoB,MAAM,CAAA;AAEvC,oGAAoG;AACpG,eAAO,MAAM,iBAAiB,KAAK,CAAA;AAEnC;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAKlD,CAAA;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAKrD,CAAA;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,EAAE,SAAS,MAAM,EAEpD,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,EAAE,SAAS,MAAM,EAEtD,CAAA;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAE/C,CAAA;AAEF,sGAAsG;AACtG,eAAO,MAAM,kBAAkB,mBAAmB,CAAA;AAElD,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB,OAAO,CAAA;AAEvC;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,OAAO,CAAA;AAExC,uFAAuF;AACvF,eAAO,MAAM,kBAAkB,EAAE,YAE/B,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,iBAAiB,CAAA"}
|
package/build/consts.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
import en from './i18n/en.json' with { type: 'json' };
|
|
2
|
+
import pl from './i18n/pl.json' with { type: 'json' };
|
|
3
|
+
import ru from './i18n/ru.json' with { type: 'json' };
|
|
4
|
+
import be from './i18n/be.json' with { type: 'json' };
|
|
5
|
+
import uk from './i18n/uk.json' with { type: 'json' };
|
|
6
|
+
import es from './i18n/es.json' with { type: 'json' };
|
|
7
|
+
import de from './i18n/de.json' with { type: 'json' };
|
|
8
|
+
import fr from './i18n/fr.json' with { type: 'json' };
|
|
1
9
|
/**
|
|
2
10
|
* Where a visitor's choice is stored.
|
|
3
11
|
*
|
|
@@ -27,38 +35,35 @@ export const CONSENT_SETUP_FLAG = 'cookieConsentSetup';
|
|
|
27
35
|
*/
|
|
28
36
|
export const CONSENT_EVENT = 'owlmeans:consent';
|
|
29
37
|
export const CONSENT_ESSENTIAL = 'essential';
|
|
30
|
-
export const CONSENT_FUNCTIONAL = 'functional';
|
|
31
38
|
export const CONSENT_ANALYTICS = 'analytics';
|
|
32
39
|
export const CONSENT_MARKETING = 'marketing';
|
|
33
|
-
/**
|
|
34
|
-
* The DOM event the store dispatches on `window` when a language that arrived with a link (or an
|
|
35
|
-
* explicit choice made before the visitor answered the dialog) has just become storable — the
|
|
36
|
-
* visitor granted functional storage — so the application can switch to it now instead of at the
|
|
37
|
-
* next load. `detail: { language }`. An application that resolves its language from storage at
|
|
38
|
-
* start-up (`@owlmeans/client-i18n`) listens for it.
|
|
39
|
-
*/
|
|
40
|
-
export const CONSENT_LANGUAGE_EVENT = 'owlmeans:language';
|
|
41
|
-
/**
|
|
42
|
-
* The `window` property the inline `<head>` fragment leaves a carried language on when it may not
|
|
43
|
-
* store it yet (no decision, or functional not granted): memory only, never storage. The store
|
|
44
|
-
* picks it up at `init` and writes it if — and only if — the visitor later grants functional storage
|
|
45
|
-
* in this page's life. Fixed for the same reason `CONSENT_SETUP_FLAG` is: two bundles, one page.
|
|
46
|
-
*/
|
|
47
|
-
export const CONSENT_PENDING_LANGUAGE = 'cookieConsentPendingLanguage';
|
|
48
40
|
/**
|
|
49
41
|
* Where an application persists an explicit interface-language choice — `@owlmeans/client-i18n`'s
|
|
50
|
-
* `owlmeans-lng`.
|
|
51
|
-
*
|
|
42
|
+
* `owlmeans-lng`. The interface language is strictly necessary storage (the visitor asked for it by
|
|
43
|
+
* choosing it), so it is written whatever the cookie decision says and no category governs it.
|
|
44
|
+
* Repeated here rather than imported: this package has no runtime dependencies, and the linker's
|
|
45
|
+
* language part has to run in an inline `<head>` script, before any bundle exists.
|
|
52
46
|
*/
|
|
53
47
|
export const CONSENT_LANGUAGE_KEY = 'owlmeans-lng';
|
|
54
48
|
export const CONSENT_LOCALES = ['en', 'pl', 'ru', 'be', 'uk', 'es', 'de', 'fr'];
|
|
49
|
+
/**
|
|
50
|
+
* The dialog's copy, in the box.
|
|
51
|
+
*
|
|
52
|
+
* Carried here rather than registered into an i18n framework because one of the three consumers is
|
|
53
|
+
* an Astro site with React islands and no OwlMeans i18n at all — and a consent dialog that renders
|
|
54
|
+
* raw keys is worse than no dialog. An application that HAS translations passes `translate` and
|
|
55
|
+
* overrides every one of these.
|
|
56
|
+
*/
|
|
57
|
+
export const DEFAULT_CONSENT_MESSAGES = {
|
|
58
|
+
en, pl, ru, be, uk, es, de, fr,
|
|
59
|
+
};
|
|
55
60
|
/**
|
|
56
61
|
* The categories every OwlMeans surface starts with.
|
|
57
62
|
*
|
|
58
63
|
* What owlmeans.com already asked (analytics, marketing) plus the essential row, which the original
|
|
59
64
|
* widget left implicit — making it explicit is what lets a flow require an acknowledgement before
|
|
60
|
-
* it sets a session cookie, and what tells a visitor what is being stored regardless
|
|
61
|
-
*
|
|
65
|
+
* it sets a session cookie, and what tells a visitor what is being stored regardless: the consent
|
|
66
|
+
* record itself and the interface language the visitor picked.
|
|
62
67
|
*/
|
|
63
68
|
export const DEFAULT_CONSENT_CATEGORIES = [
|
|
64
69
|
{
|
|
@@ -67,15 +72,6 @@ export const DEFAULT_CONSENT_CATEGORIES = [
|
|
|
67
72
|
globalVar: 'owlConsentEssential',
|
|
68
73
|
signals: ['security_storage', 'functionality_storage'],
|
|
69
74
|
},
|
|
70
|
-
// A preference the visitor set — today the interface language — remembered on their device. Not
|
|
71
|
-
// essential (nothing breaks without it) and not tracking, so it drives NO Consent Mode signal:
|
|
72
|
-
// a signal would make `trackingGranted` count it, and a visitor who only allowed their language
|
|
73
|
-
// to be remembered would load the tag container.
|
|
74
|
-
{
|
|
75
|
-
key: CONSENT_FUNCTIONAL,
|
|
76
|
-
labelKey: 'functional', descriptionKey: 'functionalDesc',
|
|
77
|
-
globalVar: 'owlConsentFunctional',
|
|
78
|
-
},
|
|
79
75
|
{
|
|
80
76
|
key: CONSENT_ANALYTICS,
|
|
81
77
|
labelKey: 'analytics', descriptionKey: 'analyticsDesc',
|
|
@@ -104,4 +100,89 @@ export const CONSENT_SIGNAL_DEFAULTS = {
|
|
|
104
100
|
personalization_storage: 'denied',
|
|
105
101
|
security_storage: 'granted',
|
|
106
102
|
};
|
|
103
|
+
/** The URL parameter a decorated link carries the decision in, absent an override. */
|
|
104
|
+
export const CONSENT_LINK_PARAM = 'owlcc';
|
|
105
|
+
/** How old a decorated link's timestamp may be and still be trusted, in seconds, absent an override. */
|
|
106
|
+
export const CONSENT_LINK_MAX_AGE = 300;
|
|
107
|
+
/** Clock skew allowed the OTHER way — a timestamp up to this far in the future is still trusted. */
|
|
108
|
+
export const CONSENT_LINK_SKEW = 60;
|
|
109
|
+
/**
|
|
110
|
+
* Where prior consent for non-essential cookies is the law: the EU and EEA (ePrivacy Art. 5(3) with
|
|
111
|
+
* the GDPR), including the parts of member states that carry an ISO code of their own — Åland and
|
|
112
|
+
* the French outermost regions (French Guiana, Guadeloupe, Martinique, Réunion, Mayotte,
|
|
113
|
+
* Saint-Martin). The Canary Islands, Azores, Madeira, Ceuta and Melilla report their state's code.
|
|
114
|
+
* Greece is `GR`, as Cloudflare and every ISO feed spell it.
|
|
115
|
+
*/
|
|
116
|
+
export const CONSENT_COUNTRIES_GDPR = Object.freeze([
|
|
117
|
+
'AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GR', 'HR', 'HU',
|
|
118
|
+
'IE', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'PL', 'PT', 'RO', 'SE', 'SI', 'SK',
|
|
119
|
+
'AX', 'GF', 'GP', 'MQ', 'RE', 'YT', 'MF',
|
|
120
|
+
'IS', 'LI', 'NO',
|
|
121
|
+
]);
|
|
122
|
+
/**
|
|
123
|
+
* Jurisdictions outside the EEA whose rule for cookies is the same prior opt-in, by statute or by
|
|
124
|
+
* the regulator's guidance (2026):
|
|
125
|
+
*
|
|
126
|
+
* - the United Kingdom (PECR — the 2025 Data (Use and Access) Act exempts some first-party
|
|
127
|
+
* analytics, advertising still needs consent), the Crown Dependencies and Gibraltar;
|
|
128
|
+
* - Switzerland (FDPIC guidelines, 2025: explicit consent for tracking and profiling);
|
|
129
|
+
* - Andorra, Monaco, San Marino and the Vatican; Türkiye (KVKK cookie guide); Serbia (ZZPL and the
|
|
130
|
+
* electronic-communications law); Albania, Bosnia and Herzegovina, Montenegro, North Macedonia,
|
|
131
|
+
* Kosovo, Moldova, Georgia and Ukraine (GDPR-modelled laws);
|
|
132
|
+
* - territories under a member state's regulator but outside the EU: the Faroe Islands and
|
|
133
|
+
* Greenland (Denmark); Saint-Barthélemy, Saint-Pierre-et-Miquelon, New Caledonia, French
|
|
134
|
+
* Polynesia, Wallis and Futuna (France); the Caribbean Netherlands.
|
|
135
|
+
*/
|
|
136
|
+
export const CONSENT_COUNTRIES_ALIGNED = Object.freeze([
|
|
137
|
+
'GB', 'GG', 'JE', 'IM', 'GI',
|
|
138
|
+
'CH',
|
|
139
|
+
'AD', 'MC', 'SM', 'VA', 'TR', 'RS', 'AL', 'BA', 'ME', 'MK', 'XK', 'MD', 'GE', 'UA',
|
|
140
|
+
'FO', 'GL', 'BL', 'PM', 'NC', 'PF', 'WF', 'BQ',
|
|
141
|
+
]);
|
|
142
|
+
/**
|
|
143
|
+
* Prior opt-in regimes elsewhere (2026): Brazil (LGPD, ANPD cookie guide), Canada (Québec's Law 25
|
|
144
|
+
* — the country is the finest grain a CDN reports, so all of Canada), China (PIPL), South Korea
|
|
145
|
+
* (PIPA), Nigeria (NDPA), Saudi Arabia (PDPL), Thailand (PDPA), Vietnam (PDPL 2026).
|
|
146
|
+
*
|
|
147
|
+
* Deliberately absent: India (the DPDP Act's consent rules apply from mid-2027 — add `IN` then),
|
|
148
|
+
* and the notice-or-opt-out regimes — the United States, Japan, Australia, Singapore. South
|
|
149
|
+
* Africa's POPIA is read both ways by the guides and is left out until its regulator says more.
|
|
150
|
+
*/
|
|
151
|
+
export const CONSENT_COUNTRIES_OPT_IN = Object.freeze([
|
|
152
|
+
'BR', 'CA', 'CN', 'KR', 'NG', 'SA', 'TH', 'VN',
|
|
153
|
+
]);
|
|
154
|
+
/**
|
|
155
|
+
* Every country where a located visitor is ASKED (`ConsentGeoOptions.countries` replaces it). A
|
|
156
|
+
* visitor located anywhere else gets an automatic decision; one who cannot be located is asked.
|
|
157
|
+
*/
|
|
158
|
+
export const CONSENT_REQUIRED_COUNTRIES = Object.freeze([
|
|
159
|
+
...CONSENT_COUNTRIES_GDPR, ...CONSENT_COUNTRIES_ALIGNED, ...CONSENT_COUNTRIES_OPT_IN,
|
|
160
|
+
]);
|
|
161
|
+
/**
|
|
162
|
+
* Codes that name no country: Cloudflare's `XX` (no data) and `T1` (Tor), the retired MaxMind
|
|
163
|
+
* pseudo-codes (`A1` anonymous proxy, `A2` satellite, `O1` other) and the continent buckets some
|
|
164
|
+
* feeds fall back to (`EU`, `AP`), plus `ZZ` (unknown). A visitor reported with one is asked.
|
|
165
|
+
*/
|
|
166
|
+
export const CONSENT_GEO_UNKNOWN = Object.freeze([
|
|
167
|
+
'XX', 'T1', 'A1', 'A2', 'O1', 'EU', 'AP', 'ZZ',
|
|
168
|
+
]);
|
|
169
|
+
/** Cloudflare's trace endpoint — served by the edge on every proxied host, `loc=` among its lines. */
|
|
170
|
+
export const CONSENT_TRACE_PATH = '/cdn-cgi/trace';
|
|
171
|
+
/** How long locating may take before the visitor is asked anyway, in ms. */
|
|
172
|
+
export const CONSENT_GEO_TIMEOUT = 2500;
|
|
173
|
+
/**
|
|
174
|
+
* How long an automatic decision is trusted, in seconds. Older, it counts as undecided — in the
|
|
175
|
+
* head scripts as much as in the store — until the visitor is located again, so a grant derived in
|
|
176
|
+
* one country never reaches a page opened an hour later in another.
|
|
177
|
+
*/
|
|
178
|
+
export const CONSENT_AUTO_MAX_AGE = 3600;
|
|
179
|
+
/** The state of a store nobody has initialised — and the only server-side snapshot. */
|
|
180
|
+
export const CONSENT_IDLE_STATE = Object.freeze({
|
|
181
|
+
record: null, open: false, reason: null, locating: null,
|
|
182
|
+
});
|
|
183
|
+
/**
|
|
184
|
+
* The attribute on `<html>` that mirrors the consent phase: `locating`, `open`, `decided` or `idle`.
|
|
185
|
+
* Absent until the store first runs. A test waits on it, and a stylesheet may key on it.
|
|
186
|
+
*/
|
|
187
|
+
export const CONSENT_STATE_ATTRIBUTE = 'data-consent';
|
|
107
188
|
//# sourceMappingURL=consts.js.map
|
package/build/consts.js.map
CHANGED
|
@@ -1 +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;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,kBAAkB,CAAA;AAE/C,MAAM,CAAC,MAAM,iBAAiB,GAAG,WAAW,CAAA;AAC5C,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const CONSENT_LINK_VERSION = 2;
|
|
2
|
+
/** A BCP 47-shaped tag: a 2–3 letter language and up to three subtags (`pl`, `pt-BR`, `zh-Hant-TW`). */
|
|
3
|
+
export declare const LANGUAGE_TAG: RegExp;
|
|
4
|
+
/** The built-in Cloudflare locator's registry alias. */
|
|
5
|
+
export declare const CLOUDFLARE_LOCATOR_ALIAS = "cloudflare";
|
|
6
|
+
/** Below anything an application registers: an application's own locator always asks first. */
|
|
7
|
+
export declare const CLOUDFLARE_LOCATOR_PRIORITY = -100;
|
|
8
|
+
/** An ISO 3166-1 alpha-2 code, upper case. */
|
|
9
|
+
export declare const COUNTRY_CODE: RegExp;
|
|
10
|
+
/** Clock skew tolerated on an automatic decision's timestamp, in seconds. */
|
|
11
|
+
export declare const AUTO_SKEW = 60;
|
|
12
|
+
//# sourceMappingURL=consts.local.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consts.local.d.ts","sourceRoot":"","sources":["../src/consts.local.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,IAAI,CAAA;AAErC,wGAAwG;AACxG,eAAO,MAAM,YAAY,QAA4C,CAAA;AAErE,wDAAwD;AACxD,eAAO,MAAM,wBAAwB,eAAe,CAAA;AAEpD,+FAA+F;AAC/F,eAAO,MAAM,2BAA2B,OAAO,CAAA;AAE/C,8CAA8C;AAC9C,eAAO,MAAM,YAAY,QAAe,CAAA;AAExC,6EAA6E;AAC7E,eAAO,MAAM,SAAS,KAAK,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const CONSENT_LINK_VERSION = 2;
|
|
2
|
+
/** A BCP 47-shaped tag: a 2–3 letter language and up to three subtags (`pl`, `pt-BR`, `zh-Hant-TW`). */
|
|
3
|
+
export const LANGUAGE_TAG = /^[a-z]{2,3}(?:[-_][a-z0-9]{1,8}){0,3}$/i;
|
|
4
|
+
/** The built-in Cloudflare locator's registry alias. */
|
|
5
|
+
export const CLOUDFLARE_LOCATOR_ALIAS = 'cloudflare';
|
|
6
|
+
/** Below anything an application registers: an application's own locator always asks first. */
|
|
7
|
+
export const CLOUDFLARE_LOCATOR_PRIORITY = -100;
|
|
8
|
+
/** An ISO 3166-1 alpha-2 code, upper case. */
|
|
9
|
+
export const COUNTRY_CODE = /^[A-Z]{2}$/;
|
|
10
|
+
/** Clock skew tolerated on an automatic decision's timestamp, in seconds. */
|
|
11
|
+
export const AUTO_SKEW = 60;
|
|
12
|
+
//# sourceMappingURL=consts.local.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consts.local.js","sourceRoot":"","sources":["../src/consts.local.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAA;AAErC,wGAAwG;AACxG,MAAM,CAAC,MAAM,YAAY,GAAG,yCAAyC,CAAA;AAErE,wDAAwD;AACxD,MAAM,CAAC,MAAM,wBAAwB,GAAG,YAAY,CAAA;AAEpD,+FAA+F;AAC/F,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,GAAG,CAAA;AAE/C,8CAA8C;AAC9C,MAAM,CAAC,MAAM,YAAY,GAAG,YAAY,CAAA;AAExC,6EAA6E;AAC7E,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,CAAA"}
|