@c15t/scripts 3.0.0-alpha.3 → 3.0.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -143,7 +143,7 @@ These docs describe c15t v3. Find your app's row in Choose your setup, then foll
143
143
  - [Pinterest Tag](./docs/integrations/pinterest-tag.md): Load the Pinterest Tag only after marketing consent with the c15t pinterestTag helper, guard pintrk event calls, and check it in DevTools.
144
144
  - [Pirsch](./docs/integrations/pirsch.md): Load Pirsch Analytics only after measurement consent with the c15t pirsch helper, keep custom event bindings working, and check it in DevTools.
145
145
  - [Plausible Analytics](./docs/integrations/plausible-analytics.md): Load the Plausible Analytics tracker only after measurement consent with the c15t plausibleAnalytics helper, and check it in DevTools.
146
- - [PostHog](./docs/integrations/posthog.md): Load PostHog before or after measurement consent with the c15t posthog helper, choose its cookieless behavior, and sync consent with an SDK you already initialize.
146
+ - [PostHog](./docs/integrations/posthog.md): Load PostHog before or after measurement consent with the c15t posthog helper, choose its cookieless behavior, turn off PostHog modules you do not use, and sync consent with an SDK you already initialize.
147
147
  - [Promptwatch](./docs/integrations/promptwatch.md): Load the Promptwatch attribution client only after measurement consent with the c15t promptwatch helper, and check it in DevTools.
148
148
  - [Reddit Pixel](./docs/integrations/reddit-pixel.md): Load the Reddit Pixel only after marketing consent with the c15t redditPixel helper, guard rdt conversion calls, and check it in DevTools.
149
149
  - [RudderStack](./docs/integrations/rudderstack.md): Load the RudderStack JavaScript SDK after measurement consent with the c15t rudderstack helper, or map c15t categories to destination consent IDs, and check each mode.
package/docs/README.md CHANGED
@@ -143,7 +143,7 @@ These docs describe c15t v3. Find your app's row in Choose your setup, then foll
143
143
  - [Pinterest Tag](./integrations/pinterest-tag.md): Load the Pinterest Tag only after marketing consent with the c15t pinterestTag helper, guard pintrk event calls, and check it in DevTools.
144
144
  - [Pirsch](./integrations/pirsch.md): Load Pirsch Analytics only after measurement consent with the c15t pirsch helper, keep custom event bindings working, and check it in DevTools.
145
145
  - [Plausible Analytics](./integrations/plausible-analytics.md): Load the Plausible Analytics tracker only after measurement consent with the c15t plausibleAnalytics helper, and check it in DevTools.
146
- - [PostHog](./integrations/posthog.md): Load PostHog before or after measurement consent with the c15t posthog helper, choose its cookieless behavior, and sync consent with an SDK you already initialize.
146
+ - [PostHog](./integrations/posthog.md): Load PostHog before or after measurement consent with the c15t posthog helper, choose its cookieless behavior, turn off PostHog modules you do not use, and sync consent with an SDK you already initialize.
147
147
  - [Promptwatch](./integrations/promptwatch.md): Load the Promptwatch attribution client only after measurement consent with the c15t promptwatch helper, and check it in DevTools.
148
148
  - [Reddit Pixel](./integrations/reddit-pixel.md): Load the Reddit Pixel only after marketing consent with the c15t redditPixel helper, guard rdt conversion calls, and check it in DevTools.
149
149
  - [RudderStack](./integrations/rudderstack.md): Load the RudderStack JavaScript SDK after measurement consent with the c15t rudderstack helper, or map c15t categories to destination consent IDs, and check each mode.
@@ -31,8 +31,9 @@ feature, stay blocked.
31
31
 
32
32
  A save records the choice in the browser first and sends it to the backend
33
33
  afterwards. The stock banner, preference dialog and IAB surfaces in every
34
- framework adapter, and the browser client's `acceptAll()`, `rejectAll()`
35
- and `save()`, close without waiting for the backend. In order:
34
+ framework adapter, and the `acceptAll()`, `rejectAll()` and `save()` methods
35
+ of the browser and Astro clients, close without waiting for the backend. In
36
+ order:
36
37
 
37
38
  1. In the click task, the explicit choice and effective permissions change,
