@react-lgpd-consent/core 0.6.3 → 0.7.0
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 +141 -2
- package/README.md +46 -0
- package/dist/index.cjs +233 -60
- package/dist/index.d.cts +118 -5
- package/dist/index.d.ts +118 -5
- package/dist/index.js +231 -61
- package/package.json +2 -3
package/dist/index.cjs
CHANGED
|
@@ -336,15 +336,15 @@ var DEFAULT_STORAGE_VERSION = "1";
|
|
|
336
336
|
function buildConsentStorageKey(options) {
|
|
337
337
|
const namespaceRaw = options?.namespace?.trim() || DEFAULT_STORAGE_NAMESPACE;
|
|
338
338
|
const versionRaw = options?.version?.trim() || DEFAULT_STORAGE_VERSION;
|
|
339
|
-
const sanitizedNamespace = namespaceRaw.
|
|
340
|
-
const sanitizedVersion = versionRaw.
|
|
339
|
+
const sanitizedNamespace = namespaceRaw.replaceAll(/[^a-z0-9._-]+/gi, "-").toLowerCase();
|
|
340
|
+
const sanitizedVersion = versionRaw.replaceAll(/[^a-z0-9._-]+/gi, "-").toLowerCase();
|
|
341
341
|
return `${sanitizedNamespace}__v${sanitizedVersion}`;
|
|
342
342
|
}
|
|
343
343
|
var DEFAULT_COOKIE_OPTS = {
|
|
344
344
|
name: "cookieConsent",
|
|
345
345
|
maxAgeDays: 365,
|
|
346
346
|
sameSite: "Lax",
|
|
347
|
-
secure:
|
|
347
|
+
secure: globalThis.window === void 0 ? false : globalThis.window.location.protocol === "https:",
|
|
348
348
|
path: "/",
|
|
349
349
|
domain: void 0
|
|
350
350
|
};
|
|
@@ -424,6 +424,23 @@ function writeConsentCookie(state, config, opts, source = "banner") {
|
|
|
424
424
|
preferencesCount: Object.keys(cookieData.preferences).length
|
|
425
425
|
});
|
|
426
426
|
}
|
|
427
|
+
function createConsentAuditEntry(state, params) {
|
|
428
|
+
const preferences = ensureNecessaryAlwaysOn(state.preferences);
|
|
429
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
430
|
+
return {
|
|
431
|
+
action: params.action,
|
|
432
|
+
storageKey: params.storageKey,
|
|
433
|
+
consentVersion: params.consentVersion?.trim() || "1",
|
|
434
|
+
timestamp: now,
|
|
435
|
+
consentDate: state.consentDate,
|
|
436
|
+
lastUpdate: state.lastUpdate,
|
|
437
|
+
consented: state.consented,
|
|
438
|
+
preferences,
|
|
439
|
+
version: state.version,
|
|
440
|
+
source: params.origin ?? state.source,
|
|
441
|
+
projectConfig: state.projectConfig
|
|
442
|
+
};
|
|
443
|
+
}
|
|
427
444
|
function removeConsentCookie(opts) {
|
|
428
445
|
if (typeof document === "undefined") {
|
|
429
446
|
logger.debug("Cookie removal skipped: server-side environment");
|
|
@@ -436,15 +453,14 @@ function removeConsentCookie(opts) {
|
|
|
436
453
|
}
|
|
437
454
|
|
|
438
455
|
// src/utils/dataLayerEvents.ts
|
|
439
|
-
var LIBRARY_VERSION = "0.
|
|
456
|
+
var LIBRARY_VERSION = "0.7.0";
|
|
440
457
|
function ensureDataLayer() {
|
|
441
|
-
|
|
442
|
-
if (
|
|
443
|
-
|
|
444
|
-
}
|
|
458
|
+
var _a;
|
|
459
|
+
if (globalThis.window === void 0) return;
|
|
460
|
+
(_a = globalThis.window).dataLayer ?? (_a.dataLayer = []);
|
|
445
461
|
}
|
|
446
462
|
function pushConsentInitializedEvent(categories) {
|
|
447
|
-
if (
|
|
463
|
+
if (globalThis.window === void 0) return;
|
|
448
464
|
ensureDataLayer();
|
|
449
465
|
const event = {
|
|
450
466
|
event: "consent_initialized",
|
|
@@ -452,10 +468,10 @@ function pushConsentInitializedEvent(categories) {
|
|
|
452
468
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
453
469
|
categories
|
|
454
470
|
};
|
|
455
|
-
window.dataLayer?.push(event);
|
|
471
|
+
globalThis.window.dataLayer?.push(event);
|
|
456
472
|
}
|
|
457
473
|
function pushConsentUpdatedEvent(categories, origin, previousCategories) {
|
|
458
|
-
if (
|
|
474
|
+
if (globalThis.window === void 0) return;
|
|
459
475
|
ensureDataLayer();
|
|
460
476
|
const changedCategories = previousCategories ? Object.keys(categories).filter((key) => categories[key] !== previousCategories[key]) : [];
|
|
461
477
|
const event = {
|
|
@@ -466,7 +482,7 @@ function pushConsentUpdatedEvent(categories, origin, previousCategories) {
|
|
|
466
482
|
categories,
|
|
467
483
|
changed_categories: changedCategories
|
|
468
484
|
};
|
|
469
|
-
window.dataLayer?.push(event);
|
|
485
|
+
globalThis.window.dataLayer?.push(event);
|
|
470
486
|
}
|
|
471
487
|
function useDataLayerEvents() {
|
|
472
488
|
return {
|
|
@@ -655,10 +671,10 @@ var COOKIE_CATALOG_OVERRIDES = {};
|
|
|
655
671
|
var COOKIE_CATEGORY_OVERRIDES = {};
|
|
656
672
|
function setCookieCatalogOverrides(overrides) {
|
|
657
673
|
COOKIE_CATALOG_OVERRIDES = {
|
|
658
|
-
byCategory: { ...COOKIE_CATALOG_OVERRIDES.byCategory
|
|
674
|
+
byCategory: { ...COOKIE_CATALOG_OVERRIDES.byCategory, ...overrides.byCategory },
|
|
659
675
|
byIntegration: {
|
|
660
|
-
...COOKIE_CATALOG_OVERRIDES.byIntegration
|
|
661
|
-
...overrides.byIntegration
|
|
676
|
+
...COOKIE_CATALOG_OVERRIDES.byIntegration,
|
|
677
|
+
...overrides.byIntegration
|
|
662
678
|
}
|
|
663
679
|
};
|
|
664
680
|
}
|
|
@@ -680,7 +696,7 @@ function getCookiesInfoForCategory(categoryId, usedIntegrations) {
|
|
|
680
696
|
([pattern]) => matchPattern(desc.name, pattern)
|
|
681
697
|
)?.[1];
|
|
682
698
|
const finalCat = overrideCat ?? defaultCat;
|
|
683
|
-
if (finalCat === categoryId && !result.
|
|
699
|
+
if (finalCat === categoryId && !result.some((d) => d.name === desc.name)) result.push(desc);
|
|
684
700
|
});
|
|
685
701
|
});
|
|
686
702
|
const catOverride = COOKIE_CATALOG_OVERRIDES.byCategory?.[categoryId];
|
|
@@ -692,7 +708,7 @@ function getCookiesInfoForCategory(categoryId, usedIntegrations) {
|
|
|
692
708
|
});
|
|
693
709
|
}
|
|
694
710
|
if (categoryId === "necessary") {
|
|
695
|
-
if (!result.
|
|
711
|
+
if (!result.some((d) => d.name === "cookieConsent")) {
|
|
696
712
|
result.push({
|
|
697
713
|
name: "cookieConsent",
|
|
698
714
|
purpose: "Armazena suas prefer\xEAncias de consentimento",
|
|
@@ -1074,9 +1090,9 @@ var GUIDANCE_PRESETS = {
|
|
|
1074
1090
|
|
|
1075
1091
|
// src/utils/peerDepsCheck.ts
|
|
1076
1092
|
function detectMultipleReactInstances() {
|
|
1077
|
-
if (
|
|
1093
|
+
if (globalThis.window === void 0) return false;
|
|
1078
1094
|
try {
|
|
1079
|
-
const reactSymbols = Object.getOwnPropertySymbols(window).map(
|
|
1095
|
+
const reactSymbols = Object.getOwnPropertySymbols(globalThis.window).map(String).filter((name) => name.includes("react"));
|
|
1080
1096
|
if (reactSymbols.length > 1) {
|
|
1081
1097
|
return true;
|
|
1082
1098
|
}
|
|
@@ -1091,7 +1107,7 @@ function detectMultipleReactInstances() {
|
|
|
1091
1107
|
}
|
|
1092
1108
|
}
|
|
1093
1109
|
function getPackageVersion(packageName) {
|
|
1094
|
-
if (
|
|
1110
|
+
if (globalThis.window === void 0) return null;
|
|
1095
1111
|
try {
|
|
1096
1112
|
const pkg = window[packageName];
|
|
1097
1113
|
if (pkg?.version) return pkg.version;
|
|
@@ -1105,7 +1121,7 @@ function getPackageVersion(packageName) {
|
|
|
1105
1121
|
}
|
|
1106
1122
|
}
|
|
1107
1123
|
function isVersionInRange(version, minMajor, maxMajor) {
|
|
1108
|
-
const major = parseInt(version.split(".")[0], 10);
|
|
1124
|
+
const major = Number.parseInt(version.split(".")[0], 10);
|
|
1109
1125
|
return major >= minMajor && major <= maxMajor;
|
|
1110
1126
|
}
|
|
1111
1127
|
function checkPeerDeps(options = {}) {
|
|
@@ -1119,7 +1135,7 @@ function checkPeerDeps(options = {}) {
|
|
|
1119
1135
|
if (skipInProduction && isProduction) {
|
|
1120
1136
|
return result;
|
|
1121
1137
|
}
|
|
1122
|
-
if (
|
|
1138
|
+
if (globalThis.window === void 0) {
|
|
1123
1139
|
return result;
|
|
1124
1140
|
}
|
|
1125
1141
|
if (detectMultipleReactInstances()) {
|
|
@@ -1281,7 +1297,7 @@ function validateConsentProviderProps(props) {
|
|
|
1281
1297
|
const sanitized = {};
|
|
1282
1298
|
if (!isDev()) {
|
|
1283
1299
|
if (props.categories) {
|
|
1284
|
-
const enabled =
|
|
1300
|
+
const enabled = [...new Set(props.categories.enabledCategories ?? [])];
|
|
1285
1301
|
const sanitizedEnabled = enabled.filter((c) => c !== "necessary");
|
|
1286
1302
|
sanitized.categories = {
|
|
1287
1303
|
enabledCategories: sanitizedEnabled,
|
|
@@ -1318,11 +1334,11 @@ function validateConsentProviderProps(props) {
|
|
|
1318
1334
|
}
|
|
1319
1335
|
if (!props.categories) {
|
|
1320
1336
|
warnings.push(
|
|
1321
|
-
"Prop 'categories' n\xE3o fornecida
|
|
1337
|
+
"Prop 'categories' n\xE3o fornecida \u2014 o ConsentProvider requer configura\xE7\xE3o de categorias."
|
|
1322
1338
|
);
|
|
1323
1339
|
} else {
|
|
1324
1340
|
const cat = props.categories;
|
|
1325
|
-
const enabled =
|
|
1341
|
+
const enabled = [...new Set(cat.enabledCategories ?? [])];
|
|
1326
1342
|
if (enabled.includes("necessary")) {
|
|
1327
1343
|
warnings.push("'necessary' \xE9 sempre inclu\xEDda automaticamente \u2014 remova de enabledCategories.");
|
|
1328
1344
|
}
|
|
@@ -1330,7 +1346,7 @@ function validateConsentProviderProps(props) {
|
|
|
1330
1346
|
const invalidEnabled = sanitizedEnabled.filter((c) => typeof c !== "string" || c.trim() === "");
|
|
1331
1347
|
if (invalidEnabled.length > 0) {
|
|
1332
1348
|
warnings.push(
|
|
1333
|
-
`enabledCategories cont\xE9m valores inv\xE1lidos: ${invalidEnabled.map(
|
|
1349
|
+
`enabledCategories cont\xE9m valores inv\xE1lidos: ${invalidEnabled.map(String).join(", ")} \u2014 remova ou corrija os IDs de categoria`
|
|
1334
1350
|
);
|
|
1335
1351
|
}
|
|
1336
1352
|
const custom = cat.customCategories ?? [];
|
|
@@ -1424,13 +1440,13 @@ function detectConsentCookieName() {
|
|
|
1424
1440
|
}
|
|
1425
1441
|
return null;
|
|
1426
1442
|
}
|
|
1443
|
+
function matchPattern2(name, pattern) {
|
|
1444
|
+
if (pattern.endsWith("*")) return name.startsWith(pattern.slice(0, -1));
|
|
1445
|
+
return name === pattern;
|
|
1446
|
+
}
|
|
1427
1447
|
function categorizeDiscoveredCookies(discovered, registerOverrides = false) {
|
|
1428
1448
|
const list = discovered || globalThis.__LGPD_DISCOVERED_COOKIES__ || [];
|
|
1429
1449
|
const out = {};
|
|
1430
|
-
function matchPattern2(name, pattern) {
|
|
1431
|
-
if (pattern.endsWith("*")) return name.startsWith(pattern.slice(0, -1));
|
|
1432
|
-
return name === pattern;
|
|
1433
|
-
}
|
|
1434
1450
|
list.filter((d) => d.name && d.name !== "cookieConsent").forEach((d) => {
|
|
1435
1451
|
let assigned = null;
|
|
1436
1452
|
Object.keys(COOKIE_PATTERNS_BY_CATEGORY).forEach((cat2) => {
|
|
@@ -1438,9 +1454,9 @@ function categorizeDiscoveredCookies(discovered, registerOverrides = false) {
|
|
|
1438
1454
|
const patterns = COOKIE_PATTERNS_BY_CATEGORY[cat2] || [];
|
|
1439
1455
|
if (patterns.some((p) => matchPattern2(d.name, p))) assigned = cat2;
|
|
1440
1456
|
});
|
|
1441
|
-
const cat = assigned
|
|
1457
|
+
const cat = assigned ?? "analytics";
|
|
1442
1458
|
out[cat] = out[cat] || [];
|
|
1443
|
-
if (!out[cat].
|
|
1459
|
+
if (!out[cat].some((x) => x.name === d.name)) out[cat].push(d);
|
|
1444
1460
|
});
|
|
1445
1461
|
if (registerOverrides) {
|
|
1446
1462
|
const byCategory = {};
|
|
@@ -1517,7 +1533,7 @@ function useCategories() {
|
|
|
1517
1533
|
const context = React4__namespace.useContext(CategoriesContext);
|
|
1518
1534
|
if (!context) {
|
|
1519
1535
|
throw new Error(
|
|
1520
|
-
"useCategories deve ser usado dentro de
|
|
1536
|
+
"[react-lgpd-consent] useCategories deve ser usado dentro de <ConsentProvider>. Adicione o provider ao redor da sua \xE1rvore antes de chamar o hook."
|
|
1521
1537
|
);
|
|
1522
1538
|
}
|
|
1523
1539
|
return context;
|
|
@@ -1668,6 +1684,11 @@ var StateCtx = React4__namespace.createContext(null);
|
|
|
1668
1684
|
var ActionsCtx = React4__namespace.createContext(null);
|
|
1669
1685
|
var TextsCtx = React4__namespace.createContext(DEFAULT_TEXTS);
|
|
1670
1686
|
var HydrationCtx = React4__namespace.createContext(false);
|
|
1687
|
+
function buildProviderError(hookName) {
|
|
1688
|
+
return new Error(
|
|
1689
|
+
`[react-lgpd-consent] ${hookName} deve ser usado dentro de <ConsentProvider>. Envolva seu componente com o provider ou use o wrapper @react-lgpd-consent/mui.`
|
|
1690
|
+
);
|
|
1691
|
+
}
|
|
1671
1692
|
function ConsentProvider({
|
|
1672
1693
|
initialState,
|
|
1673
1694
|
categories,
|
|
@@ -1691,7 +1712,10 @@ function ConsentProvider({
|
|
|
1691
1712
|
disableDeveloperGuidance,
|
|
1692
1713
|
guidanceConfig,
|
|
1693
1714
|
children,
|
|
1694
|
-
disableDiscoveryLog
|
|
1715
|
+
disableDiscoveryLog,
|
|
1716
|
+
onConsentInit,
|
|
1717
|
+
onConsentChange,
|
|
1718
|
+
onAuditLog
|
|
1695
1719
|
}) {
|
|
1696
1720
|
const texts = React4__namespace.useMemo(() => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }), [textsProp]);
|
|
1697
1721
|
const cookie = React4__namespace.useMemo(() => {
|
|
@@ -1705,6 +1729,7 @@ function ConsentProvider({
|
|
|
1705
1729
|
}
|
|
1706
1730
|
return base;
|
|
1707
1731
|
}, [cookieOpts, storage?.domain, storage?.namespace, storage?.version]);
|
|
1732
|
+
const consentVersion = storage?.version?.trim() || "1";
|
|
1708
1733
|
const finalCategoriesConfig = React4__namespace.useMemo(() => {
|
|
1709
1734
|
const isProd = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
1710
1735
|
if (!categories) return DEFAULT_PROJECT_CATEGORIES;
|
|
@@ -1751,6 +1776,8 @@ function ConsentProvider({
|
|
|
1751
1776
|
const skipCookiePersistRef = React4__namespace.useRef(false);
|
|
1752
1777
|
const [isHydrated, setIsHydrated] = React4__namespace.useState(false);
|
|
1753
1778
|
const previousPreferencesRef = React4__namespace.useRef(state.preferences);
|
|
1779
|
+
const auditInitEmittedRef = React4__namespace.useRef(false);
|
|
1780
|
+
const previousConsentedAuditRef = React4__namespace.useRef(state.consented);
|
|
1754
1781
|
React4__namespace.useEffect(() => {
|
|
1755
1782
|
if (!initialState) {
|
|
1756
1783
|
const saved = readConsentCookie(cookie.name);
|
|
@@ -1799,13 +1826,44 @@ function ConsentProvider({
|
|
|
1799
1826
|
logger.info("DataLayer: consent_initialized event dispatched", {
|
|
1800
1827
|
preferences: state.preferences
|
|
1801
1828
|
});
|
|
1829
|
+
if (onConsentInit) onConsentInit(state);
|
|
1802
1830
|
}
|
|
1803
1831
|
}, [isHydrated]);
|
|
1832
|
+
React4__namespace.useEffect(() => {
|
|
1833
|
+
if (!isHydrated) return;
|
|
1834
|
+
if (!onAuditLog) return;
|
|
1835
|
+
if (auditInitEmittedRef.current) return;
|
|
1836
|
+
onAuditLog(
|
|
1837
|
+
createConsentAuditEntry(state, {
|
|
1838
|
+
action: "init",
|
|
1839
|
+
storageKey: cookie.name,
|
|
1840
|
+
consentVersion
|
|
1841
|
+
})
|
|
1842
|
+
);
|
|
1843
|
+
auditInitEmittedRef.current = true;
|
|
1844
|
+
}, [isHydrated, onAuditLog, state, cookie.name, consentVersion]);
|
|
1804
1845
|
React4__namespace.useEffect(() => {
|
|
1805
1846
|
if (!state.consented) return;
|
|
1806
1847
|
if (skipCookiePersistRef.current) return;
|
|
1807
1848
|
writeConsentCookie(state, finalCategoriesConfig, cookie);
|
|
1808
1849
|
}, [state, cookie, finalCategoriesConfig]);
|
|
1850
|
+
React4__namespace.useEffect(() => {
|
|
1851
|
+
if (!onAuditLog) {
|
|
1852
|
+
previousConsentedAuditRef.current = state.consented;
|
|
1853
|
+
return;
|
|
1854
|
+
}
|
|
1855
|
+
if (previousConsentedAuditRef.current && !state.consented) {
|
|
1856
|
+
onAuditLog(
|
|
1857
|
+
createConsentAuditEntry(state, {
|
|
1858
|
+
action: "reset",
|
|
1859
|
+
storageKey: cookie.name,
|
|
1860
|
+
consentVersion,
|
|
1861
|
+
origin: "reset"
|
|
1862
|
+
})
|
|
1863
|
+
);
|
|
1864
|
+
}
|
|
1865
|
+
previousConsentedAuditRef.current = state.consented;
|
|
1866
|
+
}, [state, onAuditLog, cookie.name, consentVersion]);
|
|
1809
1867
|
const prevConsented = React4__namespace.useRef(state.consented);
|
|
1810
1868
|
React4__namespace.useEffect(() => {
|
|
1811
1869
|
if (!prevConsented.current && state.consented && onConsentGiven) {
|
|
@@ -1826,9 +1884,32 @@ function ConsentProvider({
|
|
|
1826
1884
|
preferences: state.preferences,
|
|
1827
1885
|
consented: state.consented
|
|
1828
1886
|
});
|
|
1887
|
+
if (onConsentChange) {
|
|
1888
|
+
onConsentChange(state, { origin });
|
|
1889
|
+
}
|
|
1890
|
+
if (onAuditLog) {
|
|
1891
|
+
onAuditLog(
|
|
1892
|
+
createConsentAuditEntry(state, {
|
|
1893
|
+
action: "update",
|
|
1894
|
+
storageKey: cookie.name,
|
|
1895
|
+
consentVersion,
|
|
1896
|
+
origin
|
|
1897
|
+
})
|
|
1898
|
+
);
|
|
1899
|
+
}
|
|
1829
1900
|
previousPreferencesRef.current = state.preferences;
|
|
1830
1901
|
}
|
|
1831
|
-
}, [
|
|
1902
|
+
}, [
|
|
1903
|
+
state,
|
|
1904
|
+
state.preferences,
|
|
1905
|
+
state.consented,
|
|
1906
|
+
state.source,
|
|
1907
|
+
isHydrated,
|
|
1908
|
+
onConsentChange,
|
|
1909
|
+
onAuditLog,
|
|
1910
|
+
cookie.name,
|
|
1911
|
+
consentVersion
|
|
1912
|
+
]);
|
|
1832
1913
|
const api = React4__namespace.useMemo(() => {
|
|
1833
1914
|
const acceptAll = () => dispatch({ type: "ACCEPT_ALL", config: finalCategoriesConfig });
|
|
1834
1915
|
const rejectAll = () => dispatch({ type: "REJECT_ALL", config: finalCategoriesConfig });
|
|
@@ -1879,6 +1960,14 @@ function ConsentProvider({
|
|
|
1879
1960
|
if (typeof backdrop === "string") return backdrop;
|
|
1880
1961
|
return "rgba(0, 0, 0, 0.4)";
|
|
1881
1962
|
}, [designTokens]);
|
|
1963
|
+
const cookieBannerPropsWithDefaults = React4__namespace.useMemo(() => {
|
|
1964
|
+
const incoming = cookieBannerProps ?? {};
|
|
1965
|
+
return {
|
|
1966
|
+
...incoming,
|
|
1967
|
+
blocking: incoming.blocking === void 0 ? blocking : Boolean(incoming.blocking),
|
|
1968
|
+
hideBranding: incoming.hideBranding === void 0 ? _hideBranding : Boolean(incoming.hideBranding)
|
|
1969
|
+
};
|
|
1970
|
+
}, [cookieBannerProps, blocking, _hideBranding]);
|
|
1882
1971
|
const content = /* @__PURE__ */ jsxRuntime.jsx(StateCtx.Provider, { value: state, children: /* @__PURE__ */ jsxRuntime.jsx(ActionsCtx.Provider, { value: api, children: /* @__PURE__ */ jsxRuntime.jsx(TextsCtx.Provider, { value: texts, children: /* @__PURE__ */ jsxRuntime.jsx(HydrationCtx.Provider, { value: isHydrated, children: /* @__PURE__ */ jsxRuntime.jsx(DesignProvider, { tokens: designTokens, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1883
1972
|
CategoriesProvider,
|
|
1884
1973
|
{
|
|
@@ -1899,7 +1988,7 @@ function ConsentProvider({
|
|
|
1899
1988
|
}
|
|
1900
1989
|
) : (
|
|
1901
1990
|
// Aviso de desenvolvimento: usuário pode estar esquecendo de fornecer componentes UI
|
|
1902
|
-
process.env.NODE_ENV === "development" &&
|
|
1991
|
+
process.env.NODE_ENV === "development" && globalThis.window !== void 0 && !didWarnAboutMissingUI.current && !CookieBannerComponent && !FloatingPreferencesButtonComponent && (() => {
|
|
1903
1992
|
didWarnAboutMissingUI.current = true;
|
|
1904
1993
|
console.warn(
|
|
1905
1994
|
"%c[@react-lgpd-consent/core] Aviso: Nenhum componente UI fornecido",
|
|
@@ -1961,8 +2050,7 @@ function ConsentProvider({
|
|
|
1961
2050
|
rejectAll: api.rejectAll,
|
|
1962
2051
|
openPreferences: api.openPreferences,
|
|
1963
2052
|
texts,
|
|
1964
|
-
|
|
1965
|
-
...cookieBannerProps
|
|
2053
|
+
...cookieBannerPropsWithDefaults
|
|
1966
2054
|
}
|
|
1967
2055
|
),
|
|
1968
2056
|
state.consented && !disableFloatingPreferencesButton && FloatingPreferencesButtonComponent && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1980,12 +2068,12 @@ function ConsentProvider({
|
|
|
1980
2068
|
}
|
|
1981
2069
|
function useConsentStateInternal() {
|
|
1982
2070
|
const ctx = React4__namespace.useContext(StateCtx);
|
|
1983
|
-
if (!ctx) throw
|
|
2071
|
+
if (!ctx) throw buildProviderError("useConsentState");
|
|
1984
2072
|
return ctx;
|
|
1985
2073
|
}
|
|
1986
2074
|
function useConsentActionsInternal() {
|
|
1987
2075
|
const ctx = React4__namespace.useContext(ActionsCtx);
|
|
1988
|
-
if (!ctx) throw
|
|
2076
|
+
if (!ctx) throw buildProviderError("useConsentActions");
|
|
1989
2077
|
return ctx;
|
|
1990
2078
|
}
|
|
1991
2079
|
function useConsentTextsInternal() {
|
|
@@ -2004,7 +2092,7 @@ function ConsentGate(props) {
|
|
|
2004
2092
|
|
|
2005
2093
|
// src/utils/scriptLoader.ts
|
|
2006
2094
|
var LOADING_SCRIPTS = /* @__PURE__ */ new Map();
|
|
2007
|
-
function loadScript(id, src, category = null, attrs = {}) {
|
|
2095
|
+
function loadScript(id, src, category = null, attrs = {}, nonce) {
|
|
2008
2096
|
if (typeof document === "undefined") return Promise.resolve();
|
|
2009
2097
|
if (document.getElementById(id)) return Promise.resolve();
|
|
2010
2098
|
const existingPromise = LOADING_SCRIPTS.get(id);
|
|
@@ -2030,7 +2118,13 @@ function loadScript(id, src, category = null, attrs = {}) {
|
|
|
2030
2118
|
s.id = id;
|
|
2031
2119
|
s.src = src;
|
|
2032
2120
|
s.async = true;
|
|
2033
|
-
|
|
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);
|
|
2034
2128
|
s.onload = () => {
|
|
2035
2129
|
LOADING_SCRIPTS.delete(id);
|
|
2036
2130
|
resolve();
|
|
@@ -2208,7 +2302,8 @@ function validateNecessaryClassification(integrations, enabledCategories) {
|
|
|
2208
2302
|
// src/utils/ConsentScriptLoader.tsx
|
|
2209
2303
|
function ConsentScriptLoader({
|
|
2210
2304
|
integrations,
|
|
2211
|
-
reloadOnChange = false
|
|
2305
|
+
reloadOnChange = false,
|
|
2306
|
+
nonce
|
|
2212
2307
|
}) {
|
|
2213
2308
|
const { preferences, consented } = useConsent();
|
|
2214
2309
|
const categories = useCategories();
|
|
@@ -2241,8 +2336,8 @@ function ConsentScriptLoader({
|
|
|
2241
2336
|
const current = Array.isArray(gt.__LGPD_REQUIRED_CATEGORIES__) ? gt.__LGPD_REQUIRED_CATEGORIES__ : [];
|
|
2242
2337
|
const merged = Array.from(/* @__PURE__ */ new Set([...current, ...required]));
|
|
2243
2338
|
gt.__LGPD_REQUIRED_CATEGORIES__ = merged;
|
|
2244
|
-
if (
|
|
2245
|
-
window.dispatchEvent(new CustomEvent("lgpd:requiredCategories"));
|
|
2339
|
+
if (globalThis.window !== void 0 && typeof globalThis.window.dispatchEvent === "function") {
|
|
2340
|
+
globalThis.window.dispatchEvent(new CustomEvent("lgpd:requiredCategories"));
|
|
2246
2341
|
}
|
|
2247
2342
|
} catch {
|
|
2248
2343
|
}
|
|
@@ -2250,7 +2345,7 @@ function ConsentScriptLoader({
|
|
|
2250
2345
|
React4__namespace.useEffect(() => {
|
|
2251
2346
|
const isDev2 = process.env.NODE_ENV !== "production";
|
|
2252
2347
|
if (!isDev2 || integrations.length === 0) return;
|
|
2253
|
-
const enabledCategories = categories.
|
|
2348
|
+
const enabledCategories = categories.config.enabledCategories ?? [];
|
|
2254
2349
|
const isValid = validateIntegrationCategories(integrations, enabledCategories);
|
|
2255
2350
|
if (!isValid) {
|
|
2256
2351
|
autoConfigureCategories({ enabledCategories }, integrations, {
|
|
@@ -2281,11 +2376,15 @@ function ConsentScriptLoader({
|
|
|
2281
2376
|
const alreadyLoaded = loadedScripts.current.has(integration.id);
|
|
2282
2377
|
if (shouldLoad && (!alreadyLoaded || reloadOnChange)) {
|
|
2283
2378
|
try {
|
|
2379
|
+
const mergedAttrs = integration.attrs ?? {};
|
|
2380
|
+
const scriptNonce = integration.nonce ?? nonce;
|
|
2381
|
+
if (scriptNonce && !mergedAttrs.nonce) mergedAttrs.nonce = scriptNonce;
|
|
2284
2382
|
await loadScript(
|
|
2285
2383
|
integration.id,
|
|
2286
2384
|
integration.src,
|
|
2287
2385
|
integration.category,
|
|
2288
|
-
|
|
2386
|
+
mergedAttrs,
|
|
2387
|
+
scriptNonce
|
|
2289
2388
|
);
|
|
2290
2389
|
if (integration.init) {
|
|
2291
2390
|
integration.init();
|
|
@@ -2298,13 +2397,13 @@ function ConsentScriptLoader({
|
|
|
2298
2397
|
}
|
|
2299
2398
|
}, 0);
|
|
2300
2399
|
return () => clearTimeout(timeoutId);
|
|
2301
|
-
}, [preferences, consented, integrations, reloadOnChange]);
|
|
2400
|
+
}, [preferences, consented, integrations, reloadOnChange, nonce]);
|
|
2302
2401
|
return null;
|
|
2303
2402
|
}
|
|
2304
2403
|
function useConsentScriptLoader() {
|
|
2305
2404
|
const { preferences, consented } = useConsent();
|
|
2306
2405
|
return React4__namespace.useCallback(
|
|
2307
|
-
async (integration) => {
|
|
2406
|
+
async (integration, nonce) => {
|
|
2308
2407
|
if (!consented) {
|
|
2309
2408
|
logger.warn(`\u26A0\uFE0F Cannot load script ${integration.id}: No consent given`);
|
|
2310
2409
|
return false;
|
|
@@ -2317,7 +2416,16 @@ function useConsentScriptLoader() {
|
|
|
2317
2416
|
return false;
|
|
2318
2417
|
}
|
|
2319
2418
|
try {
|
|
2320
|
-
|
|
2419
|
+
const mergedAttrs = integration.attrs ? { ...integration.attrs } : {};
|
|
2420
|
+
const scriptNonce = integration.nonce ?? nonce;
|
|
2421
|
+
if (scriptNonce && !mergedAttrs.nonce) mergedAttrs.nonce = scriptNonce;
|
|
2422
|
+
await loadScript(
|
|
2423
|
+
integration.id,
|
|
2424
|
+
integration.src,
|
|
2425
|
+
integration.category,
|
|
2426
|
+
mergedAttrs,
|
|
2427
|
+
scriptNonce
|
|
2428
|
+
);
|
|
2321
2429
|
if (integration.init) {
|
|
2322
2430
|
integration.init();
|
|
2323
2431
|
}
|
|
@@ -2360,7 +2468,7 @@ function createGoogleAnalyticsIntegration(config) {
|
|
|
2360
2468
|
}
|
|
2361
2469
|
],
|
|
2362
2470
|
init: () => {
|
|
2363
|
-
if (
|
|
2471
|
+
if (globalThis.window !== void 0) {
|
|
2364
2472
|
const w = window;
|
|
2365
2473
|
w.dataLayer = w.dataLayer ?? [];
|
|
2366
2474
|
const gtag = (...args) => {
|
|
@@ -2382,12 +2490,12 @@ function createGoogleTagManagerIntegration(config) {
|
|
|
2382
2490
|
src,
|
|
2383
2491
|
cookies: ["_gcl_au"],
|
|
2384
2492
|
init: () => {
|
|
2385
|
-
if (
|
|
2493
|
+
if (globalThis.window !== void 0) {
|
|
2386
2494
|
const dataLayerName = config.dataLayerName || "dataLayer";
|
|
2387
2495
|
const w = window;
|
|
2388
2496
|
const layer = w[dataLayerName] ?? [];
|
|
2389
2497
|
w[dataLayerName] = layer;
|
|
2390
|
-
layer.push({ "gtm.start":
|
|
2498
|
+
layer.push({ "gtm.start": Date.now(), event: "gtm.js" });
|
|
2391
2499
|
}
|
|
2392
2500
|
}
|
|
2393
2501
|
};
|
|
@@ -2400,7 +2508,7 @@ function createUserWayIntegration(config) {
|
|
|
2400
2508
|
src,
|
|
2401
2509
|
cookies: ["_userway_*"],
|
|
2402
2510
|
init: () => {
|
|
2403
|
-
if (
|
|
2511
|
+
if (globalThis.window !== void 0) {
|
|
2404
2512
|
const w = window;
|
|
2405
2513
|
w.UserWayWidgetApp = w.UserWayWidgetApp || {};
|
|
2406
2514
|
w.UserWayWidgetApp.accountId = config.accountId;
|
|
@@ -2422,7 +2530,7 @@ function createFacebookPixelIntegration(config) {
|
|
|
2422
2530
|
src,
|
|
2423
2531
|
cookies: ["_fbp", "fr"],
|
|
2424
2532
|
init: () => {
|
|
2425
|
-
if (
|
|
2533
|
+
if (globalThis.window !== void 0) {
|
|
2426
2534
|
const w = window;
|
|
2427
2535
|
if (!w.fbq) {
|
|
2428
2536
|
const fbq = (...args) => {
|
|
@@ -2489,7 +2597,7 @@ function createHotjarIntegration(config) {
|
|
|
2489
2597
|
}
|
|
2490
2598
|
],
|
|
2491
2599
|
init: () => {
|
|
2492
|
-
if (
|
|
2600
|
+
if (globalThis.window !== void 0) {
|
|
2493
2601
|
const w = window;
|
|
2494
2602
|
w._hjSettings = { hjid: config.siteId, hjsv: v };
|
|
2495
2603
|
if (!w.hj) {
|
|
@@ -2522,7 +2630,7 @@ function createMixpanelIntegration(config) {
|
|
|
2522
2630
|
}
|
|
2523
2631
|
],
|
|
2524
2632
|
init: () => {
|
|
2525
|
-
if (
|
|
2633
|
+
if (globalThis.window !== void 0) {
|
|
2526
2634
|
const w = window;
|
|
2527
2635
|
w.mixpanel = w.mixpanel || { init: () => void 0 };
|
|
2528
2636
|
if (w.mixpanel && typeof w.mixpanel.init === "function") {
|
|
@@ -2546,7 +2654,7 @@ function createClarityIntegration(config) {
|
|
|
2546
2654
|
src,
|
|
2547
2655
|
cookies: ["_clck", "_clsk", "CLID", "ANONCHK", "MR", "MUID", "SM"],
|
|
2548
2656
|
init: () => {
|
|
2549
|
-
if (
|
|
2657
|
+
if (globalThis.window !== void 0 && typeof config.upload !== "undefined") {
|
|
2550
2658
|
const w = window;
|
|
2551
2659
|
if (typeof w.clarity === "function") {
|
|
2552
2660
|
try {
|
|
@@ -2569,7 +2677,7 @@ function createIntercomIntegration(config) {
|
|
|
2569
2677
|
src,
|
|
2570
2678
|
cookies: ["intercom-id-*", "intercom-session-*"],
|
|
2571
2679
|
init: () => {
|
|
2572
|
-
if (
|
|
2680
|
+
if (globalThis.window !== void 0) {
|
|
2573
2681
|
const w = window;
|
|
2574
2682
|
if (typeof w.Intercom === "function") {
|
|
2575
2683
|
try {
|
|
@@ -2592,7 +2700,7 @@ function createZendeskChatIntegration(config) {
|
|
|
2592
2700
|
src,
|
|
2593
2701
|
cookies: ["__zlcmid", "_zendesk_shared_session"],
|
|
2594
2702
|
init: () => {
|
|
2595
|
-
if (
|
|
2703
|
+
if (globalThis.window !== void 0) {
|
|
2596
2704
|
const w = window;
|
|
2597
2705
|
if (typeof w.zE === "function") {
|
|
2598
2706
|
try {
|
|
@@ -2656,6 +2764,68 @@ function suggestCategoryForScript(name) {
|
|
|
2656
2764
|
return ["analytics"];
|
|
2657
2765
|
}
|
|
2658
2766
|
|
|
2767
|
+
// src/utils/categoryPresets.ts
|
|
2768
|
+
var ANPD_CATEGORY_PRESETS = {
|
|
2769
|
+
necessary: {
|
|
2770
|
+
id: "necessary",
|
|
2771
|
+
name: "Necess\xE1rios",
|
|
2772
|
+
description: "Essenciais para funcionamento do site e seguran\xE7a. Sempre ativos.",
|
|
2773
|
+
essential: true,
|
|
2774
|
+
cookies: []
|
|
2775
|
+
},
|
|
2776
|
+
analytics: {
|
|
2777
|
+
id: "analytics",
|
|
2778
|
+
name: "Analytics",
|
|
2779
|
+
description: "Mede desempenho e uso para melhorar a experi\xEAncia.",
|
|
2780
|
+
essential: false,
|
|
2781
|
+
cookies: ["_ga", "_ga_*", "_gid"]
|
|
2782
|
+
},
|
|
2783
|
+
functional: {
|
|
2784
|
+
id: "functional",
|
|
2785
|
+
name: "Funcionais",
|
|
2786
|
+
description: "Habilitam recursos adicionais e prefer\xEAncias do usu\xE1rio.",
|
|
2787
|
+
essential: false,
|
|
2788
|
+
cookies: []
|
|
2789
|
+
},
|
|
2790
|
+
marketing: {
|
|
2791
|
+
id: "marketing",
|
|
2792
|
+
name: "Marketing",
|
|
2793
|
+
description: "Personaliza an\xFAncios e campanhas baseadas no seu perfil.",
|
|
2794
|
+
essential: false,
|
|
2795
|
+
cookies: ["_fbp", "fr"]
|
|
2796
|
+
},
|
|
2797
|
+
social: {
|
|
2798
|
+
id: "social",
|
|
2799
|
+
name: "Social",
|
|
2800
|
+
description: "Integra\xE7\xF5es sociais, compartilhamento e widgets de redes.",
|
|
2801
|
+
essential: false,
|
|
2802
|
+
cookies: []
|
|
2803
|
+
},
|
|
2804
|
+
personalization: {
|
|
2805
|
+
id: "personalization",
|
|
2806
|
+
name: "Personaliza\xE7\xE3o",
|
|
2807
|
+
description: "Personaliza conte\xFAdo e recomenda\xE7\xF5es.",
|
|
2808
|
+
essential: false,
|
|
2809
|
+
cookies: []
|
|
2810
|
+
}
|
|
2811
|
+
};
|
|
2812
|
+
function createAnpdCategoriesConfig(options = {}) {
|
|
2813
|
+
const include = options.include && options.include.length > 0 ? options.include : ["analytics", "functional", "marketing"];
|
|
2814
|
+
const enabledCategories = include.filter((cat) => cat !== "necessary");
|
|
2815
|
+
const customCategories = include.filter((cat) => cat === "necessary").map((cat) => {
|
|
2816
|
+
const base = ANPD_CATEGORY_PRESETS[cat];
|
|
2817
|
+
return {
|
|
2818
|
+
...base,
|
|
2819
|
+
name: options.names?.[cat] ?? base.name,
|
|
2820
|
+
description: options.descriptions?.[cat] ?? base.description
|
|
2821
|
+
};
|
|
2822
|
+
});
|
|
2823
|
+
return {
|
|
2824
|
+
enabledCategories,
|
|
2825
|
+
customCategories: customCategories.length ? customCategories : void 0
|
|
2826
|
+
};
|
|
2827
|
+
}
|
|
2828
|
+
|
|
2659
2829
|
// src/types/advancedTexts.ts
|
|
2660
2830
|
var EXPANDED_DEFAULT_TEXTS = {
|
|
2661
2831
|
// Textos adicionais
|
|
@@ -2867,6 +3037,7 @@ var TEXT_TEMPLATES = {
|
|
|
2867
3037
|
}
|
|
2868
3038
|
};
|
|
2869
3039
|
|
|
3040
|
+
exports.ANPD_CATEGORY_PRESETS = ANPD_CATEGORY_PRESETS;
|
|
2870
3041
|
exports.COMMON_INTEGRATIONS = COMMON_INTEGRATIONS;
|
|
2871
3042
|
exports.ConsentGate = ConsentGate;
|
|
2872
3043
|
exports.ConsentProvider = ConsentProvider;
|
|
@@ -2884,7 +3055,9 @@ exports.autoConfigureCategories = autoConfigureCategories;
|
|
|
2884
3055
|
exports.buildConsentStorageKey = buildConsentStorageKey;
|
|
2885
3056
|
exports.categorizeDiscoveredCookies = categorizeDiscoveredCookies;
|
|
2886
3057
|
exports.checkPeerDeps = checkPeerDeps;
|
|
3058
|
+
exports.createAnpdCategoriesConfig = createAnpdCategoriesConfig;
|
|
2887
3059
|
exports.createClarityIntegration = createClarityIntegration;
|
|
3060
|
+
exports.createConsentAuditEntry = createConsentAuditEntry;
|
|
2888
3061
|
exports.createCorporateIntegrations = createCorporateIntegrations;
|
|
2889
3062
|
exports.createECommerceIntegrations = createECommerceIntegrations;
|
|
2890
3063
|
exports.createFacebookPixelIntegration = createFacebookPixelIntegration;
|