@react-lgpd-consent/core 0.7.0 → 0.7.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/CHANGELOG.md +238 -1
- package/README.md +16 -1
- package/dist/index.cjs +1156 -468
- package/dist/index.d.cts +1346 -1045
- package/dist/index.d.ts +1346 -1045
- package/dist/index.js +1151 -469
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -11,6 +11,219 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
11
11
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
+
// src/types/advancedTexts.ts
|
|
15
|
+
var EXPANDED_DEFAULT_TEXTS = {
|
|
16
|
+
// Textos adicionais
|
|
17
|
+
confirm: "Confirmar",
|
|
18
|
+
cancel: "Cancelar",
|
|
19
|
+
loading: "Carregando...",
|
|
20
|
+
// Feedback
|
|
21
|
+
feedback: {
|
|
22
|
+
saveSuccess: "Prefer\xEAncias salvas com sucesso!",
|
|
23
|
+
saveError: "Erro ao salvar prefer\xEAncias. Tente novamente.",
|
|
24
|
+
consentUpdated: "Consentimento atualizado.",
|
|
25
|
+
cookiesRejected: "Cookies opcionais rejeitados.",
|
|
26
|
+
settingsReset: "Configura\xE7\xF5es resetadas."
|
|
27
|
+
},
|
|
28
|
+
// Acessibilidade
|
|
29
|
+
accessibility: {
|
|
30
|
+
bannerLabel: "Banner de consentimento de cookies",
|
|
31
|
+
modalLabel: "Modal de prefer\xEAncias de cookies",
|
|
32
|
+
keyboardNavigation: "Use Tab para navegar, Enter para selecionar",
|
|
33
|
+
toggleState: {
|
|
34
|
+
enabled: "Habilitado",
|
|
35
|
+
disabled: "Desabilitado"
|
|
36
|
+
},
|
|
37
|
+
liveRegion: "Regi\xE3o de an\xFAncios din\xE2micos"
|
|
38
|
+
},
|
|
39
|
+
// Categorias
|
|
40
|
+
categories: {
|
|
41
|
+
necessary: {
|
|
42
|
+
name: "Cookies Necess\xE1rios",
|
|
43
|
+
description: "Essenciais para o funcionamento b\xE1sico do site",
|
|
44
|
+
examples: "Sess\xE3o, seguran\xE7a, prefer\xEAncias de idioma"
|
|
45
|
+
},
|
|
46
|
+
analytics: {
|
|
47
|
+
name: "Cookies de Analytics",
|
|
48
|
+
description: "Ajudam a entender como os visitantes usam o site",
|
|
49
|
+
examples: "Google Analytics, contadores de p\xE1gina"
|
|
50
|
+
},
|
|
51
|
+
marketing: {
|
|
52
|
+
name: "Cookies de Marketing",
|
|
53
|
+
description: "Usados para personalizar an\xFAncios e ofertas",
|
|
54
|
+
examples: "Facebook Pixel, Google Ads, remarketing"
|
|
55
|
+
},
|
|
56
|
+
functional: {
|
|
57
|
+
name: "Cookies Funcionais",
|
|
58
|
+
description: "Melhoram a funcionalidade e personaliza\xE7\xE3o",
|
|
59
|
+
examples: "Chat, mapas, v\xEDdeos embarcados"
|
|
60
|
+
},
|
|
61
|
+
performance: {
|
|
62
|
+
name: "Cookies de Performance",
|
|
63
|
+
description: "Coletam informa\xE7\xF5es sobre velocidade e estabilidade",
|
|
64
|
+
examples: "Monitoramento de erro, otimiza\xE7\xE3o de velocidade"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
// Contextos específicos
|
|
68
|
+
contexts: {
|
|
69
|
+
ecommerce: {
|
|
70
|
+
cartAbandonment: "Lembramos dos produtos no seu carrinho",
|
|
71
|
+
personalizedOffers: "Ofertas personalizadas baseadas no seu hist\xF3rico",
|
|
72
|
+
paymentSecurity: "Seguran\xE7a adicional no processo de pagamento",
|
|
73
|
+
productRecommendations: "Sugest\xF5es de produtos relevantes"
|
|
74
|
+
},
|
|
75
|
+
saas: {
|
|
76
|
+
userAnalytics: "An\xE1lise de uso para melhorar funcionalidades",
|
|
77
|
+
performanceMonitoring: "Monitoramento de performance da aplica\xE7\xE3o",
|
|
78
|
+
featureUsage: "Estat\xEDsticas de uso de recursos",
|
|
79
|
+
customerSupport: "Suporte ao cliente mais eficiente"
|
|
80
|
+
},
|
|
81
|
+
government: {
|
|
82
|
+
citizenServices: "Melhoria dos servi\xE7os ao cidad\xE3o",
|
|
83
|
+
dataProtection: "Prote\xE7\xE3o rigorosa dos dados pessoais",
|
|
84
|
+
transparency: "Transpar\xEAncia no uso de dados",
|
|
85
|
+
accessibility: "Recursos de acessibilidade digital"
|
|
86
|
+
},
|
|
87
|
+
education: {
|
|
88
|
+
studentProgress: "Acompanhamento do progresso educacional",
|
|
89
|
+
learningAnalytics: "Analytics para melhorar o aprendizado",
|
|
90
|
+
accessibility: "Recursos educacionais acess\xEDveis",
|
|
91
|
+
parentalConsent: "Consentimento parental quando necess\xE1rio"
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
// Variações de tom
|
|
95
|
+
variants: {
|
|
96
|
+
formal: {
|
|
97
|
+
bannerMessage: "Este s\xEDtio eletr\xF4nico utiliza cookies para otimizar a experi\xEAncia de navega\xE7\xE3o.",
|
|
98
|
+
acceptAll: "Concordar com todos os cookies",
|
|
99
|
+
declineAll: "Recusar cookies opcionais",
|
|
100
|
+
modalTitle: "Configura\xE7\xE3o de Cookies"
|
|
101
|
+
},
|
|
102
|
+
casual: {
|
|
103
|
+
bannerMessage: "\u{1F36A} Ei! Usamos cookies para tornar sua experi\xEAncia ainda melhor!",
|
|
104
|
+
acceptAll: "Aceitar tudo",
|
|
105
|
+
declineAll: "S\xF3 o essencial",
|
|
106
|
+
modalTitle: "Seus Cookies"
|
|
107
|
+
},
|
|
108
|
+
concise: {
|
|
109
|
+
bannerMessage: "Usamos cookies. Voc\xEA aceita?",
|
|
110
|
+
acceptAll: "Sim",
|
|
111
|
+
declineAll: "N\xE3o",
|
|
112
|
+
modalTitle: "Cookies"
|
|
113
|
+
},
|
|
114
|
+
detailed: {
|
|
115
|
+
bannerMessage: "Utilizamos cookies e tecnologias similares para melhorar sua experi\xEAncia de navega\xE7\xE3o, personalizar conte\xFAdo, analisar tr\xE1fego e oferecer funcionalidades de redes sociais.",
|
|
116
|
+
acceptAll: "Aceitar todos os cookies e tecnologias",
|
|
117
|
+
declineAll: "Recusar todos os cookies opcionais",
|
|
118
|
+
modalTitle: "Centro de Prefer\xEAncias de Privacidade"
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
// Internacionalização simplificada (apenas textos básicos)
|
|
122
|
+
i18n: {
|
|
123
|
+
en: {
|
|
124
|
+
bannerMessage: "We use cookies to enhance your experience.",
|
|
125
|
+
acceptAll: "Accept All",
|
|
126
|
+
declineAll: "Decline",
|
|
127
|
+
preferences: "Preferences",
|
|
128
|
+
modalTitle: "Cookie Preferences",
|
|
129
|
+
modalIntro: "Customize your cookie preferences below.",
|
|
130
|
+
save: "Save Preferences",
|
|
131
|
+
necessaryAlwaysOn: "Necessary cookies (always active)"
|
|
132
|
+
},
|
|
133
|
+
es: {
|
|
134
|
+
bannerMessage: "Utilizamos cookies para mejorar su experiencia.",
|
|
135
|
+
acceptAll: "Aceptar Todo",
|
|
136
|
+
declineAll: "Rechazar",
|
|
137
|
+
preferences: "Preferencias",
|
|
138
|
+
modalTitle: "Preferencias de Cookies",
|
|
139
|
+
modalIntro: "Personalice sus preferencias de cookies a continuaci\xF3n.",
|
|
140
|
+
save: "Guardar Preferencias",
|
|
141
|
+
necessaryAlwaysOn: "Cookies necess\xE1rias (sempre ativas)"
|
|
142
|
+
},
|
|
143
|
+
fr: {
|
|
144
|
+
bannerMessage: "Nous utilisons des cookies pour am\xE9liorer votre exp\xE9rience.",
|
|
145
|
+
acceptAll: "Tout Accepter",
|
|
146
|
+
declineAll: "Refuser",
|
|
147
|
+
preferences: "Pr\xE9f\xE9rences",
|
|
148
|
+
modalTitle: "Pr\xE9f\xE9rences des Cookies",
|
|
149
|
+
modalIntro: "Personnalisez vos pr\xE9f\xE9rences de cookies ci-dessous.",
|
|
150
|
+
save: "Enregistrer les Pr\xE9f\xE9rences",
|
|
151
|
+
necessaryAlwaysOn: "Cookies n\xE9cessaires (toujours actifs)"
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
// Textos técnicos
|
|
155
|
+
technical: {
|
|
156
|
+
sessionCookies: "Cookies de sess\xE3o s\xE3o tempor\xE1rios e expiram quando voc\xEA fecha o navegador.",
|
|
157
|
+
persistentCookies: "Cookies persistentes permanecem no seu dispositivo at\xE9 expirarem ou serem removidos.",
|
|
158
|
+
thirdPartyCookies: "Cookies de terceiros s\xE3o definidos por dom\xEDnios diferentes do site que voc\xEA est\xE1 visitando.",
|
|
159
|
+
browserSettings: "Voc\xEA pode gerenciar cookies nas configura\xE7\xF5es do seu navegador.",
|
|
160
|
+
disablingImpact: "Desabilitar cookies pode afetar a funcionalidade do site."
|
|
161
|
+
},
|
|
162
|
+
// Cookie details
|
|
163
|
+
cookieDetails: {
|
|
164
|
+
tableHeaders: {
|
|
165
|
+
name: "Nome",
|
|
166
|
+
purpose: "Finalidade",
|
|
167
|
+
duration: "Dura\xE7\xE3o",
|
|
168
|
+
provider: "Fornecedor",
|
|
169
|
+
type: "Tipo"
|
|
170
|
+
},
|
|
171
|
+
noCookies: "Nenhum cookie encontrado para esta categoria.",
|
|
172
|
+
toggleDetails: {
|
|
173
|
+
expand: "Ver detalhes",
|
|
174
|
+
collapse: "Ocultar detalhes"
|
|
175
|
+
},
|
|
176
|
+
scriptLabelPrefix: "(script) ",
|
|
177
|
+
scriptPurpose: "Script de integra\xE7\xE3o ativo"
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
function resolveTexts(texts, options = {}) {
|
|
181
|
+
const { language = "pt", variant } = options;
|
|
182
|
+
let resolved = { ...texts };
|
|
183
|
+
if (variant && texts.variants?.[variant]) {
|
|
184
|
+
resolved = { ...resolved, ...texts.variants[variant] };
|
|
185
|
+
}
|
|
186
|
+
if (language !== "pt" && texts.i18n?.[language]) {
|
|
187
|
+
resolved = { ...resolved, ...texts.i18n[language] };
|
|
188
|
+
}
|
|
189
|
+
return resolved;
|
|
190
|
+
}
|
|
191
|
+
var TEXT_TEMPLATES = {
|
|
192
|
+
ecommerce: {
|
|
193
|
+
...EXPANDED_DEFAULT_TEXTS,
|
|
194
|
+
bannerMessage: "Utilizamos cookies para personalizar ofertas e melhorar sua experi\xEAncia de compra.",
|
|
195
|
+
acceptAll: "Aceitar e continuar",
|
|
196
|
+
variants: {
|
|
197
|
+
casual: {
|
|
198
|
+
bannerMessage: "\u{1F6D2} Usamos cookies para encontrar as melhores ofertas para voc\xEA!",
|
|
199
|
+
acceptAll: "Quero ofertas personalizadas!"
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
saas: {
|
|
204
|
+
...EXPANDED_DEFAULT_TEXTS,
|
|
205
|
+
bannerMessage: "Utilizamos cookies para otimizar o desempenho da aplica\xE7\xE3o e sua experi\xEAncia.",
|
|
206
|
+
acceptAll: "Aceitar e otimizar",
|
|
207
|
+
variants: {
|
|
208
|
+
formal: {
|
|
209
|
+
bannerMessage: "Esta aplica\xE7\xE3o utiliza cookies para an\xE1lise de performance e melhoria cont\xEDnua da experi\xEAncia do usu\xE1rio.",
|
|
210
|
+
acceptAll: "Autorizar coleta de dados de uso"
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
government: {
|
|
215
|
+
...EXPANDED_DEFAULT_TEXTS,
|
|
216
|
+
bannerMessage: "Este portal utiliza cookies em conformidade com a LGPD para melhorar os servi\xE7os p\xFAblicos.",
|
|
217
|
+
acceptAll: "Aceitar em conformidade",
|
|
218
|
+
variants: {
|
|
219
|
+
formal: {
|
|
220
|
+
bannerMessage: "Este s\xEDtio eletr\xF4nico do governo utiliza cookies estritamente necess\xE1rios e opcionais, em conformidade com a Lei Geral de Prote\xE7\xE3o de Dados.",
|
|
221
|
+
acceptAll: "Concordar com o uso de cookies"
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
|
|
14
227
|
// src/utils/categoryUtils.ts
|
|
15
228
|
function createProjectPreferences(config, defaultValue = false) {
|
|
16
229
|
const preferences = {
|
|
@@ -309,6 +522,7 @@ function setDebugLogging(enabled, level = 2 /* INFO */) {
|
|
|
309
522
|
// src/utils/cookieUtils.ts
|
|
310
523
|
var DEFAULT_STORAGE_NAMESPACE = "lgpd-consent";
|
|
311
524
|
var DEFAULT_STORAGE_VERSION = "1";
|
|
525
|
+
var DEFAULT_MAX_AGE_SECONDS = 365 * 24 * 60 * 60;
|
|
312
526
|
function buildConsentStorageKey(options) {
|
|
313
527
|
const namespaceRaw = options?.namespace?.trim() || DEFAULT_STORAGE_NAMESPACE;
|
|
314
528
|
const versionRaw = options?.version?.trim() || DEFAULT_STORAGE_VERSION;
|
|
@@ -318,16 +532,36 @@ function buildConsentStorageKey(options) {
|
|
|
318
532
|
}
|
|
319
533
|
var DEFAULT_COOKIE_OPTS = {
|
|
320
534
|
name: "cookieConsent",
|
|
535
|
+
maxAge: DEFAULT_MAX_AGE_SECONDS,
|
|
321
536
|
maxAgeDays: 365,
|
|
322
537
|
sameSite: "Lax",
|
|
323
|
-
secure:
|
|
538
|
+
secure: false,
|
|
324
539
|
path: "/",
|
|
325
540
|
domain: void 0
|
|
326
541
|
};
|
|
542
|
+
function resolveCookieOptions(opts) {
|
|
543
|
+
const currentWindow = globalThis.window;
|
|
544
|
+
const currentLocation = globalThis.location;
|
|
545
|
+
const protocols = [currentWindow?.location?.protocol, currentLocation?.protocol].filter(
|
|
546
|
+
Boolean
|
|
547
|
+
);
|
|
548
|
+
const forceHttps = globalThis.__LGPD_FORCE_HTTPS__ === true;
|
|
549
|
+
const isHttps = forceHttps || protocols.includes("https:");
|
|
550
|
+
const maxAgeSecondsFromDays = typeof opts?.maxAgeDays === "number" ? Math.max(0, opts.maxAgeDays * 24 * 60 * 60) : null;
|
|
551
|
+
const maxAgeSeconds = typeof opts?.maxAge === "number" ? Math.max(0, opts.maxAge) : maxAgeSecondsFromDays ?? DEFAULT_MAX_AGE_SECONDS;
|
|
552
|
+
return {
|
|
553
|
+
name: opts?.name ?? DEFAULT_COOKIE_OPTS.name,
|
|
554
|
+
maxAge: maxAgeSeconds,
|
|
555
|
+
sameSite: opts?.sameSite ?? DEFAULT_COOKIE_OPTS.sameSite ?? "Lax",
|
|
556
|
+
secure: typeof opts?.secure === "boolean" ? opts.secure : isHttps ? true : DEFAULT_COOKIE_OPTS.secure,
|
|
557
|
+
path: opts?.path ?? DEFAULT_COOKIE_OPTS.path ?? "/",
|
|
558
|
+
domain: opts?.domain ?? DEFAULT_COOKIE_OPTS.domain ?? void 0
|
|
559
|
+
};
|
|
560
|
+
}
|
|
327
561
|
var COOKIE_SCHEMA_VERSION = "1.0";
|
|
328
562
|
function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
|
|
329
563
|
logger.debug("Reading consent cookie", { name });
|
|
330
|
-
if (
|
|
564
|
+
if (globalThis.document === void 0) {
|
|
331
565
|
logger.debug("Cookie read skipped: server-side environment");
|
|
332
566
|
return null;
|
|
333
567
|
}
|
|
@@ -339,6 +573,10 @@ function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
|
|
|
339
573
|
try {
|
|
340
574
|
const data = JSON.parse(raw);
|
|
341
575
|
logger.cookieOperation("read", name, data);
|
|
576
|
+
if (!data || typeof data !== "object") {
|
|
577
|
+
logger.warn("Consent cookie malformed: payload is not an object");
|
|
578
|
+
return null;
|
|
579
|
+
}
|
|
342
580
|
if (!data.version) {
|
|
343
581
|
logger.debug("Migrating legacy cookie format");
|
|
344
582
|
return migrateLegacyCookie(data);
|
|
@@ -347,7 +585,11 @@ function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
|
|
|
347
585
|
logger.warn(`Cookie version mismatch: ${data.version} != ${COOKIE_SCHEMA_VERSION}`);
|
|
348
586
|
return null;
|
|
349
587
|
}
|
|
350
|
-
|
|
588
|
+
const preferences = data && typeof data.preferences === "object" ? data.preferences : { necessary: true };
|
|
589
|
+
return {
|
|
590
|
+
...data,
|
|
591
|
+
preferences: ensureNecessaryAlwaysOn(preferences)
|
|
592
|
+
};
|
|
351
593
|
} catch (error) {
|
|
352
594
|
logger.error("Error parsing consent cookie", error);
|
|
353
595
|
return null;
|
|
@@ -370,12 +612,12 @@ function migrateLegacyCookie(legacyData) {
|
|
|
370
612
|
}
|
|
371
613
|
}
|
|
372
614
|
function writeConsentCookie(state, config, opts, source = "banner") {
|
|
373
|
-
if (
|
|
615
|
+
if (globalThis.document === void 0 || globalThis.window === void 0 || globalThis.__LGPD_SSR__ === true) {
|
|
374
616
|
logger.debug("Cookie write skipped: server-side environment");
|
|
375
617
|
return;
|
|
376
618
|
}
|
|
377
619
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
378
|
-
const o =
|
|
620
|
+
const o = resolveCookieOptions(opts);
|
|
379
621
|
const preferences = ensureNecessaryAlwaysOn(state.preferences);
|
|
380
622
|
const cookieData = {
|
|
381
623
|
version: COOKIE_SCHEMA_VERSION,
|
|
@@ -387,8 +629,9 @@ function writeConsentCookie(state, config, opts, source = "banner") {
|
|
|
387
629
|
projectConfig: config
|
|
388
630
|
};
|
|
389
631
|
logger.cookieOperation("write", o.name, cookieData);
|
|
632
|
+
const expires = new Date(Date.now() + o.maxAge * 1e3);
|
|
390
633
|
Cookies.set(o.name, JSON.stringify(cookieData), {
|
|
391
|
-
expires
|
|
634
|
+
expires,
|
|
392
635
|
sameSite: o.sameSite,
|
|
393
636
|
secure: o.secure,
|
|
394
637
|
path: o.path,
|
|
@@ -418,36 +661,48 @@ function createConsentAuditEntry(state, params) {
|
|
|
418
661
|
};
|
|
419
662
|
}
|
|
420
663
|
function removeConsentCookie(opts) {
|
|
421
|
-
if (
|
|
664
|
+
if (globalThis.document === void 0) {
|
|
422
665
|
logger.debug("Cookie removal skipped: server-side environment");
|
|
423
666
|
return;
|
|
424
667
|
}
|
|
425
|
-
const o =
|
|
668
|
+
const o = resolveCookieOptions(opts);
|
|
426
669
|
logger.cookieOperation("delete", o.name);
|
|
427
670
|
Cookies.remove(o.name, { path: o.path, domain: o.domain });
|
|
428
671
|
logger.info("Consent cookie removed");
|
|
429
672
|
}
|
|
430
673
|
|
|
431
674
|
// src/utils/dataLayerEvents.ts
|
|
432
|
-
var LIBRARY_VERSION = "0.7.
|
|
675
|
+
var LIBRARY_VERSION = "0.7.2";
|
|
433
676
|
function ensureDataLayer() {
|
|
434
|
-
|
|
435
|
-
if (
|
|
436
|
-
|
|
677
|
+
const currentWindow = globalThis.window;
|
|
678
|
+
if (!currentWindow) return;
|
|
679
|
+
const currentLayer = currentWindow.dataLayer;
|
|
680
|
+
if (currentLayer == null) {
|
|
681
|
+
currentWindow.dataLayer = [];
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
if (typeof currentLayer.push !== "function") {
|
|
685
|
+
const env = globalThis.process?.env?.NODE_ENV ?? "production";
|
|
686
|
+
if (env !== "production") {
|
|
687
|
+
console.warn("[LGPD-CONSENT] dataLayer presente mas sem push; eventos n\xE3o ser\xE3o registrados.");
|
|
688
|
+
}
|
|
689
|
+
}
|
|
437
690
|
}
|
|
438
691
|
function pushConsentInitializedEvent(categories) {
|
|
439
|
-
if (globalThis.window === void 0) return;
|
|
440
692
|
ensureDataLayer();
|
|
441
693
|
const event = {
|
|
442
694
|
event: "consent_initialized",
|
|
443
695
|
consent_version: LIBRARY_VERSION,
|
|
444
696
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
445
|
-
categories
|
|
697
|
+
categories,
|
|
698
|
+
preferences: categories
|
|
446
699
|
};
|
|
447
|
-
globalThis.window
|
|
700
|
+
const layer = globalThis.window?.dataLayer;
|
|
701
|
+
if (layer && typeof layer.push === "function") {
|
|
702
|
+
layer.push(event);
|
|
703
|
+
}
|
|
448
704
|
}
|
|
449
705
|
function pushConsentUpdatedEvent(categories, origin, previousCategories) {
|
|
450
|
-
if (globalThis.window === void 0) return;
|
|
451
706
|
ensureDataLayer();
|
|
452
707
|
const changedCategories = previousCategories ? Object.keys(categories).filter((key) => categories[key] !== previousCategories[key]) : [];
|
|
453
708
|
const event = {
|
|
@@ -456,9 +711,13 @@ function pushConsentUpdatedEvent(categories, origin, previousCategories) {
|
|
|
456
711
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
457
712
|
origin,
|
|
458
713
|
categories,
|
|
714
|
+
preferences: categories,
|
|
459
715
|
changed_categories: changedCategories
|
|
460
716
|
};
|
|
461
|
-
globalThis.window
|
|
717
|
+
const layer = globalThis.window?.dataLayer;
|
|
718
|
+
if (layer && typeof layer.push === "function") {
|
|
719
|
+
layer.push(event);
|
|
720
|
+
}
|
|
462
721
|
}
|
|
463
722
|
function useDataLayerEvents() {
|
|
464
723
|
return {
|
|
@@ -788,7 +1047,7 @@ function analyzeDeveloperConfiguration(config) {
|
|
|
788
1047
|
const gt = globalThis;
|
|
789
1048
|
const implied = (gt.__LGPD_REQUIRED_CATEGORIES__ || []).filter(Boolean);
|
|
790
1049
|
implied.forEach((id) => {
|
|
791
|
-
if (!guidance.activeCategoriesInfo.
|
|
1050
|
+
if (!guidance.activeCategoriesInfo.some((c) => c.id === id)) {
|
|
792
1051
|
const info = NAMES[id];
|
|
793
1052
|
if (info) {
|
|
794
1053
|
guidance.activeCategoriesInfo.push({
|
|
@@ -828,6 +1087,27 @@ function analyzeDeveloperConfiguration(config) {
|
|
|
828
1087
|
'Apenas cookies necess\xE1rios est\xE3o configurados. Para compliance LGPD, considere adicionar categorias como "analytics" ou "functional" conforme uso real.',
|
|
829
1088
|
"compliance"
|
|
830
1089
|
);
|
|
1090
|
+
} else {
|
|
1091
|
+
addMessage(
|
|
1092
|
+
"info",
|
|
1093
|
+
"Cookies n\xE3o necess\xE1rios devem iniciar desativados e exigir consentimento expresso, sem pr\xE9-sele\xE7\xE3o e sem consentimento t\xE1cito.",
|
|
1094
|
+
"consent"
|
|
1095
|
+
);
|
|
1096
|
+
addMessage(
|
|
1097
|
+
"info",
|
|
1098
|
+
"Ofere\xE7a op\xE7\xF5es claras de aceitar, rejeitar e gerenciar prefer\xEAncias com o mesmo destaque, al\xE9m de revoga\xE7\xE3o simples e gratuita.",
|
|
1099
|
+
"consent"
|
|
1100
|
+
);
|
|
1101
|
+
addMessage(
|
|
1102
|
+
"info",
|
|
1103
|
+
"Informe finalidades espec\xEDficas, per\xEDodo de reten\xE7\xE3o e compartilhamento com terceiros em pol\xEDtica/aviso de cookies.",
|
|
1104
|
+
"transparency"
|
|
1105
|
+
);
|
|
1106
|
+
addMessage(
|
|
1107
|
+
"info",
|
|
1108
|
+
"Disponibilize mecanismo pr\xF3prio de gerenciamento de cookies; configura\xE7\xF5es do navegador s\xE3o apenas complementares.",
|
|
1109
|
+
"transparency"
|
|
1110
|
+
);
|
|
831
1111
|
}
|
|
832
1112
|
if (totalToggleable > 5) {
|
|
833
1113
|
addMessage(
|
|
@@ -852,7 +1132,7 @@ function getComplianceScoreColor(score) {
|
|
|
852
1132
|
function logComplianceScore(prefix, score) {
|
|
853
1133
|
const color = getComplianceScoreColor(score);
|
|
854
1134
|
console.log(
|
|
855
|
-
`%c${prefix} Score de Conformidade LGPD: ${score}/100`,
|
|
1135
|
+
`%c${prefix} Score de Conformidade LGPD (orientativo): ${score}/100`,
|
|
856
1136
|
`color: ${color}; font-weight: bold; font-size: 14px;`
|
|
857
1137
|
);
|
|
858
1138
|
}
|
|
@@ -947,7 +1227,7 @@ function logServerSideIfAvailable(guidance) {
|
|
|
947
1227
|
}
|
|
948
1228
|
function logDeveloperGuidance(guidance, disableGuidanceProp, config) {
|
|
949
1229
|
const gt = globalThis;
|
|
950
|
-
const nodeEnv =
|
|
1230
|
+
const nodeEnv = gt.process ? gt.process?.env?.NODE_ENV : void 0;
|
|
951
1231
|
const isProd = nodeEnv === "production" || gt.__LGPD_PRODUCTION__ === true;
|
|
952
1232
|
if (isProd || disableGuidanceProp) return;
|
|
953
1233
|
const guidanceHash = getGuidanceHash(guidance);
|
|
@@ -1005,11 +1285,21 @@ function logDeveloperGuidance(guidance, disableGuidanceProp, config) {
|
|
|
1005
1285
|
"color: #9c27b0;",
|
|
1006
1286
|
"color: #7b1fa2;"
|
|
1007
1287
|
);
|
|
1288
|
+
console.info(
|
|
1289
|
+
`%c${PREFIX}%c Evite consentimento t\xE1cito e op\xE7\xF5es pr\xE9-selecionadas`,
|
|
1290
|
+
"color: #9c27b0;",
|
|
1291
|
+
"color: #7b1fa2;"
|
|
1292
|
+
);
|
|
1008
1293
|
console.info(
|
|
1009
1294
|
`%c${PREFIX}%c Documente pol\xEDticas claras por categoria`,
|
|
1010
1295
|
"color: #9c27b0;",
|
|
1011
1296
|
"color: #7b1fa2;"
|
|
1012
1297
|
);
|
|
1298
|
+
console.info(
|
|
1299
|
+
`%c${PREFIX}%c Informe finalidades, reten\xE7\xE3o e revoga\xE7\xE3o simples e gratuita`,
|
|
1300
|
+
"color: #9c27b0;",
|
|
1301
|
+
"color: #7b1fa2;"
|
|
1302
|
+
);
|
|
1013
1303
|
console.info(
|
|
1014
1304
|
`%c${PREFIX}%c Registre consentimento com data/hora/origem`,
|
|
1015
1305
|
"color: #9c27b0;",
|
|
@@ -1021,7 +1311,9 @@ function logDeveloperGuidance(guidance, disableGuidanceProp, config) {
|
|
|
1021
1311
|
function useDeveloperGuidance(config, disableGuidanceProp, guidanceConfig) {
|
|
1022
1312
|
const guidance = React4__default.useMemo(() => analyzeDeveloperConfiguration(config), [config]);
|
|
1023
1313
|
React4__default.useEffect(() => {
|
|
1024
|
-
if (!disableGuidanceProp)
|
|
1314
|
+
if (globalThis.window !== void 0 && !disableGuidanceProp) {
|
|
1315
|
+
logDeveloperGuidance(guidance, disableGuidanceProp, guidanceConfig);
|
|
1316
|
+
}
|
|
1025
1317
|
}, [guidance, disableGuidanceProp, guidanceConfig]);
|
|
1026
1318
|
return guidance;
|
|
1027
1319
|
}
|
|
@@ -1065,58 +1357,8 @@ var GUIDANCE_PRESETS = {
|
|
|
1065
1357
|
};
|
|
1066
1358
|
|
|
1067
1359
|
// src/utils/peerDepsCheck.ts
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
try {
|
|
1071
|
-
const reactSymbols = Object.getOwnPropertySymbols(globalThis.window).map(String).filter((name) => name.includes("react"));
|
|
1072
|
-
if (reactSymbols.length > 1) {
|
|
1073
|
-
return true;
|
|
1074
|
-
}
|
|
1075
|
-
const ReactModule = window.React;
|
|
1076
|
-
if (ReactModule && Array.isArray(ReactModule)) {
|
|
1077
|
-
return true;
|
|
1078
|
-
}
|
|
1079
|
-
const hasMultipleVersions = window.__REACT_DEVTOOLS_GLOBAL_HOOK__?.renderers?.size > 1;
|
|
1080
|
-
return hasMultipleVersions || false;
|
|
1081
|
-
} catch {
|
|
1082
|
-
return false;
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
function getPackageVersion(packageName) {
|
|
1086
|
-
if (globalThis.window === void 0) return null;
|
|
1087
|
-
try {
|
|
1088
|
-
const pkg = window[packageName];
|
|
1089
|
-
if (pkg?.version) return pkg.version;
|
|
1090
|
-
const React6 = window.React;
|
|
1091
|
-
if (packageName === "react" && React6?.version) {
|
|
1092
|
-
return React6.version;
|
|
1093
|
-
}
|
|
1094
|
-
return null;
|
|
1095
|
-
} catch {
|
|
1096
|
-
return null;
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
function isVersionInRange(version, minMajor, maxMajor) {
|
|
1100
|
-
const major = Number.parseInt(version.split(".")[0], 10);
|
|
1101
|
-
return major >= minMajor && major <= maxMajor;
|
|
1102
|
-
}
|
|
1103
|
-
function checkPeerDeps(options = {}) {
|
|
1104
|
-
const { skipInProduction = true, logWarnings = true } = options;
|
|
1105
|
-
const result = {
|
|
1106
|
-
ok: true,
|
|
1107
|
-
warnings: [],
|
|
1108
|
-
errors: []
|
|
1109
|
-
};
|
|
1110
|
-
const isProduction = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
1111
|
-
if (skipInProduction && isProduction) {
|
|
1112
|
-
return result;
|
|
1113
|
-
}
|
|
1114
|
-
if (globalThis.window === void 0) {
|
|
1115
|
-
return result;
|
|
1116
|
-
}
|
|
1117
|
-
if (detectMultipleReactInstances()) {
|
|
1118
|
-
result.ok = false;
|
|
1119
|
-
const errorMsg = `
|
|
1360
|
+
var MESSAGES_PT_BR = {
|
|
1361
|
+
MULTIPLE_REACT_INSTANCES: `
|
|
1120
1362
|
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
1121
1363
|
\u2551 \u26A0\uFE0F ERRO: M\xFAltiplas inst\xE2ncias de React detectadas \u2551
|
|
1122
1364
|
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
@@ -1178,22 +1420,13 @@ function checkPeerDeps(options = {}) {
|
|
|
1178
1420
|
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#multiple-react-instances
|
|
1179
1421
|
|
|
1180
1422
|
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
if (logWarnings) {
|
|
1184
|
-
console.error(errorMsg);
|
|
1185
|
-
}
|
|
1186
|
-
}
|
|
1187
|
-
const reactVersion = getPackageVersion("react");
|
|
1188
|
-
if (reactVersion) {
|
|
1189
|
-
if (!isVersionInRange(reactVersion, 18, 19)) {
|
|
1190
|
-
result.ok = false;
|
|
1191
|
-
const errorMsg = `
|
|
1423
|
+
`,
|
|
1424
|
+
UNSUPPORTED_REACT_VERSION: (version) => `
|
|
1192
1425
|
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
1193
1426
|
\u2551 \u26A0\uFE0F AVISO: Vers\xE3o do React n\xE3o suportada \u2551
|
|
1194
1427
|
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
1195
1428
|
|
|
1196
|
-
\u{1F4E6} Vers\xE3o detectada: React ${
|
|
1429
|
+
\u{1F4E6} Vers\xE3o detectada: React ${version}
|
|
1197
1430
|
\u2705 Vers\xF5es suportadas: React 18.x ou 19.x
|
|
1198
1431
|
|
|
1199
1432
|
\u{1F50D} O react-lgpd-consent requer React 18.2.0+ ou React 19.x
|
|
@@ -1211,27 +1444,13 @@ function checkPeerDeps(options = {}) {
|
|
|
1211
1444
|
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#react-version
|
|
1212
1445
|
|
|
1213
1446
|
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
if (logWarnings) {
|
|
1217
|
-
console.error(errorMsg);
|
|
1218
|
-
}
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
const muiVersion = window["@mui/material"]?.version;
|
|
1222
|
-
if (muiVersion) {
|
|
1223
|
-
if (!isVersionInRange(muiVersion, 5, 7)) {
|
|
1224
|
-
result.warnings.push(
|
|
1225
|
-
`MUI vers\xE3o ${muiVersion} detectada. Vers\xF5es suportadas: 5.15.0+, 6.x ou 7.x. Alguns componentes podem n\xE3o funcionar corretamente.`
|
|
1226
|
-
);
|
|
1227
|
-
if (logWarnings) {
|
|
1228
|
-
logger.warn(
|
|
1229
|
-
`
|
|
1447
|
+
`,
|
|
1448
|
+
UNSUPPORTED_MUI_VERSION: (version) => `
|
|
1230
1449
|
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
1231
1450
|
\u2551 \u26A0\uFE0F AVISO: Vers\xE3o do Material-UI fora do range recomendado \u2551
|
|
1232
1451
|
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
1233
1452
|
|
|
1234
|
-
\u{1F4E6} Vers\xE3o detectada: @mui/material ${
|
|
1453
|
+
\u{1F4E6} Vers\xE3o detectada: @mui/material ${version}
|
|
1235
1454
|
\u2705 Vers\xF5es suportadas: 5.15.0+, 6.x, 7.x
|
|
1236
1455
|
|
|
1237
1456
|
\u{1F50D} Componentes de UI (@react-lgpd-consent/mui) podem apresentar problemas.
|
|
@@ -1249,8 +1468,230 @@ function checkPeerDeps(options = {}) {
|
|
|
1249
1468
|
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#mui-version
|
|
1250
1469
|
|
|
1251
1470
|
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1252
|
-
|
|
1253
|
-
|
|
1471
|
+
`,
|
|
1472
|
+
MUI_OUT_OF_RANGE: (version) => `MUI vers\xE3o ${version} detectada. Vers\xF5es suportadas: 5.15.0+, 6.x ou 7.x. Alguns componentes podem n\xE3o funcionar corretamente.`
|
|
1473
|
+
};
|
|
1474
|
+
var MESSAGES_EN = {
|
|
1475
|
+
MULTIPLE_REACT_INSTANCES: `
|
|
1476
|
+
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
1477
|
+
\u2551 \u26A0\uFE0F ERROR: Multiple React instances detected \u2551
|
|
1478
|
+
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
1479
|
+
|
|
1480
|
+
\u{1F534} Problem:
|
|
1481
|
+
Your project is loading more than one copy of React, causing the error:
|
|
1482
|
+
"Invalid hook call. Hooks can only be called inside of the body of a
|
|
1483
|
+
function component."
|
|
1484
|
+
|
|
1485
|
+
\u{1F50D} Probable cause:
|
|
1486
|
+
\u2022 pnpm/Yarn PnP without proper peer dependency hoisting
|
|
1487
|
+
\u2022 node_modules with duplicate React (classic npm/yarn)
|
|
1488
|
+
\u2022 Webpack/Vite with multiple resolutions of the same package
|
|
1489
|
+
|
|
1490
|
+
\u2705 Solutions:
|
|
1491
|
+
|
|
1492
|
+
\u{1F4E6} PNPM (RECOMMENDED):
|
|
1493
|
+
Add to root package.json:
|
|
1494
|
+
{
|
|
1495
|
+
"pnpm": {
|
|
1496
|
+
"overrides": {
|
|
1497
|
+
"react": "$react",
|
|
1498
|
+
"react-dom": "$react-dom"
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
Run: pnpm install
|
|
1503
|
+
|
|
1504
|
+
\u{1F4E6} NPM/Yarn:
|
|
1505
|
+
Add to root package.json:
|
|
1506
|
+
{
|
|
1507
|
+
"overrides": {
|
|
1508
|
+
"react": "^18.2.0 || ^19.0.0",
|
|
1509
|
+
"react-dom": "^18.2.0 || ^19.0.0"
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
Run: npm install (or yarn install)
|
|
1513
|
+
|
|
1514
|
+
\u{1F527} Webpack:
|
|
1515
|
+
Add to webpack.config.js:
|
|
1516
|
+
module.exports = {
|
|
1517
|
+
resolve: {
|
|
1518
|
+
alias: {
|
|
1519
|
+
react: path.resolve('./node_modules/react'),
|
|
1520
|
+
'react-dom': path.resolve('./node_modules/react-dom'),
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1525
|
+
\u26A1 Vite:
|
|
1526
|
+
Add to vite.config.js:
|
|
1527
|
+
export default {
|
|
1528
|
+
resolve: {
|
|
1529
|
+
dedupe: ['react', 'react-dom']
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
\u{1F4DA} Documentation:
|
|
1534
|
+
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#multiple-react-instances
|
|
1535
|
+
|
|
1536
|
+
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1537
|
+
`,
|
|
1538
|
+
UNSUPPORTED_REACT_VERSION: (version) => `
|
|
1539
|
+
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
1540
|
+
\u2551 \u26A0\uFE0F WARNING: Unsupported React version \u2551
|
|
1541
|
+
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
1542
|
+
|
|
1543
|
+
\u{1F4E6} Detected version: React ${version}
|
|
1544
|
+
\u2705 Supported versions: React 18.x or 19.x
|
|
1545
|
+
|
|
1546
|
+
\u{1F50D} react-lgpd-consent requires React 18.2.0+ or React 19.x
|
|
1547
|
+
|
|
1548
|
+
\u2705 Solution:
|
|
1549
|
+
Update React to a supported version:
|
|
1550
|
+
|
|
1551
|
+
npm install react@^18.2.0 react-dom@^18.2.0
|
|
1552
|
+
|
|
1553
|
+
or
|
|
1554
|
+
|
|
1555
|
+
npm install react@^19.0.0 react-dom@^19.0.0
|
|
1556
|
+
|
|
1557
|
+
\u{1F4DA} Documentation:
|
|
1558
|
+
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#react-version
|
|
1559
|
+
|
|
1560
|
+
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1561
|
+
`,
|
|
1562
|
+
UNSUPPORTED_MUI_VERSION: (version) => `
|
|
1563
|
+
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
1564
|
+
\u2551 \u26A0\uFE0F WARNING: Material-UI version out of recommended range \u2551
|
|
1565
|
+
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
1566
|
+
|
|
1567
|
+
\u{1F4E6} Detected version: @mui/material ${version}
|
|
1568
|
+
\u2705 Supported versions: 5.15.0+, 6.x, 7.x
|
|
1569
|
+
|
|
1570
|
+
\u{1F50D} UI components (@react-lgpd-consent/mui) may have issues.
|
|
1571
|
+
|
|
1572
|
+
\u2705 Solution:
|
|
1573
|
+
Update MUI to a supported version:
|
|
1574
|
+
|
|
1575
|
+
npm install @mui/material@^7.0.0 @emotion/react @emotion/styled
|
|
1576
|
+
|
|
1577
|
+
or keep 5.15.0+:
|
|
1578
|
+
|
|
1579
|
+
npm install @mui/material@^5.15.0 @emotion/react @emotion/styled
|
|
1580
|
+
|
|
1581
|
+
\u{1F4DA} Documentation:
|
|
1582
|
+
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#mui-version
|
|
1583
|
+
|
|
1584
|
+
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1585
|
+
`,
|
|
1586
|
+
MUI_OUT_OF_RANGE: (version) => `MUI version ${version} detected. Supported versions: 5.15.0+, 6.x or 7.x. Some components may not work properly.`
|
|
1587
|
+
};
|
|
1588
|
+
var MESSAGES_BY_LOCALE = {
|
|
1589
|
+
"pt-BR": MESSAGES_PT_BR,
|
|
1590
|
+
en: MESSAGES_EN
|
|
1591
|
+
};
|
|
1592
|
+
var currentLocale = "pt-BR";
|
|
1593
|
+
var customMessages = {};
|
|
1594
|
+
function setPeerDepsLocale(locale) {
|
|
1595
|
+
currentLocale = locale;
|
|
1596
|
+
}
|
|
1597
|
+
function getPeerDepsLocale() {
|
|
1598
|
+
return currentLocale;
|
|
1599
|
+
}
|
|
1600
|
+
function setPeerDepsMessages(messages) {
|
|
1601
|
+
customMessages = { ...customMessages, ...messages };
|
|
1602
|
+
}
|
|
1603
|
+
function resetPeerDepsMessages() {
|
|
1604
|
+
customMessages = {};
|
|
1605
|
+
}
|
|
1606
|
+
function getMessages() {
|
|
1607
|
+
const baseMessages = MESSAGES_BY_LOCALE[currentLocale];
|
|
1608
|
+
if (Object.keys(customMessages).length === 0) {
|
|
1609
|
+
return baseMessages;
|
|
1610
|
+
}
|
|
1611
|
+
return {
|
|
1612
|
+
MULTIPLE_REACT_INSTANCES: customMessages.MULTIPLE_REACT_INSTANCES ?? baseMessages.MULTIPLE_REACT_INSTANCES,
|
|
1613
|
+
UNSUPPORTED_REACT_VERSION: customMessages.UNSUPPORTED_REACT_VERSION ?? baseMessages.UNSUPPORTED_REACT_VERSION,
|
|
1614
|
+
UNSUPPORTED_MUI_VERSION: customMessages.UNSUPPORTED_MUI_VERSION ?? baseMessages.UNSUPPORTED_MUI_VERSION,
|
|
1615
|
+
MUI_OUT_OF_RANGE: customMessages.MUI_OUT_OF_RANGE ?? baseMessages.MUI_OUT_OF_RANGE
|
|
1616
|
+
};
|
|
1617
|
+
}
|
|
1618
|
+
function detectMultipleReactInstances() {
|
|
1619
|
+
const currentWindow = globalThis.window;
|
|
1620
|
+
if (currentWindow === void 0) return false;
|
|
1621
|
+
try {
|
|
1622
|
+
const reactSymbols = Object.getOwnPropertySymbols(currentWindow).map(String).filter((name) => name.includes("react"));
|
|
1623
|
+
if (reactSymbols.length > 1) {
|
|
1624
|
+
return true;
|
|
1625
|
+
}
|
|
1626
|
+
const ReactModule = currentWindow.React;
|
|
1627
|
+
if (ReactModule && Array.isArray(ReactModule)) {
|
|
1628
|
+
return true;
|
|
1629
|
+
}
|
|
1630
|
+
const hasMultipleVersions = (currentWindow.__REACT_DEVTOOLS_GLOBAL_HOOK__?.renderers?.size ?? 0) > 1;
|
|
1631
|
+
return hasMultipleVersions || false;
|
|
1632
|
+
} catch {
|
|
1633
|
+
return false;
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
function getPackageVersion(packageName) {
|
|
1637
|
+
const currentWindow = globalThis.window;
|
|
1638
|
+
if (currentWindow === void 0) return null;
|
|
1639
|
+
try {
|
|
1640
|
+
const pkg = currentWindow[packageName];
|
|
1641
|
+
if (pkg?.version) return pkg.version;
|
|
1642
|
+
const React6 = currentWindow.React;
|
|
1643
|
+
if (packageName === "react" && React6?.version) {
|
|
1644
|
+
return React6.version;
|
|
1645
|
+
}
|
|
1646
|
+
return null;
|
|
1647
|
+
} catch {
|
|
1648
|
+
return null;
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
function isVersionInRange(version, minMajor, maxMajor) {
|
|
1652
|
+
const major = Number.parseInt(version.split(".")[0], 10);
|
|
1653
|
+
return major >= minMajor && major <= maxMajor;
|
|
1654
|
+
}
|
|
1655
|
+
function checkPeerDeps(options = {}) {
|
|
1656
|
+
const { skipInProduction = true, logWarnings = true } = options;
|
|
1657
|
+
const result = {
|
|
1658
|
+
ok: true,
|
|
1659
|
+
warnings: [],
|
|
1660
|
+
errors: []
|
|
1661
|
+
};
|
|
1662
|
+
const isProduction = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
1663
|
+
if (skipInProduction && isProduction) {
|
|
1664
|
+
return result;
|
|
1665
|
+
}
|
|
1666
|
+
const currentWindow = globalThis.window;
|
|
1667
|
+
if (currentWindow === void 0) {
|
|
1668
|
+
return result;
|
|
1669
|
+
}
|
|
1670
|
+
const messages = getMessages();
|
|
1671
|
+
if (detectMultipleReactInstances()) {
|
|
1672
|
+
result.ok = false;
|
|
1673
|
+
result.errors.push(messages.MULTIPLE_REACT_INSTANCES);
|
|
1674
|
+
if (logWarnings) {
|
|
1675
|
+
console.error(messages.MULTIPLE_REACT_INSTANCES);
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
const reactVersion = getPackageVersion("react");
|
|
1679
|
+
if (reactVersion) {
|
|
1680
|
+
if (!isVersionInRange(reactVersion, 18, 19)) {
|
|
1681
|
+
result.ok = false;
|
|
1682
|
+
const errorMsg = messages.UNSUPPORTED_REACT_VERSION(reactVersion);
|
|
1683
|
+
result.errors.push(errorMsg);
|
|
1684
|
+
if (logWarnings) {
|
|
1685
|
+
console.error(errorMsg);
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
const muiVersion = currentWindow["@mui/material"]?.version;
|
|
1690
|
+
if (muiVersion) {
|
|
1691
|
+
if (!isVersionInRange(muiVersion, 5, 7)) {
|
|
1692
|
+
result.warnings.push(messages.MUI_OUT_OF_RANGE(muiVersion));
|
|
1693
|
+
if (logWarnings) {
|
|
1694
|
+
logger.warn(messages.UNSUPPORTED_MUI_VERSION(muiVersion));
|
|
1254
1695
|
}
|
|
1255
1696
|
}
|
|
1256
1697
|
}
|
|
@@ -1375,10 +1816,11 @@ function validateConsentProviderProps(props) {
|
|
|
1375
1816
|
|
|
1376
1817
|
// src/utils/cookieDiscovery.ts
|
|
1377
1818
|
function discoverRuntimeCookies() {
|
|
1378
|
-
|
|
1819
|
+
const currentDocument = globalThis.document;
|
|
1820
|
+
if (currentDocument === void 0 || !currentDocument.cookie) return [];
|
|
1379
1821
|
const names = Array.from(
|
|
1380
1822
|
new Set(
|
|
1381
|
-
|
|
1823
|
+
currentDocument.cookie.split(";").map((s) => s.trim()).filter(Boolean).map((s) => s.split("=")[0])
|
|
1382
1824
|
)
|
|
1383
1825
|
);
|
|
1384
1826
|
const list = names.map((name) => ({ name }));
|
|
@@ -1389,27 +1831,34 @@ function discoverRuntimeCookies() {
|
|
|
1389
1831
|
}
|
|
1390
1832
|
return list;
|
|
1391
1833
|
}
|
|
1834
|
+
function tryDecode(val) {
|
|
1835
|
+
try {
|
|
1836
|
+
return decodeURIComponent(val);
|
|
1837
|
+
} catch {
|
|
1838
|
+
return val;
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
function isConsentJson(val) {
|
|
1842
|
+
if (!val.startsWith("{")) return false;
|
|
1843
|
+
try {
|
|
1844
|
+
const obj = JSON.parse(val);
|
|
1845
|
+
return obj && typeof obj === "object" && "preferences" in obj && "version" in obj;
|
|
1846
|
+
} catch {
|
|
1847
|
+
return false;
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1392
1850
|
function detectConsentCookieName() {
|
|
1393
|
-
|
|
1851
|
+
const currentDocument = globalThis.document;
|
|
1852
|
+
if (currentDocument === void 0 || !currentDocument.cookie) return null;
|
|
1394
1853
|
try {
|
|
1395
|
-
const pairs =
|
|
1854
|
+
const pairs = currentDocument.cookie.split(";").map((s) => s.trim()).filter(Boolean);
|
|
1396
1855
|
for (const p of pairs) {
|
|
1397
1856
|
const [name, ...rest] = p.split("=");
|
|
1398
1857
|
const raw = rest.join("=");
|
|
1399
1858
|
if (!raw) continue;
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
} catch {
|
|
1404
|
-
}
|
|
1405
|
-
if (val.startsWith("{")) {
|
|
1406
|
-
try {
|
|
1407
|
-
const obj = JSON.parse(val);
|
|
1408
|
-
if (obj && typeof obj === "object" && "preferences" in obj && "version" in obj) {
|
|
1409
|
-
return name;
|
|
1410
|
-
}
|
|
1411
|
-
} catch {
|
|
1412
|
-
}
|
|
1859
|
+
const val = tryDecode(raw);
|
|
1860
|
+
if (isConsentJson(val)) {
|
|
1861
|
+
return name;
|
|
1413
1862
|
}
|
|
1414
1863
|
}
|
|
1415
1864
|
} catch {
|
|
@@ -1451,15 +1900,6 @@ function CategoriesProvider({
|
|
|
1451
1900
|
disableDiscoveryLog
|
|
1452
1901
|
}) {
|
|
1453
1902
|
const [impliedVersion, setImpliedVersion] = React4.useState(0);
|
|
1454
|
-
React4.useEffect(() => {
|
|
1455
|
-
const handler = () => setImpliedVersion((v) => v + 1);
|
|
1456
|
-
if (typeof window !== "undefined" && typeof window.addEventListener === "function") {
|
|
1457
|
-
window.addEventListener("lgpd:requiredCategories", handler);
|
|
1458
|
-
return () => window.removeEventListener("lgpd:requiredCategories", handler);
|
|
1459
|
-
}
|
|
1460
|
-
return () => {
|
|
1461
|
-
};
|
|
1462
|
-
}, []);
|
|
1463
1903
|
const contextValue = React4.useMemo(() => {
|
|
1464
1904
|
const finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
|
|
1465
1905
|
const guidance = analyzeDeveloperConfiguration(config);
|
|
@@ -1471,35 +1911,47 @@ function CategoriesProvider({
|
|
|
1471
1911
|
allCategories: guidance.activeCategoriesInfo
|
|
1472
1912
|
};
|
|
1473
1913
|
}, [config, impliedVersion]);
|
|
1914
|
+
React4.useEffect(() => {
|
|
1915
|
+
const currentWindow = globalThis.window;
|
|
1916
|
+
if (!currentWindow || typeof currentWindow.addEventListener !== "function") return;
|
|
1917
|
+
const handler = () => {
|
|
1918
|
+
setImpliedVersion((current) => current + 1);
|
|
1919
|
+
};
|
|
1920
|
+
currentWindow.addEventListener("lgpd:requiredCategories", handler);
|
|
1921
|
+
return () => {
|
|
1922
|
+
currentWindow.removeEventListener("lgpd:requiredCategories", handler);
|
|
1923
|
+
};
|
|
1924
|
+
}, []);
|
|
1474
1925
|
React4.useEffect(() => {
|
|
1475
1926
|
logDeveloperGuidance(contextValue.guidance, disableDeveloperGuidance);
|
|
1476
1927
|
}, [contextValue.guidance, disableDeveloperGuidance]);
|
|
1477
1928
|
React4.useEffect(() => {
|
|
1478
1929
|
try {
|
|
1479
1930
|
const gt = globalThis;
|
|
1480
|
-
const env =
|
|
1931
|
+
const env = gt.process?.env?.NODE_ENV;
|
|
1481
1932
|
const isDev2 = env === "development";
|
|
1482
|
-
if (
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1933
|
+
if (isDev2 && gt.__LGPD_DISCOVERY_LOGGED__ !== true && !disableDiscoveryLog) {
|
|
1934
|
+
const discovered = discoverRuntimeCookies();
|
|
1935
|
+
const consentName = detectConsentCookieName() || DEFAULT_COOKIE_OPTS.name;
|
|
1936
|
+
const PREFIX = "[\u{1F36A} LGPD-CONSENT]";
|
|
1937
|
+
if (typeof console !== "undefined") {
|
|
1938
|
+
try {
|
|
1939
|
+
console.group(`${PREFIX} \u{1F50E} Descoberta de cookies (experimental)`);
|
|
1940
|
+
const names = Array.from(
|
|
1941
|
+
new Set([consentName, ...discovered.map((d) => d.name)].filter(Boolean))
|
|
1942
|
+
);
|
|
1943
|
+
const rows = names.map((n) => ({ Cookie: n }));
|
|
1944
|
+
if (typeof console.table === "function") console.table(rows);
|
|
1945
|
+
else console.log(rows);
|
|
1946
|
+
console.info(
|
|
1947
|
+
`${PREFIX} \u2139\uFE0F Estes nomes s\xE3o detectados em tempo de execu\xE7\xE3o. Ajuste ou categorize via APIs de override se necess\xE1rio.`
|
|
1948
|
+
);
|
|
1949
|
+
console.groupEnd();
|
|
1950
|
+
} catch {
|
|
1951
|
+
}
|
|
1500
1952
|
}
|
|
1953
|
+
gt.__LGPD_DISCOVERY_LOGGED__ = true;
|
|
1501
1954
|
}
|
|
1502
|
-
gt.__LGPD_DISCOVERY_LOGGED__ = true;
|
|
1503
1955
|
} catch {
|
|
1504
1956
|
}
|
|
1505
1957
|
}, [disableDiscoveryLog]);
|
|
@@ -1549,7 +2001,7 @@ function createFullConsentState(consented, preferences, source, projectConfig, i
|
|
|
1549
2001
|
isModalOpen
|
|
1550
2002
|
};
|
|
1551
2003
|
}
|
|
1552
|
-
var
|
|
2004
|
+
var BASE_TEXTS = {
|
|
1553
2005
|
// Textos básicos
|
|
1554
2006
|
bannerMessage: "Utilizamos cookies para melhorar sua experi\xEAncia.",
|
|
1555
2007
|
acceptAll: "Aceitar todos",
|
|
@@ -1586,6 +2038,10 @@ var DEFAULT_TEXTS = {
|
|
|
1586
2038
|
transferCountries: void 0
|
|
1587
2039
|
// Exibido se definido
|
|
1588
2040
|
};
|
|
2041
|
+
var DEFAULT_TEXTS = {
|
|
2042
|
+
...BASE_TEXTS,
|
|
2043
|
+
...EXPANDED_DEFAULT_TEXTS
|
|
2044
|
+
};
|
|
1589
2045
|
function reducer(state, action) {
|
|
1590
2046
|
logger.consentState(action.type, state);
|
|
1591
2047
|
switch (action.type) {
|
|
@@ -1669,6 +2125,8 @@ function ConsentProvider({
|
|
|
1669
2125
|
initialState,
|
|
1670
2126
|
categories,
|
|
1671
2127
|
texts: textsProp,
|
|
2128
|
+
language,
|
|
2129
|
+
textVariant,
|
|
1672
2130
|
designTokens,
|
|
1673
2131
|
PreferencesModalComponent,
|
|
1674
2132
|
preferencesModalProps = {},
|
|
@@ -1693,7 +2151,11 @@ function ConsentProvider({
|
|
|
1693
2151
|
onConsentChange,
|
|
1694
2152
|
onAuditLog
|
|
1695
2153
|
}) {
|
|
1696
|
-
const
|
|
2154
|
+
const mergedTexts = React4.useMemo(() => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }), [textsProp]);
|
|
2155
|
+
const texts = React4.useMemo(
|
|
2156
|
+
() => resolveTexts(mergedTexts, { language, variant: textVariant }),
|
|
2157
|
+
[mergedTexts, language, textVariant]
|
|
2158
|
+
);
|
|
1697
2159
|
const cookie = React4.useMemo(() => {
|
|
1698
2160
|
const base = { ...DEFAULT_COOKIE_OPTS, ...cookieOpts ?? {} };
|
|
1699
2161
|
base.name = cookieOpts?.name ?? buildConsentStorageKey({
|
|
@@ -1706,6 +2168,13 @@ function ConsentProvider({
|
|
|
1706
2168
|
return base;
|
|
1707
2169
|
}, [cookieOpts, storage?.domain, storage?.namespace, storage?.version]);
|
|
1708
2170
|
const consentVersion = storage?.version?.trim() || "1";
|
|
2171
|
+
React4.useEffect(() => {
|
|
2172
|
+
try {
|
|
2173
|
+
;
|
|
2174
|
+
globalThis.__LGPD_CONSENT_COOKIE__ = cookie.name;
|
|
2175
|
+
} catch {
|
|
2176
|
+
}
|
|
2177
|
+
}, [cookie.name]);
|
|
1709
2178
|
const finalCategoriesConfig = React4.useMemo(() => {
|
|
1710
2179
|
const isProd = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
1711
2180
|
if (!categories) return DEFAULT_PROJECT_CATEGORIES;
|
|
@@ -2068,51 +2537,100 @@ function ConsentGate(props) {
|
|
|
2068
2537
|
|
|
2069
2538
|
// src/utils/scriptLoader.ts
|
|
2070
2539
|
var LOADING_SCRIPTS = /* @__PURE__ */ new Map();
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2540
|
+
var DEFAULT_POLL_INTERVAL = 100;
|
|
2541
|
+
function resolveCookieNames(preferred) {
|
|
2542
|
+
const inferred = globalThis.__LGPD_CONSENT_COOKIE__ ?? null;
|
|
2543
|
+
const names = [preferred, inferred, "cookieConsent", "lgpd-consent__v1"].filter(
|
|
2544
|
+
Boolean
|
|
2545
|
+
);
|
|
2546
|
+
return Array.from(new Set(names));
|
|
2547
|
+
}
|
|
2548
|
+
function parseConsentFromCookie(names) {
|
|
2549
|
+
const raw = document.cookie;
|
|
2550
|
+
if (!raw) return null;
|
|
2551
|
+
const cookies = raw.split("; ").reduce((acc, part) => {
|
|
2552
|
+
const [k, ...rest] = part.split("=");
|
|
2553
|
+
acc[k] = rest.join("=");
|
|
2554
|
+
return acc;
|
|
2555
|
+
}, {});
|
|
2556
|
+
for (const name of names) {
|
|
2557
|
+
const value = cookies[name];
|
|
2558
|
+
if (!value) continue;
|
|
2559
|
+
try {
|
|
2560
|
+
const parsed = JSON.parse(decodeURIComponent(value));
|
|
2561
|
+
if (!parsed.consented || parsed.isModalOpen) continue;
|
|
2562
|
+
return parsed;
|
|
2563
|
+
} catch {
|
|
2564
|
+
continue;
|
|
2565
|
+
}
|
|
2566
|
+
}
|
|
2567
|
+
return null;
|
|
2568
|
+
}
|
|
2569
|
+
function hasCategoryConsent(snapshot, category) {
|
|
2570
|
+
if (!snapshot.consented || snapshot.isModalOpen) return false;
|
|
2571
|
+
if (category === null) return true;
|
|
2572
|
+
return Boolean(snapshot.preferences?.[category]);
|
|
2573
|
+
}
|
|
2574
|
+
function loadScript(id, src, category = null, attrs = {}, nonce, options) {
|
|
2575
|
+
const currentDocument = globalThis.document;
|
|
2576
|
+
if (!src || currentDocument === void 0) return Promise.resolve();
|
|
2577
|
+
if (currentDocument.getElementById(id)) return Promise.resolve();
|
|
2074
2578
|
const existingPromise = LOADING_SCRIPTS.get(id);
|
|
2075
2579
|
if (existingPromise) return existingPromise;
|
|
2580
|
+
const pollInterval = options?.pollIntervalMs ?? DEFAULT_POLL_INTERVAL;
|
|
2581
|
+
const names = resolveCookieNames(options?.cookieName);
|
|
2582
|
+
const mergedAttrs = { ...attrs };
|
|
2076
2583
|
const promise = new Promise((resolve, reject) => {
|
|
2584
|
+
const inject = () => {
|
|
2585
|
+
const s = currentDocument.createElement("script");
|
|
2586
|
+
s.id = id;
|
|
2587
|
+
s.src = src;
|
|
2588
|
+
s.async = mergedAttrs.async !== "false";
|
|
2589
|
+
const scriptNonce = mergedAttrs.nonce || nonce;
|
|
2590
|
+
if (scriptNonce) {
|
|
2591
|
+
s.nonce = scriptNonce;
|
|
2592
|
+
mergedAttrs.nonce = scriptNonce;
|
|
2593
|
+
}
|
|
2594
|
+
for (const [k, v] of Object.entries(mergedAttrs)) s.setAttribute(k, v);
|
|
2595
|
+
s.onload = () => {
|
|
2596
|
+
LOADING_SCRIPTS.delete(id);
|
|
2597
|
+
resolve();
|
|
2598
|
+
};
|
|
2599
|
+
s.onerror = () => {
|
|
2600
|
+
LOADING_SCRIPTS.delete(id);
|
|
2601
|
+
reject(new Error(`Failed to load script: ${src}`));
|
|
2602
|
+
};
|
|
2603
|
+
currentDocument.body.appendChild(s);
|
|
2604
|
+
};
|
|
2605
|
+
const snapshot = options?.consentSnapshot;
|
|
2606
|
+
const skipChecks = options?.skipConsentCheck === true;
|
|
2607
|
+
if (skipChecks) {
|
|
2608
|
+
inject();
|
|
2609
|
+
return;
|
|
2610
|
+
}
|
|
2611
|
+
if (snapshot) {
|
|
2612
|
+
if (!hasCategoryConsent(snapshot, category)) {
|
|
2613
|
+
reject(
|
|
2614
|
+
new Error(
|
|
2615
|
+
`Consent not granted for category '${category ?? "none"}' when attempting to load ${id}`
|
|
2616
|
+
)
|
|
2617
|
+
);
|
|
2618
|
+
return;
|
|
2619
|
+
}
|
|
2620
|
+
inject();
|
|
2621
|
+
return;
|
|
2622
|
+
}
|
|
2077
2623
|
const checkConsent = () => {
|
|
2078
|
-
const
|
|
2079
|
-
if (!
|
|
2080
|
-
setTimeout(checkConsent,
|
|
2624
|
+
const consent = parseConsentFromCookie(names);
|
|
2625
|
+
if (!consent) {
|
|
2626
|
+
setTimeout(checkConsent, pollInterval);
|
|
2081
2627
|
return;
|
|
2082
2628
|
}
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
setTimeout(checkConsent, 100);
|
|
2087
|
-
return;
|
|
2088
|
-
}
|
|
2089
|
-
if (category && !consent.preferences[category]) {
|
|
2090
|
-
setTimeout(checkConsent, 100);
|
|
2091
|
-
return;
|
|
2092
|
-
}
|
|
2093
|
-
const s = document.createElement("script");
|
|
2094
|
-
s.id = id;
|
|
2095
|
-
s.src = src;
|
|
2096
|
-
s.async = true;
|
|
2097
|
-
const mergedAttrs = { ...attrs };
|
|
2098
|
-
const scriptNonce = mergedAttrs.nonce || nonce;
|
|
2099
|
-
if (scriptNonce) {
|
|
2100
|
-
s.nonce = scriptNonce;
|
|
2101
|
-
mergedAttrs.nonce = scriptNonce;
|
|
2102
|
-
}
|
|
2103
|
-
for (const [k, v] of Object.entries(mergedAttrs)) s.setAttribute(k, v);
|
|
2104
|
-
s.onload = () => {
|
|
2105
|
-
LOADING_SCRIPTS.delete(id);
|
|
2106
|
-
resolve();
|
|
2107
|
-
};
|
|
2108
|
-
s.onerror = () => {
|
|
2109
|
-
LOADING_SCRIPTS.delete(id);
|
|
2110
|
-
reject(new Error(`Failed to load script: ${src}`));
|
|
2111
|
-
};
|
|
2112
|
-
document.body.appendChild(s);
|
|
2113
|
-
} catch {
|
|
2114
|
-
setTimeout(checkConsent, 100);
|
|
2629
|
+
if (!hasCategoryConsent(consent, category)) {
|
|
2630
|
+
setTimeout(checkConsent, pollInterval);
|
|
2631
|
+
return;
|
|
2115
2632
|
}
|
|
2633
|
+
inject();
|
|
2116
2634
|
};
|
|
2117
2635
|
checkConsent();
|
|
2118
2636
|
});
|
|
@@ -2276,14 +2794,107 @@ function validateNecessaryClassification(integrations, enabledCategories) {
|
|
|
2276
2794
|
}
|
|
2277
2795
|
|
|
2278
2796
|
// src/utils/ConsentScriptLoader.tsx
|
|
2797
|
+
var scriptRegistry = /* @__PURE__ */ new Map();
|
|
2798
|
+
var queueListeners = /* @__PURE__ */ new Set();
|
|
2799
|
+
function notifyQueue() {
|
|
2800
|
+
queueListeners.forEach((listener) => {
|
|
2801
|
+
try {
|
|
2802
|
+
listener();
|
|
2803
|
+
} catch {
|
|
2804
|
+
}
|
|
2805
|
+
});
|
|
2806
|
+
}
|
|
2807
|
+
function subscribeQueue(listener) {
|
|
2808
|
+
queueListeners.add(listener);
|
|
2809
|
+
return () => {
|
|
2810
|
+
queueListeners.delete(listener);
|
|
2811
|
+
};
|
|
2812
|
+
}
|
|
2813
|
+
function createInternalScript(def) {
|
|
2814
|
+
return {
|
|
2815
|
+
...def,
|
|
2816
|
+
status: "pending",
|
|
2817
|
+
lastAllowed: false,
|
|
2818
|
+
registeredAt: Date.now(),
|
|
2819
|
+
token: Date.now() + Math.random(),
|
|
2820
|
+
priority: def.priority ?? 0,
|
|
2821
|
+
allowReload: def.allowReload ?? false,
|
|
2822
|
+
onConsentUpdate: def.onConsentUpdate
|
|
2823
|
+
};
|
|
2824
|
+
}
|
|
2825
|
+
function registerScript(def) {
|
|
2826
|
+
const entry = createInternalScript(def);
|
|
2827
|
+
scriptRegistry.set(def.id, entry);
|
|
2828
|
+
notifyQueue();
|
|
2829
|
+
return () => {
|
|
2830
|
+
const current = scriptRegistry.get(def.id);
|
|
2831
|
+
if (current && current.token === entry.token) {
|
|
2832
|
+
scriptRegistry.delete(def.id);
|
|
2833
|
+
notifyQueue();
|
|
2834
|
+
}
|
|
2835
|
+
};
|
|
2836
|
+
}
|
|
2837
|
+
function getExecutableScripts(consent) {
|
|
2838
|
+
const allowedScripts = [];
|
|
2839
|
+
scriptRegistry.forEach((script) => {
|
|
2840
|
+
const categoryAllowed = script.category === "necessary" || consent.consented && Boolean(consent.preferences?.[script.category]);
|
|
2841
|
+
if (!categoryAllowed) {
|
|
2842
|
+
script.lastAllowed = false;
|
|
2843
|
+
return;
|
|
2844
|
+
}
|
|
2845
|
+
if (script.status === "running") return;
|
|
2846
|
+
if (script.status === "executed" && !script.allowReload) return;
|
|
2847
|
+
if (script.status === "executed" && script.allowReload && script.lastAllowed) return;
|
|
2848
|
+
script.lastAllowed = true;
|
|
2849
|
+
allowedScripts.push(script);
|
|
2850
|
+
});
|
|
2851
|
+
return allowedScripts.sort((a, b) => {
|
|
2852
|
+
if (a.category === "necessary" && b.category !== "necessary") return -1;
|
|
2853
|
+
if (b.category === "necessary" && a.category !== "necessary") return 1;
|
|
2854
|
+
if (a.category !== b.category) return a.category.localeCompare(b.category);
|
|
2855
|
+
if (a.priority !== b.priority) return (b.priority ?? 0) - (a.priority ?? 0);
|
|
2856
|
+
return a.registeredAt - b.registeredAt;
|
|
2857
|
+
});
|
|
2858
|
+
}
|
|
2859
|
+
async function processQueue(consent, devLogging) {
|
|
2860
|
+
const scripts = getExecutableScripts(consent);
|
|
2861
|
+
let order = 0;
|
|
2862
|
+
for (const script of scripts) {
|
|
2863
|
+
order += 1;
|
|
2864
|
+
script.status = "running";
|
|
2865
|
+
if (devLogging) {
|
|
2866
|
+
logger.info("[ConsentScriptLoader] executando script", {
|
|
2867
|
+
id: script.id,
|
|
2868
|
+
category: script.category,
|
|
2869
|
+
priority: script.priority ?? 0,
|
|
2870
|
+
order
|
|
2871
|
+
});
|
|
2872
|
+
}
|
|
2873
|
+
try {
|
|
2874
|
+
await Promise.resolve(script.execute());
|
|
2875
|
+
} catch (error) {
|
|
2876
|
+
logger.error(`\u274C Failed to execute script ${script.id}`, error);
|
|
2877
|
+
} finally {
|
|
2878
|
+
script.status = "executed";
|
|
2879
|
+
if (script.onConsentUpdate) {
|
|
2880
|
+
script.onConsentUpdate(consent);
|
|
2881
|
+
}
|
|
2882
|
+
}
|
|
2883
|
+
}
|
|
2884
|
+
}
|
|
2279
2885
|
function ConsentScriptLoader({
|
|
2280
2886
|
integrations,
|
|
2281
2887
|
reloadOnChange = false,
|
|
2282
2888
|
nonce
|
|
2283
2889
|
}) {
|
|
2284
2890
|
const { preferences, consented } = useConsent();
|
|
2891
|
+
const isHydrated = useConsentHydration();
|
|
2285
2892
|
const categories = useCategories();
|
|
2286
|
-
const
|
|
2893
|
+
const [queueVersion, bumpQueueVersion] = React4.useState(0);
|
|
2894
|
+
React4.useEffect(() => {
|
|
2895
|
+
const unsubscribe = subscribeQueue(() => bumpQueueVersion((v) => v + 1));
|
|
2896
|
+
return unsubscribe;
|
|
2897
|
+
}, []);
|
|
2287
2898
|
React4.useEffect(() => {
|
|
2288
2899
|
try {
|
|
2289
2900
|
const ids = (integrations || []).map((i) => i.id);
|
|
@@ -2344,15 +2955,44 @@ function ConsentScriptLoader({
|
|
|
2344
2955
|
console.groupEnd();
|
|
2345
2956
|
}
|
|
2346
2957
|
}, [integrations, categories]);
|
|
2958
|
+
const processedIntegrationsRef = React4.useRef(/* @__PURE__ */ new Map());
|
|
2347
2959
|
React4.useEffect(() => {
|
|
2348
|
-
|
|
2349
|
-
const
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2960
|
+
const cleanups = [];
|
|
2961
|
+
const currentIds = /* @__PURE__ */ new Set();
|
|
2962
|
+
integrations.forEach((integration) => {
|
|
2963
|
+
currentIds.add(integration.id);
|
|
2964
|
+
const structuralHash = JSON.stringify({
|
|
2965
|
+
category: integration.category,
|
|
2966
|
+
src: integration.src,
|
|
2967
|
+
priority: integration.priority,
|
|
2968
|
+
hasBootstrap: Boolean(integration.bootstrap),
|
|
2969
|
+
hasInit: Boolean(integration.init),
|
|
2970
|
+
hasOnConsentUpdate: Boolean(integration.onConsentUpdate)
|
|
2971
|
+
});
|
|
2972
|
+
const existingHash = processedIntegrationsRef.current.get(integration.id);
|
|
2973
|
+
if (existingHash === structuralHash && scriptRegistry.has(integration.id)) {
|
|
2974
|
+
return;
|
|
2975
|
+
}
|
|
2976
|
+
processedIntegrationsRef.current.set(integration.id, structuralHash);
|
|
2977
|
+
if (integration.bootstrap) {
|
|
2978
|
+
cleanups.push(
|
|
2979
|
+
registerScript({
|
|
2980
|
+
id: `${integration.id}__bootstrap`,
|
|
2981
|
+
category: "necessary",
|
|
2982
|
+
priority: (integration.priority ?? 0) + 1e3,
|
|
2983
|
+
execute: integration.bootstrap
|
|
2984
|
+
})
|
|
2985
|
+
);
|
|
2986
|
+
}
|
|
2987
|
+
cleanups.push(
|
|
2988
|
+
registerScript({
|
|
2989
|
+
id: integration.id,
|
|
2990
|
+
category: integration.category,
|
|
2991
|
+
priority: integration.priority,
|
|
2992
|
+
allowReload: reloadOnChange,
|
|
2993
|
+
onConsentUpdate: integration.onConsentUpdate,
|
|
2994
|
+
execute: async () => {
|
|
2995
|
+
const mergedAttrs = integration.attrs ? { ...integration.attrs } : {};
|
|
2356
2996
|
const scriptNonce = integration.nonce ?? nonce;
|
|
2357
2997
|
if (scriptNonce && !mergedAttrs.nonce) mergedAttrs.nonce = scriptNonce;
|
|
2358
2998
|
await loadScript(
|
|
@@ -2360,26 +3000,54 @@ function ConsentScriptLoader({
|
|
|
2360
3000
|
integration.src,
|
|
2361
3001
|
integration.category,
|
|
2362
3002
|
mergedAttrs,
|
|
2363
|
-
scriptNonce
|
|
3003
|
+
scriptNonce,
|
|
3004
|
+
{ skipConsentCheck: true }
|
|
2364
3005
|
);
|
|
2365
3006
|
if (integration.init) {
|
|
2366
3007
|
integration.init();
|
|
2367
3008
|
}
|
|
2368
|
-
loadedScripts.current.add(integration.id);
|
|
2369
|
-
} catch (error) {
|
|
2370
|
-
logger.error(`\u274C Failed to load script: ${integration.id}`, error);
|
|
2371
3009
|
}
|
|
3010
|
+
})
|
|
3011
|
+
);
|
|
3012
|
+
});
|
|
3013
|
+
processedIntegrationsRef.current.forEach((_, id) => {
|
|
3014
|
+
if (!currentIds.has(id)) {
|
|
3015
|
+
processedIntegrationsRef.current.delete(id);
|
|
3016
|
+
const script = scriptRegistry.get(id);
|
|
3017
|
+
if (script) {
|
|
3018
|
+
scriptRegistry.delete(id);
|
|
3019
|
+
}
|
|
3020
|
+
const bootstrapScript = scriptRegistry.get(`${id}__bootstrap`);
|
|
3021
|
+
if (bootstrapScript) {
|
|
3022
|
+
scriptRegistry.delete(`${id}__bootstrap`);
|
|
2372
3023
|
}
|
|
2373
3024
|
}
|
|
2374
|
-
}
|
|
2375
|
-
return () =>
|
|
2376
|
-
}, [
|
|
3025
|
+
});
|
|
3026
|
+
return () => cleanups.forEach((fn) => fn());
|
|
3027
|
+
}, [integrations, reloadOnChange, nonce]);
|
|
3028
|
+
React4.useEffect(() => {
|
|
3029
|
+
if (!isHydrated) return;
|
|
3030
|
+
void processQueue({ consented, preferences }, process.env.NODE_ENV !== "production");
|
|
3031
|
+
}, [consented, preferences, isHydrated, queueVersion]);
|
|
3032
|
+
React4.useEffect(() => {
|
|
3033
|
+
if (!isHydrated) return;
|
|
3034
|
+
scriptRegistry.forEach((script) => {
|
|
3035
|
+
if (script.status !== "executed") return;
|
|
3036
|
+
if (typeof script.onConsentUpdate !== "function") return;
|
|
3037
|
+
script.onConsentUpdate({ consented, preferences });
|
|
3038
|
+
});
|
|
3039
|
+
}, [consented, preferences, isHydrated]);
|
|
2377
3040
|
return null;
|
|
2378
3041
|
}
|
|
2379
3042
|
function useConsentScriptLoader() {
|
|
2380
3043
|
const { preferences, consented } = useConsent();
|
|
3044
|
+
const isHydrated = useConsentHydration();
|
|
2381
3045
|
return React4.useCallback(
|
|
2382
3046
|
async (integration, nonce) => {
|
|
3047
|
+
if (!isHydrated) {
|
|
3048
|
+
logger.warn(`\u26A0\uFE0F Cannot load script ${integration.id}: Consent not hydrated yet`);
|
|
3049
|
+
return false;
|
|
3050
|
+
}
|
|
2383
3051
|
if (!consented) {
|
|
2384
3052
|
logger.warn(`\u26A0\uFE0F Cannot load script ${integration.id}: No consent given`);
|
|
2385
3053
|
return false;
|
|
@@ -2400,7 +3068,11 @@ function useConsentScriptLoader() {
|
|
|
2400
3068
|
integration.src,
|
|
2401
3069
|
integration.category,
|
|
2402
3070
|
mergedAttrs,
|
|
2403
|
-
scriptNonce
|
|
3071
|
+
scriptNonce,
|
|
3072
|
+
{
|
|
3073
|
+
consentSnapshot: { consented, preferences },
|
|
3074
|
+
skipConsentCheck: true
|
|
3075
|
+
}
|
|
2404
3076
|
);
|
|
2405
3077
|
if (integration.init) {
|
|
2406
3078
|
integration.init();
|
|
@@ -2411,16 +3083,129 @@ function useConsentScriptLoader() {
|
|
|
2411
3083
|
return false;
|
|
2412
3084
|
}
|
|
2413
3085
|
},
|
|
2414
|
-
[preferences, consented]
|
|
3086
|
+
[preferences, consented, isHydrated]
|
|
2415
3087
|
);
|
|
2416
3088
|
}
|
|
2417
3089
|
|
|
2418
3090
|
// src/utils/scriptIntegrations.ts
|
|
3091
|
+
function createSuggestedIntegration(config) {
|
|
3092
|
+
const suggested = suggestCategoryForScript(config.id)[0] ?? "analytics";
|
|
3093
|
+
const category = resolveCategory(suggested, config.category);
|
|
3094
|
+
const { category: _ignored, ...rest } = config;
|
|
3095
|
+
return { ...rest, category };
|
|
3096
|
+
}
|
|
3097
|
+
var resolveCategory = (fallback, override) => {
|
|
3098
|
+
if (typeof override === "string" && override.trim().length > 0) return override.trim();
|
|
3099
|
+
return fallback;
|
|
3100
|
+
};
|
|
3101
|
+
var isDevEnv = () => {
|
|
3102
|
+
const env = typeof globalThis !== "undefined" ? globalThis.process?.env?.NODE_ENV : void 0;
|
|
3103
|
+
return env !== "production";
|
|
3104
|
+
};
|
|
3105
|
+
var resolveRequiredString = (value, field, integrationId) => {
|
|
3106
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
3107
|
+
if (isDevEnv()) {
|
|
3108
|
+
console.error(
|
|
3109
|
+
`[LGPD-CONSENT] Config inv\xE1lida: integra\xE7\xE3o "${integrationId}" requer "${field}".`
|
|
3110
|
+
);
|
|
3111
|
+
}
|
|
3112
|
+
return null;
|
|
3113
|
+
}
|
|
3114
|
+
return value.trim();
|
|
3115
|
+
};
|
|
3116
|
+
function buildConsentModeSignals(preferences) {
|
|
3117
|
+
const analytics = preferences.analytics ? "granted" : "denied";
|
|
3118
|
+
const marketing = preferences.marketing ? "granted" : "denied";
|
|
3119
|
+
return {
|
|
3120
|
+
ad_storage: marketing,
|
|
3121
|
+
ad_user_data: marketing,
|
|
3122
|
+
ad_personalization: marketing,
|
|
3123
|
+
analytics_storage: analytics
|
|
3124
|
+
};
|
|
3125
|
+
}
|
|
3126
|
+
function pushToLayer(entry, dataLayerName) {
|
|
3127
|
+
const currentWindow = globalThis.window;
|
|
3128
|
+
if (currentWindow === void 0) return;
|
|
3129
|
+
const registry = currentWindow;
|
|
3130
|
+
const name = dataLayerName ?? "dataLayer";
|
|
3131
|
+
const layer = registry[name] ?? [];
|
|
3132
|
+
registry[name] = layer;
|
|
3133
|
+
layer.push(entry);
|
|
3134
|
+
}
|
|
3135
|
+
function ensureGtag(dataLayerName = "dataLayer") {
|
|
3136
|
+
const currentWindow = globalThis.window;
|
|
3137
|
+
if (currentWindow === void 0) return null;
|
|
3138
|
+
const w = currentWindow;
|
|
3139
|
+
const registry = w;
|
|
3140
|
+
const layer = registry[dataLayerName] ?? [];
|
|
3141
|
+
registry[dataLayerName] = layer;
|
|
3142
|
+
if (typeof w.gtag !== "function") {
|
|
3143
|
+
const gtag = (...args) => {
|
|
3144
|
+
layer.push(args);
|
|
3145
|
+
};
|
|
3146
|
+
w.gtag = gtag;
|
|
3147
|
+
}
|
|
3148
|
+
return w.gtag;
|
|
3149
|
+
}
|
|
3150
|
+
function applyDefaultConsentMode(dataLayerName) {
|
|
3151
|
+
const payload = buildConsentModeSignals({
|
|
3152
|
+
analytics: false,
|
|
3153
|
+
marketing: false
|
|
3154
|
+
});
|
|
3155
|
+
const gtag = ensureGtag(dataLayerName);
|
|
3156
|
+
if (gtag) {
|
|
3157
|
+
gtag("consent", "default", payload);
|
|
3158
|
+
}
|
|
3159
|
+
pushToLayer(["consent", "default", payload], dataLayerName);
|
|
3160
|
+
}
|
|
3161
|
+
function applyConsentModeUpdate(preferences, dataLayerName) {
|
|
3162
|
+
const payload = buildConsentModeSignals(preferences);
|
|
3163
|
+
const gtag = ensureGtag(dataLayerName);
|
|
3164
|
+
if (gtag) {
|
|
3165
|
+
gtag("consent", "update", payload);
|
|
3166
|
+
}
|
|
3167
|
+
pushToLayer(["consent", "update", payload], dataLayerName);
|
|
3168
|
+
}
|
|
2419
3169
|
function createGoogleAnalyticsIntegration(config) {
|
|
2420
|
-
const
|
|
3170
|
+
const category = resolveCategory("analytics", config.category);
|
|
3171
|
+
const measurementId = resolveRequiredString(
|
|
3172
|
+
config.measurementId,
|
|
3173
|
+
"measurementId",
|
|
3174
|
+
"google-analytics"
|
|
3175
|
+
);
|
|
3176
|
+
if (!measurementId) {
|
|
3177
|
+
return {
|
|
3178
|
+
id: "google-analytics",
|
|
3179
|
+
category,
|
|
3180
|
+
src: "",
|
|
3181
|
+
cookies: ["_ga", "_ga_*", "_gid"],
|
|
3182
|
+
cookiesInfo: [
|
|
3183
|
+
{
|
|
3184
|
+
name: "_ga",
|
|
3185
|
+
purpose: "Identifica\xE7\xE3o \xFAnica de visitantes para an\xE1lise de tr\xE1fego",
|
|
3186
|
+
duration: "2 anos",
|
|
3187
|
+
provider: "Google Analytics"
|
|
3188
|
+
},
|
|
3189
|
+
{
|
|
3190
|
+
name: "_ga_*",
|
|
3191
|
+
purpose: "Rastreamento de sess\xF5es e eventos espec\xEDficos do stream GA4",
|
|
3192
|
+
duration: "2 anos",
|
|
3193
|
+
provider: "Google Analytics"
|
|
3194
|
+
},
|
|
3195
|
+
{
|
|
3196
|
+
name: "_gid",
|
|
3197
|
+
purpose: "Distin\xE7\xE3o de visitantes \xFAnicos em per\xEDodo de 24h",
|
|
3198
|
+
duration: "24 horas",
|
|
3199
|
+
provider: "Google Analytics"
|
|
3200
|
+
}
|
|
3201
|
+
],
|
|
3202
|
+
attrs: { async: "true" }
|
|
3203
|
+
};
|
|
3204
|
+
}
|
|
3205
|
+
const src = config.scriptUrl ?? `https://www.googletagmanager.com/gtag/js?id=${measurementId}`;
|
|
2421
3206
|
return {
|
|
2422
3207
|
id: "google-analytics",
|
|
2423
|
-
category
|
|
3208
|
+
category,
|
|
2424
3209
|
src,
|
|
2425
3210
|
cookies: ["_ga", "_ga_*", "_gid"],
|
|
2426
3211
|
cookiesInfo: [
|
|
@@ -2443,32 +3228,49 @@ function createGoogleAnalyticsIntegration(config) {
|
|
|
2443
3228
|
provider: "Google Analytics"
|
|
2444
3229
|
}
|
|
2445
3230
|
],
|
|
3231
|
+
bootstrap: () => {
|
|
3232
|
+
applyDefaultConsentMode();
|
|
3233
|
+
},
|
|
3234
|
+
onConsentUpdate: ({ preferences }) => {
|
|
3235
|
+
applyConsentModeUpdate(preferences);
|
|
3236
|
+
},
|
|
2446
3237
|
init: () => {
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
w.dataLayer.push(...args);
|
|
2452
|
-
};
|
|
2453
|
-
w.gtag = gtag;
|
|
2454
|
-
gtag("js", /* @__PURE__ */ new Date());
|
|
2455
|
-
gtag("config", config.measurementId, config.config ?? {});
|
|
2456
|
-
}
|
|
3238
|
+
const gtag = ensureGtag();
|
|
3239
|
+
if (!gtag) return;
|
|
3240
|
+
gtag("js", /* @__PURE__ */ new Date());
|
|
3241
|
+
gtag("config", measurementId, config.config ?? {});
|
|
2457
3242
|
},
|
|
2458
3243
|
attrs: { async: "true" }
|
|
2459
3244
|
};
|
|
2460
3245
|
}
|
|
2461
3246
|
function createGoogleTagManagerIntegration(config) {
|
|
2462
|
-
const
|
|
3247
|
+
const category = resolveCategory("analytics", config.category);
|
|
3248
|
+
const containerId = resolveRequiredString(config.containerId, "containerId", "google-tag-manager");
|
|
3249
|
+
if (!containerId) {
|
|
3250
|
+
return {
|
|
3251
|
+
id: "google-tag-manager",
|
|
3252
|
+
category,
|
|
3253
|
+
src: "",
|
|
3254
|
+
cookies: ["_gcl_au"]
|
|
3255
|
+
};
|
|
3256
|
+
}
|
|
3257
|
+
const src = config.scriptUrl ?? `https://www.googletagmanager.com/gtm.js?id=${containerId}`;
|
|
2463
3258
|
return {
|
|
2464
3259
|
id: "google-tag-manager",
|
|
2465
|
-
category
|
|
3260
|
+
category,
|
|
2466
3261
|
src,
|
|
2467
3262
|
cookies: ["_gcl_au"],
|
|
3263
|
+
bootstrap: () => {
|
|
3264
|
+
applyDefaultConsentMode(config.dataLayerName);
|
|
3265
|
+
},
|
|
3266
|
+
onConsentUpdate: ({ preferences }) => {
|
|
3267
|
+
applyConsentModeUpdate(preferences, config.dataLayerName);
|
|
3268
|
+
},
|
|
2468
3269
|
init: () => {
|
|
2469
|
-
|
|
3270
|
+
const currentWindow = globalThis.window;
|
|
3271
|
+
if (currentWindow !== void 0) {
|
|
2470
3272
|
const dataLayerName = config.dataLayerName || "dataLayer";
|
|
2471
|
-
const w =
|
|
3273
|
+
const w = currentWindow;
|
|
2472
3274
|
const layer = w[dataLayerName] ?? [];
|
|
2473
3275
|
w[dataLayerName] = layer;
|
|
2474
3276
|
layer.push({ "gtm.start": Date.now(), event: "gtm.js" });
|
|
@@ -2477,20 +3279,31 @@ function createGoogleTagManagerIntegration(config) {
|
|
|
2477
3279
|
};
|
|
2478
3280
|
}
|
|
2479
3281
|
function createUserWayIntegration(config) {
|
|
3282
|
+
const category = resolveCategory("functional", config.category);
|
|
3283
|
+
const accountId = resolveRequiredString(config.accountId, "accountId", "userway");
|
|
3284
|
+
if (!accountId) {
|
|
3285
|
+
return {
|
|
3286
|
+
id: "userway",
|
|
3287
|
+
category,
|
|
3288
|
+
src: "",
|
|
3289
|
+
cookies: ["_userway_*"]
|
|
3290
|
+
};
|
|
3291
|
+
}
|
|
2480
3292
|
const src = config.scriptUrl ?? "https://cdn.userway.org/widget.js";
|
|
2481
3293
|
return {
|
|
2482
3294
|
id: "userway",
|
|
2483
|
-
category
|
|
3295
|
+
category,
|
|
2484
3296
|
src,
|
|
2485
3297
|
cookies: ["_userway_*"],
|
|
2486
3298
|
init: () => {
|
|
2487
|
-
|
|
2488
|
-
|
|
3299
|
+
const currentWindow = globalThis.window;
|
|
3300
|
+
if (currentWindow !== void 0) {
|
|
3301
|
+
const w = currentWindow;
|
|
2489
3302
|
w.UserWayWidgetApp = w.UserWayWidgetApp || {};
|
|
2490
|
-
w.UserWayWidgetApp.accountId =
|
|
3303
|
+
w.UserWayWidgetApp.accountId = accountId;
|
|
2491
3304
|
}
|
|
2492
3305
|
},
|
|
2493
|
-
attrs: { "data-account":
|
|
3306
|
+
attrs: { "data-account": accountId }
|
|
2494
3307
|
};
|
|
2495
3308
|
}
|
|
2496
3309
|
var COMMON_INTEGRATIONS = {
|
|
@@ -2499,15 +3312,26 @@ var COMMON_INTEGRATIONS = {
|
|
|
2499
3312
|
userway: createUserWayIntegration
|
|
2500
3313
|
};
|
|
2501
3314
|
function createFacebookPixelIntegration(config) {
|
|
3315
|
+
const category = resolveCategory("marketing", config.category);
|
|
3316
|
+
const pixelId = resolveRequiredString(config.pixelId, "pixelId", "facebook-pixel");
|
|
3317
|
+
if (!pixelId) {
|
|
3318
|
+
return {
|
|
3319
|
+
id: "facebook-pixel",
|
|
3320
|
+
category,
|
|
3321
|
+
src: "",
|
|
3322
|
+
cookies: ["_fbp", "fr"]
|
|
3323
|
+
};
|
|
3324
|
+
}
|
|
2502
3325
|
const src = config.scriptUrl ?? "https://connect.facebook.net/en_US/fbevents.js";
|
|
2503
3326
|
return {
|
|
2504
3327
|
id: "facebook-pixel",
|
|
2505
|
-
category
|
|
3328
|
+
category,
|
|
2506
3329
|
src,
|
|
2507
3330
|
cookies: ["_fbp", "fr"],
|
|
2508
3331
|
init: () => {
|
|
2509
|
-
|
|
2510
|
-
|
|
3332
|
+
const currentWindow = globalThis.window;
|
|
3333
|
+
if (currentWindow !== void 0) {
|
|
3334
|
+
const w = currentWindow;
|
|
2511
3335
|
if (!w.fbq) {
|
|
2512
3336
|
const fbq = (...args) => {
|
|
2513
3337
|
if (w.fbq && typeof w.fbq.callMethod === "function") {
|
|
@@ -2520,18 +3344,34 @@ function createFacebookPixelIntegration(config) {
|
|
|
2520
3344
|
fbq.loaded = true;
|
|
2521
3345
|
w.fbq = fbq;
|
|
2522
3346
|
}
|
|
2523
|
-
w.fbq("init",
|
|
3347
|
+
w.fbq("init", pixelId, config.advancedMatching ?? {});
|
|
2524
3348
|
if (config.autoTrack !== false) w.fbq("track", "PageView");
|
|
2525
3349
|
}
|
|
2526
3350
|
}
|
|
2527
3351
|
};
|
|
2528
3352
|
}
|
|
2529
3353
|
function createHotjarIntegration(config) {
|
|
3354
|
+
const category = resolveCategory("analytics", config.category);
|
|
3355
|
+
const siteId = resolveRequiredString(config.siteId, "siteId", "hotjar");
|
|
2530
3356
|
const v = config.version ?? 6;
|
|
2531
|
-
|
|
3357
|
+
if (!siteId) {
|
|
3358
|
+
return {
|
|
3359
|
+
id: "hotjar",
|
|
3360
|
+
category,
|
|
3361
|
+
src: "",
|
|
3362
|
+
cookies: [
|
|
3363
|
+
"_hjSession_*",
|
|
3364
|
+
"_hjSessionUser_*",
|
|
3365
|
+
"_hjFirstSeen",
|
|
3366
|
+
"_hjIncludedInSessionSample",
|
|
3367
|
+
"_hjAbsoluteSessionInProgress"
|
|
3368
|
+
]
|
|
3369
|
+
};
|
|
3370
|
+
}
|
|
3371
|
+
const src = config.scriptUrl ?? `https://static.hotjar.com/c/hotjar-${siteId}.js?sv=${v}`;
|
|
2532
3372
|
return {
|
|
2533
3373
|
id: "hotjar",
|
|
2534
|
-
category
|
|
3374
|
+
category,
|
|
2535
3375
|
src,
|
|
2536
3376
|
cookies: [
|
|
2537
3377
|
"_hjSession_*",
|
|
@@ -2573,9 +3413,10 @@ function createHotjarIntegration(config) {
|
|
|
2573
3413
|
}
|
|
2574
3414
|
],
|
|
2575
3415
|
init: () => {
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
w
|
|
3416
|
+
const currentWindow = globalThis.window;
|
|
3417
|
+
if (currentWindow !== void 0) {
|
|
3418
|
+
const w = currentWindow;
|
|
3419
|
+
w._hjSettings = { hjid: siteId, hjsv: v };
|
|
2579
3420
|
if (!w.hj) {
|
|
2580
3421
|
const hj = (...args) => {
|
|
2581
3422
|
hj.q = hj.q || [];
|
|
@@ -2584,17 +3425,35 @@ function createHotjarIntegration(config) {
|
|
|
2584
3425
|
w.hj = hj;
|
|
2585
3426
|
}
|
|
2586
3427
|
if (config.debug && typeof console !== "undefined" && typeof console.info === "function") {
|
|
2587
|
-
console.info("[Hotjar] initialized with siteId",
|
|
3428
|
+
console.info("[Hotjar] initialized with siteId", siteId);
|
|
2588
3429
|
}
|
|
2589
3430
|
}
|
|
2590
3431
|
}
|
|
2591
3432
|
};
|
|
2592
3433
|
}
|
|
2593
3434
|
function createMixpanelIntegration(config) {
|
|
3435
|
+
const category = resolveCategory("analytics", config.category);
|
|
3436
|
+
const token = resolveRequiredString(config.token, "token", "mixpanel");
|
|
3437
|
+
if (!token) {
|
|
3438
|
+
return {
|
|
3439
|
+
id: "mixpanel",
|
|
3440
|
+
category,
|
|
3441
|
+
src: "",
|
|
3442
|
+
cookies: ["mp_*"],
|
|
3443
|
+
cookiesInfo: [
|
|
3444
|
+
{
|
|
3445
|
+
name: "mp_*",
|
|
3446
|
+
purpose: "Rastreamento de eventos e propriedades do usu\xE1rio para analytics",
|
|
3447
|
+
duration: "1 ano",
|
|
3448
|
+
provider: "Mixpanel"
|
|
3449
|
+
}
|
|
3450
|
+
]
|
|
3451
|
+
};
|
|
3452
|
+
}
|
|
2594
3453
|
const src = config.scriptUrl ?? "https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";
|
|
2595
3454
|
return {
|
|
2596
3455
|
id: "mixpanel",
|
|
2597
|
-
category
|
|
3456
|
+
category,
|
|
2598
3457
|
src,
|
|
2599
3458
|
cookies: ["mp_*"],
|
|
2600
3459
|
cookiesInfo: [
|
|
@@ -2606,12 +3465,13 @@ function createMixpanelIntegration(config) {
|
|
|
2606
3465
|
}
|
|
2607
3466
|
],
|
|
2608
3467
|
init: () => {
|
|
2609
|
-
|
|
2610
|
-
|
|
3468
|
+
const currentWindow = globalThis.window;
|
|
3469
|
+
if (currentWindow !== void 0) {
|
|
3470
|
+
const w = currentWindow;
|
|
2611
3471
|
w.mixpanel = w.mixpanel || { init: () => void 0 };
|
|
2612
3472
|
if (w.mixpanel && typeof w.mixpanel.init === "function") {
|
|
2613
3473
|
try {
|
|
2614
|
-
w.mixpanel.init(
|
|
3474
|
+
w.mixpanel.init(token, config.config ?? {}, config.api_host);
|
|
2615
3475
|
} catch (error) {
|
|
2616
3476
|
if (typeof console !== "undefined" && typeof console.warn === "function") {
|
|
2617
3477
|
console.warn("[Mixpanel] Failed to initialize:", error);
|
|
@@ -2623,15 +3483,26 @@ function createMixpanelIntegration(config) {
|
|
|
2623
3483
|
};
|
|
2624
3484
|
}
|
|
2625
3485
|
function createClarityIntegration(config) {
|
|
2626
|
-
const
|
|
3486
|
+
const category = resolveCategory("analytics", config.category);
|
|
3487
|
+
const projectId = resolveRequiredString(config.projectId, "projectId", "clarity");
|
|
3488
|
+
if (!projectId) {
|
|
3489
|
+
return {
|
|
3490
|
+
id: "clarity",
|
|
3491
|
+
category,
|
|
3492
|
+
src: "",
|
|
3493
|
+
cookies: ["_clck", "_clsk", "CLID", "ANONCHK", "MR", "MUID", "SM"]
|
|
3494
|
+
};
|
|
3495
|
+
}
|
|
3496
|
+
const src = config.scriptUrl ?? `https://www.clarity.ms/tag/${projectId}`;
|
|
2627
3497
|
return {
|
|
2628
3498
|
id: "clarity",
|
|
2629
|
-
category
|
|
3499
|
+
category,
|
|
2630
3500
|
src,
|
|
2631
3501
|
cookies: ["_clck", "_clsk", "CLID", "ANONCHK", "MR", "MUID", "SM"],
|
|
2632
3502
|
init: () => {
|
|
2633
|
-
|
|
2634
|
-
|
|
3503
|
+
const currentWindow = globalThis.window;
|
|
3504
|
+
if (currentWindow !== void 0 && typeof config.upload !== "undefined") {
|
|
3505
|
+
const w = currentWindow;
|
|
2635
3506
|
if (typeof w.clarity === "function") {
|
|
2636
3507
|
try {
|
|
2637
3508
|
w.clarity("set", "upload", config.upload);
|
|
@@ -2646,18 +3517,29 @@ function createClarityIntegration(config) {
|
|
|
2646
3517
|
};
|
|
2647
3518
|
}
|
|
2648
3519
|
function createIntercomIntegration(config) {
|
|
2649
|
-
const
|
|
3520
|
+
const category = resolveCategory("functional", config.category);
|
|
3521
|
+
const appId = resolveRequiredString(config.app_id, "app_id", "intercom");
|
|
3522
|
+
if (!appId) {
|
|
3523
|
+
return {
|
|
3524
|
+
id: "intercom",
|
|
3525
|
+
category,
|
|
3526
|
+
src: "",
|
|
3527
|
+
cookies: ["intercom-id-*", "intercom-session-*"]
|
|
3528
|
+
};
|
|
3529
|
+
}
|
|
3530
|
+
const src = config.scriptUrl ?? `https://widget.intercom.io/widget/${appId}`;
|
|
2650
3531
|
return {
|
|
2651
3532
|
id: "intercom",
|
|
2652
|
-
category
|
|
3533
|
+
category,
|
|
2653
3534
|
src,
|
|
2654
3535
|
cookies: ["intercom-id-*", "intercom-session-*"],
|
|
2655
3536
|
init: () => {
|
|
2656
|
-
|
|
2657
|
-
|
|
3537
|
+
const currentWindow = globalThis.window;
|
|
3538
|
+
if (currentWindow !== void 0) {
|
|
3539
|
+
const w = currentWindow;
|
|
2658
3540
|
if (typeof w.Intercom === "function") {
|
|
2659
3541
|
try {
|
|
2660
|
-
w.Intercom("boot", { app_id:
|
|
3542
|
+
w.Intercom("boot", { app_id: appId });
|
|
2661
3543
|
} catch (error) {
|
|
2662
3544
|
if (typeof console !== "undefined" && typeof console.warn === "function") {
|
|
2663
3545
|
console.warn("[Intercom] Failed to boot:", error);
|
|
@@ -2669,18 +3551,29 @@ function createIntercomIntegration(config) {
|
|
|
2669
3551
|
};
|
|
2670
3552
|
}
|
|
2671
3553
|
function createZendeskChatIntegration(config) {
|
|
2672
|
-
const
|
|
3554
|
+
const category = resolveCategory("functional", config.category);
|
|
3555
|
+
const key = resolveRequiredString(config.key, "key", "zendesk-chat");
|
|
3556
|
+
if (!key) {
|
|
3557
|
+
return {
|
|
3558
|
+
id: "zendesk-chat",
|
|
3559
|
+
category,
|
|
3560
|
+
src: "",
|
|
3561
|
+
cookies: ["__zlcmid", "_zendesk_shared_session"]
|
|
3562
|
+
};
|
|
3563
|
+
}
|
|
3564
|
+
const src = config.scriptUrl ?? `https://static.zdassets.com/ekr/snippet.js?key=${key}`;
|
|
2673
3565
|
return {
|
|
2674
3566
|
id: "zendesk-chat",
|
|
2675
|
-
category
|
|
3567
|
+
category,
|
|
2676
3568
|
src,
|
|
2677
3569
|
cookies: ["__zlcmid", "_zendesk_shared_session"],
|
|
2678
3570
|
init: () => {
|
|
2679
|
-
|
|
2680
|
-
|
|
3571
|
+
const currentWindow = globalThis.window;
|
|
3572
|
+
if (currentWindow !== void 0) {
|
|
3573
|
+
const w = currentWindow;
|
|
2681
3574
|
if (typeof w.zE === "function") {
|
|
2682
3575
|
try {
|
|
2683
|
-
w.zE("webWidget", "identify", { key
|
|
3576
|
+
w.zE("webWidget", "identify", { key });
|
|
2684
3577
|
} catch (error) {
|
|
2685
3578
|
if (typeof console !== "undefined" && typeof console.warn === "function") {
|
|
2686
3579
|
console.warn("[Zendesk] Failed to identify:", error);
|
|
@@ -2802,215 +3695,4 @@ function createAnpdCategoriesConfig(options = {}) {
|
|
|
2802
3695
|
};
|
|
2803
3696
|
}
|
|
2804
3697
|
|
|
2805
|
-
|
|
2806
|
-
var EXPANDED_DEFAULT_TEXTS = {
|
|
2807
|
-
// Textos adicionais
|
|
2808
|
-
confirm: "Confirmar",
|
|
2809
|
-
cancel: "Cancelar",
|
|
2810
|
-
loading: "Carregando...",
|
|
2811
|
-
// Feedback
|
|
2812
|
-
feedback: {
|
|
2813
|
-
saveSuccess: "Prefer\xEAncias salvas com sucesso!",
|
|
2814
|
-
saveError: "Erro ao salvar prefer\xEAncias. Tente novamente.",
|
|
2815
|
-
consentUpdated: "Consentimento atualizado.",
|
|
2816
|
-
cookiesRejected: "Cookies opcionais rejeitados.",
|
|
2817
|
-
settingsReset: "Configura\xE7\xF5es resetadas."
|
|
2818
|
-
},
|
|
2819
|
-
// Acessibilidade
|
|
2820
|
-
accessibility: {
|
|
2821
|
-
bannerLabel: "Banner de consentimento de cookies",
|
|
2822
|
-
modalLabel: "Modal de prefer\xEAncias de cookies",
|
|
2823
|
-
keyboardNavigation: "Use Tab para navegar, Enter para selecionar",
|
|
2824
|
-
toggleState: {
|
|
2825
|
-
enabled: "Habilitado",
|
|
2826
|
-
disabled: "Desabilitado"
|
|
2827
|
-
},
|
|
2828
|
-
liveRegion: "Regi\xE3o de an\xFAncios din\xE2micos"
|
|
2829
|
-
},
|
|
2830
|
-
// Categorias
|
|
2831
|
-
categories: {
|
|
2832
|
-
necessary: {
|
|
2833
|
-
name: "Cookies Necess\xE1rios",
|
|
2834
|
-
description: "Essenciais para o funcionamento b\xE1sico do site",
|
|
2835
|
-
examples: "Sess\xE3o, seguran\xE7a, prefer\xEAncias de idioma"
|
|
2836
|
-
},
|
|
2837
|
-
analytics: {
|
|
2838
|
-
name: "Cookies de Analytics",
|
|
2839
|
-
description: "Ajudam a entender como os visitantes usam o site",
|
|
2840
|
-
examples: "Google Analytics, contadores de p\xE1gina"
|
|
2841
|
-
},
|
|
2842
|
-
marketing: {
|
|
2843
|
-
name: "Cookies de Marketing",
|
|
2844
|
-
description: "Usados para personalizar an\xFAncios e ofertas",
|
|
2845
|
-
examples: "Facebook Pixel, Google Ads, remarketing"
|
|
2846
|
-
},
|
|
2847
|
-
functional: {
|
|
2848
|
-
name: "Cookies Funcionais",
|
|
2849
|
-
description: "Melhoram a funcionalidade e personaliza\xE7\xE3o",
|
|
2850
|
-
examples: "Chat, mapas, v\xEDdeos embarcados"
|
|
2851
|
-
},
|
|
2852
|
-
performance: {
|
|
2853
|
-
name: "Cookies de Performance",
|
|
2854
|
-
description: "Coletam informa\xE7\xF5es sobre velocidade e estabilidade",
|
|
2855
|
-
examples: "Monitoramento de erro, otimiza\xE7\xE3o de velocidade"
|
|
2856
|
-
}
|
|
2857
|
-
},
|
|
2858
|
-
// Contextos específicos
|
|
2859
|
-
contexts: {
|
|
2860
|
-
ecommerce: {
|
|
2861
|
-
cartAbandonment: "Lembramos dos produtos no seu carrinho",
|
|
2862
|
-
personalizedOffers: "Ofertas personalizadas baseadas no seu hist\xF3rico",
|
|
2863
|
-
paymentSecurity: "Seguran\xE7a adicional no processo de pagamento",
|
|
2864
|
-
productRecommendations: "Sugest\xF5es de produtos relevantes"
|
|
2865
|
-
},
|
|
2866
|
-
saas: {
|
|
2867
|
-
userAnalytics: "An\xE1lise de uso para melhorar funcionalidades",
|
|
2868
|
-
performanceMonitoring: "Monitoramento de performance da aplica\xE7\xE3o",
|
|
2869
|
-
featureUsage: "Estat\xEDsticas de uso de recursos",
|
|
2870
|
-
customerSupport: "Suporte ao cliente mais eficiente"
|
|
2871
|
-
},
|
|
2872
|
-
government: {
|
|
2873
|
-
citizenServices: "Melhoria dos servi\xE7os ao cidad\xE3o",
|
|
2874
|
-
dataProtection: "Prote\xE7\xE3o rigorosa dos dados pessoais",
|
|
2875
|
-
transparency: "Transpar\xEAncia no uso de dados",
|
|
2876
|
-
accessibility: "Recursos de acessibilidade digital"
|
|
2877
|
-
},
|
|
2878
|
-
education: {
|
|
2879
|
-
studentProgress: "Acompanhamento do progresso educacional",
|
|
2880
|
-
learningAnalytics: "Analytics para melhorar o aprendizado",
|
|
2881
|
-
accessibility: "Recursos educacionais acess\xEDveis",
|
|
2882
|
-
parentalConsent: "Consentimento parental quando necess\xE1rio"
|
|
2883
|
-
}
|
|
2884
|
-
},
|
|
2885
|
-
// Variações de tom
|
|
2886
|
-
variants: {
|
|
2887
|
-
formal: {
|
|
2888
|
-
bannerMessage: "Este s\xEDtio eletr\xF4nico utiliza cookies para otimizar a experi\xEAncia de navega\xE7\xE3o.",
|
|
2889
|
-
acceptAll: "Concordar com todos os cookies",
|
|
2890
|
-
declineAll: "Recusar cookies opcionais",
|
|
2891
|
-
modalTitle: "Configura\xE7\xE3o de Cookies"
|
|
2892
|
-
},
|
|
2893
|
-
casual: {
|
|
2894
|
-
bannerMessage: "\u{1F36A} Ei! Usamos cookies para tornar sua experi\xEAncia ainda melhor!",
|
|
2895
|
-
acceptAll: "Aceitar tudo",
|
|
2896
|
-
declineAll: "S\xF3 o essencial",
|
|
2897
|
-
modalTitle: "Seus Cookies"
|
|
2898
|
-
},
|
|
2899
|
-
concise: {
|
|
2900
|
-
bannerMessage: "Usamos cookies. Voc\xEA aceita?",
|
|
2901
|
-
acceptAll: "Sim",
|
|
2902
|
-
declineAll: "N\xE3o",
|
|
2903
|
-
modalTitle: "Cookies"
|
|
2904
|
-
},
|
|
2905
|
-
detailed: {
|
|
2906
|
-
bannerMessage: "Utilizamos cookies e tecnologias similares para melhorar sua experi\xEAncia de navega\xE7\xE3o, personalizar conte\xFAdo, analisar tr\xE1fego e oferecer funcionalidades de redes sociais.",
|
|
2907
|
-
acceptAll: "Aceitar todos os cookies e tecnologias",
|
|
2908
|
-
declineAll: "Recusar todos os cookies opcionais",
|
|
2909
|
-
modalTitle: "Centro de Prefer\xEAncias de Privacidade"
|
|
2910
|
-
}
|
|
2911
|
-
},
|
|
2912
|
-
// Internacionalização simplificada (apenas textos básicos)
|
|
2913
|
-
i18n: {
|
|
2914
|
-
en: {
|
|
2915
|
-
bannerMessage: "We use cookies to enhance your experience.",
|
|
2916
|
-
acceptAll: "Accept All",
|
|
2917
|
-
declineAll: "Decline",
|
|
2918
|
-
preferences: "Preferences",
|
|
2919
|
-
modalTitle: "Cookie Preferences",
|
|
2920
|
-
modalIntro: "Customize your cookie preferences below.",
|
|
2921
|
-
save: "Save Preferences",
|
|
2922
|
-
necessaryAlwaysOn: "Necessary cookies (always active)"
|
|
2923
|
-
},
|
|
2924
|
-
es: {
|
|
2925
|
-
bannerMessage: "Utilizamos cookies para mejorar su experiencia.",
|
|
2926
|
-
acceptAll: "Aceptar Todo",
|
|
2927
|
-
declineAll: "Rechazar",
|
|
2928
|
-
preferences: "Preferencias",
|
|
2929
|
-
modalTitle: "Preferencias de Cookies",
|
|
2930
|
-
modalIntro: "Personalice sus preferencias de cookies a continuaci\xF3n.",
|
|
2931
|
-
save: "Guardar Preferencias",
|
|
2932
|
-
necessaryAlwaysOn: "Cookies necess\xE1rias (sempre ativas)"
|
|
2933
|
-
},
|
|
2934
|
-
fr: {
|
|
2935
|
-
bannerMessage: "Nous utilisons des cookies pour am\xE9liorer votre exp\xE9rience.",
|
|
2936
|
-
acceptAll: "Tout Accepter",
|
|
2937
|
-
declineAll: "Refuser",
|
|
2938
|
-
preferences: "Pr\xE9f\xE9rences",
|
|
2939
|
-
modalTitle: "Pr\xE9f\xE9rences des Cookies",
|
|
2940
|
-
modalIntro: "Personnalisez vos pr\xE9f\xE9rences de cookies ci-dessous.",
|
|
2941
|
-
save: "Enregistrer les Pr\xE9f\xE9rences",
|
|
2942
|
-
necessaryAlwaysOn: "Cookies n\xE9cessaires (toujours actifs)"
|
|
2943
|
-
}
|
|
2944
|
-
},
|
|
2945
|
-
// Textos técnicos
|
|
2946
|
-
technical: {
|
|
2947
|
-
sessionCookies: "Cookies de sess\xE3o s\xE3o tempor\xE1rios e expiram quando voc\xEA fecha o navegador.",
|
|
2948
|
-
persistentCookies: "Cookies persistentes permanecem no seu dispositivo at\xE9 expirarem ou serem removidos.",
|
|
2949
|
-
thirdPartyCookies: "Cookies de terceiros s\xE3o definidos por dom\xEDnios diferentes do site que voc\xEA est\xE1 visitando.",
|
|
2950
|
-
browserSettings: "Voc\xEA pode gerenciar cookies nas configura\xE7\xF5es do seu navegador.",
|
|
2951
|
-
disablingImpact: "Desabilitar cookies pode afetar a funcionalidade do site."
|
|
2952
|
-
},
|
|
2953
|
-
// Cookie details
|
|
2954
|
-
cookieDetails: {
|
|
2955
|
-
tableHeaders: {
|
|
2956
|
-
name: "Nome",
|
|
2957
|
-
purpose: "Finalidade",
|
|
2958
|
-
duration: "Dura\xE7\xE3o",
|
|
2959
|
-
provider: "Fornecedor",
|
|
2960
|
-
type: "Tipo"
|
|
2961
|
-
},
|
|
2962
|
-
noCookies: "Nenhum cookie encontrado para esta categoria.",
|
|
2963
|
-
toggleDetails: {
|
|
2964
|
-
expand: "Ver detalhes",
|
|
2965
|
-
collapse: "Ocultar detalhes"
|
|
2966
|
-
}
|
|
2967
|
-
}
|
|
2968
|
-
};
|
|
2969
|
-
function resolveTexts(texts, options = {}) {
|
|
2970
|
-
const { language = "pt", variant } = options;
|
|
2971
|
-
let resolved = { ...texts };
|
|
2972
|
-
if (variant && texts.variants?.[variant]) {
|
|
2973
|
-
resolved = { ...resolved, ...texts.variants[variant] };
|
|
2974
|
-
}
|
|
2975
|
-
if (language !== "pt" && texts.i18n?.[language]) {
|
|
2976
|
-
resolved = { ...resolved, ...texts.i18n[language] };
|
|
2977
|
-
}
|
|
2978
|
-
return resolved;
|
|
2979
|
-
}
|
|
2980
|
-
var TEXT_TEMPLATES = {
|
|
2981
|
-
ecommerce: {
|
|
2982
|
-
...EXPANDED_DEFAULT_TEXTS,
|
|
2983
|
-
bannerMessage: "Utilizamos cookies para personalizar ofertas e melhorar sua experi\xEAncia de compra.",
|
|
2984
|
-
acceptAll: "Aceitar e continuar",
|
|
2985
|
-
variants: {
|
|
2986
|
-
casual: {
|
|
2987
|
-
bannerMessage: "\u{1F6D2} Usamos cookies para encontrar as melhores ofertas para voc\xEA!",
|
|
2988
|
-
acceptAll: "Quero ofertas personalizadas!"
|
|
2989
|
-
}
|
|
2990
|
-
}
|
|
2991
|
-
},
|
|
2992
|
-
saas: {
|
|
2993
|
-
...EXPANDED_DEFAULT_TEXTS,
|
|
2994
|
-
bannerMessage: "Utilizamos cookies para otimizar o desempenho da aplica\xE7\xE3o e sua experi\xEAncia.",
|
|
2995
|
-
acceptAll: "Aceitar e otimizar",
|
|
2996
|
-
variants: {
|
|
2997
|
-
formal: {
|
|
2998
|
-
bannerMessage: "Esta aplica\xE7\xE3o utiliza cookies para an\xE1lise de performance e melhoria cont\xEDnua da experi\xEAncia do usu\xE1rio.",
|
|
2999
|
-
acceptAll: "Autorizar coleta de dados de uso"
|
|
3000
|
-
}
|
|
3001
|
-
}
|
|
3002
|
-
},
|
|
3003
|
-
government: {
|
|
3004
|
-
...EXPANDED_DEFAULT_TEXTS,
|
|
3005
|
-
bannerMessage: "Este portal utiliza cookies em conformidade com a LGPD para melhorar os servi\xE7os p\xFAblicos.",
|
|
3006
|
-
acceptAll: "Aceitar em conformidade",
|
|
3007
|
-
variants: {
|
|
3008
|
-
formal: {
|
|
3009
|
-
bannerMessage: "Este s\xEDtio eletr\xF4nico do governo utiliza cookies estritamente necess\xE1rios e opcionais, em conformidade com a Lei Geral de Prote\xE7\xE3o de Dados.",
|
|
3010
|
-
acceptAll: "Concordar com o uso de cookies"
|
|
3011
|
-
}
|
|
3012
|
-
}
|
|
3013
|
-
}
|
|
3014
|
-
};
|
|
3015
|
-
|
|
3016
|
-
export { ANPD_CATEGORY_PRESETS, COMMON_INTEGRATIONS, ConsentGate, ConsentProvider, ConsentScriptLoader, DEFAULT_PROJECT_CATEGORIES, DesignProvider, EXPANDED_DEFAULT_TEXTS, GUIDANCE_PRESETS, INTEGRATION_TEMPLATES, LogLevel, TEXT_TEMPLATES, analyzeDeveloperConfiguration, analyzeIntegrationCategories, autoConfigureCategories, buildConsentStorageKey, categorizeDiscoveredCookies, checkPeerDeps, createAnpdCategoriesConfig, createClarityIntegration, createConsentAuditEntry, createCorporateIntegrations, createECommerceIntegrations, createFacebookPixelIntegration, createGoogleAnalyticsIntegration, createGoogleTagManagerIntegration, createHotjarIntegration, createIntercomIntegration, createMixpanelIntegration, createProjectPreferences, createSaaSIntegrations, createUserWayIntegration, createZendeskChatIntegration, defaultTexts, detectConsentCookieName, discoverRuntimeCookies, ensureNecessaryAlwaysOn, extractCategoriesFromIntegrations, getAllProjectCategories, getCookiesInfoForCategory, loadScript, logDeveloperGuidance, logger, openPreferencesModal, pushConsentInitializedEvent, pushConsentUpdatedEvent, resolveTexts, runPeerDepsCheck, setCookieCatalogOverrides, setCookieCategoryOverrides, setDebugLogging, suggestCategoryForScript, useCategories, useCategoryStatus, useConsent, useConsentHydration, useConsentScriptLoader, useConsentTexts, useDataLayerEvents, useDesignTokens, useDeveloperGuidance, useOpenPreferencesModal, validateIntegrationCategories, validateNecessaryClassification, validateProjectPreferences };
|
|
3698
|
+
export { ANPD_CATEGORY_PRESETS, COMMON_INTEGRATIONS, ConsentGate, ConsentProvider, ConsentScriptLoader, DEFAULT_PROJECT_CATEGORIES, DesignProvider, EXPANDED_DEFAULT_TEXTS, GUIDANCE_PRESETS, INTEGRATION_TEMPLATES, LogLevel, TEXT_TEMPLATES, analyzeDeveloperConfiguration, analyzeIntegrationCategories, autoConfigureCategories, buildConsentStorageKey, categorizeDiscoveredCookies, checkPeerDeps, createAnpdCategoriesConfig, createClarityIntegration, createConsentAuditEntry, createCorporateIntegrations, createECommerceIntegrations, createFacebookPixelIntegration, createGoogleAnalyticsIntegration, createGoogleTagManagerIntegration, createHotjarIntegration, createIntercomIntegration, createMixpanelIntegration, createProjectPreferences, createSaaSIntegrations, createSuggestedIntegration, createUserWayIntegration, createZendeskChatIntegration, defaultTexts, detectConsentCookieName, discoverRuntimeCookies, ensureNecessaryAlwaysOn, extractCategoriesFromIntegrations, getAllProjectCategories, getCookiesInfoForCategory, getPeerDepsLocale, loadScript, logDeveloperGuidance, logger, openPreferencesModal, pushConsentInitializedEvent, pushConsentUpdatedEvent, registerScript, resetPeerDepsMessages, resolveTexts, runPeerDepsCheck, setCookieCatalogOverrides, setCookieCategoryOverrides, setDebugLogging, setPeerDepsLocale, setPeerDepsMessages, suggestCategoryForScript, useCategories, useCategoryStatus, useConsent, useConsentHydration, useConsentScriptLoader, useConsentTexts, useDataLayerEvents, useDesignTokens, useDeveloperGuidance, useOpenPreferencesModal, validateIntegrationCategories, validateNecessaryClassification, validateProjectPreferences };
|