@tickboxhq/core 0.0.1 → 0.0.4

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.
@@ -0,0 +1,221 @@
1
+ /**
2
+ * How a category should be treated for a given jurisdiction.
3
+ *
4
+ * - `consent` — must opt-in. Block tags until granted. (e.g. marketing under GDPR/PECR)
5
+ * - `notice` — show info + easy opt-out, but don't block tags. (e.g. UK DUAA "statistical" analytics)
6
+ * - `always` — no consent or notice required. (e.g. necessary cookies)
7
+ */
8
+ type ConsentMode = 'consent' | 'notice' | 'always';
9
+ type CategoryId = string;
10
+ type CategoryDefinition = {
11
+ /** True for strictly necessary categories that the user cannot deny. */
12
+ required?: boolean;
13
+ /** Pre-toggled state when the user hasn't chosen yet. Ignored when `required` is true. */
14
+ default?: boolean;
15
+ /** Vendor identifiers (e.g. 'plausible', 'google-ads') used for jurisdiction classification. */
16
+ vendors?: string[];
17
+ /** Human-readable description shown in the banner / preference centre. */
18
+ description?: string;
19
+ /**
20
+ * Override the inferred mode for this category. Normally not needed —
21
+ * the jurisdiction + vendor list determines the mode.
22
+ */
23
+ mode?: ConsentMode;
24
+ };
25
+ type JurisdictionId = 'UK_DUAA' | 'EU_GDPR' | 'US_CA' | 'CCPA' | (string & {});
26
+ type Jurisdiction = {
27
+ id: JurisdictionId;
28
+ name: string;
29
+ /**
30
+ * Per-vendor classification: which vendors require full consent vs. notice-only
31
+ * vs. always-allowed under this jurisdiction.
32
+ */
33
+ vendorRules: Record<string, ConsentMode>;
34
+ /** Default mode applied to vendors not in `vendorRules`. */
35
+ defaultMode: ConsentMode;
36
+ /** UI requirements imposed by the jurisdiction. */
37
+ ui: {
38
+ /** Whether a "Reject All" button is required on the first banner layer. */
39
+ rejectButtonOnFirstLayer: boolean;
40
+ /** Whether Accept/Reject must have equal visual prominence. */
41
+ equalProminence: boolean;
42
+ /** Whether Global Privacy Control (Sec-GPC) signals must be honoured as opt-out. */
43
+ honorGPC: boolean;
44
+ };
45
+ /** Optional ISO 3166-1 alpha-2 country codes that map to this jurisdiction (used by 'auto' mode). */
46
+ countries?: readonly string[];
47
+ };
48
+ type ConsentConfig = {
49
+ /**
50
+ * The jurisdiction governing this site, or `'auto'` to detect by visitor country.
51
+ * 'auto' falls back to the strictest available match.
52
+ */
53
+ jurisdiction: Jurisdiction | 'auto';
54
+ /** Map of category ID to definition. The keys are arbitrary (e.g. 'analytics', 'marketing'). */
55
+ categories: Record<CategoryId, CategoryDefinition>;
56
+ /** Versioned policy reference. Audit log entries are tied to a policy version. */
57
+ policy?: {
58
+ version: string;
59
+ url?: string;
60
+ };
61
+ /** Cloud configuration. If omitted, the SDK runs entirely client-side with no telemetry. */
62
+ cloud?: {
63
+ apiKey?: string;
64
+ /** Override the default ingest endpoint. Useful for self-hosting. */
65
+ endpoint?: string;
66
+ };
67
+ /** Cookie storage options. */
68
+ storage?: StorageOptions;
69
+ };
70
+ type StorageOptions = {
71
+ /** Cookie name. Defaults to `__tb_consent`. */
72
+ cookieName?: string;
73
+ /** Optional Domain attribute (e.g. '.example.com' to share across subdomains). */
74
+ domain?: string;
75
+ /** Cookie max-age in days. Defaults to 365. */
76
+ maxAgeDays?: number;
77
+ };
78
+ /**
79
+ * The serialised consent record stored in the browser cookie.
80
+ * Schema is versioned via `v` so future migrations don't break readers.
81
+ */
82
+ type StoredConsent = {
83
+ /** Schema version. */
84
+ v: 1;
85
+ /** Map of category ID to granted/denied. */
86
+ c: Record<CategoryId, boolean>;
87
+ /** Policy version at the time of choice. */
88
+ pv: string;
89
+ /** Unix epoch milliseconds when the choice was made. */
90
+ ts: number;
91
+ /** Jurisdiction ID at the time of choice. */
92
+ j: JurisdictionId;
93
+ };
94
+ /**
95
+ * A category resolved against the active jurisdiction — what the SDK actually
96
+ * needs to know to render UI and gate scripts.
97
+ */
98
+ type ResolvedCategory = {
99
+ id: CategoryId;
100
+ required: boolean;
101
+ mode: ConsentMode;
102
+ default: boolean;
103
+ vendors: string[];
104
+ description?: string;
105
+ };
106
+
107
+ /**
108
+ * United Kingdom — Data (Use and Access) Act 2025 (DUAA).
109
+ *
110
+ * In force from 5 February 2026. Amends PECR to introduce new exemptions for
111
+ * cookies/storage used solely for statistical, security, authentication, and
112
+ * appearance purposes. Advertising and individual-level tracking still require
113
+ * full opt-in consent.
114
+ *
115
+ * UI requirements (ICO):
116
+ * - "Reject All" must be on the first banner layer
117
+ * - "Accept All" and "Reject All" must have equal visual prominence
118
+ * - GPC is not (yet) mandatory in UK guidance; default off.
119
+ *
120
+ * @see https://ico.org.uk/for-organisations/direct-marketing-and-privacy-and-electronic-communications/guide-to-pecr/cookies-and-similar-technologies/
121
+ */
122
+ declare const UK_DUAA: Jurisdiction;
123
+
124
+ /**
125
+ * European Union — GDPR + ePrivacy Directive ("Cookie Law").
126
+ *
127
+ * EU rules don't have UK DUAA's "statistical purposes" exemption. Even
128
+ * privacy-first first-party analytics (Plausible, Fathom, etc.) are still
129
+ * within scope of the ePrivacy Directive's storage / access provisions, so
130
+ * the conservative position is to require opt-in consent.
131
+ *
132
+ * Some national regulators (notably CNIL in France) take a more permissive
133
+ * view for strictly first-party, aggregated analytics under specific
134
+ * configurations. This preset doesn't try to encode those nuances — it picks
135
+ * the safest pan-EU classification. Override per-vendor in your config if
136
+ * you've assessed a specific vendor under your DPA's guidance.
137
+ *
138
+ * UI requirements (EDPB / national DPAs):
139
+ * - "Reject All" on first banner layer with equal prominence
140
+ * - GPC: not yet mandatory but increasingly recognised. Default off.
141
+ */
142
+ declare const EU_GDPR: Jurisdiction;
143
+
144
+ /**
145
+ * Categorised vendor identifiers used by the built-in jurisdiction presets.
146
+ *
147
+ * The lists are exported so projects can reference them directly:
148
+ *
149
+ * ```ts
150
+ * import { defineConsent, jurisdictions, ADVERTISING_VENDORS } from '@tickboxhq/core'
151
+ *
152
+ * defineConsent({
153
+ * jurisdiction: jurisdictions.UK_DUAA,
154
+ * categories: {
155
+ * marketing: { vendors: [...ADVERTISING_VENDORS] },
156
+ * },
157
+ * })
158
+ * ```
159
+ *
160
+ * Each list is intentionally *descriptive* — adding a vendor here does not
161
+ * automatically apply rules to your site. Your `consent.config.ts` is what
162
+ * declares which vendors you actually use; the jurisdiction preset then
163
+ * decides which ones need consent vs. notice vs. always-allowed.
164
+ */
165
+ /**
166
+ * Privacy-friendly statistical analytics — first-party or near-first-party,
167
+ * aggregated, no individual-level data, no advertising features.
168
+ *
169
+ * Under UK DUAA (PECR exemption from 5 Feb 2026) these qualify for the
170
+ * "statistical purposes" exemption — notice + opt-out is enough, no banner
171
+ * required. Under EU GDPR / ePrivacy these still require consent.
172
+ */
173
+ declare const PRIVACY_FRIENDLY_ANALYTICS: readonly ["plausible", "fathom", "simpleanalytics", "pirsch", "goatcounter", "umami", "tinybird-analytics", "cloudflare-web-analytics"];
174
+ /** Advertising / paid-acquisition pixels and SDKs. Always require consent. */
175
+ declare const ADVERTISING_VENDORS: readonly ["google-ads", "google-analytics", "ga4", "google-tag-manager", "gtm", "meta-pixel", "facebook-pixel", "tiktok-pixel", "linkedin-insight", "twitter-pixel", "x-pixel", "pinterest-tag", "reddit-pixel", "snapchat-pixel", "bing-uet", "microsoft-uet", "criteo", "taboola", "outbrain", "yandex-metrica", "baidu-analytics"];
176
+ /** Session-replay and individual-user fingerprinting. Always require consent. */
177
+ declare const SESSION_REPLAY_VENDORS: readonly ["hotjar", "fullstory", "microsoft-clarity", "mouseflow", "logrocket", "smartlook", "lucky-orange"];
178
+ /**
179
+ * Customer-data platforms and product analytics that send individual events.
180
+ * Always require consent.
181
+ */
182
+ declare const CDP_AND_PRODUCT_ANALYTICS: readonly ["segment", "rudderstack", "mixpanel", "amplitude", "posthog", "heap", "pendo", "june"];
183
+ /**
184
+ * Marketing-automation, CRM and email-marketing platforms with browser
185
+ * tracking. Always require consent.
186
+ */
187
+ declare const MARKETING_AUTOMATION: readonly ["hubspot", "pardot", "marketo", "mailchimp", "klaviyo", "iterable", "activecampaign", "braze", "customer-io", "sendinblue", "brevo"];
188
+ /** Live-chat widgets. Each loads third-party scripts that fingerprint users. */
189
+ declare const CHAT_WIDGETS: readonly ["intercom", "drift", "crisp", "tawk", "livechat", "olark", "tidio", "zendesk-chat"];
190
+ /**
191
+ * AI-training crawlers and LLM-related user-agents.
192
+ *
193
+ * Listed as consent-required so an explicit opt-in toggle decides whether
194
+ * site content can be crawled / used for model training. Pairs with the
195
+ * upcoming `ai_training` category and a future `/ai.txt` / `/llms.txt`
196
+ * generator. EU AI Act Article 53 enforcement starts August 2026.
197
+ */
198
+ declare const AI_TRAINING_CRAWLERS: readonly ["gptbot", "claudebot", "anthropic-ai", "google-extended", "perplexitybot", "ccbot", "bytespider", "applebot-extended", "meta-externalagent", "oai-searchbot"];
199
+ /**
200
+ * Convenience: all known vendor identifiers across all categories.
201
+ * Used by EU_GDPR to classify everything as `consent` in one shot.
202
+ */
203
+ declare const ALL_TRACKING_VENDORS: readonly ["plausible", "fathom", "simpleanalytics", "pirsch", "goatcounter", "umami", "tinybird-analytics", "cloudflare-web-analytics", "google-ads", "google-analytics", "ga4", "google-tag-manager", "gtm", "meta-pixel", "facebook-pixel", "tiktok-pixel", "linkedin-insight", "twitter-pixel", "x-pixel", "pinterest-tag", "reddit-pixel", "snapchat-pixel", "bing-uet", "microsoft-uet", "criteo", "taboola", "outbrain", "yandex-metrica", "baidu-analytics", "hotjar", "fullstory", "microsoft-clarity", "mouseflow", "logrocket", "smartlook", "lucky-orange", "segment", "rudderstack", "mixpanel", "amplitude", "posthog", "heap", "pendo", "june", "hubspot", "pardot", "marketo", "mailchimp", "klaviyo", "iterable", "activecampaign", "braze", "customer-io", "sendinblue", "brevo", "intercom", "drift", "crisp", "tawk", "livechat", "olark", "tidio", "zendesk-chat", "gptbot", "claudebot", "anthropic-ai", "google-extended", "perplexitybot", "ccbot", "bytespider", "applebot-extended", "meta-externalagent", "oai-searchbot"];
204
+
205
+ /**
206
+ * Map of all built-in jurisdiction presets, keyed by their ID for ergonomic
207
+ * lookup: `jurisdictions.UK_DUAA`.
208
+ */
209
+ declare const jurisdictions: {
210
+ readonly UK_DUAA: Jurisdiction;
211
+ readonly EU_GDPR: Jurisdiction;
212
+ };
213
+ /**
214
+ * Resolve a jurisdiction from an ISO 3166-1 alpha-2 country code (e.g. 'GB').
215
+ * Falls back to `EU_GDPR` for any country not explicitly mapped — the safer
216
+ * default for an unknown EEA visitor. Returns `null` when the code is unknown
217
+ * and no fallback is requested.
218
+ */
219
+ declare function resolveJurisdictionByCountry(country: string | undefined, fallback?: Jurisdiction | null): Jurisdiction | null;
220
+
221
+ export { ADVERTISING_VENDORS as A, type ConsentConfig as C, EU_GDPR as E, type Jurisdiction as J, MARKETING_AUTOMATION as M, PRIVACY_FRIENDLY_ANALYTICS as P, type ResolvedCategory as R, type StorageOptions as S, UK_DUAA as U, type StoredConsent as a, type CategoryDefinition as b, type CategoryId as c, type ConsentMode as d, type JurisdictionId as e, AI_TRAINING_CRAWLERS as f, ALL_TRACKING_VENDORS as g, CDP_AND_PRODUCT_ANALYTICS as h, CHAT_WIDGETS as i, jurisdictions as j, SESSION_REPLAY_VENDORS as k, resolveJurisdictionByCountry as r };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as ResolvedCategory, C as ConsentConfig, S as StorageOptions, J as Jurisdiction, a as StoredConsent } from './index-D_Xt5NFB.js';
2
- export { b as CategoryDefinition, c as CategoryId, d as ConsentMode, e as JurisdictionId, j as jurisdictions, r as resolveJurisdictionByCountry } from './index-D_Xt5NFB.js';
1
+ import { R as ResolvedCategory, C as ConsentConfig, S as StorageOptions, J as Jurisdiction, a as StoredConsent } from './index-C1gN-xur.js';
2
+ export { b as CategoryDefinition, c as CategoryId, d as ConsentMode, e as JurisdictionId, j as jurisdictions, r as resolveJurisdictionByCountry } from './index-C1gN-xur.js';
3
3
 
