@tickboxhq/core 0.0.6 → 0.0.7

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.
@@ -45,6 +45,51 @@ type Jurisdiction = {
45
45
  /** Optional ISO 3166-1 alpha-2 country codes that map to this jurisdiction (used by 'auto' mode). */
46
46
  countries?: readonly string[];
47
47
  };
48
+ /**
49
+ * The seven Google Consent Mode v2 storage / signal keys.
50
+ * @see https://developers.google.com/tag-platform/security/guides/consent
51
+ */
52
+ type GtagConsentKey = 'ad_storage' | 'ad_user_data' | 'ad_personalization' | 'analytics_storage' | 'functionality_storage' | 'personalization_storage' | 'security_storage';
53
+ /**
54
+ * Rule that maps one gtag consent key to a Tickbox category.
55
+ *
56
+ * - `category`: the consent category ID (from `ConsentConfig.categories`) that
57
+ * controls this gtag key. When the category flips granted/denied, the gtag
58
+ * key flips with it.
59
+ * - `default`: the value sent when the category is absent from the user's
60
+ * stored decisions, or when `category` itself is omitted. If omitted,
61
+ * defaults to `'denied'` for ad/analytics keys and `'granted'` for
62
+ * functionality/personalization/security keys.
63
+ */
64
+ type ConsentModeRule = {
65
+ category?: string;
66
+ default?: 'granted' | 'denied';
67
+ };
68
+ /**
69
+ * Custom mapping from Tickbox category IDs to Google Consent Mode v2 keys.
70
+ *
71
+ * Merged shallowly with the built-in defaults, so any keys you don't override
72
+ * keep their defaults. Pass `null` for a key to remove it from the
73
+ * `gtag('consent','update', ...)` call entirely.
74
+ *
75
+ * @example
76
+ * ```ts
77
+ * defineConsent({
78
+ * categories: {
79
+ * necessary: { required: true },
80
+ * advertising: { vendors: [...], default: false }, // not 'marketing'
81
+ * stats: { vendors: ['plausible'] }, // not 'analytics'
82
+ * },
83
+ * consentMode: {
84
+ * ad_storage: { category: 'advertising' },
85
+ * ad_user_data: { category: 'advertising' },
86
+ * ad_personalization: { category: 'advertising' },
87
+ * analytics_storage: { category: 'stats' },
88
+ * },
89
+ * })
90
+ * ```
91
+ */
92
+ type ConsentModeMapping = Partial<Record<GtagConsentKey, ConsentModeRule | null>>;
48
93
  type ConsentConfig = {
49
94
  /**
50
95
  * The jurisdiction governing this site, or `'auto'` to detect by visitor country.
@@ -66,6 +111,11 @@ type ConsentConfig = {
66
111
  };
67
112
  /** Cookie storage options. */
68
113
  storage?: StorageOptions;
114
+ /**
115
+ * Override the default Tickbox-category → Google Consent Mode v2 key
116
+ * mapping. Merged shallowly with the built-in defaults.
117
+ */
118
+ consentMode?: ConsentModeMapping;
69
119
  };
