@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.cjs
CHANGED
|
@@ -35,6 +35,219 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
35
35
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
+
// src/types/advancedTexts.ts
|
|
39
|
+
var EXPANDED_DEFAULT_TEXTS = {
|
|
40
|
+
// Textos adicionais
|
|
41
|
+
confirm: "Confirmar",
|
|
42
|
+
cancel: "Cancelar",
|
|
43
|
+
loading: "Carregando...",
|
|
44
|
+
// Feedback
|
|
45
|
+
feedback: {
|
|
46
|
+
saveSuccess: "Prefer\xEAncias salvas com sucesso!",
|
|
47
|
+
saveError: "Erro ao salvar prefer\xEAncias. Tente novamente.",
|
|
48
|
+
consentUpdated: "Consentimento atualizado.",
|
|
49
|
+
cookiesRejected: "Cookies opcionais rejeitados.",
|
|
50
|
+
settingsReset: "Configura\xE7\xF5es resetadas."
|
|
51
|
+
},
|
|
52
|
+
// Acessibilidade
|
|
53
|
+
accessibility: {
|
|
54
|
+
bannerLabel: "Banner de consentimento de cookies",
|
|
55
|
+
modalLabel: "Modal de prefer\xEAncias de cookies",
|
|
56
|
+
keyboardNavigation: "Use Tab para navegar, Enter para selecionar",
|
|
57
|
+
toggleState: {
|
|
58
|
+
enabled: "Habilitado",
|
|
59
|
+
disabled: "Desabilitado"
|
|
60
|
+
},
|
|
61
|
+
liveRegion: "Regi\xE3o de an\xFAncios din\xE2micos"
|
|
62
|
+
},
|
|
63
|
+
// Categorias
|
|
64
|
+
categories: {
|
|
65
|
+
necessary: {
|
|
66
|
+
name: "Cookies Necess\xE1rios",
|
|
67
|
+
description: "Essenciais para o funcionamento b\xE1sico do site",
|
|
68
|
+
examples: "Sess\xE3o, seguran\xE7a, prefer\xEAncias de idioma"
|
|
69
|
+
},
|
|
70
|
+
analytics: {
|
|
71
|
+
name: "Cookies de Analytics",
|
|
72
|
+
description: "Ajudam a entender como os visitantes usam o site",
|
|
73
|
+
examples: "Google Analytics, contadores de p\xE1gina"
|
|
74
|
+
},
|
|
75
|
+
marketing: {
|
|
76
|
+
name: "Cookies de Marketing",
|
|
77
|
+
description: "Usados para personalizar an\xFAncios e ofertas",
|
|
78
|
+
examples: "Facebook Pixel, Google Ads, remarketing"
|
|
79
|
+
},
|
|
80
|
+
functional: {
|
|
81
|
+
name: "Cookies Funcionais",
|
|
82
|
+
description: "Melhoram a funcionalidade e personaliza\xE7\xE3o",
|
|
83
|
+
examples: "Chat, mapas, v\xEDdeos embarcados"
|
|
84
|
+
},
|
|
85
|
+
performance: {
|
|
86
|
+
name: "Cookies de Performance",
|
|
87
|
+
description: "Coletam informa\xE7\xF5es sobre velocidade e estabilidade",
|
|
88
|
+
examples: "Monitoramento de erro, otimiza\xE7\xE3o de velocidade"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
// Contextos específicos
|
|
92
|
+
contexts: {
|
|
93
|
+
ecommerce: {
|
|
94
|
+
cartAbandonment: "Lembramos dos produtos no seu carrinho",
|
|
95
|
+
personalizedOffers: "Ofertas personalizadas baseadas no seu hist\xF3rico",
|
|
96
|
+
paymentSecurity: "Seguran\xE7a adicional no processo de pagamento",
|
|
97
|
+
productRecommendations: "Sugest\xF5es de produtos relevantes"
|
|
98
|
+
},
|
|
99
|
+
saas: {
|
|
100
|
+
userAnalytics: "An\xE1lise de uso para melhorar funcionalidades",
|
|
101
|
+
performanceMonitoring: "Monitoramento de performance da aplica\xE7\xE3o",
|
|
102
|
+
featureUsage: "Estat\xEDsticas de uso de recursos",
|
|
103
|
+
customerSupport: "Suporte ao cliente mais eficiente"
|
|
104
|
+
},
|
|
105
|
+
government: {
|
|
106
|
+
citizenServices: "Melhoria dos servi\xE7os ao cidad\xE3o",
|
|
107
|
+
dataProtection: "Prote\xE7\xE3o rigorosa dos dados pessoais",
|
|
108
|
+
transparency: "Transpar\xEAncia no uso de dados",
|
|
109
|
+
accessibility: "Recursos de acessibilidade digital"
|
|
110
|
+
},
|
|
111
|
+
education: {
|
|
112
|
+
studentProgress: "Acompanhamento do progresso educacional",
|
|
113
|
+
learningAnalytics: "Analytics para melhorar o aprendizado",
|
|
114
|
+
accessibility: "Recursos educacionais acess\xEDveis",
|
|
115
|
+
parentalConsent: "Consentimento parental quando necess\xE1rio"
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
// Variações de tom
|
|
119
|
+
variants: {
|
|
120
|
+
formal: {
|
|
121
|
+
bannerMessage: "Este s\xEDtio eletr\xF4nico utiliza cookies para otimizar a experi\xEAncia de navega\xE7\xE3o.",
|
|
122
|
+
acceptAll: "Concordar com todos os cookies",
|
|
123
|
+
declineAll: "Recusar cookies opcionais",
|
|
124
|
+
modalTitle: "Configura\xE7\xE3o de Cookies"
|
|
125
|
+
},
|
|
126
|
+
casual: {
|
|
127
|
+
bannerMessage: "\u{1F36A} Ei! Usamos cookies para tornar sua experi\xEAncia ainda melhor!",
|
|
128
|
+
acceptAll: "Aceitar tudo",
|
|
129
|
+
declineAll: "S\xF3 o essencial",
|
|
130
|
+
modalTitle: "Seus Cookies"
|
|
131
|
+
},
|
|
132
|
+
concise: {
|
|
133
|
+
bannerMessage: "Usamos cookies. Voc\xEA aceita?",
|
|
134
|
+
acceptAll: "Sim",
|
|
135
|
+
declineAll: "N\xE3o",
|
|
136
|
+
modalTitle: "Cookies"
|
|
137
|
+
},
|
|
138
|
+
detailed: {
|
|
139
|
+
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.",
|
|
140
|
+
acceptAll: "Aceitar todos os cookies e tecnologias",
|
|
141
|
+
declineAll: "Recusar todos os cookies opcionais",
|
|
142
|
+
modalTitle: "Centro de Prefer\xEAncias de Privacidade"
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
// Internacionalização simplificada (apenas textos básicos)
|
|
146
|
+
i18n: {
|
|
147
|
+
en: {
|
|
148
|
+
bannerMessage: "We use cookies to enhance your experience.",
|
|
149
|
+
acceptAll: "Accept All",
|
|
150
|
+
declineAll: "Decline",
|
|
151
|
+
preferences: "Preferences",
|
|
152
|
+
modalTitle: "Cookie Preferences",
|
|
153
|
+
modalIntro: "Customize your cookie preferences below.",
|
|
154
|
+
save: "Save Preferences",
|
|
155
|
+
necessaryAlwaysOn: "Necessary cookies (always active)"
|
|
156
|
+
},
|
|
157
|
+
es: {
|
|
158
|
+
bannerMessage: "Utilizamos cookies para mejorar su experiencia.",
|
|
159
|
+
acceptAll: "Aceptar Todo",
|
|
160
|
+
declineAll: "Rechazar",
|
|
161
|
+
preferences: "Preferencias",
|
|
162
|
+
modalTitle: "Preferencias de Cookies",
|
|
163
|
+
modalIntro: "Personalice sus preferencias de cookies a continuaci\xF3n.",
|
|
164
|
+
save: "Guardar Preferencias",
|
|
165
|
+
necessaryAlwaysOn: "Cookies necess\xE1rias (sempre ativas)"
|
|
166
|
+
},
|
|
167
|
+
fr: {
|
|
168
|
+
bannerMessage: "Nous utilisons des cookies pour am\xE9liorer votre exp\xE9rience.",
|
|
169
|
+
acceptAll: "Tout Accepter",
|
|
170
|
+
declineAll: "Refuser",
|
|
171
|
+
preferences: "Pr\xE9f\xE9rences",
|
|
172
|
+
modalTitle: "Pr\xE9f\xE9rences des Cookies",
|
|
173
|
+
modalIntro: "Personnalisez vos pr\xE9f\xE9rences de cookies ci-dessous.",
|
|
174
|
+
save: "Enregistrer les Pr\xE9f\xE9rences",
|
|
175
|
+
necessaryAlwaysOn: "Cookies n\xE9cessaires (toujours actifs)"
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
// Textos técnicos
|
|
179
|
+
technical: {
|
|
180
|
+
sessionCookies: "Cookies de sess\xE3o s\xE3o tempor\xE1rios e expiram quando voc\xEA fecha o navegador.",
|
|
181
|
+
persistentCookies: "Cookies persistentes permanecem no seu dispositivo at\xE9 expirarem ou serem removidos.",
|
|
182
|
+
thirdPartyCookies: "Cookies de terceiros s\xE3o definidos por dom\xEDnios diferentes do site que voc\xEA est\xE1 visitando.",
|
|
183
|
+
browserSettings: "Voc\xEA pode gerenciar cookies nas configura\xE7\xF5es do seu navegador.",
|
|
184
|
+
disablingImpact: "Desabilitar cookies pode afetar a funcionalidade do site."
|
|
185
|
+
},
|
|
186
|
+
// Cookie details
|
|
187
|
+
cookieDetails: {
|
|
188
|
+
tableHeaders: {
|
|
189
|
+
name: "Nome",
|
|
190
|
+
purpose: "Finalidade",
|
|
191
|
+
duration: "Dura\xE7\xE3o",
|
|
192
|
+
provider: "Fornecedor",
|
|
193
|
+
type: "Tipo"
|
|
194
|
+
},
|
|
195
|
+
noCookies: "Nenhum cookie encontrado para esta categoria.",
|
|
196
|
+
toggleDetails: {
|
|
197
|
+
expand: "Ver detalhes",
|
|
198
|
+
collapse: "Ocultar detalhes"
|
|
199
|
+
},
|
|
200
|
+
scriptLabelPrefix: "(script) ",
|
|
201
|
+
scriptPurpose: "Script de integra\xE7\xE3o ativo"
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
function resolveTexts(texts, options = {}) {
|
|
205
|
+
const { language = "pt", variant } = options;
|
|
206
|
+
let resolved = { ...texts };
|
|
207
|
+
if (variant && texts.variants?.[variant]) {
|
|
208
|
+
resolved = { ...resolved, ...texts.variants[variant] };
|
|
209
|
+
}
|
|
210
|
+
if (language !== "pt" && texts.i18n?.[language]) {
|
|
211
|
+
resolved = { ...resolved, ...texts.i18n[language] };
|
|
212
|
+
}
|
|
213
|
+
return resolved;
|
|
214
|
+
}
|
|
215
|
+
var TEXT_TEMPLATES = {
|
|
216
|
+
ecommerce: {
|
|
217
|
+
...EXPANDED_DEFAULT_TEXTS,
|
|
218
|
+
bannerMessage: "Utilizamos cookies para personalizar ofertas e melhorar sua experi\xEAncia de compra.",
|
|
219
|
+
acceptAll: "Aceitar e continuar",
|
|
220
|
+
variants: {
|
|
221
|
+
casual: {
|
|
222
|
+
bannerMessage: "\u{1F6D2} Usamos cookies para encontrar as melhores ofertas para voc\xEA!",
|
|
223
|
+
acceptAll: "Quero ofertas personalizadas!"
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
saas: {
|
|
228
|
+
...EXPANDED_DEFAULT_TEXTS,
|
|
229
|
+
bannerMessage: "Utilizamos cookies para otimizar o desempenho da aplica\xE7\xE3o e sua experi\xEAncia.",
|
|
230
|
+
acceptAll: "Aceitar e otimizar",
|
|
231
|
+
variants: {
|
|
232
|
+
formal: {
|
|
233
|
+
bannerMessage: "Esta aplica\xE7\xE3o utiliza cookies para an\xE1lise de performance e melhoria cont\xEDnua da experi\xEAncia do usu\xE1rio.",
|
|
234
|
+
acceptAll: "Autorizar coleta de dados de uso"
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
government: {
|
|
239
|
+
...EXPANDED_DEFAULT_TEXTS,
|
|
240
|
+
bannerMessage: "Este portal utiliza cookies em conformidade com a LGPD para melhorar os servi\xE7os p\xFAblicos.",
|
|
241
|
+
acceptAll: "Aceitar em conformidade",
|
|
242
|
+
variants: {
|
|
243
|
+
formal: {
|
|
244
|
+
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.",
|
|
245
|
+
acceptAll: "Concordar com o uso de cookies"
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
|
|
38
251
|
// src/utils/categoryUtils.ts
|
|
39
252
|
function createProjectPreferences(config, defaultValue = false) {
|
|
40
253
|
const preferences = {
|
|
@@ -333,6 +546,7 @@ function setDebugLogging(enabled, level = 2 /* INFO */) {
|
|
|
333
546
|
// src/utils/cookieUtils.ts
|
|
334
547
|
var DEFAULT_STORAGE_NAMESPACE = "lgpd-consent";
|
|
335
548
|
var DEFAULT_STORAGE_VERSION = "1";
|
|
549
|
+
var DEFAULT_MAX_AGE_SECONDS = 365 * 24 * 60 * 60;
|
|
336
550
|
function buildConsentStorageKey(options) {
|
|
337
551
|
const namespaceRaw = options?.namespace?.trim() || DEFAULT_STORAGE_NAMESPACE;
|
|
338
552
|
const versionRaw = options?.version?.trim() || DEFAULT_STORAGE_VERSION;
|
|
@@ -342,16 +556,36 @@ function buildConsentStorageKey(options) {
|
|
|
342
556
|
}
|
|
343
557
|
var DEFAULT_COOKIE_OPTS = {
|
|
344
558
|
name: "cookieConsent",
|
|
559
|
+
maxAge: DEFAULT_MAX_AGE_SECONDS,
|
|
345
560
|
maxAgeDays: 365,
|
|
346
561
|
sameSite: "Lax",
|
|
347
|
-
secure:
|
|
562
|
+
secure: false,
|
|
348
563
|
path: "/",
|
|
349
564
|
domain: void 0
|
|
350
565
|
};
|
|
566
|
+
function resolveCookieOptions(opts) {
|
|
567
|
+
const currentWindow = globalThis.window;
|
|
568
|
+
const currentLocation = globalThis.location;
|
|
569
|
+
const protocols = [currentWindow?.location?.protocol, currentLocation?.protocol].filter(
|
|
570
|
+
Boolean
|
|
571
|
+
);
|
|
572
|
+
const forceHttps = globalThis.__LGPD_FORCE_HTTPS__ === true;
|
|
573
|
+
const isHttps = forceHttps || protocols.includes("https:");
|
|
574
|
+
const maxAgeSecondsFromDays = typeof opts?.maxAgeDays === "number" ? Math.max(0, opts.maxAgeDays * 24 * 60 * 60) : null;
|
|
575
|
+
const maxAgeSeconds = typeof opts?.maxAge === "number" ? Math.max(0, opts.maxAge) : maxAgeSecondsFromDays ?? DEFAULT_MAX_AGE_SECONDS;
|
|
576
|
+
return {
|
|
577
|
+
name: opts?.name ?? DEFAULT_COOKIE_OPTS.name,
|
|
578
|
+
maxAge: maxAgeSeconds,
|
|
579
|
+
sameSite: opts?.sameSite ?? DEFAULT_COOKIE_OPTS.sameSite ?? "Lax",
|
|
580
|
+
secure: typeof opts?.secure === "boolean" ? opts.secure : isHttps ? true : DEFAULT_COOKIE_OPTS.secure,
|
|
581
|
+
path: opts?.path ?? DEFAULT_COOKIE_OPTS.path ?? "/",
|
|
582
|
+
domain: opts?.domain ?? DEFAULT_COOKIE_OPTS.domain ?? void 0
|
|
583
|
+
};
|
|
584
|
+
}
|
|
351
585
|
var COOKIE_SCHEMA_VERSION = "1.0";
|
|
352
586
|
function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
|
|
353
587
|
logger.debug("Reading consent cookie", { name });
|
|
354
|
-
if (
|
|
588
|
+
if (globalThis.document === void 0) {
|
|
355
589
|
logger.debug("Cookie read skipped: server-side environment");
|
|
356
590
|
return null;
|
|
357
591
|
}
|
|
@@ -363,6 +597,10 @@ function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
|
|
|
363
597
|
try {
|
|
364
598
|
const data = JSON.parse(raw);
|
|
365
599
|
logger.cookieOperation("read", name, data);
|
|
600
|
+
if (!data || typeof data !== "object") {
|
|
601
|
+
logger.warn("Consent cookie malformed: payload is not an object");
|
|
602
|
+
return null;
|
|
603
|
+
}
|
|
366
604
|
if (!data.version) {
|
|
367
605
|
logger.debug("Migrating legacy cookie format");
|
|
368
606
|
return migrateLegacyCookie(data);
|
|
@@ -371,7 +609,11 @@ function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
|
|
|
371
609
|
logger.warn(`Cookie version mismatch: ${data.version} != ${COOKIE_SCHEMA_VERSION}`);
|
|
372
610
|
return null;
|
|
373
611
|
}
|
|
374
|
-
|
|
612
|
+
const preferences = data && typeof data.preferences === "object" ? data.preferences : { necessary: true };
|
|
613
|
+
return {
|
|
614
|
+
...data,
|
|
615
|
+
preferences: ensureNecessaryAlwaysOn(preferences)
|
|
616
|
+
};
|
|
375
617
|
} catch (error) {
|
|
376
618
|
logger.error("Error parsing consent cookie", error);
|
|
377
619
|
return null;
|
|
@@ -394,12 +636,12 @@ function migrateLegacyCookie(legacyData) {
|
|
|
394
636
|
}
|
|
395
637
|
}
|
|
396
638
|
function writeConsentCookie(state, config, opts, source = "banner") {
|
|
397
|
-
if (
|
|
639
|
+
if (globalThis.document === void 0 || globalThis.window === void 0 || globalThis.__LGPD_SSR__ === true) {
|
|
398
640
|
logger.debug("Cookie write skipped: server-side environment");
|
|
399
641
|
return;
|
|
400
642
|
}
|
|
401
643
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
402
|
-
const o =
|
|
644
|
+
const o = resolveCookieOptions(opts);
|
|
403
645
|
const preferences = ensureNecessaryAlwaysOn(state.preferences);
|
|
404
646
|
const cookieData = {
|
|
405
647
|
version: COOKIE_SCHEMA_VERSION,
|
|
@@ -411,8 +653,9 @@ function writeConsentCookie(state, config, opts, source = "banner") {
|
|
|
411
653
|
projectConfig: config
|
|
412
654
|
};
|
|
413
655
|
logger.cookieOperation("write", o.name, cookieData);
|
|
656
|
+
const expires = new Date(Date.now() + o.maxAge * 1e3);
|
|
414
657
|
Cookies__default.default.set(o.name, JSON.stringify(cookieData), {
|
|
415
|
-
expires
|
|
658
|
+
expires,
|
|
416
659
|
sameSite: o.sameSite,
|
|
417
660
|
secure: o.secure,
|
|
418
661
|
path: o.path,
|
|
@@ -442,36 +685,48 @@ function createConsentAuditEntry(state, params) {
|
|
|
442
685
|
};
|
|
443
686
|
}
|
|
444
687
|
function removeConsentCookie(opts) {
|
|
445
|
-
if (
|
|
688
|
+
if (globalThis.document === void 0) {
|
|
446
689
|
logger.debug("Cookie removal skipped: server-side environment");
|
|
447
690
|
return;
|
|
448
691
|
}
|
|
449
|
-
const o =
|
|
692
|
+
const o = resolveCookieOptions(opts);
|
|
450
693
|
logger.cookieOperation("delete", o.name);
|
|
451
694
|
Cookies__default.default.remove(o.name, { path: o.path, domain: o.domain });
|
|
452
695
|
logger.info("Consent cookie removed");
|
|
453
696
|
}
|
|
454
697
|
|
|
455
698
|
// src/utils/dataLayerEvents.ts
|
|
456
|
-
var LIBRARY_VERSION = "0.7.
|
|
699
|
+
var LIBRARY_VERSION = "0.7.2";
|
|
457
700
|
function ensureDataLayer() {
|
|
458
|
-
|
|
459
|
-
if (
|
|
460
|
-
|
|
701
|
+
const currentWindow = globalThis.window;
|
|
702
|
+
if (!currentWindow) return;
|
|
703
|
+
const currentLayer = currentWindow.dataLayer;
|
|
704
|
+
if (currentLayer == null) {
|
|
705
|
+
currentWindow.dataLayer = [];
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
if (typeof currentLayer.push !== "function") {
|
|
709
|
+
const env = globalThis.process?.env?.NODE_ENV ?? "production";
|
|
710
|
+
if (env !== "production") {
|
|
711
|
+
console.warn("[LGPD-CONSENT] dataLayer presente mas sem push; eventos n\xE3o ser\xE3o registrados.");
|
|
712
|
+
}
|
|
713
|
+
}
|
|
461
714
|
}
|
|
462
715
|
function pushConsentInitializedEvent(categories) {
|
|
463
|
-
if (globalThis.window === void 0) return;
|
|
464
716
|
ensureDataLayer();
|
|
465
717
|
const event = {
|
|
466
718
|
event: "consent_initialized",
|
|
467
719
|
consent_version: LIBRARY_VERSION,
|
|
468
720
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
469
|
-
categories
|
|
721
|
+
categories,
|
|
722
|
+
preferences: categories
|
|
470
723
|
};
|
|
471
|
-
globalThis.window
|
|
724
|
+
const layer = globalThis.window?.dataLayer;
|
|
725
|
+
if (layer && typeof layer.push === "function") {
|
|
726
|
+
layer.push(event);
|
|
727
|
+
}
|
|
472
728
|
}
|
|
473
729
|
function pushConsentUpdatedEvent(categories, origin, previousCategories) {
|
|
474
|
-
if (globalThis.window === void 0) return;
|
|
475
730
|
ensureDataLayer();
|
|
476
731
|
const changedCategories = previousCategories ? Object.keys(categories).filter((key) => categories[key] !== previousCategories[key]) : [];
|
|
477
732
|
const event = {
|
|
@@ -480,9 +735,13 @@ function pushConsentUpdatedEvent(categories, origin, previousCategories) {
|
|
|
480
735
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
481
736
|
origin,
|
|
482
737
|
categories,
|
|
738
|
+
preferences: categories,
|
|
483
739
|
changed_categories: changedCategories
|
|
484
740
|
};
|
|
485
|
-
globalThis.window
|
|
741
|
+
const layer = globalThis.window?.dataLayer;
|
|
742
|
+
if (layer && typeof layer.push === "function") {
|
|
743
|
+
layer.push(event);
|
|
744
|
+
}
|
|
486
745
|
}
|
|
487
746
|
function useDataLayerEvents() {
|
|
488
747
|
return {
|
|
@@ -812,7 +1071,7 @@ function analyzeDeveloperConfiguration(config) {
|
|
|
812
1071
|
const gt = globalThis;
|
|
813
1072
|
const implied = (gt.__LGPD_REQUIRED_CATEGORIES__ || []).filter(Boolean);
|
|
814
1073
|
implied.forEach((id) => {
|
|
815
|
-
if (!guidance.activeCategoriesInfo.
|
|
1074
|
+
if (!guidance.activeCategoriesInfo.some((c) => c.id === id)) {
|
|
816
1075
|
const info = NAMES[id];
|
|
817
1076
|
if (info) {
|
|
818
1077
|
guidance.activeCategoriesInfo.push({
|
|
@@ -852,6 +1111,27 @@ function analyzeDeveloperConfiguration(config) {
|
|
|
852
1111
|
'Apenas cookies necess\xE1rios est\xE3o configurados. Para compliance LGPD, considere adicionar categorias como "analytics" ou "functional" conforme uso real.',
|
|
853
1112
|
"compliance"
|
|
854
1113
|
);
|
|
1114
|
+
} else {
|
|
1115
|
+
addMessage(
|
|
1116
|
+
"info",
|
|
1117
|
+
"Cookies n\xE3o necess\xE1rios devem iniciar desativados e exigir consentimento expresso, sem pr\xE9-sele\xE7\xE3o e sem consentimento t\xE1cito.",
|
|
1118
|
+
"consent"
|
|
1119
|
+
);
|
|
1120
|
+
addMessage(
|
|
1121
|
+
"info",
|
|
1122
|
+
"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.",
|
|
1123
|
+
"consent"
|
|
1124
|
+
);
|
|
1125
|
+
addMessage(
|
|
1126
|
+
"info",
|
|
1127
|
+
"Informe finalidades espec\xEDficas, per\xEDodo de reten\xE7\xE3o e compartilhamento com terceiros em pol\xEDtica/aviso de cookies.",
|
|
1128
|
+
"transparency"
|
|
1129
|
+
);
|
|
1130
|
+
addMessage(
|
|
1131
|
+
"info",
|
|
1132
|
+
"Disponibilize mecanismo pr\xF3prio de gerenciamento de cookies; configura\xE7\xF5es do navegador s\xE3o apenas complementares.",
|
|
1133
|
+
"transparency"
|
|
1134
|
+
);
|
|
855
1135
|
}
|
|
856
1136
|
if (totalToggleable > 5) {
|
|
857
1137
|
addMessage(
|
|
@@ -876,7 +1156,7 @@ function getComplianceScoreColor(score) {
|
|
|
876
1156
|
function logComplianceScore(prefix, score) {
|
|
877
1157
|
const color = getComplianceScoreColor(score);
|
|
878
1158
|
console.log(
|
|
879
|
-
`%c${prefix} Score de Conformidade LGPD: ${score}/100`,
|
|
1159
|
+
`%c${prefix} Score de Conformidade LGPD (orientativo): ${score}/100`,
|
|
880
1160
|
`color: ${color}; font-weight: bold; font-size: 14px;`
|
|
881
1161
|
);
|
|
882
1162
|
}
|
|
@@ -971,7 +1251,7 @@ function logServerSideIfAvailable(guidance) {
|
|
|
971
1251
|
}
|
|
972
1252
|
function logDeveloperGuidance(guidance, disableGuidanceProp, config) {
|
|
973
1253
|
const gt = globalThis;
|
|
974
|
-
const nodeEnv =
|
|
1254
|
+
const nodeEnv = gt.process ? gt.process?.env?.NODE_ENV : void 0;
|
|
975
1255
|
const isProd = nodeEnv === "production" || gt.__LGPD_PRODUCTION__ === true;
|
|
976
1256
|
if (isProd || disableGuidanceProp) return;
|
|
977
1257
|
const guidanceHash = getGuidanceHash(guidance);
|
|
@@ -1029,11 +1309,21 @@ function logDeveloperGuidance(guidance, disableGuidanceProp, config) {
|
|
|
1029
1309
|
"color: #9c27b0;",
|
|
1030
1310
|
"color: #7b1fa2;"
|
|
1031
1311
|
);
|
|
1312
|
+
console.info(
|
|
1313
|
+
`%c${PREFIX}%c Evite consentimento t\xE1cito e op\xE7\xF5es pr\xE9-selecionadas`,
|
|
1314
|
+
"color: #9c27b0;",
|
|
1315
|
+
"color: #7b1fa2;"
|
|
1316
|
+
);
|
|
1032
1317
|
console.info(
|
|
1033
1318
|
`%c${PREFIX}%c Documente pol\xEDticas claras por categoria`,
|
|
1034
1319
|
"color: #9c27b0;",
|
|
1035
1320
|
"color: #7b1fa2;"
|
|
1036
1321
|
);
|
|
1322
|
+
console.info(
|
|
1323
|
+
`%c${PREFIX}%c Informe finalidades, reten\xE7\xE3o e revoga\xE7\xE3o simples e gratuita`,
|
|
1324
|
+
"color: #9c27b0;",
|
|
1325
|
+
"color: #7b1fa2;"
|
|
1326
|
+
);
|
|
1037
1327
|
console.info(
|
|
1038
1328
|
`%c${PREFIX}%c Registre consentimento com data/hora/origem`,
|
|
1039
1329
|
"color: #9c27b0;",
|
|
@@ -1045,7 +1335,9 @@ function logDeveloperGuidance(guidance, disableGuidanceProp, config) {
|
|
|
1045
1335
|
function useDeveloperGuidance(config, disableGuidanceProp, guidanceConfig) {
|
|
1046
1336
|
const guidance = React4__namespace.default.useMemo(() => analyzeDeveloperConfiguration(config), [config]);
|
|
1047
1337
|
React4__namespace.default.useEffect(() => {
|
|
1048
|
-
if (!disableGuidanceProp)
|
|
1338
|
+
if (globalThis.window !== void 0 && !disableGuidanceProp) {
|
|
1339
|
+
logDeveloperGuidance(guidance, disableGuidanceProp, guidanceConfig);
|
|
1340
|
+
}
|
|
1049
1341
|
}, [guidance, disableGuidanceProp, guidanceConfig]);
|
|
1050
1342
|
return guidance;
|
|
1051
1343
|
}
|
|
@@ -1089,58 +1381,8 @@ var GUIDANCE_PRESETS = {
|
|
|
1089
1381
|
};
|
|
1090
1382
|
|
|
1091
1383
|
// src/utils/peerDepsCheck.ts
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
try {
|
|
1095
|
-
const reactSymbols = Object.getOwnPropertySymbols(globalThis.window).map(String).filter((name) => name.includes("react"));
|
|
1096
|
-
if (reactSymbols.length > 1) {
|
|
1097
|
-
return true;
|
|
1098
|
-
}
|
|
1099
|
-
const ReactModule = window.React;
|
|
1100
|
-
if (ReactModule && Array.isArray(ReactModule)) {
|
|
1101
|
-
return true;
|
|
1102
|
-
}
|
|
1103
|
-
const hasMultipleVersions = window.__REACT_DEVTOOLS_GLOBAL_HOOK__?.renderers?.size > 1;
|
|
1104
|
-
return hasMultipleVersions || false;
|
|
1105
|
-
} catch {
|
|
1106
|
-
return false;
|
|
1107
|
-
}
|
|
1108
|
-
}
|
|
1109
|
-
function getPackageVersion(packageName) {
|
|
1110
|
-
if (globalThis.window === void 0) return null;
|
|
1111
|
-
try {
|
|
1112
|
-
const pkg = window[packageName];
|
|
1113
|
-
if (pkg?.version) return pkg.version;
|
|
1114
|
-
const React6 = window.React;
|
|
1115
|
-
if (packageName === "react" && React6?.version) {
|
|
1116
|
-
return React6.version;
|
|
1117
|
-
}
|
|
1118
|
-
return null;
|
|
1119
|
-
} catch {
|
|
1120
|
-
return null;
|
|
1121
|
-
}
|
|
1122
|
-
}
|
|
1123
|
-
function isVersionInRange(version, minMajor, maxMajor) {
|
|
1124
|
-
const major = Number.parseInt(version.split(".")[0], 10);
|
|
1125
|
-
return major >= minMajor && major <= maxMajor;
|
|
1126
|
-
}
|
|
1127
|
-
function checkPeerDeps(options = {}) {
|
|
1128
|
-
const { skipInProduction = true, logWarnings = true } = options;
|
|
1129
|
-
const result = {
|
|
1130
|
-
ok: true,
|
|
1131
|
-
warnings: [],
|
|
1132
|
-
errors: []
|
|
1133
|
-
};
|
|
1134
|
-
const isProduction = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
1135
|
-
if (skipInProduction && isProduction) {
|
|
1136
|
-
return result;
|
|
1137
|
-
}
|
|
1138
|
-
if (globalThis.window === void 0) {
|
|
1139
|
-
return result;
|
|
1140
|
-
}
|
|
1141
|
-
if (detectMultipleReactInstances()) {
|
|
1142
|
-
result.ok = false;
|
|
1143
|
-
const errorMsg = `
|
|
1384
|
+
var MESSAGES_PT_BR = {
|
|
1385
|
+
MULTIPLE_REACT_INSTANCES: `
|
|
1144
1386
|
\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
|
|
1145
1387
|
\u2551 \u26A0\uFE0F ERRO: M\xFAltiplas inst\xE2ncias de React detectadas \u2551
|
|
1146
1388
|
\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
|
|
@@ -1202,22 +1444,13 @@ function checkPeerDeps(options = {}) {
|
|
|
1202
1444
|
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#multiple-react-instances
|
|
1203
1445
|
|
|
1204
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
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
if (logWarnings) {
|
|
1208
|
-
console.error(errorMsg);
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1211
|
-
const reactVersion = getPackageVersion("react");
|
|
1212
|
-
if (reactVersion) {
|
|
1213
|
-
if (!isVersionInRange(reactVersion, 18, 19)) {
|
|
1214
|
-
result.ok = false;
|
|
1215
|
-
const errorMsg = `
|
|
1447
|
+
`,
|
|
1448
|
+
UNSUPPORTED_REACT_VERSION: (version) => `
|
|
1216
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
|
|
1217
1450
|
\u2551 \u26A0\uFE0F AVISO: Vers\xE3o do React n\xE3o suportada \u2551
|
|
1218
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
|
|
1219
1452
|
|
|
1220
|
-
\u{1F4E6} Vers\xE3o detectada: React ${
|
|
1453
|
+
\u{1F4E6} Vers\xE3o detectada: React ${version}
|
|
1221
1454
|
\u2705 Vers\xF5es suportadas: React 18.x ou 19.x
|
|
1222
1455
|
|
|
1223
1456
|
\u{1F50D} O react-lgpd-consent requer React 18.2.0+ ou React 19.x
|
|
@@ -1235,27 +1468,13 @@ function checkPeerDeps(options = {}) {
|
|
|
1235
1468
|
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#react-version
|
|
1236
1469
|
|
|
1237
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
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
if (logWarnings) {
|
|
1241
|
-
console.error(errorMsg);
|
|
1242
|
-
}
|
|
1243
|
-
}
|
|
1244
|
-
}
|
|
1245
|
-
const muiVersion = window["@mui/material"]?.version;
|
|
1246
|
-
if (muiVersion) {
|
|
1247
|
-
if (!isVersionInRange(muiVersion, 5, 7)) {
|
|
1248
|
-
result.warnings.push(
|
|
1249
|
-
`MUI vers\xE3o ${muiVersion} detectada. Vers\xF5es suportadas: 5.15.0+, 6.x ou 7.x. Alguns componentes podem n\xE3o funcionar corretamente.`
|
|
1250
|
-
);
|
|
1251
|
-
if (logWarnings) {
|
|
1252
|
-
logger.warn(
|
|
1253
|
-
`
|
|
1471
|
+
`,
|
|
1472
|
+
UNSUPPORTED_MUI_VERSION: (version) => `
|
|
1254
1473
|
\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
|
|
1255
1474
|
\u2551 \u26A0\uFE0F AVISO: Vers\xE3o do Material-UI fora do range recomendado \u2551
|
|
1256
1475
|
\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
|
|
1257
1476
|
|
|
1258
|
-
\u{1F4E6} Vers\xE3o detectada: @mui/material ${
|
|
1477
|
+
\u{1F4E6} Vers\xE3o detectada: @mui/material ${version}
|
|
1259
1478
|
\u2705 Vers\xF5es suportadas: 5.15.0+, 6.x, 7.x
|
|
1260
1479
|
|
|
1261
1480
|
\u{1F50D} Componentes de UI (@react-lgpd-consent/mui) podem apresentar problemas.
|
|
@@ -1273,8 +1492,230 @@ function checkPeerDeps(options = {}) {
|
|
|
1273
1492
|
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#mui-version
|
|
1274
1493
|
|
|
1275
1494
|
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1276
|
-
|
|
1277
|
-
|
|
1495
|
+
`,
|
|
1496
|
+
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.`
|
|
1497
|
+
};
|
|
1498
|
+
var MESSAGES_EN = {
|
|
1499
|
+
MULTIPLE_REACT_INSTANCES: `
|
|
1500
|
+
\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
|
|
1501
|
+
\u2551 \u26A0\uFE0F ERROR: Multiple React instances detected \u2551
|
|
1502
|
+
\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
|
|
1503
|
+
|
|
1504
|
+
\u{1F534} Problem:
|
|
1505
|
+
Your project is loading more than one copy of React, causing the error:
|
|
1506
|
+
"Invalid hook call. Hooks can only be called inside of the body of a
|
|
1507
|
+
function component."
|
|
1508
|
+
|
|
1509
|
+
\u{1F50D} Probable cause:
|
|
1510
|
+
\u2022 pnpm/Yarn PnP without proper peer dependency hoisting
|
|
1511
|
+
\u2022 node_modules with duplicate React (classic npm/yarn)
|
|
1512
|
+
\u2022 Webpack/Vite with multiple resolutions of the same package
|
|
1513
|
+
|
|
1514
|
+
\u2705 Solutions:
|
|
1515
|
+
|
|
1516
|
+
\u{1F4E6} PNPM (RECOMMENDED):
|
|
1517
|
+
Add to root package.json:
|
|
1518
|
+
{
|
|
1519
|
+
"pnpm": {
|
|
1520
|
+
"overrides": {
|
|
1521
|
+
"react": "$react",
|
|
1522
|
+
"react-dom": "$react-dom"
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
Run: pnpm install
|
|
1527
|
+
|
|
1528
|
+
\u{1F4E6} NPM/Yarn:
|
|
1529
|
+
Add to root package.json:
|
|
1530
|
+
{
|
|
1531
|
+
"overrides": {
|
|
1532
|
+
"react": "^18.2.0 || ^19.0.0",
|
|
1533
|
+
"react-dom": "^18.2.0 || ^19.0.0"
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
Run: npm install (or yarn install)
|
|
1537
|
+
|
|
1538
|
+
\u{1F527} Webpack:
|
|
1539
|
+
Add to webpack.config.js:
|
|
1540
|
+
module.exports = {
|
|
1541
|
+
resolve: {
|
|
1542
|
+
alias: {
|
|
1543
|
+
react: path.resolve('./node_modules/react'),
|
|
1544
|
+
'react-dom': path.resolve('./node_modules/react-dom'),
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
\u26A1 Vite:
|
|
1550
|
+
Add to vite.config.js:
|
|
1551
|
+
export default {
|
|
1552
|
+
resolve: {
|
|
1553
|
+
dedupe: ['react', 'react-dom']
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
\u{1F4DA} Documentation:
|
|
1558
|
+
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#multiple-react-instances
|
|
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_REACT_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: Unsupported React version \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: React ${version}
|
|
1568
|
+
\u2705 Supported versions: React 18.x or 19.x
|
|
1569
|
+
|
|
1570
|
+
\u{1F50D} react-lgpd-consent requires React 18.2.0+ or React 19.x
|
|
1571
|
+
|
|
1572
|
+
\u2705 Solution:
|
|
1573
|
+
Update React to a supported version:
|
|
1574
|
+
|
|
1575
|
+
npm install react@^18.2.0 react-dom@^18.2.0
|
|
1576
|
+
|
|
1577
|
+
or
|
|
1578
|
+
|
|
1579
|
+
npm install react@^19.0.0 react-dom@^19.0.0
|
|
1580
|
+
|
|
1581
|
+
\u{1F4DA} Documentation:
|
|
1582
|
+
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#react-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
|
+
UNSUPPORTED_MUI_VERSION: (version) => `
|
|
1587
|
+
\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
|
|
1588
|
+
\u2551 \u26A0\uFE0F WARNING: Material-UI version out of recommended range \u2551
|
|
1589
|
+
\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
|
|
1590
|
+
|
|
1591
|
+
\u{1F4E6} Detected version: @mui/material ${version}
|
|
1592
|
+
\u2705 Supported versions: 5.15.0+, 6.x, 7.x
|
|
1593
|
+
|
|
1594
|
+
\u{1F50D} UI components (@react-lgpd-consent/mui) may have issues.
|
|
1595
|
+
|
|
1596
|
+
\u2705 Solution:
|
|
1597
|
+
Update MUI to a supported version:
|
|
1598
|
+
|
|
1599
|
+
npm install @mui/material@^7.0.0 @emotion/react @emotion/styled
|
|
1600
|
+
|
|
1601
|
+
or keep 5.15.0+:
|
|
1602
|
+
|
|
1603
|
+
npm install @mui/material@^5.15.0 @emotion/react @emotion/styled
|
|
1604
|
+
|
|
1605
|
+
\u{1F4DA} Documentation:
|
|
1606
|
+
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#mui-version
|
|
1607
|
+
|
|
1608
|
+
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1609
|
+
`,
|
|
1610
|
+
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.`
|
|
1611
|
+
};
|
|
1612
|
+
var MESSAGES_BY_LOCALE = {
|
|
1613
|
+
"pt-BR": MESSAGES_PT_BR,
|
|
1614
|
+
en: MESSAGES_EN
|
|
1615
|
+
};
|
|
1616
|
+
var currentLocale = "pt-BR";
|
|
1617
|
+
var customMessages = {};
|
|
1618
|
+
function setPeerDepsLocale(locale) {
|
|
1619
|
+
currentLocale = locale;
|
|
1620
|
+
}
|
|
1621
|
+
function getPeerDepsLocale() {
|
|
1622
|
+
return currentLocale;
|
|
1623
|
+
}
|
|
1624
|
+
function setPeerDepsMessages(messages) {
|
|
1625
|
+
customMessages = { ...customMessages, ...messages };
|
|
1626
|
+
}
|
|
1627
|
+
function resetPeerDepsMessages() {
|
|
1628
|
+
customMessages = {};
|
|
1629
|
+
}
|
|
1630
|
+
function getMessages() {
|
|
1631
|
+
const baseMessages = MESSAGES_BY_LOCALE[currentLocale];
|
|
1632
|
+
if (Object.keys(customMessages).length === 0) {
|
|
1633
|
+
return baseMessages;
|
|
1634
|
+
}
|
|
1635
|
+
return {
|
|
1636
|
+
MULTIPLE_REACT_INSTANCES: customMessages.MULTIPLE_REACT_INSTANCES ?? baseMessages.MULTIPLE_REACT_INSTANCES,
|
|
1637
|
+
UNSUPPORTED_REACT_VERSION: customMessages.UNSUPPORTED_REACT_VERSION ?? baseMessages.UNSUPPORTED_REACT_VERSION,
|
|
1638
|
+
UNSUPPORTED_MUI_VERSION: customMessages.UNSUPPORTED_MUI_VERSION ?? baseMessages.UNSUPPORTED_MUI_VERSION,
|
|
1639
|
+
MUI_OUT_OF_RANGE: customMessages.MUI_OUT_OF_RANGE ?? baseMessages.MUI_OUT_OF_RANGE
|
|
1640
|
+
};
|
|
1641
|
+
}
|
|
1642
|
+
function detectMultipleReactInstances() {
|
|
1643
|
+
const currentWindow = globalThis.window;
|
|
1644
|
+
if (currentWindow === void 0) return false;
|
|
1645
|
+
try {
|
|
1646
|
+
const reactSymbols = Object.getOwnPropertySymbols(currentWindow).map(String).filter((name) => name.includes("react"));
|
|
1647
|
+
if (reactSymbols.length > 1) {
|
|
1648
|
+
return true;
|
|
1649
|
+
}
|
|
1650
|
+
const ReactModule = currentWindow.React;
|
|
1651
|
+
if (ReactModule && Array.isArray(ReactModule)) {
|
|
1652
|
+
return true;
|
|
1653
|
+
}
|
|
1654
|
+
const hasMultipleVersions = (currentWindow.__REACT_DEVTOOLS_GLOBAL_HOOK__?.renderers?.size ?? 0) > 1;
|
|
1655
|
+
return hasMultipleVersions || false;
|
|
1656
|
+
} catch {
|
|
1657
|
+
return false;
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
function getPackageVersion(packageName) {
|
|
1661
|
+
const currentWindow = globalThis.window;
|
|
1662
|
+
if (currentWindow === void 0) return null;
|
|
1663
|
+
try {
|
|
1664
|
+
const pkg = currentWindow[packageName];
|
|
1665
|
+
if (pkg?.version) return pkg.version;
|
|
1666
|
+
const React6 = currentWindow.React;
|
|
1667
|
+
if (packageName === "react" && React6?.version) {
|
|
1668
|
+
return React6.version;
|
|
1669
|
+
}
|
|
1670
|
+
return null;
|
|
1671
|
+
} catch {
|
|
1672
|
+
return null;
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
function isVersionInRange(version, minMajor, maxMajor) {
|
|
1676
|
+
const major = Number.parseInt(version.split(".")[0], 10);
|
|
1677
|
+
return major >= minMajor && major <= maxMajor;
|
|
1678
|
+
}
|
|
1679
|
+
function checkPeerDeps(options = {}) {
|
|
1680
|
+
const { skipInProduction = true, logWarnings = true } = options;
|
|
1681
|
+
const result = {
|
|
1682
|
+
ok: true,
|
|
1683
|
+
warnings: [],
|
|
1684
|
+
errors: []
|
|
1685
|
+
};
|
|
1686
|
+
const isProduction = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
1687
|
+
if (skipInProduction && isProduction) {
|
|
1688
|
+
return result;
|
|
1689
|
+
}
|
|
1690
|
+
const currentWindow = globalThis.window;
|
|
1691
|
+
if (currentWindow === void 0) {
|
|
1692
|
+
return result;
|
|
1693
|
+
}
|
|
1694
|
+
const messages = getMessages();
|
|
1695
|
+
if (detectMultipleReactInstances()) {
|
|
1696
|
+
result.ok = false;
|
|
1697
|
+
result.errors.push(messages.MULTIPLE_REACT_INSTANCES);
|
|
1698
|
+
if (logWarnings) {
|
|
1699
|
+
console.error(messages.MULTIPLE_REACT_INSTANCES);
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
const reactVersion = getPackageVersion("react");
|
|
1703
|
+
if (reactVersion) {
|
|
1704
|
+
if (!isVersionInRange(reactVersion, 18, 19)) {
|
|
1705
|
+
result.ok = false;
|
|
1706
|
+
const errorMsg = messages.UNSUPPORTED_REACT_VERSION(reactVersion);
|
|
1707
|
+
result.errors.push(errorMsg);
|
|
1708
|
+
if (logWarnings) {
|
|
1709
|
+
console.error(errorMsg);
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
const muiVersion = currentWindow["@mui/material"]?.version;
|
|
1714
|
+
if (muiVersion) {
|
|
1715
|
+
if (!isVersionInRange(muiVersion, 5, 7)) {
|
|
1716
|
+
result.warnings.push(messages.MUI_OUT_OF_RANGE(muiVersion));
|
|
1717
|
+
if (logWarnings) {
|
|
1718
|
+
logger.warn(messages.UNSUPPORTED_MUI_VERSION(muiVersion));
|
|
1278
1719
|
}
|
|
1279
1720
|
}
|
|
1280
1721
|
}
|
|
@@ -1399,10 +1840,11 @@ function validateConsentProviderProps(props) {
|
|
|
1399
1840
|
|
|
1400
1841
|
// src/utils/cookieDiscovery.ts
|
|
1401
1842
|
function discoverRuntimeCookies() {
|
|
1402
|
-
|
|
1843
|
+
const currentDocument = globalThis.document;
|
|
1844
|
+
if (currentDocument === void 0 || !currentDocument.cookie) return [];
|
|
1403
1845
|
const names = Array.from(
|
|
1404
1846
|
new Set(
|
|
1405
|
-
|
|
1847
|
+
currentDocument.cookie.split(";").map((s) => s.trim()).filter(Boolean).map((s) => s.split("=")[0])
|
|
1406
1848
|
)
|
|
1407
1849
|
);
|
|
1408
1850
|
const list = names.map((name) => ({ name }));
|
|
@@ -1413,27 +1855,34 @@ function discoverRuntimeCookies() {
|
|
|
1413
1855
|
}
|
|
1414
1856
|
return list;
|
|
1415
1857
|
}
|
|
1858
|
+
function tryDecode(val) {
|
|
1859
|
+
try {
|
|
1860
|
+
return decodeURIComponent(val);
|
|
1861
|
+
} catch {
|
|
1862
|
+
return val;
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
function isConsentJson(val) {
|
|
1866
|
+
if (!val.startsWith("{")) return false;
|
|
1867
|
+
try {
|
|
1868
|
+
const obj = JSON.parse(val);
|
|
1869
|
+
return obj && typeof obj === "object" && "preferences" in obj && "version" in obj;
|
|
1870
|
+
} catch {
|
|
1871
|
+
return false;
|
|
1872
|
+
}
|
|
1873
|
+
}
|
|
1416
1874
|
function detectConsentCookieName() {
|
|
1417
|
-
|
|
1875
|
+
const currentDocument = globalThis.document;
|
|
1876
|
+
if (currentDocument === void 0 || !currentDocument.cookie) return null;
|
|
1418
1877
|
try {
|
|
1419
|
-
const pairs =
|
|
1878
|
+
const pairs = currentDocument.cookie.split(";").map((s) => s.trim()).filter(Boolean);
|
|
1420
1879
|
for (const p of pairs) {
|
|
1421
1880
|
const [name, ...rest] = p.split("=");
|
|
1422
1881
|
const raw = rest.join("=");
|
|
1423
1882
|
if (!raw) continue;
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
} catch {
|
|
1428
|
-
}
|
|
1429
|
-
if (val.startsWith("{")) {
|
|
1430
|
-
try {
|
|
1431
|
-
const obj = JSON.parse(val);
|
|
1432
|
-
if (obj && typeof obj === "object" && "preferences" in obj && "version" in obj) {
|
|
1433
|
-
return name;
|
|
1434
|
-
}
|
|
1435
|
-
} catch {
|
|
1436
|
-
}
|
|
1883
|
+
const val = tryDecode(raw);
|
|
1884
|
+
if (isConsentJson(val)) {
|
|
1885
|
+
return name;
|
|
1437
1886
|
}
|
|
1438
1887
|
}
|
|
1439
1888
|
} catch {
|
|
@@ -1475,15 +1924,6 @@ function CategoriesProvider({
|
|
|
1475
1924
|
disableDiscoveryLog
|
|
1476
1925
|
}) {
|
|
1477
1926
|
const [impliedVersion, setImpliedVersion] = React4__namespace.useState(0);
|
|
1478
|
-
React4__namespace.useEffect(() => {
|
|
1479
|
-
const handler = () => setImpliedVersion((v) => v + 1);
|
|
1480
|
-
if (typeof window !== "undefined" && typeof window.addEventListener === "function") {
|
|
1481
|
-
window.addEventListener("lgpd:requiredCategories", handler);
|
|
1482
|
-
return () => window.removeEventListener("lgpd:requiredCategories", handler);
|
|
1483
|
-
}
|
|
1484
|
-
return () => {
|
|
1485
|
-
};
|
|
1486
|
-
}, []);
|
|
1487
1927
|
const contextValue = React4__namespace.useMemo(() => {
|
|
1488
1928
|
const finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
|
|
1489
1929
|
const guidance = analyzeDeveloperConfiguration(config);
|
|
@@ -1495,35 +1935,47 @@ function CategoriesProvider({
|
|
|
1495
1935
|
allCategories: guidance.activeCategoriesInfo
|
|
1496
1936
|
};
|
|
1497
1937
|
}, [config, impliedVersion]);
|
|
1938
|
+
React4__namespace.useEffect(() => {
|
|
1939
|
+
const currentWindow = globalThis.window;
|
|
1940
|
+
if (!currentWindow || typeof currentWindow.addEventListener !== "function") return;
|
|
1941
|
+
const handler = () => {
|
|
1942
|
+
setImpliedVersion((current) => current + 1);
|
|
1943
|
+
};
|
|
1944
|
+
currentWindow.addEventListener("lgpd:requiredCategories", handler);
|
|
1945
|
+
return () => {
|
|
1946
|
+
currentWindow.removeEventListener("lgpd:requiredCategories", handler);
|
|
1947
|
+
};
|
|
1948
|
+
}, []);
|
|
1498
1949
|
React4__namespace.useEffect(() => {
|
|
1499
1950
|
logDeveloperGuidance(contextValue.guidance, disableDeveloperGuidance);
|
|
1500
1951
|
}, [contextValue.guidance, disableDeveloperGuidance]);
|
|
1501
1952
|
React4__namespace.useEffect(() => {
|
|
1502
1953
|
try {
|
|
1503
1954
|
const gt = globalThis;
|
|
1504
|
-
const env =
|
|
1955
|
+
const env = gt.process?.env?.NODE_ENV;
|
|
1505
1956
|
const isDev2 = env === "development";
|
|
1506
|
-
if (
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1957
|
+
if (isDev2 && gt.__LGPD_DISCOVERY_LOGGED__ !== true && !disableDiscoveryLog) {
|
|
1958
|
+
const discovered = discoverRuntimeCookies();
|
|
1959
|
+
const consentName = detectConsentCookieName() || DEFAULT_COOKIE_OPTS.name;
|
|
1960
|
+
const PREFIX = "[\u{1F36A} LGPD-CONSENT]";
|
|
1961
|
+
if (typeof console !== "undefined") {
|
|
1962
|
+
try {
|
|
1963
|
+
console.group(`${PREFIX} \u{1F50E} Descoberta de cookies (experimental)`);
|
|
1964
|
+
const names = Array.from(
|
|
1965
|
+
new Set([consentName, ...discovered.map((d) => d.name)].filter(Boolean))
|
|
1966
|
+
);
|
|
1967
|
+
const rows = names.map((n) => ({ Cookie: n }));
|
|
1968
|
+
if (typeof console.table === "function") console.table(rows);
|
|
1969
|
+
else console.log(rows);
|
|
1970
|
+
console.info(
|
|
1971
|
+
`${PREFIX} \u2139\uFE0F Estes nomes s\xE3o detectados em tempo de execu\xE7\xE3o. Ajuste ou categorize via APIs de override se necess\xE1rio.`
|
|
1972
|
+
);
|
|
1973
|
+
console.groupEnd();
|
|
1974
|
+
} catch {
|
|
1975
|
+
}
|
|
1524
1976
|
}
|
|
1977
|
+
gt.__LGPD_DISCOVERY_LOGGED__ = true;
|
|
1525
1978
|
}
|
|
1526
|
-
gt.__LGPD_DISCOVERY_LOGGED__ = true;
|
|
1527
1979
|
} catch {
|
|
1528
1980
|
}
|
|
1529
1981
|
}, [disableDiscoveryLog]);
|
|
@@ -1573,7 +2025,7 @@ function createFullConsentState(consented, preferences, source, projectConfig, i
|
|
|
1573
2025
|
isModalOpen
|
|
1574
2026
|
};
|
|
1575
2027
|
}
|
|
1576
|
-
var
|
|
2028
|
+
var BASE_TEXTS = {
|
|
1577
2029
|
// Textos básicos
|
|
1578
2030
|
bannerMessage: "Utilizamos cookies para melhorar sua experi\xEAncia.",
|
|
1579
2031
|
acceptAll: "Aceitar todos",
|
|
@@ -1610,6 +2062,10 @@ var DEFAULT_TEXTS = {
|
|
|
1610
2062
|
transferCountries: void 0
|
|
1611
2063
|
// Exibido se definido
|
|
1612
2064
|
};
|
|
2065
|
+
var DEFAULT_TEXTS = {
|
|
2066
|
+
...BASE_TEXTS,
|
|
2067
|
+
...EXPANDED_DEFAULT_TEXTS
|
|
2068
|
+
};
|
|
1613
2069
|
function reducer(state, action) {
|
|
1614
2070
|
logger.consentState(action.type, state);
|
|
1615
2071
|
switch (action.type) {
|
|
@@ -1693,6 +2149,8 @@ function ConsentProvider({
|
|
|
1693
2149
|
initialState,
|
|
1694
2150
|
categories,
|
|
1695
2151
|
texts: textsProp,
|
|
2152
|
+
language,
|
|
2153
|
+
textVariant,
|
|
1696
2154
|
designTokens,
|
|
1697
2155
|
PreferencesModalComponent,
|
|
1698
2156
|
preferencesModalProps = {},
|
|
@@ -1717,7 +2175,11 @@ function ConsentProvider({
|
|
|
1717
2175
|
onConsentChange,
|
|
1718
2176
|
onAuditLog
|
|
1719
2177
|
}) {
|
|
1720
|
-
const
|
|
2178
|
+
const mergedTexts = React4__namespace.useMemo(() => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }), [textsProp]);
|
|
2179
|
+
const texts = React4__namespace.useMemo(
|
|
2180
|
+
() => resolveTexts(mergedTexts, { language, variant: textVariant }),
|
|
2181
|
+
[mergedTexts, language, textVariant]
|
|
2182
|
+
);
|
|
1721
2183
|
const cookie = React4__namespace.useMemo(() => {
|
|
1722
2184
|
const base = { ...DEFAULT_COOKIE_OPTS, ...cookieOpts ?? {} };
|
|
1723
2185
|
base.name = cookieOpts?.name ?? buildConsentStorageKey({
|
|
@@ -1730,6 +2192,13 @@ function ConsentProvider({
|
|
|
1730
2192
|
return base;
|
|
1731
2193
|
}, [cookieOpts, storage?.domain, storage?.namespace, storage?.version]);
|
|
1732
2194
|
const consentVersion = storage?.version?.trim() || "1";
|
|
2195
|
+
React4__namespace.useEffect(() => {
|
|
2196
|
+
try {
|
|
2197
|
+
;
|
|
2198
|
+
globalThis.__LGPD_CONSENT_COOKIE__ = cookie.name;
|
|
2199
|
+
} catch {
|
|
2200
|
+
}
|
|
2201
|
+
}, [cookie.name]);
|
|
1733
2202
|
const finalCategoriesConfig = React4__namespace.useMemo(() => {
|
|
1734
2203
|
const isProd = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
1735
2204
|
if (!categories) return DEFAULT_PROJECT_CATEGORIES;
|
|
@@ -2092,51 +2561,100 @@ function ConsentGate(props) {
|
|
|
2092
2561
|
|
|
2093
2562
|
// src/utils/scriptLoader.ts
|
|
2094
2563
|
var LOADING_SCRIPTS = /* @__PURE__ */ new Map();
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2564
|
+
var DEFAULT_POLL_INTERVAL = 100;
|
|
2565
|
+
function resolveCookieNames(preferred) {
|
|
2566
|
+
const inferred = globalThis.__LGPD_CONSENT_COOKIE__ ?? null;
|
|
2567
|
+
const names = [preferred, inferred, "cookieConsent", "lgpd-consent__v1"].filter(
|
|
2568
|
+
Boolean
|
|
2569
|
+
);
|
|
2570
|
+
return Array.from(new Set(names));
|
|
2571
|
+
}
|
|
2572
|
+
function parseConsentFromCookie(names) {
|
|
2573
|
+
const raw = document.cookie;
|
|
2574
|
+
if (!raw) return null;
|
|
2575
|
+
const cookies = raw.split("; ").reduce((acc, part) => {
|
|
2576
|
+
const [k, ...rest] = part.split("=");
|
|
2577
|
+
acc[k] = rest.join("=");
|
|
2578
|
+
return acc;
|
|
2579
|
+
}, {});
|
|
2580
|
+
for (const name of names) {
|
|
2581
|
+
const value = cookies[name];
|
|
2582
|
+
if (!value) continue;
|
|
2583
|
+
try {
|
|
2584
|
+
const parsed = JSON.parse(decodeURIComponent(value));
|
|
2585
|
+
if (!parsed.consented || parsed.isModalOpen) continue;
|
|
2586
|
+
return parsed;
|
|
2587
|
+
} catch {
|
|
2588
|
+
continue;
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
return null;
|
|
2592
|
+
}
|
|
2593
|
+
function hasCategoryConsent(snapshot, category) {
|
|
2594
|
+
if (!snapshot.consented || snapshot.isModalOpen) return false;
|
|
2595
|
+
if (category === null) return true;
|
|
2596
|
+
return Boolean(snapshot.preferences?.[category]);
|
|
2597
|
+
}
|
|
2598
|
+
function loadScript(id, src, category = null, attrs = {}, nonce, options) {
|
|
2599
|
+
const currentDocument = globalThis.document;
|
|
2600
|
+
if (!src || currentDocument === void 0) return Promise.resolve();
|
|
2601
|
+
if (currentDocument.getElementById(id)) return Promise.resolve();
|
|
2098
2602
|
const existingPromise = LOADING_SCRIPTS.get(id);
|
|
2099
2603
|
if (existingPromise) return existingPromise;
|
|
2604
|
+
const pollInterval = options?.pollIntervalMs ?? DEFAULT_POLL_INTERVAL;
|
|
2605
|
+
const names = resolveCookieNames(options?.cookieName);
|
|
2606
|
+
const mergedAttrs = { ...attrs };
|
|
2100
2607
|
const promise = new Promise((resolve, reject) => {
|
|
2608
|
+
const inject = () => {
|
|
2609
|
+
const s = currentDocument.createElement("script");
|
|
2610
|
+
s.id = id;
|
|
2611
|
+
s.src = src;
|
|
2612
|
+
s.async = mergedAttrs.async !== "false";
|
|
2613
|
+
const scriptNonce = mergedAttrs.nonce || nonce;
|
|
2614
|
+
if (scriptNonce) {
|
|
2615
|
+
s.nonce = scriptNonce;
|
|
2616
|
+
mergedAttrs.nonce = scriptNonce;
|
|
2617
|
+
}
|
|
2618
|
+
for (const [k, v] of Object.entries(mergedAttrs)) s.setAttribute(k, v);
|
|
2619
|
+
s.onload = () => {
|
|
2620
|
+
LOADING_SCRIPTS.delete(id);
|
|
2621
|
+
resolve();
|
|
2622
|
+
};
|
|
2623
|
+
s.onerror = () => {
|
|
2624
|
+
LOADING_SCRIPTS.delete(id);
|
|
2625
|
+
reject(new Error(`Failed to load script: ${src}`));
|
|
2626
|
+
};
|
|
2627
|
+
currentDocument.body.appendChild(s);
|
|
2628
|
+
};
|
|
2629
|
+
const snapshot = options?.consentSnapshot;
|
|
2630
|
+
const skipChecks = options?.skipConsentCheck === true;
|
|
2631
|
+
if (skipChecks) {
|
|
2632
|
+
inject();
|
|
2633
|
+
return;
|
|
2634
|
+
}
|
|
2635
|
+
if (snapshot) {
|
|
2636
|
+
if (!hasCategoryConsent(snapshot, category)) {
|
|
2637
|
+
reject(
|
|
2638
|
+
new Error(
|
|
2639
|
+
`Consent not granted for category '${category ?? "none"}' when attempting to load ${id}`
|
|
2640
|
+
)
|
|
2641
|
+
);
|
|
2642
|
+
return;
|
|
2643
|
+
}
|
|
2644
|
+
inject();
|
|
2645
|
+
return;
|
|
2646
|
+
}
|
|
2101
2647
|
const checkConsent = () => {
|
|
2102
|
-
const
|
|
2103
|
-
if (!
|
|
2104
|
-
setTimeout(checkConsent,
|
|
2648
|
+
const consent = parseConsentFromCookie(names);
|
|
2649
|
+
if (!consent) {
|
|
2650
|
+
setTimeout(checkConsent, pollInterval);
|
|
2105
2651
|
return;
|
|
2106
2652
|
}
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
setTimeout(checkConsent, 100);
|
|
2111
|
-
return;
|
|
2112
|
-
}
|
|
2113
|
-
if (category && !consent.preferences[category]) {
|
|
2114
|
-
setTimeout(checkConsent, 100);
|
|
2115
|
-
return;
|
|
2116
|
-
}
|
|
2117
|
-
const s = document.createElement("script");
|
|
2118
|
-
s.id = id;
|
|
2119
|
-
s.src = src;
|
|
2120
|
-
s.async = true;
|
|
2121
|
-
const mergedAttrs = { ...attrs };
|
|
2122
|
-
const scriptNonce = mergedAttrs.nonce || nonce;
|
|
2123
|
-
if (scriptNonce) {
|
|
2124
|
-
s.nonce = scriptNonce;
|
|
2125
|
-
mergedAttrs.nonce = scriptNonce;
|
|
2126
|
-
}
|
|
2127
|
-
for (const [k, v] of Object.entries(mergedAttrs)) s.setAttribute(k, v);
|
|
2128
|
-
s.onload = () => {
|
|
2129
|
-
LOADING_SCRIPTS.delete(id);
|
|
2130
|
-
resolve();
|
|
2131
|
-
};
|
|
2132
|
-
s.onerror = () => {
|
|
2133
|
-
LOADING_SCRIPTS.delete(id);
|
|
2134
|
-
reject(new Error(`Failed to load script: ${src}`));
|
|
2135
|
-
};
|
|
2136
|
-
document.body.appendChild(s);
|
|
2137
|
-
} catch {
|
|
2138
|
-
setTimeout(checkConsent, 100);
|
|
2653
|
+
if (!hasCategoryConsent(consent, category)) {
|
|
2654
|
+
setTimeout(checkConsent, pollInterval);
|
|
2655
|
+
return;
|
|
2139
2656
|
}
|
|
2657
|
+
inject();
|
|
2140
2658
|
};
|
|
2141
2659
|
checkConsent();
|
|
2142
2660
|
});
|
|
@@ -2300,14 +2818,107 @@ function validateNecessaryClassification(integrations, enabledCategories) {
|
|
|
2300
2818
|
}
|
|
2301
2819
|
|
|
2302
2820
|
// src/utils/ConsentScriptLoader.tsx
|
|
2821
|
+
var scriptRegistry = /* @__PURE__ */ new Map();
|
|
2822
|
+
var queueListeners = /* @__PURE__ */ new Set();
|
|
2823
|
+
function notifyQueue() {
|
|
2824
|
+
queueListeners.forEach((listener) => {
|
|
2825
|
+
try {
|
|
2826
|
+
listener();
|
|
2827
|
+
} catch {
|
|
2828
|
+
}
|
|
2829
|
+
});
|
|
2830
|
+
}
|
|
2831
|
+
function subscribeQueue(listener) {
|
|
2832
|
+
queueListeners.add(listener);
|
|
2833
|
+
return () => {
|
|
2834
|
+
queueListeners.delete(listener);
|
|
2835
|
+
};
|
|
2836
|
+
}
|
|
2837
|
+
function createInternalScript(def) {
|
|
2838
|
+
return {
|
|
2839
|
+
...def,
|
|
2840
|
+
status: "pending",
|
|
2841
|
+
lastAllowed: false,
|
|
2842
|
+
registeredAt: Date.now(),
|
|
2843
|
+
token: Date.now() + Math.random(),
|
|
2844
|
+
priority: def.priority ?? 0,
|
|
2845
|
+
allowReload: def.allowReload ?? false,
|
|
2846
|
+
onConsentUpdate: def.onConsentUpdate
|
|
2847
|
+
};
|
|
2848
|
+
}
|
|
2849
|
+
function registerScript(def) {
|
|
2850
|
+
const entry = createInternalScript(def);
|
|
2851
|
+
scriptRegistry.set(def.id, entry);
|
|
2852
|
+
notifyQueue();
|
|
2853
|
+
return () => {
|
|
2854
|
+
const current = scriptRegistry.get(def.id);
|
|
2855
|
+
if (current && current.token === entry.token) {
|
|
2856
|
+
scriptRegistry.delete(def.id);
|
|
2857
|
+
notifyQueue();
|
|
2858
|
+
}
|
|
2859
|
+
};
|
|
2860
|
+
}
|
|
2861
|
+
function getExecutableScripts(consent) {
|
|
2862
|
+
const allowedScripts = [];
|
|
2863
|
+
scriptRegistry.forEach((script) => {
|
|
2864
|
+
const categoryAllowed = script.category === "necessary" || consent.consented && Boolean(consent.preferences?.[script.category]);
|
|
2865
|
+
if (!categoryAllowed) {
|
|
2866
|
+
script.lastAllowed = false;
|
|
2867
|
+
return;
|
|
2868
|
+
}
|
|
2869
|
+
if (script.status === "running") return;
|
|
2870
|
+
if (script.status === "executed" && !script.allowReload) return;
|
|
2871
|
+
if (script.status === "executed" && script.allowReload && script.lastAllowed) return;
|
|
2872
|
+
script.lastAllowed = true;
|
|
2873
|
+
allowedScripts.push(script);
|
|
2874
|
+
});
|
|
2875
|
+
return allowedScripts.sort((a, b) => {
|
|
2876
|
+
if (a.category === "necessary" && b.category !== "necessary") return -1;
|
|
2877
|
+
if (b.category === "necessary" && a.category !== "necessary") return 1;
|
|
2878
|
+
if (a.category !== b.category) return a.category.localeCompare(b.category);
|
|
2879
|
+
if (a.priority !== b.priority) return (b.priority ?? 0) - (a.priority ?? 0);
|
|
2880
|
+
return a.registeredAt - b.registeredAt;
|
|
2881
|
+
});
|
|
2882
|
+
}
|
|
2883
|
+
async function processQueue(consent, devLogging) {
|
|
2884
|
+
const scripts = getExecutableScripts(consent);
|
|
2885
|
+
let order = 0;
|
|
2886
|
+
for (const script of scripts) {
|
|
2887
|
+
order += 1;
|
|
2888
|
+
script.status = "running";
|
|
2889
|
+
if (devLogging) {
|
|
2890
|
+
logger.info("[ConsentScriptLoader] executando script", {
|
|
2891
|
+
id: script.id,
|
|
2892
|
+
category: script.category,
|
|
2893
|
+
priority: script.priority ?? 0,
|
|
2894
|
+
order
|
|
2895
|
+
});
|
|
2896
|
+
}
|
|
2897
|
+
try {
|
|
2898
|
+
await Promise.resolve(script.execute());
|
|
2899
|
+
} catch (error) {
|
|
2900
|
+
logger.error(`\u274C Failed to execute script ${script.id}`, error);
|
|
2901
|
+
} finally {
|
|
2902
|
+
script.status = "executed";
|
|
2903
|
+
if (script.onConsentUpdate) {
|
|
2904
|
+
script.onConsentUpdate(consent);
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2303
2909
|
function ConsentScriptLoader({
|
|
2304
2910
|
integrations,
|
|
2305
2911
|
reloadOnChange = false,
|
|
2306
2912
|
nonce
|
|
2307
2913
|
}) {
|
|
2308
2914
|
const { preferences, consented } = useConsent();
|
|
2915
|
+
const isHydrated = useConsentHydration();
|
|
2309
2916
|
const categories = useCategories();
|
|
2310
|
-
const
|
|
2917
|
+
const [queueVersion, bumpQueueVersion] = React4__namespace.useState(0);
|
|
2918
|
+
React4__namespace.useEffect(() => {
|
|
2919
|
+
const unsubscribe = subscribeQueue(() => bumpQueueVersion((v) => v + 1));
|
|
2920
|
+
return unsubscribe;
|
|
2921
|
+
}, []);
|
|
2311
2922
|
React4__namespace.useEffect(() => {
|
|
2312
2923
|
try {
|
|
2313
2924
|
const ids = (integrations || []).map((i) => i.id);
|
|
@@ -2368,15 +2979,44 @@ function ConsentScriptLoader({
|
|
|
2368
2979
|
console.groupEnd();
|
|
2369
2980
|
}
|
|
2370
2981
|
}, [integrations, categories]);
|
|
2982
|
+
const processedIntegrationsRef = React4__namespace.useRef(/* @__PURE__ */ new Map());
|
|
2371
2983
|
React4__namespace.useEffect(() => {
|
|
2372
|
-
|
|
2373
|
-
const
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2984
|
+
const cleanups = [];
|
|
2985
|
+
const currentIds = /* @__PURE__ */ new Set();
|
|
2986
|
+
integrations.forEach((integration) => {
|
|
2987
|
+
currentIds.add(integration.id);
|
|
2988
|
+
const structuralHash = JSON.stringify({
|
|
2989
|
+
category: integration.category,
|
|
2990
|
+
src: integration.src,
|
|
2991
|
+
priority: integration.priority,
|
|
2992
|
+
hasBootstrap: Boolean(integration.bootstrap),
|
|
2993
|
+
hasInit: Boolean(integration.init),
|
|
2994
|
+
hasOnConsentUpdate: Boolean(integration.onConsentUpdate)
|
|
2995
|
+
});
|
|
2996
|
+
const existingHash = processedIntegrationsRef.current.get(integration.id);
|
|
2997
|
+
if (existingHash === structuralHash && scriptRegistry.has(integration.id)) {
|
|
2998
|
+
return;
|
|
2999
|
+
}
|
|
3000
|
+
processedIntegrationsRef.current.set(integration.id, structuralHash);
|
|
3001
|
+
if (integration.bootstrap) {
|
|
3002
|
+
cleanups.push(
|
|
3003
|
+
registerScript({
|
|
3004
|
+
id: `${integration.id}__bootstrap`,
|
|
3005
|
+
category: "necessary",
|
|
3006
|
+
priority: (integration.priority ?? 0) + 1e3,
|
|
3007
|
+
execute: integration.bootstrap
|
|
3008
|
+
})
|
|
3009
|
+
);
|
|
3010
|
+
}
|
|
3011
|
+
cleanups.push(
|
|
3012
|
+
registerScript({
|
|
3013
|
+
id: integration.id,
|
|
3014
|
+
category: integration.category,
|
|
3015
|
+
priority: integration.priority,
|
|
3016
|
+
allowReload: reloadOnChange,
|
|
3017
|
+
onConsentUpdate: integration.onConsentUpdate,
|
|
3018
|
+
execute: async () => {
|
|
3019
|
+
const mergedAttrs = integration.attrs ? { ...integration.attrs } : {};
|
|
2380
3020
|
const scriptNonce = integration.nonce ?? nonce;
|
|
2381
3021
|
if (scriptNonce && !mergedAttrs.nonce) mergedAttrs.nonce = scriptNonce;
|
|
2382
3022
|
await loadScript(
|
|
@@ -2384,26 +3024,54 @@ function ConsentScriptLoader({
|
|
|
2384
3024
|
integration.src,
|
|
2385
3025
|
integration.category,
|
|
2386
3026
|
mergedAttrs,
|
|
2387
|
-
scriptNonce
|
|
3027
|
+
scriptNonce,
|
|
3028
|
+
{ skipConsentCheck: true }
|
|
2388
3029
|
);
|
|
2389
3030
|
if (integration.init) {
|
|
2390
3031
|
integration.init();
|
|
2391
3032
|
}
|
|
2392
|
-
loadedScripts.current.add(integration.id);
|
|
2393
|
-
} catch (error) {
|
|
2394
|
-
logger.error(`\u274C Failed to load script: ${integration.id}`, error);
|
|
2395
3033
|
}
|
|
3034
|
+
})
|
|
3035
|
+
);
|
|
3036
|
+
});
|
|
3037
|
+
processedIntegrationsRef.current.forEach((_, id) => {
|
|
3038
|
+
if (!currentIds.has(id)) {
|
|
3039
|
+
processedIntegrationsRef.current.delete(id);
|
|
3040
|
+
const script = scriptRegistry.get(id);
|
|
3041
|
+
if (script) {
|
|
3042
|
+
scriptRegistry.delete(id);
|
|
3043
|
+
}
|
|
3044
|
+
const bootstrapScript = scriptRegistry.get(`${id}__bootstrap`);
|
|
3045
|
+
if (bootstrapScript) {
|
|
3046
|
+
scriptRegistry.delete(`${id}__bootstrap`);
|
|
2396
3047
|
}
|
|
2397
3048
|
}
|
|
2398
|
-
}
|
|
2399
|
-
return () =>
|
|
2400
|
-
}, [
|
|
3049
|
+
});
|
|
3050
|
+
return () => cleanups.forEach((fn) => fn());
|
|
3051
|
+
}, [integrations, reloadOnChange, nonce]);
|
|
3052
|
+
React4__namespace.useEffect(() => {
|
|
3053
|
+
if (!isHydrated) return;
|
|
3054
|
+
void processQueue({ consented, preferences }, process.env.NODE_ENV !== "production");
|
|
3055
|
+
}, [consented, preferences, isHydrated, queueVersion]);
|
|
3056
|
+
React4__namespace.useEffect(() => {
|
|
3057
|
+
if (!isHydrated) return;
|
|
3058
|
+
scriptRegistry.forEach((script) => {
|
|
3059
|
+
if (script.status !== "executed") return;
|
|
3060
|
+
if (typeof script.onConsentUpdate !== "function") return;
|
|
3061
|
+
script.onConsentUpdate({ consented, preferences });
|
|
3062
|
+
});
|
|
3063
|
+
}, [consented, preferences, isHydrated]);
|
|
2401
3064
|
return null;
|
|
2402
3065
|
}
|
|
2403
3066
|
function useConsentScriptLoader() {
|
|
2404
3067
|
const { preferences, consented } = useConsent();
|
|
3068
|
+
const isHydrated = useConsentHydration();
|
|
2405
3069
|
return React4__namespace.useCallback(
|
|
2406
3070
|
async (integration, nonce) => {
|
|
3071
|
+
if (!isHydrated) {
|
|
3072
|
+
logger.warn(`\u26A0\uFE0F Cannot load script ${integration.id}: Consent not hydrated yet`);
|
|
3073
|
+
return false;
|
|
3074
|
+
}
|
|
2407
3075
|
if (!consented) {
|
|
2408
3076
|
logger.warn(`\u26A0\uFE0F Cannot load script ${integration.id}: No consent given`);
|
|
2409
3077
|
return false;
|
|
@@ -2424,7 +3092,11 @@ function useConsentScriptLoader() {
|
|
|
2424
3092
|
integration.src,
|
|
2425
3093
|
integration.category,
|
|
2426
3094
|
mergedAttrs,
|
|
2427
|
-
scriptNonce
|
|
3095
|
+
scriptNonce,
|
|
3096
|
+
{
|
|
3097
|
+
consentSnapshot: { consented, preferences },
|
|
3098
|
+
skipConsentCheck: true
|
|
3099
|
+
}
|
|
2428
3100
|
);
|
|
2429
3101
|
if (integration.init) {
|
|
2430
3102
|
integration.init();
|
|
@@ -2435,16 +3107,129 @@ function useConsentScriptLoader() {
|
|
|
2435
3107
|
return false;
|
|
2436
3108
|
}
|
|
2437
3109
|
},
|
|
2438
|
-
[preferences, consented]
|
|
3110
|
+
[preferences, consented, isHydrated]
|
|
2439
3111
|
);
|
|
2440
3112
|
}
|
|
2441
3113
|
|
|
2442
3114
|
// src/utils/scriptIntegrations.ts
|
|
3115
|
+
function createSuggestedIntegration(config) {
|
|
3116
|
+
const suggested = suggestCategoryForScript(config.id)[0] ?? "analytics";
|
|
3117
|
+
const category = resolveCategory(suggested, config.category);
|
|
3118
|
+
const { category: _ignored, ...rest } = config;
|
|
3119
|
+
return { ...rest, category };
|
|
3120
|
+
}
|
|
3121
|
+
var resolveCategory = (fallback, override) => {
|
|
3122
|
+
if (typeof override === "string" && override.trim().length > 0) return override.trim();
|
|
3123
|
+
return fallback;
|
|
3124
|
+
};
|
|
3125
|
+
var isDevEnv = () => {
|
|
3126
|
+
const env = typeof globalThis !== "undefined" ? globalThis.process?.env?.NODE_ENV : void 0;
|
|
3127
|
+
return env !== "production";
|
|
3128
|
+
};
|
|
3129
|
+
var resolveRequiredString = (value, field, integrationId) => {
|
|
3130
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
3131
|
+
if (isDevEnv()) {
|
|
3132
|
+
console.error(
|
|
3133
|
+
`[LGPD-CONSENT] Config inv\xE1lida: integra\xE7\xE3o "${integrationId}" requer "${field}".`
|
|
3134
|
+
);
|
|
3135
|
+
}
|
|
3136
|
+
return null;
|
|
3137
|
+
}
|
|
3138
|
+
return value.trim();
|
|
3139
|
+
};
|
|
3140
|
+
function buildConsentModeSignals(preferences) {
|
|
3141
|
+
const analytics = preferences.analytics ? "granted" : "denied";
|
|
3142
|
+
const marketing = preferences.marketing ? "granted" : "denied";
|
|
3143
|
+
return {
|
|
3144
|
+
ad_storage: marketing,
|
|
3145
|
+
ad_user_data: marketing,
|
|
3146
|
+
ad_personalization: marketing,
|
|
3147
|
+
analytics_storage: analytics
|
|
3148
|
+
};
|
|
3149
|
+
}
|
|
3150
|
+
function pushToLayer(entry, dataLayerName) {
|
|
3151
|
+
const currentWindow = globalThis.window;
|
|
3152
|
+
if (currentWindow === void 0) return;
|
|
3153
|
+
const registry = currentWindow;
|
|
3154
|
+
const name = dataLayerName ?? "dataLayer";
|
|
3155
|
+
const layer = registry[name] ?? [];
|
|
3156
|
+
registry[name] = layer;
|
|
3157
|
+
layer.push(entry);
|
|
3158
|
+
}
|
|
3159
|
+
function ensureGtag(dataLayerName = "dataLayer") {
|
|
3160
|
+
const currentWindow = globalThis.window;
|
|
3161
|
+
if (currentWindow === void 0) return null;
|
|
3162
|
+
const w = currentWindow;
|
|
3163
|
+
const registry = w;
|
|
3164
|
+
const layer = registry[dataLayerName] ?? [];
|
|
3165
|
+
registry[dataLayerName] = layer;
|
|
3166
|
+
if (typeof w.gtag !== "function") {
|
|
3167
|
+
const gtag = (...args) => {
|
|
3168
|
+
layer.push(args);
|
|
3169
|
+
};
|
|
3170
|
+
w.gtag = gtag;
|
|
3171
|
+
}
|
|
3172
|
+
return w.gtag;
|
|
3173
|
+
}
|
|
3174
|
+
function applyDefaultConsentMode(dataLayerName) {
|
|
3175
|
+
const payload = buildConsentModeSignals({
|
|
3176
|
+
analytics: false,
|
|
3177
|
+
marketing: false
|
|
3178
|
+
});
|
|
3179
|
+
const gtag = ensureGtag(dataLayerName);
|
|
3180
|
+
if (gtag) {
|
|
3181
|
+
gtag("consent", "default", payload);
|
|
3182
|
+
}
|
|
3183
|
+
pushToLayer(["consent", "default", payload], dataLayerName);
|
|
3184
|
+
}
|
|
3185
|
+
function applyConsentModeUpdate(preferences, dataLayerName) {
|
|
3186
|
+
const payload = buildConsentModeSignals(preferences);
|
|
3187
|
+
const gtag = ensureGtag(dataLayerName);
|
|
3188
|
+
if (gtag) {
|
|
3189
|
+
gtag("consent", "update", payload);
|
|
3190
|
+
}
|
|
3191
|
+
pushToLayer(["consent", "update", payload], dataLayerName);
|
|
3192
|
+
}
|
|
2443
3193
|
function createGoogleAnalyticsIntegration(config) {
|
|
2444
|
-
const
|
|
3194
|
+
const category = resolveCategory("analytics", config.category);
|
|
3195
|
+
const measurementId = resolveRequiredString(
|
|
3196
|
+
config.measurementId,
|
|
3197
|
+
"measurementId",
|
|
3198
|
+
"google-analytics"
|
|
3199
|
+
);
|
|
3200
|
+
if (!measurementId) {
|
|
3201
|
+
return {
|
|
3202
|
+
id: "google-analytics",
|
|
3203
|
+
category,
|
|
3204
|
+
src: "",
|
|
3205
|
+
cookies: ["_ga", "_ga_*", "_gid"],
|
|
3206
|
+
cookiesInfo: [
|
|
3207
|
+
{
|
|
3208
|
+
name: "_ga",
|
|
3209
|
+
purpose: "Identifica\xE7\xE3o \xFAnica de visitantes para an\xE1lise de tr\xE1fego",
|
|
3210
|
+
duration: "2 anos",
|
|
3211
|
+
provider: "Google Analytics"
|
|
3212
|
+
},
|
|
3213
|
+
{
|
|
3214
|
+
name: "_ga_*",
|
|
3215
|
+
purpose: "Rastreamento de sess\xF5es e eventos espec\xEDficos do stream GA4",
|
|
3216
|
+
duration: "2 anos",
|
|
3217
|
+
provider: "Google Analytics"
|
|
3218
|
+
},
|
|
3219
|
+
{
|
|
3220
|
+
name: "_gid",
|
|
3221
|
+
purpose: "Distin\xE7\xE3o de visitantes \xFAnicos em per\xEDodo de 24h",
|
|
3222
|
+
duration: "24 horas",
|
|
3223
|
+
provider: "Google Analytics"
|
|
3224
|
+
}
|
|
3225
|
+
],
|
|
3226
|
+
attrs: { async: "true" }
|
|
3227
|
+
};
|
|
3228
|
+
}
|
|
3229
|
+
const src = config.scriptUrl ?? `https://www.googletagmanager.com/gtag/js?id=${measurementId}`;
|
|
2445
3230
|
return {
|
|
2446
3231
|
id: "google-analytics",
|
|
2447
|
-
category
|
|
3232
|
+
category,
|
|
2448
3233
|
src,
|
|
2449
3234
|
cookies: ["_ga", "_ga_*", "_gid"],
|
|
2450
3235
|
cookiesInfo: [
|
|
@@ -2467,32 +3252,49 @@ function createGoogleAnalyticsIntegration(config) {
|
|
|
2467
3252
|
provider: "Google Analytics"
|
|
2468
3253
|
}
|
|
2469
3254
|
],
|
|
3255
|
+
bootstrap: () => {
|
|
3256
|
+
applyDefaultConsentMode();
|
|
3257
|
+
},
|
|
3258
|
+
onConsentUpdate: ({ preferences }) => {
|
|
3259
|
+
applyConsentModeUpdate(preferences);
|
|
3260
|
+
},
|
|
2470
3261
|
init: () => {
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
w.dataLayer.push(...args);
|
|
2476
|
-
};
|
|
2477
|
-
w.gtag = gtag;
|
|
2478
|
-
gtag("js", /* @__PURE__ */ new Date());
|
|
2479
|
-
gtag("config", config.measurementId, config.config ?? {});
|
|
2480
|
-
}
|
|
3262
|
+
const gtag = ensureGtag();
|
|
3263
|
+
if (!gtag) return;
|
|
3264
|
+
gtag("js", /* @__PURE__ */ new Date());
|
|
3265
|
+
gtag("config", measurementId, config.config ?? {});
|
|
2481
3266
|
},
|
|
2482
3267
|
attrs: { async: "true" }
|
|
2483
3268
|
};
|
|
2484
3269
|
}
|
|
2485
3270
|
function createGoogleTagManagerIntegration(config) {
|
|
2486
|
-
const
|
|
3271
|
+
const category = resolveCategory("analytics", config.category);
|
|
3272
|
+
const containerId = resolveRequiredString(config.containerId, "containerId", "google-tag-manager");
|
|
3273
|
+
if (!containerId) {
|
|
3274
|
+
return {
|
|
3275
|
+
id: "google-tag-manager",
|
|
3276
|
+
category,
|
|
3277
|
+
src: "",
|
|
3278
|
+
cookies: ["_gcl_au"]
|
|
3279
|
+
};
|
|
3280
|
+
}
|
|
3281
|
+
const src = config.scriptUrl ?? `https://www.googletagmanager.com/gtm.js?id=${containerId}`;
|
|
2487
3282
|
return {
|
|
2488
3283
|
id: "google-tag-manager",
|
|
2489
|
-
category
|
|
3284
|
+
category,
|
|
2490
3285
|
src,
|
|
2491
3286
|
cookies: ["_gcl_au"],
|
|
3287
|
+
bootstrap: () => {
|
|
3288
|
+
applyDefaultConsentMode(config.dataLayerName);
|
|
3289
|
+
},
|
|
3290
|
+
onConsentUpdate: ({ preferences }) => {
|
|
3291
|
+
applyConsentModeUpdate(preferences, config.dataLayerName);
|
|
3292
|
+
},
|
|
2492
3293
|
init: () => {
|
|
2493
|
-
|
|
3294
|
+
const currentWindow = globalThis.window;
|
|
3295
|
+
if (currentWindow !== void 0) {
|
|
2494
3296
|
const dataLayerName = config.dataLayerName || "dataLayer";
|
|
2495
|
-
const w =
|
|
3297
|
+
const w = currentWindow;
|
|
2496
3298
|
const layer = w[dataLayerName] ?? [];
|
|
2497
3299
|
w[dataLayerName] = layer;
|
|
2498
3300
|
layer.push({ "gtm.start": Date.now(), event: "gtm.js" });
|
|
@@ -2501,20 +3303,31 @@ function createGoogleTagManagerIntegration(config) {
|
|
|
2501
3303
|
};
|
|
2502
3304
|
}
|
|
2503
3305
|
function createUserWayIntegration(config) {
|
|
3306
|
+
const category = resolveCategory("functional", config.category);
|
|
3307
|
+
const accountId = resolveRequiredString(config.accountId, "accountId", "userway");
|
|
3308
|
+
if (!accountId) {
|
|
3309
|
+
return {
|
|
3310
|
+
id: "userway",
|
|
3311
|
+
category,
|
|
3312
|
+
src: "",
|
|
3313
|
+
cookies: ["_userway_*"]
|
|
3314
|
+
};
|
|
3315
|
+
}
|
|
2504
3316
|
const src = config.scriptUrl ?? "https://cdn.userway.org/widget.js";
|
|
2505
3317
|
return {
|
|
2506
3318
|
id: "userway",
|
|
2507
|
-
category
|
|
3319
|
+
category,
|
|
2508
3320
|
src,
|
|
2509
3321
|
cookies: ["_userway_*"],
|
|
2510
3322
|
init: () => {
|
|
2511
|
-
|
|
2512
|
-
|
|
3323
|
+
const currentWindow = globalThis.window;
|
|
3324
|
+
if (currentWindow !== void 0) {
|
|
3325
|
+
const w = currentWindow;
|
|
2513
3326
|
w.UserWayWidgetApp = w.UserWayWidgetApp || {};
|
|
2514
|
-
w.UserWayWidgetApp.accountId =
|
|
3327
|
+
w.UserWayWidgetApp.accountId = accountId;
|
|
2515
3328
|
}
|
|
2516
3329
|
},
|
|
2517
|
-
attrs: { "data-account":
|
|
3330
|
+
attrs: { "data-account": accountId }
|
|
2518
3331
|
};
|
|
2519
3332
|
}
|
|
2520
3333
|
var COMMON_INTEGRATIONS = {
|
|
@@ -2523,15 +3336,26 @@ var COMMON_INTEGRATIONS = {
|
|
|
2523
3336
|
userway: createUserWayIntegration
|
|
2524
3337
|
};
|
|
2525
3338
|
function createFacebookPixelIntegration(config) {
|
|
3339
|
+
const category = resolveCategory("marketing", config.category);
|
|
3340
|
+
const pixelId = resolveRequiredString(config.pixelId, "pixelId", "facebook-pixel");
|
|
3341
|
+
if (!pixelId) {
|
|
3342
|
+
return {
|
|
3343
|
+
id: "facebook-pixel",
|
|
3344
|
+
category,
|
|
3345
|
+
src: "",
|
|
3346
|
+
cookies: ["_fbp", "fr"]
|
|
3347
|
+
};
|
|
3348
|
+
}
|
|
2526
3349
|
const src = config.scriptUrl ?? "https://connect.facebook.net/en_US/fbevents.js";
|
|
2527
3350
|
return {
|
|
2528
3351
|
id: "facebook-pixel",
|
|
2529
|
-
category
|
|
3352
|
+
category,
|
|
2530
3353
|
src,
|
|
2531
3354
|
cookies: ["_fbp", "fr"],
|
|
2532
3355
|
init: () => {
|
|
2533
|
-
|
|
2534
|
-
|
|
3356
|
+
const currentWindow = globalThis.window;
|
|
3357
|
+
if (currentWindow !== void 0) {
|
|
3358
|
+
const w = currentWindow;
|
|
2535
3359
|
if (!w.fbq) {
|
|
2536
3360
|
const fbq = (...args) => {
|
|
2537
3361
|
if (w.fbq && typeof w.fbq.callMethod === "function") {
|
|
@@ -2544,18 +3368,34 @@ function createFacebookPixelIntegration(config) {
|
|
|
2544
3368
|
fbq.loaded = true;
|
|
2545
3369
|
w.fbq = fbq;
|
|
2546
3370
|
}
|
|
2547
|
-
w.fbq("init",
|
|
3371
|
+
w.fbq("init", pixelId, config.advancedMatching ?? {});
|
|
2548
3372
|
if (config.autoTrack !== false) w.fbq("track", "PageView");
|
|
2549
3373
|
}
|
|
2550
3374
|
}
|
|
2551
3375
|
};
|
|
2552
3376
|
}
|
|
2553
3377
|
function createHotjarIntegration(config) {
|
|
3378
|
+
const category = resolveCategory("analytics", config.category);
|
|
3379
|
+
const siteId = resolveRequiredString(config.siteId, "siteId", "hotjar");
|
|
2554
3380
|
const v = config.version ?? 6;
|
|
2555
|
-
|
|
3381
|
+
if (!siteId) {
|
|
3382
|
+
return {
|
|
3383
|
+
id: "hotjar",
|
|
3384
|
+
category,
|
|
3385
|
+
src: "",
|
|
3386
|
+
cookies: [
|
|
3387
|
+
"_hjSession_*",
|
|
3388
|
+
"_hjSessionUser_*",
|
|
3389
|
+
"_hjFirstSeen",
|
|
3390
|
+
"_hjIncludedInSessionSample",
|
|
3391
|
+
"_hjAbsoluteSessionInProgress"
|
|
3392
|
+
]
|
|
3393
|
+
};
|
|
3394
|
+
}
|
|
3395
|
+
const src = config.scriptUrl ?? `https://static.hotjar.com/c/hotjar-${siteId}.js?sv=${v}`;
|
|
2556
3396
|
return {
|
|
2557
3397
|
id: "hotjar",
|
|
2558
|
-
category
|
|
3398
|
+
category,
|
|
2559
3399
|
src,
|
|
2560
3400
|
cookies: [
|
|
2561
3401
|
"_hjSession_*",
|
|
@@ -2597,9 +3437,10 @@ function createHotjarIntegration(config) {
|
|
|
2597
3437
|
}
|
|
2598
3438
|
],
|
|
2599
3439
|
init: () => {
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
w
|
|
3440
|
+
const currentWindow = globalThis.window;
|
|
3441
|
+
if (currentWindow !== void 0) {
|
|
3442
|
+
const w = currentWindow;
|
|
3443
|
+
w._hjSettings = { hjid: siteId, hjsv: v };
|
|
2603
3444
|
if (!w.hj) {
|
|
2604
3445
|
const hj = (...args) => {
|
|
2605
3446
|
hj.q = hj.q || [];
|
|
@@ -2608,17 +3449,35 @@ function createHotjarIntegration(config) {
|
|
|
2608
3449
|
w.hj = hj;
|
|
2609
3450
|
}
|
|
2610
3451
|
if (config.debug && typeof console !== "undefined" && typeof console.info === "function") {
|
|
2611
|
-
console.info("[Hotjar] initialized with siteId",
|
|
3452
|
+
console.info("[Hotjar] initialized with siteId", siteId);
|
|
2612
3453
|
}
|
|
2613
3454
|
}
|
|
2614
3455
|
}
|
|
2615
3456
|
};
|
|
2616
3457
|
}
|
|
2617
3458
|
function createMixpanelIntegration(config) {
|
|
3459
|
+
const category = resolveCategory("analytics", config.category);
|
|
3460
|
+
const token = resolveRequiredString(config.token, "token", "mixpanel");
|
|
3461
|
+
if (!token) {
|
|
3462
|
+
return {
|
|
3463
|
+
id: "mixpanel",
|
|
3464
|
+
category,
|
|
3465
|
+
src: "",
|
|
3466
|
+
cookies: ["mp_*"],
|
|
3467
|
+
cookiesInfo: [
|
|
3468
|
+
{
|
|
3469
|
+
name: "mp_*",
|
|
3470
|
+
purpose: "Rastreamento de eventos e propriedades do usu\xE1rio para analytics",
|
|
3471
|
+
duration: "1 ano",
|
|
3472
|
+
provider: "Mixpanel"
|
|
3473
|
+
}
|
|
3474
|
+
]
|
|
3475
|
+
};
|
|
3476
|
+
}
|
|
2618
3477
|
const src = config.scriptUrl ?? "https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";
|
|
2619
3478
|
return {
|
|
2620
3479
|
id: "mixpanel",
|
|
2621
|
-
category
|
|
3480
|
+
category,
|
|
2622
3481
|
src,
|
|
2623
3482
|
cookies: ["mp_*"],
|
|
2624
3483
|
cookiesInfo: [
|
|
@@ -2630,12 +3489,13 @@ function createMixpanelIntegration(config) {
|
|
|
2630
3489
|
}
|
|
2631
3490
|
],
|
|
2632
3491
|
init: () => {
|
|
2633
|
-
|
|
2634
|
-
|
|
3492
|
+
const currentWindow = globalThis.window;
|
|
3493
|
+
if (currentWindow !== void 0) {
|
|
3494
|
+
const w = currentWindow;
|
|
2635
3495
|
w.mixpanel = w.mixpanel || { init: () => void 0 };
|
|
2636
3496
|
if (w.mixpanel && typeof w.mixpanel.init === "function") {
|
|
2637
3497
|
try {
|
|
2638
|
-
w.mixpanel.init(
|
|
3498
|
+
w.mixpanel.init(token, config.config ?? {}, config.api_host);
|
|
2639
3499
|
} catch (error) {
|
|
2640
3500
|
if (typeof console !== "undefined" && typeof console.warn === "function") {
|
|
2641
3501
|
console.warn("[Mixpanel] Failed to initialize:", error);
|
|
@@ -2647,15 +3507,26 @@ function createMixpanelIntegration(config) {
|
|
|
2647
3507
|
};
|
|
2648
3508
|
}
|
|
2649
3509
|
function createClarityIntegration(config) {
|
|
2650
|
-
const
|
|
3510
|
+
const category = resolveCategory("analytics", config.category);
|
|
3511
|
+
const projectId = resolveRequiredString(config.projectId, "projectId", "clarity");
|
|
3512
|
+
if (!projectId) {
|
|
3513
|
+
return {
|
|
3514
|
+
id: "clarity",
|
|
3515
|
+
category,
|
|
3516
|
+
src: "",
|
|
3517
|
+
cookies: ["_clck", "_clsk", "CLID", "ANONCHK", "MR", "MUID", "SM"]
|
|
3518
|
+
};
|
|
3519
|
+
}
|
|
3520
|
+
const src = config.scriptUrl ?? `https://www.clarity.ms/tag/${projectId}`;
|
|
2651
3521
|
return {
|
|
2652
3522
|
id: "clarity",
|
|
2653
|
-
category
|
|
3523
|
+
category,
|
|
2654
3524
|
src,
|
|
2655
3525
|
cookies: ["_clck", "_clsk", "CLID", "ANONCHK", "MR", "MUID", "SM"],
|
|
2656
3526
|
init: () => {
|
|
2657
|
-
|
|
2658
|
-
|
|
3527
|
+
const currentWindow = globalThis.window;
|
|
3528
|
+
if (currentWindow !== void 0 && typeof config.upload !== "undefined") {
|
|
3529
|
+
const w = currentWindow;
|
|
2659
3530
|
if (typeof w.clarity === "function") {
|
|
2660
3531
|
try {
|
|
2661
3532
|
w.clarity("set", "upload", config.upload);
|
|
@@ -2670,18 +3541,29 @@ function createClarityIntegration(config) {
|
|
|
2670
3541
|
};
|
|
2671
3542
|
}
|
|
2672
3543
|
function createIntercomIntegration(config) {
|
|
2673
|
-
const
|
|
3544
|
+
const category = resolveCategory("functional", config.category);
|
|
3545
|
+
const appId = resolveRequiredString(config.app_id, "app_id", "intercom");
|
|
3546
|
+
if (!appId) {
|
|
3547
|
+
return {
|
|
3548
|
+
id: "intercom",
|
|
3549
|
+
category,
|
|
3550
|
+
src: "",
|
|
3551
|
+
cookies: ["intercom-id-*", "intercom-session-*"]
|
|
3552
|
+
};
|
|
3553
|
+
}
|
|
3554
|
+
const src = config.scriptUrl ?? `https://widget.intercom.io/widget/${appId}`;
|
|
2674
3555
|
return {
|
|
2675
3556
|
id: "intercom",
|
|
2676
|
-
category
|
|
3557
|
+
category,
|
|
2677
3558
|
src,
|
|
2678
3559
|
cookies: ["intercom-id-*", "intercom-session-*"],
|
|
2679
3560
|
init: () => {
|
|
2680
|
-
|
|
2681
|
-
|
|
3561
|
+
const currentWindow = globalThis.window;
|
|
3562
|
+
if (currentWindow !== void 0) {
|
|
3563
|
+
const w = currentWindow;
|
|
2682
3564
|
if (typeof w.Intercom === "function") {
|
|
2683
3565
|
try {
|
|
2684
|
-
w.Intercom("boot", { app_id:
|
|
3566
|
+
w.Intercom("boot", { app_id: appId });
|
|
2685
3567
|
} catch (error) {
|
|
2686
3568
|
if (typeof console !== "undefined" && typeof console.warn === "function") {
|
|
2687
3569
|
console.warn("[Intercom] Failed to boot:", error);
|
|
@@ -2693,18 +3575,29 @@ function createIntercomIntegration(config) {
|
|
|
2693
3575
|
};
|
|
2694
3576
|
}
|
|
2695
3577
|
function createZendeskChatIntegration(config) {
|
|
2696
|
-
const
|
|
3578
|
+
const category = resolveCategory("functional", config.category);
|
|
3579
|
+
const key = resolveRequiredString(config.key, "key", "zendesk-chat");
|
|
3580
|
+
if (!key) {
|
|
3581
|
+
return {
|
|
3582
|
+
id: "zendesk-chat",
|
|
3583
|
+
category,
|
|
3584
|
+
src: "",
|
|
3585
|
+
cookies: ["__zlcmid", "_zendesk_shared_session"]
|
|
3586
|
+
};
|
|
3587
|
+
}
|
|
3588
|
+
const src = config.scriptUrl ?? `https://static.zdassets.com/ekr/snippet.js?key=${key}`;
|
|
2697
3589
|
return {
|
|
2698
3590
|
id: "zendesk-chat",
|
|
2699
|
-
category
|
|
3591
|
+
category,
|
|
2700
3592
|
src,
|
|
2701
3593
|
cookies: ["__zlcmid", "_zendesk_shared_session"],
|
|
2702
3594
|
init: () => {
|
|
2703
|
-
|
|
2704
|
-
|
|
3595
|
+
const currentWindow = globalThis.window;
|
|
3596
|
+
if (currentWindow !== void 0) {
|
|
3597
|
+
const w = currentWindow;
|
|
2705
3598
|
if (typeof w.zE === "function") {
|
|
2706
3599
|
try {
|
|
2707
|
-
w.zE("webWidget", "identify", { key
|
|
3600
|
+
w.zE("webWidget", "identify", { key });
|
|
2708
3601
|
} catch (error) {
|
|
2709
3602
|
if (typeof console !== "undefined" && typeof console.warn === "function") {
|
|
2710
3603
|
console.warn("[Zendesk] Failed to identify:", error);
|
|
@@ -2826,217 +3719,6 @@ function createAnpdCategoriesConfig(options = {}) {
|
|
|
2826
3719
|
};
|
|
2827
3720
|
}
|
|
2828
3721
|
|
|
2829
|
-
// src/types/advancedTexts.ts
|
|
2830
|
-
var EXPANDED_DEFAULT_TEXTS = {
|
|
2831
|
-
// Textos adicionais
|
|
2832
|
-
confirm: "Confirmar",
|
|
2833
|
-
cancel: "Cancelar",
|
|
2834
|
-
loading: "Carregando...",
|
|
2835
|
-
// Feedback
|
|
2836
|
-
feedback: {
|
|
2837
|
-
saveSuccess: "Prefer\xEAncias salvas com sucesso!",
|
|
2838
|
-
saveError: "Erro ao salvar prefer\xEAncias. Tente novamente.",
|
|
2839
|
-
consentUpdated: "Consentimento atualizado.",
|
|
2840
|
-
cookiesRejected: "Cookies opcionais rejeitados.",
|
|
2841
|
-
settingsReset: "Configura\xE7\xF5es resetadas."
|
|
2842
|
-
},
|
|
2843
|
-
// Acessibilidade
|
|
2844
|
-
accessibility: {
|
|
2845
|
-
bannerLabel: "Banner de consentimento de cookies",
|
|
2846
|
-
modalLabel: "Modal de prefer\xEAncias de cookies",
|
|
2847
|
-
keyboardNavigation: "Use Tab para navegar, Enter para selecionar",
|
|
2848
|
-
toggleState: {
|
|
2849
|
-
enabled: "Habilitado",
|
|
2850
|
-
disabled: "Desabilitado"
|
|
2851
|
-
},
|
|
2852
|
-
liveRegion: "Regi\xE3o de an\xFAncios din\xE2micos"
|
|
2853
|
-
},
|
|
2854
|
-
// Categorias
|
|
2855
|
-
categories: {
|
|
2856
|
-
necessary: {
|
|
2857
|
-
name: "Cookies Necess\xE1rios",
|
|
2858
|
-
description: "Essenciais para o funcionamento b\xE1sico do site",
|
|
2859
|
-
examples: "Sess\xE3o, seguran\xE7a, prefer\xEAncias de idioma"
|
|
2860
|
-
},
|
|
2861
|
-
analytics: {
|
|
2862
|
-
name: "Cookies de Analytics",
|
|
2863
|
-
description: "Ajudam a entender como os visitantes usam o site",
|
|
2864
|
-
examples: "Google Analytics, contadores de p\xE1gina"
|
|
2865
|
-
},
|
|
2866
|
-
marketing: {
|
|
2867
|
-
name: "Cookies de Marketing",
|
|
2868
|
-
description: "Usados para personalizar an\xFAncios e ofertas",
|
|
2869
|
-
examples: "Facebook Pixel, Google Ads, remarketing"
|
|
2870
|
-
},
|
|
2871
|
-
functional: {
|
|
2872
|
-
name: "Cookies Funcionais",
|
|
2873
|
-
description: "Melhoram a funcionalidade e personaliza\xE7\xE3o",
|
|
2874
|
-
examples: "Chat, mapas, v\xEDdeos embarcados"
|
|
2875
|
-
},
|
|
2876
|
-
performance: {
|
|
2877
|
-
name: "Cookies de Performance",
|
|
2878
|
-
description: "Coletam informa\xE7\xF5es sobre velocidade e estabilidade",
|
|
2879
|
-
examples: "Monitoramento de erro, otimiza\xE7\xE3o de velocidade"
|
|
2880
|
-
}
|
|
2881
|
-
},
|
|
2882
|
-
// Contextos específicos
|
|
2883
|
-
contexts: {
|
|
2884
|
-
ecommerce: {
|
|
2885
|
-
cartAbandonment: "Lembramos dos produtos no seu carrinho",
|
|
2886
|
-
personalizedOffers: "Ofertas personalizadas baseadas no seu hist\xF3rico",
|
|
2887
|
-
paymentSecurity: "Seguran\xE7a adicional no processo de pagamento",
|
|
2888
|
-
productRecommendations: "Sugest\xF5es de produtos relevantes"
|
|
2889
|
-
},
|
|
2890
|
-
saas: {
|
|
2891
|
-
userAnalytics: "An\xE1lise de uso para melhorar funcionalidades",
|
|
2892
|
-
performanceMonitoring: "Monitoramento de performance da aplica\xE7\xE3o",
|
|
2893
|
-
featureUsage: "Estat\xEDsticas de uso de recursos",
|
|
2894
|
-
customerSupport: "Suporte ao cliente mais eficiente"
|
|
2895
|
-
},
|
|
2896
|
-
government: {
|
|
2897
|
-
citizenServices: "Melhoria dos servi\xE7os ao cidad\xE3o",
|
|
2898
|
-
dataProtection: "Prote\xE7\xE3o rigorosa dos dados pessoais",
|
|
2899
|
-
transparency: "Transpar\xEAncia no uso de dados",
|
|
2900
|
-
accessibility: "Recursos de acessibilidade digital"
|
|
2901
|
-
},
|
|
2902
|
-
education: {
|
|
2903
|
-
studentProgress: "Acompanhamento do progresso educacional",
|
|
2904
|
-
learningAnalytics: "Analytics para melhorar o aprendizado",
|
|
2905
|
-
accessibility: "Recursos educacionais acess\xEDveis",
|
|
2906
|
-
parentalConsent: "Consentimento parental quando necess\xE1rio"
|
|
2907
|
-
}
|
|
2908
|
-
},
|
|
2909
|
-
// Variações de tom
|
|
2910
|
-
variants: {
|
|
2911
|
-
formal: {
|
|
2912
|
-
bannerMessage: "Este s\xEDtio eletr\xF4nico utiliza cookies para otimizar a experi\xEAncia de navega\xE7\xE3o.",
|
|
2913
|
-
acceptAll: "Concordar com todos os cookies",
|
|
2914
|
-
declineAll: "Recusar cookies opcionais",
|
|
2915
|
-
modalTitle: "Configura\xE7\xE3o de Cookies"
|
|
2916
|
-
},
|
|
2917
|
-
casual: {
|
|
2918
|
-
bannerMessage: "\u{1F36A} Ei! Usamos cookies para tornar sua experi\xEAncia ainda melhor!",
|
|
2919
|
-
acceptAll: "Aceitar tudo",
|
|
2920
|
-
declineAll: "S\xF3 o essencial",
|
|
2921
|
-
modalTitle: "Seus Cookies"
|
|
2922
|
-
},
|
|
2923
|
-
concise: {
|
|
2924
|
-
bannerMessage: "Usamos cookies. Voc\xEA aceita?",
|
|
2925
|
-
acceptAll: "Sim",
|
|
2926
|
-
declineAll: "N\xE3o",
|
|
2927
|
-
modalTitle: "Cookies"
|
|
2928
|
-
},
|
|
2929
|
-
detailed: {
|
|
2930
|
-
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.",
|
|
2931
|
-
acceptAll: "Aceitar todos os cookies e tecnologias",
|
|
2932
|
-
declineAll: "Recusar todos os cookies opcionais",
|
|
2933
|
-
modalTitle: "Centro de Prefer\xEAncias de Privacidade"
|
|
2934
|
-
}
|
|
2935
|
-
},
|
|
2936
|
-
// Internacionalização simplificada (apenas textos básicos)
|
|
2937
|
-
i18n: {
|
|
2938
|
-
en: {
|
|
2939
|
-
bannerMessage: "We use cookies to enhance your experience.",
|
|
2940
|
-
acceptAll: "Accept All",
|
|
2941
|
-
declineAll: "Decline",
|
|
2942
|
-
preferences: "Preferences",
|
|
2943
|
-
modalTitle: "Cookie Preferences",
|
|
2944
|
-
modalIntro: "Customize your cookie preferences below.",
|
|
2945
|
-
save: "Save Preferences",
|
|
2946
|
-
necessaryAlwaysOn: "Necessary cookies (always active)"
|
|
2947
|
-
},
|
|
2948
|
-
es: {
|
|
2949
|
-
bannerMessage: "Utilizamos cookies para mejorar su experiencia.",
|
|
2950
|
-
acceptAll: "Aceptar Todo",
|
|
2951
|
-
declineAll: "Rechazar",
|
|
2952
|
-
preferences: "Preferencias",
|
|
2953
|
-
modalTitle: "Preferencias de Cookies",
|
|
2954
|
-
modalIntro: "Personalice sus preferencias de cookies a continuaci\xF3n.",
|
|
2955
|
-
save: "Guardar Preferencias",
|
|
2956
|
-
necessaryAlwaysOn: "Cookies necess\xE1rias (sempre ativas)"
|
|
2957
|
-
},
|
|
2958
|
-
fr: {
|
|
2959
|
-
bannerMessage: "Nous utilisons des cookies pour am\xE9liorer votre exp\xE9rience.",
|
|
2960
|
-
acceptAll: "Tout Accepter",
|
|
2961
|
-
declineAll: "Refuser",
|
|
2962
|
-
preferences: "Pr\xE9f\xE9rences",
|
|
2963
|
-
modalTitle: "Pr\xE9f\xE9rences des Cookies",
|
|
2964
|
-
modalIntro: "Personnalisez vos pr\xE9f\xE9rences de cookies ci-dessous.",
|
|
2965
|
-
save: "Enregistrer les Pr\xE9f\xE9rences",
|
|
2966
|
-
necessaryAlwaysOn: "Cookies n\xE9cessaires (toujours actifs)"
|
|
2967
|
-
}
|
|
2968
|
-
},
|
|
2969
|
-
// Textos técnicos
|
|
2970
|
-
technical: {
|
|
2971
|
-
sessionCookies: "Cookies de sess\xE3o s\xE3o tempor\xE1rios e expiram quando voc\xEA fecha o navegador.",
|
|
2972
|
-
persistentCookies: "Cookies persistentes permanecem no seu dispositivo at\xE9 expirarem ou serem removidos.",
|
|
2973
|
-
thirdPartyCookies: "Cookies de terceiros s\xE3o definidos por dom\xEDnios diferentes do site que voc\xEA est\xE1 visitando.",
|
|
2974
|
-
browserSettings: "Voc\xEA pode gerenciar cookies nas configura\xE7\xF5es do seu navegador.",
|
|
2975
|
-
disablingImpact: "Desabilitar cookies pode afetar a funcionalidade do site."
|
|
2976
|
-
},
|
|
2977
|
-
// Cookie details
|
|
2978
|
-
cookieDetails: {
|
|
2979
|
-
tableHeaders: {
|
|
2980
|
-
name: "Nome",
|
|
2981
|
-
purpose: "Finalidade",
|
|
2982
|
-
duration: "Dura\xE7\xE3o",
|
|
2983
|
-
provider: "Fornecedor",
|
|
2984
|
-
type: "Tipo"
|
|
2985
|
-
},
|
|
2986
|
-
noCookies: "Nenhum cookie encontrado para esta categoria.",
|
|
2987
|
-
toggleDetails: {
|
|
2988
|
-
expand: "Ver detalhes",
|
|
2989
|
-
collapse: "Ocultar detalhes"
|
|
2990
|
-
}
|
|
2991
|
-
}
|
|
2992
|
-
};
|
|
2993
|
-
function resolveTexts(texts, options = {}) {
|
|
2994
|
-
const { language = "pt", variant } = options;
|
|
2995
|
-
let resolved = { ...texts };
|
|
2996
|
-
if (variant && texts.variants?.[variant]) {
|
|
2997
|
-
resolved = { ...resolved, ...texts.variants[variant] };
|
|
2998
|
-
}
|
|
2999
|
-
if (language !== "pt" && texts.i18n?.[language]) {
|
|
3000
|
-
resolved = { ...resolved, ...texts.i18n[language] };
|
|
3001
|
-
}
|
|
3002
|
-
return resolved;
|
|
3003
|
-
}
|
|
3004
|
-
var TEXT_TEMPLATES = {
|
|
3005
|
-
ecommerce: {
|
|
3006
|
-
...EXPANDED_DEFAULT_TEXTS,
|
|
3007
|
-
bannerMessage: "Utilizamos cookies para personalizar ofertas e melhorar sua experi\xEAncia de compra.",
|
|
3008
|
-
acceptAll: "Aceitar e continuar",
|
|
3009
|
-
variants: {
|
|
3010
|
-
casual: {
|
|
3011
|
-
bannerMessage: "\u{1F6D2} Usamos cookies para encontrar as melhores ofertas para voc\xEA!",
|
|
3012
|
-
acceptAll: "Quero ofertas personalizadas!"
|
|
3013
|
-
}
|
|
3014
|
-
}
|
|
3015
|
-
},
|
|
3016
|
-
saas: {
|
|
3017
|
-
...EXPANDED_DEFAULT_TEXTS,
|
|
3018
|
-
bannerMessage: "Utilizamos cookies para otimizar o desempenho da aplica\xE7\xE3o e sua experi\xEAncia.",
|
|
3019
|
-
acceptAll: "Aceitar e otimizar",
|
|
3020
|
-
variants: {
|
|
3021
|
-
formal: {
|
|
3022
|
-
bannerMessage: "Esta aplica\xE7\xE3o utiliza cookies para an\xE1lise de performance e melhoria cont\xEDnua da experi\xEAncia do usu\xE1rio.",
|
|
3023
|
-
acceptAll: "Autorizar coleta de dados de uso"
|
|
3024
|
-
}
|
|
3025
|
-
}
|
|
3026
|
-
},
|
|
3027
|
-
government: {
|
|
3028
|
-
...EXPANDED_DEFAULT_TEXTS,
|
|
3029
|
-
bannerMessage: "Este portal utiliza cookies em conformidade com a LGPD para melhorar os servi\xE7os p\xFAblicos.",
|
|
3030
|
-
acceptAll: "Aceitar em conformidade",
|
|
3031
|
-
variants: {
|
|
3032
|
-
formal: {
|
|
3033
|
-
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.",
|
|
3034
|
-
acceptAll: "Concordar com o uso de cookies"
|
|
3035
|
-
}
|
|
3036
|
-
}
|
|
3037
|
-
}
|
|
3038
|
-
};
|
|
3039
|
-
|
|
3040
3722
|
exports.ANPD_CATEGORY_PRESETS = ANPD_CATEGORY_PRESETS;
|
|
3041
3723
|
exports.COMMON_INTEGRATIONS = COMMON_INTEGRATIONS;
|
|
3042
3724
|
exports.ConsentGate = ConsentGate;
|
|
@@ -3068,6 +3750,7 @@ exports.createIntercomIntegration = createIntercomIntegration;
|
|
|
3068
3750
|
exports.createMixpanelIntegration = createMixpanelIntegration;
|
|
3069
3751
|
exports.createProjectPreferences = createProjectPreferences;
|
|
3070
3752
|
exports.createSaaSIntegrations = createSaaSIntegrations;
|
|
3753
|
+
exports.createSuggestedIntegration = createSuggestedIntegration;
|
|
3071
3754
|
exports.createUserWayIntegration = createUserWayIntegration;
|
|
3072
3755
|
exports.createZendeskChatIntegration = createZendeskChatIntegration;
|
|
3073
3756
|
exports.defaultTexts = defaultTexts;
|
|
@@ -3077,17 +3760,22 @@ exports.ensureNecessaryAlwaysOn = ensureNecessaryAlwaysOn;
|
|
|
3077
3760
|
exports.extractCategoriesFromIntegrations = extractCategoriesFromIntegrations;
|
|
3078
3761
|
exports.getAllProjectCategories = getAllProjectCategories;
|
|
3079
3762
|
exports.getCookiesInfoForCategory = getCookiesInfoForCategory;
|
|
3763
|
+
exports.getPeerDepsLocale = getPeerDepsLocale;
|
|
3080
3764
|
exports.loadScript = loadScript;
|
|
3081
3765
|
exports.logDeveloperGuidance = logDeveloperGuidance;
|
|
3082
3766
|
exports.logger = logger;
|
|
3083
3767
|
exports.openPreferencesModal = openPreferencesModal;
|
|
3084
3768
|
exports.pushConsentInitializedEvent = pushConsentInitializedEvent;
|
|
3085
3769
|
exports.pushConsentUpdatedEvent = pushConsentUpdatedEvent;
|
|
3770
|
+
exports.registerScript = registerScript;
|
|
3771
|
+
exports.resetPeerDepsMessages = resetPeerDepsMessages;
|
|
3086
3772
|
exports.resolveTexts = resolveTexts;
|
|
3087
3773
|
exports.runPeerDepsCheck = runPeerDepsCheck;
|
|
3088
3774
|
exports.setCookieCatalogOverrides = setCookieCatalogOverrides;
|
|
3089
3775
|
exports.setCookieCategoryOverrides = setCookieCategoryOverrides;
|
|
3090
3776
|
exports.setDebugLogging = setDebugLogging;
|
|
3777
|
+
exports.setPeerDepsLocale = setPeerDepsLocale;
|
|
3778
|
+
exports.setPeerDepsMessages = setPeerDepsMessages;
|
|
3091
3779
|
exports.suggestCategoryForScript = suggestCategoryForScript;
|
|
3092
3780
|
exports.useCategories = useCategories;
|
|
3093
3781
|
exports.useCategoryStatus = useCategoryStatus;
|