@el7ven/cookie-kit 0.2.19 → 0.2.21
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/package.json +4 -2
- package/src/core/analytics.js +220 -0
- package/src/core/index.js +112 -5
- package/src/index.js +8 -0
- package/src/vue/CookieConsent.vue +165 -62
- package/src/vue/CookieConsentDebug.vue +168 -0
- package/src/vue/CookieDrawer.vue +274 -104
- package/src/vue/index.js +6 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@el7ven/cookie-kit",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.21",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"module": "./src/index.js",
|
|
@@ -11,8 +11,10 @@
|
|
|
11
11
|
"./dist/styles": "./dist/styles/index.css",
|
|
12
12
|
"./react": "./src/react/index.js",
|
|
13
13
|
"./vue": "./src/vue/index.js",
|
|
14
|
-
"./
|
|
14
|
+
"./analytics": "./src/core/analytics.js",
|
|
15
|
+
"./config": "./src/core/index.js",
|
|
15
16
|
"./composables/useCookieConsent": "./src/vue/composables/useCookieConsent.js",
|
|
17
|
+
"./src/composables/useCookieConsent": "./src/vue/composables/useCookieConsent.js",
|
|
16
18
|
"./package.json": "./package.json"
|
|
17
19
|
},
|
|
18
20
|
"files": [
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @el7ven/cookie-kit - Analytics Integration Module
|
|
3
|
+
* Google Consent Mode v2, GTM, GA4, Meta Pixel, Yandex Metrica
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Initialize Google Consent Mode v2 with default denied state
|
|
8
|
+
*/
|
|
9
|
+
export function initGoogleConsentMode() {
|
|
10
|
+
if (typeof window === 'undefined') return
|
|
11
|
+
|
|
12
|
+
window.dataLayer = window.dataLayer || []
|
|
13
|
+
window.gtag = window.gtag || function gtag() { window.dataLayer.push(arguments) }
|
|
14
|
+
|
|
15
|
+
// Set default consent state - all denied until user consents
|
|
16
|
+
window.gtag('consent', 'default', {
|
|
17
|
+
ad_storage: 'denied',
|
|
18
|
+
ad_user_data: 'denied',
|
|
19
|
+
ad_personalization: 'denied',
|
|
20
|
+
analytics_storage: 'denied',
|
|
21
|
+
functionality_storage: 'denied',
|
|
22
|
+
personalization_storage: 'denied',
|
|
23
|
+
security_storage: 'granted' // Always granted for security
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Update Google Consent Mode based on cookie consent categories
|
|
29
|
+
* @param {Object} categories - { analytics: true, marketing: false, preferences: true }
|
|
30
|
+
*/
|
|
31
|
+
export function updateGoogleConsent(categories = {}) {
|
|
32
|
+
if (typeof window === 'undefined' || !window.gtag) return
|
|
33
|
+
|
|
34
|
+
const consentUpdate = {
|
|
35
|
+
analytics_storage: categories.analytics ? 'granted' : 'denied',
|
|
36
|
+
ad_storage: categories.marketing ? 'granted' : 'denied',
|
|
37
|
+
ad_user_data: categories.marketing ? 'granted' : 'denied',
|
|
38
|
+
ad_personalization: categories.marketing ? 'granted' : 'denied',
|
|
39
|
+
functionality_storage: categories.preferences ? 'granted' : 'denied',
|
|
40
|
+
personalization_storage: categories.preferences ? 'granted' : 'denied',
|
|
41
|
+
security_storage: 'granted'
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
window.gtag('consent', 'update', consentUpdate)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Load Google Tag Manager
|
|
49
|
+
* @param {string} gtmId - GTM container ID (e.g., 'GTM-XXXXX')
|
|
50
|
+
*/
|
|
51
|
+
export function loadGTM(gtmId) {
|
|
52
|
+
if (!gtmId || typeof document === 'undefined') return
|
|
53
|
+
|
|
54
|
+
const script = document.createElement('script')
|
|
55
|
+
script.async = true
|
|
56
|
+
script.src = `https://www.googletagmanager.com/gtm.js?id=${gtmId}`
|
|
57
|
+
document.head.appendChild(script)
|
|
58
|
+
|
|
59
|
+
window.dataLayer = window.dataLayer || []
|
|
60
|
+
window.dataLayer.push({
|
|
61
|
+
'gtm.start': new Date().getTime(),
|
|
62
|
+
event: 'gtm.js'
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Load Google Analytics 4
|
|
68
|
+
* @param {string} ga4Id - GA4 measurement ID (e.g., 'G-XXXXX')
|
|
69
|
+
*/
|
|
70
|
+
export function loadGA4(ga4Id) {
|
|
71
|
+
if (!ga4Id || typeof document === 'undefined') return
|
|
72
|
+
|
|
73
|
+
const script = document.createElement('script')
|
|
74
|
+
script.async = true
|
|
75
|
+
script.src = `https://www.googletagmanager.com/gtag/js?id=${ga4Id}`
|
|
76
|
+
document.head.appendChild(script)
|
|
77
|
+
|
|
78
|
+
window.dataLayer = window.dataLayer || []
|
|
79
|
+
window.gtag = window.gtag || function gtag() { window.dataLayer.push(arguments) }
|
|
80
|
+
window.gtag('js', new Date())
|
|
81
|
+
window.gtag('config', ga4Id)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Load Meta (Facebook) Pixel
|
|
86
|
+
* @param {string} pixelId - Meta Pixel ID
|
|
87
|
+
*/
|
|
88
|
+
export function loadMetaPixel(pixelId) {
|
|
89
|
+
if (!pixelId || typeof window === 'undefined') return
|
|
90
|
+
|
|
91
|
+
/* eslint-disable */
|
|
92
|
+
!function(f,b,e,v,n,t,s)
|
|
93
|
+
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
|
|
94
|
+
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
|
|
95
|
+
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
|
|
96
|
+
n.queue=[];t=b.createElement(e);t.async=!0;
|
|
97
|
+
t.src=v;s=b.getElementsByTagName(e)[0];
|
|
98
|
+
s.parentNode.insertBefore(t,s)}(window, document,'script',
|
|
99
|
+
'https://connect.facebook.net/en_US/fbevents.js');
|
|
100
|
+
/* eslint-enable */
|
|
101
|
+
|
|
102
|
+
window.fbq('init', pixelId)
|
|
103
|
+
window.fbq('track', 'PageView')
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Load Yandex Metrica
|
|
108
|
+
* @param {string} counterId - Yandex Metrica counter ID
|
|
109
|
+
*/
|
|
110
|
+
export function loadYandexMetrica(counterId) {
|
|
111
|
+
if (!counterId || typeof document === 'undefined') return
|
|
112
|
+
|
|
113
|
+
/* eslint-disable */
|
|
114
|
+
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
|
115
|
+
m[i].l=1*new Date();
|
|
116
|
+
for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
|
|
117
|
+
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
|
118
|
+
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
|
119
|
+
/* eslint-enable */
|
|
120
|
+
|
|
121
|
+
window.ym(counterId, 'init', {
|
|
122
|
+
clickmap: true,
|
|
123
|
+
trackLinks: true,
|
|
124
|
+
accurateTrackBounce: true,
|
|
125
|
+
webvisor: true
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Block/unblock scripts based on consent categories
|
|
131
|
+
* Scripts with data-cookie-category attribute will be managed
|
|
132
|
+
* @param {Object} categories - { analytics: true, marketing: false }
|
|
133
|
+
*/
|
|
134
|
+
export function manageScriptBlocking(categories = {}) {
|
|
135
|
+
if (typeof document === 'undefined') return
|
|
136
|
+
|
|
137
|
+
document.querySelectorAll('script[data-cookie-category]').forEach(script => {
|
|
138
|
+
const category = script.getAttribute('data-cookie-category')
|
|
139
|
+
if (categories[category]) {
|
|
140
|
+
// Re-enable script
|
|
141
|
+
if (script.type === 'text/plain' && script.dataset.originalSrc) {
|
|
142
|
+
const newScript = document.createElement('script')
|
|
143
|
+
newScript.src = script.dataset.originalSrc
|
|
144
|
+
newScript.async = true
|
|
145
|
+
script.parentNode.replaceChild(newScript, script)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
})
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Create analytics manager that auto-integrates with cookie consent
|
|
153
|
+
* @param {Object} config - { ga4: 'G-XXX', gtm: 'GTM-XXX', metaPixel: 'XXX', yandexMetrica: 'XXX' }
|
|
154
|
+
* @returns {Object} Analytics manager instance
|
|
155
|
+
*/
|
|
156
|
+
export function createAnalyticsManager(config = {}) {
|
|
157
|
+
let initialized = false
|
|
158
|
+
|
|
159
|
+
const init = () => {
|
|
160
|
+
if (initialized) return
|
|
161
|
+
initialized = true
|
|
162
|
+
|
|
163
|
+
// Always init Google Consent Mode first (denied by default)
|
|
164
|
+
initGoogleConsentMode()
|
|
165
|
+
|
|
166
|
+
// Load GTM if configured (it respects consent mode)
|
|
167
|
+
if (config.gtm) loadGTM(config.gtm)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const onConsentUpdate = (categories = {}) => {
|
|
171
|
+
// Update Google Consent Mode
|
|
172
|
+
updateGoogleConsent(categories)
|
|
173
|
+
|
|
174
|
+
// Load analytics scripts based on consent
|
|
175
|
+
if (categories.analytics) {
|
|
176
|
+
if (config.ga4) loadGA4(config.ga4)
|
|
177
|
+
if (config.yandexMetrica) loadYandexMetrica(config.yandexMetrica)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (categories.marketing) {
|
|
181
|
+
if (config.metaPixel) loadMetaPixel(config.metaPixel)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Manage script blocking
|
|
185
|
+
manageScriptBlocking(categories)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const connectToCookieConsent = () => {
|
|
189
|
+
if (typeof window === 'undefined') return
|
|
190
|
+
|
|
191
|
+
// Wait for CookieConsent to be available
|
|
192
|
+
const checkInterval = setInterval(() => {
|
|
193
|
+
if (window.CookieConsent) {
|
|
194
|
+
clearInterval(checkInterval)
|
|
195
|
+
|
|
196
|
+
// Check if consent already given
|
|
197
|
+
const currentConsent = window.CookieConsent.getConsent()
|
|
198
|
+
if (currentConsent?.categories) {
|
|
199
|
+
onConsentUpdate(currentConsent.categories)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Listen for future changes
|
|
203
|
+
window.CookieConsent.on('consentChanged', ({ consent }) => {
|
|
204
|
+
if (consent?.categories) {
|
|
205
|
+
onConsentUpdate(consent.categories)
|
|
206
|
+
}
|
|
207
|
+
})
|
|
208
|
+
}
|
|
209
|
+
}, 100)
|
|
210
|
+
|
|
211
|
+
// Stop checking after 10 seconds
|
|
212
|
+
setTimeout(() => clearInterval(checkInterval), 10000)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return {
|
|
216
|
+
init,
|
|
217
|
+
onConsentUpdate,
|
|
218
|
+
connectToCookieConsent
|
|
219
|
+
}
|
|
220
|
+
}
|
package/src/core/index.js
CHANGED
|
@@ -1,13 +1,120 @@
|
|
|
1
1
|
import { VERSION, getVersion, getVersionInfo, logVersion } from './version.js'
|
|
2
2
|
|
|
3
3
|
const DEFAULT_CONFIG = {
|
|
4
|
-
|
|
4
|
+
// Version and revision for consent invalidation
|
|
5
|
+
version: 'v2',
|
|
6
|
+
revision: 0,
|
|
7
|
+
|
|
8
|
+
// GDPR compliance
|
|
5
9
|
consentExpireDays: 365,
|
|
10
|
+
auditLog: false,
|
|
11
|
+
|
|
12
|
+
// Storage
|
|
13
|
+
storageKey: 'cookie_consent',
|
|
14
|
+
storageType: 'localStorage', // 'localStorage' | 'cookie' | 'both'
|
|
15
|
+
|
|
16
|
+
// Mode
|
|
17
|
+
mode: 'gdpr', // 'gdpr' | 'essential'
|
|
18
|
+
|
|
19
|
+
// Auto show
|
|
20
|
+
autoShow: true,
|
|
21
|
+
|
|
22
|
+
// Debug
|
|
23
|
+
debug: false,
|
|
24
|
+
|
|
25
|
+
// Region (optional)
|
|
26
|
+
region: null, // 'EU' | 'US' | 'OTHER'
|
|
27
|
+
|
|
28
|
+
// Categories
|
|
6
29
|
categories: {
|
|
7
|
-
necessary: {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
30
|
+
necessary: {
|
|
31
|
+
id: 'necessary',
|
|
32
|
+
label: 'Necesare',
|
|
33
|
+
description: 'Cookie-uri esențiale pentru funcționarea site-ului',
|
|
34
|
+
required: true,
|
|
35
|
+
locked: true,
|
|
36
|
+
enabled: true
|
|
37
|
+
},
|
|
38
|
+
analytics: {
|
|
39
|
+
id: 'analytics',
|
|
40
|
+
label: 'Analiză',
|
|
41
|
+
description: 'Cookie-uri pentru analiza traficului și comportamentului utilizatorilor',
|
|
42
|
+
required: false,
|
|
43
|
+
locked: false,
|
|
44
|
+
enabled: true
|
|
45
|
+
},
|
|
46
|
+
marketing: {
|
|
47
|
+
id: 'marketing',
|
|
48
|
+
label: 'Marketing',
|
|
49
|
+
description: 'Cookie-uri pentru publicitate personalizată',
|
|
50
|
+
required: false,
|
|
51
|
+
locked: false,
|
|
52
|
+
enabled: true
|
|
53
|
+
},
|
|
54
|
+
preferences: {
|
|
55
|
+
id: 'preferences',
|
|
56
|
+
label: 'Preferințe',
|
|
57
|
+
description: 'Cookie-uri pentru salvarea preferințelor utilizatorului',
|
|
58
|
+
required: false,
|
|
59
|
+
locked: false,
|
|
60
|
+
enabled: true
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
// Texts
|
|
65
|
+
texts: {
|
|
66
|
+
essential: {
|
|
67
|
+
title: '🍪 Файлы Cookie',
|
|
68
|
+
message: 'Мы используем необходимые файлы cookie для работы сайта. Никакой аналитики и маркетинга.',
|
|
69
|
+
button: 'Принять'
|
|
70
|
+
},
|
|
71
|
+
gdpr: {
|
|
72
|
+
title: 'Preferințe Cookie-uri',
|
|
73
|
+
message: 'Folosim cookie-uri pentru a-ți oferi cea mai bună experiență. Alege ce tipuri de cookie-uri accepți.',
|
|
74
|
+
buttons: {
|
|
75
|
+
acceptAll: 'Acceptă toate',
|
|
76
|
+
rejectAll: 'Respinge toate',
|
|
77
|
+
acceptSelection: 'Acceptă selecția',
|
|
78
|
+
settings: 'Setări'
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
settings: {
|
|
82
|
+
title: 'Setări Cookie-uri',
|
|
83
|
+
tabs: {
|
|
84
|
+
privacy: 'Confidențialitate'
|
|
85
|
+
},
|
|
86
|
+
buttons: {
|
|
87
|
+
acceptAll: 'Acceptă toate',
|
|
88
|
+
rejectAll: 'Respinge toate',
|
|
89
|
+
acceptSelection: 'Salvează selecția'
|
|
90
|
+
},
|
|
91
|
+
links: {
|
|
92
|
+
moreInfo: 'Mai multe informații',
|
|
93
|
+
cookieDetails: 'Detalii cookie-uri'
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
// Policy links
|
|
99
|
+
policies: {
|
|
100
|
+
privacy: '/privacy-policy',
|
|
101
|
+
cookies: '/cookie-policy'
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
// Display options
|
|
105
|
+
display: {
|
|
106
|
+
position: 'bottom-right', // 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'center'
|
|
107
|
+
backdrop: true,
|
|
108
|
+
closeOnBackdrop: true
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
// Analytics providers (optional)
|
|
112
|
+
analytics: null,
|
|
113
|
+
|
|
114
|
+
// Script blocking (optional)
|
|
115
|
+
scriptBlocking: {
|
|
116
|
+
enabled: true,
|
|
117
|
+
strategy: 'data-category' // 'data-category' | 'type-rewrite'
|
|
11
118
|
}
|
|
12
119
|
}
|
|
13
120
|
|
package/src/index.js
CHANGED
|
@@ -8,8 +8,12 @@
|
|
|
8
8
|
// Core functionality
|
|
9
9
|
export { createCookieKit, CookieKitCore, DEFAULT_CONFIG } from './core/index.js'
|
|
10
10
|
|
|
11
|
+
// Analytics integration
|
|
12
|
+
export { createAnalyticsManager, initGoogleConsentMode, updateGoogleConsent, loadGTM, loadGA4, loadMetaPixel, loadYandexMetrica, manageScriptBlocking } from './core/analytics.js'
|
|
13
|
+
|
|
11
14
|
// Import for default export
|
|
12
15
|
import { createCookieKit, CookieKitCore, DEFAULT_CONFIG } from './core/index.js'
|
|
16
|
+
import { createAnalyticsManager } from './core/analytics.js'
|
|
13
17
|
import { initCookieKit } from './js/index.js'
|
|
14
18
|
import { VERSION } from './core/version.js'
|
|
15
19
|
|
|
@@ -22,6 +26,9 @@ export * from './react/index.js'
|
|
|
22
26
|
// Vue components
|
|
23
27
|
export * from './vue/index.js'
|
|
24
28
|
|
|
29
|
+
// Vue composable
|
|
30
|
+
export { useCookieConsent } from './vue/composables/useCookieConsent.js'
|
|
31
|
+
|
|
25
32
|
// Version info
|
|
26
33
|
export { VERSION, getVersion, getVersionInfo, logVersion } from './core/version.js'
|
|
27
34
|
|
|
@@ -59,6 +66,7 @@ export function autoCookieConsent(config = {}) {
|
|
|
59
66
|
export default {
|
|
60
67
|
createCookieKit,
|
|
61
68
|
createCookieConsent,
|
|
69
|
+
createAnalyticsManager,
|
|
62
70
|
autoCookieConsent,
|
|
63
71
|
initCookieKit,
|
|
64
72
|
CookieKitCore,
|