38
39
  `onChoiceRecorded` and `onPermissionsChanged` run, gated scripts, iframes
@@ -52,9 +53,10 @@ and `save()`, close without waiting for the backend. In order:
52
53
 
53
54
  A failed request does not reopen the surface or roll the choice back. The
54
55
  kernel emits `command:error`, which reaches the `onError` callback in adapters
55
- that accept one, and queues the payload in localStorage. The queue is replayed
56
- after the next successful initialization and when the browser comes back
57
- online, up to 10 attempts over 7 days. A replay carries the original action
56
+ that accept one, and queues the payload in localStorage. Where localStorage is
57
+ unavailable, the queue lives in memory until the page unloads. The queue is
58
+ replayed after the next successful initialization and when the browser comes
59
+ back online, up to 10 attempts over 7 days. A replay carries the original action
58
60
  time and policy snapshot token, so the backend records when the visitor
59
61
  decided, and a duplicate submission resolves to the same consent record. A
60
62
  backend that signs policy snapshot tokens rejects a replay made after the
@@ -66,6 +68,14 @@ after its TC string is encoded, which can wait for the TCF library to load.
66
68
  If that local step records nothing, for example because the vendor list
67
69
  failed to load, the surface comes back so the visitor can try again.
68
70
 
71
+ Every adapter leaves the same surface after a save: the banner while the
72
+ policy still owes a choice or a notice, and nothing once no prompt is owed,
73
+ while the policy is still loading, or after it failed to resolve. A banner
74
+ the visitor reopened closes too. A save that records nothing new, such as an
75
+ unchanged selection, closes the surface when it resolves successfully. Opening
76
+ or closing a surface, or starting another save, before then leaves the surface
77
+ as the visitor set it.
78
+
69
79
  ## Preserve records during hydration
70
80
 
71
81
  Server helpers return records with policy information and evaluation time.
@@ -194,6 +204,10 @@ receive a stale TC string: c15t withdraws it, or holds it back, before
194
204
 
195
205
  ### Clearing records across tabs
196
206
 
207
+ `clearRecords()` also drops every save queued for replay, with or without
208
+ browser persistence, so nothing the visitor decided before the clear reaches
209
+ the backend afterwards.
210
+
197
211
  `clearRecords()` removes every record and then stores the time of the clear,
198
212
  the clear epoch, under its own key: `c15t-epoch` in localStorage and a cookie
199
213
  of the same name (`<storageKey>-epoch` with a custom `storageKey`). Clearing
@@ -68,8 +68,7 @@ The `ConsentGate` placeholder reads the `consentGate` section:
68
68
  | `consentGate.policyBlocked` | React and Vue show it in place of the title, with no button, when a strict policy leaves the category out of scope. |
69
69
 
70
70
  Earlier versions called this section `frame`. Copy under `frame` in
71
- `i18n.messages`, custom translations or an older backend's `/init` response
72
- still applies. c15t reads it as `consentGate`, a key set under `consentGate`
71
+ `i18n.messages` or custom translations still applies. c15t reads it as `consentGate`, a key set under `consentGate`
73
72
  wins over the same key under `frame`, and c15t logs a warning once outside
74
73
  production. Rename the section to `consentGate` to remove the warning.
75
74
 
