@c15t/scripts 3.0.0-alpha.1 → 3.0.0-alpha.2
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 +4 -0
- package/README.md +3 -3
- package/dist/e2e-test-utils.js +5 -3
- package/dist/events.js +218 -0
- package/dist/registry.js +30 -0
- package/dist/vendors/ads-and-pixels/pinterest-tag.js +123 -0
- package/dist/vendors/analytics/google-tag.js +14 -2
- package/dist/vendors/analytics/one-dollar-stats.js +30 -0
- package/dist/vendors/analytics/segment.js +10 -1
- package/dist/vendors/functional/front-chat.js +64 -0
- package/dist/vendors/tag-managers/google-tag-manager.js +17 -3
- package/dist-types/events.d.ts +46 -0
- package/dist-types/registry.d.ts +27 -0
- package/dist-types/vendors/ads-and-pixels/pinterest-tag.d.ts +295 -0
- package/dist-types/vendors/analytics/google-tag.d.ts +3 -1
- package/dist-types/vendors/analytics/one-dollar-stats.d.ts +39 -0
- package/dist-types/vendors/analytics/segment.d.ts +7 -1
- package/dist-types/vendors/functional/front-chat.d.ts +62 -0
- package/dist-types/vendors/tag-managers/google-tag-manager.d.ts +3 -1
- package/docs/README.md +4 -0
- package/docs/customization/overview.md +4 -3
- package/docs/customization/recipes.md +4 -2
- package/docs/customization/tokens.md +66 -3
- package/docs/frameworks/javascript/script-loader.md +6 -0
- package/docs/frameworks/next/script-loader.md +18 -12
- package/docs/frameworks/react/script-loader.md +6 -0
- package/docs/guides/consent-state.md +327 -0
- package/docs/guides/shared-consent-controls.md +158 -0
- package/docs/integrations/adobe-analytics.md +1 -1
- package/docs/integrations/ahrefs-analytics.md +1 -1
- package/docs/integrations/amplitude.md +1 -1
- package/docs/integrations/clearbit.md +1 -1
- package/docs/integrations/cloudflare-web-analytics.md +1 -1
- package/docs/integrations/cloudflare-zaraz.md +1 -1
- package/docs/integrations/crisp.md +1 -1
- package/docs/integrations/databuddy.md +1 -1
- package/docs/integrations/fathom-analytics.md +1 -1
- package/docs/integrations/front-chat.md +322 -0
- package/docs/integrations/google-maps.md +1 -1
- package/docs/integrations/google-tag-manager.md +1 -1
- package/docs/integrations/google-tag.md +1 -1
- package/docs/integrations/granular-consent.md +3 -1
- package/docs/integrations/heap.md +1 -1
- package/docs/integrations/hightouch.md +1 -1
- package/docs/integrations/hotjar.md +1 -1
- package/docs/integrations/intercom.md +1 -1
- package/docs/integrations/linkedin-insights.md +1 -1
- package/docs/integrations/logrocket.md +1 -1
- package/docs/integrations/matomo-analytics.md +1 -1
- package/docs/integrations/meta-pixel.md +1 -1
- package/docs/integrations/microsoft-clarity.md +1 -1
- package/docs/integrations/microsoft-uet.md +1 -1
- package/docs/integrations/mixpanel-analytics.md +1 -1
- package/docs/integrations/one-dollar-stats.md +305 -0
- package/docs/integrations/openai-pixel.md +1 -1
- package/docs/integrations/overview.md +17 -14
- package/docs/integrations/pinterest-tag.md +321 -0
- package/docs/integrations/pirsch.md +1 -1
- package/docs/integrations/plausible-analytics.md +1 -1
- package/docs/integrations/posthog.md +1 -1
- package/docs/integrations/promptwatch.md +1 -1
- package/docs/integrations/reddit-pixel.md +1 -1
- package/docs/integrations/rudderstack.md +1 -1
- package/docs/integrations/rybbit-analytics.md +1 -1
- package/docs/integrations/segment.md +1 -1
- package/docs/integrations/snapchat-pixel.md +1 -1
- package/docs/integrations/tiktok-pixel.md +1 -1
- package/docs/integrations/umami-analytics.md +1 -1
- package/docs/integrations/vercel-analytics.md +1 -1
- package/docs/integrations/x-pixel.md +1 -1
- package/docs/integrations/youtube.md +1 -1
- package/docs/upgrade-v3.md +129 -1
- package/package.json +25 -2
package/AGENTS.md
CHANGED
|
@@ -30,6 +30,7 @@ These docs describe v3. Start with Inth hosted setup, identify the framework, ro
|
|
|
30
30
|
- [Understand consent state](./docs/guides/consent-state.md): Distinguish policy resolution, effective permissions, explicit choices, notices and privacy signals.
|
|
31
31
|
- [Data fetching and transports](./docs/guides/data-fetching.md): Choose cached manifests, backend init or offline policy resolution, and understand where consent records are saved.
|
|
32
32
|
- [Choose a deployment mode](./docs/guides/deployment-modes.md): Choose who runs your consent backend, then select manifest, init or offline resolution for your deployment.
|
|
33
|
+
- [Share consent controls across frameworks](./docs/guides/shared-consent-controls.md): Use the same c15t script lifecycle, external consent source, and event controls in every framework.
|
|
33
34
|
- [Troubleshoot consent](./docs/guides/troubleshooting.md): Diagnose missing banners, early vendor requests, lost choices and hydration differences.
|
|
34
35
|
- [Verify consent before shipping](./docs/guides/verify-consent.md): Test requests, policy resolution, persistence, navigation and preference changes in a production build.
|
|
35
36
|
|
|
@@ -54,6 +55,7 @@ These docs describe v3. Start with Inth hosted setup, identify the framework, ro
|
|
|
54
55
|
- [Crisp](./docs/integrations/crisp.md): Configure Crisp with c15t v3, understand functionality permission and verify loading and revocation.
|
|
55
56
|
- [Databuddy](./docs/integrations/databuddy.md): Configure Databuddy's initial and updated consent state with c15t v3.
|
|
56
57
|
- [Fathom Analytics](./docs/integrations/fathom-analytics.md): Configure Fathom Analytics with c15t v3, understand measurement permission and verify loading and revocation.
|
|
58
|
+
- [Front Chat](./docs/integrations/front-chat.md): Load the Front Chat widget with functionality permission, forward CSP nonces and clear the session on revocation.
|
|
57
59
|
- [Google Maps](./docs/integrations/google-maps.md): Prevent a map iframe from mounting before the required permission.
|
|
58
60
|
- [Google Tag](./docs/integrations/google-tag.md): Configure gtag with c15t Consent Mode signals and understand its loading behavior.
|
|
59
61
|
- [Google Tag Manager](./docs/integrations/google-tag-manager.md): Load GTM with c15t consent signals and verify the tags inside your container.
|
|
@@ -69,8 +71,10 @@ These docs describe v3. Start with Inth hosted setup, identify the framework, ro
|
|
|
69
71
|
- [Microsoft Clarity](./docs/integrations/microsoft-clarity.md): Configure Microsoft Clarity with c15t v3, understand measurement permission and verify loading and revocation.
|
|
70
72
|
- [Microsoft UET](./docs/integrations/microsoft-uet.md): Configure Microsoft UET with c15t v3, understand marketing permission and verify loading and revocation.
|
|
71
73
|
- [Mixpanel](./docs/integrations/mixpanel-analytics.md): Configure Mixpanel with c15t v3, understand measurement permission and verify loading and revocation.
|
|
74
|
+
- [OneDollarStats](./docs/integrations/one-dollar-stats.md): Load the OneDollarStats tracker with measurement permission, forward its settings and verify loading and revocation.
|
|
72
75
|
- [OpenAI Pixel](./docs/integrations/openai-pixel.md): Configure the OpenAI Measurement Pixel for ChatGPT Ads with c15t v3, manage marketing permission and verify conversion delivery.
|
|
73
76
|
- [Overview](./docs/integrations/overview.md): Find all c15t integrations for analytics, tag managers, advertising, chat and embedded content.
|
|
77
|
+
- [Pinterest Tag](./docs/integrations/pinterest-tag.md): Configure the Pinterest Tag with c15t v3, track typed events and verify marketing permission, revocation and reload.
|
|
74
78
|
- [Pirsch](./docs/integrations/pirsch.md): Configure Pirsch with c15t v3, understand measurement permission and verify loading and revocation.
|
|
75
79
|
- [Plausible Analytics](./docs/integrations/plausible-analytics.md): Configure Plausible Analytics with c15t v3, understand measurement permission and verify loading and revocation.
|
|
76
80
|
- [PostHog](./docs/integrations/posthog.md): Choose PostHog loading and cookieless behavior, configure the region, and synchronize v3 permissions.
|
package/README.md
CHANGED
|
@@ -39,9 +39,9 @@ For further information, guides, and examples visit the [reference documentation
|
|
|
39
39
|
- **Google Tag Manager**: Loads with Google Consent Mode v2 defaults set to denied; GTM-managed tags fire only once matching consent is granted ([guide](https://c15t.com/docs/integrations/google-tag-manager))
|
|
40
40
|
- **Cloudflare Zaraz**: Maps c15t effective permissions to Zaraz purpose IDs for tools managed in Cloudflare ([guide](https://c15t.com/docs/integrations/cloudflare-zaraz))
|
|
41
41
|
- **Google Analytics 4 + Google Ads (gtag.js)**: Consent Mode v2 defaults and consent updates when users make a choice ([guide](https://c15t.com/docs/integrations/google-tag))
|
|
42
|
-
- **Conversion pixels**: Meta Pixel, OpenAI Pixel, TikTok Pixel, LinkedIn Insights, Microsoft UET (Microsoft Ads), X Pixel, Reddit Pixel, Snapchat Pixel
|
|
43
|
-
- **Analytics**: PostHog, Amplitude, Heap, Segment, RudderStack, Hightouch, Mixpanel, Microsoft Clarity, Hotjar, Plausible, Fathom, Matomo, Umami, Vercel Analytics
|
|
44
|
-
- **Chat widgets**: Intercom, Crisp
|
|
42
|
+
- **Conversion pixels**: Meta Pixel, OpenAI Pixel, Pinterest Tag, TikTok Pixel, LinkedIn Insights, Microsoft UET (Microsoft Ads), X Pixel, Reddit Pixel, Snapchat Pixel
|
|
43
|
+
- **Analytics**: PostHog, Amplitude, Heap, Segment, RudderStack, Hightouch, Mixpanel, Microsoft Clarity, Hotjar, Plausible, Fathom, Matomo, Umami, Vercel Analytics, OneDollarStats
|
|
44
|
+
- **Chat widgets**: Intercom, Crisp, Front Chat
|
|
45
45
|
|
|
46
46
|
## Example
|
|
47
47
|
|
package/dist/e2e-test-utils.js
CHANGED
|
@@ -9,12 +9,13 @@ const e2e_test_utils_muteSubscription = function(source) {
|
|
|
9
9
|
subscribe: ()=>()=>{}
|
|
10
10
|
};
|
|
11
11
|
};
|
|
12
|
-
const e2e_test_utils_reconcileScripts = function(scripts, consents) {
|
|
12
|
+
const e2e_test_utils_reconcileScripts = function(scripts, consents, options = {}) {
|
|
13
13
|
const before = loader ? loader.getLoadedScriptIds() : [];
|
|
14
14
|
kernel.commands.save(consents);
|
|
15
15
|
if (loader) loader.updateScripts(scripts);
|
|
16
16
|
else loader = createScriptLoader({
|
|
17
17
|
kernel: e2e_test_utils_muteSubscription(kernel),
|
|
18
|
+
nonce: options.nonce,
|
|
18
19
|
scripts
|
|
19
20
|
});
|
|
20
21
|
const after = loader.getLoadedScriptIds();
|
|
@@ -23,8 +24,8 @@ const e2e_test_utils_reconcileScripts = function(scripts, consents) {
|
|
|
23
24
|
unloaded: before.filter((id)=>!after.includes(id))
|
|
24
25
|
};
|
|
25
26
|
};
|
|
26
|
-
const e2e_test_utils_loadScripts = function(scripts, consents) {
|
|
27
|
-
return e2e_test_utils_reconcileScripts(scripts, consents).loaded;
|
|
27
|
+
const e2e_test_utils_loadScripts = function(scripts, consents, options = {}) {
|
|
28
|
+
return e2e_test_utils_reconcileScripts(scripts, consents, options).loaded;
|
|
28
29
|
};
|
|
29
30
|
const e2e_test_utils_updateScripts = function(scripts, consents) {
|
|
30
31
|
return e2e_test_utils_reconcileScripts(scripts, consents);
|
|
@@ -110,6 +111,7 @@ const e2e_test_utils_resetVendorGlobals = function() {
|
|
|
110
111
|
'pirschClearSession',
|
|
111
112
|
'pirschInit',
|
|
112
113
|
'pirschNotFound',
|
|
114
|
+
'pintrk',
|
|
113
115
|
'plausible',
|
|
114
116
|
'posthog',
|
|
115
117
|
'rdt',
|
package/dist/events.js
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { evaluateConsent, getEffectiveGateState } from "@c15t/core";
|
|
2
|
+
const createEventDispatcher = (options)=>{
|
|
3
|
+
let previousPath;
|
|
4
|
+
const globals = options.globals ?? ("u" < typeof window ? {} : window);
|
|
5
|
+
const call = (path, args)=>{
|
|
6
|
+
let owner = globals;
|
|
7
|
+
const keys = 'string' == typeof path ? path.split('.') : [
|
|
8
|
+
...path
|
|
9
|
+
];
|
|
10
|
+
const method = keys.pop();
|
|
11
|
+
for (const key of keys){
|
|
12
|
+
if (!owner || 'object' != typeof owner && 'function' != typeof owner) return;
|
|
13
|
+
owner = Reflect.get(owner, key);
|
|
14
|
+
}
|
|
15
|
+
if (!owner || !method || 'object' != typeof owner && 'function' != typeof owner) return;
|
|
16
|
+
const fn = Reflect.get(owner, method);
|
|
17
|
+
if ('function' == typeof fn) Reflect.apply(fn, owner, args);
|
|
18
|
+
};
|
|
19
|
+
const permitted = ()=>{
|
|
20
|
+
const snapshot = options.getSnapshot();
|
|
21
|
+
if (!getEffectiveGateState(snapshot).effectivePermissions.measurement) return [];
|
|
22
|
+
return options.scripts.filter((script)=>evaluateConsent(script, snapshot));
|
|
23
|
+
};
|
|
24
|
+
return {
|
|
25
|
+
pageview (path) {
|
|
26
|
+
const [next] = path.split('#');
|
|
27
|
+
const changed = void 0 !== previousPath && previousPath !== next;
|
|
28
|
+
previousPath = next;
|
|
29
|
+
if (!changed) return;
|
|
30
|
+
const sent = new Set();
|
|
31
|
+
for (const script of permitted()){
|
|
32
|
+
const vendor = script.vendor ?? script.id;
|
|
33
|
+
if (!(!vendor || sent.has(vendor)) && options.pageviews?.includes(vendor)) {
|
|
34
|
+
sent.add(vendor);
|
|
35
|
+
try {
|
|
36
|
+
if ('posthog' === vendor) call('posthog.capture', [
|
|
37
|
+
'$pageview'
|
|
38
|
+
]);
|
|
39
|
+
if ('segment' === vendor) call('analytics.page', []);
|
|
40
|
+
if ('hightouch' === vendor) call('htevents.page', []);
|
|
41
|
+
} catch {}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
track (event, properties = {}) {
|
|
46
|
+
const sent = new Set();
|
|
47
|
+
for (const script of permitted()){
|
|
48
|
+
const vendor = script.vendor ?? script.id;
|
|
49
|
+
if (!vendor || sent.has(vendor)) continue;
|
|
50
|
+
sent.add(vendor);
|
|
51
|
+
const props = {
|
|
52
|
+
...properties
|
|
53
|
+
};
|
|
54
|
+
try {
|
|
55
|
+
switch(vendor){
|
|
56
|
+
case 'google-tag-manager':
|
|
57
|
+
call([
|
|
58
|
+
script.attributes?.['data-c15t-layer'] ?? 'dataLayer',
|
|
59
|
+
'push'
|
|
60
|
+
], [
|
|
61
|
+
{
|
|
62
|
+
...props,
|
|
63
|
+
event
|
|
64
|
+
}
|
|
65
|
+
]);
|
|
66
|
+
break;
|
|
67
|
+
case 'gtag':
|
|
68
|
+
call('gtag', [
|
|
69
|
+
'event',
|
|
70
|
+
event,
|
|
71
|
+
props
|
|
72
|
+
]);
|
|
73
|
+
break;
|
|
74
|
+
case 'posthog':
|
|
75
|
+
call('posthog.capture', [
|
|
76
|
+
event,
|
|
77
|
+
props
|
|
78
|
+
]);
|
|
79
|
+
break;
|
|
80
|
+
case 'mixpanel':
|
|
81
|
+
case 'mixpanel-analytics':
|
|
82
|
+
call('mixpanel.track', [
|
|
83
|
+
event,
|
|
84
|
+
props
|
|
85
|
+
]);
|
|
86
|
+
break;
|
|
87
|
+
case 'segment':
|
|
88
|
+
call('analytics.track', [
|
|
89
|
+
event,
|
|
90
|
+
props
|
|
91
|
+
]);
|
|
92
|
+
break;
|
|
93
|
+
case 'hightouch':
|
|
94
|
+
call('htevents.track', [
|
|
95
|
+
event,
|
|
96
|
+
props
|
|
97
|
+
]);
|
|
98
|
+
break;
|
|
99
|
+
case 'heap':
|
|
100
|
+
call('heap.track', [
|
|
101
|
+
event,
|
|
102
|
+
props
|
|
103
|
+
]);
|
|
104
|
+
break;
|
|
105
|
+
case 'amplitude':
|
|
106
|
+
call('amplitude.track', [
|
|
107
|
+
event,
|
|
108
|
+
props
|
|
109
|
+
]);
|
|
110
|
+
break;
|
|
111
|
+
case 'logrocket':
|
|
112
|
+
call('LogRocket.track', [
|
|
113
|
+
event,
|
|
114
|
+
props
|
|
115
|
+
]);
|
|
116
|
+
break;
|
|
117
|
+
case 'adobe-analytics':
|
|
118
|
+
call('_satellite.track', [
|
|
119
|
+
event,
|
|
120
|
+
props
|
|
121
|
+
]);
|
|
122
|
+
break;
|
|
123
|
+
case 'databuddy':
|
|
124
|
+
call('databuddy.track', [
|
|
125
|
+
event,
|
|
126
|
+
props
|
|
127
|
+
]);
|
|
128
|
+
break;
|
|
129
|
+
case 'plausible-analytics':
|
|
130
|
+
call('plausible', [
|
|
131
|
+
event,
|
|
132
|
+
{
|
|
133
|
+
props
|
|
134
|
+
}
|
|
135
|
+
]);
|
|
136
|
+
break;
|
|
137
|
+
case 'fathom-analytics':
|
|
138
|
+
call('fathom.trackEvent', [
|
|
139
|
+
event
|
|
140
|
+
]);
|
|
141
|
+
break;
|
|
142
|
+
case 'pirsch':
|
|
143
|
+
call('pirsch', [
|
|
144
|
+
event,
|
|
145
|
+
{
|
|
146
|
+
meta: props
|
|
147
|
+
}
|
|
148
|
+
]);
|
|
149
|
+
break;
|
|
150
|
+
case 'microsoft-clarity':
|
|
151
|
+
call('clarity', [
|
|
152
|
+
'event',
|
|
153
|
+
event
|
|
154
|
+
]);
|
|
155
|
+
break;
|
|
156
|
+
case 'hotjar':
|
|
157
|
+
call('hj', [
|
|
158
|
+
'event',
|
|
159
|
+
event
|
|
160
|
+
]);
|
|
161
|
+
break;
|
|
162
|
+
case 'vercel-analytics':
|
|
163
|
+
call('va', [
|
|
164
|
+
'event',
|
|
165
|
+
{
|
|
166
|
+
data: props,
|
|
167
|
+
name: event
|
|
168
|
+
}
|
|
169
|
+
]);
|
|
170
|
+
break;
|
|
171
|
+
case 'one-dollar-stats':
|
|
172
|
+
call('stonks.event', [
|
|
173
|
+
event,
|
|
174
|
+
Object.fromEntries(Object.entries(props).map(([key, value])=>[
|
|
175
|
+
key,
|
|
176
|
+
String(value)
|
|
177
|
+
]))
|
|
178
|
+
]);
|
|
179
|
+
break;
|
|
180
|
+
case 'umami':
|
|
181
|
+
case 'umami-analytics':
|
|
182
|
+
call('umami.track', [
|
|
183
|
+
event,
|
|
184
|
+
props
|
|
185
|
+
]);
|
|
186
|
+
break;
|
|
187
|
+
case 'rybbit':
|
|
188
|
+
case 'rybbit-analytics':
|
|
189
|
+
call('rybbit.event', [
|
|
190
|
+
event,
|
|
191
|
+
props
|
|
192
|
+
]);
|
|
193
|
+
break;
|
|
194
|
+
case 'rudderstack':
|
|
195
|
+
call('rudderanalytics.track', [
|
|
196
|
+
event,
|
|
197
|
+
props
|
|
198
|
+
]);
|
|
199
|
+
break;
|
|
200
|
+
case 'matomo':
|
|
201
|
+
case 'matomo-analytics':
|
|
202
|
+
call('_paq.push', [
|
|
203
|
+
[
|
|
204
|
+
'trackEvent',
|
|
205
|
+
'custom',
|
|
206
|
+
event
|
|
207
|
+
]
|
|
208
|
+
]);
|
|
209
|
+
break;
|
|
210
|
+
default:
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
} catch {}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
};
|
|
218
|
+
export { createEventDispatcher };
|
package/dist/registry.js
CHANGED
|
@@ -147,6 +147,16 @@ const builtInScriptIntegrations = [
|
|
|
147
147
|
packageSubpath: 'mixpanel-analytics',
|
|
148
148
|
vendor: 'mixpanel-analytics'
|
|
149
149
|
},
|
|
150
|
+
{
|
|
151
|
+
consentCategory: 'measurement',
|
|
152
|
+
docsSlug: 'one-dollar-stats',
|
|
153
|
+
hint: 'Website analytics with no API key',
|
|
154
|
+
integrationCategory: 'analytics',
|
|
155
|
+
key: 'oneDollarStats',
|
|
156
|
+
label: 'OneDollarStats',
|
|
157
|
+
packageSubpath: 'one-dollar-stats',
|
|
158
|
+
vendor: 'one-dollar-stats'
|
|
159
|
+
},
|
|
150
160
|
{
|
|
151
161
|
consentCategory: 'measurement',
|
|
152
162
|
docsSlug: 'hotjar',
|
|
@@ -287,6 +297,16 @@ const builtInScriptIntegrations = [
|
|
|
287
297
|
packageSubpath: 'crisp',
|
|
288
298
|
vendor: 'crisp'
|
|
289
299
|
},
|
|
300
|
+
{
|
|
301
|
+
consentCategory: 'functionality',
|
|
302
|
+
docsSlug: 'front-chat',
|
|
303
|
+
hint: 'Live chat widget',
|
|
304
|
+
integrationCategory: 'functional',
|
|
305
|
+
key: 'frontChat',
|
|
306
|
+
label: 'Front Chat',
|
|
307
|
+
packageSubpath: 'front-chat',
|
|
308
|
+
vendor: 'front-chat'
|
|
309
|
+
},
|
|
290
310
|
{
|
|
291
311
|
consentCategory: 'functionality',
|
|
292
312
|
docsSlug: 'intercom',
|
|
@@ -317,6 +337,16 @@ const builtInScriptIntegrations = [
|
|
|
317
337
|
packageSubpath: 'openai-pixel',
|
|
318
338
|
vendor: 'openai-pixel'
|
|
319
339
|
},
|
|
340
|
+
{
|
|
341
|
+
consentCategory: 'marketing',
|
|
342
|
+
docsSlug: 'pinterest-tag',
|
|
343
|
+
hint: 'Pinterest ads tracking',
|
|
344
|
+
integrationCategory: 'ads-and-pixels',
|
|
345
|
+
key: 'pinterestTag',
|
|
346
|
+
label: 'Pinterest Tag',
|
|
347
|
+
packageSubpath: 'pinterest-tag',
|
|
348
|
+
vendor: 'pinterest-tag'
|
|
349
|
+
},
|
|
320
350
|
{
|
|
321
351
|
consentCategory: 'marketing',
|
|
322
352
|
docsSlug: 'reddit-pixel',
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { resolveManifest } from "../../resolve.js";
|
|
2
|
+
import { vendorManifestContract } from "../../types.js";
|
|
3
|
+
import { resolveScriptUrl } from "../_shared/script-url.js";
|
|
4
|
+
const pinterestTagManifest = {
|
|
5
|
+
...vendorManifestContract,
|
|
6
|
+
bootstrap: [
|
|
7
|
+
{
|
|
8
|
+
ifUndefined: true,
|
|
9
|
+
name: 'pintrk',
|
|
10
|
+
properties: {
|
|
11
|
+
version: '3.0'
|
|
12
|
+
},
|
|
13
|
+
queue: {
|
|
14
|
+
property: 'queue'
|
|
15
|
+
},
|
|
16
|
+
queueFormat: 'array',
|
|
17
|
+
type: 'defineStubFunction'
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
category: 'marketing',
|
|
21
|
+
install: [
|
|
22
|
+
{
|
|
23
|
+
args: [
|
|
24
|
+
'load',
|
|
25
|
+
'{{tagId}}'
|
|
26
|
+
],
|
|
27
|
+
global: 'pintrk',
|
|
28
|
+
type: 'callGlobal'
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
args: [
|
|
32
|
+
'setconsent',
|
|
33
|
+
true
|
|
34
|
+
],
|
|
35
|
+
global: 'pintrk',
|
|
36
|
+
type: 'callGlobal'
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
args: [
|
|
40
|
+
'page'
|
|
41
|
+
],
|
|
42
|
+
global: 'pintrk',
|
|
43
|
+
type: 'callGlobal'
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
async: true,
|
|
47
|
+
src: "{{scriptUrl}}",
|
|
48
|
+
type: 'loadScript'
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
onConsentDenied: [
|
|
52
|
+
{
|
|
53
|
+
args: [
|
|
54
|
+
'setconsent',
|
|
55
|
+
false
|
|
56
|
+
],
|
|
57
|
+
global: 'pintrk',
|
|
58
|
+
type: 'callGlobal'
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
onConsentGranted: [
|
|
62
|
+
{
|
|
63
|
+
args: [
|
|
64
|
+
'setconsent',
|
|
65
|
+
true
|
|
66
|
+
],
|
|
67
|
+
global: 'pintrk',
|
|
68
|
+
type: 'callGlobal'
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
persistAfterConsentRevoked: true,
|
|
72
|
+
vendor: 'pinterest-tag'
|
|
73
|
+
};
|
|
74
|
+
const pinterest_tag_pinterestTag = function({ tagId, loadOptions, trackPageVisit = true, scriptUrl }) {
|
|
75
|
+
const loadArgs = [
|
|
76
|
+
'load',
|
|
77
|
+
'{{tagId}}'
|
|
78
|
+
];
|
|
79
|
+
if (void 0 !== loadOptions) loadArgs.push('{{loadOptions}}');
|
|
80
|
+
const install = [
|
|
81
|
+
{
|
|
82
|
+
args: loadArgs,
|
|
83
|
+
global: 'pintrk',
|
|
84
|
+
type: 'callGlobal'
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
args: [
|
|
88
|
+
'setconsent',
|
|
89
|
+
true
|
|
90
|
+
],
|
|
91
|
+
global: 'pintrk',
|
|
92
|
+
type: 'callGlobal'
|
|
93
|
+
}
|
|
94
|
+
];
|
|
95
|
+
if (trackPageVisit) install.push({
|
|
96
|
+
args: [
|
|
97
|
+
'page'
|
|
98
|
+
],
|
|
99
|
+
global: 'pintrk',
|
|
100
|
+
type: 'callGlobal'
|
|
101
|
+
});
|
|
102
|
+
install.push({
|
|
103
|
+
async: true,
|
|
104
|
+
src: "{{scriptUrl}}",
|
|
105
|
+
type: 'loadScript'
|
|
106
|
+
});
|
|
107
|
+
const manifest = {
|
|
108
|
+
...pinterestTagManifest,
|
|
109
|
+
install
|
|
110
|
+
};
|
|
111
|
+
return resolveManifest(manifest, {
|
|
112
|
+
loadOptions,
|
|
113
|
+
scriptUrl: resolveScriptUrl(scriptUrl, 'https://s.pinimg.com/ct/core.js'),
|
|
114
|
+
tagId
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
const pinterestTagEvent = (eventName, eventData, callback)=>{
|
|
118
|
+
if ("u" < typeof window || 'function' != typeof window.pintrk) return;
|
|
119
|
+
if (void 0 !== callback) return void window.pintrk('track', eventName, eventData ?? {}, callback);
|
|
120
|
+
if (void 0 === eventData) return void window.pintrk('track', eventName);
|
|
121
|
+
window.pintrk('track', eventName, eventData);
|
|
122
|
+
};
|
|
123
|
+
export { pinterestTagEvent, pinterestTagManifest, pinterest_tag_pinterestTag as pinterestTag };
|
|
@@ -47,10 +47,22 @@ const gtagManifest = {
|
|
|
47
47
|
persistAfterConsentRevoked: true,
|
|
48
48
|
vendor: 'gtag'
|
|
49
49
|
};
|
|
50
|
-
const google_tag_gtag = function({ id, category, consentMapping, script }) {
|
|
51
|
-
const
|
|
50
|
+
const google_tag_gtag = function({ id, config, category, consentMapping, script }) {
|
|
51
|
+
const base = void 0 === config ? gtagManifest : {
|
|
52
|
+
...gtagManifest,
|
|
53
|
+
install: gtagManifest.install.map((step)=>'callGlobal' === step.type && 'config' === step.args[0] ? {
|
|
54
|
+
...step,
|
|
55
|
+
args: [
|
|
56
|
+
'config',
|
|
57
|
+
'{{id}}',
|
|
58
|
+
'{{config}}'
|
|
59
|
+
]
|
|
60
|
+
} : step)
|
|
61
|
+
};
|
|
62
|
+
const manifest = withOptionalConsentMapping(base, consentMapping);
|
|
52
63
|
const resolved = resolveManifest(manifest, {
|
|
53
64
|
category,
|
|
65
|
+
config,
|
|
54
66
|
id
|
|
55
67
|
});
|
|
56
68
|
if (!script) return resolved;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { resolveManifest } from "../../resolve.js";
|
|
2
|
+
import { vendorManifestContract } from "../../types.js";
|
|
3
|
+
const ONE_DOLLAR_STATS_SCRIPT_SRC = 'https://assets.onedollarstats.com/stonks.js';
|
|
4
|
+
const oneDollarStatsManifest = {
|
|
5
|
+
...vendorManifestContract,
|
|
6
|
+
category: 'measurement',
|
|
7
|
+
install: [
|
|
8
|
+
{
|
|
9
|
+
defer: true,
|
|
10
|
+
src: ONE_DOLLAR_STATS_SCRIPT_SRC,
|
|
11
|
+
type: 'loadScript'
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
vendor: 'one-dollar-stats'
|
|
15
|
+
};
|
|
16
|
+
const SETTING_NAME = /^[a-z][a-z0-9-]*$/u;
|
|
17
|
+
const one_dollar_stats_oneDollarStats = function(options = {}) {
|
|
18
|
+
if (void 0 !== options.hostname && ('string' != typeof options.hostname || !/^[\p{L}\p{N}-]+(?:\.[\p{L}\p{N}-]+)*(?::\d+)?$/u.test(options.hostname))) throw new Error('oneDollarStats: hostname must be a bare host name like docs.example.com, without a scheme, path, query, or fragment');
|
|
19
|
+
const attributes = {};
|
|
20
|
+
for (const [setting, value] of Object.entries(options))if (void 0 !== value) {
|
|
21
|
+
if (!SETTING_NAME.test(setting)) throw new Error(`oneDollarStats: ${setting} is not a valid setting name; use lowercase letters, digits and hyphens`);
|
|
22
|
+
if ('string' != typeof value) throw new Error(`oneDollarStats: ${setting} must be a string`);
|
|
23
|
+
if ('hash-routing' !== setting || 'false' !== value) attributes[`data-${setting}`] = value;
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
...resolveManifest(oneDollarStatsManifest),
|
|
27
|
+
attributes
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export { ONE_DOLLAR_STATS_SCRIPT_SRC, oneDollarStatsManifest, one_dollar_stats_oneDollarStats as oneDollarStats };
|
|
@@ -25,6 +25,14 @@ const segmentManifest = {
|
|
|
25
25
|
],
|
|
26
26
|
category: 'measurement',
|
|
27
27
|
install: [
|
|
28
|
+
{
|
|
29
|
+
path: [
|
|
30
|
+
'analytics',
|
|
31
|
+
'_loadOptions'
|
|
32
|
+
],
|
|
33
|
+
type: 'setGlobalPath',
|
|
34
|
+
value: '{{loadOptions}}'
|
|
35
|
+
},
|
|
28
36
|
{
|
|
29
37
|
global: 'analytics',
|
|
30
38
|
method: 'page',
|
|
@@ -38,7 +46,7 @@ const segmentManifest = {
|
|
|
38
46
|
],
|
|
39
47
|
vendor: 'segment'
|
|
40
48
|
};
|
|
41
|
-
const segment_segment = function({ writeKey, trackPageView = true, scriptUrl }) {
|
|
49
|
+
const segment_segment = function({ writeKey, loadOptions = {}, trackPageView = true, scriptUrl }) {
|
|
42
50
|
let normalizedWriteKey = '';
|
|
43
51
|
if ('string' == typeof writeKey) normalizedWriteKey = writeKey.trim();
|
|
44
52
|
if (0 === normalizedWriteKey.length) throw new Error('segment: missing or invalid writeKey');
|
|
@@ -50,6 +58,7 @@ const segment_segment = function({ writeKey, trackPageView = true, scriptUrl })
|
|
|
50
58
|
install: segmentManifest.install.filter((step)=>!('callGlobal' === step.type && 'analytics' === step.global && 'page' === step.method))
|
|
51
59
|
};
|
|
52
60
|
return resolveManifest(manifest, {
|
|
61
|
+
loadOptions,
|
|
53
62
|
scriptUrl: resolveScriptUrl(scriptUrl, defaultScriptUrl)
|
|
54
63
|
});
|
|
55
64
|
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { resolveManifest } from "../../resolve.js";
|
|
2
|
+
import { vendorManifestContract } from "../../types.js";
|
|
3
|
+
import { resolveScriptUrl, trimToUndefined } from "../_shared/script-url.js";
|
|
4
|
+
const FRONT_CHAT_SCRIPT_SRC = 'https://chat-assets.frontapp.com/v1/chat.bundle.js';
|
|
5
|
+
const frontChatManifest = {
|
|
6
|
+
...vendorManifestContract,
|
|
7
|
+
category: 'functionality',
|
|
8
|
+
install: [
|
|
9
|
+
{
|
|
10
|
+
async: true,
|
|
11
|
+
src: "{{scriptSrc}}",
|
|
12
|
+
type: 'loadScript'
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
onLoadGranted: [
|
|
16
|
+
{
|
|
17
|
+
args: [
|
|
18
|
+
'init',
|
|
19
|
+
'{{initOptions}}'
|
|
20
|
+
],
|
|
21
|
+
global: 'FrontChat',
|
|
22
|
+
type: 'callGlobal'
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
vendor: 'front-chat'
|
|
26
|
+
};
|
|
27
|
+
const front_chat_frontChat = function(options) {
|
|
28
|
+
const chatId = 'string' == typeof options?.chatId ? options.chatId.trim() : '';
|
|
29
|
+
if (!chatId) throw new Error('frontChat: chatId must be a non-empty string.');
|
|
30
|
+
const scriptSrc = resolveScriptUrl(trimToUndefined(options.scriptSrc), FRONT_CHAT_SCRIPT_SRC);
|
|
31
|
+
const nonce = trimToUndefined(options.nonce);
|
|
32
|
+
const initOptions = {
|
|
33
|
+
chatId,
|
|
34
|
+
useDefaultLauncher: options.useDefaultLauncher ?? true
|
|
35
|
+
};
|
|
36
|
+
if (nonce) initOptions.nonce = nonce;
|
|
37
|
+
const script = resolveManifest(frontChatManifest, {
|
|
38
|
+
initOptions,
|
|
39
|
+
scriptSrc
|
|
40
|
+
});
|
|
41
|
+
return {
|
|
42
|
+
...script,
|
|
43
|
+
nonce,
|
|
44
|
+
onLoad (info) {
|
|
45
|
+
if (!info.hasConsent || !info.element?.isConnected) return;
|
|
46
|
+
const loadedNonce = info.element.nonce;
|
|
47
|
+
const resolved = loadedNonce ? resolveManifest(frontChatManifest, {
|
|
48
|
+
initOptions: {
|
|
49
|
+
...initOptions,
|
|
50
|
+
nonce: loadedNonce
|
|
51
|
+
},
|
|
52
|
+
scriptSrc
|
|
53
|
+
}) : script;
|
|
54
|
+
resolved.onLoad?.(info);
|
|
55
|
+
},
|
|
56
|
+
target: 'body'
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
const front_chat_shutdownFrontChat = function() {
|
|
60
|
+
if ("u" > typeof window && 'function' == typeof window.FrontChat) window.FrontChat('shutdown', {
|
|
61
|
+
clearSession: true
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
export { frontChatManifest, front_chat_frontChat as frontChat, front_chat_shutdownFrontChat as shutdownFrontChat };
|
|
@@ -48,12 +48,26 @@ const googleTagManagerManifest = {
|
|
|
48
48
|
],
|
|
49
49
|
vendor: 'google-tag-manager'
|
|
50
50
|
};
|
|
51
|
-
const google_tag_manager_googleTagManager = function({ id, updateEventName, consentMapping }) {
|
|
52
|
-
|
|
51
|
+
const google_tag_manager_googleTagManager = function({ id, dataLayer = 'dataLayer', updateEventName, consentMapping }) {
|
|
52
|
+
let manifest = withOptionalConsentMapping(googleTagManagerManifest, consentMapping);
|
|
53
|
+
if ('dataLayer' !== dataLayer) {
|
|
54
|
+
manifest = JSON.parse(JSON.stringify(manifest).replace(/"(?:dataLayer|gtag)"/gu, (token)=>JSON.stringify('"dataLayer"' === token ? dataLayer : `${dataLayer}Gtag`)).replace('gtm.js?id={{id}}', `gtm.js?id={{id}}&l=${encodeURIComponent(dataLayer)}`));
|
|
55
|
+
manifest = {
|
|
56
|
+
...manifest,
|
|
57
|
+
consentSignal: 'gtag',
|
|
58
|
+
consentSignalTarget: `${dataLayer}Gtag`
|
|
59
|
+
};
|
|
60
|
+
}
|
|
53
61
|
const resolved = resolveManifest(manifest, {
|
|
54
62
|
id,
|
|
55
63
|
updateEventName: updateEventName ?? 'consent-update'
|
|
56
64
|
});
|
|
57
|
-
return
|
|
65
|
+
return {
|
|
66
|
+
...resolved,
|
|
67
|
+
attributes: {
|
|
68
|
+
...resolved.attributes,
|
|
69
|
+
'data-c15t-layer': dataLayer
|
|
70
|
+
}
|
|
71
|
+
};
|
|
58
72
|
};
|
|
59
73
|
export { googleTagManagerManifest, google_tag_manager_googleTagManager as googleTagManager };
|