@react-lgpd-consent/core 0.6.3 → 0.7.1
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 +346 -2
- package/README.md +62 -1
- package/dist/index.cjs +816 -195
- package/dist/index.d.cts +283 -16
- package/dist/index.d.ts +283 -16
- package/dist/index.js +809 -196
- package/package.json +3 -4
package/dist/index.js
CHANGED
|
@@ -309,21 +309,41 @@ function setDebugLogging(enabled, level = 2 /* INFO */) {
|
|
|
309
309
|
// src/utils/cookieUtils.ts
|
|
310
310
|
var DEFAULT_STORAGE_NAMESPACE = "lgpd-consent";
|
|
311
311
|
var DEFAULT_STORAGE_VERSION = "1";
|
|
312
|
+
var DEFAULT_MAX_AGE_SECONDS = 365 * 24 * 60 * 60;
|
|
312
313
|
function buildConsentStorageKey(options) {
|
|
313
314
|
const namespaceRaw = options?.namespace?.trim() || DEFAULT_STORAGE_NAMESPACE;
|
|
314
315
|
const versionRaw = options?.version?.trim() || DEFAULT_STORAGE_VERSION;
|
|
315
|
-
const sanitizedNamespace = namespaceRaw.
|
|
316
|
-
const sanitizedVersion = versionRaw.
|
|
316
|
+
const sanitizedNamespace = namespaceRaw.replaceAll(/[^a-z0-9._-]+/gi, "-").toLowerCase();
|
|
317
|
+
const sanitizedVersion = versionRaw.replaceAll(/[^a-z0-9._-]+/gi, "-").toLowerCase();
|
|
317
318
|
return `${sanitizedNamespace}__v${sanitizedVersion}`;
|
|
318
319
|
}
|
|
319
320
|
var DEFAULT_COOKIE_OPTS = {
|
|
320
321
|
name: "cookieConsent",
|
|
322
|
+
maxAge: DEFAULT_MAX_AGE_SECONDS,
|
|
321
323
|
maxAgeDays: 365,
|
|
322
324
|
sameSite: "Lax",
|
|
323
|
-
secure:
|
|
325
|
+
secure: globalThis.window === void 0 ? false : globalThis.window.location.protocol === "https:",
|
|
324
326
|
path: "/",
|
|
325
327
|
domain: void 0
|
|
326
328
|
};
|
|
329
|
+
function resolveCookieOptions(opts) {
|
|
330
|
+
const protocols = [
|
|
331
|
+
typeof globalThis.window !== "undefined" ? globalThis.window?.location?.protocol : void 0,
|
|
332
|
+
typeof globalThis.location !== "undefined" ? globalThis.location?.protocol : void 0
|
|
333
|
+
].filter(Boolean);
|
|
334
|
+
const forceHttps = globalThis.__LGPD_FORCE_HTTPS__ === true;
|
|
335
|
+
const isHttps = forceHttps || protocols.includes("https:");
|
|
336
|
+
const maxAgeSecondsFromDays = typeof opts?.maxAgeDays === "number" ? Math.max(0, opts.maxAgeDays * 24 * 60 * 60) : null;
|
|
337
|
+
const maxAgeSeconds = typeof opts?.maxAge === "number" ? Math.max(0, opts.maxAge) : maxAgeSecondsFromDays ?? DEFAULT_MAX_AGE_SECONDS;
|
|
338
|
+
return {
|
|
339
|
+
name: opts?.name ?? DEFAULT_COOKIE_OPTS.name,
|
|
340
|
+
maxAge: maxAgeSeconds,
|
|
341
|
+
sameSite: opts?.sameSite ?? DEFAULT_COOKIE_OPTS.sameSite ?? "Lax",
|
|
342
|
+
secure: typeof opts?.secure === "boolean" ? opts.secure : isHttps ? true : DEFAULT_COOKIE_OPTS.secure ?? false,
|
|
343
|
+
path: opts?.path ?? DEFAULT_COOKIE_OPTS.path ?? "/",
|
|
344
|
+
domain: opts?.domain ?? DEFAULT_COOKIE_OPTS.domain ?? void 0
|
|
345
|
+
};
|
|
346
|
+
}
|
|
327
347
|
var COOKIE_SCHEMA_VERSION = "1.0";
|
|
328
348
|
function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
|
|
329
349
|
logger.debug("Reading consent cookie", { name });
|
|
@@ -339,6 +359,10 @@ function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
|
|
|
339
359
|
try {
|
|
340
360
|
const data = JSON.parse(raw);
|
|
341
361
|
logger.cookieOperation("read", name, data);
|
|
362
|
+
if (!data || typeof data !== "object") {
|
|
363
|
+
logger.warn("Consent cookie malformed: payload is not an object");
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
342
366
|
if (!data.version) {
|
|
343
367
|
logger.debug("Migrating legacy cookie format");
|
|
344
368
|
return migrateLegacyCookie(data);
|
|
@@ -347,7 +371,11 @@ function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
|
|
|
347
371
|
logger.warn(`Cookie version mismatch: ${data.version} != ${COOKIE_SCHEMA_VERSION}`);
|
|
348
372
|
return null;
|
|
349
373
|
}
|
|
350
|
-
|
|
374
|
+
const preferences = data && typeof data.preferences === "object" ? data.preferences : { necessary: true };
|
|
375
|
+
return {
|
|
376
|
+
...data,
|
|
377
|
+
preferences: ensureNecessaryAlwaysOn(preferences)
|
|
378
|
+
};
|
|
351
379
|
} catch (error) {
|
|
352
380
|
logger.error("Error parsing consent cookie", error);
|
|
353
381
|
return null;
|
|
@@ -370,12 +398,12 @@ function migrateLegacyCookie(legacyData) {
|
|
|
370
398
|
}
|
|
371
399
|
}
|
|
372
400
|
function writeConsentCookie(state, config, opts, source = "banner") {
|
|
373
|
-
if (typeof document === "undefined") {
|
|
401
|
+
if (typeof document === "undefined" || typeof window === "undefined" || globalThis.__LGPD_SSR__ === true) {
|
|
374
402
|
logger.debug("Cookie write skipped: server-side environment");
|
|
375
403
|
return;
|
|
376
404
|
}
|
|
377
405
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
378
|
-
const o =
|
|
406
|
+
const o = resolveCookieOptions(opts);
|
|
379
407
|
const preferences = ensureNecessaryAlwaysOn(state.preferences);
|
|
380
408
|
const cookieData = {
|
|
381
409
|
version: COOKIE_SCHEMA_VERSION,
|
|
@@ -387,8 +415,9 @@ function writeConsentCookie(state, config, opts, source = "banner") {
|
|
|
387
415
|
projectConfig: config
|
|
388
416
|
};
|
|
389
417
|
logger.cookieOperation("write", o.name, cookieData);
|
|
418
|
+
const expires = new Date(Date.now() + o.maxAge * 1e3);
|
|
390
419
|
Cookies.set(o.name, JSON.stringify(cookieData), {
|
|
391
|
-
expires
|
|
420
|
+
expires,
|
|
392
421
|
sameSite: o.sameSite,
|
|
393
422
|
secure: o.secure,
|
|
394
423
|
path: o.path,
|
|
@@ -400,38 +429,55 @@ function writeConsentCookie(state, config, opts, source = "banner") {
|
|
|
400
429
|
preferencesCount: Object.keys(cookieData.preferences).length
|
|
401
430
|
});
|
|
402
431
|
}
|
|
432
|
+
function createConsentAuditEntry(state, params) {
|
|
433
|
+
const preferences = ensureNecessaryAlwaysOn(state.preferences);
|
|
434
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
435
|
+
return {
|
|
436
|
+
action: params.action,
|
|
437
|
+
storageKey: params.storageKey,
|
|
438
|
+
consentVersion: params.consentVersion?.trim() || "1",
|
|
439
|
+
timestamp: now,
|
|
440
|
+
consentDate: state.consentDate,
|
|
441
|
+
lastUpdate: state.lastUpdate,
|
|
442
|
+
consented: state.consented,
|
|
443
|
+
preferences,
|
|
444
|
+
version: state.version,
|
|
445
|
+
source: params.origin ?? state.source,
|
|
446
|
+
projectConfig: state.projectConfig
|
|
447
|
+
};
|
|
448
|
+
}
|
|
403
449
|
function removeConsentCookie(opts) {
|
|
404
450
|
if (typeof document === "undefined") {
|
|
405
451
|
logger.debug("Cookie removal skipped: server-side environment");
|
|
406
452
|
return;
|
|
407
453
|
}
|
|
408
|
-
const o =
|
|
454
|
+
const o = resolveCookieOptions(opts);
|
|
409
455
|
logger.cookieOperation("delete", o.name);
|
|
410
456
|
Cookies.remove(o.name, { path: o.path, domain: o.domain });
|
|
411
457
|
logger.info("Consent cookie removed");
|
|
412
458
|
}
|
|
413
459
|
|
|
414
460
|
// src/utils/dataLayerEvents.ts
|
|
415
|
-
var LIBRARY_VERSION = "0.
|
|
461
|
+
var LIBRARY_VERSION = "0.7.1";
|
|
416
462
|
function ensureDataLayer() {
|
|
417
|
-
|
|
418
|
-
if (
|
|
419
|
-
|
|
420
|
-
}
|
|
463
|
+
var _a;
|
|
464
|
+
if (globalThis.window === void 0) return;
|
|
465
|
+
(_a = globalThis.window).dataLayer ?? (_a.dataLayer = []);
|
|
421
466
|
}
|
|
422
467
|
function pushConsentInitializedEvent(categories) {
|
|
423
|
-
if (
|
|
468
|
+
if (globalThis.window === void 0) return;
|
|
424
469
|
ensureDataLayer();
|
|
425
470
|
const event = {
|
|
426
471
|
event: "consent_initialized",
|
|
427
472
|
consent_version: LIBRARY_VERSION,
|
|
428
473
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
429
|
-
categories
|
|
474
|
+
categories,
|
|
475
|
+
preferences: categories
|
|
430
476
|
};
|
|
431
|
-
window.dataLayer?.push(event);
|
|
477
|
+
globalThis.window.dataLayer?.push(event);
|
|
432
478
|
}
|
|
433
479
|
function pushConsentUpdatedEvent(categories, origin, previousCategories) {
|
|
434
|
-
if (
|
|
480
|
+
if (globalThis.window === void 0) return;
|
|
435
481
|
ensureDataLayer();
|
|
436
482
|
const changedCategories = previousCategories ? Object.keys(categories).filter((key) => categories[key] !== previousCategories[key]) : [];
|
|
437
483
|
const event = {
|
|
@@ -440,9 +486,10 @@ function pushConsentUpdatedEvent(categories, origin, previousCategories) {
|
|
|
440
486
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
441
487
|
origin,
|
|
442
488
|
categories,
|
|
489
|
+
preferences: categories,
|
|
443
490
|
changed_categories: changedCategories
|
|
444
491
|
};
|
|
445
|
-
window.dataLayer?.push(event);
|
|
492
|
+
globalThis.window.dataLayer?.push(event);
|
|
446
493
|
}
|
|
447
494
|
function useDataLayerEvents() {
|
|
448
495
|
return {
|
|
@@ -631,10 +678,10 @@ var COOKIE_CATALOG_OVERRIDES = {};
|
|
|
631
678
|
var COOKIE_CATEGORY_OVERRIDES = {};
|
|
632
679
|
function setCookieCatalogOverrides(overrides) {
|
|
633
680
|
COOKIE_CATALOG_OVERRIDES = {
|
|
634
|
-
byCategory: { ...COOKIE_CATALOG_OVERRIDES.byCategory
|
|
681
|
+
byCategory: { ...COOKIE_CATALOG_OVERRIDES.byCategory, ...overrides.byCategory },
|
|
635
682
|
byIntegration: {
|
|
636
|
-
...COOKIE_CATALOG_OVERRIDES.byIntegration
|
|
637
|
-
...overrides.byIntegration
|
|
683
|
+
...COOKIE_CATALOG_OVERRIDES.byIntegration,
|
|
684
|
+
...overrides.byIntegration
|
|
638
685
|
}
|
|
639
686
|
};
|
|
640
687
|
}
|
|
@@ -656,7 +703,7 @@ function getCookiesInfoForCategory(categoryId, usedIntegrations) {
|
|
|
656
703
|
([pattern]) => matchPattern(desc.name, pattern)
|
|
657
704
|
)?.[1];
|
|
658
705
|
const finalCat = overrideCat ?? defaultCat;
|
|
659
|
-
if (finalCat === categoryId && !result.
|
|
706
|
+
if (finalCat === categoryId && !result.some((d) => d.name === desc.name)) result.push(desc);
|
|
660
707
|
});
|
|
661
708
|
});
|
|
662
709
|
const catOverride = COOKIE_CATALOG_OVERRIDES.byCategory?.[categoryId];
|
|
@@ -668,7 +715,7 @@ function getCookiesInfoForCategory(categoryId, usedIntegrations) {
|
|
|
668
715
|
});
|
|
669
716
|
}
|
|
670
717
|
if (categoryId === "necessary") {
|
|
671
|
-
if (!result.
|
|
718
|
+
if (!result.some((d) => d.name === "cookieConsent")) {
|
|
672
719
|
result.push({
|
|
673
720
|
name: "cookieConsent",
|
|
674
721
|
purpose: "Armazena suas prefer\xEAncias de consentimento",
|
|
@@ -1049,58 +1096,8 @@ var GUIDANCE_PRESETS = {
|
|
|
1049
1096
|
};
|
|
1050
1097
|
|
|
1051
1098
|
// src/utils/peerDepsCheck.ts
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
try {
|
|
1055
|
-
const reactSymbols = Object.getOwnPropertySymbols(window).map((sym) => String(sym)).filter((name) => name.includes("react"));
|
|
1056
|
-
if (reactSymbols.length > 1) {
|
|
1057
|
-
return true;
|
|
1058
|
-
}
|
|
1059
|
-
const ReactModule = window.React;
|
|
1060
|
-
if (ReactModule && Array.isArray(ReactModule)) {
|
|
1061
|
-
return true;
|
|
1062
|
-
}
|
|
1063
|
-
const hasMultipleVersions = window.__REACT_DEVTOOLS_GLOBAL_HOOK__?.renderers?.size > 1;
|
|
1064
|
-
return hasMultipleVersions || false;
|
|
1065
|
-
} catch {
|
|
1066
|
-
return false;
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
function getPackageVersion(packageName) {
|
|
1070
|
-
if (typeof window === "undefined") return null;
|
|
1071
|
-
try {
|
|
1072
|
-
const pkg = window[packageName];
|
|
1073
|
-
if (pkg?.version) return pkg.version;
|
|
1074
|
-
const React6 = window.React;
|
|
1075
|
-
if (packageName === "react" && React6?.version) {
|
|
1076
|
-
return React6.version;
|
|
1077
|
-
}
|
|
1078
|
-
return null;
|
|
1079
|
-
} catch {
|
|
1080
|
-
return null;
|
|
1081
|
-
}
|
|
1082
|
-
}
|
|
1083
|
-
function isVersionInRange(version, minMajor, maxMajor) {
|
|
1084
|
-
const major = parseInt(version.split(".")[0], 10);
|
|
1085
|
-
return major >= minMajor && major <= maxMajor;
|
|
1086
|
-
}
|
|
1087
|
-
function checkPeerDeps(options = {}) {
|
|
1088
|
-
const { skipInProduction = true, logWarnings = true } = options;
|
|
1089
|
-
const result = {
|
|
1090
|
-
ok: true,
|
|
1091
|
-
warnings: [],
|
|
1092
|
-
errors: []
|
|
1093
|
-
};
|
|
1094
|
-
const isProduction = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
1095
|
-
if (skipInProduction && isProduction) {
|
|
1096
|
-
return result;
|
|
1097
|
-
}
|
|
1098
|
-
if (typeof window === "undefined") {
|
|
1099
|
-
return result;
|
|
1100
|
-
}
|
|
1101
|
-
if (detectMultipleReactInstances()) {
|
|
1102
|
-
result.ok = false;
|
|
1103
|
-
const errorMsg = `
|
|
1099
|
+
var MESSAGES_PT_BR = {
|
|
1100
|
+
MULTIPLE_REACT_INSTANCES: `
|
|
1104
1101
|
\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
|
|
1105
1102
|
\u2551 \u26A0\uFE0F ERRO: M\xFAltiplas inst\xE2ncias de React detectadas \u2551
|
|
1106
1103
|
\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
|
|
@@ -1162,22 +1159,13 @@ function checkPeerDeps(options = {}) {
|
|
|
1162
1159
|
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#multiple-react-instances
|
|
1163
1160
|
|
|
1164
1161
|
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
if (logWarnings) {
|
|
1168
|
-
console.error(errorMsg);
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
const reactVersion = getPackageVersion("react");
|
|
1172
|
-
if (reactVersion) {
|
|
1173
|
-
if (!isVersionInRange(reactVersion, 18, 19)) {
|
|
1174
|
-
result.ok = false;
|
|
1175
|
-
const errorMsg = `
|
|
1162
|
+
`,
|
|
1163
|
+
UNSUPPORTED_REACT_VERSION: (version) => `
|
|
1176
1164
|
\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
|
|
1177
1165
|
\u2551 \u26A0\uFE0F AVISO: Vers\xE3o do React n\xE3o suportada \u2551
|
|
1178
1166
|
\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
|
|
1179
1167
|
|
|
1180
|
-
\u{1F4E6} Vers\xE3o detectada: React ${
|
|
1168
|
+
\u{1F4E6} Vers\xE3o detectada: React ${version}
|
|
1181
1169
|
\u2705 Vers\xF5es suportadas: React 18.x ou 19.x
|
|
1182
1170
|
|
|
1183
1171
|
\u{1F50D} O react-lgpd-consent requer React 18.2.0+ ou React 19.x
|
|
@@ -1195,27 +1183,13 @@ function checkPeerDeps(options = {}) {
|
|
|
1195
1183
|
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#react-version
|
|
1196
1184
|
|
|
1197
1185
|
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
if (logWarnings) {
|
|
1201
|
-
console.error(errorMsg);
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
}
|
|
1205
|
-
const muiVersion = window["@mui/material"]?.version;
|
|
1206
|
-
if (muiVersion) {
|
|
1207
|
-
if (!isVersionInRange(muiVersion, 5, 7)) {
|
|
1208
|
-
result.warnings.push(
|
|
1209
|
-
`MUI vers\xE3o ${muiVersion} detectada. Vers\xF5es suportadas: 5.15.0+, 6.x ou 7.x. Alguns componentes podem n\xE3o funcionar corretamente.`
|
|
1210
|
-
);
|
|
1211
|
-
if (logWarnings) {
|
|
1212
|
-
logger.warn(
|
|
1213
|
-
`
|
|
1186
|
+
`,
|
|
1187
|
+
UNSUPPORTED_MUI_VERSION: (version) => `
|
|
1214
1188
|
\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
|
|
1215
1189
|
\u2551 \u26A0\uFE0F AVISO: Vers\xE3o do Material-UI fora do range recomendado \u2551
|
|
1216
1190
|
\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
|
|
1217
1191
|
|
|
1218
|
-
\u{1F4E6} Vers\xE3o detectada: @mui/material ${
|
|
1192
|
+
\u{1F4E6} Vers\xE3o detectada: @mui/material ${version}
|
|
1219
1193
|
\u2705 Vers\xF5es suportadas: 5.15.0+, 6.x, 7.x
|
|
1220
1194
|
|
|
1221
1195
|
\u{1F50D} Componentes de UI (@react-lgpd-consent/mui) podem apresentar problemas.
|
|
@@ -1233,8 +1207,227 @@ function checkPeerDeps(options = {}) {
|
|
|
1233
1207
|
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#mui-version
|
|
1234
1208
|
|
|
1235
1209
|
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1236
|
-
|
|
1237
|
-
|
|
1210
|
+
`,
|
|
1211
|
+
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.`
|
|
1212
|
+
};
|
|
1213
|
+
var MESSAGES_EN = {
|
|
1214
|
+
MULTIPLE_REACT_INSTANCES: `
|
|
1215
|
+
\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
|
|
1216
|
+
\u2551 \u26A0\uFE0F ERROR: Multiple React instances detected \u2551
|
|
1217
|
+
\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
|
|
1218
|
+
|
|
1219
|
+
\u{1F534} Problem:
|
|
1220
|
+
Your project is loading more than one copy of React, causing the error:
|
|
1221
|
+
"Invalid hook call. Hooks can only be called inside of the body of a
|
|
1222
|
+
function component."
|
|
1223
|
+
|
|
1224
|
+
\u{1F50D} Probable cause:
|
|
1225
|
+
\u2022 pnpm/Yarn PnP without proper peer dependency hoisting
|
|
1226
|
+
\u2022 node_modules with duplicate React (classic npm/yarn)
|
|
1227
|
+
\u2022 Webpack/Vite with multiple resolutions of the same package
|
|
1228
|
+
|
|
1229
|
+
\u2705 Solutions:
|
|
1230
|
+
|
|
1231
|
+
\u{1F4E6} PNPM (RECOMMENDED):
|
|
1232
|
+
Add to root package.json:
|
|
1233
|
+
{
|
|
1234
|
+
"pnpm": {
|
|
1235
|
+
"overrides": {
|
|
1236
|
+
"react": "$react",
|
|
1237
|
+
"react-dom": "$react-dom"
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
Run: pnpm install
|
|
1242
|
+
|
|
1243
|
+
\u{1F4E6} NPM/Yarn:
|
|
1244
|
+
Add to root package.json:
|
|
1245
|
+
{
|
|
1246
|
+
"overrides": {
|
|
1247
|
+
"react": "^18.2.0 || ^19.0.0",
|
|
1248
|
+
"react-dom": "^18.2.0 || ^19.0.0"
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
Run: npm install (or yarn install)
|
|
1252
|
+
|
|
1253
|
+
\u{1F527} Webpack:
|
|
1254
|
+
Add to webpack.config.js:
|
|
1255
|
+
module.exports = {
|
|
1256
|
+
resolve: {
|
|
1257
|
+
alias: {
|
|
1258
|
+
react: path.resolve('./node_modules/react'),
|
|
1259
|
+
'react-dom': path.resolve('./node_modules/react-dom'),
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
\u26A1 Vite:
|
|
1265
|
+
Add to vite.config.js:
|
|
1266
|
+
export default {
|
|
1267
|
+
resolve: {
|
|
1268
|
+
dedupe: ['react', 'react-dom']
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
\u{1F4DA} Documentation:
|
|
1273
|
+
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#multiple-react-instances
|
|
1274
|
+
|
|
1275
|
+
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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
|
+
UNSUPPORTED_REACT_VERSION: (version) => `
|
|
1278
|
+
\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
|
|
1279
|
+
\u2551 \u26A0\uFE0F WARNING: Unsupported React version \u2551
|
|
1280
|
+
\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
|
|
1281
|
+
|
|
1282
|
+
\u{1F4E6} Detected version: React ${version}
|
|
1283
|
+
\u2705 Supported versions: React 18.x or 19.x
|
|
1284
|
+
|
|
1285
|
+
\u{1F50D} react-lgpd-consent requires React 18.2.0+ or React 19.x
|
|
1286
|
+
|
|
1287
|
+
\u2705 Solution:
|
|
1288
|
+
Update React to a supported version:
|
|
1289
|
+
|
|
1290
|
+
npm install react@^18.2.0 react-dom@^18.2.0
|
|
1291
|
+
|
|
1292
|
+
or
|
|
1293
|
+
|
|
1294
|
+
npm install react@^19.0.0 react-dom@^19.0.0
|
|
1295
|
+
|
|
1296
|
+
\u{1F4DA} Documentation:
|
|
1297
|
+
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#react-version
|
|
1298
|
+
|
|
1299
|
+
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1300
|
+
`,
|
|
1301
|
+
UNSUPPORTED_MUI_VERSION: (version) => `
|
|
1302
|
+
\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
|
|
1303
|
+
\u2551 \u26A0\uFE0F WARNING: Material-UI version out of recommended range \u2551
|
|
1304
|
+
\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
|
|
1305
|
+
|
|
1306
|
+
\u{1F4E6} Detected version: @mui/material ${version}
|
|
1307
|
+
\u2705 Supported versions: 5.15.0+, 6.x, 7.x
|
|
1308
|
+
|
|
1309
|
+
\u{1F50D} UI components (@react-lgpd-consent/mui) may have issues.
|
|
1310
|
+
|
|
1311
|
+
\u2705 Solution:
|
|
1312
|
+
Update MUI to a supported version:
|
|
1313
|
+
|
|
1314
|
+
npm install @mui/material@^7.0.0 @emotion/react @emotion/styled
|
|
1315
|
+
|
|
1316
|
+
or keep 5.15.0+:
|
|
1317
|
+
|
|
1318
|
+
npm install @mui/material@^5.15.0 @emotion/react @emotion/styled
|
|
1319
|
+
|
|
1320
|
+
\u{1F4DA} Documentation:
|
|
1321
|
+
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#mui-version
|
|
1322
|
+
|
|
1323
|
+
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1324
|
+
`,
|
|
1325
|
+
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.`
|
|
1326
|
+
};
|
|
1327
|
+
var MESSAGES_BY_LOCALE = {
|
|
1328
|
+
"pt-BR": MESSAGES_PT_BR,
|
|
1329
|
+
en: MESSAGES_EN
|
|
1330
|
+
};
|
|
1331
|
+
var currentLocale = "pt-BR";
|
|
1332
|
+
var customMessages = {};
|
|
1333
|
+
function setPeerDepsLocale(locale) {
|
|
1334
|
+
currentLocale = locale;
|
|
1335
|
+
}
|
|
1336
|
+
function getPeerDepsLocale() {
|
|
1337
|
+
return currentLocale;
|
|
1338
|
+
}
|
|
1339
|
+
function setPeerDepsMessages(messages) {
|
|
1340
|
+
customMessages = { ...customMessages, ...messages };
|
|
1341
|
+
}
|
|
1342
|
+
function resetPeerDepsMessages() {
|
|
1343
|
+
customMessages = {};
|
|
1344
|
+
}
|
|
1345
|
+
function getMessages() {
|
|
1346
|
+
const baseMessages = MESSAGES_BY_LOCALE[currentLocale];
|
|
1347
|
+
if (Object.keys(customMessages).length === 0) {
|
|
1348
|
+
return baseMessages;
|
|
1349
|
+
}
|
|
1350
|
+
return {
|
|
1351
|
+
MULTIPLE_REACT_INSTANCES: customMessages.MULTIPLE_REACT_INSTANCES ?? baseMessages.MULTIPLE_REACT_INSTANCES,
|
|
1352
|
+
UNSUPPORTED_REACT_VERSION: customMessages.UNSUPPORTED_REACT_VERSION ?? baseMessages.UNSUPPORTED_REACT_VERSION,
|
|
1353
|
+
UNSUPPORTED_MUI_VERSION: customMessages.UNSUPPORTED_MUI_VERSION ?? baseMessages.UNSUPPORTED_MUI_VERSION,
|
|
1354
|
+
MUI_OUT_OF_RANGE: customMessages.MUI_OUT_OF_RANGE ?? baseMessages.MUI_OUT_OF_RANGE
|
|
1355
|
+
};
|
|
1356
|
+
}
|
|
1357
|
+
function detectMultipleReactInstances() {
|
|
1358
|
+
if (globalThis.window === void 0) return false;
|
|
1359
|
+
try {
|
|
1360
|
+
const reactSymbols = Object.getOwnPropertySymbols(globalThis.window).map(String).filter((name) => name.includes("react"));
|
|
1361
|
+
if (reactSymbols.length > 1) {
|
|
1362
|
+
return true;
|
|
1363
|
+
}
|
|
1364
|
+
const ReactModule = window.React;
|
|
1365
|
+
if (ReactModule && Array.isArray(ReactModule)) {
|
|
1366
|
+
return true;
|
|
1367
|
+
}
|
|
1368
|
+
const hasMultipleVersions = window.__REACT_DEVTOOLS_GLOBAL_HOOK__?.renderers?.size > 1;
|
|
1369
|
+
return hasMultipleVersions || false;
|
|
1370
|
+
} catch {
|
|
1371
|
+
return false;
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
function getPackageVersion(packageName) {
|
|
1375
|
+
if (globalThis.window === void 0) return null;
|
|
1376
|
+
try {
|
|
1377
|
+
const pkg = window[packageName];
|
|
1378
|
+
if (pkg?.version) return pkg.version;
|
|
1379
|
+
const React6 = window.React;
|
|
1380
|
+
if (packageName === "react" && React6?.version) {
|
|
1381
|
+
return React6.version;
|
|
1382
|
+
}
|
|
1383
|
+
return null;
|
|
1384
|
+
} catch {
|
|
1385
|
+
return null;
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
function isVersionInRange(version, minMajor, maxMajor) {
|
|
1389
|
+
const major = Number.parseInt(version.split(".")[0], 10);
|
|
1390
|
+
return major >= minMajor && major <= maxMajor;
|
|
1391
|
+
}
|
|
1392
|
+
function checkPeerDeps(options = {}) {
|
|
1393
|
+
const { skipInProduction = true, logWarnings = true } = options;
|
|
1394
|
+
const result = {
|
|
1395
|
+
ok: true,
|
|
1396
|
+
warnings: [],
|
|
1397
|
+
errors: []
|
|
1398
|
+
};
|
|
1399
|
+
const isProduction = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
1400
|
+
if (skipInProduction && isProduction) {
|
|
1401
|
+
return result;
|
|
1402
|
+
}
|
|
1403
|
+
if (globalThis.window === void 0) {
|
|
1404
|
+
return result;
|
|
1405
|
+
}
|
|
1406
|
+
const messages = getMessages();
|
|
1407
|
+
if (detectMultipleReactInstances()) {
|
|
1408
|
+
result.ok = false;
|
|
1409
|
+
result.errors.push(messages.MULTIPLE_REACT_INSTANCES);
|
|
1410
|
+
if (logWarnings) {
|
|
1411
|
+
console.error(messages.MULTIPLE_REACT_INSTANCES);
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
const reactVersion = getPackageVersion("react");
|
|
1415
|
+
if (reactVersion) {
|
|
1416
|
+
if (!isVersionInRange(reactVersion, 18, 19)) {
|
|
1417
|
+
result.ok = false;
|
|
1418
|
+
const errorMsg = messages.UNSUPPORTED_REACT_VERSION(reactVersion);
|
|
1419
|
+
result.errors.push(errorMsg);
|
|
1420
|
+
if (logWarnings) {
|
|
1421
|
+
console.error(errorMsg);
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
const muiVersion = window["@mui/material"]?.version;
|
|
1426
|
+
if (muiVersion) {
|
|
1427
|
+
if (!isVersionInRange(muiVersion, 5, 7)) {
|
|
1428
|
+
result.warnings.push(messages.MUI_OUT_OF_RANGE(muiVersion));
|
|
1429
|
+
if (logWarnings) {
|
|
1430
|
+
logger.warn(messages.UNSUPPORTED_MUI_VERSION(muiVersion));
|
|
1238
1431
|
}
|
|
1239
1432
|
}
|
|
1240
1433
|
}
|
|
@@ -1257,7 +1450,7 @@ function validateConsentProviderProps(props) {
|
|
|
1257
1450
|
const sanitized = {};
|
|
1258
1451
|
if (!isDev()) {
|
|
1259
1452
|
if (props.categories) {
|
|
1260
|
-
const enabled =
|
|
1453
|
+
const enabled = [...new Set(props.categories.enabledCategories ?? [])];
|
|
1261
1454
|
const sanitizedEnabled = enabled.filter((c) => c !== "necessary");
|
|
1262
1455
|
sanitized.categories = {
|
|
1263
1456
|
enabledCategories: sanitizedEnabled,
|
|
@@ -1294,11 +1487,11 @@ function validateConsentProviderProps(props) {
|
|
|
1294
1487
|
}
|
|
1295
1488
|
if (!props.categories) {
|
|
1296
1489
|
warnings.push(
|
|
1297
|
-
"Prop 'categories' n\xE3o fornecida
|
|
1490
|
+
"Prop 'categories' n\xE3o fornecida \u2014 o ConsentProvider requer configura\xE7\xE3o de categorias."
|
|
1298
1491
|
);
|
|
1299
1492
|
} else {
|
|
1300
1493
|
const cat = props.categories;
|
|
1301
|
-
const enabled =
|
|
1494
|
+
const enabled = [...new Set(cat.enabledCategories ?? [])];
|
|
1302
1495
|
if (enabled.includes("necessary")) {
|
|
1303
1496
|
warnings.push("'necessary' \xE9 sempre inclu\xEDda automaticamente \u2014 remova de enabledCategories.");
|
|
1304
1497
|
}
|
|
@@ -1306,7 +1499,7 @@ function validateConsentProviderProps(props) {
|
|
|
1306
1499
|
const invalidEnabled = sanitizedEnabled.filter((c) => typeof c !== "string" || c.trim() === "");
|
|
1307
1500
|
if (invalidEnabled.length > 0) {
|
|
1308
1501
|
warnings.push(
|
|
1309
|
-
`enabledCategories cont\xE9m valores inv\xE1lidos: ${invalidEnabled.map(
|
|
1502
|
+
`enabledCategories cont\xE9m valores inv\xE1lidos: ${invalidEnabled.map(String).join(", ")} \u2014 remova ou corrija os IDs de categoria`
|
|
1310
1503
|
);
|
|
1311
1504
|
}
|
|
1312
1505
|
const custom = cat.customCategories ?? [];
|
|
@@ -1400,13 +1593,13 @@ function detectConsentCookieName() {
|
|
|
1400
1593
|
}
|
|
1401
1594
|
return null;
|
|
1402
1595
|
}
|
|
1596
|
+
function matchPattern2(name, pattern) {
|
|
1597
|
+
if (pattern.endsWith("*")) return name.startsWith(pattern.slice(0, -1));
|
|
1598
|
+
return name === pattern;
|
|
1599
|
+
}
|
|
1403
1600
|
function categorizeDiscoveredCookies(discovered, registerOverrides = false) {
|
|
1404
1601
|
const list = discovered || globalThis.__LGPD_DISCOVERED_COOKIES__ || [];
|
|
1405
1602
|
const out = {};
|
|
1406
|
-
function matchPattern2(name, pattern) {
|
|
1407
|
-
if (pattern.endsWith("*")) return name.startsWith(pattern.slice(0, -1));
|
|
1408
|
-
return name === pattern;
|
|
1409
|
-
}
|
|
1410
1603
|
list.filter((d) => d.name && d.name !== "cookieConsent").forEach((d) => {
|
|
1411
1604
|
let assigned = null;
|
|
1412
1605
|
Object.keys(COOKIE_PATTERNS_BY_CATEGORY).forEach((cat2) => {
|
|
@@ -1414,9 +1607,9 @@ function categorizeDiscoveredCookies(discovered, registerOverrides = false) {
|
|
|
1414
1607
|
const patterns = COOKIE_PATTERNS_BY_CATEGORY[cat2] || [];
|
|
1415
1608
|
if (patterns.some((p) => matchPattern2(d.name, p))) assigned = cat2;
|
|
1416
1609
|
});
|
|
1417
|
-
const cat = assigned
|
|
1610
|
+
const cat = assigned ?? "analytics";
|
|
1418
1611
|
out[cat] = out[cat] || [];
|
|
1419
|
-
if (!out[cat].
|
|
1612
|
+
if (!out[cat].some((x) => x.name === d.name)) out[cat].push(d);
|
|
1420
1613
|
});
|
|
1421
1614
|
if (registerOverrides) {
|
|
1422
1615
|
const byCategory = {};
|
|
@@ -1493,7 +1686,7 @@ function useCategories() {
|
|
|
1493
1686
|
const context = React4.useContext(CategoriesContext);
|
|
1494
1687
|
if (!context) {
|
|
1495
1688
|
throw new Error(
|
|
1496
|
-
"useCategories deve ser usado dentro de
|
|
1689
|
+
"[react-lgpd-consent] useCategories deve ser usado dentro de <ConsentProvider>. Adicione o provider ao redor da sua \xE1rvore antes de chamar o hook."
|
|
1497
1690
|
);
|
|
1498
1691
|
}
|
|
1499
1692
|
return context;
|
|
@@ -1644,6 +1837,11 @@ var StateCtx = React4.createContext(null);
|
|
|
1644
1837
|
var ActionsCtx = React4.createContext(null);
|
|
1645
1838
|
var TextsCtx = React4.createContext(DEFAULT_TEXTS);
|
|
1646
1839
|
var HydrationCtx = React4.createContext(false);
|
|
1840
|
+
function buildProviderError(hookName) {
|
|
1841
|
+
return new Error(
|
|
1842
|
+
`[react-lgpd-consent] ${hookName} deve ser usado dentro de <ConsentProvider>. Envolva seu componente com o provider ou use o wrapper @react-lgpd-consent/mui.`
|
|
1843
|
+
);
|
|
1844
|
+
}
|
|
1647
1845
|
function ConsentProvider({
|
|
1648
1846
|
initialState,
|
|
1649
1847
|
categories,
|
|
@@ -1667,7 +1865,10 @@ function ConsentProvider({
|
|
|
1667
1865
|
disableDeveloperGuidance,
|
|
1668
1866
|
guidanceConfig,
|
|
1669
1867
|
children,
|
|
1670
|
-
disableDiscoveryLog
|
|
1868
|
+
disableDiscoveryLog,
|
|
1869
|
+
onConsentInit,
|
|
1870
|
+
onConsentChange,
|
|
1871
|
+
onAuditLog
|
|
1671
1872
|
}) {
|
|
1672
1873
|
const texts = React4.useMemo(() => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }), [textsProp]);
|
|
1673
1874
|
const cookie = React4.useMemo(() => {
|
|
@@ -1681,6 +1882,14 @@ function ConsentProvider({
|
|
|
1681
1882
|
}
|
|
1682
1883
|
return base;
|
|
1683
1884
|
}, [cookieOpts, storage?.domain, storage?.namespace, storage?.version]);
|
|
1885
|
+
const consentVersion = storage?.version?.trim() || "1";
|
|
1886
|
+
React4.useEffect(() => {
|
|
1887
|
+
try {
|
|
1888
|
+
;
|
|
1889
|
+
globalThis.__LGPD_CONSENT_COOKIE__ = cookie.name;
|
|
1890
|
+
} catch {
|
|
1891
|
+
}
|
|
1892
|
+
}, [cookie.name]);
|
|
1684
1893
|
const finalCategoriesConfig = React4.useMemo(() => {
|
|
1685
1894
|
const isProd = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
1686
1895
|
if (!categories) return DEFAULT_PROJECT_CATEGORIES;
|
|
@@ -1727,6 +1936,8 @@ function ConsentProvider({
|
|
|
1727
1936
|
const skipCookiePersistRef = React4.useRef(false);
|
|
1728
1937
|
const [isHydrated, setIsHydrated] = React4.useState(false);
|
|
1729
1938
|
const previousPreferencesRef = React4.useRef(state.preferences);
|
|
1939
|
+
const auditInitEmittedRef = React4.useRef(false);
|
|
1940
|
+
const previousConsentedAuditRef = React4.useRef(state.consented);
|
|
1730
1941
|
React4.useEffect(() => {
|
|
1731
1942
|
if (!initialState) {
|
|
1732
1943
|
const saved = readConsentCookie(cookie.name);
|
|
@@ -1775,13 +1986,44 @@ function ConsentProvider({
|
|
|
1775
1986
|
logger.info("DataLayer: consent_initialized event dispatched", {
|
|
1776
1987
|
preferences: state.preferences
|
|
1777
1988
|
});
|
|
1989
|
+
if (onConsentInit) onConsentInit(state);
|
|
1778
1990
|
}
|
|
1779
1991
|
}, [isHydrated]);
|
|
1992
|
+
React4.useEffect(() => {
|
|
1993
|
+
if (!isHydrated) return;
|
|
1994
|
+
if (!onAuditLog) return;
|
|
1995
|
+
if (auditInitEmittedRef.current) return;
|
|
1996
|
+
onAuditLog(
|
|
1997
|
+
createConsentAuditEntry(state, {
|
|
1998
|
+
action: "init",
|
|
1999
|
+
storageKey: cookie.name,
|
|
2000
|
+
consentVersion
|
|
2001
|
+
})
|
|
2002
|
+
);
|
|
2003
|
+
auditInitEmittedRef.current = true;
|
|
2004
|
+
}, [isHydrated, onAuditLog, state, cookie.name, consentVersion]);
|
|
1780
2005
|
React4.useEffect(() => {
|
|
1781
2006
|
if (!state.consented) return;
|
|
1782
2007
|
if (skipCookiePersistRef.current) return;
|
|
1783
2008
|
writeConsentCookie(state, finalCategoriesConfig, cookie);
|
|
1784
2009
|
}, [state, cookie, finalCategoriesConfig]);
|
|
2010
|
+
React4.useEffect(() => {
|
|
2011
|
+
if (!onAuditLog) {
|
|
2012
|
+
previousConsentedAuditRef.current = state.consented;
|
|
2013
|
+
return;
|
|
2014
|
+
}
|
|
2015
|
+
if (previousConsentedAuditRef.current && !state.consented) {
|
|
2016
|
+
onAuditLog(
|
|
2017
|
+
createConsentAuditEntry(state, {
|
|
2018
|
+
action: "reset",
|
|
2019
|
+
storageKey: cookie.name,
|
|
2020
|
+
consentVersion,
|
|
2021
|
+
origin: "reset"
|
|
2022
|
+
})
|
|
2023
|
+
);
|
|
2024
|
+
}
|
|
2025
|
+
previousConsentedAuditRef.current = state.consented;
|
|
2026
|
+
}, [state, onAuditLog, cookie.name, consentVersion]);
|
|
1785
2027
|
const prevConsented = React4.useRef(state.consented);
|
|
1786
2028
|
React4.useEffect(() => {
|
|
1787
2029
|
if (!prevConsented.current && state.consented && onConsentGiven) {
|
|
@@ -1802,9 +2044,32 @@ function ConsentProvider({
|
|
|
1802
2044
|
preferences: state.preferences,
|
|
1803
2045
|
consented: state.consented
|
|
1804
2046
|
});
|
|
2047
|
+
if (onConsentChange) {
|
|
2048
|
+
onConsentChange(state, { origin });
|
|
2049
|
+
}
|
|
2050
|
+
if (onAuditLog) {
|
|
2051
|
+
onAuditLog(
|
|
2052
|
+
createConsentAuditEntry(state, {
|
|
2053
|
+
action: "update",
|
|
2054
|
+
storageKey: cookie.name,
|
|
2055
|
+
consentVersion,
|
|
2056
|
+
origin
|
|
2057
|
+
})
|
|
2058
|
+
);
|
|
2059
|
+
}
|
|
1805
2060
|
previousPreferencesRef.current = state.preferences;
|
|
1806
2061
|
}
|
|
1807
|
-
}, [
|
|
2062
|
+
}, [
|
|
2063
|
+
state,
|
|
2064
|
+
state.preferences,
|
|
2065
|
+
state.consented,
|
|
2066
|
+
state.source,
|
|
2067
|
+
isHydrated,
|
|
2068
|
+
onConsentChange,
|
|
2069
|
+
onAuditLog,
|
|
2070
|
+
cookie.name,
|
|
2071
|
+
consentVersion
|
|
2072
|
+
]);
|
|
1808
2073
|
const api = React4.useMemo(() => {
|
|
1809
2074
|
const acceptAll = () => dispatch({ type: "ACCEPT_ALL", config: finalCategoriesConfig });
|
|
1810
2075
|
const rejectAll = () => dispatch({ type: "REJECT_ALL", config: finalCategoriesConfig });
|
|
@@ -1855,6 +2120,14 @@ function ConsentProvider({
|
|
|
1855
2120
|
if (typeof backdrop === "string") return backdrop;
|
|
1856
2121
|
return "rgba(0, 0, 0, 0.4)";
|
|
1857
2122
|
}, [designTokens]);
|
|
2123
|
+
const cookieBannerPropsWithDefaults = React4.useMemo(() => {
|
|
2124
|
+
const incoming = cookieBannerProps ?? {};
|
|
2125
|
+
return {
|
|
2126
|
+
...incoming,
|
|
2127
|
+
blocking: incoming.blocking === void 0 ? blocking : Boolean(incoming.blocking),
|
|
2128
|
+
hideBranding: incoming.hideBranding === void 0 ? _hideBranding : Boolean(incoming.hideBranding)
|
|
2129
|
+
};
|
|
2130
|
+
}, [cookieBannerProps, blocking, _hideBranding]);
|
|
1858
2131
|
const content = /* @__PURE__ */ jsx(StateCtx.Provider, { value: state, children: /* @__PURE__ */ jsx(ActionsCtx.Provider, { value: api, children: /* @__PURE__ */ jsx(TextsCtx.Provider, { value: texts, children: /* @__PURE__ */ jsx(HydrationCtx.Provider, { value: isHydrated, children: /* @__PURE__ */ jsx(DesignProvider, { tokens: designTokens, children: /* @__PURE__ */ jsxs(
|
|
1859
2132
|
CategoriesProvider,
|
|
1860
2133
|
{
|
|
@@ -1875,7 +2148,7 @@ function ConsentProvider({
|
|
|
1875
2148
|
}
|
|
1876
2149
|
) : (
|
|
1877
2150
|
// Aviso de desenvolvimento: usuário pode estar esquecendo de fornecer componentes UI
|
|
1878
|
-
process.env.NODE_ENV === "development" &&
|
|
2151
|
+
process.env.NODE_ENV === "development" && globalThis.window !== void 0 && !didWarnAboutMissingUI.current && !CookieBannerComponent && !FloatingPreferencesButtonComponent && (() => {
|
|
1879
2152
|
didWarnAboutMissingUI.current = true;
|
|
1880
2153
|
console.warn(
|
|
1881
2154
|
"%c[@react-lgpd-consent/core] Aviso: Nenhum componente UI fornecido",
|
|
@@ -1937,8 +2210,7 @@ function ConsentProvider({
|
|
|
1937
2210
|
rejectAll: api.rejectAll,
|
|
1938
2211
|
openPreferences: api.openPreferences,
|
|
1939
2212
|
texts,
|
|
1940
|
-
|
|
1941
|
-
...cookieBannerProps
|
|
2213
|
+
...cookieBannerPropsWithDefaults
|
|
1942
2214
|
}
|
|
1943
2215
|
),
|
|
1944
2216
|
state.consented && !disableFloatingPreferencesButton && FloatingPreferencesButtonComponent && /* @__PURE__ */ jsx(
|
|
@@ -1956,12 +2228,12 @@ function ConsentProvider({
|
|
|
1956
2228
|
}
|
|
1957
2229
|
function useConsentStateInternal() {
|
|
1958
2230
|
const ctx = React4.useContext(StateCtx);
|
|
1959
|
-
if (!ctx) throw
|
|
2231
|
+
if (!ctx) throw buildProviderError("useConsentState");
|
|
1960
2232
|
return ctx;
|
|
1961
2233
|
}
|
|
1962
2234
|
function useConsentActionsInternal() {
|
|
1963
2235
|
const ctx = React4.useContext(ActionsCtx);
|
|
1964
|
-
if (!ctx) throw
|
|
2236
|
+
if (!ctx) throw buildProviderError("useConsentActions");
|
|
1965
2237
|
return ctx;
|
|
1966
2238
|
}
|
|
1967
2239
|
function useConsentTextsInternal() {
|
|
@@ -1980,45 +2252,99 @@ function ConsentGate(props) {
|
|
|
1980
2252
|
|
|
1981
2253
|
// src/utils/scriptLoader.ts
|
|
1982
2254
|
var LOADING_SCRIPTS = /* @__PURE__ */ new Map();
|
|
1983
|
-
|
|
2255
|
+
var DEFAULT_POLL_INTERVAL = 100;
|
|
2256
|
+
function resolveCookieNames(preferred) {
|
|
2257
|
+
const inferred = globalThis.__LGPD_CONSENT_COOKIE__ ?? null;
|
|
2258
|
+
const names = [preferred, inferred, "cookieConsent", "lgpd-consent__v1"].filter(
|
|
2259
|
+
Boolean
|
|
2260
|
+
);
|
|
2261
|
+
return Array.from(new Set(names));
|
|
2262
|
+
}
|
|
2263
|
+
function parseConsentFromCookie(names) {
|
|
2264
|
+
const raw = document.cookie;
|
|
2265
|
+
if (!raw) return null;
|
|
2266
|
+
const cookies = raw.split("; ").reduce((acc, part) => {
|
|
2267
|
+
const [k, ...rest] = part.split("=");
|
|
2268
|
+
acc[k] = rest.join("=");
|
|
2269
|
+
return acc;
|
|
2270
|
+
}, {});
|
|
2271
|
+
for (const name of names) {
|
|
2272
|
+
const value = cookies[name];
|
|
2273
|
+
if (!value) continue;
|
|
2274
|
+
try {
|
|
2275
|
+
const parsed = JSON.parse(decodeURIComponent(value));
|
|
2276
|
+
if (!parsed.consented || parsed.isModalOpen) continue;
|
|
2277
|
+
return parsed;
|
|
2278
|
+
} catch {
|
|
2279
|
+
continue;
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
2282
|
+
return null;
|
|
2283
|
+
}
|
|
2284
|
+
function hasCategoryConsent(snapshot, category) {
|
|
2285
|
+
if (!snapshot.consented || snapshot.isModalOpen) return false;
|
|
2286
|
+
if (category === null) return true;
|
|
2287
|
+
return Boolean(snapshot.preferences?.[category]);
|
|
2288
|
+
}
|
|
2289
|
+
function loadScript(id, src, category = null, attrs = {}, nonce, options) {
|
|
1984
2290
|
if (typeof document === "undefined") return Promise.resolve();
|
|
1985
2291
|
if (document.getElementById(id)) return Promise.resolve();
|
|
1986
2292
|
const existingPromise = LOADING_SCRIPTS.get(id);
|
|
1987
2293
|
if (existingPromise) return existingPromise;
|
|
2294
|
+
const pollInterval = options?.pollIntervalMs ?? DEFAULT_POLL_INTERVAL;
|
|
2295
|
+
const names = resolveCookieNames(options?.cookieName);
|
|
2296
|
+
const mergedAttrs = { ...attrs };
|
|
1988
2297
|
const promise = new Promise((resolve, reject) => {
|
|
2298
|
+
const inject = () => {
|
|
2299
|
+
const s = document.createElement("script");
|
|
2300
|
+
s.id = id;
|
|
2301
|
+
s.src = src;
|
|
2302
|
+
s.async = mergedAttrs.async !== "false";
|
|
2303
|
+
const scriptNonce = mergedAttrs.nonce || nonce;
|
|
2304
|
+
if (scriptNonce) {
|
|
2305
|
+
s.nonce = scriptNonce;
|
|
2306
|
+
mergedAttrs.nonce = scriptNonce;
|
|
2307
|
+
}
|
|
2308
|
+
for (const [k, v] of Object.entries(mergedAttrs)) s.setAttribute(k, v);
|
|
2309
|
+
s.onload = () => {
|
|
2310
|
+
LOADING_SCRIPTS.delete(id);
|
|
2311
|
+
resolve();
|
|
2312
|
+
};
|
|
2313
|
+
s.onerror = () => {
|
|
2314
|
+
LOADING_SCRIPTS.delete(id);
|
|
2315
|
+
reject(new Error(`Failed to load script: ${src}`));
|
|
2316
|
+
};
|
|
2317
|
+
document.body.appendChild(s);
|
|
2318
|
+
};
|
|
2319
|
+
const snapshot = options?.consentSnapshot;
|
|
2320
|
+
const skipChecks = options?.skipConsentCheck === true;
|
|
2321
|
+
if (skipChecks) {
|
|
2322
|
+
inject();
|
|
2323
|
+
return;
|
|
2324
|
+
}
|
|
2325
|
+
if (snapshot) {
|
|
2326
|
+
if (!hasCategoryConsent(snapshot, category)) {
|
|
2327
|
+
reject(
|
|
2328
|
+
new Error(
|
|
2329
|
+
`Consent not granted for category '${category ?? "none"}' when attempting to load ${id}`
|
|
2330
|
+
)
|
|
2331
|
+
);
|
|
2332
|
+
return;
|
|
2333
|
+
}
|
|
2334
|
+
inject();
|
|
2335
|
+
return;
|
|
2336
|
+
}
|
|
1989
2337
|
const checkConsent = () => {
|
|
1990
|
-
const
|
|
1991
|
-
if (!
|
|
1992
|
-
setTimeout(checkConsent,
|
|
2338
|
+
const consent = parseConsentFromCookie(names);
|
|
2339
|
+
if (!consent) {
|
|
2340
|
+
setTimeout(checkConsent, pollInterval);
|
|
1993
2341
|
return;
|
|
1994
2342
|
}
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
setTimeout(checkConsent, 100);
|
|
1999
|
-
return;
|
|
2000
|
-
}
|
|
2001
|
-
if (category && !consent.preferences[category]) {
|
|
2002
|
-
setTimeout(checkConsent, 100);
|
|
2003
|
-
return;
|
|
2004
|
-
}
|
|
2005
|
-
const s = document.createElement("script");
|
|
2006
|
-
s.id = id;
|
|
2007
|
-
s.src = src;
|
|
2008
|
-
s.async = true;
|
|
2009
|
-
for (const [k, v] of Object.entries(attrs)) s.setAttribute(k, v);
|
|
2010
|
-
s.onload = () => {
|
|
2011
|
-
LOADING_SCRIPTS.delete(id);
|
|
2012
|
-
resolve();
|
|
2013
|
-
};
|
|
2014
|
-
s.onerror = () => {
|
|
2015
|
-
LOADING_SCRIPTS.delete(id);
|
|
2016
|
-
reject(new Error(`Failed to load script: ${src}`));
|
|
2017
|
-
};
|
|
2018
|
-
document.body.appendChild(s);
|
|
2019
|
-
} catch {
|
|
2020
|
-
setTimeout(checkConsent, 100);
|
|
2343
|
+
if (!hasCategoryConsent(consent, category)) {
|
|
2344
|
+
setTimeout(checkConsent, pollInterval);
|
|
2345
|
+
return;
|
|
2021
2346
|
}
|
|
2347
|
+
inject();
|
|
2022
2348
|
};
|
|
2023
2349
|
checkConsent();
|
|
2024
2350
|
});
|
|
@@ -2182,13 +2508,107 @@ function validateNecessaryClassification(integrations, enabledCategories) {
|
|
|
2182
2508
|
}
|
|
2183
2509
|
|
|
2184
2510
|
// src/utils/ConsentScriptLoader.tsx
|
|
2511
|
+
var scriptRegistry = /* @__PURE__ */ new Map();
|
|
2512
|
+
var queueListeners = /* @__PURE__ */ new Set();
|
|
2513
|
+
function notifyQueue() {
|
|
2514
|
+
queueListeners.forEach((listener) => {
|
|
2515
|
+
try {
|
|
2516
|
+
listener();
|
|
2517
|
+
} catch {
|
|
2518
|
+
}
|
|
2519
|
+
});
|
|
2520
|
+
}
|
|
2521
|
+
function subscribeQueue(listener) {
|
|
2522
|
+
queueListeners.add(listener);
|
|
2523
|
+
return () => {
|
|
2524
|
+
queueListeners.delete(listener);
|
|
2525
|
+
};
|
|
2526
|
+
}
|
|
2527
|
+
function createInternalScript(def) {
|
|
2528
|
+
return {
|
|
2529
|
+
...def,
|
|
2530
|
+
status: "pending",
|
|
2531
|
+
lastAllowed: false,
|
|
2532
|
+
registeredAt: Date.now(),
|
|
2533
|
+
token: Date.now() + Math.random(),
|
|
2534
|
+
priority: def.priority ?? 0,
|
|
2535
|
+
allowReload: def.allowReload ?? false,
|
|
2536
|
+
onConsentUpdate: def.onConsentUpdate
|
|
2537
|
+
};
|
|
2538
|
+
}
|
|
2539
|
+
function registerScript(def) {
|
|
2540
|
+
const entry = createInternalScript(def);
|
|
2541
|
+
scriptRegistry.set(def.id, entry);
|
|
2542
|
+
notifyQueue();
|
|
2543
|
+
return () => {
|
|
2544
|
+
const current = scriptRegistry.get(def.id);
|
|
2545
|
+
if (current && current.token === entry.token) {
|
|
2546
|
+
scriptRegistry.delete(def.id);
|
|
2547
|
+
notifyQueue();
|
|
2548
|
+
}
|
|
2549
|
+
};
|
|
2550
|
+
}
|
|
2551
|
+
function getExecutableScripts(consent) {
|
|
2552
|
+
const allowedScripts = [];
|
|
2553
|
+
scriptRegistry.forEach((script) => {
|
|
2554
|
+
const categoryAllowed = script.category === "necessary" || consent.consented && Boolean(consent.preferences?.[script.category]);
|
|
2555
|
+
if (!categoryAllowed) {
|
|
2556
|
+
script.lastAllowed = false;
|
|
2557
|
+
return;
|
|
2558
|
+
}
|
|
2559
|
+
if (script.status === "running") return;
|
|
2560
|
+
if (script.status === "executed" && !script.allowReload) return;
|
|
2561
|
+
if (script.status === "executed" && script.allowReload && script.lastAllowed) return;
|
|
2562
|
+
script.lastAllowed = true;
|
|
2563
|
+
allowedScripts.push(script);
|
|
2564
|
+
});
|
|
2565
|
+
return allowedScripts.sort((a, b) => {
|
|
2566
|
+
if (a.category === "necessary" && b.category !== "necessary") return -1;
|
|
2567
|
+
if (b.category === "necessary" && a.category !== "necessary") return 1;
|
|
2568
|
+
if (a.category !== b.category) return a.category.localeCompare(b.category);
|
|
2569
|
+
if (a.priority !== b.priority) return (b.priority ?? 0) - (a.priority ?? 0);
|
|
2570
|
+
return a.registeredAt - b.registeredAt;
|
|
2571
|
+
});
|
|
2572
|
+
}
|
|
2573
|
+
async function processQueue(consent, devLogging) {
|
|
2574
|
+
const scripts = getExecutableScripts(consent);
|
|
2575
|
+
let order = 0;
|
|
2576
|
+
for (const script of scripts) {
|
|
2577
|
+
order += 1;
|
|
2578
|
+
script.status = "running";
|
|
2579
|
+
if (devLogging) {
|
|
2580
|
+
logger.info("[ConsentScriptLoader] executando script", {
|
|
2581
|
+
id: script.id,
|
|
2582
|
+
category: script.category,
|
|
2583
|
+
priority: script.priority ?? 0,
|
|
2584
|
+
order
|
|
2585
|
+
});
|
|
2586
|
+
}
|
|
2587
|
+
try {
|
|
2588
|
+
await Promise.resolve(script.execute());
|
|
2589
|
+
} catch (error) {
|
|
2590
|
+
logger.error(`\u274C Failed to execute script ${script.id}`, error);
|
|
2591
|
+
} finally {
|
|
2592
|
+
script.status = "executed";
|
|
2593
|
+
if (script.onConsentUpdate) {
|
|
2594
|
+
script.onConsentUpdate(consent);
|
|
2595
|
+
}
|
|
2596
|
+
}
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
2185
2599
|
function ConsentScriptLoader({
|
|
2186
2600
|
integrations,
|
|
2187
|
-
reloadOnChange = false
|
|
2601
|
+
reloadOnChange = false,
|
|
2602
|
+
nonce
|
|
2188
2603
|
}) {
|
|
2189
2604
|
const { preferences, consented } = useConsent();
|
|
2605
|
+
const isHydrated = useConsentHydration();
|
|
2190
2606
|
const categories = useCategories();
|
|
2191
|
-
const
|
|
2607
|
+
const [queueVersion, bumpQueueVersion] = React4.useState(0);
|
|
2608
|
+
React4.useEffect(() => {
|
|
2609
|
+
const unsubscribe = subscribeQueue(() => bumpQueueVersion((v) => v + 1));
|
|
2610
|
+
return unsubscribe;
|
|
2611
|
+
}, []);
|
|
2192
2612
|
React4.useEffect(() => {
|
|
2193
2613
|
try {
|
|
2194
2614
|
const ids = (integrations || []).map((i) => i.id);
|
|
@@ -2217,8 +2637,8 @@ function ConsentScriptLoader({
|
|
|
2217
2637
|
const current = Array.isArray(gt.__LGPD_REQUIRED_CATEGORIES__) ? gt.__LGPD_REQUIRED_CATEGORIES__ : [];
|
|
2218
2638
|
const merged = Array.from(/* @__PURE__ */ new Set([...current, ...required]));
|
|
2219
2639
|
gt.__LGPD_REQUIRED_CATEGORIES__ = merged;
|
|
2220
|
-
if (
|
|
2221
|
-
window.dispatchEvent(new CustomEvent("lgpd:requiredCategories"));
|
|
2640
|
+
if (globalThis.window !== void 0 && typeof globalThis.window.dispatchEvent === "function") {
|
|
2641
|
+
globalThis.window.dispatchEvent(new CustomEvent("lgpd:requiredCategories"));
|
|
2222
2642
|
}
|
|
2223
2643
|
} catch {
|
|
2224
2644
|
}
|
|
@@ -2226,7 +2646,7 @@ function ConsentScriptLoader({
|
|
|
2226
2646
|
React4.useEffect(() => {
|
|
2227
2647
|
const isDev2 = process.env.NODE_ENV !== "production";
|
|
2228
2648
|
if (!isDev2 || integrations.length === 0) return;
|
|
2229
|
-
const enabledCategories = categories.
|
|
2649
|
+
const enabledCategories = categories.config.enabledCategories ?? [];
|
|
2230
2650
|
const isValid = validateIntegrationCategories(integrations, enabledCategories);
|
|
2231
2651
|
if (!isValid) {
|
|
2232
2652
|
autoConfigureCategories({ enabledCategories }, integrations, {
|
|
@@ -2249,38 +2669,99 @@ function ConsentScriptLoader({
|
|
|
2249
2669
|
console.groupEnd();
|
|
2250
2670
|
}
|
|
2251
2671
|
}, [integrations, categories]);
|
|
2672
|
+
const processedIntegrationsRef = React4.useRef(/* @__PURE__ */ new Map());
|
|
2252
2673
|
React4.useEffect(() => {
|
|
2253
|
-
|
|
2254
|
-
const
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2674
|
+
const cleanups = [];
|
|
2675
|
+
const currentIds = /* @__PURE__ */ new Set();
|
|
2676
|
+
integrations.forEach((integration) => {
|
|
2677
|
+
currentIds.add(integration.id);
|
|
2678
|
+
const structuralHash = JSON.stringify({
|
|
2679
|
+
category: integration.category,
|
|
2680
|
+
src: integration.src,
|
|
2681
|
+
priority: integration.priority,
|
|
2682
|
+
hasBootstrap: Boolean(integration.bootstrap),
|
|
2683
|
+
hasInit: Boolean(integration.init),
|
|
2684
|
+
hasOnConsentUpdate: Boolean(integration.onConsentUpdate)
|
|
2685
|
+
});
|
|
2686
|
+
const existingHash = processedIntegrationsRef.current.get(integration.id);
|
|
2687
|
+
if (existingHash === structuralHash && scriptRegistry.has(integration.id)) {
|
|
2688
|
+
return;
|
|
2689
|
+
}
|
|
2690
|
+
processedIntegrationsRef.current.set(integration.id, structuralHash);
|
|
2691
|
+
if (integration.bootstrap) {
|
|
2692
|
+
cleanups.push(
|
|
2693
|
+
registerScript({
|
|
2694
|
+
id: `${integration.id}__bootstrap`,
|
|
2695
|
+
category: "necessary",
|
|
2696
|
+
priority: (integration.priority ?? 0) + 1e3,
|
|
2697
|
+
execute: integration.bootstrap
|
|
2698
|
+
})
|
|
2699
|
+
);
|
|
2700
|
+
}
|
|
2701
|
+
cleanups.push(
|
|
2702
|
+
registerScript({
|
|
2703
|
+
id: integration.id,
|
|
2704
|
+
category: integration.category,
|
|
2705
|
+
priority: integration.priority,
|
|
2706
|
+
allowReload: reloadOnChange,
|
|
2707
|
+
onConsentUpdate: integration.onConsentUpdate,
|
|
2708
|
+
execute: async () => {
|
|
2709
|
+
const mergedAttrs = integration.attrs ? { ...integration.attrs } : {};
|
|
2710
|
+
const scriptNonce = integration.nonce ?? nonce;
|
|
2711
|
+
if (scriptNonce && !mergedAttrs.nonce) mergedAttrs.nonce = scriptNonce;
|
|
2260
2712
|
await loadScript(
|
|
2261
2713
|
integration.id,
|
|
2262
2714
|
integration.src,
|
|
2263
2715
|
integration.category,
|
|
2264
|
-
|
|
2716
|
+
mergedAttrs,
|
|
2717
|
+
scriptNonce,
|
|
2718
|
+
{ skipConsentCheck: true }
|
|
2265
2719
|
);
|
|
2266
2720
|
if (integration.init) {
|
|
2267
2721
|
integration.init();
|
|
2268
2722
|
}
|
|
2269
|
-
loadedScripts.current.add(integration.id);
|
|
2270
|
-
} catch (error) {
|
|
2271
|
-
logger.error(`\u274C Failed to load script: ${integration.id}`, error);
|
|
2272
2723
|
}
|
|
2724
|
+
})
|
|
2725
|
+
);
|
|
2726
|
+
});
|
|
2727
|
+
processedIntegrationsRef.current.forEach((_, id) => {
|
|
2728
|
+
if (!currentIds.has(id)) {
|
|
2729
|
+
processedIntegrationsRef.current.delete(id);
|
|
2730
|
+
const script = scriptRegistry.get(id);
|
|
2731
|
+
if (script) {
|
|
2732
|
+
scriptRegistry.delete(id);
|
|
2733
|
+
}
|
|
2734
|
+
const bootstrapScript = scriptRegistry.get(`${id}__bootstrap`);
|
|
2735
|
+
if (bootstrapScript) {
|
|
2736
|
+
scriptRegistry.delete(`${id}__bootstrap`);
|
|
2273
2737
|
}
|
|
2274
2738
|
}
|
|
2275
|
-
}
|
|
2276
|
-
return () =>
|
|
2277
|
-
}, [
|
|
2739
|
+
});
|
|
2740
|
+
return () => cleanups.forEach((fn) => fn());
|
|
2741
|
+
}, [integrations, reloadOnChange, nonce]);
|
|
2742
|
+
React4.useEffect(() => {
|
|
2743
|
+
if (!isHydrated) return;
|
|
2744
|
+
void processQueue({ consented, preferences }, process.env.NODE_ENV !== "production");
|
|
2745
|
+
}, [consented, preferences, isHydrated, queueVersion]);
|
|
2746
|
+
React4.useEffect(() => {
|
|
2747
|
+
if (!isHydrated) return;
|
|
2748
|
+
scriptRegistry.forEach((script) => {
|
|
2749
|
+
if (script.status !== "executed") return;
|
|
2750
|
+
if (typeof script.onConsentUpdate !== "function") return;
|
|
2751
|
+
script.onConsentUpdate({ consented, preferences });
|
|
2752
|
+
});
|
|
2753
|
+
}, [consented, preferences, isHydrated]);
|
|
2278
2754
|
return null;
|
|
2279
2755
|
}
|
|
2280
2756
|
function useConsentScriptLoader() {
|
|
2281
2757
|
const { preferences, consented } = useConsent();
|
|
2758
|
+
const isHydrated = useConsentHydration();
|
|
2282
2759
|
return React4.useCallback(
|
|
2283
|
-
async (integration) => {
|
|
2760
|
+
async (integration, nonce) => {
|
|
2761
|
+
if (!isHydrated) {
|
|
2762
|
+
logger.warn(`\u26A0\uFE0F Cannot load script ${integration.id}: Consent not hydrated yet`);
|
|
2763
|
+
return false;
|
|
2764
|
+
}
|
|
2284
2765
|
if (!consented) {
|
|
2285
2766
|
logger.warn(`\u26A0\uFE0F Cannot load script ${integration.id}: No consent given`);
|
|
2286
2767
|
return false;
|
|
@@ -2293,7 +2774,20 @@ function useConsentScriptLoader() {
|
|
|
2293
2774
|
return false;
|
|
2294
2775
|
}
|
|
2295
2776
|
try {
|
|
2296
|
-
|
|
2777
|
+
const mergedAttrs = integration.attrs ? { ...integration.attrs } : {};
|
|
2778
|
+
const scriptNonce = integration.nonce ?? nonce;
|
|
2779
|
+
if (scriptNonce && !mergedAttrs.nonce) mergedAttrs.nonce = scriptNonce;
|
|
2780
|
+
await loadScript(
|
|
2781
|
+
integration.id,
|
|
2782
|
+
integration.src,
|
|
2783
|
+
integration.category,
|
|
2784
|
+
mergedAttrs,
|
|
2785
|
+
scriptNonce,
|
|
2786
|
+
{
|
|
2787
|
+
consentSnapshot: { consented, preferences },
|
|
2788
|
+
skipConsentCheck: true
|
|
2789
|
+
}
|
|
2790
|
+
);
|
|
2297
2791
|
if (integration.init) {
|
|
2298
2792
|
integration.init();
|
|
2299
2793
|
}
|
|
@@ -2303,11 +2797,62 @@ function useConsentScriptLoader() {
|
|
|
2303
2797
|
return false;
|
|
2304
2798
|
}
|
|
2305
2799
|
},
|
|
2306
|
-
[preferences, consented]
|
|
2800
|
+
[preferences, consented, isHydrated]
|
|
2307
2801
|
);
|
|
2308
2802
|
}
|
|
2309
2803
|
|
|
2310
2804
|
// src/utils/scriptIntegrations.ts
|
|
2805
|
+
function buildConsentModeSignals(preferences) {
|
|
2806
|
+
const analytics = preferences.analytics ? "granted" : "denied";
|
|
2807
|
+
const marketing = preferences.marketing ? "granted" : "denied";
|
|
2808
|
+
return {
|
|
2809
|
+
ad_storage: marketing,
|
|
2810
|
+
ad_user_data: marketing,
|
|
2811
|
+
ad_personalization: marketing,
|
|
2812
|
+
analytics_storage: analytics
|
|
2813
|
+
};
|
|
2814
|
+
}
|
|
2815
|
+
function pushToLayer(entry, dataLayerName) {
|
|
2816
|
+
if (typeof globalThis.window === "undefined") return;
|
|
2817
|
+
const registry = globalThis.window;
|
|
2818
|
+
const name = dataLayerName ?? "dataLayer";
|
|
2819
|
+
const layer = registry[name] ?? [];
|
|
2820
|
+
registry[name] = layer;
|
|
2821
|
+
layer.push(entry);
|
|
2822
|
+
}
|
|
2823
|
+
function ensureGtag(dataLayerName = "dataLayer") {
|
|
2824
|
+
if (typeof globalThis.window === "undefined") return null;
|
|
2825
|
+
const w = window;
|
|
2826
|
+
const registry = w;
|
|
2827
|
+
const layer = registry[dataLayerName] ?? [];
|
|
2828
|
+
registry[dataLayerName] = layer;
|
|
2829
|
+
if (typeof w.gtag !== "function") {
|
|
2830
|
+
const gtag = (...args) => {
|
|
2831
|
+
layer.push(args);
|
|
2832
|
+
};
|
|
2833
|
+
w.gtag = gtag;
|
|
2834
|
+
}
|
|
2835
|
+
return w.gtag;
|
|
2836
|
+
}
|
|
2837
|
+
function applyDefaultConsentMode(dataLayerName) {
|
|
2838
|
+
const payload = buildConsentModeSignals({
|
|
2839
|
+
analytics: false,
|
|
2840
|
+
marketing: false
|
|
2841
|
+
});
|
|
2842
|
+
const gtag = ensureGtag(dataLayerName);
|
|
2843
|
+
if (gtag) {
|
|
2844
|
+
gtag("consent", "default", payload);
|
|
2845
|
+
}
|
|
2846
|
+
pushToLayer(["consent", "default", payload], dataLayerName);
|
|
2847
|
+
}
|
|
2848
|
+
function applyConsentModeUpdate(preferences, dataLayerName) {
|
|
2849
|
+
const payload = buildConsentModeSignals(preferences);
|
|
2850
|
+
const gtag = ensureGtag(dataLayerName);
|
|
2851
|
+
if (gtag) {
|
|
2852
|
+
gtag("consent", "update", payload);
|
|
2853
|
+
}
|
|
2854
|
+
pushToLayer(["consent", "update", payload], dataLayerName);
|
|
2855
|
+
}
|
|
2311
2856
|
function createGoogleAnalyticsIntegration(config) {
|
|
2312
2857
|
const src = config.scriptUrl ?? `https://www.googletagmanager.com/gtag/js?id=${config.measurementId}`;
|
|
2313
2858
|
return {
|
|
@@ -2335,17 +2880,17 @@ function createGoogleAnalyticsIntegration(config) {
|
|
|
2335
2880
|
provider: "Google Analytics"
|
|
2336
2881
|
}
|
|
2337
2882
|
],
|
|
2883
|
+
bootstrap: () => {
|
|
2884
|
+
applyDefaultConsentMode();
|
|
2885
|
+
},
|
|
2886
|
+
onConsentUpdate: ({ preferences }) => {
|
|
2887
|
+
applyConsentModeUpdate(preferences);
|
|
2888
|
+
},
|
|
2338
2889
|
init: () => {
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
w.dataLayer.push(...args);
|
|
2344
|
-
};
|
|
2345
|
-
w.gtag = gtag;
|
|
2346
|
-
gtag("js", /* @__PURE__ */ new Date());
|
|
2347
|
-
gtag("config", config.measurementId, config.config ?? {});
|
|
2348
|
-
}
|
|
2890
|
+
const gtag = ensureGtag();
|
|
2891
|
+
if (!gtag) return;
|
|
2892
|
+
gtag("js", /* @__PURE__ */ new Date());
|
|
2893
|
+
gtag("config", config.measurementId, config.config ?? {});
|
|
2349
2894
|
},
|
|
2350
2895
|
attrs: { async: "true" }
|
|
2351
2896
|
};
|
|
@@ -2357,13 +2902,19 @@ function createGoogleTagManagerIntegration(config) {
|
|
|
2357
2902
|
category: "analytics",
|
|
2358
2903
|
src,
|
|
2359
2904
|
cookies: ["_gcl_au"],
|
|
2905
|
+
bootstrap: () => {
|
|
2906
|
+
applyDefaultConsentMode(config.dataLayerName);
|
|
2907
|
+
},
|
|
2908
|
+
onConsentUpdate: ({ preferences }) => {
|
|
2909
|
+
applyConsentModeUpdate(preferences, config.dataLayerName);
|
|
2910
|
+
},
|
|
2360
2911
|
init: () => {
|
|
2361
|
-
if (
|
|
2912
|
+
if (globalThis.window !== void 0) {
|
|
2362
2913
|
const dataLayerName = config.dataLayerName || "dataLayer";
|
|
2363
2914
|
const w = window;
|
|
2364
2915
|
const layer = w[dataLayerName] ?? [];
|
|
2365
2916
|
w[dataLayerName] = layer;
|
|
2366
|
-
layer.push({ "gtm.start":
|
|
2917
|
+
layer.push({ "gtm.start": Date.now(), event: "gtm.js" });
|
|
2367
2918
|
}
|
|
2368
2919
|
}
|
|
2369
2920
|
};
|
|
@@ -2376,7 +2927,7 @@ function createUserWayIntegration(config) {
|
|
|
2376
2927
|
src,
|
|
2377
2928
|
cookies: ["_userway_*"],
|
|
2378
2929
|
init: () => {
|
|
2379
|
-
if (
|
|
2930
|
+
if (globalThis.window !== void 0) {
|
|
2380
2931
|
const w = window;
|
|
2381
2932
|
w.UserWayWidgetApp = w.UserWayWidgetApp || {};
|
|
2382
2933
|
w.UserWayWidgetApp.accountId = config.accountId;
|
|
@@ -2398,7 +2949,7 @@ function createFacebookPixelIntegration(config) {
|
|
|
2398
2949
|
src,
|
|
2399
2950
|
cookies: ["_fbp", "fr"],
|
|
2400
2951
|
init: () => {
|
|
2401
|
-
if (
|
|
2952
|
+
if (globalThis.window !== void 0) {
|
|
2402
2953
|
const w = window;
|
|
2403
2954
|
if (!w.fbq) {
|
|
2404
2955
|
const fbq = (...args) => {
|
|
@@ -2465,7 +3016,7 @@ function createHotjarIntegration(config) {
|
|
|
2465
3016
|
}
|
|
2466
3017
|
],
|
|
2467
3018
|
init: () => {
|
|
2468
|
-
if (
|
|
3019
|
+
if (globalThis.window !== void 0) {
|
|
2469
3020
|
const w = window;
|
|
2470
3021
|
w._hjSettings = { hjid: config.siteId, hjsv: v };
|
|
2471
3022
|
if (!w.hj) {
|
|
@@ -2498,7 +3049,7 @@ function createMixpanelIntegration(config) {
|
|
|
2498
3049
|
}
|
|
2499
3050
|
],
|
|
2500
3051
|
init: () => {
|
|
2501
|
-
if (
|
|
3052
|
+
if (globalThis.window !== void 0) {
|
|
2502
3053
|
const w = window;
|
|
2503
3054
|
w.mixpanel = w.mixpanel || { init: () => void 0 };
|
|
2504
3055
|
if (w.mixpanel && typeof w.mixpanel.init === "function") {
|
|
@@ -2522,7 +3073,7 @@ function createClarityIntegration(config) {
|
|
|
2522
3073
|
src,
|
|
2523
3074
|
cookies: ["_clck", "_clsk", "CLID", "ANONCHK", "MR", "MUID", "SM"],
|
|
2524
3075
|
init: () => {
|
|
2525
|
-
if (
|
|
3076
|
+
if (globalThis.window !== void 0 && typeof config.upload !== "undefined") {
|
|
2526
3077
|
const w = window;
|
|
2527
3078
|
if (typeof w.clarity === "function") {
|
|
2528
3079
|
try {
|
|
@@ -2545,7 +3096,7 @@ function createIntercomIntegration(config) {
|
|
|
2545
3096
|
src,
|
|
2546
3097
|
cookies: ["intercom-id-*", "intercom-session-*"],
|
|
2547
3098
|
init: () => {
|
|
2548
|
-
if (
|
|
3099
|
+
if (globalThis.window !== void 0) {
|
|
2549
3100
|
const w = window;
|
|
2550
3101
|
if (typeof w.Intercom === "function") {
|
|
2551
3102
|
try {
|
|
@@ -2568,7 +3119,7 @@ function createZendeskChatIntegration(config) {
|
|
|
2568
3119
|
src,
|
|
2569
3120
|
cookies: ["__zlcmid", "_zendesk_shared_session"],
|
|
2570
3121
|
init: () => {
|
|
2571
|
-
if (
|
|
3122
|
+
if (globalThis.window !== void 0) {
|
|
2572
3123
|
const w = window;
|
|
2573
3124
|
if (typeof w.zE === "function") {
|
|
2574
3125
|
try {
|
|
@@ -2632,6 +3183,68 @@ function suggestCategoryForScript(name) {
|
|
|
2632
3183
|
return ["analytics"];
|
|
2633
3184
|
}
|
|
2634
3185
|
|
|
3186
|
+
// src/utils/categoryPresets.ts
|
|
3187
|
+
var ANPD_CATEGORY_PRESETS = {
|
|
3188
|
+
necessary: {
|
|
3189
|
+
id: "necessary",
|
|
3190
|
+
name: "Necess\xE1rios",
|
|
3191
|
+
description: "Essenciais para funcionamento do site e seguran\xE7a. Sempre ativos.",
|
|
3192
|
+
essential: true,
|
|
3193
|
+
cookies: []
|
|
3194
|
+
},
|
|
3195
|
+
analytics: {
|
|
3196
|
+
id: "analytics",
|
|
3197
|
+
name: "Analytics",
|
|
3198
|
+
description: "Mede desempenho e uso para melhorar a experi\xEAncia.",
|
|
3199
|
+
essential: false,
|
|
3200
|
+
cookies: ["_ga", "_ga_*", "_gid"]
|
|
3201
|
+
},
|
|
3202
|
+
functional: {
|
|
3203
|
+
id: "functional",
|
|
3204
|
+
name: "Funcionais",
|
|
3205
|
+
description: "Habilitam recursos adicionais e prefer\xEAncias do usu\xE1rio.",
|
|
3206
|
+
essential: false,
|
|
3207
|
+
cookies: []
|
|
3208
|
+
},
|
|
3209
|
+
marketing: {
|
|
3210
|
+
id: "marketing",
|
|
3211
|
+
name: "Marketing",
|
|
3212
|
+
description: "Personaliza an\xFAncios e campanhas baseadas no seu perfil.",
|
|
3213
|
+
essential: false,
|
|
3214
|
+
cookies: ["_fbp", "fr"]
|
|
3215
|
+
},
|
|
3216
|
+
social: {
|
|
3217
|
+
id: "social",
|
|
3218
|
+
name: "Social",
|
|
3219
|
+
description: "Integra\xE7\xF5es sociais, compartilhamento e widgets de redes.",
|
|
3220
|
+
essential: false,
|
|
3221
|
+
cookies: []
|
|
3222
|
+
},
|
|
3223
|
+
personalization: {
|
|
3224
|
+
id: "personalization",
|
|
3225
|
+
name: "Personaliza\xE7\xE3o",
|
|
3226
|
+
description: "Personaliza conte\xFAdo e recomenda\xE7\xF5es.",
|
|
3227
|
+
essential: false,
|
|
3228
|
+
cookies: []
|
|
3229
|
+
}
|
|
3230
|
+
};
|
|
3231
|
+
function createAnpdCategoriesConfig(options = {}) {
|
|
3232
|
+
const include = options.include && options.include.length > 0 ? options.include : ["analytics", "functional", "marketing"];
|
|
3233
|
+
const enabledCategories = include.filter((cat) => cat !== "necessary");
|
|
3234
|
+
const customCategories = include.filter((cat) => cat === "necessary").map((cat) => {
|
|
3235
|
+
const base = ANPD_CATEGORY_PRESETS[cat];
|
|
3236
|
+
return {
|
|
3237
|
+
...base,
|
|
3238
|
+
name: options.names?.[cat] ?? base.name,
|
|
3239
|
+
description: options.descriptions?.[cat] ?? base.description
|
|
3240
|
+
};
|
|
3241
|
+
});
|
|
3242
|
+
return {
|
|
3243
|
+
enabledCategories,
|
|
3244
|
+
customCategories: customCategories.length ? customCategories : void 0
|
|
3245
|
+
};
|
|
3246
|
+
}
|
|
3247
|
+
|
|
2635
3248
|
// src/types/advancedTexts.ts
|
|
2636
3249
|
var EXPANDED_DEFAULT_TEXTS = {
|
|
2637
3250
|
// Textos adicionais
|
|
@@ -2843,4 +3456,4 @@ var TEXT_TEMPLATES = {
|
|
|
2843
3456
|
}
|
|
2844
3457
|
};
|
|
2845
3458
|
|
|
2846
|
-
export { COMMON_INTEGRATIONS, ConsentGate, ConsentProvider, ConsentScriptLoader, DEFAULT_PROJECT_CATEGORIES, DesignProvider, EXPANDED_DEFAULT_TEXTS, GUIDANCE_PRESETS, INTEGRATION_TEMPLATES, LogLevel, TEXT_TEMPLATES, analyzeDeveloperConfiguration, analyzeIntegrationCategories, autoConfigureCategories, buildConsentStorageKey, categorizeDiscoveredCookies, checkPeerDeps, createClarityIntegration, createCorporateIntegrations, createECommerceIntegrations, createFacebookPixelIntegration, createGoogleAnalyticsIntegration, createGoogleTagManagerIntegration, createHotjarIntegration, createIntercomIntegration, createMixpanelIntegration, createProjectPreferences, createSaaSIntegrations, createUserWayIntegration, createZendeskChatIntegration, defaultTexts, detectConsentCookieName, discoverRuntimeCookies, ensureNecessaryAlwaysOn, extractCategoriesFromIntegrations, getAllProjectCategories, getCookiesInfoForCategory, loadScript, logDeveloperGuidance, logger, openPreferencesModal, pushConsentInitializedEvent, pushConsentUpdatedEvent, resolveTexts, runPeerDepsCheck, setCookieCatalogOverrides, setCookieCategoryOverrides, setDebugLogging, suggestCategoryForScript, useCategories, useCategoryStatus, useConsent, useConsentHydration, useConsentScriptLoader, useConsentTexts, useDataLayerEvents, useDesignTokens, useDeveloperGuidance, useOpenPreferencesModal, validateIntegrationCategories, validateNecessaryClassification, validateProjectPreferences };
|
|
3459
|
+
export { ANPD_CATEGORY_PRESETS, COMMON_INTEGRATIONS, ConsentGate, ConsentProvider, ConsentScriptLoader, DEFAULT_PROJECT_CATEGORIES, DesignProvider, EXPANDED_DEFAULT_TEXTS, GUIDANCE_PRESETS, INTEGRATION_TEMPLATES, LogLevel, TEXT_TEMPLATES, analyzeDeveloperConfiguration, analyzeIntegrationCategories, autoConfigureCategories, buildConsentStorageKey, categorizeDiscoveredCookies, checkPeerDeps, createAnpdCategoriesConfig, createClarityIntegration, createConsentAuditEntry, createCorporateIntegrations, createECommerceIntegrations, createFacebookPixelIntegration, createGoogleAnalyticsIntegration, createGoogleTagManagerIntegration, createHotjarIntegration, createIntercomIntegration, createMixpanelIntegration, createProjectPreferences, createSaaSIntegrations, createUserWayIntegration, createZendeskChatIntegration, defaultTexts, detectConsentCookieName, discoverRuntimeCookies, ensureNecessaryAlwaysOn, extractCategoriesFromIntegrations, getAllProjectCategories, getCookiesInfoForCategory, getPeerDepsLocale, loadScript, logDeveloperGuidance, logger, openPreferencesModal, pushConsentInitializedEvent, pushConsentUpdatedEvent, registerScript, resetPeerDepsMessages, resolveTexts, runPeerDepsCheck, setCookieCatalogOverrides, setCookieCategoryOverrides, setDebugLogging, setPeerDepsLocale, setPeerDepsMessages, suggestCategoryForScript, useCategories, useCategoryStatus, useConsent, useConsentHydration, useConsentScriptLoader, useConsentTexts, useDataLayerEvents, useDesignTokens, useDeveloperGuidance, useOpenPreferencesModal, validateIntegrationCategories, validateNecessaryClassification, validateProjectPreferences };
|