@ecomconsult/consentkit 0.3.5 → 0.4.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/README.md +160 -16
- package/npm/core.mjs +4 -1
- package/npm/index.cjs +4 -1
- package/npm/index.d.ts +68 -0
- package/npm/index.mjs +14 -2
- package/npm/internal-stub.mjs +7 -1
- package/package.json +1 -1
- package/src/ck-core.js +390 -37
- package/src/ck-debug.js +17 -2
- package/src/ck-saas.js +36 -1
- package/src/ck-ui-branding.js +511 -0
- package/src/ck-ui.js +43 -416
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ Four ways to add ConsentKit to a site, from simplest to most integrated.
|
|
|
44
44
|
|---|---|---|---|
|
|
45
45
|
| 1 | **Script tags** — copy `src/` to your server, three `<script>` tags in `<head>` | Any site you control | [Quickstart below](#quickstart--script-tags) |
|
|
46
46
|
| 2 | **npm** — `npm install @ecomconsult/consentkit` | Bundled apps, React | [Quickstart below](#quickstart--npm) |
|
|
47
|
-
| 3 | **WordPress plugin** — copy the plugin folder to `wp-content/plugins
|
|
47
|
+
| 3 | **WordPress plugin** — copy the plugin folder to `wp-content/plugins/`; rewrites static tracker tags server-side | WordPress / WooCommerce | [`plugins/wordpress/consentkit/`](plugins/wordpress/consentkit/) |
|
|
48
48
|
| 4 | **Google Tag Manager** — import the container, trigger tags on consent events | Sites already running GTM | [`integrations/gtm/README.md`](integrations/gtm/README.md) |
|
|
49
49
|
|
|
50
50
|
```sh
|
|
@@ -66,6 +66,7 @@ must come first and should not be deferred.
|
|
|
66
66
|
```html
|
|
67
67
|
<script src="/consentkit/src/ck-core.js"></script>
|
|
68
68
|
<script src="/consentkit/src/ck-locales.js"></script><!-- optional: extra languages -->
|
|
69
|
+
<script src="/consentkit/src/ck-ui-branding.js"></script><!-- optional: logo / attribution -->
|
|
69
70
|
<script src="/consentkit/src/ck-ui.js"></script>
|
|
70
71
|
<script>
|
|
71
72
|
ConsentKit.init({
|
|
@@ -188,6 +189,9 @@ Pass any subset to `init()`. Nested objects merge with the defaults.
|
|
|
188
189
|
| `consentTtlDays` | `number` | `365` | Lifetime of the stored decision |
|
|
189
190
|
| `integrations.gcm` | `boolean` | `true` | Google Consent Mode v2 signals |
|
|
190
191
|
| `integrations.gtmDataLayer` | `boolean` | `true` | Push consent events to `window.dataLayer` |
|
|
192
|
+
| `blocking.mode` | `"known" \| "strict"` | `"known"` | `strict` also holds back unknown third-party scripts and iframes — see [Strict mode](#strict-mode) |
|
|
193
|
+
| `blocking.allow` | `string[]` | `[]` | Hosts strict mode must never intercept. Matched by suffix, so `partner.com` also covers `cdn.partner.com` |
|
|
194
|
+
| `hostdb` | `Record<string, Category>` | — | Extra `host: category` pairs merged into the tracker database, applied before the initial scan. SaaS mode fills this from the service; `ConsentKit._extendHostDb()` does the same at any later point |
|
|
191
195
|
| `cookieTable` | `CkCookieTableEntry[]` | `[]` | Declared cookies, listed per category in the panel |
|
|
192
196
|
|
|
193
197
|
`cookieTable` entries:
|
|
@@ -279,6 +283,11 @@ Iframes use `data-src`, which is applied once the category is allowed:
|
|
|
279
283
|
|
|
280
284
|
`data-ck` accepts any category name: `functional`, `analytics`, `marketing`.
|
|
281
285
|
|
|
286
|
+
> On WordPress this markup is applied **automatically, server-side**, for every
|
|
287
|
+
> tracker in the built-in database — see "Server-side markup" below. Manual
|
|
288
|
+
> markup is still needed for trackers the database does not know (your own
|
|
289
|
+
> domain, an unlisted vendor) and for inline snippets.
|
|
290
|
+
|
|
282
291
|
### Automatic blocking
|
|
283
292
|
|
|
284
293
|
Scripts injected at runtime are intercepted without any markup. ConsentKit
|
|
@@ -301,6 +310,130 @@ and DoubleClick.
|
|
|
301
310
|
Because the patches install at parse time, `ck-core.js` must load before any
|
|
302
311
|
tracker — put it first in `<head>` and do not add `defer`.
|
|
303
312
|
|
|
313
|
+
`<iframe src>` is covered by the same three patches, and a blocked frame keeps
|
|
314
|
+
its URL in `data-src` until its category is granted.
|
|
315
|
+
|
|
316
|
+
### Extending the tracker database
|
|
317
|
+
|
|
318
|
+
The built-in host list is a snapshot, not an oracle. `_extendHostDb()` merges
|
|
319
|
+
extra `host: category` pairs into it at runtime:
|
|
320
|
+
|
|
321
|
+
```js
|
|
322
|
+
ConsentKit._extendHostDb({
|
|
323
|
+
'analytics.vendor.example': 'analytics',
|
|
324
|
+
'pixel.partner.example': 'marketing'
|
|
325
|
+
});
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Matching is the same as for built-in entries — a bare domain also covers its
|
|
329
|
+
subdomains — and an override wins over the shipped classification for the same
|
|
330
|
+
host. Categories outside `necessary | functional | analytics | marketing` and
|
|
331
|
+
malformed hostnames are ignored; the call returns how many pairs were accepted.
|
|
332
|
+
|
|
333
|
+
It works both **before and after** `init()`. Calling it afterwards does not
|
|
334
|
+
re-examine anything already inserted (a script that has loaded cannot be
|
|
335
|
+
unloaded), but every later insertion is classified against the extended map.
|
|
336
|
+
|
|
337
|
+
In SaaS mode this is automatic: `ck-saas.js` applies `config.hostdb` from the
|
|
338
|
+
service *before* it calls `init()`, and again when a background revalidation
|
|
339
|
+
brings a changed table. At release time `node tools/sync-hostdb.mjs` bakes the
|
|
340
|
+
same public table into `src/ck-core.js`, so inline blocks, the npm package and
|
|
341
|
+
the WordPress plugin get it too.
|
|
342
|
+
|
|
343
|
+
### Strict mode
|
|
344
|
+
|
|
345
|
+
By default ConsentKit blocks what it **recognises**. `blocking.mode: 'strict'`
|
|
346
|
+
inverts that for third parties: before consent, any `<script src>` or
|
|
347
|
+
`<iframe src>` pointing at a host that is not same-site is intercepted, whether
|
|
348
|
+
or not the tracker database has ever heard of it.
|
|
349
|
+
|
|
350
|
+
```js
|
|
351
|
+
ConsentKit.init({
|
|
352
|
+
blocking: { mode: 'strict', allow: ['widgets.partner.example'] }
|
|
353
|
+
});
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
Four things are never intercepted:
|
|
357
|
+
|
|
358
|
+
1. **Same-site URLs** — the page's own host, its subdomains, and anything
|
|
359
|
+
sharing its registrable domain. The check is deliberately conservative: when
|
|
360
|
+
the answer is unclear it says same-site, because wrongly blocking a
|
|
361
|
+
first-party asset breaks the site.
|
|
362
|
+
2. **`blocking.allow`** — your own list, matched by suffix.
|
|
363
|
+
3. **The built-in allowlist**, readable as `ConsentKit._baseAllow`: asset CDNs
|
|
364
|
+
(`cdn.jsdelivr.net`, `unpkg.com`, `cdnjs.cloudflare.com`, `code.jquery.com`,
|
|
365
|
+
`fonts.googleapis.com`, `fonts.gstatic.com`) and things a page is unusable
|
|
366
|
+
without (`js.stripe.com`, `pay.google.com`, `checkout.creem.io`,
|
|
367
|
+
`hcaptcha.com`, and reCAPTCHA — scoped to `www.google.com/recaptcha` and
|
|
368
|
+
`www.gstatic.com/recaptcha`, not to those hosts at large).
|
|
369
|
+
4. **Known `necessary` / `functional` hosts** already granted, which keep their
|
|
370
|
+
real category rather than being swept up as marketing.
|
|
371
|
+
|
|
372
|
+
Anything else is filed under **`marketing`** — the strictest category — and
|
|
373
|
+
comes back only when the visitor accepts marketing.
|
|
374
|
+
|
|
375
|
+
**Read this before switching it on.** Strict mode will block third-party code
|
|
376
|
+
your site needs and that ConsentKit has no way to recognise as necessary: a
|
|
377
|
+
booking widget, a map, a review embed, a payment provider that is not on the
|
|
378
|
+
list. Turn it on, load the site with `?ck_debug=1`, and read the "Blocked until
|
|
379
|
+
consent" list in the panel — entries the engine held back only because of strict
|
|
380
|
+
mode are labelled `strict`. Everything there that the page genuinely needs
|
|
381
|
+
belongs in `blocking.allow`.
|
|
382
|
+
|
|
383
|
+
Two limits are worth stating plainly:
|
|
384
|
+
|
|
385
|
+
* **Dynamic insertions only**, exactly as for known trackers. A tag written
|
|
386
|
+
straight into the HTML starts its request before ConsentKit runs (see below).
|
|
387
|
+
The WordPress plugin's server-side rewrite currently marks up *known* trackers
|
|
388
|
+
only; extending it to strict mode is recorded as a follow-up in SPEC.md.
|
|
389
|
+
* **Strict starts when the config does.** The mode is read from `config`, so in
|
|
390
|
+
SaaS mode nothing is blocked strictly until the config has arrived. Blocking
|
|
391
|
+
of *known* trackers still begins at parse time, as always.
|
|
392
|
+
|
|
393
|
+
### Static tags: what the browser cannot catch
|
|
394
|
+
|
|
395
|
+
Runtime injection is covered by the patches above. A tracker tag written
|
|
396
|
+
**directly into the HTML** is not: the parser starts that request before the
|
|
397
|
+
first line of `ck-core.js` runs. The gap was measured (debt Д9: request at
|
|
398
|
+
14 ms, our script at 18 ms) and it is negative — no client-side technique
|
|
399
|
+
closes it. Such tags need either manual markup, or a server that rewrites them
|
|
400
|
+
before the page is sent.
|
|
401
|
+
|
|
402
|
+
### Server-side markup (WordPress plugin)
|
|
403
|
+
|
|
404
|
+
The WordPress plugin does exactly that, and it is **on by default** since 0.3.5.
|
|
405
|
+
While the page is generated, it rewrites tracker tags in the finished HTML:
|
|
406
|
+
|
|
407
|
+
```html
|
|
408
|
+
<!-- what the theme wrote -->
|
|
409
|
+
<script src="https://mc.yandex.ru/metrika/tag.js"></script>
|
|
410
|
+
|
|
411
|
+
<!-- what the browser receives -->
|
|
412
|
+
<script type="text/plain" data-ck="analytics"
|
|
413
|
+
data-ck-src="https://mc.yandex.ru/metrika/tag.js"></script>
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
`<iframe src>` of a known host becomes `data-ck` + `data-src` with `src`
|
|
417
|
+
removed. The categories come from the same HOST_DB/PATH_DB as the browser
|
|
418
|
+
engine: `tools/export-hostdb.mjs` generates
|
|
419
|
+
`plugins/wordpress/consentkit/includes/hostdb.php` from `src/ck-core.js`, and
|
|
420
|
+
`test/hostdb.test.mjs` fails if the two drift.
|
|
421
|
+
|
|
422
|
+
What it skips: ConsentKit's own assets, tags carrying `data-ck-ignore`, tags
|
|
423
|
+
already marked up by hand, inline scripts (there is no URL to defer), the GTM
|
|
424
|
+
container, and anything inside comments, `<pre>` or `<textarea>`. On any error
|
|
425
|
+
the page is returned unchanged.
|
|
426
|
+
|
|
427
|
+
The `<pre>` / `<textarea>` skip keeps the *source text* byte-identical, which is
|
|
428
|
+
what a page documenting a tracker snippet needs. It does not keep such a tag
|
|
429
|
+
alive: the browser parses `<pre><script src=…>` as a real script element
|
|
430
|
+
whatever the server did, so the runtime engine may still intercept it. Caching plugins are compatible and get the
|
|
431
|
+
already-rewritten HTML, because the rewrite happens at the PHP level before the
|
|
432
|
+
page is cached.
|
|
433
|
+
|
|
434
|
+
Outside WordPress the same idea applies to any server-side template: emit the
|
|
435
|
+
`type="text/plain" data-ck` form directly, as in "Manual markup" above.
|
|
436
|
+
|
|
304
437
|
## Google Consent Mode v2
|
|
305
438
|
|
|
306
439
|
With `integrations.gcm` (default), the core pushes `consent: default` with every
|
|
@@ -348,18 +481,23 @@ external requests. Rebuild them with `tools/build-inline.mjs` (see
|
|
|
348
481
|
[`tools/README.md`](tools/README.md)); each block's header records the exact
|
|
349
482
|
command that produced it.
|
|
350
483
|
|
|
351
|
-
ConsentKit 0.
|
|
352
|
-
this roughly three- to fourfold. Every block includes the
|
|
353
|
-
`--no-branding`
|
|
484
|
+
ConsentKit 0.4.0, rebuilt 2026-09-05, uncompressed — gzip on the server cuts
|
|
485
|
+
this roughly three- to fourfold. Every block includes the branding extension
|
|
486
|
+
and the attribution line; `--no-branding` drops both the code and the config
|
|
487
|
+
and takes **~24 KB** back off:
|
|
354
488
|
|
|
355
|
-
| Block | Languages | Bytes |
|
|
356
|
-
|
|
357
|
-
| `ready/en-bar.txt` | en |
|
|
358
|
-
| `ready/ru-bar.txt` | ru, ro, en |
|
|
359
|
-
| `ready/ru-box.txt` | ru, ro, en |
|
|
360
|
-
| `ready/ru-box-right.txt` | ru, ro, en |
|
|
361
|
-
| `ready/ru-modal.txt` | ru, ro, en |
|
|
362
|
-
| `ready/eu-bar.txt` | 34 languages | 161,
|
|
489
|
+
| Block | Languages | Bytes | gzip | `--no-branding` |
|
|
490
|
+
|---|---|---|---|---|
|
|
491
|
+
| `ready/en-bar.txt` | en | 134,969 | 40,519 | 110,907 |
|
|
492
|
+
| `ready/ru-bar.txt` | ru, ro, en | 136,590 | 41,315 | 112,508 |
|
|
493
|
+
| `ready/ru-box.txt` | ru, ro, en | 136,605 | 41,320 | 112,523 |
|
|
494
|
+
| `ready/ru-box-right.txt` | ru, ro, en | 136,614 | 41,326 | 112,526 |
|
|
495
|
+
| `ready/ru-modal.txt` | ru, ro, en | 136,598 | 41,318 | 112,514 |
|
|
496
|
+
| `ready/eu-bar.txt` | 34 languages | 185,244 | 59,665 | 161,182 |
|
|
497
|
+
|
|
498
|
+
0.4.0 adds roughly 16.1 KB over 0.3.6: iframe interception, strict mode
|
|
499
|
+
(same-site detection, the allowlists, the public-suffix table) and the
|
|
500
|
+
extensible tracker database.
|
|
363
501
|
|
|
364
502
|
Size is driven almost entirely by the bundled languages: `en` and `ru` are
|
|
365
503
|
built into the UI and cost nothing extra, while layout, position, theme and
|
|
@@ -540,13 +678,19 @@ has been verified and what has not.
|
|
|
540
678
|
- `dataLayer` event trace for consent restore, upgrade and withdrawal.
|
|
541
679
|
- npm entry points and TypeScript types: syntax and import smoke tests in Node
|
|
542
680
|
without a DOM.
|
|
543
|
-
- PHP files of the WordPress plugin pass `php -l` on 7.4 and 8.5.
|
|
681
|
+
- PHP files of the WordPress plugin pass `php -l` on 7.4, 8.3 and 8.5.
|
|
682
|
+
- The server-side rewriting engine has its own suite of 61 cases
|
|
683
|
+
(`plugins/wordpress/consentkit/tests/rewrite.test.php`), green on PHP 7.4,
|
|
684
|
+
8.3 and 8.5. It is a plain PHP CLI script, so it runs outside `npm test`.
|
|
544
685
|
|
|
545
686
|
### Not verified — read before production use
|
|
546
687
|
|
|
547
|
-
- **The WordPress plugin has
|
|
548
|
-
|
|
549
|
-
|
|
688
|
+
- **The WordPress plugin has been verified on a live install, but only one.**
|
|
689
|
+
It was run on WordPress 7.1 / PHP 8.3 in Docker (activation, settings
|
|
690
|
+
round-trip, shortcode, uninstall, server-side markup end to end). The declared
|
|
691
|
+
floor of WordPress 6.0 / PHP 7.4 has not been exercised live — the PHP files
|
|
692
|
+
pass `php -l` and the rewriting test suite on 7.4, 8.3 and 8.5 — and no theme
|
|
693
|
+
conflict or multisite behaviour has been observed.
|
|
550
694
|
- **The GTM container has never been through a real import.** The JSON is valid
|
|
551
695
|
and structurally modelled on the documented export format, but Tag Manager has
|
|
552
696
|
not accepted it in practice; some field names (notably GA4 config
|
package/npm/core.mjs
CHANGED
|
@@ -28,6 +28,9 @@ export const {
|
|
|
28
28
|
rejectAll,
|
|
29
29
|
withdraw,
|
|
30
30
|
show,
|
|
31
|
-
hide
|
|
31
|
+
hide,
|
|
32
|
+
// v0.4.0 (§1.3): merging service overrides into the tracker database is part
|
|
33
|
+
// of the public surface, so it must be reachable as a named import too.
|
|
34
|
+
_extendHostDb
|
|
32
35
|
} = ConsentKit;
|
|
33
36
|
export { ConsentKit };
|
package/npm/index.cjs
CHANGED
|
@@ -69,7 +69,10 @@ var hasDom = typeof document !== 'undefined' && typeof window !== 'undefined';
|
|
|
69
69
|
if (hasDom) {
|
|
70
70
|
// 2. Locales — optional language packs.
|
|
71
71
|
try { require('../src/ck-locales.js'); } catch (e) { /* optional */ }
|
|
72
|
-
// 3.
|
|
72
|
+
// 3. Branding — optional, and before the UI: it registers itself on
|
|
73
|
+
// ConsentKit._uiExtensions and must be there before the first mount().
|
|
74
|
+
try { require('../src/ck-ui-branding.js'); } catch (e) { /* optional */ }
|
|
75
|
+
// 4. UI — touches `document` at module scope, browser only.
|
|
73
76
|
try { require('../src/ck-ui.js'); } catch (e) { /* best effort */ }
|
|
74
77
|
}
|
|
75
78
|
|
package/npm/index.d.ts
CHANGED
|
@@ -88,6 +88,20 @@ export interface CkIntegrationsConfig {
|
|
|
88
88
|
gtmDataLayer?: boolean;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
/** v0.4.0 (§2). How much the blocking engine holds back before consent. */
|
|
92
|
+
export interface CkBlockingConfig {
|
|
93
|
+
/**
|
|
94
|
+
* `'known'` (default) blocks what the tracker database recognises.
|
|
95
|
+
* `'strict'` additionally intercepts EVERY third-party `<script src>` and
|
|
96
|
+
* `<iframe src>` that is not same-site, not in `allow`, not in the built-in
|
|
97
|
+
* allowlist (`ConsentKit._baseAllow`) and not an already-granted
|
|
98
|
+
* necessary/functional host. Interceptions are filed under `marketing`.
|
|
99
|
+
*/
|
|
100
|
+
mode?: 'known' | 'strict';
|
|
101
|
+
/** Hosts strict mode must never intercept. Suffix match: `p.com` covers `cdn.p.com`. */
|
|
102
|
+
allow?: string[];
|
|
103
|
+
}
|
|
104
|
+
|
|
91
105
|
/** One declared cookie, shown under its category in the preferences panel. */
|
|
92
106
|
export interface CkCookieTableEntry {
|
|
93
107
|
name: string;
|
|
@@ -109,6 +123,15 @@ export interface CkConfig {
|
|
|
109
123
|
/** Lifetime of the stored decision, in days. Default `365`. */
|
|
110
124
|
consentTtlDays?: number;
|
|
111
125
|
integrations?: CkIntegrationsConfig;
|
|
126
|
+
/** v0.4.0. Default `{ mode: 'known', allow: [] }`. */
|
|
127
|
+
blocking?: CkBlockingConfig;
|
|
128
|
+
/**
|
|
129
|
+
* v0.4.0 (§1.3). Extra `host: category` pairs merged into the tracker
|
|
130
|
+
* database. `init()` applies them before its initial scan, so scripts
|
|
131
|
+
* already in the markup are classified against them. In SaaS mode the
|
|
132
|
+
* service supplies this; `_extendHostDb()` does the same at any later point.
|
|
133
|
+
*/
|
|
134
|
+
hostdb?: Record<string, CkCategory>;
|
|
112
135
|
cookieTable?: CkCookieTableEntry[];
|
|
113
136
|
}
|
|
114
137
|
|
|
@@ -141,6 +164,50 @@ export interface ConsentKitApi {
|
|
|
141
164
|
show(): void;
|
|
142
165
|
/** Dispatches `ck:ui:close`. */
|
|
143
166
|
hide(): void;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* v0.4.0 (§1.3). Merges `{ host: category }` into the runtime tracker
|
|
170
|
+
* database and returns how many pairs were accepted. Matching follows the
|
|
171
|
+
* built-in table: a bare domain also covers its subdomains, and an override
|
|
172
|
+
* wins over the shipped classification for the same host.
|
|
173
|
+
*
|
|
174
|
+
* Safe before AND after `init()`. Afterwards, nothing already inserted is
|
|
175
|
+
* re-examined — a script that has loaded cannot be unloaded — but every
|
|
176
|
+
* later insertion is classified against the extended map.
|
|
177
|
+
*/
|
|
178
|
+
_extendHostDb(map: Record<string, CkCategory>): number;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* v0.4.0 (§2). The built-in strict-mode allowlist, as hosts plus a few
|
|
182
|
+
* `host/path` entries (reCAPTCHA). A copy: mutating it changes nothing.
|
|
183
|
+
*/
|
|
184
|
+
readonly _baseAllow: string[];
|
|
185
|
+
|
|
186
|
+
/** The category the engine would assign to a URL, or `null` if unknown. */
|
|
187
|
+
_categoryForUrl(url: string): CkCategory | null;
|
|
188
|
+
|
|
189
|
+
/** What is currently held back, host+path only — never a query string. */
|
|
190
|
+
_blocked(): CkBlockedEntry[];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** One entry of `ConsentKit._blocked()`. */
|
|
194
|
+
export interface CkBlockedEntry {
|
|
195
|
+
host: string;
|
|
196
|
+
path: string;
|
|
197
|
+
/** `'script'`, `'iframe'`, … */
|
|
198
|
+
kind: string;
|
|
199
|
+
category: CkCategory | null;
|
|
200
|
+
/** `'engine'` — intercepted by the patches; `'markup'` — marked up by hand. */
|
|
201
|
+
origin: 'engine' | 'markup';
|
|
202
|
+
/** v0.4.0. True when strict mode held this back, i.e. the host is unknown. */
|
|
203
|
+
strict: boolean;
|
|
204
|
+
/**
|
|
205
|
+
* v0.4.0. `false` when the category was granted but the element still never
|
|
206
|
+
* loaded — typically a script created and given a `src` without ever being
|
|
207
|
+
* appended, which `applyConsentToDom()` cannot reach. Such entries stay in
|
|
208
|
+
* the report after consent precisely so they can be diagnosed.
|
|
209
|
+
*/
|
|
210
|
+
revived: boolean;
|
|
144
211
|
}
|
|
145
212
|
|
|
146
213
|
declare const ConsentKit: ConsentKitApi;
|
|
@@ -156,6 +223,7 @@ export declare function rejectAll(): CkState;
|
|
|
156
223
|
export declare function withdraw(): CkState;
|
|
157
224
|
export declare function show(): void;
|
|
158
225
|
export declare function hide(): void;
|
|
226
|
+
export declare function _extendHostDb(map: Record<string, CkCategory>): number;
|
|
159
227
|
|
|
160
228
|
declare global {
|
|
161
229
|
interface Window {
|
package/npm/index.mjs
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
* re-exports the public API.
|
|
4
4
|
*
|
|
5
5
|
* Load order is contractual: ck-core.js (blocking starts at parse time) →
|
|
6
|
-
* ck-locales.js (extra language packs) → ck-ui.js (
|
|
6
|
+
* ck-locales.js (extra language packs) → ck-ui-branding.js (optional logo /
|
|
7
|
+
* attribution extension, which must register before the UI mounts) →
|
|
8
|
+
* ck-ui.js (Shadow DOM layer).
|
|
7
9
|
*
|
|
8
10
|
* Only the core is DOM-optional. `src/ck-ui.js` touches `document` at module
|
|
9
11
|
* scope, so it is imported dynamically behind a `typeof document` guard —
|
|
@@ -25,6 +27,13 @@ if (hasDom) {
|
|
|
25
27
|
await import('../src/ck-locales.js');
|
|
26
28
|
} catch (e) { /* locales are optional; ck-ui falls back to built-in en/ru */ }
|
|
27
29
|
|
|
30
|
+
// Optional branding extension. Before ck-ui.js on purpose: it registers
|
|
31
|
+
// itself on ConsentKit._uiExtensions and must be there before the first
|
|
32
|
+
// mount(). Absent, the UI simply draws no logo and no attribution line.
|
|
33
|
+
try {
|
|
34
|
+
await import('../src/ck-ui-branding.js');
|
|
35
|
+
} catch (e) { /* branding is optional; the UI renders without it */ }
|
|
36
|
+
|
|
28
37
|
// Required in the browser, fatal in Node — hence the guard above.
|
|
29
38
|
try {
|
|
30
39
|
await import('../src/ck-ui.js');
|
|
@@ -42,6 +51,9 @@ export const {
|
|
|
42
51
|
rejectAll,
|
|
43
52
|
withdraw,
|
|
44
53
|
show,
|
|
45
|
-
hide
|
|
54
|
+
hide,
|
|
55
|
+
// v0.4.0 (§1.3): merging service overrides into the tracker database is part
|
|
56
|
+
// of the public surface, so it must be reachable as a named import too.
|
|
57
|
+
_extendHostDb
|
|
46
58
|
} = ConsentKit;
|
|
47
59
|
export { ConsentKit };
|
package/npm/internal-stub.mjs
CHANGED
|
@@ -28,7 +28,7 @@ export function undecidedState() {
|
|
|
28
28
|
*/
|
|
29
29
|
export function createStub() {
|
|
30
30
|
const stub = {
|
|
31
|
-
version: '0.
|
|
31
|
+
version: '0.4.0',
|
|
32
32
|
config: {},
|
|
33
33
|
init: function () { return undecidedState(); },
|
|
34
34
|
allowed: function (cat) { return cat === 'necessary'; },
|
|
@@ -39,6 +39,12 @@ export function createStub() {
|
|
|
39
39
|
show: function () {},
|
|
40
40
|
hide: function () {},
|
|
41
41
|
_categories: CATEGORIES.slice(),
|
|
42
|
+
// v0.4.0: the stub mirrors the real surface, so consumer code that calls
|
|
43
|
+
// these needs no branching when the core failed to attach.
|
|
44
|
+
_extendHostDb: function () { return 0; },
|
|
45
|
+
_baseAllow: [],
|
|
46
|
+
_categoryForUrl: function () { return null; },
|
|
47
|
+
_blocked: function () { return []; },
|
|
42
48
|
_isStub: true
|
|
43
49
|
};
|
|
44
50
|
return stub;
|
package/package.json
CHANGED