4
4
  type ConsentState = {
5
5
  /** True after the store has hydrated from the cookie (client-only). */
package/dist/index.js CHANGED
@@ -57,11 +57,109 @@ function isGPCSignaled() {
57
57
  return navigator.globalPrivacyControl === true;
58
58
  }
59
59
 
60
+ // src/jurisdictions/vendors.ts
61
+ var PRIVACY_FRIENDLY_ANALYTICS = [
62
+ "plausible",
63
+ "fathom",
64
+ "simpleanalytics",
65
+ "pirsch",
66
+ "goatcounter",
67
+ "umami",
68
+ "tinybird-analytics",
69
+ "cloudflare-web-analytics"
70
+ ];
71
+ var ADVERTISING_VENDORS = [
72
+ "google-ads",
73
+ "google-analytics",
74
+ "ga4",
75
+ "google-tag-manager",
76
+ "gtm",
77
+ "meta-pixel",
78
+ "facebook-pixel",
79
+ "tiktok-pixel",
80
+ "linkedin-insight",
81
+ "twitter-pixel",
82
+ "x-pixel",
83
+ "pinterest-tag",
84
+ "reddit-pixel",
85
+ "snapchat-pixel",
86
+ "bing-uet",
87
+ "microsoft-uet",
88
+ "criteo",
89
+ "taboola",
90
+ "outbrain",
91
+ "yandex-metrica",
92
+ "baidu-analytics"
93
+ ];
94
+ var SESSION_REPLAY_VENDORS = [
95
+ "hotjar",
96
+ "fullstory",
97
+ "microsoft-clarity",
98
+ "mouseflow",
99
+ "logrocket",
100
+ "smartlook",
101
+ "lucky-orange"
102
+ ];
103
+ var CDP_AND_PRODUCT_ANALYTICS = [
104
+ "segment",
105
+ "rudderstack",
106
+ "mixpanel",
107
+ "amplitude",
108
+ "posthog",
109
+ "heap",
110
+ "pendo",
111
+ "june"
112
+ ];
113
+ var MARKETING_AUTOMATION = [
114
+ "hubspot",
115
+ "pardot",
116
+ "marketo",
117
+ "mailchimp",
118
+ "klaviyo",
119
+ "iterable",
120
+ "activecampaign",
121
+ "braze",
122
+ "customer-io",
123
+ "sendinblue",
124
+ "brevo"
125
+ ];
126
+ var CHAT_WIDGETS = [
127
+ "intercom",
128
+ "drift",
129
+ "crisp",
130
+ "tawk",
131
+ "livechat",
132
+ "olark",
133
+ "tidio",
134
+ "zendesk-chat"
135
+ ];
136
+ var AI_TRAINING_CRAWLERS = [
137
+ "gptbot",
138
+ "claudebot",
139
+ "anthropic-ai",
140
+ "google-extended",
141
+ "perplexitybot",
142
+ "ccbot",
143
+ "bytespider",
144
+ "applebot-extended",
145
+ "meta-externalagent",
146
+ "oai-searchbot"
147
+ ];
148
+ var ALL_TRACKING_VENDORS = [
149
+ ...PRIVACY_FRIENDLY_ANALYTICS,
150
+ ...ADVERTISING_VENDORS,
151
+ ...SESSION_REPLAY_VENDORS,
152
+ ...CDP_AND_PRODUCT_ANALYTICS,
153
+ ...MARKETING_AUTOMATION,
154
+ ...CHAT_WIDGETS,
155
+ ...AI_TRAINING_CRAWLERS
156
+ ];
157
+
60
158
  // src/jurisdictions/eu-gdpr.ts
61
159
  var EU_GDPR = {
62
160
  id: "EU_GDPR",
63
161
  name: "European Union (GDPR / ePrivacy)",
64
- vendorRules: {},
162
+ vendorRules: Object.fromEntries(ALL_TRACKING_VENDORS.map((v) => [v, "consent"])),
65
163
  defaultMode: "consent",
66
164
  ui: {
67
165
  rejectButtonOnFirstLayer: true,
@@ -104,57 +202,20 @@ var EU_GDPR = {
104
202
  };
105
203
 
106
204
  // src/jurisdictions/uk-duaa.ts
107
- var DUAA_STATISTICAL_VENDORS = [
108
- "plausible",
109
- "fathom",
110
- "simpleanalytics",
111
- "pirsch",
112
- "goatcounter",
113
- "umami",
114
- "tinybird-analytics",
115
- "cloudflare-web-analytics"
116
- ];
117
- var DUAA_CONSENT_REQUIRED_VENDORS = [
118
- // Advertising
119
- "google-ads",
120
- "google-analytics",
121
- "ga4",
122
- "meta-pixel",
123
- "facebook-pixel",
124
- "tiktok-pixel",
125
- "linkedin-insight",
126
- "twitter-pixel",
127
- "pinterest-tag",
128
- "reddit-pixel",
129
- // Session replay / individual tracking
130
- "hotjar",
131
- "fullstory",
132
- "microsoft-clarity",
133
- "mouseflow",
134
- "logrocket",
135
- // CDPs / marketing automation
136
- "segment",
137
- "rudderstack",
138
- "hubspot",
139
- "mixpanel",
140
- "amplitude",
141
- // AI training crawlers (always require explicit opt-in/out)
142
- "gptbot",
143
- "claudebot",
144
- "anthropic-ai",
145
- "google-extended",
146
- "perplexitybot",
147
- "ccbot",
148
- "bytespider",
149
- "applebot-extended"
150
- ];
151
205
  var UK_DUAA = {
152
206
  id: "UK_DUAA",
153
207
  name: "United Kingdom (Data (Use and Access) Act 2025)",
154
- vendorRules: {
155
- ...Object.fromEntries(DUAA_STATISTICAL_VENDORS.map((v) => [v, "notice"])),
156
- ...Object.fromEntries(DUAA_CONSENT_REQUIRED_VENDORS.map((v) => [v, "consent"]))
157
- },
208
+ vendorRules: classify({
209
+ notice: PRIVACY_FRIENDLY_ANALYTICS,
210
+ consent: [
211
+ ...ADVERTISING_VENDORS,
212
+ ...SESSION_REPLAY_VENDORS,
213
+ ...CDP_AND_PRODUCT_ANALYTICS,
214
+ ...MARKETING_AUTOMATION,
215
+ ...CHAT_WIDGETS,
216
+ ...AI_TRAINING_CRAWLERS
217
+ ]
218
+ }),
158
219
  defaultMode: "consent",
159
220
  ui: {
160
221
  rejectButtonOnFirstLayer: true,
@@ -163,6 +224,13 @@ var UK_DUAA = {
163
224
  },
164
225
  countries: ["GB"]
165
226
  };
227
+ function classify(buckets) {
228
+ const result = {};
229
+ for (const v of buckets.always ?? []) result[v] = "always";
230
+ for (const v of buckets.notice ?? []) result[v] = "notice";
231
+ for (const v of buckets.consent ?? []) result[v] = "consent";
232
+ return result;
233
+ }
166
234
 
167
235
  // src/jurisdictions/index.ts
168
236
  var jurisdictions = {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/apply.ts","../src/define-consent.ts","../src/gpc.ts","../src/jurisdictions/eu-gdpr.ts","../src/jurisdictions/uk-duaa.ts","../src/jurisdictions/index.ts","../src/resolve.ts","../src/storage.ts","../src/store.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { ConsentState } from './store.js'\n\n/**\n * Element attribute used by Tickbox-aware scripts to declare their category.\n *\n * @example\n * ```html\n * <script type=\"text/plain\" data-tb-category=\"analytics\" src=\"plausible.js\"></script>\n * ```\n *\n * On grant, the SDK rewrites `type` to `text/javascript` so the browser executes the script.\n * On deny, the script is left as `text/plain` (browser ignores it).\n */\nexport const TAG_ATTRIBUTE = 'data-tb-category'\n\n/**\n * Apply a consent state to the document by:\n * 1. Activating any `<script type=\"text/plain\" data-tb-category=\"X\">` whose category was granted\n * 2. Calling `gtag('consent', 'update', ...)` if `gtag` is on the global scope\n * 3. Dispatching a `tickbox:consent-changed` CustomEvent for any custom integrations\n *\n * No-op on the server.\n */\nexport function applyConsent(state: ConsentState): void {\n if (typeof document === 'undefined') return\n activateScripts(state.decisions)\n updateConsentMode(state.decisions)\n dispatchEvent(state)\n}\n\nfunction activateScripts(decisions: Record<string, boolean>): void {\n const blocked = document.querySelectorAll(`script[type=\"text/plain\"][${TAG_ATTRIBUTE}]`)\n for (const node of Array.from(blocked)) {\n const category = node.getAttribute(TAG_ATTRIBUTE)\n if (!category || !decisions[category]) continue\n const replacement = document.createElement('script')\n for (const attr of Array.from(node.attributes)) {\n if (attr.name === 'type') continue\n replacement.setAttribute(attr.name, attr.value)\n }\n replacement.text = node.textContent ?? ''\n node.parentNode?.replaceChild(replacement, node)\n }\n}\n\ntype Gtag = (cmd: 'consent', action: 'update', params: Record<string, 'granted' | 'denied'>) => void\n\nfunction updateConsentMode(decisions: Record<string, boolean>): void {\n const win = globalThis as unknown as { gtag?: Gtag }\n if (typeof win.gtag !== 'function') return\n win.gtag('consent', 'update', {\n ad_storage: gv(decisions, 'marketing'),\n ad_user_data: gv(decisions, 'marketing'),\n ad_personalization: gv(decisions, 'marketing'),\n analytics_storage: gv(decisions, 'analytics'),\n functionality_storage: gv(decisions, 'functional', true),\n personalization_storage: gv(decisions, 'preferences', true),\n security_storage: 'granted',\n })\n}\n\nfunction gv(\n decisions: Record<string, boolean>,\n id: string,\n defaultGranted = false,\n): 'granted' | 'denied' {\n const value = decisions[id]\n if (value === undefined) return defaultGranted ? 'granted' : 'denied'\n return value ? 'granted' : 'denied'\n}\n\nfunction dispatchEvent(state: ConsentState): void {\n document.dispatchEvent(\n new CustomEvent('tickbox:consent-changed', {\n detail: { decisions: state.decisions, ts: state.storedAt },\n }),\n )\n}\n","import type { ConsentConfig } from './types.js'\n\n/**\n * Identity helper that narrows the type of a consent config so users get\n * full autocomplete + type-checking in their `consent.config.ts`.\n *\n * @example\n * ```ts\n * import { defineConsent, jurisdictions } from '@tickboxhq/core'\n *\n * export default defineConsent({\n * jurisdiction: jurisdictions.UK_DUAA,\n * categories: {\n * necessary: { required: true },\n * analytics: { vendors: ['plausible'] },\n * },\n * })\n * ```\n */\nexport function defineConsent<const T extends ConsentConfig>(config: T): T {\n return config\n}\n","/**\n * Detect a Global Privacy Control signal from the visitor's browser.\n *\n * GPC is exposed as `navigator.globalPrivacyControl` (boolean) and the\n * `Sec-GPC: 1` HTTP header. The header is server-side only; this helper\n * covers the client-side property.\n *\n * @see https://globalprivacycontrol.org/\n */\nexport function isGPCSignaled(): boolean {\n if (typeof navigator === 'undefined') return false\n return (navigator as Navigator & { globalPrivacyControl?: boolean }).globalPrivacyControl === true\n}\n","import type { Jurisdiction } from '../types.js'\n\n/**\n * European Union — GDPR + ePrivacy Directive (\"Cookie Law\").\n *\n * EU rules don't have the DUAA \"statistical exemption\" — analytics that\n * involve client-side storage on a user's device generally require opt-in\n * consent, even for first-party privacy-friendly tools (positions vary by\n * DPA; CNIL has been more permissive than others). This preset takes the\n * conservative position: treat all tracking categories as consent-required.\n *\n * UI requirements (EDPB / national DPAs):\n * - \"Reject All\" on first banner layer with equal prominence\n * - GPC: not yet mandatory but increasingly recognised\n */\nexport const EU_GDPR: Jurisdiction = {\n id: 'EU_GDPR',\n name: 'European Union (GDPR / ePrivacy)',\n vendorRules: {},\n defaultMode: 'consent',\n ui: {\n rejectButtonOnFirstLayer: true,\n equalProminence: true,\n honorGPC: false,\n },\n countries: [\n 'AT',\n 'BE',\n 'BG',\n 'HR',\n 'CY',\n 'CZ',\n 'DK',\n 'EE',\n 'FI',\n 'FR',\n 'DE',\n 'GR',\n 'HU',\n 'IE',\n 'IT',\n 'LV',\n 'LT',\n 'LU',\n 'MT',\n 'NL',\n 'PL',\n 'PT',\n 'RO',\n 'SK',\n 'SI',\n 'ES',\n 'SE',\n // EEA additions\n 'IS',\n 'LI',\n 'NO',\n ],\n}\n","import type { Jurisdiction } from '../types.js'\n\n/**\n * Vendors classified as eligible for the DUAA \"statistical purposes\" exemption:\n * privacy-first analytics with aggregated, non-identifying data and no ad features.\n *\n * These do **not** require consent under the UK Data (Use and Access) Act 2025\n * but still require clear notice and an easy way to object.\n *\n * Treat the list as a starting position; specific deployments may still need\n * consent depending on configuration (e.g. session replay, cross-domain tracking).\n */\nconst DUAA_STATISTICAL_VENDORS = [\n 'plausible',\n 'fathom',\n 'simpleanalytics',\n 'pirsch',\n 'goatcounter',\n 'umami',\n 'tinybird-analytics',\n 'cloudflare-web-analytics',\n] as const\n\n/**\n * Vendors that require full opt-in consent under DUAA — anything that touches\n * advertising, individual-level tracking, session replay, or cross-site profiles.\n */\nconst DUAA_CONSENT_REQUIRED_VENDORS = [\n // Advertising\n 'google-ads',\n 'google-analytics',\n 'ga4',\n 'meta-pixel',\n 'facebook-pixel',\n 'tiktok-pixel',\n 'linkedin-insight',\n 'twitter-pixel',\n 'pinterest-tag',\n 'reddit-pixel',\n // Session replay / individual tracking\n 'hotjar',\n 'fullstory',\n 'microsoft-clarity',\n 'mouseflow',\n 'logrocket',\n // CDPs / marketing automation\n 'segment',\n 'rudderstack',\n 'hubspot',\n 'mixpanel',\n 'amplitude',\n // AI training crawlers (always require explicit opt-in/out)\n 'gptbot',\n 'claudebot',\n 'anthropic-ai',\n 'google-extended',\n 'perplexitybot',\n 'ccbot',\n 'bytespider',\n 'applebot-extended',\n] as const\n\n/**\n * United Kingdom — Data (Use and Access) Act 2025 (DUAA).\n *\n * In force from 5 February 2026. Amends PECR to introduce new exemptions for\n * cookies/storage used solely for statistical, security, authentication, and\n * appearance purposes. Advertising and individual-level tracking still require\n * full opt-in consent.\n *\n * UI requirements (ICO):\n * - \"Reject All\" must be on the first banner layer\n * - \"Accept All\" and \"Reject All\" must have equal visual prominence\n * - GPC is not (yet) mandatory in UK guidance; default off.\n *\n * @see https://ico.org.uk/for-organisations/direct-marketing-and-privacy-and-electronic-communications/guide-to-pecr/cookies-and-similar-technologies/\n */\nexport const UK_DUAA: Jurisdiction = {\n id: 'UK_DUAA',\n name: 'United Kingdom (Data (Use and Access) Act 2025)',\n vendorRules: {\n ...Object.fromEntries(DUAA_STATISTICAL_VENDORS.map((v) => [v, 'notice' as const])),\n ...Object.fromEntries(DUAA_CONSENT_REQUIRED_VENDORS.map((v) => [v, 'consent' as const])),\n },\n defaultMode: 'consent',\n ui: {\n rejectButtonOnFirstLayer: true,\n equalProminence: true,\n honorGPC: false,\n },\n countries: ['GB'],\n}\n","import type { Jurisdiction } from '../types.js'\nimport { EU_GDPR } from './eu-gdpr.js'\nimport { UK_DUAA } from './uk-duaa.js'\n\nexport { UK_DUAA } from './uk-duaa.js'\nexport { EU_GDPR } from './eu-gdpr.js'\n\n/**\n * Map of all built-in jurisdiction presets, keyed by their ID for ergonomic\n * lookup: `jurisdictions.UK_DUAA`.\n */\nexport const jurisdictions = {\n UK_DUAA,\n EU_GDPR,\n} as const\n\n/**\n * Resolve a jurisdiction from an ISO 3166-1 alpha-2 country code (e.g. 'GB').\n * Falls back to `EU_GDPR` for any country not explicitly mapped — the safer\n * default for an unknown EEA visitor. Returns `null` when the code is unknown\n * and no fallback is requested.\n */\nexport function resolveJurisdictionByCountry(\n country: string | undefined,\n fallback: Jurisdiction | null = EU_GDPR,\n): Jurisdiction | null {\n if (!country) return fallback\n const upper = country.toUpperCase()\n for (const j of Object.values(jurisdictions)) {\n if (j.countries?.includes(upper)) return j\n }\n return fallback\n}\n","import type { ConsentConfig, ConsentMode, Jurisdiction, ResolvedCategory } from './types.js'\n\n/**\n * Resolve each declared category against the active jurisdiction's vendor rules.\n *\n * For each category, the most-restrictive vendor mode wins:\n * `consent` > `notice` > `always`\n *\n * Categories with no vendors fall back to the jurisdiction's default mode,\n * unless `required: true` (always allowed) or an explicit `mode` override is set.\n */\nexport function resolveCategories(\n config: ConsentConfig,\n jurisdiction: Jurisdiction,\n): ResolvedCategory[] {\n return Object.entries(config.categories).map(([id, def]) => {\n const required = def.required === true\n const explicit = def.mode\n const vendors = def.vendors ?? []\n\n let mode: ConsentMode\n if (required) {\n mode = 'always'\n } else if (explicit) {\n mode = explicit\n } else if (vendors.length === 0) {\n mode = jurisdiction.defaultMode\n } else {\n mode = mostRestrictive(\n vendors.map((v) => jurisdiction.vendorRules[v] ?? jurisdiction.defaultMode),\n )\n }\n\n return {\n id,\n required,\n mode,\n default: required ? true : (def.default ?? false),\n vendors,\n description: def.description,\n }\n })\n}\n\nconst ORDER: Record<ConsentMode, number> = { always: 0, notice: 1, consent: 2 }\n\nfunction mostRestrictive(modes: ConsentMode[]): ConsentMode {\n let winner: ConsentMode = 'always'\n for (const m of modes) {\n if (ORDER[m] > ORDER[winner]) winner = m\n }\n return winner\n}\n","import type { StorageOptions, StoredConsent } from './types.js'\n\nconst DEFAULT_COOKIE_NAME = '__tb_consent'\nconst DEFAULT_MAX_AGE_DAYS = 365\n\n/**\n * Read the stored consent record from `document.cookie`.\n * Returns `null` on the server, when no cookie is set, or when the cookie is malformed.\n */\nexport function readConsent(options: StorageOptions = {}): StoredConsent | null {\n if (typeof document === 'undefined') return null\n return parseConsentFromHeader(document.cookie, options)\n}\n\n/**\n * Parse a stored consent record from a raw `Cookie` header string.\n * Useful on the server: pass the request's `cookie` header.\n * Returns `null` when the cookie isn't present or is malformed.\n */\nexport function parseConsentFromHeader(\n cookieHeader: string | undefined,\n options: StorageOptions = {},\n): StoredConsent | null {\n if (!cookieHeader) return null\n const name = options.cookieName ?? DEFAULT_COOKIE_NAME\n const match = cookieHeader.match(new RegExp(`(?:^|; )${name}=([^;]+)`))\n if (!match) return null\n try {\n const parsed = JSON.parse(decodeURIComponent(match[1]!)) as unknown\n if (isStoredConsent(parsed)) return parsed\n return null\n } catch {\n return null\n }\n}\n\n/**\n * Persist a consent record to `document.cookie`.\n * No-op on the server.\n */\nexport function writeConsent(value: StoredConsent, options: StorageOptions = {}): void {\n if (typeof document === 'undefined') return\n const name = options.cookieName ?? DEFAULT_COOKIE_NAME\n const maxAge = (options.maxAgeDays ?? DEFAULT_MAX_AGE_DAYS) * 86_400\n const domain = options.domain ? `; Domain=${options.domain}` : ''\n const secure = typeof location !== 'undefined' && location.protocol === 'https:' ? '; Secure' : ''\n const encoded = encodeURIComponent(JSON.stringify(value))\n document.cookie = `${name}=${encoded}; Path=/; Max-Age=${maxAge}; SameSite=Lax${secure}${domain}`\n}\n\n/** Clear the stored consent cookie. */\nexport function clearConsent(options: StorageOptions = {}): void {\n if (typeof document === 'undefined') return\n const name = options.cookieName ?? DEFAULT_COOKIE_NAME\n const domain = options.domain ? `; Domain=${options.domain}` : ''\n document.cookie = `${name}=; Path=/; Max-Age=0${domain}`\n}\n\nfunction isStoredConsent(value: unknown): value is StoredConsent {\n if (typeof value !== 'object' || value === null) return false\n const v = value as Record<string, unknown>\n return (\n v.v === 1 &&\n typeof v.c === 'object' &&\n v.c !== null &&\n typeof v.pv === 'string' &&\n typeof v.ts === 'number' &&\n typeof v.j === 'string'\n )\n}\n","import { resolveCategories } from './resolve.js'\nimport { parseConsentFromHeader, readConsent, writeConsent } from './storage.js'\nimport type {\n ConsentConfig,\n Jurisdiction,\n ResolvedCategory,\n StorageOptions,\n StoredConsent,\n} from './types.js'\n\nexport type ConsentState = {\n /** True after the store has hydrated from the cookie (client-only). */\n ready: boolean\n /** True when the banner / preference centre should be visible. */\n isOpen: boolean\n /** Map of category ID → granted (true) / denied (false). */\n decisions: Record<string, boolean>\n /** Resolved categories for the active jurisdiction. */\n resolved: ResolvedCategory[]\n /** Timestamp of the most-recent stored decision, if any. */\n storedAt: number | null\n}\n\ntype Listener = (state: ConsentState) => void\n\nexport type StoreOptions = {\n /** Storage options forwarded to the cookie reader/writer. */\n storage?: StorageOptions\n /** When `true`, side-effects like script rewriting fire on state changes. Defaults to true. */\n applyEffects?: boolean\n /** Custom side-effect handler. Receives `(state, resolved)` whenever decisions change. */\n onApply?: (state: ConsentState) => void\n /** Active jurisdiction. Required — pass `config.jurisdiction` after resolving 'auto'. */\n jurisdiction: Jurisdiction\n}\n\n/**\n * Framework-agnostic consent state machine.\n *\n * The store hydrates from the cookie on first read, keeps decisions in memory,\n * and broadcasts changes to subscribers. Adapters (`@tickboxhq/react`,\n * `@tickboxhq/vue`) bind to it via their idiomatic reactivity primitive.\n */\nexport class ConsentStore {\n private state: ConsentState\n private readonly listeners = new Set<Listener>()\n private readonly config: ConsentConfig\n private readonly options: StoreOptions\n\n constructor(config: ConsentConfig, options: StoreOptions) {\n this.config = config\n this.options = options\n const resolved = resolveCategories(config, options.jurisdiction)\n this.state = {\n ready: false,\n isOpen: false,\n decisions: defaultDecisions(resolved),\n resolved,\n storedAt: null,\n }\n }\n\n /**\n * Read the stored cookie and update state. Safe to call on the server\n * (no-op when `document` is unavailable). Call from a mount effect.\n */\n hydrate(): void {\n const stored = readConsent(this.options.storage)\n this.applyHydration(stored)\n }\n\n /**\n * Hydrate from a raw Cookie header — for server-side rendering.\n * Pass the value of the request's `cookie` header (or `undefined` if absent).\n */\n hydrateFromHeader(cookieHeader: string | undefined): void {\n const stored = parseConsentFromHeader(cookieHeader, this.options.storage)\n this.applyHydration(stored)\n }\n\n private applyHydration(stored: StoredConsent | null): void {\n if (stored) {\n this.state = {\n ...this.state,\n ready: true,\n isOpen: needsRefresh(stored, this.config),\n decisions: mergeDecisions(this.state.resolved, stored.c),\n storedAt: stored.ts,\n }\n } else {\n this.state = {\n ...this.state,\n ready: true,\n isOpen: shouldShowBanner(this.state.resolved),\n }\n }\n this.emit()\n }\n\n getState(): ConsentState {\n return this.state\n }\n\n subscribe(fn: Listener): () => void {\n this.listeners.add(fn)\n return () => {\n this.listeners.delete(fn)\n }\n }\n\n grant(id: string): void {\n this.update({ [id]: true })\n }\n\n deny(id: string): void {\n if (this.isRequired(id)) return\n this.update({ [id]: false })\n }\n\n grantAll(): void {\n const next: Record<string, boolean> = {}\n for (const r of this.state.resolved) next[r.id] = true\n this.update(next, { close: true })\n }\n\n denyAll(): void {\n const next: Record<string, boolean> = {}\n for (const r of this.state.resolved) next[r.id] = r.required\n this.update(next, { close: true })\n }\n\n /** Persist the current decisions and close the banner. */\n save(): void {\n const ts = this.persist(this.state.decisions)\n this.state = { ...this.state, isOpen: false, storedAt: ts }\n this.emit()\n }\n\n open(): void {\n if (this.state.isOpen) return\n this.state = { ...this.state, isOpen: true }\n this.emit()\n }\n\n close(): void {\n if (!this.state.isOpen) return\n this.state = { ...this.state, isOpen: false }\n this.emit()\n }\n\n /** Wipe stored consent and reopen the banner. */\n reset(): void {\n this.state = {\n ...this.state,\n decisions: defaultDecisions(this.state.resolved),\n isOpen: true,\n storedAt: null,\n }\n this.emit()\n }\n\n isRequired(id: string): boolean {\n return this.state.resolved.find((r) => r.id === id)?.required === true\n }\n\n private update(partial: Record<string, boolean>, opts: { close?: boolean } = {}): void {\n const next = { ...this.state.decisions, ...partial }\n const ts = this.persist(next)\n this.state = {\n ...this.state,\n decisions: next,\n isOpen: opts.close ? false : this.state.isOpen,\n storedAt: ts,\n }\n this.emit()\n }\n\n private persist(decisions: Record<string, boolean>): number {\n const ts = Date.now()\n const stored: StoredConsent = {\n v: 1,\n c: decisions,\n pv: this.config.policy?.version ?? '0',\n ts,\n j: this.options.jurisdiction.id,\n }\n writeConsent(stored, this.options.storage)\n return ts\n }\n\n private emit(): void {\n if (this.options.applyEffects !== false) {\n this.options.onApply?.(this.state)\n }\n for (const fn of this.listeners) fn(this.state)\n }\n}\n\nfunction defaultDecisions(resolved: ResolvedCategory[]): Record<string, boolean> {\n const out: Record<string, boolean> = {}\n for (const r of resolved) out[r.id] = r.required ? true : r.default\n return out\n}\n\nfunction mergeDecisions(\n resolved: ResolvedCategory[],\n stored: Record<string, boolean>,\n): Record<string, boolean> {\n const out: Record<string, boolean> = {}\n for (const r of resolved) {\n if (r.required) {\n out[r.id] = true\n } else if (stored[r.id] !== undefined) {\n out[r.id] = stored[r.id]!\n } else {\n out[r.id] = r.default\n }\n }\n return out\n}\n\nfunction needsRefresh(stored: StoredConsent, config: ConsentConfig): boolean {\n const declared = config.policy?.version\n if (!declared) return false\n return stored.pv !== declared\n}\n\nfunction shouldShowBanner(resolved: ResolvedCategory[]): boolean {\n return resolved.some((r) => r.mode === 'consent' && !r.required)\n}\n"]}
1
+ {"version":3,"sources":["../src/apply.ts","../src/define-consent.ts","../src/gpc.ts","../src/jurisdictions/vendors.ts","../src/jurisdictions/eu-gdpr.ts","../src/jurisdictions/uk-duaa.ts","../src/jurisdictions/index.ts","../src/resolve.ts","../src/storage.ts","../src/store.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { ConsentState } from './store.js'\n\n/**\n * Element attribute used by Tickbox-aware scripts to declare their category.\n *\n * @example\n * ```html\n * <script type=\"text/plain\" data-tb-category=\"analytics\" src=\"plausible.js\"></script>\n * ```\n *\n * On grant, the SDK rewrites `type` to `text/javascript` so the browser executes the script.\n * On deny, the script is left as `text/plain` (browser ignores it).\n */\nexport const TAG_ATTRIBUTE = 'data-tb-category'\n\n/**\n * Apply a consent state to the document by:\n * 1. Activating any `<script type=\"text/plain\" data-tb-category=\"X\">` whose category was granted\n * 2. Calling `gtag('consent', 'update', ...)` if `gtag` is on the global scope\n * 3. Dispatching a `tickbox:consent-changed` CustomEvent for any custom integrations\n *\n * No-op on the server.\n */\nexport function applyConsent(state: ConsentState): void {\n if (typeof document === 'undefined') return\n activateScripts(state.decisions)\n updateConsentMode(state.decisions)\n dispatchEvent(state)\n}\n\nfunction activateScripts(decisions: Record<string, boolean>): void {\n const blocked = document.querySelectorAll(`script[type=\"text/plain\"][${TAG_ATTRIBUTE}]`)\n for (const node of Array.from(blocked)) {\n const category = node.getAttribute(TAG_ATTRIBUTE)\n if (!category || !decisions[category]) continue\n const replacement = document.createElement('script')\n for (const attr of Array.from(node.attributes)) {\n if (attr.name === 'type') continue\n replacement.setAttribute(attr.name, attr.value)\n }\n replacement.text = node.textContent ?? ''\n node.parentNode?.replaceChild(replacement, node)\n }\n}\n\ntype Gtag = (cmd: 'consent', action: 'update', params: Record<string, 'granted' | 'denied'>) => void\n\nfunction updateConsentMode(decisions: Record<string, boolean>): void {\n const win = globalThis as unknown as { gtag?: Gtag }\n if (typeof win.gtag !== 'function') return\n win.gtag('consent', 'update', {\n ad_storage: gv(decisions, 'marketing'),\n ad_user_data: gv(decisions, 'marketing'),\n ad_personalization: gv(decisions, 'marketing'),\n analytics_storage: gv(decisions, 'analytics'),\n functionality_storage: gv(decisions, 'functional', true),\n personalization_storage: gv(decisions, 'preferences', true),\n security_storage: 'granted',\n })\n}\n\nfunction gv(\n decisions: Record<string, boolean>,\n id: string,\n defaultGranted = false,\n): 'granted' | 'denied' {\n const value = decisions[id]\n if (value === undefined) return defaultGranted ? 'granted' : 'denied'\n return value ? 'granted' : 'denied'\n}\n\nfunction dispatchEvent(state: ConsentState): void {\n document.dispatchEvent(\n new CustomEvent('tickbox:consent-changed', {\n detail: { decisions: state.decisions, ts: state.storedAt },\n }),\n )\n}\n","import type { ConsentConfig } from './types.js'\n\n/**\n * Identity helper that narrows the type of a consent config so users get\n * full autocomplete + type-checking in their `consent.config.ts`.\n *\n * @example\n * ```ts\n * import { defineConsent, jurisdictions } from '@tickboxhq/core'\n *\n * export default defineConsent({\n * jurisdiction: jurisdictions.UK_DUAA,\n * categories: {\n * necessary: { required: true },\n * analytics: { vendors: ['plausible'] },\n * },\n * })\n * ```\n */\nexport function defineConsent<const T extends ConsentConfig>(config: T): T {\n return config\n}\n","/**\n * Detect a Global Privacy Control signal from the visitor's browser.\n *\n * GPC is exposed as `navigator.globalPrivacyControl` (boolean) and the\n * `Sec-GPC: 1` HTTP header. The header is server-side only; this helper\n * covers the client-side property.\n *\n * @see https://globalprivacycontrol.org/\n */\nexport function isGPCSignaled(): boolean {\n if (typeof navigator === 'undefined') return false\n return (navigator as Navigator & { globalPrivacyControl?: boolean }).globalPrivacyControl === true\n}\n","/**\n * Categorised vendor identifiers used by the built-in jurisdiction presets.\n *\n * The lists are exported so projects can reference them directly:\n *\n * ```ts\n * import { defineConsent, jurisdictions, ADVERTISING_VENDORS } from '@tickboxhq/core'\n *\n * defineConsent({\n * jurisdiction: jurisdictions.UK_DUAA,\n * categories: {\n * marketing: { vendors: [...ADVERTISING_VENDORS] },\n * },\n * })\n * ```\n *\n * Each list is intentionally *descriptive* — adding a vendor here does not\n * automatically apply rules to your site. Your `consent.config.ts` is what\n * declares which vendors you actually use; the jurisdiction preset then\n * decides which ones need consent vs. notice vs. always-allowed.\n */\n\n/**\n * Privacy-friendly statistical analytics — first-party or near-first-party,\n * aggregated, no individual-level data, no advertising features.\n *\n * Under UK DUAA (PECR exemption from 5 Feb 2026) these qualify for the\n * \"statistical purposes\" exemption — notice + opt-out is enough, no banner\n * required. Under EU GDPR / ePrivacy these still require consent.\n */\nexport const PRIVACY_FRIENDLY_ANALYTICS = [\n 'plausible',\n 'fathom',\n 'simpleanalytics',\n 'pirsch',\n 'goatcounter',\n 'umami',\n 'tinybird-analytics',\n 'cloudflare-web-analytics',\n] as const\n\n/** Advertising / paid-acquisition pixels and SDKs. Always require consent. */\nexport const ADVERTISING_VENDORS = [\n 'google-ads',\n 'google-analytics',\n 'ga4',\n 'google-tag-manager',\n 'gtm',\n 'meta-pixel',\n 'facebook-pixel',\n 'tiktok-pixel',\n 'linkedin-insight',\n 'twitter-pixel',\n 'x-pixel',\n 'pinterest-tag',\n 'reddit-pixel',\n 'snapchat-pixel',\n 'bing-uet',\n 'microsoft-uet',\n 'criteo',\n 'taboola',\n 'outbrain',\n 'yandex-metrica',\n 'baidu-analytics',\n] as const\n\n/** Session-replay and individual-user fingerprinting. Always require consent. */\nexport const SESSION_REPLAY_VENDORS = [\n 'hotjar',\n 'fullstory',\n 'microsoft-clarity',\n 'mouseflow',\n 'logrocket',\n 'smartlook',\n 'lucky-orange',\n] as const\n\n/**\n * Customer-data platforms and product analytics that send individual events.\n * Always require consent.\n */\nexport const CDP_AND_PRODUCT_ANALYTICS = [\n 'segment',\n 'rudderstack',\n 'mixpanel',\n 'amplitude',\n 'posthog',\n 'heap',\n 'pendo',\n 'june',\n] as const\n\n/**\n * Marketing-automation, CRM and email-marketing platforms with browser\n * tracking. Always require consent.\n */\nexport const MARKETING_AUTOMATION = [\n 'hubspot',\n 'pardot',\n 'marketo',\n 'mailchimp',\n 'klaviyo',\n 'iterable',\n 'activecampaign',\n 'braze',\n 'customer-io',\n 'sendinblue',\n 'brevo',\n] as const\n\n/** Live-chat widgets. Each loads third-party scripts that fingerprint users. */\nexport const CHAT_WIDGETS = [\n 'intercom',\n 'drift',\n 'crisp',\n 'tawk',\n 'livechat',\n 'olark',\n 'tidio',\n 'zendesk-chat',\n] as const\n\n/**\n * AI-training crawlers and LLM-related user-agents.\n *\n * Listed as consent-required so an explicit opt-in toggle decides whether\n * site content can be crawled / used for model training. Pairs with the\n * upcoming `ai_training` category and a future `/ai.txt` / `/llms.txt`\n * generator. EU AI Act Article 53 enforcement starts August 2026.\n */\nexport const AI_TRAINING_CRAWLERS = [\n 'gptbot',\n 'claudebot',\n 'anthropic-ai',\n 'google-extended',\n 'perplexitybot',\n 'ccbot',\n 'bytespider',\n 'applebot-extended',\n 'meta-externalagent',\n 'oai-searchbot',\n] as const\n\n/**\n * Convenience: all known vendor identifiers across all categories.\n * Used by EU_GDPR to classify everything as `consent` in one shot.\n */\nexport const ALL_TRACKING_VENDORS = [\n ...PRIVACY_FRIENDLY_ANALYTICS,\n ...ADVERTISING_VENDORS,\n ...SESSION_REPLAY_VENDORS,\n ...CDP_AND_PRODUCT_ANALYTICS,\n ...MARKETING_AUTOMATION,\n ...CHAT_WIDGETS,\n ...AI_TRAINING_CRAWLERS,\n] as const\n","import type { ConsentMode, Jurisdiction } from '../types.js'\nimport { ALL_TRACKING_VENDORS } from './vendors.js'\n\n/**\n * European Union — GDPR + ePrivacy Directive (\"Cookie Law\").\n *\n * EU rules don't have UK DUAA's \"statistical purposes\" exemption. Even\n * privacy-first first-party analytics (Plausible, Fathom, etc.) are still\n * within scope of the ePrivacy Directive's storage / access provisions, so\n * the conservative position is to require opt-in consent.\n *\n * Some national regulators (notably CNIL in France) take a more permissive\n * view for strictly first-party, aggregated analytics under specific\n * configurations. This preset doesn't try to encode those nuances — it picks\n * the safest pan-EU classification. Override per-vendor in your config if\n * you've assessed a specific vendor under your DPA's guidance.\n *\n * UI requirements (EDPB / national DPAs):\n * - \"Reject All\" on first banner layer with equal prominence\n * - GPC: not yet mandatory but increasingly recognised. Default off.\n */\nexport const EU_GDPR: Jurisdiction = {\n id: 'EU_GDPR',\n name: 'European Union (GDPR / ePrivacy)',\n vendorRules: Object.fromEntries(ALL_TRACKING_VENDORS.map((v) => [v, 'consent' as ConsentMode])),\n defaultMode: 'consent',\n ui: {\n rejectButtonOnFirstLayer: true,\n equalProminence: true,\n honorGPC: false,\n },\n countries: [\n 'AT',\n 'BE',\n 'BG',\n 'HR',\n 'CY',\n 'CZ',\n 'DK',\n 'EE',\n 'FI',\n 'FR',\n 'DE',\n 'GR',\n 'HU',\n 'IE',\n 'IT',\n 'LV',\n 'LT',\n 'LU',\n 'MT',\n 'NL',\n 'PL',\n 'PT',\n 'RO',\n 'SK',\n 'SI',\n 'ES',\n 'SE',\n // EEA additions\n 'IS',\n 'LI',\n 'NO',\n ],\n}\n","import type { ConsentMode, Jurisdiction } from '../types.js'\nimport {\n ADVERTISING_VENDORS,\n AI_TRAINING_CRAWLERS,\n CDP_AND_PRODUCT_ANALYTICS,\n CHAT_WIDGETS,\n MARKETING_AUTOMATION,\n PRIVACY_FRIENDLY_ANALYTICS,\n SESSION_REPLAY_VENDORS,\n} from './vendors.js'\n\n/**\n * United Kingdom — Data (Use and Access) Act 2025 (DUAA).\n *\n * In force from 5 February 2026. Amends PECR to introduce new exemptions for\n * cookies/storage used solely for statistical, security, authentication, and\n * appearance purposes. Advertising and individual-level tracking still require\n * full opt-in consent.\n *\n * UI requirements (ICO):\n * - \"Reject All\" must be on the first banner layer\n * - \"Accept All\" and \"Reject All\" must have equal visual prominence\n * - GPC is not (yet) mandatory in UK guidance; default off.\n *\n * @see https://ico.org.uk/for-organisations/direct-marketing-and-privacy-and-electronic-communications/guide-to-pecr/cookies-and-similar-technologies/\n */\nexport const UK_DUAA: Jurisdiction = {\n id: 'UK_DUAA',\n name: 'United Kingdom (Data (Use and Access) Act 2025)',\n vendorRules: classify({\n notice: PRIVACY_FRIENDLY_ANALYTICS,\n consent: [\n ...ADVERTISING_VENDORS,\n ...SESSION_REPLAY_VENDORS,\n ...CDP_AND_PRODUCT_ANALYTICS,\n ...MARKETING_AUTOMATION,\n ...CHAT_WIDGETS,\n ...AI_TRAINING_CRAWLERS,\n ],\n }),\n defaultMode: 'consent',\n ui: {\n rejectButtonOnFirstLayer: true,\n equalProminence: true,\n honorGPC: false,\n },\n countries: ['GB'],\n}\n\nfunction classify(buckets: {\n notice?: readonly string[]\n consent?: readonly string[]\n always?: readonly string[]\n}): Record<string, ConsentMode> {\n const result: Record<string, ConsentMode> = {}\n for (const v of buckets.always ?? []) result[v] = 'always'\n for (const v of buckets.notice ?? []) result[v] = 'notice'\n for (const v of buckets.consent ?? []) result[v] = 'consent'\n return result\n}\n","import type { Jurisdiction } from '../types.js'\nimport { EU_GDPR } from './eu-gdpr.js'\nimport { UK_DUAA } from './uk-duaa.js'\n\nexport { UK_DUAA } from './uk-duaa.js'\nexport { EU_GDPR } from './eu-gdpr.js'\nexport {\n ADVERTISING_VENDORS,\n AI_TRAINING_CRAWLERS,\n ALL_TRACKING_VENDORS,\n CDP_AND_PRODUCT_ANALYTICS,\n CHAT_WIDGETS,\n MARKETING_AUTOMATION,\n PRIVACY_FRIENDLY_ANALYTICS,\n SESSION_REPLAY_VENDORS,\n} from './vendors.js'\n\n/**\n * Map of all built-in jurisdiction presets, keyed by their ID for ergonomic\n * lookup: `jurisdictions.UK_DUAA`.\n */\nexport const jurisdictions = {\n UK_DUAA,\n EU_GDPR,\n} as const\n\n/**\n * Resolve a jurisdiction from an ISO 3166-1 alpha-2 country code (e.g. 'GB').\n * Falls back to `EU_GDPR` for any country not explicitly mapped — the safer\n * default for an unknown EEA visitor. Returns `null` when the code is unknown\n * and no fallback is requested.\n */\nexport function resolveJurisdictionByCountry(\n country: string | undefined,\n fallback: Jurisdiction | null = EU_GDPR,\n): Jurisdiction | null {\n if (!country) return fallback\n const upper = country.toUpperCase()\n for (const j of Object.values(jurisdictions)) {\n if (j.countries?.includes(upper)) return j\n }\n return fallback\n}\n","import type { ConsentConfig, ConsentMode, Jurisdiction, ResolvedCategory } from './types.js'\n\n/**\n * Resolve each declared category against the active jurisdiction's vendor rules.\n *\n * For each category, the most-restrictive vendor mode wins:\n * `consent` > `notice` > `always`\n *\n * Categories with no vendors fall back to the jurisdiction's default mode,\n * unless `required: true` (always allowed) or an explicit `mode` override is set.\n */\nexport function resolveCategories(\n config: ConsentConfig,\n jurisdiction: Jurisdiction,\n): ResolvedCategory[] {\n return Object.entries(config.categories).map(([id, def]) => {\n const required = def.required === true\n const explicit = def.mode\n const vendors = def.vendors ?? []\n\n let mode: ConsentMode\n if (required) {\n mode = 'always'\n } else if (explicit) {\n mode = explicit\n } else if (vendors.length === 0) {\n mode = jurisdiction.defaultMode\n } else {\n mode = mostRestrictive(\n vendors.map((v) => jurisdiction.vendorRules[v] ?? jurisdiction.defaultMode),\n )\n }\n\n return {\n id,\n required,\n mode,\n default: required ? true : (def.default ?? false),\n vendors,\n description: def.description,\n }\n })\n}\n\nconst ORDER: Record<ConsentMode, number> = { always: 0, notice: 1, consent: 2 }\n\nfunction mostRestrictive(modes: ConsentMode[]): ConsentMode {\n let winner: ConsentMode = 'always'\n for (const m of modes) {\n if (ORDER[m] > ORDER[winner]) winner = m\n }\n return winner\n}\n","import type { StorageOptions, StoredConsent } from './types.js'\n\nconst DEFAULT_COOKIE_NAME = '__tb_consent'\nconst DEFAULT_MAX_AGE_DAYS = 365\n\n/**\n * Read the stored consent record from `document.cookie`.\n * Returns `null` on the server, when no cookie is set, or when the cookie is malformed.\n */\nexport function readConsent(options: StorageOptions = {}): StoredConsent | null {\n if (typeof document === 'undefined') return null\n return parseConsentFromHeader(document.cookie, options)\n}\n\n/**\n * Parse a stored consent record from a raw `Cookie` header string.\n * Useful on the server: pass the request's `cookie` header.\n * Returns `null` when the cookie isn't present or is malformed.\n */\nexport function parseConsentFromHeader(\n cookieHeader: string | undefined,\n options: StorageOptions = {},\n): StoredConsent | null {\n if (!cookieHeader) return null\n const name = options.cookieName ?? DEFAULT_COOKIE_NAME\n const match = cookieHeader.match(new RegExp(`(?:^|; )${name}=([^;]+)`))\n if (!match) return null\n try {\n const parsed = JSON.parse(decodeURIComponent(match[1]!)) as unknown\n if (isStoredConsent(parsed)) return parsed\n return null\n } catch {\n return null\n }\n}\n\n/**\n * Persist a consent record to `document.cookie`.\n * No-op on the server.\n */\nexport function writeConsent(value: StoredConsent, options: StorageOptions = {}): void {\n if (typeof document === 'undefined') return\n const name = options.cookieName ?? DEFAULT_COOKIE_NAME\n const maxAge = (options.maxAgeDays ?? DEFAULT_MAX_AGE_DAYS) * 86_400\n const domain = options.domain ? `; Domain=${options.domain}` : ''\n const secure = typeof location !== 'undefined' && location.protocol === 'https:' ? '; Secure' : ''\n const encoded = encodeURIComponent(JSON.stringify(value))\n document.cookie = `${name}=${encoded}; Path=/; Max-Age=${maxAge}; SameSite=Lax${secure}${domain}`\n}\n\n/** Clear the stored consent cookie. */\nexport function clearConsent(options: StorageOptions = {}): void {\n if (typeof document === 'undefined') return\n const name = options.cookieName ?? DEFAULT_COOKIE_NAME\n const domain = options.domain ? `; Domain=${options.domain}` : ''\n document.cookie = `${name}=; Path=/; Max-Age=0${domain}`\n}\n\nfunction isStoredConsent(value: unknown): value is StoredConsent {\n if (typeof value !== 'object' || value === null) return false\n const v = value as Record<string, unknown>\n return (\n v.v === 1 &&\n typeof v.c === 'object' &&\n v.c !== null &&\n typeof v.pv === 'string' &&\n typeof v.ts === 'number' &&\n typeof v.j === 'string'\n )\n}\n","import { resolveCategories } from './resolve.js'\nimport { parseConsentFromHeader, readConsent, writeConsent } from './storage.js'\nimport type {\n ConsentConfig,\n Jurisdiction,\n ResolvedCategory,\n StorageOptions,\n StoredConsent,\n} from './types.js'\n\nexport type ConsentState = {\n /** True after the store has hydrated from the cookie (client-only). */\n ready: boolean\n /** True when the banner / preference centre should be visible. */\n isOpen: boolean\n /** Map of category ID → granted (true) / denied (false). */\n decisions: Record<string, boolean>\n /** Resolved categories for the active jurisdiction. */\n resolved: ResolvedCategory[]\n /** Timestamp of the most-recent stored decision, if any. */\n storedAt: number | null\n}\n\ntype Listener = (state: ConsentState) => void\n\nexport type StoreOptions = {\n /** Storage options forwarded to the cookie reader/writer. */\n storage?: StorageOptions\n /** When `true`, side-effects like script rewriting fire on state changes. Defaults to true. */\n applyEffects?: boolean\n /** Custom side-effect handler. Receives `(state, resolved)` whenever decisions change. */\n onApply?: (state: ConsentState) => void\n /** Active jurisdiction. Required — pass `config.jurisdiction` after resolving 'auto'. */\n jurisdiction: Jurisdiction\n}\n\n/**\n * Framework-agnostic consent state machine.\n *\n * The store hydrates from the cookie on first read, keeps decisions in memory,\n * and broadcasts changes to subscribers. Adapters (`@tickboxhq/react`,\n * `@tickboxhq/vue`) bind to it via their idiomatic reactivity primitive.\n */\nexport class ConsentStore {\n private state: ConsentState\n private readonly listeners = new Set<Listener>()\n private readonly config: ConsentConfig\n private readonly options: StoreOptions\n\n constructor(config: ConsentConfig, options: StoreOptions) {\n this.config = config\n this.options = options\n const resolved = resolveCategories(config, options.jurisdiction)\n this.state = {\n ready: false,\n isOpen: false,\n decisions: defaultDecisions(resolved),\n resolved,\n storedAt: null,\n }\n }\n\n /**\n * Read the stored cookie and update state. Safe to call on the server\n * (no-op when `document` is unavailable). Call from a mount effect.\n */\n hydrate(): void {\n const stored = readConsent(this.options.storage)\n this.applyHydration(stored)\n }\n\n /**\n * Hydrate from a raw Cookie header — for server-side rendering.\n * Pass the value of the request's `cookie` header (or `undefined` if absent).\n */\n hydrateFromHeader(cookieHeader: string | undefined): void {\n const stored = parseConsentFromHeader(cookieHeader, this.options.storage)\n this.applyHydration(stored)\n }\n\n private applyHydration(stored: StoredConsent | null): void {\n if (stored) {\n this.state = {\n ...this.state,\n ready: true,\n isOpen: needsRefresh(stored, this.config),\n decisions: mergeDecisions(this.state.resolved, stored.c),\n storedAt: stored.ts,\n }\n } else {\n this.state = {\n ...this.state,\n ready: true,\n isOpen: shouldShowBanner(this.state.resolved),\n }\n }\n this.emit()\n }\n\n getState(): ConsentState {\n return this.state\n }\n\n subscribe(fn: Listener): () => void {\n this.listeners.add(fn)\n return () => {\n this.listeners.delete(fn)\n }\n }\n\n grant(id: string): void {\n this.update({ [id]: true })\n }\n\n deny(id: string): void {\n if (this.isRequired(id)) return\n this.update({ [id]: false })\n }\n\n grantAll(): void {\n const next: Record<string, boolean> = {}\n for (const r of this.state.resolved) next[r.id] = true\n this.update(next, { close: true })\n }\n\n denyAll(): void {\n const next: Record<string, boolean> = {}\n for (const r of this.state.resolved) next[r.id] = r.required\n this.update(next, { close: true })\n }\n\n /** Persist the current decisions and close the banner. */\n save(): void {\n const ts = this.persist(this.state.decisions)\n this.state = { ...this.state, isOpen: false, storedAt: ts }\n this.emit()\n }\n\n open(): void {\n if (this.state.isOpen) return\n this.state = { ...this.state, isOpen: true }\n this.emit()\n }\n\n close(): void {\n if (!this.state.isOpen) return\n this.state = { ...this.state, isOpen: false }\n this.emit()\n }\n\n /** Wipe stored consent and reopen the banner. */\n reset(): void {\n this.state = {\n ...this.state,\n decisions: defaultDecisions(this.state.resolved),\n isOpen: true,\n storedAt: null,\n }\n this.emit()\n }\n\n isRequired(id: string): boolean {\n return this.state.resolved.find((r) => r.id === id)?.required === true\n }\n\n private update(partial: Record<string, boolean>, opts: { close?: boolean } = {}): void {\n const next = { ...this.state.decisions, ...partial }\n const ts = this.persist(next)\n this.state = {\n ...this.state,\n decisions: next,\n isOpen: opts.close ? false : this.state.isOpen,\n storedAt: ts,\n }\n this.emit()\n }\n\n private persist(decisions: Record<string, boolean>): number {\n const ts = Date.now()\n const stored: StoredConsent = {\n v: 1,\n c: decisions,\n pv: this.config.policy?.version ?? '0',\n ts,\n j: this.options.jurisdiction.id,\n }\n writeConsent(stored, this.options.storage)\n return ts\n }\n\n private emit(): void {\n if (this.options.applyEffects !== false) {\n this.options.onApply?.(this.state)\n }\n for (const fn of this.listeners) fn(this.state)\n }\n}\n\nfunction defaultDecisions(resolved: ResolvedCategory[]): Record<string, boolean> {\n const out: Record<string, boolean> = {}\n for (const r of resolved) out[r.id] = r.required ? true : r.default\n return out\n}\n\nfunction mergeDecisions(\n resolved: ResolvedCategory[],\n stored: Record<string, boolean>,\n): Record<string, boolean> {\n const out: Record<string, boolean> = {}\n for (const r of resolved) {\n if (r.required) {\n out[r.id] = true\n } else if (stored[r.id] !== undefined) {\n out[r.id] = stored[r.id]!\n } else {\n out[r.id] = r.default\n }\n }\n return out\n}\n\nfunction needsRefresh(stored: StoredConsent, config: ConsentConfig): boolean {\n const declared = config.policy?.version\n if (!declared) return false\n return stored.pv !== declared\n}\n\nfunction shouldShowBanner(resolved: ResolvedCategory[]): boolean {\n return resolved.some((r) => r.mode === 'consent' && !r.required)\n}\n"]}
@@ -1 +1 @@
1
- export { E as EU_GDPR, U as UK_DUAA, j as jurisdictions, r as resolveJurisdictionByCountry } from '../index-D_Xt5NFB.js';
1
+ export { A as ADVERTISING_VENDORS, f as AI_TRAINING_CRAWLERS, g as ALL_TRACKING_VENDORS, h as CDP_AND_PRODUCT_ANALYTICS, i as CHAT_WIDGETS, E as EU_GDPR, M as MARKETING_AUTOMATION, P as PRIVACY_FRIENDLY_ANALYTICS, k as SESSION_REPLAY_VENDORS, U as UK_DUAA, j as jurisdictions, r as resolveJurisdictionByCountry } from '../index-C1gN-xur.js';
@@ -1,8 +1,106 @@
1
+ // src/jurisdictions/vendors.ts
2
+ var PRIVACY_FRIENDLY_ANALYTICS = [
3
+ "plausible",
4
+ "fathom",
5
+ "simpleanalytics",
6
+ "pirsch",
7
+ "goatcounter",
8
+ "umami",
9
+ "tinybird-analytics",
10
+ "cloudflare-web-analytics"
11
+ ];
12
+ var ADVERTISING_VENDORS = [
13
+ "google-ads",
14
+ "google-analytics",
15
+ "ga4",
16
+ "google-tag-manager",
17
+ "gtm",
18
+ "meta-pixel",
19
+ "facebook-pixel",
20
+ "tiktok-pixel",
21
+ "linkedin-insight",
22
+ "twitter-pixel",
23
+ "x-pixel",
24
+ "pinterest-tag",
25
+ "reddit-pixel",
26
+ "snapchat-pixel",
27
+ "bing-uet",
28
+ "microsoft-uet",
29
+ "criteo",
30
+ "taboola",
31
+ "outbrain",
32
+ "yandex-metrica",
33
+ "baidu-analytics"
34
+ ];
35
+ var SESSION_REPLAY_VENDORS = [
36
+ "hotjar",
37
+ "fullstory",
38
+ "microsoft-clarity",
39
+ "mouseflow",
40
+ "logrocket",
41
+ "smartlook",
42
+ "lucky-orange"
43
+ ];
44
+ var CDP_AND_PRODUCT_ANALYTICS = [
45
+ "segment",
46
+ "rudderstack",
47
+ "mixpanel",
48
+ "amplitude",
49
+ "posthog",
50
+ "heap",
51
+ "pendo",
52
+ "june"
53
+ ];
54
+ var MARKETING_AUTOMATION = [
55
+ "hubspot",
56
+ "pardot",
57
+ "marketo",
58
+ "mailchimp",
59
+ "klaviyo",
60
+ "iterable",
61
+ "activecampaign",
62
+ "braze",
63
+ "customer-io",
64
+ "sendinblue",
65
+ "brevo"
66
+ ];
67
+ var CHAT_WIDGETS = [
68
+ "intercom",
69
+ "drift",
70
+ "crisp",
71
+ "tawk",
72
+ "livechat",
73
+ "olark",
74
+ "tidio",
75
+ "zendesk-chat"
76
+ ];
77
+ var AI_TRAINING_CRAWLERS = [
78
+ "gptbot",
79
+ "claudebot",
80
+ "anthropic-ai",
81
+ "google-extended",
82
+ "perplexitybot",
83
+ "ccbot",
84
+ "bytespider",
85
+ "applebot-extended",
86
+ "meta-externalagent",
87
+ "oai-searchbot"
88
+ ];
89
+ var ALL_TRACKING_VENDORS = [
90
+ ...PRIVACY_FRIENDLY_ANALYTICS,
91
+ ...ADVERTISING_VENDORS,
92
+ ...SESSION_REPLAY_VENDORS,
93
+ ...CDP_AND_PRODUCT_ANALYTICS,
94
+ ...MARKETING_AUTOMATION,
95
+ ...CHAT_WIDGETS,
96
+ ...AI_TRAINING_CRAWLERS
97
+ ];
98
+
1
99
  // src/jurisdictions/eu-gdpr.ts
2
100
  var EU_GDPR = {
3
101
  id: "EU_GDPR",
4
102
  name: "European Union (GDPR / ePrivacy)",
5
- vendorRules: {},
103
+ vendorRules: Object.fromEntries(ALL_TRACKING_VENDORS.map((v) => [v, "consent"])),
6
104
  defaultMode: "consent",
7
105
  ui: {
8
106
  rejectButtonOnFirstLayer: true,
@@ -45,57 +143,20 @@ var EU_GDPR = {
45
143
  };
46
144
 
47
145
  // src/jurisdictions/uk-duaa.ts
48
- var DUAA_STATISTICAL_VENDORS = [
49
- "plausible",
50
- "fathom",
51
- "simpleanalytics",
52
- "pirsch",
53
- "goatcounter",
54
- "umami",
55
- "tinybird-analytics",
56
- "cloudflare-web-analytics"
57
- ];
58
- var DUAA_CONSENT_REQUIRED_VENDORS = [
59
- // Advertising
60
- "google-ads",
61
- "google-analytics",
62
- "ga4",
63
- "meta-pixel",
64
- "facebook-pixel",
65
- "tiktok-pixel",
66
- "linkedin-insight",
67
- "twitter-pixel",
68
- "pinterest-tag",
69
- "reddit-pixel",
70
- // Session replay / individual tracking
71
- "hotjar",
72
- "fullstory",
73
- "microsoft-clarity",
74
- "mouseflow",
75
- "logrocket",
76
- // CDPs / marketing automation
77
- "segment",
78
- "rudderstack",
79
- "hubspot",
80
- "mixpanel",
81
- "amplitude",
82
- // AI training crawlers (always require explicit opt-in/out)
83
- "gptbot",
84
- "claudebot",
85
- "anthropic-ai",
86
- "google-extended",
87
- "perplexitybot",
88
- "ccbot",
89
- "bytespider",
90
- "applebot-extended"
91
- ];
92
146
  var UK_DUAA = {
93
147
  id: "UK_DUAA",
94
148
  name: "United Kingdom (Data (Use and Access) Act 2025)",
95
- vendorRules: {
96
- ...Object.fromEntries(DUAA_STATISTICAL_VENDORS.map((v) => [v, "notice"])),
97
- ...Object.fromEntries(DUAA_CONSENT_REQUIRED_VENDORS.map((v) => [v, "consent"]))
98
- },
149
+ vendorRules: classify({
150
+ notice: PRIVACY_FRIENDLY_ANALYTICS,
151
+ consent: [
152
+ ...ADVERTISING_VENDORS,
153
+ ...SESSION_REPLAY_VENDORS,
154
+ ...CDP_AND_PRODUCT_ANALYTICS,
155
+ ...MARKETING_AUTOMATION,
156
+ ...CHAT_WIDGETS,
157
+ ...AI_TRAINING_CRAWLERS
158
+ ]
159
+ }),
99
160
  defaultMode: "consent",
100
161
  ui: {
101
162
  rejectButtonOnFirstLayer: true,
@@ -104,6 +165,13 @@ var UK_DUAA = {
104
165
  },
105
166
  countries: ["GB"]
106
167
  };
168
+ function classify(buckets) {
169
+ const result = {};
170
+ for (const v of buckets.always ?? []) result[v] = "always";
171
+ for (const v of buckets.notice ?? []) result[v] = "notice";
172
+ for (const v of buckets.consent ?? []) result[v] = "consent";
173
+ return result;
174
+ }
107
175
 
108
176
  // src/jurisdictions/index.ts
109
177
  var jurisdictions = {
@@ -119,6 +187,6 @@ function resolveJurisdictionByCountry(country, fallback = EU_GDPR) {
119
187
  return fallback;
120
188
  }
121
189
 
122
- export { EU_GDPR, UK_DUAA, jurisdictions, resolveJurisdictionByCountry };
190
+ export { ADVERTISING_VENDORS, AI_TRAINING_CRAWLERS, ALL_TRACKING_VENDORS, CDP_AND_PRODUCT_ANALYTICS, CHAT_WIDGETS, EU_GDPR, MARKETING_AUTOMATION, PRIVACY_FRIENDLY_ANALYTICS, SESSION_REPLAY_VENDORS, UK_DUAA, jurisdictions, resolveJurisdictionByCountry };
123
191
  //# sourceMappingURL=index.js.map
124
192
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/jurisdictions/eu-gdpr.ts","../../src/jurisdictions/uk-duaa.ts","../../src/jurisdictions/index.ts"],"names":[],"mappings":";AAeO,IAAM,OAAA,GAAwB;AAAA,EACnC,EAAA,EAAI,SAAA;AAAA,EACJ,IAAA,EAAM,kCAAA;AAAA,EACN,aAAa,EAAC;AAAA,EACd,WAAA,EAAa,SAAA;AAAA,EACb,EAAA,EAAI;AAAA,IACF,wBAAA,EAA0B,IAAA;AAAA,IAC1B,eAAA,EAAiB,IAAA;AAAA,IACjB,QAAA,EAAU;AAAA,GACZ;AAAA,EACA,SAAA,EAAW;AAAA,IACT,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA;AAAA,IAEA,IAAA;AAAA,IACA,IAAA;AAAA,IACA;AAAA;AAEJ;;;AC9CA,IAAM,wBAAA,GAA2B;AAAA,EAC/B,WAAA;AAAA,EACA,QAAA;AAAA,EACA,iBAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA,OAAA;AAAA,EACA,oBAAA;AAAA,EACA;AACF,CAAA;AAMA,IAAM,6BAAA,GAAgC;AAAA;AAAA,EAEpC,YAAA;AAAA,EACA,kBAAA;AAAA,EACA,KAAA;AAAA,EACA,YAAA;AAAA,EACA,gBAAA;AAAA,EACA,cAAA;AAAA,EACA,kBAAA;AAAA,EACA,eAAA;AAAA,EACA,eAAA;AAAA,EACA,cAAA;AAAA;AAAA,EAEA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,mBAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA;AAAA,EAEA,SAAA;AAAA,EACA,aAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA;AAAA,EAEA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,cAAA;AAAA,EACA,iBAAA;AAAA,EACA,eAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF,CAAA;AAiBO,IAAM,OAAA,GAAwB;AAAA,EACnC,EAAA,EAAI,SAAA;AAAA,EACJ,IAAA,EAAM,iDAAA;AAAA,EACN,WAAA,EAAa;AAAA,IACX,GAAG,MAAA,CAAO,WAAA,CAAY,wBAAA,CAAyB,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,EAAG,QAAiB,CAAC,CAAC,CAAA;AAAA,IACjF,GAAG,MAAA,CAAO,WAAA,CAAY,6BAAA,CAA8B,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,EAAG,SAAkB,CAAC,CAAC;AAAA,GACzF;AAAA,EACA,WAAA,EAAa,SAAA;AAAA,EACb,EAAA,EAAI;AAAA,IACF,wBAAA,EAA0B,IAAA;AAAA,IAC1B,eAAA,EAAiB,IAAA;AAAA,IACjB,QAAA,EAAU;AAAA,GACZ;AAAA,EACA,SAAA,EAAW,CAAC,IAAI;AAClB;;;AChFO,IAAM,aAAA,GAAgB;AAAA,EAC3B,OAAA;AAAA,EACA;AACF;AAQO,SAAS,4BAAA,CACd,OAAA,EACA,QAAA,GAAgC,OAAA,EACX;AACrB,EAAA,IAAI,CAAC,SAAS,OAAO,QAAA;AACrB,EAAA,MAAM,KAAA,GAAQ,QAAQ,WAAA,EAAY;AAClC,EAAA,KAAA,MAAW,CAAA,IAAK,MAAA,CAAO,MAAA,CAAO,aAAa,CAAA,EAAG;AAC5C,IAAA,IAAI,CAAA,CAAE,SAAA,EAAW,QAAA,CAAS,KAAK,GAAG,OAAO,CAAA;AAAA,EAC3C;AACA,EAAA,OAAO,QAAA;AACT","file":"index.js","sourcesContent":["import type { Jurisdiction } from '../types.js'\n\n/**\n * European Union — GDPR + ePrivacy Directive (\"Cookie Law\").\n *\n * EU rules don't have the DUAA \"statistical exemption\" — analytics that\n * involve client-side storage on a user's device generally require opt-in\n * consent, even for first-party privacy-friendly tools (positions vary by\n * DPA; CNIL has been more permissive than others). This preset takes the\n * conservative position: treat all tracking categories as consent-required.\n *\n * UI requirements (EDPB / national DPAs):\n * - \"Reject All\" on first banner layer with equal prominence\n * - GPC: not yet mandatory but increasingly recognised\n */\nexport const EU_GDPR: Jurisdiction = {\n id: 'EU_GDPR',\n name: 'European Union (GDPR / ePrivacy)',\n vendorRules: {},\n defaultMode: 'consent',\n ui: {\n rejectButtonOnFirstLayer: true,\n equalProminence: true,\n honorGPC: false,\n },\n countries: [\n 'AT',\n 'BE',\n 'BG',\n 'HR',\n 'CY',\n 'CZ',\n 'DK',\n 'EE',\n 'FI',\n 'FR',\n 'DE',\n 'GR',\n 'HU',\n 'IE',\n 'IT',\n 'LV',\n 'LT',\n 'LU',\n 'MT',\n 'NL',\n 'PL',\n 'PT',\n 'RO',\n 'SK',\n 'SI',\n 'ES',\n 'SE',\n // EEA additions\n 'IS',\n 'LI',\n 'NO',\n ],\n}\n","import type { Jurisdiction } from '../types.js'\n\n/**\n * Vendors classified as eligible for the DUAA \"statistical purposes\" exemption:\n * privacy-first analytics with aggregated, non-identifying data and no ad features.\n *\n * These do **not** require consent under the UK Data (Use and Access) Act 2025\n * but still require clear notice and an easy way to object.\n *\n * Treat the list as a starting position; specific deployments may still need\n * consent depending on configuration (e.g. session replay, cross-domain tracking).\n */\nconst DUAA_STATISTICAL_VENDORS = [\n 'plausible',\n 'fathom',\n 'simpleanalytics',\n 'pirsch',\n 'goatcounter',\n 'umami',\n 'tinybird-analytics',\n 'cloudflare-web-analytics',\n] as const\n\n/**\n * Vendors that require full opt-in consent under DUAA — anything that touches\n * advertising, individual-level tracking, session replay, or cross-site profiles.\n */\nconst DUAA_CONSENT_REQUIRED_VENDORS = [\n // Advertising\n 'google-ads',\n 'google-analytics',\n 'ga4',\n 'meta-pixel',\n 'facebook-pixel',\n 'tiktok-pixel',\n 'linkedin-insight',\n 'twitter-pixel',\n 'pinterest-tag',\n 'reddit-pixel',\n // Session replay / individual tracking\n 'hotjar',\n 'fullstory',\n 'microsoft-clarity',\n 'mouseflow',\n 'logrocket',\n // CDPs / marketing automation\n 'segment',\n 'rudderstack',\n 'hubspot',\n 'mixpanel',\n 'amplitude',\n // AI training crawlers (always require explicit opt-in/out)\n 'gptbot',\n 'claudebot',\n 'anthropic-ai',\n 'google-extended',\n 'perplexitybot',\n 'ccbot',\n 'bytespider',\n 'applebot-extended',\n] as const\n\n/**\n * United Kingdom — Data (Use and Access) Act 2025 (DUAA).\n *\n * In force from 5 February 2026. Amends PECR to introduce new exemptions for\n * cookies/storage used solely for statistical, security, authentication, and\n * appearance purposes. Advertising and individual-level tracking still require\n * full opt-in consent.\n *\n * UI requirements (ICO):\n * - \"Reject All\" must be on the first banner layer\n * - \"Accept All\" and \"Reject All\" must have equal visual prominence\n * - GPC is not (yet) mandatory in UK guidance; default off.\n *\n * @see https://ico.org.uk/for-organisations/direct-marketing-and-privacy-and-electronic-communications/guide-to-pecr/cookies-and-similar-technologies/\n */\nexport const UK_DUAA: Jurisdiction = {\n id: 'UK_DUAA',\n name: 'United Kingdom (Data (Use and Access) Act 2025)',\n vendorRules: {\n ...Object.fromEntries(DUAA_STATISTICAL_VENDORS.map((v) => [v, 'notice' as const])),\n ...Object.fromEntries(DUAA_CONSENT_REQUIRED_VENDORS.map((v) => [v, 'consent' as const])),\n },\n defaultMode: 'consent',\n ui: {\n rejectButtonOnFirstLayer: true,\n equalProminence: true,\n honorGPC: false,\n },\n countries: ['GB'],\n}\n","import type { Jurisdiction } from '../types.js'\nimport { EU_GDPR } from './eu-gdpr.js'\nimport { UK_DUAA } from './uk-duaa.js'\n\nexport { UK_DUAA } from './uk-duaa.js'\nexport { EU_GDPR } from './eu-gdpr.js'\n\n/**\n * Map of all built-in jurisdiction presets, keyed by their ID for ergonomic\n * lookup: `jurisdictions.UK_DUAA`.\n */\nexport const jurisdictions = {\n UK_DUAA,\n EU_GDPR,\n} as const\n\n/**\n * Resolve a jurisdiction from an ISO 3166-1 alpha-2 country code (e.g. 'GB').\n * Falls back to `EU_GDPR` for any country not explicitly mapped — the safer\n * default for an unknown EEA visitor. Returns `null` when the code is unknown\n * and no fallback is requested.\n */\nexport function resolveJurisdictionByCountry(\n country: string | undefined,\n fallback: Jurisdiction | null = EU_GDPR,\n): Jurisdiction | null {\n if (!country) return fallback\n const upper = country.toUpperCase()\n for (const j of Object.values(jurisdictions)) {\n if (j.countries?.includes(upper)) return j\n }\n return fallback\n}\n"]}
1
+ {"version":3,"sources":["../../src/jurisdictions/vendors.ts","../../src/jurisdictions/eu-gdpr.ts","../../src/jurisdictions/uk-duaa.ts","../../src/jurisdictions/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Categorised vendor identifiers used by the built-in jurisdiction presets.\n *\n * The lists are exported so projects can reference them directly:\n *\n * ```ts\n * import { defineConsent, jurisdictions, ADVERTISING_VENDORS } from '@tickboxhq/core'\n *\n * defineConsent({\n * jurisdiction: jurisdictions.UK_DUAA,\n * categories: {\n * marketing: { vendors: [...ADVERTISING_VENDORS] },\n * },\n * })\n * ```\n *\n * Each list is intentionally *descriptive* — adding a vendor here does not\n * automatically apply rules to your site. Your `consent.config.ts` is what\n * declares which vendors you actually use; the jurisdiction preset then\n * decides which ones need consent vs. notice vs. always-allowed.\n */\n\n/**\n * Privacy-friendly statistical analytics — first-party or near-first-party,\n * aggregated, no individual-level data, no advertising features.\n *\n * Under UK DUAA (PECR exemption from 5 Feb 2026) these qualify for the\n * \"statistical purposes\" exemption — notice + opt-out is enough, no banner\n * required. Under EU GDPR / ePrivacy these still require consent.\n */\nexport const PRIVACY_FRIENDLY_ANALYTICS = [\n 'plausible',\n 'fathom',\n 'simpleanalytics',\n 'pirsch',\n 'goatcounter',\n 'umami',\n 'tinybird-analytics',\n 'cloudflare-web-analytics',\n] as const\n\n/** Advertising / paid-acquisition pixels and SDKs. Always require consent. */\nexport const ADVERTISING_VENDORS = [\n 'google-ads',\n 'google-analytics',\n 'ga4',\n 'google-tag-manager',\n 'gtm',\n 'meta-pixel',\n 'facebook-pixel',\n 'tiktok-pixel',\n 'linkedin-insight',\n 'twitter-pixel',\n 'x-pixel',\n 'pinterest-tag',\n 'reddit-pixel',\n 'snapchat-pixel',\n 'bing-uet',\n 'microsoft-uet',\n 'criteo',\n 'taboola',\n 'outbrain',\n 'yandex-metrica',\n 'baidu-analytics',\n] as const\n\n/** Session-replay and individual-user fingerprinting. Always require consent. */\nexport const SESSION_REPLAY_VENDORS = [\n 'hotjar',\n 'fullstory',\n 'microsoft-clarity',\n 'mouseflow',\n 'logrocket',\n 'smartlook',\n 'lucky-orange',\n] as const\n\n/**\n * Customer-data platforms and product analytics that send individual events.\n * Always require consent.\n */\nexport const CDP_AND_PRODUCT_ANALYTICS = [\n 'segment',\n 'rudderstack',\n 'mixpanel',\n 'amplitude',\n 'posthog',\n 'heap',\n 'pendo',\n 'june',\n] as const\n\n/**\n * Marketing-automation, CRM and email-marketing platforms with browser\n * tracking. Always require consent.\n */\nexport const MARKETING_AUTOMATION = [\n 'hubspot',\n 'pardot',\n 'marketo',\n 'mailchimp',\n 'klaviyo',\n 'iterable',\n 'activecampaign',\n 'braze',\n 'customer-io',\n 'sendinblue',\n 'brevo',\n] as const\n\n/** Live-chat widgets. Each loads third-party scripts that fingerprint users. */\nexport const CHAT_WIDGETS = [\n 'intercom',\n 'drift',\n 'crisp',\n 'tawk',\n 'livechat',\n 'olark',\n 'tidio',\n 'zendesk-chat',\n] as const\n\n/**\n * AI-training crawlers and LLM-related user-agents.\n *\n * Listed as consent-required so an explicit opt-in toggle decides whether\n * site content can be crawled / used for model training. Pairs with the\n * upcoming `ai_training` category and a future `/ai.txt` / `/llms.txt`\n * generator. EU AI Act Article 53 enforcement starts August 2026.\n */\nexport const AI_TRAINING_CRAWLERS = [\n 'gptbot',\n 'claudebot',\n 'anthropic-ai',\n 'google-extended',\n 'perplexitybot',\n 'ccbot',\n 'bytespider',\n 'applebot-extended',\n 'meta-externalagent',\n 'oai-searchbot',\n] as const\n\n/**\n * Convenience: all known vendor identifiers across all categories.\n * Used by EU_GDPR to classify everything as `consent` in one shot.\n */\nexport const ALL_TRACKING_VENDORS = [\n ...PRIVACY_FRIENDLY_ANALYTICS,\n ...ADVERTISING_VENDORS,\n ...SESSION_REPLAY_VENDORS,\n ...CDP_AND_PRODUCT_ANALYTICS,\n ...MARKETING_AUTOMATION,\n ...CHAT_WIDGETS,\n ...AI_TRAINING_CRAWLERS,\n] as const\n","import type { ConsentMode, Jurisdiction } from '../types.js'\nimport { ALL_TRACKING_VENDORS } from './vendors.js'\n\n/**\n * European Union — GDPR + ePrivacy Directive (\"Cookie Law\").\n *\n * EU rules don't have UK DUAA's \"statistical purposes\" exemption. Even\n * privacy-first first-party analytics (Plausible, Fathom, etc.) are still\n * within scope of the ePrivacy Directive's storage / access provisions, so\n * the conservative position is to require opt-in consent.\n *\n * Some national regulators (notably CNIL in France) take a more permissive\n * view for strictly first-party, aggregated analytics under specific\n * configurations. This preset doesn't try to encode those nuances — it picks\n * the safest pan-EU classification. Override per-vendor in your config if\n * you've assessed a specific vendor under your DPA's guidance.\n *\n * UI requirements (EDPB / national DPAs):\n * - \"Reject All\" on first banner layer with equal prominence\n * - GPC: not yet mandatory but increasingly recognised. Default off.\n */\nexport const EU_GDPR: Jurisdiction = {\n id: 'EU_GDPR',\n name: 'European Union (GDPR / ePrivacy)',\n vendorRules: Object.fromEntries(ALL_TRACKING_VENDORS.map((v) => [v, 'consent' as ConsentMode])),\n defaultMode: 'consent',\n ui: {\n rejectButtonOnFirstLayer: true,\n equalProminence: true,\n honorGPC: false,\n },\n countries: [\n 'AT',\n 'BE',\n 'BG',\n 'HR',\n 'CY',\n 'CZ',\n 'DK',\n 'EE',\n 'FI',\n 'FR',\n 'DE',\n 'GR',\n 'HU',\n 'IE',\n 'IT',\n 'LV',\n 'LT',\n 'LU',\n 'MT',\n 'NL',\n 'PL',\n 'PT',\n 'RO',\n 'SK',\n 'SI',\n 'ES',\n 'SE',\n // EEA additions\n 'IS',\n 'LI',\n 'NO',\n ],\n}\n","import type { ConsentMode, Jurisdiction } from '../types.js'\nimport {\n ADVERTISING_VENDORS,\n AI_TRAINING_CRAWLERS,\n CDP_AND_PRODUCT_ANALYTICS,\n CHAT_WIDGETS,\n MARKETING_AUTOMATION,\n PRIVACY_FRIENDLY_ANALYTICS,\n SESSION_REPLAY_VENDORS,\n} from './vendors.js'\n\n/**\n * United Kingdom — Data (Use and Access) Act 2025 (DUAA).\n *\n * In force from 5 February 2026. Amends PECR to introduce new exemptions for\n * cookies/storage used solely for statistical, security, authentication, and\n * appearance purposes. Advertising and individual-level tracking still require\n * full opt-in consent.\n *\n * UI requirements (ICO):\n * - \"Reject All\" must be on the first banner layer\n * - \"Accept All\" and \"Reject All\" must have equal visual prominence\n * - GPC is not (yet) mandatory in UK guidance; default off.\n *\n * @see https://ico.org.uk/for-organisations/direct-marketing-and-privacy-and-electronic-communications/guide-to-pecr/cookies-and-similar-technologies/\n */\nexport const UK_DUAA: Jurisdiction = {\n id: 'UK_DUAA',\n name: 'United Kingdom (Data (Use and Access) Act 2025)',\n vendorRules: classify({\n notice: PRIVACY_FRIENDLY_ANALYTICS,\n consent: [\n ...ADVERTISING_VENDORS,\n ...SESSION_REPLAY_VENDORS,\n ...CDP_AND_PRODUCT_ANALYTICS,\n ...MARKETING_AUTOMATION,\n ...CHAT_WIDGETS,\n ...AI_TRAINING_CRAWLERS,\n ],\n }),\n defaultMode: 'consent',\n ui: {\n rejectButtonOnFirstLayer: true,\n equalProminence: true,\n honorGPC: false,\n },\n countries: ['GB'],\n}\n\nfunction classify(buckets: {\n notice?: readonly string[]\n consent?: readonly string[]\n always?: readonly string[]\n}): Record<string, ConsentMode> {\n const result: Record<string, ConsentMode> = {}\n for (const v of buckets.always ?? []) result[v] = 'always'\n for (const v of buckets.notice ?? []) result[v] = 'notice'\n for (const v of buckets.consent ?? []) result[v] = 'consent'\n return result\n}\n","import type { Jurisdiction } from '../types.js'\nimport { EU_GDPR } from './eu-gdpr.js'\nimport { UK_DUAA } from './uk-duaa.js'\n\nexport { UK_DUAA } from './uk-duaa.js'\nexport { EU_GDPR } from './eu-gdpr.js'\nexport {\n ADVERTISING_VENDORS,\n AI_TRAINING_CRAWLERS,\n ALL_TRACKING_VENDORS,\n CDP_AND_PRODUCT_ANALYTICS,\n CHAT_WIDGETS,\n MARKETING_AUTOMATION,\n PRIVACY_FRIENDLY_ANALYTICS,\n SESSION_REPLAY_VENDORS,\n} from './vendors.js'\n\n/**\n * Map of all built-in jurisdiction presets, keyed by their ID for ergonomic\n * lookup: `jurisdictions.UK_DUAA`.\n */\nexport const jurisdictions = {\n UK_DUAA,\n EU_GDPR,\n} as const\n\n/**\n * Resolve a jurisdiction from an ISO 3166-1 alpha-2 country code (e.g. 'GB').\n * Falls back to `EU_GDPR` for any country not explicitly mapped — the safer\n * default for an unknown EEA visitor. Returns `null` when the code is unknown\n * and no fallback is requested.\n */\nexport function resolveJurisdictionByCountry(\n country: string | undefined,\n fallback: Jurisdiction | null = EU_GDPR,\n): Jurisdiction | null {\n if (!country) return fallback\n const upper = country.toUpperCase()\n for (const j of Object.values(jurisdictions)) {\n if (j.countries?.includes(upper)) return j\n }\n return fallback\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tickboxhq/core",
3
- "version": "0.0.1",
3
+ "version": "0.0.4",
4
4
  "description": "Core types, jurisdictions, and storage primitives for Tickbox consent management",
5
5
  "license": "MIT",
6
6
  "homepage": "https://tickbox.dev",
@@ -1,155 +0,0 @@
1
- /**
2
- * How a category should be treated for a given jurisdiction.
3
- *
4
- * - `consent` — must opt-in. Block tags until granted. (e.g. marketing under GDPR/PECR)
5
- * - `notice` — show info + easy opt-out, but don't block tags. (e.g. UK DUAA "statistical" analytics)
6
- * - `always` — no consent or notice required. (e.g. necessary cookies)
7
- */
8
- type ConsentMode = 'consent' | 'notice' | 'always';
9
- type CategoryId = string;
10
- type CategoryDefinition = {
11
- /** True for strictly necessary categories that the user cannot deny. */
12
- required?: boolean;
13
- /** Pre-toggled state when the user hasn't chosen yet. Ignored when `required` is true. */
14
- default?: boolean;
15
- /** Vendor identifiers (e.g. 'plausible', 'google-ads') used for jurisdiction classification. */
16
- vendors?: string[];
17
- /** Human-readable description shown in the banner / preference centre. */
18
- description?: string;
19
- /**
20
- * Override the inferred mode for this category. Normally not needed —
21
- * the jurisdiction + vendor list determines the mode.
22
- */
23
- mode?: ConsentMode;
24
- };
25
- type JurisdictionId = 'UK_DUAA' | 'EU_GDPR' | 'US_CA' | 'CCPA' | (string & {});
26
- type Jurisdiction = {
27
- id: JurisdictionId;
28
- name: string;
29
- /**
30
- * Per-vendor classification: which vendors require full consent vs. notice-only
31
- * vs. always-allowed under this jurisdiction.
32
- */
33
- vendorRules: Record<string, ConsentMode>;
34
- /** Default mode applied to vendors not in `vendorRules`. */
35
- defaultMode: ConsentMode;
36
- /** UI requirements imposed by the jurisdiction. */
37
- ui: {
38
- /** Whether a "Reject All" button is required on the first banner layer. */
39
- rejectButtonOnFirstLayer: boolean;
40
- /** Whether Accept/Reject must have equal visual prominence. */
41
- equalProminence: boolean;
42
- /** Whether Global Privacy Control (Sec-GPC) signals must be honoured as opt-out. */
43
- honorGPC: boolean;
44
- };
45
- /** Optional ISO 3166-1 alpha-2 country codes that map to this jurisdiction (used by 'auto' mode). */
46
- countries?: readonly string[];
47
- };
48
- type ConsentConfig = {
49
- /**
50
- * The jurisdiction governing this site, or `'auto'` to detect by visitor country.
51
- * 'auto' falls back to the strictest available match.
52
- */
53
- jurisdiction: Jurisdiction | 'auto';
54
- /** Map of category ID to definition. The keys are arbitrary (e.g. 'analytics', 'marketing'). */
55
- categories: Record<CategoryId, CategoryDefinition>;
56
- /** Versioned policy reference. Audit log entries are tied to a policy version. */
57
- policy?: {
58
- version: string;
59
- url?: string;
60
- };
61
- /** Cloud configuration. If omitted, the SDK runs entirely client-side with no telemetry. */
62
- cloud?: {
63
- apiKey?: string;
64
- /** Override the default ingest endpoint. Useful for self-hosting. */
65
- endpoint?: string;
66
- };
67
- /** Cookie storage options. */
68
- storage?: StorageOptions;
69
- };
70
- type StorageOptions = {
71
- /** Cookie name. Defaults to `__tb_consent`. */
72
- cookieName?: string;
73
- /** Optional Domain attribute (e.g. '.example.com' to share across subdomains). */
74
- domain?: string;
75
- /** Cookie max-age in days. Defaults to 365. */
76
- maxAgeDays?: number;
77
- };
78
- /**
79
- * The serialised consent record stored in the browser cookie.
80
- * Schema is versioned via `v` so future migrations don't break readers.
81
- */
82
- type StoredConsent = {
83
- /** Schema version. */
84
- v: 1;
85
- /** Map of category ID to granted/denied. */
86
- c: Record<CategoryId, boolean>;
87
- /** Policy version at the time of choice. */
88
- pv: string;
89
- /** Unix epoch milliseconds when the choice was made. */
90
- ts: number;
91
- /** Jurisdiction ID at the time of choice. */
92
- j: JurisdictionId;
93
- };
94
- /**
95
- * A category resolved against the active jurisdiction — what the SDK actually
96
- * needs to know to render UI and gate scripts.
97
- */
98
- type ResolvedCategory = {
99
- id: CategoryId;
100
- required: boolean;
101
- mode: ConsentMode;
102
- default: boolean;
103
- vendors: string[];
104
- description?: string;
105
- };
106
-
107
- /**
108
- * United Kingdom — Data (Use and Access) Act 2025 (DUAA).
109
- *
110
- * In force from 5 February 2026. Amends PECR to introduce new exemptions for
111
- * cookies/storage used solely for statistical, security, authentication, and
112
- * appearance purposes. Advertising and individual-level tracking still require
113
- * full opt-in consent.
114
- *
115
- * UI requirements (ICO):
116
- * - "Reject All" must be on the first banner layer
117
- * - "Accept All" and "Reject All" must have equal visual prominence
118
- * - GPC is not (yet) mandatory in UK guidance; default off.
119
- *
120
- * @see https://ico.org.uk/for-organisations/direct-marketing-and-privacy-and-electronic-communications/guide-to-pecr/cookies-and-similar-technologies/
121
- */
122
- declare const UK_DUAA: Jurisdiction;
123
-
124
- /**
125
- * European Union — GDPR + ePrivacy Directive ("Cookie Law").
126
- *
127
- * EU rules don't have the DUAA "statistical exemption" — analytics that
128
- * involve client-side storage on a user's device generally require opt-in
129
- * consent, even for first-party privacy-friendly tools (positions vary by
130
- * DPA; CNIL has been more permissive than others). This preset takes the
131
- * conservative position: treat all tracking categories as consent-required.
132
- *
133
- * UI requirements (EDPB / national DPAs):
134
- * - "Reject All" on first banner layer with equal prominence
135
- * - GPC: not yet mandatory but increasingly recognised
136
- */
137
- declare const EU_GDPR: Jurisdiction;
138
-
139
- /**
140
- * Map of all built-in jurisdiction presets, keyed by their ID for ergonomic
141
- * lookup: `jurisdictions.UK_DUAA`.
142
- */
143
- declare const jurisdictions: {
144
- readonly UK_DUAA: Jurisdiction;
145
- readonly EU_GDPR: Jurisdiction;
146
- };
147
- /**
148
- * Resolve a jurisdiction from an ISO 3166-1 alpha-2 country code (e.g. 'GB').
149
- * Falls back to `EU_GDPR` for any country not explicitly mapped — the safer
150
- * default for an unknown EEA visitor. Returns `null` when the code is unknown
151
- * and no fallback is requested.
152
- */
153
- declare function resolveJurisdictionByCountry(country: string | undefined, fallback?: Jurisdiction | null): Jurisdiction | null;
154
-
155
- export { type ConsentConfig as C, EU_GDPR as E, type Jurisdiction as J, type ResolvedCategory as R, type StorageOptions as S, UK_DUAA as U, type StoredConsent as a, type CategoryDefinition as b, type CategoryId as c, type ConsentMode as d, type JurisdictionId as e, jurisdictions as j, resolveJurisdictionByCountry as r };