@@ -65,6 +65,15 @@ c15t({
65
65
 
66
66
  Scripts from `astro.config.mjs` and from the client entrypoint both load.
67
67
 
68
+ ## What a site without scripts skips
69
+
70
+ The script loader is part of the page's boot script only when the site
71
+ configures `scripts` in `astro.config.mjs` or sets a `clientEntrypoint`, which
72
+ may add some. A site with neither never downloads it, about 4 KB gzip less on
73
+ every page. The [network blocker](./network-blocker.md) works the same way: it
74
+ ships in the boot script when the integration options have `networkBlocker`
75
+ rules, and loads as its own chunk when only the client entrypoint sets them.
76
+
68
77
  ## Gate an inline script
69
78
 
70
79
  For a script that has to stay in the page's markup, make it inert and label it
@@ -52,6 +52,24 @@ const scripts = [
52
52
  [script loader](https://c15t.com/docs/frameworks/javascript/modules/script-loader) page lists
53
53
  every field and callback.
54
54
 
55
+ ## When the script loader downloads
56
+
57
+ With `@c15t/browser` from npm, the script loader and the network blocker
58
+ share a separate chunk. It loads when c15t starts, and only if `scripts` is
59
+ not empty or `networkBlocker` has rules, so a page with neither never
60
+ downloads it. On a page with either, the browser requests it after your
61
+ JavaScript has run, which delays a returning visitor's consented scripts and
62
+ held requests by one request.
63
+
64
+ Your bundler names that chunk, so c15t cannot link it from your HTML. To
65
+ start the download earlier, add a `<link rel="modulepreload">` for the chunk
66
+ your build emits for `@c15t/core/dist/modules/loader-and-blocker.js`. With
67
+ Vite, `.vite/manifest.json` lists it under that path when `build.manifest` is
68
+ on. Give the link `fetchpriority="low"`. c15t needs the chunk only when it
69
+ starts, and at the default priority the preload can delay your app's own
70
+ chunks over HTTP/1.1. The script-tag build, `c15t.js`, already contains the
71
+ loader.
72
+
55
73
  ## Gate a snippet in your HTML
56
74
 
57
75
  `@c15t/browser` also runs `<script type="text/plain" data-c15t-category>`
@@ -28,6 +28,13 @@ export const scripts = [
28
28
 
29
29
  Replace the placeholder PostHog project key and X Pixel ID with your own.
30
30
 
31
+ The provider loads the script loader as a separate chunk, shared with the
32
+ [network blocker](./network-blocker.md), and only when `scripts` is not empty or
33
+ the blocker has rules, so an app with neither never downloads it. A
34
+ single-page app has no server render to link the chunk from, so the browser
35
+ requests it after your app's JavaScript has run. A SvelteKit app can preload
36
+ it from the server-rendered page; the SvelteKit scripts guide shows how.
37
+
31
38
  ## How registered scripts load
32
39
 
33
40
  The provider's `scripts` prop takes an array of script configurations. Each
@@ -140,6 +140,16 @@ Open DevTools, clear site data for your origin and reload:
140
140
  `fetch('https://www.google-analytics.com/g/collect')` in the console returns a
141
141
  response with status `451` while measurement is denied.
142
142
 
143
+ ## Preload the blocker
144
+
145
+ The blocker shares a separate chunk with the script loader. The chunk loads
146
+ only on pages with `networkBlocker` rules or `scripts`, and matching requests
147
+ wait until it has loaded. Add the `c15tPreload()` Vite plugin so `c15tHandle`
148
+ links the chunk from the page's `<head>` and the browser fetches it with the
149
+ app's own code.
150
+ [Preload the script loader](./scripts.md#preload-the-script-loader) shows the
151
+ setup.
152
+
143
153
  ## Server requests are not blocked
144
154
 
145
155
  The network blocker runs in the browser. A `fetch` in a SvelteKit `load`,
@@ -32,6 +32,37 @@ configurations hold functions, which a server load cannot send to the
32
32
  browser. Scripts load only in the browser, after hydration, so they never
33
33
  appear in server HTML.
34
34
 
35
+ ## Preload the script loader
36
+
37
+ The provider loads the script loader only on pages whose `scripts` array is
38
+ not empty or that have [network blocker](./network-blocker.md) rules. The loader
39
+ and the blocker share one separate chunk. Pages with neither never download
40
+ it. On a page with either, the browser would otherwise request the chunk after
41
+ the app's JavaScript has run, and a returning visitor's consented scripts and
42
+ held requests would wait for that extra request.
43
+
44
+ Add the `c15tPreload()` Vite plugin so `c15tHandle` can link the chunk from
45
+ the page's `<head>` with `<link rel="modulepreload">`:
46
+
47
+ ```ts title="vite.config.ts (partial)"
48
+ import { c15tPreload } from '@c15t/svelte/vite';
49
+
50
+ export default defineConfig({ plugins: [sveltekit(), c15tPreload()] });
51
+ ```
52
+
53
+ SvelteKit builds the server before the client, so the server cannot know the
54
+ chunk's file name. After the client build, the plugin writes the chunk URL
55
+ into the server output, before SvelteKit prerenders pages and before the
56
+ adapter copies the build. Then `c15tHandle` adds one link to every page whose
57
+ provider has scripts or blocker rules, prerendered pages included. The link
58
+ carries the provider's `nonce`, or else the nonce SvelteKit put on its own
59
+ scripts. It asks for low priority (`fetchpriority="low"`): the
60
+ runtime needs the chunk only after hydration, so the browser fetches your
61
+ app's own chunks first. It does nothing in `vite dev`.
62
+
63
+ Without the plugin, or without `c15tHandle` in `hooks.server.ts`, scripts
64
+ still load, one request later.
65
+
35
66
  ## How registered scripts load
36
67
 
37
68
  The provider's `scripts` prop takes an array of script configurations. Each
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  title: PostHog
3
3
  description: Load PostHog before or after measurement consent with the c15t
4
- posthog helper, choose its cookieless behavior, and sync consent with an SDK
5
- you already initialize.
4
+ posthog helper, choose its cookieless behavior, turn off PostHog modules you
5
+ do not use, and sync consent with an SDK you already initialize.
6
6
  icon: posthog
7
7
  group: integrations
8
8
  ---
@@ -257,15 +257,20 @@ A kernel you create yourself needs a loader from
257
257
 
258
258
  ## Options
259
259
 
260
- | Option | Default | Behavior |
261
- | ------------- | ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
262
- | `id` | Required | Project token, starting with `phc_`. The helper trims it. Empty or whitespace-only values throw. |
263
- | `region` | `'eu'` | `'eu'` or `'us'`. Picks the API, UI and loader hosts when you do not set them. |
264
- | `apiHost` | `https://eu.i.posthog.com` | API host for a proxy or self-hosted PostHog. Without `scriptUrl`, the loader URL becomes `<apiHost>/static/array.js`. |
265
- | `uiHost` | The region's UI host | UI host, for example `https://eu.posthog.com`. A custom `apiHost` with no `region` uses the API host. |
266
- | `scriptUrl` | `https://eu-assets.i.posthog.com/static/array.js` | Loader URL override. A blank value falls back to the default. |
267
- | `loadMode` | `'always'` | When the SDK loads. See the table below. |
268
- | `initOptions` | `{ cookieless_mode: 'on_reject', defaults: '2026-01-30' }` | Options passed to `posthog.init`, merged over the defaults. The helper sets `api_host` and `ui_host` after your values, so change hosts with the options above. |
260
+ | Option | Default | Behavior |
261
+ | ----------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
262
+ | `id` | Required | Project token, starting with `phc_`. The helper trims it. Empty or whitespace-only values throw. |
263
+ | `region` | `'eu'` | `'eu'` or `'us'`. Picks the API, UI and loader hosts when you do not set them. |
264
+ | `apiHost` | `https://eu.i.posthog.com` | API host for a proxy or self-hosted PostHog. Without `scriptUrl`, the loader URL becomes `<apiHost>/static/array.js`. |
265
+ | `uiHost` | The region's UI host | UI host, for example `https://eu.posthog.com`. A custom `apiHost` with no `region` uses the API host. |
266
+ | `scriptUrl` | `https://eu-assets.i.posthog.com/static/array.js` | Loader URL override. A blank value falls back to the default. |
267
+ | `loadMode` | `'always'` | When the SDK loads. See the table below. |
268
+ | `features.surveys` | Unset | `false` sets `disable_surveys: true` and skips `surveys.js`. See [turn off features you do not use](#turn-off-features-you-do-not-use). |
269
+ | `features.heatmaps` | Unset, follows the project | Sets `capture_heatmaps`. |
270
+ | `features.deadClicks` | Unset, follows the project | Sets `capture_dead_clicks`. |
271
+ | `features.webVitals` | Unset, follows the project | Sets `capture_performance: { web_vitals }`. Replay network timing keeps following the project. |
272
+ | `features.featureFlags` | Unset, follows the project | `false` sets `advanced_disable_feature_flags: true` and stops `/flags` requests. |
273
+ | `initOptions` | `{ cookieless_mode: 'on_reject', defaults: '2026-01-30' }` | Options passed to `posthog.init`, merged over the defaults and `features`. The helper sets `api_host` and `ui_host` after your values, so change hosts with the options above. |
269
274
 
270
275
  ## Loading and revocation
271
276
 
@@ -283,6 +288,78 @@ project; see
283
288
  Set `cookieless_mode: 'never'`, as in the example, if a refusal must stop
284
289
  capture.
285
290
 
291
+ ## Turn off features you do not use
292
+
293
+ After `array.js` loads, PostHog reads your `posthog.init` options and the
294
+ project's remote config, then decides which extra modules to download and
295
+ whether to request `/flags`. Set a `features` switch to `false` for each
296
+ feature your site does not use:
297
+
298
+ ```ts
299
+ posthog({
300
+ id: 'phc_YOUR_PROJECT_TOKEN',
301
+ region: 'eu',
302
+ loadMode: 'after-consent',
303
+ features: {
304
+ surveys: false,
305
+ heatmaps: false,
306
+ deadClicks: false,
307
+ webVitals: false,
308
+ featureFlags: false,
309
+ },
310
+ });
311
+ ```
312
+
313
+ | Switch | `false` sets | What PostHog skips |
314
+ | -------------- | -------------------------------------------- | --------------------------------------------------------------------------- |
315
+ | `surveys` | `disable_surveys: true` | `surveys.js`, about 29 KB |
316
+ | `heatmaps` | `capture_heatmaps: false` | Heatmap capture. With `deadClicks: false` too, `dead-clicks-autocapture.js` |
317
+ | `deadClicks` | `capture_dead_clicks: false` | `dead-clicks-autocapture.js`, about 8 KB, once heatmaps are off too |
318
+ | `webVitals` | `capture_performance: { web_vitals: false }` | `web-vitals-with-attribution.js`, about 6 KB |
319
+ | `featureFlags` | `advanced_disable_feature_flags: true` | `/flags` requests. The remote config still loads |
320
+
321
+ Sizes are brotli-compressed, measured from posthog-js 1.436.1.
322
+
323
+ An unset switch adds nothing to `posthog.init`. For heatmaps, dead clicks, web
324
+ vitals and feature flags, PostHog then follows the setting in your PostHog
325
+ project. `true` sets the opposite value and overrides the project. For
326
+ `surveys` and `featureFlags`, `true` is PostHog's own default, so it behaves
327
+ the same as unset.
328
+
329
+ Surveys work differently. PostHog downloads `surveys.js` whenever the remote
330
+ config includes a `surveys` value, even when surveys are off in the project.
331
+ `surveys: false` is the only way to skip it.
332
+
333
+ `initOptions` wins over a switch that sets the same key. A
334
+ `capture_performance` value in `initOptions` replaces the whole object that
335
+ `webVitals` builds.
336
+
337
+ ### Avoid PostHog's option traps
338
+
339
+ These rules also apply when you pass PostHog options yourself, in
340
+ `initOptions` or in your own `posthog.init`:
341
+
342
+ * Use `advanced_disable_feature_flags: true` to stop `/flags`, not
343
+ `advanced_disable_flags: true`. The second also stops PostHog loading the
344
+ remote config, so session replay never starts and other features fall back to
345
+ local config.
346
+ * With feature flags off, surveys that target a feature flag never show.
347
+ PostHog logs a warning about it. If you need those surveys, leave
348
+ `featureFlags` unset and pass
349
+ `advanced_only_evaluate_survey_feature_flags: true` instead. PostHog still
350
+ requests `/flags`, but evaluates only survey flags.
351
+ * While heatmaps are on, in `posthog.init` or in the project, PostHog loads
352
+ `dead-clicks-autocapture.js` whatever `capture_dead_clicks` says. Turn off
353
+ both to skip it.
354
+ * `capture_performance: false` turns off web vitals and session replay network
355
+ timing. `{ web_vitals: false }`, which `webVitals: false` sets, leaves network
356
+ timing to the project. `capture_performance: true` forces both on.
357
+
358
+ Product tours (`product-tours.js`, about 36 KB) and exception autocapture
359
+ (`exception-autocapture.js`, about 6 KB) load only when the project turns them
360
+ on. To keep them off whatever the project says, pass
361
+ `disable_product_tours: true` or `capture_exceptions: false` in `initOptions`.
362
+
286
363
  ## Guard your own capture calls
287
364
 
288
365
  Events your code sends need their own permission check. The `posthog` global
@@ -338,6 +415,11 @@ measurement is denied, so the SDK is told to opt out. `onConsentChange` runs on
338
415
  every later change. This does not delay the SDK import or its first request.
339
416
  `loadMode: 'disabled'` is not a substitute, because it syncs nothing.
340
417
 
418
+ `features` belongs to the helper, so it does nothing here. To skip modules you
419
+ do not use, pass the PostHog options from
420
+ [turn off features you do not use](#turn-off-features-you-do-not-use) to your
421
+ own `posthog.init`, for example `disable_surveys: true`.
422
+
341
423
  ## Measure opt-in rate
342
424
 
343
425
  If you run a banner experiment, the backend already counts visitors and
@@ -355,6 +437,12 @@ With `loadMode: 'always'`, `array.js` loads before a choice instead. Check that
355
437
  no capture request is sent while measurement is denied, unless you chose
356
438
  cookieless capture.
357
439
 
440
+ If you turned features off, allow measurement and filter the DevTools Network
441
+ panel by `posthog`. Reload the page. You should see `array.js`, the remote
442
+ config and capture requests, but no `/flags` request with `featureFlags: false`
443
+ and none of the modules you turned off, such as `surveys.js` or
444
+ `dead-clicks-autocapture.js`.
445
+
358
446
  Test in a private window with an opt-in policy. Open DevTools Network, disable
359
447
  the cache and filter by the vendor's domain:
360
448
 
@@ -431,10 +431,31 @@ npx @c15t/cli@alpha self-host migrate --config ./c15t-backend.config.ts --apply
431
431
  ```
432
432
 
433
433
  The migrator recognizes the v2 schema, adopts it, and adds the v3 tables and
434
- columns. [Database setup](https://c15t.com/docs/self-host/guides/database-setup#upgrade-a-v2-backend)
434
+ columns. Apply it before the v3 backend serves traffic: v3 records policy
435
+ decisions without the v2 `jurisdiction` label, which the migration makes
436
+ nullable. [Database setup](https://c15t.com/docs/self-host/guides/database-setup#upgrade-a-v2-backend)
435
437
  covers the details, and the [backend quickstart](https://c15t.com/docs/self-host/quickstart)
436
438
  shows a complete v3 config and route.
437
439
 
440
+ ### Remove `disableGeoLocation`
441
+
442
+ v3 removes the `disableGeoLocation` manifest option. Policy rules decide by
443
+ country and region. To show every visitor the same banner, configure one rule
444
+ with `match: { isDefault: true }`. It applies wherever the visitor is, so the
445
+ browser can resolve it without asking the backend for a location.
446
+
447
+ To test one region's rule from anywhere, set the country in the client's
448
+ `overrides`, for example `overrides: { country: 'US' }`. See
449
+ [runtime options](https://c15t.com/docs/frameworks/javascript/api/runtime).
450
+
451
+ ### Stop reading `jurisdiction`
452
+
453
+ `/init` responses, session reports and `sessions.onReport` no longer carry a
454
+ `jurisdiction` label such as `GDPR`. Read the matched policy from
455
+ `policyResolution` instead, or the report's `policy`, `country` and `region`.
456
+ The backend still accepts `jurisdiction` in a v2 client's save request and
457
+ ignores it.
458
+
438
459
  ## Update the Node.js SDK
439
460
 
440
461
  Install `@c15t/node-sdk@alpha`. The v2 client is gone: create one with
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c15t/scripts",
3
- "version": "3.0.0-alpha.3",
3
+ "version": "3.0.0-alpha.4",
4
4
  "description": "Deprecated v3 compatibility package for @c15t/integrations. Migrate before v4.",
5
5
  "homepage": "https://c15t.com/docs/upgrade-v3#rename-the-integrations-dependency",
6
6
  "bugs": {
@@ -41,7 +41,7 @@
41
41
  "test": "vitest run"
42
42
  },
43
43
  "dependencies": {
44
- "@c15t/integrations": "3.0.0-alpha.3"
44
+ "@c15t/integrations": "3.0.0-alpha.4"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@c15t/typescript-config": "0.0.1",