@cookieyes/core 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/categories-D1vlERV6.d.ts +776 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +60 -739
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations.cjs +2 -0
- package/dist/integrations.cjs.map +1 -0
- package/dist/integrations.d.ts +1 -0
- package/dist/integrations.js +2 -0
- package/dist/integrations.js.map +1 -0
- package/dist/network-blocker--Z2J__Xr.cjs +2 -0
- package/dist/network-blocker--Z2J__Xr.cjs.map +1 -0
- package/dist/network-blocker-zdjGiuQN.js +2 -0
- package/dist/network-blocker-zdjGiuQN.js.map +1 -0
- package/dist/network-blocker.cjs +2 -0
- package/dist/network-blocker.cjs.map +1 -0
- package/dist/network-blocker.d.ts +1 -0
- package/dist/network-blocker.js +2 -0
- package/dist/network-blocker.js.map +1 -0
- package/package.json +6 -1
|
@@ -0,0 +1,776 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The integration format — the shared contract between the consent engine and
|
|
3
|
+
* every vendor preset (Google, Segment, Meta, …). It carries no vendor
|
|
4
|
+
* knowledge; a preset in `@cookieyes/scripts` fills it in.
|
|
5
|
+
*
|
|
6
|
+
* Two plain axes describe every vendor:
|
|
7
|
+
* - `load`: when the vendor starts — right away, or only after consent.
|
|
8
|
+
* - `onRevoke`: what happens when consent is withdrawn — one of three modes.
|
|
9
|
+
*
|
|
10
|
+
* `onRevoke` is declarative (readable without running `setup`, so a debug view
|
|
11
|
+
* or a version check can inspect it), and it's a discriminated union so the
|
|
12
|
+
* compiler forces the matching handler — you can't declare `"silence"` with no
|
|
13
|
+
* way to actually silence.
|
|
14
|
+
*/
|
|
15
|
+
type Cleanup = () => void;
|
|
16
|
+
type SilenceControl = {
|
|
17
|
+
silence: () => void;
|
|
18
|
+
resume: () => void;
|
|
19
|
+
};
|
|
20
|
+
/** What a vendor's `setup` receives from the engine. */
|
|
21
|
+
type SetupCtx = {
|
|
22
|
+
/** Is this integration's category currently committed-granted? */
|
|
23
|
+
granted: () => boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Subscribe to committed-consent changes; returns an unsubscribe function.
|
|
26
|
+
* `keep` vendors (e.g. Google Consent Mode) use this to emit their own
|
|
27
|
+
* updates on every change. The engine also releases these automatically when
|
|
28
|
+
* the integration is torn down, so a vendor listener never outlives it.
|
|
29
|
+
*/
|
|
30
|
+
onConsentChange: (fn: () => void) => () => void;
|
|
31
|
+
/** Resolved region/regulation — for a vendor's US-state privacy switch. */
|
|
32
|
+
region: RegionDecision;
|
|
33
|
+
};
|
|
34
|
+
type Base = {
|
|
35
|
+
id: string;
|
|
36
|
+
/**
|
|
37
|
+
* The consent category (or categories) that gate this integration. Pass an
|
|
38
|
+
* array to require more than one — combined with {@link Base.match}.
|
|
39
|
+
*/
|
|
40
|
+
category: ConsentCategory | ConsentCategory[];
|
|
41
|
+
/**
|
|
42
|
+
* How to combine multiple categories: `"all"` (default) needs every one
|
|
43
|
+
* granted; `"any"` needs at least one. Ignored for a single category.
|
|
44
|
+
*/
|
|
45
|
+
match?: "all" | "any";
|
|
46
|
+
/** Format version; an unknown version is refused (see {@link runIntegrations}). */
|
|
47
|
+
version: number;
|
|
48
|
+
/**
|
|
49
|
+
* When to start. Note: `setup` always runs on a microtask, so `immediately`
|
|
50
|
+
* is *very early* but not synchronous / same-tick. The truly-first-thing case
|
|
51
|
+
* (Consent Mode's deny-default before any tag fires) is the server `<head>`
|
|
52
|
+
* snippet's job, not the engine's.
|
|
53
|
+
*/
|
|
54
|
+
load: "immediately" | "afterConsent";
|
|
55
|
+
};
|
|
56
|
+
type Integration = Base & ({
|
|
57
|
+
onRevoke: "keep";
|
|
58
|
+
setup: (ctx: SetupCtx) => void | Promise<void>;
|
|
59
|
+
} | {
|
|
60
|
+
onRevoke: "remove";
|
|
61
|
+
setup: (ctx: SetupCtx) => Cleanup | Promise<Cleanup>;
|
|
62
|
+
} | {
|
|
63
|
+
onRevoke: "silence";
|
|
64
|
+
setup: (ctx: SetupCtx) => SilenceControl | Promise<SilenceControl>;
|
|
65
|
+
});
|
|
66
|
+
/** The format version this engine understands. Bump on a breaking format change. */
|
|
67
|
+
declare const INTEGRATION_FORMAT_VERSION = 1;
|
|
68
|
+
/**
|
|
69
|
+
* Warn when a vendor is configured on both sides — a new `integrations` preset
|
|
70
|
+
* whose id matches a deprecated `builtInIntegrations` vendor. Both would run,
|
|
71
|
+
* which for a tracker means double-counted events (the DEVP-38 double-pixel).
|
|
72
|
+
* Preset ids are the vendor's canonical name (`"segment"`, `"meta"`, …), which
|
|
73
|
+
* is exactly the built-in vendor name, so the match is a plain id === vendor.
|
|
74
|
+
*/
|
|
75
|
+
declare function warnOverlappingVendors(integrationIds: string[], builtInVendors: string[]): void;
|
|
76
|
+
/**
|
|
77
|
+
* Warn when an `afterConsent` integration is gated on a category that isn't in
|
|
78
|
+
* the configured taxonomy — otherwise it waits for consent that can never be
|
|
79
|
+
* granted and silently never loads. A common trap with a custom `categories`
|
|
80
|
+
* list plus a preset left on its default category (e.g. `segment()` → "analytics").
|
|
81
|
+
* `immediately` integrations aren't gated by category, so they're not checked.
|
|
82
|
+
*/
|
|
83
|
+
declare function warnUnknownCategories(integrations: Integration[], knownCategoryIds: string[]): void;
|
|
84
|
+
/** Live status of one integration — read by the debug/self-check view. */
|
|
85
|
+
type IntegrationStatus = "idle" | "loading" | "active" | "silenced" | "removed" | "error";
|
|
86
|
+
/** What the engine needs from the consent runtime — framework-agnostic. */
|
|
87
|
+
type IntegrationHost = {
|
|
88
|
+
/** Committed-granted state for a category (never the unsaved toggle). */
|
|
89
|
+
granted: (category: ConsentCategory) => boolean;
|
|
90
|
+
/** Subscribe to committed-consent changes; returns unsubscribe. */
|
|
91
|
+
subscribe: (fn: () => void) => () => void;
|
|
92
|
+
region: RegionDecision;
|
|
93
|
+
};
|
|
94
|
+
/** One row for a debug view: an integration's config plus its live status. */
|
|
95
|
+
type IntegrationDebugInfo = {
|
|
96
|
+
id: string;
|
|
97
|
+
category: ConsentCategory | ConsentCategory[];
|
|
98
|
+
load: "immediately" | "afterConsent";
|
|
99
|
+
onRevoke: "keep" | "remove" | "silence";
|
|
100
|
+
status: IntegrationStatus;
|
|
101
|
+
};
|
|
102
|
+
type IntegrationRunner = {
|
|
103
|
+
/** Current status per integration id — the debug/self-check view reads this. */
|
|
104
|
+
status: () => Record<string, IntegrationStatus>;
|
|
105
|
+
/**
|
|
106
|
+
* Config + live status for every registered integration, in order — the data
|
|
107
|
+
* for a debug view (e.g. `console.table(runner.list())`).
|
|
108
|
+
*/
|
|
109
|
+
list: () => IntegrationDebugInfo[];
|
|
110
|
+
/**
|
|
111
|
+
* Tear the runner down: stop reconciling, release every vendor's
|
|
112
|
+
* consent-change listener, and undo each loaded vendor — `remove` runs its
|
|
113
|
+
* cleanup, `silence` is silenced. `keep` vendors' scripts stay (that's the
|
|
114
|
+
* mode), but their listeners are still released. Safe to call more than once.
|
|
115
|
+
*/
|
|
116
|
+
stop: () => void;
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Run a set of integrations against the consent runtime. Reconciles each one on
|
|
120
|
+
* load and on every committed-consent change:
|
|
121
|
+
* - not loaded → load it (immediately, or once its category is granted)
|
|
122
|
+
* - `keep` → nothing on revoke (the vendor manages its own update)
|
|
123
|
+
* - `remove` → run cleanup on revoke; re-load on re-grant
|
|
124
|
+
* - `silence` → call `silence()` on revoke; `resume()` on re-grant
|
|
125
|
+
*
|
|
126
|
+
* `setup` may be async and may fail; a failure marks the integration `error`
|
|
127
|
+
* and is retried on the next trigger (never loops on its own). Nothing here
|
|
128
|
+
* throws into the host.
|
|
129
|
+
*/
|
|
130
|
+
declare function runIntegrations(integrations: Integration[], host: IntegrationHost): IntegrationRunner;
|
|
131
|
+
|
|
132
|
+
type NetworkBlockerRule = {
|
|
133
|
+
id: string;
|
|
134
|
+
domain: string;
|
|
135
|
+
pathIncludes?: string | undefined;
|
|
136
|
+
methods?: string[] | undefined;
|
|
137
|
+
category: ConsentCategory;
|
|
138
|
+
};
|
|
139
|
+
type BlockedRequestInfo = {
|
|
140
|
+
rule: NetworkBlockerRule;
|
|
141
|
+
url: string;
|
|
142
|
+
method: string;
|
|
143
|
+
};
|
|
144
|
+
type NetworkBlockerConfig = {
|
|
145
|
+
rules: NetworkBlockerRule[];
|
|
146
|
+
onRequestBlocked?: ((info: BlockedRequestInfo) => void) | undefined;
|
|
147
|
+
logBlockedRequests?: boolean | undefined;
|
|
148
|
+
};
|
|
149
|
+
type ConsentChecker = (category: ConsentCategory) => boolean;
|
|
150
|
+
declare function installNetworkBlocker(config: NetworkBlockerConfig, hasConsent: ConsentChecker): () => void;
|
|
151
|
+
declare function uninstallNetworkBlocker(): void;
|
|
152
|
+
/**
|
|
153
|
+
* Register the network blocker so that a configured `networkBlocker` actually
|
|
154
|
+
* installs. Call it once, before your setup call:
|
|
155
|
+
*
|
|
156
|
+
* ```ts
|
|
157
|
+
* import { initCookieYes } from "@cookieyes/core";
|
|
158
|
+
* import { registerNetworkBlocker } from "@cookieyes/core/network-blocker";
|
|
159
|
+
*
|
|
160
|
+
* registerNetworkBlocker();
|
|
161
|
+
* initCookieYes({ mode: "cookie-only", networkBlocker: { rules: [...] } });
|
|
162
|
+
* ```
|
|
163
|
+
*
|
|
164
|
+
* This indirection is what keeps the blocker out of the download for everyone
|
|
165
|
+
* who does not use it. Because it is reached by an ordinary static import, the
|
|
166
|
+
* blocker is already loaded when setup runs and patches the browser's
|
|
167
|
+
* networking immediately — there is no window in which requests slip through,
|
|
168
|
+
* which is the flaw a dynamic import would have introduced. See
|
|
169
|
+
* `network-blocker-slot.ts` for the full reasoning.
|
|
170
|
+
*
|
|
171
|
+
* Idempotent: calling it more than once replaces the registration with the same
|
|
172
|
+
* installer and changes nothing.
|
|
173
|
+
*/
|
|
174
|
+
declare function registerNetworkBlocker(): void;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* A tool that can be stopped (and optionally resumed) at runtime when consent
|
|
178
|
+
* for its category changes — no page reload needed. `stop()` is called when the
|
|
179
|
+
* category is revoked; `resume()` (if provided) when it's re-granted.
|
|
180
|
+
*
|
|
181
|
+
* If `stop()` throws, that tool is treated as "couldn't be stopped cleanly" and
|
|
182
|
+
* falls back to the reload notice for that one tool — it never breaks the page.
|
|
183
|
+
*/
|
|
184
|
+
type StopHandler = {
|
|
185
|
+
id: string;
|
|
186
|
+
category: ConsentCategory;
|
|
187
|
+
stop: () => void;
|
|
188
|
+
resume?: (() => void) | undefined;
|
|
189
|
+
};
|
|
190
|
+
/**
|
|
191
|
+
* A tool with no known clean runtime stop — revoking its category can only be
|
|
192
|
+
* fully applied by reloading the page. Registering one means "if this category
|
|
193
|
+
* is revoked, show the visitor the reload notice."
|
|
194
|
+
*/
|
|
195
|
+
type ReloadOnlyHandler = {
|
|
196
|
+
id: string;
|
|
197
|
+
category: ConsentCategory;
|
|
198
|
+
needsReload: true;
|
|
199
|
+
};
|
|
200
|
+
type AnyStopHandler = StopHandler | ReloadOnlyHandler;
|
|
201
|
+
/**
|
|
202
|
+
* Built-in, first-party integrations. Each maps to either a clean stop-handler
|
|
203
|
+
* or a reload-only marker (see the audit in the README).
|
|
204
|
+
*
|
|
205
|
+
* Note: Google Analytics 4 and Google Tag Manager are **not** listed here.
|
|
206
|
+
* They're governed by Google Consent Mode v2, which the SDK broadcasts
|
|
207
|
+
* automatically whenever a `dataLayer` is present (see google-consent-mode.ts)
|
|
208
|
+
* — on load and on every consent change, derived from each category's `gcm`
|
|
209
|
+
* mapping. So you don't register them as integrations; just add the standard
|
|
210
|
+
* Consent Mode default snippet and the SDK owns the updates.
|
|
211
|
+
*
|
|
212
|
+
* VERIFIED clean-stop vendors (documented, stable runtime opt-out):
|
|
213
|
+
* - `meta` — `fbq('consent','revoke'|'grant')`, Meta's official consent API.
|
|
214
|
+
*
|
|
215
|
+
* The rest have no confident, documented runtime stop, so they're modelled as
|
|
216
|
+
* reload-only (Story 1's honest answer). Upgrading any of them to a clean-stop
|
|
217
|
+
* later is a one-line change here once a real API is confirmed.
|
|
218
|
+
*/
|
|
219
|
+
type BuiltInIntegration = {
|
|
220
|
+
vendor: "meta";
|
|
221
|
+
category?: ConsentCategory | undefined;
|
|
222
|
+
} | {
|
|
223
|
+
vendor: "tiktok";
|
|
224
|
+
category?: ConsentCategory | undefined;
|
|
225
|
+
} | {
|
|
226
|
+
vendor: "linkedin";
|
|
227
|
+
category?: ConsentCategory | undefined;
|
|
228
|
+
} | {
|
|
229
|
+
vendor: "hotjar";
|
|
230
|
+
category?: ConsentCategory | undefined;
|
|
231
|
+
} | {
|
|
232
|
+
vendor: "segment";
|
|
233
|
+
category?: ConsentCategory | undefined;
|
|
234
|
+
};
|
|
235
|
+
declare function resolveBuiltInIntegration(cfg: BuiltInIntegration): AnyStopHandler;
|
|
236
|
+
declare function registerStopHandler(handler: AnyStopHandler): void;
|
|
237
|
+
/** Test-only: reset registry + transition state between cases. */
|
|
238
|
+
declare function _clearStopHandlers(): void;
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* A consent category id. The five built-in ids are offered for autocomplete,
|
|
242
|
+
* but any string is valid — customers can define their own taxonomy via
|
|
243
|
+
* `categories` (see {@link CategoryDef}).
|
|
244
|
+
*/
|
|
245
|
+
type ConsentCategory = "necessary" | "functional" | "analytics" | "performance" | "advertisement" | (string & {});
|
|
246
|
+
type Regulation = "GDPR" | "CCPA" | "DEFAULT";
|
|
247
|
+
/** Display text for one consent category. */
|
|
248
|
+
type CategoryText = {
|
|
249
|
+
label: string;
|
|
250
|
+
description: string;
|
|
251
|
+
};
|
|
252
|
+
type TranslationMap = {
|
|
253
|
+
bannerTitle: string;
|
|
254
|
+
bannerDescription: string;
|
|
255
|
+
acceptAll: string;
|
|
256
|
+
rejectAll: string;
|
|
257
|
+
managePreferences: string;
|
|
258
|
+
savePreferences: string;
|
|
259
|
+
doNotSell: string;
|
|
260
|
+
ccpaDescription: string;
|
|
261
|
+
accept: string;
|
|
262
|
+
poweredBy: string;
|
|
263
|
+
preferencesTitle: string;
|
|
264
|
+
preferencesIntro: string;
|
|
265
|
+
/** Shown in place of a toggle on a category marked `required: true`. */
|
|
266
|
+
alwaysActive: string;
|
|
267
|
+
/** Accessible name of the preferences dialog. */
|
|
268
|
+
preferencesDialogLabel: string;
|
|
269
|
+
/** Accessible name of the opt-out dialog. */
|
|
270
|
+
optOutDialogLabel: string;
|
|
271
|
+
/** Accessible name of the floating recall button. */
|
|
272
|
+
recallButtonLabel: string;
|
|
273
|
+
/** Accessible name of the banner's close button (rendered under CCPA only). */
|
|
274
|
+
bannerCloseLabel: string;
|
|
275
|
+
/** Accessible name of the preferences dialog's close button. */
|
|
276
|
+
preferencesCloseLabel: string;
|
|
277
|
+
/** Accessible name of the opt-out dialog's close button. */
|
|
278
|
+
optOutCloseLabel: string;
|
|
279
|
+
categories: {
|
|
280
|
+
necessary: CategoryText;
|
|
281
|
+
functional: CategoryText;
|
|
282
|
+
analytics: CategoryText;
|
|
283
|
+
performance: CategoryText;
|
|
284
|
+
advertisement: CategoryText;
|
|
285
|
+
} & Record<string, CategoryText>;
|
|
286
|
+
optOut: {
|
|
287
|
+
title: string;
|
|
288
|
+
description: string;
|
|
289
|
+
cancel: string;
|
|
290
|
+
successText: string;
|
|
291
|
+
successCountdown: string;
|
|
292
|
+
};
|
|
293
|
+
gatedFrame: {
|
|
294
|
+
/** Placeholder shown in place of blocked embedded content. `{category}` is substituted. */
|
|
295
|
+
placeholder: string;
|
|
296
|
+
/** Label of the placeholder's button, which opens the preferences dialog. */
|
|
297
|
+
action: string;
|
|
298
|
+
};
|
|
299
|
+
reloadNotice: {
|
|
300
|
+
message: string;
|
|
301
|
+
reloadButton: string;
|
|
302
|
+
dismissButton: string;
|
|
303
|
+
};
|
|
304
|
+
};
|
|
305
|
+
/** A subset of TranslationMap — lets a customer override just a few strings. */
|
|
306
|
+
type DeepPartial<T> = T extends object ? {
|
|
307
|
+
[K in keyof T]?: DeepPartial<T[K]>;
|
|
308
|
+
} : T;
|
|
309
|
+
type PartialTranslations = DeepPartial<TranslationMap>;
|
|
310
|
+
/** Reading direction of a language. */
|
|
311
|
+
type TextDirection = "ltr" | "rtl";
|
|
312
|
+
/** The active language, its reading direction, and the languages currently loaded. */
|
|
313
|
+
type LanguageInfo = {
|
|
314
|
+
language: string;
|
|
315
|
+
direction: TextDirection;
|
|
316
|
+
languages: string[];
|
|
317
|
+
};
|
|
318
|
+
/** Returns the visitor's region synchronously, e.g. "DE" or "US-CA" (or undefined). */
|
|
319
|
+
type RegionDetector = () => string | undefined;
|
|
320
|
+
/** Optional geo-detection: pick the banner's regulation from the visitor's region. */
|
|
321
|
+
type RegionConfig = {
|
|
322
|
+
/** Return the visitor's region synchronously — e.g. from a hosting header you read. */
|
|
323
|
+
detect?: RegionDetector | undefined;
|
|
324
|
+
/** Which regulation each region maps to (you own this). Matched most-specific first: "US-CA" then "US". */
|
|
325
|
+
map?: Record<string, Regulation> | undefined;
|
|
326
|
+
/** Honour the browser's GPC "do not sell/share" signal (a CCPA opt-out). Default `true`. */
|
|
327
|
+
honorGpc?: boolean | undefined;
|
|
328
|
+
/** Regulation to apply when the region is unknown or detection fails. Default `"GDPR"`. */
|
|
329
|
+
strictest?: Regulation | undefined;
|
|
330
|
+
/** Log the region decision to the console at setup (for local debugging). Default `false`. */
|
|
331
|
+
debug?: boolean | undefined;
|
|
332
|
+
};
|
|
333
|
+
/** How the active regulation was decided. */
|
|
334
|
+
type RegionSource = "manual" | "detected" | "strictest";
|
|
335
|
+
/** The outcome of geo-detection — the region seen and the regulation chosen. */
|
|
336
|
+
type RegionDecision = {
|
|
337
|
+
region: string | undefined;
|
|
338
|
+
regulation: Regulation;
|
|
339
|
+
source: RegionSource;
|
|
340
|
+
confidence: "high" | "low";
|
|
341
|
+
};
|
|
342
|
+
type ThemeConfig = {
|
|
343
|
+
primaryColor?: string | undefined;
|
|
344
|
+
backgroundColor?: string | undefined;
|
|
345
|
+
textColor?: string | undefined;
|
|
346
|
+
mutedTextColor?: string | undefined;
|
|
347
|
+
borderColor?: string | undefined;
|
|
348
|
+
borderRadius?: string | undefined;
|
|
349
|
+
fontFamily?: string | undefined;
|
|
350
|
+
/**
|
|
351
|
+
* Focus-ring color for interactive elements. Falls back to
|
|
352
|
+
* `var(--cy-primary)` — the ring matches your brand color exactly like it
|
|
353
|
+
* did before this field existed.
|
|
354
|
+
*/
|
|
355
|
+
focusColor?: string | undefined;
|
|
356
|
+
/**
|
|
357
|
+
* Background color of the floating recall widget (the small circular
|
|
358
|
+
* re-open button). Falls back to `"#0056a7"` in light mode. In dark mode,
|
|
359
|
+
* this value is still respected if you set it; only when you don't set it
|
|
360
|
+
* does a dark-mode default apply, the same way
|
|
361
|
+
* backgroundColor/textColor/mutedTextColor/borderColor already work.
|
|
362
|
+
*/
|
|
363
|
+
widgetBackgroundColor?: string | undefined;
|
|
364
|
+
};
|
|
365
|
+
type ScriptEntry = {
|
|
366
|
+
id: string;
|
|
367
|
+
src: string;
|
|
368
|
+
category: ConsentCategory;
|
|
369
|
+
onLoad?: (() => void) | undefined;
|
|
370
|
+
};
|
|
371
|
+
type I18nConfig = {
|
|
372
|
+
/** Translations per language. Each may be partial — missing text falls back to English. */
|
|
373
|
+
messages?: Record<string, PartialTranslations> | undefined;
|
|
374
|
+
locale?: string | undefined;
|
|
375
|
+
detectBrowserLanguage?: boolean | undefined;
|
|
376
|
+
/**
|
|
377
|
+
* Called when a language is switched to that isn't already in `messages` —
|
|
378
|
+
* return its translations (fetch them from your own URL, import them, etc.).
|
|
379
|
+
* Lets you load languages on demand instead of bundling them all upfront.
|
|
380
|
+
*/
|
|
381
|
+
loadLanguage?: ((tag: string) => PartialTranslations | Promise<PartialTranslations>) | undefined;
|
|
382
|
+
};
|
|
383
|
+
type ConsentConfig = {
|
|
384
|
+
apiUrl?: string | undefined;
|
|
385
|
+
apiKey?: string | undefined;
|
|
386
|
+
backend?: ConsentBackend | undefined;
|
|
387
|
+
regulation?: Regulation | undefined;
|
|
388
|
+
/**
|
|
389
|
+
* Define your own category taxonomy. Omit to get the built-in five
|
|
390
|
+
* (necessary, functional, analytics, performance, advertisement) unchanged.
|
|
391
|
+
* At least one category must be `{ required: true }`. Invalid configs fall
|
|
392
|
+
* back to the built-in five with a console warning. See {@link CategoryDef}.
|
|
393
|
+
*/
|
|
394
|
+
categories?: CategoryDef[] | undefined;
|
|
395
|
+
theme?: ThemeConfig | undefined;
|
|
396
|
+
colorScheme?: ColorScheme | undefined;
|
|
397
|
+
reloadOnRevoke?: boolean | undefined;
|
|
398
|
+
/**
|
|
399
|
+
* How to combine multiple categories that map to the same Google Consent Mode
|
|
400
|
+
* signal: `"any"` (default) grants the signal if any maps-and-granted; `"all"`
|
|
401
|
+
* requires every mapping category. Only affects custom overlapping mappings.
|
|
402
|
+
*/
|
|
403
|
+
googleConsentMatch?: "all" | "any" | undefined;
|
|
404
|
+
/**
|
|
405
|
+
* Built-in, first-party integrations to stop cleanly (no reload) when their
|
|
406
|
+
* category is revoked — e.g. `{ vendor: "meta" }`. (Google Analytics/Tag
|
|
407
|
+
* Manager are handled automatically via the Consent Mode broadcast — no entry
|
|
408
|
+
* needed.) Integrations with no clean runtime stop fall back to the reload notice.
|
|
409
|
+
*/
|
|
410
|
+
integrations?: BuiltInIntegration[] | undefined;
|
|
411
|
+
/**
|
|
412
|
+
* Your own scripts' stop instructions, for anything without a built-in
|
|
413
|
+
* integration. A handler that can stop cleanly provides `stop()`; one that
|
|
414
|
+
* can't should be registered as a reload-only handler instead so revoking it
|
|
415
|
+
* shows the reload notice rather than silently continuing to track.
|
|
416
|
+
*/
|
|
417
|
+
customStopHandlers?: StopHandler[] | undefined;
|
|
418
|
+
/** Detected region (e.g. "US-CA"), recorded on the consent-log payload. */
|
|
419
|
+
region?: string | undefined;
|
|
420
|
+
/**
|
|
421
|
+
* Internal — set by the runtime when a CCPA visitor arrives with the browser's
|
|
422
|
+
* GPC "do not sell" signal on. Starts them opted out (non-required categories
|
|
423
|
+
* off) until they explicitly choose otherwise, so nothing is shared first.
|
|
424
|
+
*/
|
|
425
|
+
gpcOptOut?: boolean | undefined;
|
|
426
|
+
onConsentReady?: ((state: ConsentSnapshot) => void) | undefined;
|
|
427
|
+
onConsentUpdate?: ((state: ConsentSnapshot) => void) | undefined;
|
|
428
|
+
};
|
|
429
|
+
/**
|
|
430
|
+
* Surfaced when a revoked tool has no clean runtime stop and can only be fully
|
|
431
|
+
* applied by reloading. `required` is false once dismissed; `reasons` lists the
|
|
432
|
+
* handler ids that triggered it (e.g. `["hotjar"]`).
|
|
433
|
+
*/
|
|
434
|
+
type ReloadNoticeState = {
|
|
435
|
+
required: boolean;
|
|
436
|
+
reasons: string[];
|
|
437
|
+
};
|
|
438
|
+
type ConsentSnapshot = {
|
|
439
|
+
consentId: string;
|
|
440
|
+
hasActed: boolean;
|
|
441
|
+
/** Category id → granted. Keys are the configured taxonomy's ids. */
|
|
442
|
+
categories: Record<string, boolean>;
|
|
443
|
+
regulation: Regulation;
|
|
444
|
+
lastRenewed?: number | undefined;
|
|
445
|
+
/**
|
|
446
|
+
* Signature of the category taxonomy in effect when this consent was
|
|
447
|
+
* recorded. Lets us (and the customer) tell what a returning visitor
|
|
448
|
+
* actually agreed to, and drives re-request when the taxonomy changes.
|
|
449
|
+
*/
|
|
450
|
+
taxonomyHash?: string | undefined;
|
|
451
|
+
};
|
|
452
|
+
type ConsentManager = ConsentSnapshot & {
|
|
453
|
+
/**
|
|
454
|
+
* Consent in effect — changes only on a real decision (accept / reject / save
|
|
455
|
+
* / reset), never on a dialog toggle. Gate scripts/embeds on this. (`categories`
|
|
456
|
+
* is the live value that drives the dialog checkboxes.)
|
|
457
|
+
*/
|
|
458
|
+
committedCategories: Record<string, boolean>;
|
|
459
|
+
acceptAll: () => void;
|
|
460
|
+
rejectAll: () => void;
|
|
461
|
+
acceptSelected: (categories: ConsentCategory[]) => void;
|
|
462
|
+
updateCategory: (category: ConsentCategory, value: boolean) => void;
|
|
463
|
+
savePreferences: () => void;
|
|
464
|
+
resetConsent: () => void;
|
|
465
|
+
showPreferences: () => void;
|
|
466
|
+
hidePreferences: () => void;
|
|
467
|
+
isPreferencesOpen: boolean;
|
|
468
|
+
subscribe: (listener: (state: ConsentSnapshot) => void) => () => void;
|
|
469
|
+
registerScript: (entry: ScriptEntry) => void;
|
|
470
|
+
/** Current reload-notice state (see {@link ReloadNoticeState}). */
|
|
471
|
+
reloadNotice: ReloadNoticeState;
|
|
472
|
+
/** Dismiss the reload notice; it won't reappear until a new revoke needs one. */
|
|
473
|
+
dismissReloadNotice: () => void;
|
|
474
|
+
};
|
|
475
|
+
/**
|
|
476
|
+
* Shape of the JSON body POSTed to the customer's `apiUrl`
|
|
477
|
+
* on every consent decision (Accept All / Reject All / Save Preferences).
|
|
478
|
+
*
|
|
479
|
+
* Customers building a TypeScript backend can import this type to get
|
|
480
|
+
* full type safety on their request handler.
|
|
481
|
+
*/
|
|
482
|
+
type ConsentPayload = {
|
|
483
|
+
consentId: string;
|
|
484
|
+
categories: Record<string, boolean>;
|
|
485
|
+
regulation: Regulation;
|
|
486
|
+
domain: string;
|
|
487
|
+
/** Detected region when geo-detection is on (e.g. "US-CA"); omitted otherwise. */
|
|
488
|
+
region?: string | undefined;
|
|
489
|
+
};
|
|
490
|
+
/**
|
|
491
|
+
* Customer-implemented adapter that decides how a consent decision
|
|
492
|
+
* reaches their backend. Provide this when `mode: "self-hosted"` and you
|
|
493
|
+
* need full control over the request shape, headers, auth, transport,
|
|
494
|
+
* batching, retries, etc. — anything you can't express with `apiUrl`.
|
|
495
|
+
*
|
|
496
|
+
* The SDK hands you a standardised `ConsentPayload`; you transform and
|
|
497
|
+
* dispatch it however your backend expects.
|
|
498
|
+
*/
|
|
499
|
+
interface ConsentBackend {
|
|
500
|
+
persist(payload: ConsentPayload): Promise<void> | void;
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* @deprecated Use `"cookie-only"` instead — identical behavior, clearer name.
|
|
504
|
+
* `"offline"` still works but will be removed after three release cycles.
|
|
505
|
+
*/
|
|
506
|
+
type DeprecatedOfflineMode = "offline";
|
|
507
|
+
type ConsentRuntimeMode = "self-hosted" | "cookie-only" | DeprecatedOfflineMode;
|
|
508
|
+
type ColorScheme = "light" | "dark" | "system";
|
|
509
|
+
/**
|
|
510
|
+
* Fields shared by every {@link CookieYesConfig} regardless of `mode`.
|
|
511
|
+
* This is the one canonical config surface — both `@cookieyes/core` and
|
|
512
|
+
* `@cookieyes/react` consume the exact same object, so a config is
|
|
513
|
+
* copy-pasteable between them with zero edits.
|
|
514
|
+
*/
|
|
515
|
+
type CookieYesConfigCommon = {
|
|
516
|
+
/**
|
|
517
|
+
* Which privacy regulation applies. Top-level and identical across every
|
|
518
|
+
* package (replaces the builder's `.regulation()` and core's former
|
|
519
|
+
* nested `overrides.regulation`).
|
|
520
|
+
*/
|
|
521
|
+
regulation?: Regulation | undefined;
|
|
522
|
+
/**
|
|
523
|
+
* Optional geo-detection: choose the regulation from the visitor's region.
|
|
524
|
+
* Fully optional — omit it and nothing changes. A manual `regulation` (above)
|
|
525
|
+
* always wins over detection. See {@link RegionConfig}.
|
|
526
|
+
*/
|
|
527
|
+
region?: RegionConfig | undefined;
|
|
528
|
+
colorScheme?: ColorScheme | undefined;
|
|
529
|
+
theme?: ThemeConfig | undefined;
|
|
530
|
+
i18n?: I18nConfig | undefined;
|
|
531
|
+
/**
|
|
532
|
+
* Define your own category taxonomy. Omit to get the built-in five
|
|
533
|
+
* (necessary, functional, analytics, performance, advertisement) unchanged.
|
|
534
|
+
* At least one category must be `{ required: true }`. Invalid configs fall
|
|
535
|
+
* back to the built-in five with a console warning. See {@link CategoryDef}.
|
|
536
|
+
*/
|
|
537
|
+
categories?: CategoryDef[] | undefined;
|
|
538
|
+
networkBlocker?: NetworkBlockerConfig | undefined;
|
|
539
|
+
reloadOnRevoke?: boolean | undefined;
|
|
540
|
+
/**
|
|
541
|
+
* How to combine multiple categories that map to the same Google Consent Mode
|
|
542
|
+
* signal: `"any"` (default) or `"all"`. Only matters for a custom taxonomy
|
|
543
|
+
* where more than one category maps to the same signal.
|
|
544
|
+
*/
|
|
545
|
+
googleConsentMatch?: "all" | "any" | undefined;
|
|
546
|
+
/**
|
|
547
|
+
* Ready-made third-party integrations to gate behind consent — Segment, Meta,
|
|
548
|
+
* Google, and more — using a preset from `@cookieyes/scripts`. Each preset
|
|
549
|
+
* returns an {@link Integration}: it loads only once its category is granted
|
|
550
|
+
* (or, for Google Consent Mode, loads immediately and denies by default), and
|
|
551
|
+
* is removed or silenced on withdrawal.
|
|
552
|
+
*
|
|
553
|
+
* @example integrations: [segment({ writeKey: "..." })]
|
|
554
|
+
*/
|
|
555
|
+
integrations?: Integration[] | undefined;
|
|
556
|
+
/**
|
|
557
|
+
* @deprecated Renamed from `integrations`. Built-in stop-handlers for a few
|
|
558
|
+
* first-party vendors — e.g. `{ vendor: "meta" }` — stopped cleanly (no
|
|
559
|
+
* reload) when their category is revoked. Prefer the new `integrations` field
|
|
560
|
+
* with a preset from `@cookieyes/scripts`; this will be removed after three
|
|
561
|
+
* release cycles.
|
|
562
|
+
*/
|
|
563
|
+
builtInIntegrations?: BuiltInIntegration[] | undefined;
|
|
564
|
+
/**
|
|
565
|
+
* Your own scripts' stop instructions, for anything without a built-in
|
|
566
|
+
* integration. A handler that can stop cleanly provides `stop()`; one that
|
|
567
|
+
* can't should be registered as a reload-only handler instead so revoking it
|
|
568
|
+
* shows the reload notice rather than silently continuing to track.
|
|
569
|
+
*/
|
|
570
|
+
customStopHandlers?: StopHandler[] | undefined;
|
|
571
|
+
/** Low-level: fires once, after the runtime's initial state is known (e.g. to conditionally load analytics on first load). For ongoing updates, use `consentStore.subscribeToConsentChanges` instead. */
|
|
572
|
+
onConsentReady?: ((state: ConsentSnapshot) => void) | undefined;
|
|
573
|
+
/** Low-level: fires on every saved consent change, for the lifetime of this config. If you need to subscribe/unsubscribe dynamically after mount, use `consentStore.getState().subscribeToConsentChanges` instead. */
|
|
574
|
+
onConsentUpdate?: ((state: ConsentSnapshot) => void) | undefined;
|
|
575
|
+
/**
|
|
576
|
+
* @deprecated Set `regulation` at the top level instead. This nested form
|
|
577
|
+
* still works and maps to the top-level field; if both are given, the
|
|
578
|
+
* top-level `regulation` wins. Retained for back-compat and removed after
|
|
579
|
+
* three release cycles, per the SDK deprecation policy.
|
|
580
|
+
*/
|
|
581
|
+
overrides?: {
|
|
582
|
+
regulation?: Regulation | undefined;
|
|
583
|
+
} | undefined;
|
|
584
|
+
};
|
|
585
|
+
/**
|
|
586
|
+
* Cookie-only mode — consent is stored client-side only; no backend keys are
|
|
587
|
+
* permitted (they fail at the type level). `mode: "cookie-only"` is the
|
|
588
|
+
* canonical value; `mode: "offline"` is a deprecated alias with identical
|
|
589
|
+
* behavior that emits a one-time-per-page-load deprecation warning.
|
|
590
|
+
*/
|
|
591
|
+
type CookieYesOfflineConfig = CookieYesConfigCommon & {
|
|
592
|
+
mode: "cookie-only" | DeprecatedOfflineMode;
|
|
593
|
+
};
|
|
594
|
+
/** Self-hosted mode — consent decisions are persisted to your own backend. */
|
|
595
|
+
type CookieYesSelfHostedConfig = CookieYesConfigCommon & {
|
|
596
|
+
mode: "self-hosted";
|
|
597
|
+
/** Endpoint the {@link ConsentPayload} is POSTed to. Canonical key. */
|
|
598
|
+
apiUrl?: string | undefined;
|
|
599
|
+
apiKey?: string | undefined;
|
|
600
|
+
/** Custom persistence adapter — full control over transport/headers/retries. */
|
|
601
|
+
backend?: ConsentBackend | undefined;
|
|
602
|
+
/**
|
|
603
|
+
* @deprecated Renamed to `apiUrl`. This alias still works and maps to
|
|
604
|
+
* `apiUrl`; if both are given, `apiUrl` wins. Retained for back-compat and
|
|
605
|
+
* removed after three release cycles, per the SDK deprecation policy.
|
|
606
|
+
*/
|
|
607
|
+
backendURL?: string | undefined;
|
|
608
|
+
};
|
|
609
|
+
/**
|
|
610
|
+
* The canonical configuration object for the CookieYes SDK, discriminated on
|
|
611
|
+
* `mode`. Passed identically to `initCookieYes()` /
|
|
612
|
+
* `getOrCreateConsentRuntime()` in `@cookieyes/core` and `initCookieYes()` in
|
|
613
|
+
* `@cookieyes/react`.
|
|
614
|
+
*
|
|
615
|
+
* The discriminated union guarantees invalid combinations fail at compile time
|
|
616
|
+
* — e.g. supplying `apiUrl`/`backend` under `mode: "cookie-only"` is a type error.
|
|
617
|
+
*/
|
|
618
|
+
type CookieYesConfig = CookieYesOfflineConfig | CookieYesSelfHostedConfig;
|
|
619
|
+
/**
|
|
620
|
+
* @deprecated Renamed to {@link CookieYesConfig}. Retained as a type alias for
|
|
621
|
+
* back-compat and removed after three release cycles, per the SDK deprecation
|
|
622
|
+
* policy.
|
|
623
|
+
*/
|
|
624
|
+
type ConsentRuntimeOptions = CookieYesConfig;
|
|
625
|
+
type ConsentChangePayload = {
|
|
626
|
+
allowedCategories: ConsentCategory[];
|
|
627
|
+
deniedCategories: ConsentCategory[];
|
|
628
|
+
};
|
|
629
|
+
/** Which consent event to listen for. See {@link ConsentStore.on}. */
|
|
630
|
+
type ConsentEventType = "save" | "change";
|
|
631
|
+
type ConsentEventPayload = {
|
|
632
|
+
/** The full committed consent map in effect when the event fired. */
|
|
633
|
+
categories: Record<string, boolean>;
|
|
634
|
+
/** Categories whose value differed from before. Empty on the initial replay. */
|
|
635
|
+
changedCategories: ConsentCategory[];
|
|
636
|
+
/**
|
|
637
|
+
* `true` when this is the one-off replay a listener gets on attach (here's
|
|
638
|
+
* the current state), `false` when the visitor actually just acted.
|
|
639
|
+
*/
|
|
640
|
+
isInitial: boolean;
|
|
641
|
+
};
|
|
642
|
+
type ConsentEventListener = (payload: ConsentEventPayload) => void;
|
|
643
|
+
/** Restrict a listener to a single category (fires only when it changes). */
|
|
644
|
+
type ConsentEventOptions = {
|
|
645
|
+
category?: ConsentCategory;
|
|
646
|
+
};
|
|
647
|
+
type ActiveUI = "banner" | "dialog" | null;
|
|
648
|
+
type ConsentStoreState = ConsentSnapshot & {
|
|
649
|
+
activeUI: ActiveUI;
|
|
650
|
+
/** Live/working values — reflect in-progress dialog toggles. Drive checkboxes. */
|
|
651
|
+
consents: Record<string, boolean>;
|
|
652
|
+
/**
|
|
653
|
+
* Consent in effect — changes only on a saved decision, not a toggle. Gate
|
|
654
|
+
* scripts/embeds on this (or {@link ConsentStoreState.has}).
|
|
655
|
+
*/
|
|
656
|
+
committedConsents: Record<string, boolean>;
|
|
657
|
+
/** True when `category` is committed-granted (a saved decision), not just toggled. */
|
|
658
|
+
has: (category: ConsentCategory) => boolean;
|
|
659
|
+
saveConsents: (target: "all" | "necessary" | ConsentCategory[]) => Promise<void>;
|
|
660
|
+
setConsent: (category: ConsentCategory, value: boolean) => void;
|
|
661
|
+
/** Low-level: fires only on *saved* preference changes, not transient UI toggles — see `ConsentStore.subscribe` for the recommended, general-purpose subscription. */
|
|
662
|
+
subscribeToConsentChanges: (listener: (payload: ConsentChangePayload) => void) => () => void;
|
|
663
|
+
};
|
|
664
|
+
/**
|
|
665
|
+
* The recommended way to read consent state outside React. `subscribe` fires
|
|
666
|
+
* on every state change (including transient UI toggles, e.g. a checkbox
|
|
667
|
+
* flip before saving); for saved-changes-only, see
|
|
668
|
+
* `ConsentStoreState.subscribeToConsentChanges`.
|
|
669
|
+
*/
|
|
670
|
+
type ConsentStore = {
|
|
671
|
+
subscribe: (listener: (state: ConsentStoreState) => void) => () => void;
|
|
672
|
+
getState: () => ConsentStoreState;
|
|
673
|
+
/** Text for the active language (English fills gaps). Swaps on `setLanguage`. */
|
|
674
|
+
translations: TranslationMap;
|
|
675
|
+
/** The active language, its reading direction, and the languages loaded. */
|
|
676
|
+
getLanguageInfo: () => LanguageInfo;
|
|
677
|
+
/**
|
|
678
|
+
* Switch language live (no reload) — `subscribe` listeners fire so a custom UI
|
|
679
|
+
* can re-render. Loads the language via `i18n.loadLanguage` if not bundled.
|
|
680
|
+
*/
|
|
681
|
+
setLanguage: (tag: string) => Promise<void>;
|
|
682
|
+
/** Customer-provided text for a category in the active language, if any. */
|
|
683
|
+
getCategoryText: (id: string) => Partial<CategoryText> | undefined;
|
|
684
|
+
/**
|
|
685
|
+
* The category taxonomy in effect (custom list or the built-in five) — its
|
|
686
|
+
* ids, which are `required`, etc. Use it to render categories in a custom UI
|
|
687
|
+
* so it follows whatever taxonomy is configured.
|
|
688
|
+
*/
|
|
689
|
+
categories: ResolvedCategories;
|
|
690
|
+
/** How the active regulation was decided (region, source, confidence). */
|
|
691
|
+
getRegion: () => RegionDecision;
|
|
692
|
+
/**
|
|
693
|
+
* React to consent decisions. `"save"` fires on every save (even an
|
|
694
|
+
* unchanged re-confirm); `"change"` fires only when a category actually
|
|
695
|
+
* differs — use it to (re)load a script without re-running on a re-confirm.
|
|
696
|
+
* The listener fires once immediately with the current state
|
|
697
|
+
* (`isInitial: true`). Pass `{ category }` to only hear about one category.
|
|
698
|
+
* Returns an unsubscribe function.
|
|
699
|
+
*/
|
|
700
|
+
on: (type: ConsentEventType, listener: ConsentEventListener, options?: ConsentEventOptions) => () => void;
|
|
701
|
+
};
|
|
702
|
+
type ConsentRuntime = {
|
|
703
|
+
consentManager: ConsentManager;
|
|
704
|
+
consentStore: ConsentStore;
|
|
705
|
+
/** Config + live status for each script integration — data for a debug view. */
|
|
706
|
+
getIntegrations: () => IntegrationDebugInfo[];
|
|
707
|
+
/**
|
|
708
|
+
* Resolves once configured integrations have been loaded and wired up.
|
|
709
|
+
*
|
|
710
|
+
* The integration runner is loaded on demand — it is the largest subsystem in
|
|
711
|
+
* the package and does nothing unless `integrations` is configured — so there
|
|
712
|
+
* is a short window after setup in which `getIntegrations()` returns `[]` and
|
|
713
|
+
* no integration has been set up yet. Await this to act after that window;
|
|
714
|
+
* it resolves immediately when no integrations are configured.
|
|
715
|
+
*
|
|
716
|
+
* Nothing about consent gating depends on it: an integration cannot run
|
|
717
|
+
* before its category is granted whether or not it has loaded yet.
|
|
718
|
+
*/
|
|
719
|
+
integrationsReady: Promise<void>;
|
|
720
|
+
};
|
|
721
|
+
|
|
722
|
+
/**
|
|
723
|
+
* Google Consent Mode v2 storage/signal types. A category can declare which of
|
|
724
|
+
* these it represents via {@link CategoryDef.gcm}; the SDK then broadcasts them
|
|
725
|
+
* (see google-consent-mode.ts). `security_storage` is always granted and is
|
|
726
|
+
* handled by the broadcast itself, so it never needs to be mapped.
|
|
727
|
+
*/
|
|
728
|
+
type GoogleConsentSignal = "ad_storage" | "ad_user_data" | "ad_personalization" | "analytics_storage" | "functionality_storage" | "personalization_storage" | "security_storage";
|
|
729
|
+
/**
|
|
730
|
+
* A single consent category. `id` is the stable key stored in the cookie and
|
|
731
|
+
* used everywhere (banner, preferences, read APIs, integrations). Exactly one
|
|
732
|
+
* category should be marked `required` — the always-on, non-optional one (like
|
|
733
|
+
* the default "necessary") — flagged explicitly here, never inferred from a
|
|
734
|
+
* name, so it survives full renaming.
|
|
735
|
+
*/
|
|
736
|
+
type CategoryDef = {
|
|
737
|
+
id: ConsentCategory;
|
|
738
|
+
/** The always-on, non-optional category. At least one is required. */
|
|
739
|
+
required?: boolean | undefined;
|
|
740
|
+
/** Display label. Falls back to the translation for built-in ids. */
|
|
741
|
+
label?: string | undefined;
|
|
742
|
+
/** Display description. Falls back to the translation for built-in ids. */
|
|
743
|
+
description?: string | undefined;
|
|
744
|
+
/** Google Consent Mode signals this category governs (see {@link GoogleConsentSignal}). */
|
|
745
|
+
gcm?: GoogleConsentSignal[] | undefined;
|
|
746
|
+
};
|
|
747
|
+
/**
|
|
748
|
+
* The built-in five, used verbatim when a customer configures nothing. GCM
|
|
749
|
+
* mapping mirrors production's `_ckySetGoogleConsentMode` (analytics →
|
|
750
|
+
* analytics_storage, advertisement → the ad_* signals, functional →
|
|
751
|
+
* functionality/personalization; performance maps to nothing; security_storage
|
|
752
|
+
* is always granted by the broadcast).
|
|
753
|
+
*/
|
|
754
|
+
declare const DEFAULT_CATEGORIES: CategoryDef[];
|
|
755
|
+
type ResolvedCategories = {
|
|
756
|
+
/** Ordered category definitions actually in effect. */
|
|
757
|
+
list: CategoryDef[];
|
|
758
|
+
/** Ordered ids (fast access). */
|
|
759
|
+
ids: ConsentCategory[];
|
|
760
|
+
/** Ids marked `required` (always granted, never toggleable). */
|
|
761
|
+
requiredIds: Set<ConsentCategory>;
|
|
762
|
+
/** Stable signature of this taxonomy; a change here re-requests consent. */
|
|
763
|
+
taxonomyHash: string;
|
|
764
|
+
/** True when the built-in five are in effect (configured or fallback). */
|
|
765
|
+
isDefault: boolean;
|
|
766
|
+
};
|
|
767
|
+
/**
|
|
768
|
+
* Resolve the category list from config. Returns the built-in five when nothing
|
|
769
|
+
* is configured. On an invalid custom config (empty, duplicate/reserved ids, or
|
|
770
|
+
* no `required` category) it warns and falls back to the built-in five, rather
|
|
771
|
+
* than leaving the visitor a broken/empty or unprotected setup.
|
|
772
|
+
*/
|
|
773
|
+
declare function resolveCategories(defs?: CategoryDef[]): ResolvedCategories;
|
|
774
|
+
|
|
775
|
+
export { DEFAULT_CATEGORIES as M, INTEGRATION_FORMAT_VERSION as O, _clearStopHandlers as a1, installNetworkBlocker as a2, registerNetworkBlocker as a3, registerStopHandler as a4, resolveBuiltInIntegration as a5, resolveCategories as a6, runIntegrations as a7, uninstallNetworkBlocker as a8, warnOverlappingVendors as a9, warnUnknownCategories as aa };
|
|
776
|
+
export type { SetupCtx as $, ActiveUI as A, BuiltInIntegration as B, ConsentRuntimeMode as C, ConsentPayload as D, ConsentRuntimeOptions as E, ConsentStore as F, GoogleConsentSignal as G, ConsentStoreState as H, I18nConfig as I, CookieYesOfflineConfig as J, CookieYesSelfHostedConfig as K, LanguageInfo as L, NetworkBlockerConfig as N, PartialTranslations as P, IntegrationDebugInfo as Q, Regulation as R, StopHandler as S, ThemeConfig as T, IntegrationStatus as U, NetworkBlockerRule as V, RegionDetector as W, RegionSource as X, ReloadNoticeState as Y, ReloadOnlyHandler as Z, ScriptEntry as _, RegionConfig as a, SilenceControl as a0, ColorScheme as b, CategoryDef as c, Integration as d, ConsentSnapshot as e, ConsentBackend as f, CookieYesConfig as g, ConsentEventType as h, ConsentEventListener as i, ConsentEventOptions as j, ResolvedCategories as k, TranslationMap as l, TextDirection as m, IntegrationHost as n, IntegrationRunner as o, CategoryText as p, ConsentConfig as q, ConsentManager as r, ConsentCategory as s, RegionDecision as t, ConsentRuntime as u, AnyStopHandler as v, BlockedRequestInfo as w, Cleanup as x, ConsentChangePayload as y, ConsentEventPayload as z };
|