@react-lgpd-consent/core 0.5.0 → 0.6.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 +19 -0
- package/dist/index.cjs +307 -18
- package/dist/index.d.cts +186 -2
- package/dist/index.d.ts +186 -2
- package/dist/index.js +304 -19
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31,6 +31,15 @@ function createProjectPreferences(config, defaultValue = false) {
|
|
|
31
31
|
});
|
|
32
32
|
return preferences;
|
|
33
33
|
}
|
|
34
|
+
function ensureNecessaryAlwaysOn(preferences) {
|
|
35
|
+
if (preferences.necessary === true) {
|
|
36
|
+
return { ...preferences, necessary: true };
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
...preferences,
|
|
40
|
+
necessary: true
|
|
41
|
+
};
|
|
42
|
+
}
|
|
34
43
|
function validateProjectPreferences(preferences, config) {
|
|
35
44
|
const validPreferences = {
|
|
36
45
|
necessary: true
|
|
@@ -298,12 +307,22 @@ function setDebugLogging(enabled, level = 2 /* INFO */) {
|
|
|
298
307
|
}
|
|
299
308
|
|
|
300
309
|
// src/utils/cookieUtils.ts
|
|
310
|
+
var DEFAULT_STORAGE_NAMESPACE = "lgpd-consent";
|
|
311
|
+
var DEFAULT_STORAGE_VERSION = "1";
|
|
312
|
+
function buildConsentStorageKey(options) {
|
|
313
|
+
const namespaceRaw = options?.namespace?.trim() || DEFAULT_STORAGE_NAMESPACE;
|
|
314
|
+
const versionRaw = options?.version?.trim() || DEFAULT_STORAGE_VERSION;
|
|
315
|
+
const sanitizedNamespace = namespaceRaw.replace(/[^a-z0-9._-]+/gi, "-").toLowerCase();
|
|
316
|
+
const sanitizedVersion = versionRaw.replace(/[^a-z0-9._-]+/gi, "-").toLowerCase();
|
|
317
|
+
return `${sanitizedNamespace}__v${sanitizedVersion}`;
|
|
318
|
+
}
|
|
301
319
|
var DEFAULT_COOKIE_OPTS = {
|
|
302
320
|
name: "cookieConsent",
|
|
303
321
|
maxAgeDays: 365,
|
|
304
322
|
sameSite: "Lax",
|
|
305
323
|
secure: typeof window !== "undefined" ? window.location.protocol === "https:" : false,
|
|
306
|
-
path: "/"
|
|
324
|
+
path: "/",
|
|
325
|
+
domain: void 0
|
|
307
326
|
};
|
|
308
327
|
var COOKIE_SCHEMA_VERSION = "1.0";
|
|
309
328
|
function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
|
|
@@ -357,10 +376,11 @@ function writeConsentCookie(state, config, opts, source = "banner") {
|
|
|
357
376
|
}
|
|
358
377
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
359
378
|
const o = { ...DEFAULT_COOKIE_OPTS, ...opts };
|
|
379
|
+
const preferences = ensureNecessaryAlwaysOn(state.preferences);
|
|
360
380
|
const cookieData = {
|
|
361
381
|
version: COOKIE_SCHEMA_VERSION,
|
|
362
382
|
consented: state.consented,
|
|
363
|
-
preferences
|
|
383
|
+
preferences,
|
|
364
384
|
consentDate: state.consentDate || now,
|
|
365
385
|
lastUpdate: now,
|
|
366
386
|
source,
|
|
@@ -371,7 +391,8 @@ function writeConsentCookie(state, config, opts, source = "banner") {
|
|
|
371
391
|
expires: o.maxAgeDays,
|
|
372
392
|
sameSite: o.sameSite,
|
|
373
393
|
secure: o.secure,
|
|
374
|
-
path: o.path
|
|
394
|
+
path: o.path,
|
|
395
|
+
domain: o.domain
|
|
375
396
|
});
|
|
376
397
|
logger.info("Consent cookie saved", {
|
|
377
398
|
consented: cookieData.consented,
|
|
@@ -386,12 +407,12 @@ function removeConsentCookie(opts) {
|
|
|
386
407
|
}
|
|
387
408
|
const o = { ...DEFAULT_COOKIE_OPTS, ...opts };
|
|
388
409
|
logger.cookieOperation("delete", o.name);
|
|
389
|
-
Cookies.remove(o.name, { path: o.path });
|
|
410
|
+
Cookies.remove(o.name, { path: o.path, domain: o.domain });
|
|
390
411
|
logger.info("Consent cookie removed");
|
|
391
412
|
}
|
|
392
413
|
|
|
393
414
|
// src/utils/dataLayerEvents.ts
|
|
394
|
-
var LIBRARY_VERSION = "0.
|
|
415
|
+
var LIBRARY_VERSION = "0.6.1";
|
|
395
416
|
function ensureDataLayer() {
|
|
396
417
|
if (typeof window === "undefined") return;
|
|
397
418
|
if (!window.dataLayer) {
|
|
@@ -1027,6 +1048,207 @@ var GUIDANCE_PRESETS = {
|
|
|
1027
1048
|
}
|
|
1028
1049
|
};
|
|
1029
1050
|
|
|
1051
|
+
// src/utils/peerDepsCheck.ts
|
|
1052
|
+
function detectMultipleReactInstances() {
|
|
1053
|
+
if (typeof window === "undefined") return false;
|
|
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 = `
|
|
1104
|
+
\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
|
+
\u2551 \u26A0\uFE0F ERRO: M\xFAltiplas inst\xE2ncias de React detectadas \u2551
|
|
1106
|
+
\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
|
|
1107
|
+
|
|
1108
|
+
\u{1F534} Problema:
|
|
1109
|
+
Seu projeto est\xE1 carregando mais de uma c\xF3pia do React, causando o erro:
|
|
1110
|
+
"Invalid hook call. Hooks can only be called inside of the body of a
|
|
1111
|
+
function component."
|
|
1112
|
+
|
|
1113
|
+
\u{1F50D} Causa prov\xE1vel:
|
|
1114
|
+
\u2022 pnpm/Yarn PnP sem hoisting adequado de peer dependencies
|
|
1115
|
+
\u2022 node_modules com React duplicado (npm/yarn cl\xE1ssico)
|
|
1116
|
+
\u2022 Webpack/Vite com m\xFAltiplas resolu\xE7\xF5es do mesmo pacote
|
|
1117
|
+
|
|
1118
|
+
\u2705 Solu\xE7\xF5es:
|
|
1119
|
+
|
|
1120
|
+
\u{1F4E6} PNPM (RECOMENDADO):
|
|
1121
|
+
Adicione ao package.json raiz:
|
|
1122
|
+
{
|
|
1123
|
+
"pnpm": {
|
|
1124
|
+
"overrides": {
|
|
1125
|
+
"react": "$react",
|
|
1126
|
+
"react-dom": "$react-dom"
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
Execute: pnpm install
|
|
1131
|
+
|
|
1132
|
+
\u{1F4E6} NPM/Yarn:
|
|
1133
|
+
Adicione ao package.json raiz:
|
|
1134
|
+
{
|
|
1135
|
+
"overrides": {
|
|
1136
|
+
"react": "^18.2.0 || ^19.0.0",
|
|
1137
|
+
"react-dom": "^18.2.0 || ^19.0.0"
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
Execute: npm install (ou yarn install)
|
|
1141
|
+
|
|
1142
|
+
\u{1F527} Webpack:
|
|
1143
|
+
Adicione ao webpack.config.js:
|
|
1144
|
+
module.exports = {
|
|
1145
|
+
resolve: {
|
|
1146
|
+
alias: {
|
|
1147
|
+
react: path.resolve('./node_modules/react'),
|
|
1148
|
+
'react-dom': path.resolve('./node_modules/react-dom'),
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
\u26A1 Vite:
|
|
1154
|
+
Adicione ao vite.config.js:
|
|
1155
|
+
export default {
|
|
1156
|
+
resolve: {
|
|
1157
|
+
dedupe: ['react', 'react-dom']
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
\u{1F4DA} Documenta\xE7\xE3o:
|
|
1162
|
+
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#multiple-react-instances
|
|
1163
|
+
|
|
1164
|
+
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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
|
+
result.errors.push(errorMsg);
|
|
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 = `
|
|
1176
|
+
\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
|
+
\u2551 \u26A0\uFE0F AVISO: Vers\xE3o do React n\xE3o suportada \u2551
|
|
1178
|
+
\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
|
+
|
|
1180
|
+
\u{1F4E6} Vers\xE3o detectada: React ${reactVersion}
|
|
1181
|
+
\u2705 Vers\xF5es suportadas: React 18.x ou 19.x
|
|
1182
|
+
|
|
1183
|
+
\u{1F50D} O react-lgpd-consent requer React 18.2.0+ ou React 19.x
|
|
1184
|
+
|
|
1185
|
+
\u2705 Solu\xE7\xE3o:
|
|
1186
|
+
Atualize o React para uma vers\xE3o suportada:
|
|
1187
|
+
|
|
1188
|
+
npm install react@^18.2.0 react-dom@^18.2.0
|
|
1189
|
+
|
|
1190
|
+
ou
|
|
1191
|
+
|
|
1192
|
+
npm install react@^19.0.0 react-dom@^19.0.0
|
|
1193
|
+
|
|
1194
|
+
\u{1F4DA} Documenta\xE7\xE3o:
|
|
1195
|
+
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#react-version
|
|
1196
|
+
|
|
1197
|
+
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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
|
+
result.errors.push(errorMsg);
|
|
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
|
+
`
|
|
1214
|
+
\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
|
+
\u2551 \u26A0\uFE0F AVISO: Vers\xE3o do Material-UI fora do range recomendado \u2551
|
|
1216
|
+
\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
|
+
|
|
1218
|
+
\u{1F4E6} Vers\xE3o detectada: @mui/material ${muiVersion}
|
|
1219
|
+
\u2705 Vers\xF5es suportadas: 5.15.0+, 6.x, 7.x
|
|
1220
|
+
|
|
1221
|
+
\u{1F50D} Componentes de UI (@react-lgpd-consent/mui) podem apresentar problemas.
|
|
1222
|
+
|
|
1223
|
+
\u2705 Solu\xE7\xE3o:
|
|
1224
|
+
Atualize o MUI para uma vers\xE3o suportada:
|
|
1225
|
+
|
|
1226
|
+
npm install @mui/material@^7.0.0 @emotion/react @emotion/styled
|
|
1227
|
+
|
|
1228
|
+
ou mantenha 5.15.0+:
|
|
1229
|
+
|
|
1230
|
+
npm install @mui/material@^5.15.0 @emotion/react @emotion/styled
|
|
1231
|
+
|
|
1232
|
+
\u{1F4DA} Documenta\xE7\xE3o:
|
|
1233
|
+
https://github.com/lucianoedipo/react-lgpd-consent/blob/main/TROUBLESHOOTING.md#mui-version
|
|
1234
|
+
|
|
1235
|
+
\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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
|
+
);
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
return result;
|
|
1242
|
+
}
|
|
1243
|
+
function runPeerDepsCheck() {
|
|
1244
|
+
const result = checkPeerDeps({ logWarnings: true });
|
|
1245
|
+
if (result.ok && result.warnings.length === 0) {
|
|
1246
|
+
logger.debug("\u2705 Peer dependencies check: OK");
|
|
1247
|
+
} else if (result.warnings.length > 0) {
|
|
1248
|
+
logger.warn("\u26A0\uFE0F Peer dependencies check: avisos detectados");
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1030
1252
|
// src/utils/validation.ts
|
|
1031
1253
|
var isDev = () => typeof process !== "undefined" && process.env.NODE_ENV !== "production";
|
|
1032
1254
|
function validateConsentProviderProps(props) {
|
|
@@ -1299,10 +1521,11 @@ function useDesignTokens() {
|
|
|
1299
1521
|
}
|
|
1300
1522
|
function createFullConsentState(consented, preferences, source, projectConfig, isModalOpen = false, existingState) {
|
|
1301
1523
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1524
|
+
const enforcedPreferences = ensureNecessaryAlwaysOn(preferences);
|
|
1302
1525
|
return {
|
|
1303
1526
|
version: "1.0",
|
|
1304
1527
|
consented,
|
|
1305
|
-
preferences,
|
|
1528
|
+
preferences: enforcedPreferences,
|
|
1306
1529
|
consentDate: existingState?.consentDate || now,
|
|
1307
1530
|
lastUpdate: now,
|
|
1308
1531
|
source,
|
|
@@ -1366,7 +1589,11 @@ function reducer(state, action) {
|
|
|
1366
1589
|
});
|
|
1367
1590
|
return newState;
|
|
1368
1591
|
}
|
|
1369
|
-
case "SET_CATEGORY":
|
|
1592
|
+
case "SET_CATEGORY": {
|
|
1593
|
+
if (action.category === "necessary") {
|
|
1594
|
+
logger.warn("Attempt to toggle necessary category ignored for compliance reasons.");
|
|
1595
|
+
return state;
|
|
1596
|
+
}
|
|
1370
1597
|
logger.debug("Category preference changed", {
|
|
1371
1598
|
category: action.category,
|
|
1372
1599
|
value: action.value
|
|
@@ -1379,9 +1606,12 @@ function reducer(state, action) {
|
|
|
1379
1606
|
},
|
|
1380
1607
|
lastUpdate: (/* @__PURE__ */ new Date()).toISOString()
|
|
1381
1608
|
};
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1609
|
+
}
|
|
1610
|
+
case "SET_PREFERENCES": {
|
|
1611
|
+
const sanitized = ensureNecessaryAlwaysOn(action.preferences);
|
|
1612
|
+
logger.info("Preferences saved", { preferences: sanitized });
|
|
1613
|
+
return createFullConsentState(true, sanitized, "modal", action.config, false, state);
|
|
1614
|
+
}
|
|
1385
1615
|
case "OPEN_MODAL":
|
|
1386
1616
|
return { ...state, isModalOpen: true };
|
|
1387
1617
|
case "CLOSE_MODAL":
|
|
@@ -1432,16 +1662,25 @@ function ConsentProvider({
|
|
|
1432
1662
|
onConsentGiven,
|
|
1433
1663
|
onPreferencesSaved,
|
|
1434
1664
|
cookie: cookieOpts,
|
|
1665
|
+
storage,
|
|
1666
|
+
onConsentVersionChange,
|
|
1435
1667
|
disableDeveloperGuidance,
|
|
1436
1668
|
guidanceConfig,
|
|
1437
1669
|
children,
|
|
1438
1670
|
disableDiscoveryLog
|
|
1439
1671
|
}) {
|
|
1440
1672
|
const texts = React4.useMemo(() => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }), [textsProp]);
|
|
1441
|
-
const cookie = React4.useMemo(
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1673
|
+
const cookie = React4.useMemo(() => {
|
|
1674
|
+
const base = { ...DEFAULT_COOKIE_OPTS, ...cookieOpts ?? {} };
|
|
1675
|
+
base.name = cookieOpts?.name ?? buildConsentStorageKey({
|
|
1676
|
+
namespace: storage?.namespace,
|
|
1677
|
+
version: storage?.version
|
|
1678
|
+
});
|
|
1679
|
+
if (!base.domain && storage?.domain) {
|
|
1680
|
+
base.domain = storage.domain;
|
|
1681
|
+
}
|
|
1682
|
+
return base;
|
|
1683
|
+
}, [cookieOpts, storage?.domain, storage?.namespace, storage?.version]);
|
|
1445
1684
|
const finalCategoriesConfig = React4.useMemo(() => {
|
|
1446
1685
|
const isProd = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
1447
1686
|
if (!categories) return DEFAULT_PROJECT_CATEGORIES;
|
|
@@ -1459,6 +1698,12 @@ function ConsentProvider({
|
|
|
1459
1698
|
}, [categories]);
|
|
1460
1699
|
const didWarnAboutMissingUI = React4.useRef(false);
|
|
1461
1700
|
useDeveloperGuidance(finalCategoriesConfig, disableDeveloperGuidance, guidanceConfig);
|
|
1701
|
+
React4.useEffect(() => {
|
|
1702
|
+
const isProd = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
1703
|
+
if (!isProd && !disableDeveloperGuidance) {
|
|
1704
|
+
runPeerDepsCheck();
|
|
1705
|
+
}
|
|
1706
|
+
}, [disableDeveloperGuidance]);
|
|
1462
1707
|
React4.useEffect(() => {
|
|
1463
1708
|
const isProd = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
1464
1709
|
if (!isProd && PreferencesModalComponent) {
|
|
@@ -1478,6 +1723,8 @@ function ConsentProvider({
|
|
|
1478
1723
|
);
|
|
1479
1724
|
}, [initialState, finalCategoriesConfig]);
|
|
1480
1725
|
const [state, dispatch] = React4.useReducer(reducer, boot);
|
|
1726
|
+
const previousCookieRef = React4.useRef(cookie);
|
|
1727
|
+
const skipCookiePersistRef = React4.useRef(false);
|
|
1481
1728
|
const [isHydrated, setIsHydrated] = React4.useState(false);
|
|
1482
1729
|
const previousPreferencesRef = React4.useRef(state.preferences);
|
|
1483
1730
|
React4.useEffect(() => {
|
|
@@ -1493,6 +1740,35 @@ function ConsentProvider({
|
|
|
1493
1740
|
}
|
|
1494
1741
|
setIsHydrated(true);
|
|
1495
1742
|
}, [cookie.name, initialState, finalCategoriesConfig]);
|
|
1743
|
+
React4.useEffect(() => {
|
|
1744
|
+
const previousCookie = previousCookieRef.current;
|
|
1745
|
+
const isSameCookie = previousCookie.name === cookie.name && previousCookie.domain === cookie.domain && previousCookie.path === cookie.path;
|
|
1746
|
+
if (isSameCookie) {
|
|
1747
|
+
previousCookieRef.current = cookie;
|
|
1748
|
+
return;
|
|
1749
|
+
}
|
|
1750
|
+
skipCookiePersistRef.current = true;
|
|
1751
|
+
removeConsentCookie(previousCookie);
|
|
1752
|
+
const reset = () => {
|
|
1753
|
+
removeConsentCookie(cookie);
|
|
1754
|
+
dispatch({ type: "RESET", config: finalCategoriesConfig });
|
|
1755
|
+
};
|
|
1756
|
+
reset();
|
|
1757
|
+
if (onConsentVersionChange) {
|
|
1758
|
+
onConsentVersionChange({
|
|
1759
|
+
previousKey: previousCookie.name,
|
|
1760
|
+
nextKey: cookie.name,
|
|
1761
|
+
resetConsent: reset
|
|
1762
|
+
});
|
|
1763
|
+
}
|
|
1764
|
+
previousCookieRef.current = cookie;
|
|
1765
|
+
}, [cookie, finalCategoriesConfig, onConsentVersionChange, dispatch]);
|
|
1766
|
+
function resetSkipCookiePersistOnConsentRevoked() {
|
|
1767
|
+
if (skipCookiePersistRef.current && !state.consented) {
|
|
1768
|
+
skipCookiePersistRef.current = false;
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
React4.useEffect(resetSkipCookiePersistOnConsentRevoked, [state.consented]);
|
|
1496
1772
|
React4.useEffect(() => {
|
|
1497
1773
|
if (isHydrated) {
|
|
1498
1774
|
pushConsentInitializedEvent(state.preferences);
|
|
@@ -1502,7 +1778,9 @@ function ConsentProvider({
|
|
|
1502
1778
|
}
|
|
1503
1779
|
}, [isHydrated]);
|
|
1504
1780
|
React4.useEffect(() => {
|
|
1505
|
-
if (state.consented)
|
|
1781
|
+
if (!state.consented) return;
|
|
1782
|
+
if (skipCookiePersistRef.current) return;
|
|
1783
|
+
writeConsentCookie(state, finalCategoriesConfig, cookie);
|
|
1506
1784
|
}, [state, cookie, finalCategoriesConfig]);
|
|
1507
1785
|
const prevConsented = React4.useRef(state.consented);
|
|
1508
1786
|
React4.useEffect(() => {
|
|
@@ -1530,15 +1808,22 @@ function ConsentProvider({
|
|
|
1530
1808
|
const api = React4.useMemo(() => {
|
|
1531
1809
|
const acceptAll = () => dispatch({ type: "ACCEPT_ALL", config: finalCategoriesConfig });
|
|
1532
1810
|
const rejectAll = () => dispatch({ type: "REJECT_ALL", config: finalCategoriesConfig });
|
|
1533
|
-
const setPreference = (category, value) =>
|
|
1811
|
+
const setPreference = (category, value) => {
|
|
1812
|
+
if (category === "necessary") {
|
|
1813
|
+
logger.warn("setPreference: attempt to toggle necessary category ignored.");
|
|
1814
|
+
return;
|
|
1815
|
+
}
|
|
1816
|
+
dispatch({ type: "SET_CATEGORY", category, value });
|
|
1817
|
+
};
|
|
1534
1818
|
const setPreferences = (preferences) => {
|
|
1819
|
+
const sanitized = ensureNecessaryAlwaysOn(preferences);
|
|
1535
1820
|
dispatch({
|
|
1536
1821
|
type: "SET_PREFERENCES",
|
|
1537
|
-
preferences,
|
|
1822
|
+
preferences: sanitized,
|
|
1538
1823
|
config: finalCategoriesConfig
|
|
1539
1824
|
});
|
|
1540
1825
|
if (onPreferencesSaved) {
|
|
1541
|
-
setTimeout(() => onPreferencesSaved(
|
|
1826
|
+
setTimeout(() => onPreferencesSaved(sanitized), 150);
|
|
1542
1827
|
}
|
|
1543
1828
|
};
|
|
1544
1829
|
const openPreferences = () => dispatch({ type: "OPEN_MODAL" });
|
|
@@ -2539,4 +2824,4 @@ var TEXT_TEMPLATES = {
|
|
|
2539
2824
|
}
|
|
2540
2825
|
};
|
|
2541
2826
|
|
|
2542
|
-
export { COMMON_INTEGRATIONS, ConsentGate, ConsentProvider, ConsentScriptLoader, DEFAULT_PROJECT_CATEGORIES, DesignProvider, EXPANDED_DEFAULT_TEXTS, GUIDANCE_PRESETS, INTEGRATION_TEMPLATES, LogLevel, TEXT_TEMPLATES, analyzeDeveloperConfiguration, analyzeIntegrationCategories, autoConfigureCategories, categorizeDiscoveredCookies, createClarityIntegration, createCorporateIntegrations, createECommerceIntegrations, createFacebookPixelIntegration, createGoogleAnalyticsIntegration, createGoogleTagManagerIntegration, createHotjarIntegration, createIntercomIntegration, createMixpanelIntegration, createProjectPreferences, createSaaSIntegrations, createUserWayIntegration, createZendeskChatIntegration, defaultTexts, detectConsentCookieName, discoverRuntimeCookies, extractCategoriesFromIntegrations, getAllProjectCategories, getCookiesInfoForCategory, loadScript, logDeveloperGuidance, logger, openPreferencesModal, pushConsentInitializedEvent, pushConsentUpdatedEvent, resolveTexts, setCookieCatalogOverrides, setCookieCategoryOverrides, setDebugLogging, suggestCategoryForScript, useCategories, useCategoryStatus, useConsent, useConsentHydration, useConsentScriptLoader, useConsentTexts, useDataLayerEvents, useDesignTokens, useDeveloperGuidance, useOpenPreferencesModal, validateIntegrationCategories, validateNecessaryClassification, validateProjectPreferences };
|
|
2827
|
+
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 };
|