70
120
  type StorageOptions = {
71
121
  /** Cookie name. Defaults to `__tb_consent`. */
@@ -218,4 +268,4 @@ declare const jurisdictions: {
218
268
  */
219
269
  declare function resolveJurisdictionByCountry(country: string | undefined, fallback?: Jurisdiction | null): Jurisdiction | null;
220
270
 
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 };
271
+ export { ADVERTISING_VENDORS as A, type ConsentConfig as C, EU_GDPR as E, type GtagConsentKey as G, 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 ConsentModeMapping as a, type StoredConsent as b, type CategoryDefinition as c, type CategoryId as d, type ConsentMode as e, type ConsentModeRule as f, type JurisdictionId as g, AI_TRAINING_CRAWLERS as h, ALL_TRACKING_VENDORS as i, jurisdictions as j, CDP_AND_PRODUCT_ANALYTICS as k, CHAT_WIDGETS as l, SESSION_REPLAY_VENDORS as m, resolveJurisdictionByCountry as r };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as ConsentConfig, R as ResolvedCategory, 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';
1
+ import { C as ConsentConfig, R as ResolvedCategory, S as StorageOptions, J as Jurisdiction, a as ConsentModeMapping, b as StoredConsent } from './index-DKbTmpmB.js';
2
+ export { c as CategoryDefinition, d as CategoryId, e as ConsentMode, f as ConsentModeRule, G as GtagConsentKey, g as JurisdictionId, j as jurisdictions, r as resolveJurisdictionByCountry } from './index-DKbTmpmB.js';
3
3
 
4
4
  type AiTxtOptions = {
5
5
  /** Site URL — included as a comment for human readers and crawlers. */
@@ -122,6 +122,15 @@ declare class ConsentStore {
122
122
  * On deny, the script is left as `text/plain` (browser ignores it).
123
123
  */
124
124
  declare const TAG_ATTRIBUTE = "data-tb-category";
125
+ type ApplyOptions = {
126
+ /**
127
+ * Override which Tickbox categories drive which gtag consent keys.
128
+ * Merged shallowly with the built-in defaults — any keys you don't
129
+ * override keep their defaults. Pass `null` for a key to remove it from
130
+ * the `gtag('consent','update', ...)` call entirely.
131
+ */
132
+ consentMode?: ConsentModeMapping;
133
+ };
125
134
  /**
126
135
  * Apply a consent state to the document by:
127
136
  * 1. Activating any `<script type="text/plain" data-tb-category="X">` whose category was granted
@@ -130,7 +139,7 @@ declare const TAG_ATTRIBUTE = "data-tb-category";
130
139
  *
131
140
  * No-op on the server.
132
141
  */
133
- declare function applyConsent(state: ConsentState): void;
142
+ declare function applyConsent(state: ConsentState, options?: ApplyOptions): void;
134
143
 
135
144
  /**
136
145
  * Identity helper that narrows the type of a consent config so users get
@@ -192,4 +201,4 @@ declare function writeConsent(value: StoredConsent, options?: StorageOptions): v
192
201
  /** Clear the stored consent cookie. */
193
202
  declare function clearConsent(options?: StorageOptions): void;
194
203
 
195
- export { type AiTxtOptions, ConsentConfig, type ConsentState, ConsentStore, Jurisdiction, ResolvedCategory, StorageOptions, type StoreOptions, StoredConsent, TAG_ATTRIBUTE, applyConsent, clearConsent, defineConsent, generateAiBotRobotsRules, generateAiTxt, isGPCSignaled, parseConsentFromHeader, readConsent, resolveCategories, writeConsent };
204
+ export { type AiTxtOptions, type ApplyOptions, ConsentConfig, ConsentModeMapping, type ConsentState, ConsentStore, Jurisdiction, ResolvedCategory, StorageOptions, type StoreOptions, StoredConsent, TAG_ATTRIBUTE, applyConsent, clearConsent, defineConsent, generateAiBotRobotsRules, generateAiTxt, isGPCSignaled, parseConsentFromHeader, readConsent, resolveCategories, writeConsent };
package/dist/index.js CHANGED
@@ -153,10 +153,28 @@ ${sections.join("\n")}`;
153
153
 
154
154
  // src/apply.ts
155
155
  var TAG_ATTRIBUTE = "data-tb-category";
156
- function applyConsent(state) {
156
+ var DEFAULT_CONSENT_MODE = {
157
+ ad_storage: { category: "marketing", default: "denied" },
158
+ ad_user_data: { category: "marketing", default: "denied" },
159
+ ad_personalization: { category: "marketing", default: "denied" },
160
+ analytics_storage: { category: "analytics", default: "denied" },
161
+ functionality_storage: { category: "functional", default: "granted" },
162
+ personalization_storage: { category: "preferences", default: "granted" },
163
+ security_storage: { default: "granted" }
164
+ };
165
+ var ALL_KEYS = [
166
+ "ad_storage",
167
+ "ad_user_data",
168
+ "ad_personalization",
169
+ "analytics_storage",
170
+ "functionality_storage",
171
+ "personalization_storage",
172
+ "security_storage"
173
+ ];
174
+ function applyConsent(state, options = {}) {
157
175
  if (typeof document === "undefined") return;
158
176
  activateScripts(state.decisions);
159
- updateConsentMode(state.decisions);
177
+ updateConsentMode(state.decisions, options.consentMode);
160
178
  dispatchEvent(state);
161
179
  }
162
180
  function activateScripts(decisions) {
@@ -173,22 +191,23 @@ function activateScripts(decisions) {
173
191
  node.parentNode?.replaceChild(replacement, node);
174
192
  }
175
193
  }
176
- function updateConsentMode(decisions) {
194
+ function updateConsentMode(decisions, mappingOverride) {
177
195
  const win = globalThis;
178
196
  if (typeof win.gtag !== "function") return;
179
- win.gtag("consent", "update", {
180
- ad_storage: gv(decisions, "marketing"),
181
- ad_user_data: gv(decisions, "marketing"),
182
- ad_personalization: gv(decisions, "marketing"),
183
- analytics_storage: gv(decisions, "analytics"),
184
- functionality_storage: gv(decisions, "functional", true),
185
- personalization_storage: gv(decisions, "preferences", true),
186
- security_storage: "granted"
187
- });
197
+ const params = {};
198
+ for (const key of ALL_KEYS) {
199
+ const override = mappingOverride?.[key];
200
+ if (override === null) continue;
201
+ const rule = override ?? DEFAULT_CONSENT_MODE[key];
202
+ params[key] = resolveValue(decisions, rule);
203
+ }
204
+ if (Object.keys(params).length === 0) return;
205
+ win.gtag("consent", "update", params);
188
206
  }
189
- function gv(decisions, id, defaultGranted = false) {
190
- const value = decisions[id];
191
- if (value === void 0) return defaultGranted ? "granted" : "denied";
207
+ function resolveValue(decisions, rule) {
208
+ if (!rule.category) return rule.default ?? "denied";
209
+ const value = decisions[rule.category];
210
+ if (value === void 0) return rule.default ?? "denied";
192
211
  return value ? "granted" : "denied";
193
212
  }
194
213
  function dispatchEvent(state) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/jurisdictions/vendors.ts","../src/ai-txt.ts","../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":["/**\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 { AI_TRAINING_CRAWLERS } from './jurisdictions/vendors.js'\nimport type { ConsentConfig } from './types.js'\n\n/**\n * Map our internal vendor identifiers to the User-Agent strings each AI\n * crawler advertises. Used by `generateAiBotRobotsRules`. Keep this in sync\n * with `AI_TRAINING_CRAWLERS` in jurisdictions/vendors.ts.\n */\nconst VENDOR_TO_USER_AGENT: Record<string, string> = {\n gptbot: 'GPTBot',\n claudebot: 'ClaudeBot',\n 'anthropic-ai': 'anthropic-ai',\n 'google-extended': 'Google-Extended',\n perplexitybot: 'PerplexityBot',\n ccbot: 'CCBot',\n bytespider: 'Bytespider',\n 'applebot-extended': 'Applebot-Extended',\n 'meta-externalagent': 'meta-externalagent',\n 'oai-searchbot': 'OAI-SearchBot',\n}\n\nexport type AiTxtOptions = {\n /** Site URL — included as a comment for human readers and crawlers. */\n siteUrl?: string\n}\n\n/**\n * Whether the site's effective stance is to deny AI training. True when:\n * - The config has no `ai_training` category at all (safer default)\n * - Or `ai_training.default !== true`\n *\n * Granting AI training requires an explicit `default: true` opt-in.\n */\nfunction isAiTrainingDenied(config: ConsentConfig): boolean {\n const cat = config.categories.ai_training\n if (!cat) return true\n if (cat.required) return false\n return cat.default !== true\n}\n\n/**\n * Generate the contents of `/ai.txt` (Spawning.ai-compatible format).\n *\n * Returns a robots.txt-style plain-text file declaring the site's AI\n * training policy based on the `ai_training` category. If the category\n * isn't declared, defaults to disallow — the safer position under the\n * EU AI Act Article 53 framework where machine-readable opt-outs are\n * legally enforceable from August 2026.\n *\n * @example\n * ```ts\n * generateAiTxt(config, { siteUrl: 'https://example.com' })\n * // → \"# https://example.com/ai.txt\n * // # Generated by Tickbox from consent.config.ts\n * // # Policy version: 2026-05-06\n * //\n * // User-Agent: *\n * // Disallow: /\n * // \"\n * ```\n */\nexport function generateAiTxt(config: ConsentConfig, options: AiTxtOptions = {}): string {\n const denied = isAiTrainingDenied(config)\n const lines: string[] = []\n if (options.siteUrl) {\n const trimmed = options.siteUrl.replace(/\\/+$/, '')\n lines.push(`# ${trimmed}/ai.txt`)\n }\n lines.push('# Generated by Tickbox from consent.config.ts')\n if (config.policy?.version) {\n lines.push(`# Policy version: ${config.policy.version}`)\n }\n lines.push('')\n lines.push('User-Agent: *')\n lines.push(denied ? 'Disallow: /' : 'Allow: /')\n return `${lines.join('\\n')}\\n`\n}\n\n/**\n * Generate a robots.txt fragment with Disallow rules for AI training\n * crawlers based on the `ai_training` category in the config.\n *\n * If `ai_training.vendors` is non-empty, only those crawlers are listed.\n * If absent or empty, all crawlers in `AI_TRAINING_CRAWLERS` are listed.\n * If AI training is allowed, returns a single comment line so the caller\n * can still concatenate it into their robots.txt without conditional logic.\n *\n * Append this to your existing robots.txt content.\n *\n * @example\n * ```ts\n * const robotsTxt = `${userExistingRobotsRules}\\n\\n${generateAiBotRobotsRules(config)}`\n * ```\n */\nexport function generateAiBotRobotsRules(config: ConsentConfig): string {\n const denied = isAiTrainingDenied(config)\n if (!denied) {\n return '# AI training: allowed for all crawlers\\n'\n }\n\n const cat = config.categories.ai_training\n const declaredVendors = cat?.vendors ?? []\n const vendorList =\n declaredVendors.length > 0 ? declaredVendors : (AI_TRAINING_CRAWLERS as readonly string[])\n\n const userAgents = vendorList\n .map((v) => VENDOR_TO_USER_AGENT[v])\n .filter((ua): ua is string => Boolean(ua))\n\n if (userAgents.length === 0) {\n return '# AI training: denied (no known crawlers in config)\\n'\n }\n\n const sections = userAgents.map((ua) => `User-agent: ${ua}\\nDisallow: /\\n`)\n return `# AI training crawlers — blocked\\n${sections.join('\\n')}`\n}\n","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 { 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
+ {"version":3,"sources":["../src/jurisdictions/vendors.ts","../src/ai-txt.ts","../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":["/**\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 { AI_TRAINING_CRAWLERS } from './jurisdictions/vendors.js'\nimport type { ConsentConfig } from './types.js'\n\n/**\n * Map our internal vendor identifiers to the User-Agent strings each AI\n * crawler advertises. Used by `generateAiBotRobotsRules`. Keep this in sync\n * with `AI_TRAINING_CRAWLERS` in jurisdictions/vendors.ts.\n */\nconst VENDOR_TO_USER_AGENT: Record<string, string> = {\n gptbot: 'GPTBot',\n claudebot: 'ClaudeBot',\n 'anthropic-ai': 'anthropic-ai',\n 'google-extended': 'Google-Extended',\n perplexitybot: 'PerplexityBot',\n ccbot: 'CCBot',\n bytespider: 'Bytespider',\n 'applebot-extended': 'Applebot-Extended',\n 'meta-externalagent': 'meta-externalagent',\n 'oai-searchbot': 'OAI-SearchBot',\n}\n\nexport type AiTxtOptions = {\n /** Site URL — included as a comment for human readers and crawlers. */\n siteUrl?: string\n}\n\n/**\n * Whether the site's effective stance is to deny AI training. True when:\n * - The config has no `ai_training` category at all (safer default)\n * - Or `ai_training.default !== true`\n *\n * Granting AI training requires an explicit `default: true` opt-in.\n */\nfunction isAiTrainingDenied(config: ConsentConfig): boolean {\n const cat = config.categories.ai_training\n if (!cat) return true\n if (cat.required) return false\n return cat.default !== true\n}\n\n/**\n * Generate the contents of `/ai.txt` (Spawning.ai-compatible format).\n *\n * Returns a robots.txt-style plain-text file declaring the site's AI\n * training policy based on the `ai_training` category. If the category\n * isn't declared, defaults to disallow — the safer position under the\n * EU AI Act Article 53 framework where machine-readable opt-outs are\n * legally enforceable from August 2026.\n *\n * @example\n * ```ts\n * generateAiTxt(config, { siteUrl: 'https://example.com' })\n * // → \"# https://example.com/ai.txt\n * // # Generated by Tickbox from consent.config.ts\n * // # Policy version: 2026-05-06\n * //\n * // User-Agent: *\n * // Disallow: /\n * // \"\n * ```\n */\nexport function generateAiTxt(config: ConsentConfig, options: AiTxtOptions = {}): string {\n const denied = isAiTrainingDenied(config)\n const lines: string[] = []\n if (options.siteUrl) {\n const trimmed = options.siteUrl.replace(/\\/+$/, '')\n lines.push(`# ${trimmed}/ai.txt`)\n }\n lines.push('# Generated by Tickbox from consent.config.ts')\n if (config.policy?.version) {\n lines.push(`# Policy version: ${config.policy.version}`)\n }\n lines.push('')\n lines.push('User-Agent: *')\n lines.push(denied ? 'Disallow: /' : 'Allow: /')\n return `${lines.join('\\n')}\\n`\n}\n\n/**\n * Generate a robots.txt fragment with Disallow rules for AI training\n * crawlers based on the `ai_training` category in the config.\n *\n * If `ai_training.vendors` is non-empty, only those crawlers are listed.\n * If absent or empty, all crawlers in `AI_TRAINING_CRAWLERS` are listed.\n * If AI training is allowed, returns a single comment line so the caller\n * can still concatenate it into their robots.txt without conditional logic.\n *\n * Append this to your existing robots.txt content.\n *\n * @example\n * ```ts\n * const robotsTxt = `${userExistingRobotsRules}\\n\\n${generateAiBotRobotsRules(config)}`\n * ```\n */\nexport function generateAiBotRobotsRules(config: ConsentConfig): string {\n const denied = isAiTrainingDenied(config)\n if (!denied) {\n return '# AI training: allowed for all crawlers\\n'\n }\n\n const cat = config.categories.ai_training\n const declaredVendors = cat?.vendors ?? []\n const vendorList =\n declaredVendors.length > 0 ? declaredVendors : (AI_TRAINING_CRAWLERS as readonly string[])\n\n const userAgents = vendorList\n .map((v) => VENDOR_TO_USER_AGENT[v])\n .filter((ua): ua is string => Boolean(ua))\n\n if (userAgents.length === 0) {\n return '# AI training: denied (no known crawlers in config)\\n'\n }\n\n const sections = userAgents.map((ua) => `User-agent: ${ua}\\nDisallow: /\\n`)\n return `# AI training crawlers — blocked\\n${sections.join('\\n')}`\n}\n","import type { ConsentState } from './store.js'\nimport type { ConsentModeMapping, ConsentModeRule, GtagConsentKey } from './types.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 * Built-in default mapping. Each gtag consent key is wired to a sensible\n * Tickbox category, with a sensible default for when that category isn't\n * declared on the user's site.\n */\nconst DEFAULT_CONSENT_MODE: Record<GtagConsentKey, ConsentModeRule> = {\n ad_storage: { category: 'marketing', default: 'denied' },\n ad_user_data: { category: 'marketing', default: 'denied' },\n ad_personalization: { category: 'marketing', default: 'denied' },\n analytics_storage: { category: 'analytics', default: 'denied' },\n functionality_storage: { category: 'functional', default: 'granted' },\n personalization_storage: { category: 'preferences', default: 'granted' },\n security_storage: { default: 'granted' },\n}\n\nconst ALL_KEYS: readonly GtagConsentKey[] = [\n 'ad_storage',\n 'ad_user_data',\n 'ad_personalization',\n 'analytics_storage',\n 'functionality_storage',\n 'personalization_storage',\n 'security_storage',\n]\n\nexport type ApplyOptions = {\n /**\n * Override which Tickbox categories drive which gtag consent keys.\n * Merged shallowly with the built-in defaults — any keys you don't\n * override keep their defaults. Pass `null` for a key to remove it from\n * the `gtag('consent','update', ...)` call entirely.\n */\n consentMode?: ConsentModeMapping\n}\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, options: ApplyOptions = {}): void {\n if (typeof document === 'undefined') return\n activateScripts(state.decisions)\n updateConsentMode(state.decisions, options.consentMode)\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(\n decisions: Record<string, boolean>,\n mappingOverride: ConsentModeMapping | undefined,\n): void {\n const win = globalThis as unknown as { gtag?: Gtag }\n if (typeof win.gtag !== 'function') return\n\n const params: Record<string, 'granted' | 'denied'> = {}\n\n for (const key of ALL_KEYS) {\n const override = mappingOverride?.[key]\n // Explicit null → user opts this key out of the gtag call.\n if (override === null) continue\n const rule = override ?? DEFAULT_CONSENT_MODE[key]\n params[key] = resolveValue(decisions, rule)\n }\n\n // Nothing to send (every key was nulled).\n if (Object.keys(params).length === 0) return\n\n win.gtag('consent', 'update', params)\n}\n\nfunction resolveValue(\n decisions: Record<string, boolean>,\n rule: ConsentModeRule,\n): 'granted' | 'denied' {\n // No category → static value.\n if (!rule.category) return rule.default ?? 'denied'\n const value = decisions[rule.category]\n if (value === undefined) return rule.default ?? '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 { 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 { 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
+ export { A as ADVERTISING_VENDORS, h as AI_TRAINING_CRAWLERS, i as ALL_TRACKING_VENDORS, k as CDP_AND_PRODUCT_ANALYTICS, l as CHAT_WIDGETS, E as EU_GDPR, M as MARKETING_AUTOMATION, P as PRIVACY_FRIENDLY_ANALYTICS, m as SESSION_REPLAY_VENDORS, U as UK_DUAA, j as jurisdictions, r as resolveJurisdictionByCountry } from '../index-DKbTmpmB.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tickboxhq/core",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "Core types, jurisdictions, and storage primitives for Tickbox consent management",
5
5
  "license": "MIT",
6
6
  "homepage": "https://tickbox.dev",