@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/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.replace(/[^a-z0-9._-]+/gi, "-").toLowerCase();
340
- const sanitizedVersion = versionRaw.replace(/[^a-z0-9._-]+/gi, "-").toLowerCase();
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: typeof window !== "undefined" ? window.location.protocol === "https:" : false,
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.6.3";
456
+ var LIBRARY_VERSION = "0.7.0";
440
457
  function ensureDataLayer() {
441
- if (typeof window === "undefined") return;
442
- if (!window.dataLayer) {
443
- window.dataLayer = [];
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 (typeof window === "undefined") return;
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 (typeof window === "undefined") return;
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 || {}, ...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.find((d) => d.name === desc.name)) result.push(desc);
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.find((d) => d.name === "cookieConsent")) {
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 (typeof window === "undefined") return false;
1093
+ if (globalThis.window === void 0) return false;
1078
1094
  try {
1079
- const reactSymbols = Object.getOwnPropertySymbols(window).map((sym) => String(sym)).filter((name) => name.includes("react"));
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 (typeof window === "undefined") return null;
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 (typeof window === "undefined") {
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 = Array.from(/* @__PURE__ */ new Set([...props.categories.enabledCategories ?? []]));
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. A lib aplicar\xE1 um padr\xE3o seguro, mas recomenda-se definir 'categories.enabledCategories' explicitamente para clareza e auditoria."
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 = Array.from(/* @__PURE__ */ new Set([...cat.enabledCategories ?? []]));
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((v) => String(v)).join(", ")} \u2014 remova ou corrija os IDs de categoria`
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 || "analytics";
1457
+ const cat = assigned ?? "analytics";
1442
1458
  out[cat] = out[cat] || [];
1443
- if (!out[cat].find((x) => x.name === d.name)) out[cat].push(d);
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 CategoriesProvider. Certifique-se de que o ConsentProvider est\xE1 envolvendo seu componente."
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
- }, [state.preferences, state.consented, state.source, isHydrated]);
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" && typeof window !== "undefined" && !didWarnAboutMissingUI.current && !CookieBannerComponent && !FloatingPreferencesButtonComponent && (() => {
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
- blocking,
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 new Error("useConsentState must be used within ConsentProvider");
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 new Error("useConsentActions must be used within ConsentProvider");
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
- for (const [k, v] of Object.entries(attrs)) s.setAttribute(k, v);
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 (typeof window !== "undefined" && typeof window.dispatchEvent === "function") {
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.allCategories.map((cat) => cat.id);
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
- integration.attrs
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
- await loadScript(integration.id, integration.src, integration.category, integration.attrs);
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 (typeof window !== "undefined") {
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 (typeof window !== "undefined") {
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": (/* @__PURE__ */ new Date()).getTime(), event: "gtm.js" });
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 (typeof window !== "undefined") {
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 (typeof window !== "undefined") {
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 (typeof window !== "undefined") {
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 (typeof window !== "undefined") {
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 (typeof window !== "undefined" && typeof config.upload !== "undefined") {
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 (typeof window !== "undefined") {
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 (typeof window !== "undefined") {
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;