react-lgpd-consent 0.4.0 → 0.4.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 +100 -0
- package/QUICKSTART.en.md +34 -0
- package/QUICKSTART.md +308 -1
- package/README.en.md +19 -0
- package/README.md +30 -0
- package/dist/{PreferencesModal-D2SEVH3N.js → PreferencesModal-RNRD3JKB.js} +1 -1
- package/dist/{chunk-B5FNONG3.js → chunk-VOQUCGOA.js} +902 -242
- package/dist/index.cjs +1698 -277
- package/dist/index.d.cts +1782 -230
- package/dist/index.d.ts +1782 -230
- package/dist/index.js +738 -8
- package/package.json +32 -4
package/dist/index.cjs
CHANGED
|
@@ -30,196 +30,266 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
30
|
));
|
|
31
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
32
|
|
|
33
|
-
// src/utils/
|
|
34
|
-
function
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
};
|
|
41
|
-
const finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
|
|
42
|
-
if (!config) {
|
|
43
|
-
guidance.warnings.push(
|
|
44
|
-
'LGPD-CONSENT: Nenhuma configura\xE7\xE3o de categorias especificada. Usando padr\xE3o: necessary + analytics. Para produ\xE7\xE3o, recomenda-se especificar explicitamente as categorias via prop "categories".'
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
guidance.activeCategoriesInfo.push({
|
|
48
|
-
id: "necessary",
|
|
49
|
-
name: "Cookies Necess\xE1rios",
|
|
50
|
-
description: "Essenciais para funcionamento b\xE1sico do site",
|
|
51
|
-
essential: true,
|
|
52
|
-
uiRequired: false
|
|
53
|
-
});
|
|
54
|
-
const enabledCategories = finalConfig.enabledCategories || [];
|
|
55
|
-
const categoryNames = {
|
|
56
|
-
analytics: {
|
|
57
|
-
name: "Cookies Anal\xEDticos",
|
|
58
|
-
description: "Medem uso e performance do site"
|
|
59
|
-
},
|
|
60
|
-
functional: {
|
|
61
|
-
name: "Cookies Funcionais",
|
|
62
|
-
description: "Melhoram experi\xEAncia e funcionalidades"
|
|
63
|
-
},
|
|
64
|
-
marketing: {
|
|
65
|
-
name: "Cookies de Marketing",
|
|
66
|
-
description: "Publicidade direcionada e campanhas"
|
|
67
|
-
},
|
|
68
|
-
social: {
|
|
69
|
-
name: "Cookies de Redes Sociais",
|
|
70
|
-
description: "Integra\xE7\xE3o com plataformas sociais"
|
|
71
|
-
},
|
|
72
|
-
personalization: {
|
|
73
|
-
name: "Cookies de Personaliza\xE7\xE3o",
|
|
74
|
-
description: "Adaptam conte\xFAdo \xE0s prefer\xEAncias do usu\xE1rio"
|
|
33
|
+
// src/utils/cookieRegistry.ts
|
|
34
|
+
function setCookieCatalogOverrides(overrides) {
|
|
35
|
+
COOKIE_CATALOG_OVERRIDES = {
|
|
36
|
+
byCategory: { ...COOKIE_CATALOG_OVERRIDES.byCategory || {}, ...overrides.byCategory || {} },
|
|
37
|
+
byIntegration: {
|
|
38
|
+
...COOKIE_CATALOG_OVERRIDES.byIntegration || {},
|
|
39
|
+
...overrides.byIntegration || {}
|
|
75
40
|
}
|
|
76
41
|
};
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
uiRequired: !cat.essential
|
|
42
|
+
}
|
|
43
|
+
function setCookieCategoryOverrides(map) {
|
|
44
|
+
COOKIE_CATEGORY_OVERRIDES = { ...COOKIE_CATEGORY_OVERRIDES, ...map };
|
|
45
|
+
}
|
|
46
|
+
function matchPattern(name, pattern) {
|
|
47
|
+
if (pattern.endsWith("*")) return name.startsWith(pattern.slice(0, -1));
|
|
48
|
+
return name === pattern;
|
|
49
|
+
}
|
|
50
|
+
function getCookiesInfoForCategory(categoryId, usedIntegrations) {
|
|
51
|
+
const result = [];
|
|
52
|
+
usedIntegrations.forEach((id) => {
|
|
53
|
+
const defaultCat = INTEGRATION_DEFAULT_CATEGORY[id];
|
|
54
|
+
const defaults = COOKIE_INFO_BY_INTEGRATION[id] || [];
|
|
55
|
+
const list = COOKIE_CATALOG_OVERRIDES.byIntegration?.[id] || defaults;
|
|
56
|
+
list.forEach((desc) => {
|
|
57
|
+
const overrideCat = Object.entries(COOKIE_CATEGORY_OVERRIDES).find(
|
|
58
|
+
([pattern]) => matchPattern(desc.name, pattern)
|
|
59
|
+
)?.[1];
|
|
60
|
+
const finalCat = overrideCat ?? defaultCat;
|
|
61
|
+
if (finalCat === categoryId && !result.find((d) => d.name === desc.name)) result.push(desc);
|
|
98
62
|
});
|
|
99
63
|
});
|
|
100
|
-
const
|
|
101
|
-
if (
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
guidance.warnings.push(
|
|
108
|
-
`${totalToggleable} categorias opcionais detectadas. UI com muitas op\xE7\xF5es pode prejudicar experi\xEAncia do usu\xE1rio. Considere agrupar categorias similares.`
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
return guidance;
|
|
112
|
-
}
|
|
113
|
-
function logDeveloperGuidance(guidance, disableGuidanceProp) {
|
|
114
|
-
const gt = globalThis;
|
|
115
|
-
const nodeEnv = typeof gt.process !== "undefined" ? gt.process?.env?.NODE_ENV : void 0;
|
|
116
|
-
const isProd = nodeEnv === "production" || gt.__LGPD_PRODUCTION__ === true;
|
|
117
|
-
const isDisabled = !!disableGuidanceProp || gt.__LGPD_DISABLE_GUIDANCE__ === true;
|
|
118
|
-
if (isProd || isDisabled) return;
|
|
119
|
-
const PREFIX = "[\u{1F36A} LGPD-CONSENT]";
|
|
120
|
-
if (guidance.warnings.length > 0) {
|
|
121
|
-
console.group(`${PREFIX} \u26A0\uFE0F Avisos de Configura\xE7\xE3o`);
|
|
122
|
-
guidance.warnings.forEach((msg) => console.warn(`${PREFIX} ${msg}`));
|
|
123
|
-
console.groupEnd();
|
|
124
|
-
}
|
|
125
|
-
if (guidance.suggestions.length > 0) {
|
|
126
|
-
console.group(`${PREFIX} \u{1F4A1} Sugest\xF5es`);
|
|
127
|
-
guidance.suggestions.forEach((msg) => console.info(`${PREFIX} ${msg}`));
|
|
128
|
-
console.groupEnd();
|
|
129
|
-
}
|
|
130
|
-
if (guidance.usingDefaults) {
|
|
131
|
-
console.warn(
|
|
132
|
-
`${PREFIX} \u{1F4CB} Usando configura\xE7\xE3o padr\xE3o. Para personalizar, use a prop "categories" no ConsentProvider.`
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
const rows = guidance.activeCategoriesInfo.map((cat) => ({
|
|
136
|
-
ID: cat.id,
|
|
137
|
-
Nome: cat.name,
|
|
138
|
-
"Toggle UI?": cat.uiRequired ? "\u2705 SIM" : "\u274C N\xC3O (sempre ativo)",
|
|
139
|
-
"Essencial?": cat.essential ? "\u{1F512} SIM" : "\u2699\uFE0F N\xC3O"
|
|
140
|
-
}));
|
|
141
|
-
if (typeof console.table === "function") {
|
|
142
|
-
console.group(`${PREFIX} \u{1F527} Categorias Ativas (para UI customizada)`);
|
|
143
|
-
console.table(rows);
|
|
144
|
-
console.info(`${PREFIX} \u2139\uFE0F Use estes dados para criar componentes customizados adequados.`);
|
|
145
|
-
console.groupEnd();
|
|
146
|
-
} else {
|
|
147
|
-
console.log(`${PREFIX} \u{1F527} Categorias Ativas (para UI customizada)`, rows);
|
|
148
|
-
console.info(`${PREFIX} \u2139\uFE0F Use estes dados para criar componentes customizados adequados.`);
|
|
64
|
+
const catOverride = COOKIE_CATALOG_OVERRIDES.byCategory?.[categoryId];
|
|
65
|
+
if (catOverride) {
|
|
66
|
+
catOverride.forEach((d) => {
|
|
67
|
+
const idx = result.findIndex((x) => x.name === d.name);
|
|
68
|
+
if (idx >= 0) result[idx] = d;
|
|
69
|
+
else result.push(d);
|
|
70
|
+
});
|
|
149
71
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
72
|
+
if (categoryId === "necessary") {
|
|
73
|
+
if (!result.find((d) => d.name === "cookieConsent")) {
|
|
74
|
+
result.push({
|
|
75
|
+
name: "cookieConsent",
|
|
76
|
+
purpose: "Armazena suas prefer\xEAncias de consentimento",
|
|
77
|
+
duration: "365 dias",
|
|
78
|
+
provider: "Este site"
|
|
79
|
+
});
|
|
158
80
|
}
|
|
159
|
-
}
|
|
160
|
-
return
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
161
83
|
}
|
|
162
|
-
var
|
|
163
|
-
var
|
|
164
|
-
"src/utils/
|
|
84
|
+
var COOKIE_PATTERNS_BY_CATEGORY, COOKIE_INFO_BY_INTEGRATION, INTEGRATION_DEFAULT_CATEGORY, COOKIE_CATALOG_OVERRIDES, COOKIE_CATEGORY_OVERRIDES;
|
|
85
|
+
var init_cookieRegistry = __esm({
|
|
86
|
+
"src/utils/cookieRegistry.ts"() {
|
|
165
87
|
"use strict";
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
88
|
+
COOKIE_PATTERNS_BY_CATEGORY = {
|
|
89
|
+
necessary: ["cookieConsent"],
|
|
90
|
+
analytics: ["_ga", "_ga_*", "_gid", "_gcl_au", "_hj*", "mp_*", "_clck", "_clsk"],
|
|
91
|
+
functional: ["intercom-*", "__zlcmid", "_zendesk_shared_session", "_userway_*"],
|
|
92
|
+
marketing: ["_fbp", "fr"],
|
|
93
|
+
social: [],
|
|
94
|
+
personalization: []
|
|
169
95
|
};
|
|
96
|
+
COOKIE_INFO_BY_INTEGRATION = {
|
|
97
|
+
"google-analytics": [
|
|
98
|
+
{
|
|
99
|
+
name: "_ga",
|
|
100
|
+
purpose: "Identifica\xE7\xE3o \xFAnica de visitantes para an\xE1lise de tr\xE1fego",
|
|
101
|
+
duration: "2 anos",
|
|
102
|
+
provider: "Google Analytics"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: "_ga_*",
|
|
106
|
+
purpose: "Rastreamento de sess\xF5es e eventos espec\xEDficos do stream GA4",
|
|
107
|
+
duration: "2 anos",
|
|
108
|
+
provider: "Google Analytics"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
name: "_gid",
|
|
112
|
+
purpose: "Distin\xE7\xE3o de visitantes \xFAnicos em per\xEDodo de 24h",
|
|
113
|
+
duration: "24 horas",
|
|
114
|
+
provider: "Google Analytics"
|
|
115
|
+
}
|
|
116
|
+
],
|
|
117
|
+
"google-tag-manager": [
|
|
118
|
+
{
|
|
119
|
+
name: "_gcl_au",
|
|
120
|
+
purpose: "Rastreamento de convers\xF5es de an\xFAncios",
|
|
121
|
+
duration: "90 dias",
|
|
122
|
+
provider: "Google"
|
|
123
|
+
}
|
|
124
|
+
],
|
|
125
|
+
hotjar: [
|
|
126
|
+
{
|
|
127
|
+
name: "_hjSession_*",
|
|
128
|
+
purpose: "Rastreamento de sess\xE3o",
|
|
129
|
+
duration: "30 minutos",
|
|
130
|
+
provider: "Hotjar"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: "_hjSessionUser_*",
|
|
134
|
+
purpose: "Persist\xEAncia de usu\xE1rio entre sess\xF5es",
|
|
135
|
+
duration: "365 dias",
|
|
136
|
+
provider: "Hotjar"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: "_hjFirstSeen",
|
|
140
|
+
purpose: "Detec\xE7\xE3o da primeira visita do usu\xE1rio",
|
|
141
|
+
duration: "Sess\xE3o",
|
|
142
|
+
provider: "Hotjar"
|
|
143
|
+
}
|
|
144
|
+
],
|
|
145
|
+
mixpanel: [
|
|
146
|
+
{
|
|
147
|
+
name: "mp_*",
|
|
148
|
+
purpose: "Rastreamento de eventos e propriedades do usu\xE1rio para analytics",
|
|
149
|
+
duration: "1 ano",
|
|
150
|
+
provider: "Mixpanel"
|
|
151
|
+
}
|
|
152
|
+
],
|
|
153
|
+
clarity: [
|
|
154
|
+
{
|
|
155
|
+
name: "_clck",
|
|
156
|
+
purpose: "Identificador de usu\xE1rio",
|
|
157
|
+
duration: "365 dias",
|
|
158
|
+
provider: "Microsoft"
|
|
159
|
+
},
|
|
160
|
+
{ name: "_clsk", purpose: "Rastreamento de sess\xE3o", duration: "1 dia", provider: "Microsoft" }
|
|
161
|
+
],
|
|
162
|
+
intercom: [
|
|
163
|
+
{
|
|
164
|
+
name: "intercom-id-*",
|
|
165
|
+
purpose: "Identificador do usu\xE1rio",
|
|
166
|
+
duration: "9 meses",
|
|
167
|
+
provider: "Intercom"
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
name: "intercom-session-*",
|
|
171
|
+
purpose: "Gerenciamento de sess\xE3o",
|
|
172
|
+
duration: "1 semana",
|
|
173
|
+
provider: "Intercom"
|
|
174
|
+
}
|
|
175
|
+
],
|
|
176
|
+
"zendesk-chat": [
|
|
177
|
+
{
|
|
178
|
+
name: "__zlcmid",
|
|
179
|
+
purpose: "Identificador de sess\xE3o de chat",
|
|
180
|
+
duration: "1 ano",
|
|
181
|
+
provider: "Zendesk"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
name: "_zendesk_shared_session",
|
|
185
|
+
purpose: "Gerenciamento de sess\xE3o",
|
|
186
|
+
duration: "Sess\xE3o",
|
|
187
|
+
provider: "Zendesk"
|
|
188
|
+
}
|
|
189
|
+
],
|
|
190
|
+
userway: [
|
|
191
|
+
{
|
|
192
|
+
name: "_userway_*",
|
|
193
|
+
purpose: "Prefer\xEAncias de acessibilidade",
|
|
194
|
+
duration: "1 ano",
|
|
195
|
+
provider: "UserWay"
|
|
196
|
+
}
|
|
197
|
+
],
|
|
198
|
+
"facebook-pixel": [
|
|
199
|
+
{ name: "_fbp", purpose: "Rastreamento de an\xFAncios", duration: "90 dias", provider: "Meta" },
|
|
200
|
+
{ name: "fr", purpose: "Direcionamento de an\xFAncios", duration: "90 dias", provider: "Meta" }
|
|
201
|
+
]
|
|
202
|
+
};
|
|
203
|
+
INTEGRATION_DEFAULT_CATEGORY = {
|
|
204
|
+
"google-analytics": "analytics",
|
|
205
|
+
"google-tag-manager": "analytics",
|
|
206
|
+
hotjar: "analytics",
|
|
207
|
+
mixpanel: "analytics",
|
|
208
|
+
clarity: "analytics",
|
|
209
|
+
intercom: "functional",
|
|
210
|
+
"zendesk-chat": "functional",
|
|
211
|
+
userway: "functional",
|
|
212
|
+
"facebook-pixel": "marketing"
|
|
213
|
+
};
|
|
214
|
+
COOKIE_CATALOG_OVERRIDES = {};
|
|
215
|
+
COOKIE_CATEGORY_OVERRIDES = {};
|
|
170
216
|
}
|
|
171
217
|
});
|
|
172
218
|
|
|
173
|
-
// src/
|
|
174
|
-
function
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
};
|
|
189
|
-
}, [config]);
|
|
190
|
-
React2.useEffect(() => {
|
|
191
|
-
logDeveloperGuidance(contextValue.guidance, disableDeveloperGuidance);
|
|
192
|
-
}, [contextValue.guidance, disableDeveloperGuidance]);
|
|
193
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CategoriesContext.Provider, { value: contextValue, children });
|
|
219
|
+
// src/utils/cookieDiscovery.ts
|
|
220
|
+
function discoverRuntimeCookies() {
|
|
221
|
+
if (typeof document === "undefined" || !document.cookie) return [];
|
|
222
|
+
const names = Array.from(
|
|
223
|
+
new Set(
|
|
224
|
+
document.cookie.split(";").map((s) => s.trim()).filter(Boolean).map((s) => s.split("=")[0])
|
|
225
|
+
)
|
|
226
|
+
);
|
|
227
|
+
const list = names.map((name) => ({ name }));
|
|
228
|
+
try {
|
|
229
|
+
;
|
|
230
|
+
globalThis.__LGPD_DISCOVERED_COOKIES__ = list;
|
|
231
|
+
} catch {
|
|
232
|
+
}
|
|
233
|
+
return list;
|
|
194
234
|
}
|
|
195
|
-
function
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
235
|
+
function detectConsentCookieName() {
|
|
236
|
+
if (typeof document === "undefined" || !document.cookie) return null;
|
|
237
|
+
try {
|
|
238
|
+
const pairs = document.cookie.split(";").map((s) => s.trim()).filter(Boolean);
|
|
239
|
+
for (const p of pairs) {
|
|
240
|
+
const [name, ...rest] = p.split("=");
|
|
241
|
+
const raw = rest.join("=");
|
|
242
|
+
if (!raw) continue;
|
|
243
|
+
let val = raw;
|
|
244
|
+
try {
|
|
245
|
+
val = decodeURIComponent(raw);
|
|
246
|
+
} catch {
|
|
247
|
+
}
|
|
248
|
+
if (val.startsWith("{")) {
|
|
249
|
+
try {
|
|
250
|
+
const obj = JSON.parse(val);
|
|
251
|
+
if (obj && typeof obj === "object" && "preferences" in obj && "version" in obj) {
|
|
252
|
+
return name;
|
|
253
|
+
}
|
|
254
|
+
} catch {
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
} catch {
|
|
201
259
|
}
|
|
202
|
-
return
|
|
260
|
+
return null;
|
|
203
261
|
}
|
|
204
|
-
function
|
|
205
|
-
const
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
262
|
+
function categorizeDiscoveredCookies(discovered, registerOverrides = false) {
|
|
263
|
+
const list = discovered || globalThis.__LGPD_DISCOVERED_COOKIES__ || [];
|
|
264
|
+
const out = {};
|
|
265
|
+
function matchPattern2(name, pattern) {
|
|
266
|
+
if (pattern.endsWith("*")) return name.startsWith(pattern.slice(0, -1));
|
|
267
|
+
return name === pattern;
|
|
268
|
+
}
|
|
269
|
+
list.filter((d) => d.name && d.name !== "cookieConsent").forEach((d) => {
|
|
270
|
+
let assigned = null;
|
|
271
|
+
Object.keys(COOKIE_PATTERNS_BY_CATEGORY).forEach((cat2) => {
|
|
272
|
+
if (assigned) return;
|
|
273
|
+
const patterns = COOKIE_PATTERNS_BY_CATEGORY[cat2] || [];
|
|
274
|
+
if (patterns.some((p) => matchPattern2(d.name, p))) assigned = cat2;
|
|
275
|
+
});
|
|
276
|
+
const cat = assigned || "analytics";
|
|
277
|
+
out[cat] = out[cat] || [];
|
|
278
|
+
if (!out[cat].find((x) => x.name === d.name)) out[cat].push(d);
|
|
279
|
+
});
|
|
280
|
+
if (registerOverrides) {
|
|
281
|
+
const byCategory = {};
|
|
282
|
+
Object.entries(out).forEach(([cat, cookies]) => {
|
|
283
|
+
byCategory[cat] = cookies;
|
|
284
|
+
});
|
|
285
|
+
setCookieCatalogOverrides({ byCategory });
|
|
286
|
+
}
|
|
287
|
+
return out;
|
|
214
288
|
}
|
|
215
|
-
var
|
|
216
|
-
|
|
217
|
-
"src/context/CategoriesContext.tsx"() {
|
|
289
|
+
var init_cookieDiscovery = __esm({
|
|
290
|
+
"src/utils/cookieDiscovery.ts"() {
|
|
218
291
|
"use strict";
|
|
219
|
-
|
|
220
|
-
init_developerGuidance();
|
|
221
|
-
import_jsx_runtime = require("react/jsx-runtime");
|
|
222
|
-
CategoriesContext = React2.createContext(null);
|
|
292
|
+
init_cookieRegistry();
|
|
223
293
|
}
|
|
224
294
|
});
|
|
225
295
|
|
|
@@ -504,6 +574,497 @@ var init_cookieUtils = __esm({
|
|
|
504
574
|
}
|
|
505
575
|
});
|
|
506
576
|
|
|
577
|
+
// src/utils/developerGuidance.ts
|
|
578
|
+
function calculateComplianceScore(guidance) {
|
|
579
|
+
let score = 0;
|
|
580
|
+
const maxScore = 100;
|
|
581
|
+
if (!guidance.usingDefaults) score += 30;
|
|
582
|
+
const totalCategories = guidance.activeCategoriesInfo.length;
|
|
583
|
+
const toggleableCategories = guidance.activeCategoriesInfo.filter((c) => c.uiRequired).length;
|
|
584
|
+
if (totalCategories > 1) score += 20;
|
|
585
|
+
if (toggleableCategories >= 2 && toggleableCategories <= 4) score += 25;
|
|
586
|
+
const criticalWarnings = guidance.messages.filter((m) => m.severity === "error").length;
|
|
587
|
+
const warnings = guidance.messages.filter((m) => m.severity === "warning").length;
|
|
588
|
+
if (criticalWarnings === 0) score += 15;
|
|
589
|
+
if (warnings === 0) score += 10;
|
|
590
|
+
return Math.min(score, maxScore);
|
|
591
|
+
}
|
|
592
|
+
function analyzeDeveloperConfiguration(config) {
|
|
593
|
+
const guidance = {
|
|
594
|
+
warnings: [],
|
|
595
|
+
suggestions: [],
|
|
596
|
+
messages: [],
|
|
597
|
+
activeCategoriesInfo: [],
|
|
598
|
+
usingDefaults: !config,
|
|
599
|
+
complianceScore: 0
|
|
600
|
+
};
|
|
601
|
+
const addMessage = (severity, message, category, actionable = true) => {
|
|
602
|
+
const guidanceMessage = { severity, message, category, actionable };
|
|
603
|
+
guidance.messages.push(guidanceMessage);
|
|
604
|
+
if (severity === "warning" || severity === "error") {
|
|
605
|
+
guidance.warnings.push(message);
|
|
606
|
+
} else {
|
|
607
|
+
guidance.suggestions.push(message);
|
|
608
|
+
}
|
|
609
|
+
};
|
|
610
|
+
const finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
|
|
611
|
+
if (!config) {
|
|
612
|
+
addMessage(
|
|
613
|
+
"warning",
|
|
614
|
+
'LGPD-CONSENT: Nenhuma configura\xE7\xE3o de categorias especificada. Usando padr\xE3o: necessary + analytics. Para produ\xE7\xE3o, especifique explicitamente as categorias via prop "categories".',
|
|
615
|
+
"configuration"
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
guidance.activeCategoriesInfo.push({
|
|
619
|
+
id: "necessary",
|
|
620
|
+
name: "Cookies Necess\xE1rios",
|
|
621
|
+
description: "Essenciais para funcionamento b\xE1sico do site",
|
|
622
|
+
essential: true,
|
|
623
|
+
uiRequired: false,
|
|
624
|
+
cookies: COOKIE_PATTERNS_BY_CATEGORY["necessary"]
|
|
625
|
+
});
|
|
626
|
+
const enabled = finalConfig.enabledCategories || [];
|
|
627
|
+
const NAMES = {
|
|
628
|
+
analytics: { name: "Cookies Anal\xEDticos", description: "Medem uso e performance do site" },
|
|
629
|
+
functional: {
|
|
630
|
+
name: "Cookies Funcionais",
|
|
631
|
+
description: "Melhoram experi\xEAncia e funcionalidades"
|
|
632
|
+
},
|
|
633
|
+
marketing: { name: "Cookies de Marketing", description: "Publicidade direcionada e campanhas" },
|
|
634
|
+
social: { name: "Cookies de Redes Sociais", description: "Integra\xE7\xE3o com plataformas sociais" },
|
|
635
|
+
personalization: { name: "Cookies de Personaliza\xE7\xE3o", description: "Adapta\xE7\xE3o de conte\xFAdo" }
|
|
636
|
+
};
|
|
637
|
+
enabled.forEach((id) => {
|
|
638
|
+
const info = NAMES[id];
|
|
639
|
+
if (info) {
|
|
640
|
+
guidance.activeCategoriesInfo.push({
|
|
641
|
+
id,
|
|
642
|
+
name: info.name,
|
|
643
|
+
description: info.description,
|
|
644
|
+
essential: false,
|
|
645
|
+
uiRequired: true,
|
|
646
|
+
cookies: COOKIE_PATTERNS_BY_CATEGORY[id]
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
});
|
|
650
|
+
const custom = finalConfig.customCategories || [];
|
|
651
|
+
custom.forEach((cat) => {
|
|
652
|
+
if (!cat?.id || cat.id === "necessary") return;
|
|
653
|
+
guidance.activeCategoriesInfo.push({
|
|
654
|
+
id: cat.id,
|
|
655
|
+
name: cat.name,
|
|
656
|
+
description: cat.description,
|
|
657
|
+
essential: !!cat.essential,
|
|
658
|
+
uiRequired: !cat.essential,
|
|
659
|
+
cookies: cat.cookies
|
|
660
|
+
});
|
|
661
|
+
});
|
|
662
|
+
try {
|
|
663
|
+
const gt = globalThis;
|
|
664
|
+
const implied = (gt.__LGPD_REQUIRED_CATEGORIES__ || []).filter(Boolean);
|
|
665
|
+
implied.forEach((id) => {
|
|
666
|
+
if (!guidance.activeCategoriesInfo.find((c) => c.id === id)) {
|
|
667
|
+
const info = NAMES[id];
|
|
668
|
+
if (info) {
|
|
669
|
+
guidance.activeCategoriesInfo.push({
|
|
670
|
+
id,
|
|
671
|
+
name: info.name,
|
|
672
|
+
description: info.description,
|
|
673
|
+
essential: false,
|
|
674
|
+
uiRequired: true,
|
|
675
|
+
cookies: COOKIE_PATTERNS_BY_CATEGORY[id]
|
|
676
|
+
});
|
|
677
|
+
if (!enabled.includes(id)) {
|
|
678
|
+
addMessage(
|
|
679
|
+
"info",
|
|
680
|
+
`Integra\xE7\xF5es detectadas requerem a categoria '${id}'. Adicione-a em categories.enabledCategories.`,
|
|
681
|
+
"integration"
|
|
682
|
+
);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
} catch {
|
|
688
|
+
}
|
|
689
|
+
try {
|
|
690
|
+
const gt2 = globalThis;
|
|
691
|
+
const used = gt2.__LGPD_USED_INTEGRATIONS__ || [];
|
|
692
|
+
guidance.activeCategoriesInfo = guidance.activeCategoriesInfo.map((c) => {
|
|
693
|
+
const info = getCookiesInfoForCategory(c.id, used);
|
|
694
|
+
const names = Array.from(/* @__PURE__ */ new Set([...c.cookies || [], ...info.map((d) => d.name)]));
|
|
695
|
+
return { ...c, cookies: names };
|
|
696
|
+
});
|
|
697
|
+
} catch {
|
|
698
|
+
}
|
|
699
|
+
const totalToggleable = guidance.activeCategoriesInfo.filter((c) => c.uiRequired).length;
|
|
700
|
+
if (totalToggleable === 0) {
|
|
701
|
+
addMessage(
|
|
702
|
+
"info",
|
|
703
|
+
'Apenas cookies necess\xE1rios est\xE3o configurados. Para compliance LGPD, considere adicionar categorias como "analytics" ou "functional" conforme uso real.',
|
|
704
|
+
"compliance"
|
|
705
|
+
);
|
|
706
|
+
}
|
|
707
|
+
if (totalToggleable > 5) {
|
|
708
|
+
addMessage(
|
|
709
|
+
"warning",
|
|
710
|
+
`${totalToggleable} categorias opcionais detectadas. UI com muitas op\xE7\xF5es pode prejudicar a experi\xEAncia. Considere agrupar categorias similares.`,
|
|
711
|
+
"usability"
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
guidance.complianceScore = calculateComplianceScore(guidance);
|
|
715
|
+
return guidance;
|
|
716
|
+
}
|
|
717
|
+
function getComplianceScoreColor(score) {
|
|
718
|
+
if (score >= 80) return "#4caf50";
|
|
719
|
+
if (score >= 60) return "#ff9800";
|
|
720
|
+
return "#f44336";
|
|
721
|
+
}
|
|
722
|
+
function logComplianceScore(prefix, score) {
|
|
723
|
+
const color = getComplianceScoreColor(score);
|
|
724
|
+
console.log(
|
|
725
|
+
`%c${prefix} Score de Conformidade LGPD: ${score}/100`,
|
|
726
|
+
`color: ${color}; font-weight: bold; font-size: 14px;`
|
|
727
|
+
);
|
|
728
|
+
}
|
|
729
|
+
function logMessagesByType(prefix, messages, type, config) {
|
|
730
|
+
const filteredMessages = messages.filter((m) => m.severity === type);
|
|
731
|
+
if (filteredMessages.length === 0) return false;
|
|
732
|
+
const typeConfig = {
|
|
733
|
+
error: {
|
|
734
|
+
show: config.showWarnings,
|
|
735
|
+
title: "Erros Cr\xEDticos",
|
|
736
|
+
color: "#d32f2f",
|
|
737
|
+
method: console.error
|
|
738
|
+
},
|
|
739
|
+
warning: {
|
|
740
|
+
show: config.showWarnings,
|
|
741
|
+
title: "Avisos de Configura\xE7\xE3o",
|
|
742
|
+
color: "#f57c00",
|
|
743
|
+
method: console.warn
|
|
744
|
+
},
|
|
745
|
+
info: {
|
|
746
|
+
show: config.showSuggestions,
|
|
747
|
+
title: "Sugest\xF5es",
|
|
748
|
+
color: "#2196f3",
|
|
749
|
+
method: console.info
|
|
750
|
+
}
|
|
751
|
+
};
|
|
752
|
+
const typeSettings = typeConfig[type];
|
|
753
|
+
if (!typeSettings.show) return false;
|
|
754
|
+
console.group(
|
|
755
|
+
`%c${prefix} ${typeSettings.title}`,
|
|
756
|
+
`color: ${typeSettings.color}; font-weight: bold;`
|
|
757
|
+
);
|
|
758
|
+
filteredMessages.forEach(
|
|
759
|
+
(msg) => typeSettings.method(
|
|
760
|
+
`%c${prefix}%c ${msg.message}`,
|
|
761
|
+
`color: ${typeSettings.color};`,
|
|
762
|
+
"color: #333;"
|
|
763
|
+
)
|
|
764
|
+
);
|
|
765
|
+
console.groupEnd();
|
|
766
|
+
return true;
|
|
767
|
+
}
|
|
768
|
+
function getGuidanceHash(guidance) {
|
|
769
|
+
const sortedWarnings = [...guidance.warnings].sort((a, b) => a.localeCompare(b));
|
|
770
|
+
const sortedSuggestions = [...guidance.suggestions].sort(
|
|
771
|
+
(a, b) => a.localeCompare(b)
|
|
772
|
+
);
|
|
773
|
+
const sortedCategories = guidance.activeCategoriesInfo.map((c) => c.id).sort((a, b) => a.localeCompare(b));
|
|
774
|
+
return JSON.stringify({
|
|
775
|
+
warnings: sortedWarnings,
|
|
776
|
+
suggestions: sortedSuggestions,
|
|
777
|
+
categories: sortedCategories,
|
|
778
|
+
usingDefaults: guidance.usingDefaults
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
function logIntroOnce() {
|
|
782
|
+
if (SESSION_LOGGED.intro) return;
|
|
783
|
+
SESSION_LOGGED.intro = true;
|
|
784
|
+
console.log(
|
|
785
|
+
`%c\u{1F36A} LGPD-CONSENT %c- Sistema de Consentimento Ativo`,
|
|
786
|
+
"background: #4caf50; color: white; padding: 4px 8px; border-radius: 4px; font-weight: bold;",
|
|
787
|
+
"color: #2e7d32; font-weight: 500;"
|
|
788
|
+
);
|
|
789
|
+
}
|
|
790
|
+
function logServerSideIfAvailable(guidance) {
|
|
791
|
+
try {
|
|
792
|
+
const gt = globalThis;
|
|
793
|
+
if (gt.process?.stdout?.write) {
|
|
794
|
+
const prefix = "\x1B[36m[LGPD-CONSENT]\x1B[0m";
|
|
795
|
+
const warnings = guidance.warnings.length;
|
|
796
|
+
const suggestions = guidance.suggestions.length;
|
|
797
|
+
const stdout = gt.process.stdout;
|
|
798
|
+
if (warnings > 0 || suggestions > 0) {
|
|
799
|
+
stdout.write(`${prefix} \u{1F527} Config: ${warnings} avisos, ${suggestions} sugest\xF5es
|
|
800
|
+
`);
|
|
801
|
+
if (warnings > 0) {
|
|
802
|
+
guidance.warnings.forEach((w) => {
|
|
803
|
+
stdout.write(`${prefix} \x1B[33m\u26A0\uFE0F ${w}\x1B[0m
|
|
804
|
+
`);
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
if (suggestions > 0) {
|
|
808
|
+
guidance.suggestions.forEach((s) => {
|
|
809
|
+
stdout.write(`${prefix} \x1B[36m\u{1F4A1} ${s}\x1B[0m
|
|
810
|
+
`);
|
|
811
|
+
});
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
} catch {
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
function logDeveloperGuidance(guidance, disableGuidanceProp, config) {
|
|
819
|
+
const gt = globalThis;
|
|
820
|
+
const nodeEnv = typeof gt.process !== "undefined" ? gt.process?.env?.NODE_ENV : void 0;
|
|
821
|
+
const isProd = nodeEnv === "production" || gt.__LGPD_PRODUCTION__ === true;
|
|
822
|
+
if (isProd || disableGuidanceProp) return;
|
|
823
|
+
const guidanceHash = getGuidanceHash(guidance);
|
|
824
|
+
if (GUIDANCE_CACHE.has(guidanceHash)) return;
|
|
825
|
+
GUIDANCE_CACHE.add(guidanceHash);
|
|
826
|
+
logServerSideIfAvailable(guidance);
|
|
827
|
+
const guidanceConfig = {
|
|
828
|
+
showWarnings: true,
|
|
829
|
+
showSuggestions: true,
|
|
830
|
+
showCategoriesTable: true,
|
|
831
|
+
showBestPractices: true,
|
|
832
|
+
showComplianceScore: true,
|
|
833
|
+
minimumSeverity: "info",
|
|
834
|
+
...config
|
|
835
|
+
};
|
|
836
|
+
if (guidanceConfig.messageProcessor) {
|
|
837
|
+
guidanceConfig.messageProcessor(guidance.messages);
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
840
|
+
logIntroOnce();
|
|
841
|
+
const PREFIX = "\u{1F36A}";
|
|
842
|
+
let hasImportantInfo = false;
|
|
843
|
+
const filteredMessages = guidance.messages.filter((msg) => {
|
|
844
|
+
const severityLevels = { info: 0, warning: 1, error: 2 };
|
|
845
|
+
const minLevel = severityLevels[guidanceConfig.minimumSeverity || "info"];
|
|
846
|
+
const msgLevel = severityLevels[msg.severity];
|
|
847
|
+
return msgLevel >= minLevel;
|
|
848
|
+
});
|
|
849
|
+
hasImportantInfo = logMessagesByType(PREFIX, filteredMessages, "error", guidanceConfig) || hasImportantInfo;
|
|
850
|
+
hasImportantInfo = logMessagesByType(PREFIX, filteredMessages, "warning", guidanceConfig) || hasImportantInfo;
|
|
851
|
+
if (hasImportantInfo || guidance.usingDefaults) {
|
|
852
|
+
hasImportantInfo = logMessagesByType(PREFIX, filteredMessages, "info", guidanceConfig) || hasImportantInfo;
|
|
853
|
+
}
|
|
854
|
+
if (guidanceConfig.showComplianceScore && guidance.complianceScore !== void 0) {
|
|
855
|
+
logComplianceScore(PREFIX, guidance.complianceScore);
|
|
856
|
+
}
|
|
857
|
+
if (guidanceConfig.showCategoriesTable && (hasImportantInfo || guidance.usingDefaults)) {
|
|
858
|
+
const rows = guidance.activeCategoriesInfo.map((cat) => ({
|
|
859
|
+
"\u{1F4CA} Categoria": cat.id,
|
|
860
|
+
"\u{1F3F7}\uFE0F Nome": cat.name,
|
|
861
|
+
"\u{1F39B}\uFE0F UI": cat.uiRequired ? "\u2705" : "\u{1F512}",
|
|
862
|
+
"\u{1F36A} Cookies": (cat.cookies || []).slice(0, 3).join(", ") + (cat.cookies && cat.cookies.length > 3 ? ` (+${cat.cookies.length - 3})` : "")
|
|
863
|
+
}));
|
|
864
|
+
if (typeof console.table === "function") {
|
|
865
|
+
console.group(`%c${PREFIX} Configura\xE7\xE3o Ativa`, "color: #4caf50; font-weight: bold;");
|
|
866
|
+
console.table(rows);
|
|
867
|
+
console.groupEnd();
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
if (!SESSION_LOGGED.bestPractices && hasImportantInfo) {
|
|
871
|
+
SESSION_LOGGED.bestPractices = true;
|
|
872
|
+
console.group(`%c${PREFIX} LGPD - Boas Pr\xE1ticas`, "color: #9c27b0; font-weight: bold;");
|
|
873
|
+
console.info(
|
|
874
|
+
`%c${PREFIX}%c Necessary: sempre ativo \u2022 Demais: opt-out por padr\xE3o`,
|
|
875
|
+
"color: #9c27b0;",
|
|
876
|
+
"color: #7b1fa2;"
|
|
877
|
+
);
|
|
878
|
+
console.info(
|
|
879
|
+
`%c${PREFIX}%c Documente pol\xEDticas claras por categoria`,
|
|
880
|
+
"color: #9c27b0;",
|
|
881
|
+
"color: #7b1fa2;"
|
|
882
|
+
);
|
|
883
|
+
console.info(
|
|
884
|
+
`%c${PREFIX}%c Registre consentimento com data/hora/origem`,
|
|
885
|
+
"color: #9c27b0;",
|
|
886
|
+
"color: #7b1fa2;"
|
|
887
|
+
);
|
|
888
|
+
console.groupEnd();
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
function useDeveloperGuidance(config, disableGuidanceProp, guidanceConfig) {
|
|
892
|
+
const guidance = import_react.default.useMemo(() => analyzeDeveloperConfiguration(config), [config]);
|
|
893
|
+
import_react.default.useEffect(() => {
|
|
894
|
+
if (!disableGuidanceProp) logDeveloperGuidance(guidance, disableGuidanceProp, guidanceConfig);
|
|
895
|
+
}, [guidance, disableGuidanceProp, guidanceConfig]);
|
|
896
|
+
return guidance;
|
|
897
|
+
}
|
|
898
|
+
var import_react, DEFAULT_PROJECT_CATEGORIES, GUIDANCE_CACHE, SESSION_LOGGED, GUIDANCE_PRESETS;
|
|
899
|
+
var init_developerGuidance = __esm({
|
|
900
|
+
"src/utils/developerGuidance.ts"() {
|
|
901
|
+
"use strict";
|
|
902
|
+
import_react = __toESM(require("react"), 1);
|
|
903
|
+
init_cookieRegistry();
|
|
904
|
+
DEFAULT_PROJECT_CATEGORIES = {
|
|
905
|
+
enabledCategories: ["analytics"]
|
|
906
|
+
};
|
|
907
|
+
GUIDANCE_CACHE = /* @__PURE__ */ new Set();
|
|
908
|
+
SESSION_LOGGED = {
|
|
909
|
+
intro: false,
|
|
910
|
+
bestPractices: false
|
|
911
|
+
};
|
|
912
|
+
GUIDANCE_PRESETS = {
|
|
913
|
+
/** Configuração completa para desenvolvimento */
|
|
914
|
+
development: {
|
|
915
|
+
showWarnings: true,
|
|
916
|
+
showSuggestions: true,
|
|
917
|
+
showCategoriesTable: true,
|
|
918
|
+
showBestPractices: true,
|
|
919
|
+
showComplianceScore: true,
|
|
920
|
+
minimumSeverity: "info"
|
|
921
|
+
},
|
|
922
|
+
/** Configuração silenciosa para produção */
|
|
923
|
+
production: {
|
|
924
|
+
showWarnings: false,
|
|
925
|
+
showSuggestions: false,
|
|
926
|
+
showCategoriesTable: false,
|
|
927
|
+
showBestPractices: false,
|
|
928
|
+
showComplianceScore: false,
|
|
929
|
+
minimumSeverity: "error"
|
|
930
|
+
},
|
|
931
|
+
/** Apenas erros críticos */
|
|
932
|
+
minimal: {
|
|
933
|
+
showWarnings: true,
|
|
934
|
+
showSuggestions: false,
|
|
935
|
+
showCategoriesTable: false,
|
|
936
|
+
showBestPractices: false,
|
|
937
|
+
showComplianceScore: false,
|
|
938
|
+
minimumSeverity: "error"
|
|
939
|
+
},
|
|
940
|
+
/** Focado em conformidade LGPD */
|
|
941
|
+
compliance: {
|
|
942
|
+
showWarnings: true,
|
|
943
|
+
showSuggestions: true,
|
|
944
|
+
showCategoriesTable: true,
|
|
945
|
+
showBestPractices: true,
|
|
946
|
+
showComplianceScore: true,
|
|
947
|
+
minimumSeverity: "warning"
|
|
948
|
+
}
|
|
949
|
+
};
|
|
950
|
+
}
|
|
951
|
+
});
|
|
952
|
+
|
|
953
|
+
// src/context/CategoriesContext.tsx
|
|
954
|
+
function CategoriesProvider({
|
|
955
|
+
children,
|
|
956
|
+
config,
|
|
957
|
+
disableDeveloperGuidance,
|
|
958
|
+
disableDiscoveryLog
|
|
959
|
+
}) {
|
|
960
|
+
const [impliedVersion, setImpliedVersion] = React2.useState(0);
|
|
961
|
+
React2.useEffect(() => {
|
|
962
|
+
const handler = () => setImpliedVersion((v) => v + 1);
|
|
963
|
+
if (typeof window !== "undefined" && typeof window.addEventListener === "function") {
|
|
964
|
+
window.addEventListener("lgpd:requiredCategories", handler);
|
|
965
|
+
return () => window.removeEventListener("lgpd:requiredCategories", handler);
|
|
966
|
+
}
|
|
967
|
+
return () => {
|
|
968
|
+
};
|
|
969
|
+
}, []);
|
|
970
|
+
const contextValue = React2.useMemo(() => {
|
|
971
|
+
const finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
|
|
972
|
+
const guidance = analyzeDeveloperConfiguration(config);
|
|
973
|
+
const toggleableCategories = guidance.activeCategoriesInfo.filter((cat) => cat.uiRequired);
|
|
974
|
+
return {
|
|
975
|
+
config: finalConfig,
|
|
976
|
+
guidance,
|
|
977
|
+
toggleableCategories,
|
|
978
|
+
allCategories: guidance.activeCategoriesInfo
|
|
979
|
+
};
|
|
980
|
+
}, [config, impliedVersion]);
|
|
981
|
+
React2.useEffect(() => {
|
|
982
|
+
logDeveloperGuidance(contextValue.guidance, disableDeveloperGuidance);
|
|
983
|
+
}, [contextValue.guidance, disableDeveloperGuidance]);
|
|
984
|
+
React2.useEffect(() => {
|
|
985
|
+
try {
|
|
986
|
+
const gt = globalThis;
|
|
987
|
+
const env = typeof gt.process !== "undefined" ? gt.process?.env?.NODE_ENV : void 0;
|
|
988
|
+
const isDev = env === "development";
|
|
989
|
+
if (!isDev || gt.__LGPD_DISCOVERY_LOGGED__ === true || disableDiscoveryLog) return;
|
|
990
|
+
const discovered = discoverRuntimeCookies();
|
|
991
|
+
const consentName = detectConsentCookieName() || DEFAULT_COOKIE_OPTS.name;
|
|
992
|
+
const PREFIX = "[\u{1F36A} LGPD-CONSENT]";
|
|
993
|
+
if (typeof console !== "undefined") {
|
|
994
|
+
try {
|
|
995
|
+
console.group(`${PREFIX} \u{1F50E} Descoberta de cookies (experimental)`);
|
|
996
|
+
const names = Array.from(
|
|
997
|
+
new Set([consentName, ...discovered.map((d) => d.name)].filter(Boolean))
|
|
998
|
+
);
|
|
999
|
+
const rows = names.map((n) => ({ Cookie: n }));
|
|
1000
|
+
if (typeof console.table === "function") console.table(rows);
|
|
1001
|
+
else console.log(rows);
|
|
1002
|
+
console.info(
|
|
1003
|
+
`${PREFIX} \u2139\uFE0F Estes nomes s\xE3o detectados em tempo de execu\xE7\xE3o. Ajuste ou categorize via APIs de override se necess\xE1rio.`
|
|
1004
|
+
);
|
|
1005
|
+
console.groupEnd();
|
|
1006
|
+
} catch {
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
gt.__LGPD_DISCOVERY_LOGGED__ = true;
|
|
1010
|
+
} catch {
|
|
1011
|
+
}
|
|
1012
|
+
}, [disableDiscoveryLog]);
|
|
1013
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CategoriesContext.Provider, { value: contextValue, children });
|
|
1014
|
+
}
|
|
1015
|
+
function useCategories() {
|
|
1016
|
+
const context = React2.useContext(CategoriesContext);
|
|
1017
|
+
if (!context) {
|
|
1018
|
+
throw new Error(
|
|
1019
|
+
"useCategories deve ser usado dentro de CategoriesProvider. Certifique-se de que o ConsentProvider est\xE1 envolvendo seu componente."
|
|
1020
|
+
);
|
|
1021
|
+
}
|
|
1022
|
+
return context;
|
|
1023
|
+
}
|
|
1024
|
+
function useCategoryStatus(categoryId) {
|
|
1025
|
+
const { allCategories } = useCategories();
|
|
1026
|
+
const category = allCategories.find((cat) => cat.id === categoryId);
|
|
1027
|
+
return {
|
|
1028
|
+
isActive: !!category,
|
|
1029
|
+
isEssential: category?.essential || false,
|
|
1030
|
+
needsToggle: category?.uiRequired || false,
|
|
1031
|
+
name: category?.name,
|
|
1032
|
+
description: category?.description
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
1035
|
+
var React2, import_jsx_runtime, CategoriesContext;
|
|
1036
|
+
var init_CategoriesContext = __esm({
|
|
1037
|
+
"src/context/CategoriesContext.tsx"() {
|
|
1038
|
+
"use strict";
|
|
1039
|
+
React2 = __toESM(require("react"), 1);
|
|
1040
|
+
init_cookieDiscovery();
|
|
1041
|
+
init_cookieUtils();
|
|
1042
|
+
init_developerGuidance();
|
|
1043
|
+
import_jsx_runtime = require("react/jsx-runtime");
|
|
1044
|
+
CategoriesContext = React2.createContext(null);
|
|
1045
|
+
}
|
|
1046
|
+
});
|
|
1047
|
+
|
|
1048
|
+
// src/context/DesignContext.tsx
|
|
1049
|
+
function DesignProvider({
|
|
1050
|
+
tokens,
|
|
1051
|
+
children
|
|
1052
|
+
}) {
|
|
1053
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DesignContext.Provider, { value: tokens, children });
|
|
1054
|
+
}
|
|
1055
|
+
function useDesignTokens() {
|
|
1056
|
+
return React3.useContext(DesignContext);
|
|
1057
|
+
}
|
|
1058
|
+
var React3, import_jsx_runtime2, DesignContext;
|
|
1059
|
+
var init_DesignContext = __esm({
|
|
1060
|
+
"src/context/DesignContext.tsx"() {
|
|
1061
|
+
"use strict";
|
|
1062
|
+
React3 = __toESM(require("react"), 1);
|
|
1063
|
+
import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1064
|
+
DesignContext = React3.createContext(void 0);
|
|
1065
|
+
}
|
|
1066
|
+
});
|
|
1067
|
+
|
|
507
1068
|
// src/utils/categoryUtils.ts
|
|
508
1069
|
function createProjectPreferences(config, defaultValue = false) {
|
|
509
1070
|
const preferences = {
|
|
@@ -516,8 +1077,8 @@ function createProjectPreferences(config, defaultValue = false) {
|
|
|
516
1077
|
preferences[category] = defaultValue;
|
|
517
1078
|
}
|
|
518
1079
|
});
|
|
519
|
-
const
|
|
520
|
-
|
|
1080
|
+
const customCategories = config?.customCategories || [];
|
|
1081
|
+
customCategories.forEach((cat) => {
|
|
521
1082
|
if (cat.id && cat.id !== "necessary") {
|
|
522
1083
|
preferences[cat.id] = defaultValue;
|
|
523
1084
|
}
|
|
@@ -535,8 +1096,8 @@ function validateProjectPreferences(preferences, config) {
|
|
|
535
1096
|
validPreferences[category] = preferences[category];
|
|
536
1097
|
}
|
|
537
1098
|
});
|
|
538
|
-
const
|
|
539
|
-
|
|
1099
|
+
const customCategories = config?.customCategories || [];
|
|
1100
|
+
customCategories.forEach((cat) => {
|
|
540
1101
|
const id = cat.id;
|
|
541
1102
|
if (id && id !== "necessary" && preferences[id] !== void 0) {
|
|
542
1103
|
validPreferences[id] = preferences[id];
|
|
@@ -559,8 +1120,8 @@ function getAllProjectCategories(config) {
|
|
|
559
1120
|
allCategories.push(getDefaultCategoryDefinition(category));
|
|
560
1121
|
}
|
|
561
1122
|
});
|
|
562
|
-
const
|
|
563
|
-
|
|
1123
|
+
const customCategories = config?.customCategories || [];
|
|
1124
|
+
customCategories.forEach((cat) => {
|
|
564
1125
|
if (cat.id && cat.id !== "necessary") {
|
|
565
1126
|
allCategories.push({ ...cat, essential: !!cat.essential });
|
|
566
1127
|
}
|
|
@@ -597,40 +1158,20 @@ function getDefaultCategoryDefinition(category) {
|
|
|
597
1158
|
id: "social",
|
|
598
1159
|
name: "Redes Sociais",
|
|
599
1160
|
description: "Cookies para integra\xE7\xE3o com redes sociais e compartilhamento",
|
|
600
|
-
essential: false
|
|
601
|
-
},
|
|
602
|
-
personalization: {
|
|
603
|
-
id: "personalization",
|
|
604
|
-
name: "Personaliza\xE7\xE3o",
|
|
605
|
-
description: "Cookies para personaliza\xE7\xE3o de conte\xFAdo e experi\xEAncia",
|
|
606
|
-
essential: false
|
|
607
|
-
}
|
|
608
|
-
};
|
|
609
|
-
return definitions[category];
|
|
610
|
-
}
|
|
611
|
-
var init_categoryUtils = __esm({
|
|
612
|
-
"src/utils/categoryUtils.ts"() {
|
|
613
|
-
"use strict";
|
|
614
|
-
}
|
|
615
|
-
});
|
|
616
|
-
|
|
617
|
-
// src/context/DesignContext.tsx
|
|
618
|
-
function DesignProvider({
|
|
619
|
-
tokens,
|
|
620
|
-
children
|
|
621
|
-
}) {
|
|
622
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DesignContext.Provider, { value: tokens, children });
|
|
623
|
-
}
|
|
624
|
-
function useDesignTokens() {
|
|
625
|
-
return React3.useContext(DesignContext);
|
|
1161
|
+
essential: false
|
|
1162
|
+
},
|
|
1163
|
+
personalization: {
|
|
1164
|
+
id: "personalization",
|
|
1165
|
+
name: "Personaliza\xE7\xE3o",
|
|
1166
|
+
description: "Cookies para personaliza\xE7\xE3o de conte\xFAdo e experi\xEAncia",
|
|
1167
|
+
essential: false
|
|
1168
|
+
}
|
|
1169
|
+
};
|
|
1170
|
+
return definitions[category];
|
|
626
1171
|
}
|
|
627
|
-
var
|
|
628
|
-
|
|
629
|
-
"src/context/DesignContext.tsx"() {
|
|
1172
|
+
var init_categoryUtils = __esm({
|
|
1173
|
+
"src/utils/categoryUtils.ts"() {
|
|
630
1174
|
"use strict";
|
|
631
|
-
React3 = __toESM(require("react"), 1);
|
|
632
|
-
import_jsx_runtime2 = require("react/jsx-runtime");
|
|
633
|
-
DesignContext = React3.createContext(void 0);
|
|
634
1175
|
}
|
|
635
1176
|
});
|
|
636
1177
|
|
|
@@ -708,6 +1249,7 @@ var init_Branding = __esm({
|
|
|
708
1249
|
// src/components/CookieBanner.tsx
|
|
709
1250
|
function CookieBanner({
|
|
710
1251
|
policyLinkUrl,
|
|
1252
|
+
termsLinkUrl,
|
|
711
1253
|
debug,
|
|
712
1254
|
blocking = true,
|
|
713
1255
|
hideBranding = false,
|
|
@@ -727,15 +1269,15 @@ function CookieBanner({
|
|
|
727
1269
|
hideBranding
|
|
728
1270
|
});
|
|
729
1271
|
if (!open) return null;
|
|
730
|
-
const bannerStyle = {
|
|
1272
|
+
const bannerStyle = (theme) => ({
|
|
731
1273
|
p: designTokens?.spacing?.padding?.banner ?? 2,
|
|
732
1274
|
maxWidth: 720,
|
|
733
1275
|
mx: "auto",
|
|
734
|
-
backgroundColor: designTokens?.colors?.background,
|
|
735
|
-
color: designTokens?.colors?.text,
|
|
1276
|
+
backgroundColor: designTokens?.colors?.background ?? theme.palette.background?.paper,
|
|
1277
|
+
color: designTokens?.colors?.text ?? theme.palette.text?.primary,
|
|
736
1278
|
borderRadius: designTokens?.spacing?.borderRadius?.banner,
|
|
737
1279
|
fontFamily: designTokens?.typography?.fontFamily
|
|
738
|
-
};
|
|
1280
|
+
});
|
|
739
1281
|
const bannerContent = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_Paper.default, { elevation: 3, sx: bannerStyle, ...PaperProps, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_Stack.default, { spacing: 1, children: [
|
|
740
1282
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_Typography2.default, { variant: "body2", sx: { fontSize: designTokens?.typography?.fontSize?.banner }, children: [
|
|
741
1283
|
texts.bannerMessage,
|
|
@@ -801,27 +1343,51 @@ function CookieBanner({
|
|
|
801
1343
|
width: designTokens?.layout?.width?.desktop ?? "100%",
|
|
802
1344
|
p: 2
|
|
803
1345
|
};
|
|
804
|
-
let backdropColor = "rgba(0, 0, 0, 0.4)";
|
|
805
1346
|
const backdropToken = designTokens?.layout?.backdrop;
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
1347
|
+
const resolveBackdropColor = (theme) => {
|
|
1348
|
+
if (backdropToken === false) return "transparent";
|
|
1349
|
+
if (typeof backdropToken === "string") {
|
|
1350
|
+
if (backdropToken.toLowerCase() === "auto") {
|
|
1351
|
+
const isDark2 = theme?.palette?.mode === "dark";
|
|
1352
|
+
return isDark2 ? "rgba(255, 255, 255, 0.12)" : "rgba(0, 0, 0, 0.4)";
|
|
1353
|
+
}
|
|
1354
|
+
return backdropToken;
|
|
1355
|
+
}
|
|
1356
|
+
const isDark = theme?.palette?.mode === "dark";
|
|
1357
|
+
return isDark ? "rgba(255, 255, 255, 0.12)" : "rgba(0, 0, 0, 0.4)";
|
|
1358
|
+
};
|
|
1359
|
+
const isSafeRoute = (() => {
|
|
1360
|
+
try {
|
|
1361
|
+
if (typeof window === "undefined") return false;
|
|
1362
|
+
const current = new URL(window.location.href);
|
|
1363
|
+
const safeUrls = [policyLinkUrl, termsLinkUrl].filter(Boolean);
|
|
1364
|
+
return safeUrls.some((u) => {
|
|
1365
|
+
try {
|
|
1366
|
+
const target = new URL(u, current.origin);
|
|
1367
|
+
return target.pathname === current.pathname;
|
|
1368
|
+
} catch {
|
|
1369
|
+
return false;
|
|
1370
|
+
}
|
|
1371
|
+
});
|
|
1372
|
+
} catch {
|
|
1373
|
+
return false;
|
|
1374
|
+
}
|
|
1375
|
+
})();
|
|
1376
|
+
const effectiveBlocking = blocking && !isSafeRoute;
|
|
1377
|
+
if (effectiveBlocking) {
|
|
812
1378
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
813
1379
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
814
1380
|
import_Box.default,
|
|
815
1381
|
{
|
|
816
|
-
sx: {
|
|
1382
|
+
sx: (theme) => ({
|
|
817
1383
|
position: "fixed",
|
|
818
1384
|
top: 0,
|
|
819
1385
|
left: 0,
|
|
820
1386
|
right: 0,
|
|
821
1387
|
bottom: 0,
|
|
822
|
-
backgroundColor:
|
|
1388
|
+
backgroundColor: resolveBackdropColor(theme),
|
|
823
1389
|
zIndex: 1299
|
|
824
|
-
}
|
|
1390
|
+
})
|
|
825
1391
|
}
|
|
826
1392
|
),
|
|
827
1393
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_Box.default, { sx: positionStyle, children: bannerContent })
|
|
@@ -1053,7 +1619,9 @@ function ConsentProvider({
|
|
|
1053
1619
|
onPreferencesSaved,
|
|
1054
1620
|
cookie: cookieOpts,
|
|
1055
1621
|
disableDeveloperGuidance,
|
|
1056
|
-
|
|
1622
|
+
guidanceConfig,
|
|
1623
|
+
children,
|
|
1624
|
+
disableDiscoveryLog
|
|
1057
1625
|
}) {
|
|
1058
1626
|
const texts = React4.useMemo(() => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }), [textsProp]);
|
|
1059
1627
|
const cookie = React4.useMemo(
|
|
@@ -1065,7 +1633,15 @@ function ConsentProvider({
|
|
|
1065
1633
|
if (categories) return categories;
|
|
1066
1634
|
return DEFAULT_PROJECT_CATEGORIES;
|
|
1067
1635
|
}, [categories]);
|
|
1068
|
-
useDeveloperGuidance(finalCategoriesConfig, disableDeveloperGuidance);
|
|
1636
|
+
useDeveloperGuidance(finalCategoriesConfig, disableDeveloperGuidance, guidanceConfig);
|
|
1637
|
+
React4.useEffect(() => {
|
|
1638
|
+
const isProd = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
1639
|
+
if (!isProd && PreferencesModalComponent) {
|
|
1640
|
+
console.info(
|
|
1641
|
+
"[LGPD-CONSENT] Dica: seu PreferencesModal \xE9 customizado. Garanta exibir os detalhes dos cookies por categoria (nome, finalidade, dura\xE7\xE3o) usando as APIs setCookieCatalogOverrides / setCookieCategoryOverrides e getCookiesInfoForCategory. Consulte QUICKSTART e INTEGRACOES.md."
|
|
1642
|
+
);
|
|
1643
|
+
}
|
|
1644
|
+
}, [PreferencesModalComponent]);
|
|
1069
1645
|
const boot = React4.useMemo(() => {
|
|
1070
1646
|
if (initialState) return { ...initialState, isModalOpen: false };
|
|
1071
1647
|
return createFullConsentState(
|
|
@@ -1149,6 +1725,7 @@ function ConsentProvider({
|
|
|
1149
1725
|
{
|
|
1150
1726
|
config: finalCategoriesConfig,
|
|
1151
1727
|
disableDeveloperGuidance,
|
|
1728
|
+
disableDiscoveryLog,
|
|
1152
1729
|
children: [
|
|
1153
1730
|
children,
|
|
1154
1731
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(React4.Suspense, { fallback: null, children: PreferencesModalComponent ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
@@ -1238,19 +1815,19 @@ function useConsentTextsInternal() {
|
|
|
1238
1815
|
function useConsentHydrationInternal() {
|
|
1239
1816
|
return React4.useContext(HydrationCtx);
|
|
1240
1817
|
}
|
|
1241
|
-
var
|
|
1818
|
+
var import_styles2, React4, import_jsx_runtime6, PreferencesModal, DEFAULT_TEXTS, StateCtx, ActionsCtx, TextsCtx, HydrationCtx, defaultTexts;
|
|
1242
1819
|
var init_ConsentContext = __esm({
|
|
1243
1820
|
"src/context/ConsentContext.tsx"() {
|
|
1244
1821
|
"use strict";
|
|
1245
|
-
React4 = __toESM(require("react"), 1);
|
|
1246
1822
|
import_styles2 = require("@mui/material/styles");
|
|
1247
|
-
|
|
1823
|
+
React4 = __toESM(require("react"), 1);
|
|
1248
1824
|
init_categoryUtils();
|
|
1249
|
-
|
|
1250
|
-
init_DesignContext();
|
|
1251
|
-
init_developerGuidance();
|
|
1825
|
+
init_cookieUtils();
|
|
1252
1826
|
init_useConsent();
|
|
1827
|
+
init_developerGuidance();
|
|
1253
1828
|
init_logger();
|
|
1829
|
+
init_CategoriesContext();
|
|
1830
|
+
init_DesignContext();
|
|
1254
1831
|
init_CookieBanner();
|
|
1255
1832
|
init_FloatingPreferencesButton();
|
|
1256
1833
|
import_jsx_runtime6 = require("react/jsx-runtime");
|
|
@@ -1327,25 +1904,30 @@ function useConsentTexts() {
|
|
|
1327
1904
|
function useConsentHydration() {
|
|
1328
1905
|
return useConsentHydrationInternal();
|
|
1329
1906
|
}
|
|
1907
|
+
function _registerGlobalOpenPreferences(openPreferences) {
|
|
1908
|
+
globalOpenPreferences = openPreferences;
|
|
1909
|
+
}
|
|
1910
|
+
function _unregisterGlobalOpenPreferences() {
|
|
1911
|
+
globalOpenPreferences = null;
|
|
1912
|
+
}
|
|
1330
1913
|
function useOpenPreferencesModal() {
|
|
1331
|
-
const
|
|
1332
|
-
|
|
1914
|
+
const actions = useConsentActionsInternal();
|
|
1915
|
+
if (!actions) {
|
|
1916
|
+
throw new Error(
|
|
1917
|
+
"[LGPD-CONSENT] useOpenPreferencesModal deve ser usado dentro do ConsentProvider. Envolva seu componente com <ConsentProvider>."
|
|
1918
|
+
);
|
|
1919
|
+
}
|
|
1920
|
+
return actions.openPreferences;
|
|
1333
1921
|
}
|
|
1334
1922
|
function openPreferencesModal() {
|
|
1335
1923
|
if (globalOpenPreferences) {
|
|
1336
1924
|
globalOpenPreferences();
|
|
1337
1925
|
} else {
|
|
1338
1926
|
logger.warn(
|
|
1339
|
-
"openPreferencesModal
|
|
1927
|
+
"openPreferencesModal called but no ConsentProvider is mounted. Make sure ConsentProvider is rendered before calling this function."
|
|
1340
1928
|
);
|
|
1341
1929
|
}
|
|
1342
1930
|
}
|
|
1343
|
-
function _registerGlobalOpenPreferences(openPreferences) {
|
|
1344
|
-
globalOpenPreferences = openPreferences;
|
|
1345
|
-
}
|
|
1346
|
-
function _unregisterGlobalOpenPreferences() {
|
|
1347
|
-
globalOpenPreferences = null;
|
|
1348
|
-
}
|
|
1349
1931
|
var globalOpenPreferences;
|
|
1350
1932
|
var init_useConsent = __esm({
|
|
1351
1933
|
"src/hooks/useConsent.ts"() {
|
|
@@ -1368,7 +1950,7 @@ function PreferencesModal2({
|
|
|
1368
1950
|
const { preferences, setPreferences, closePreferences, isModalOpen } = useConsent();
|
|
1369
1951
|
const texts = useConsentTexts();
|
|
1370
1952
|
const designTokens = useDesignTokens();
|
|
1371
|
-
const { toggleableCategories } = useCategories();
|
|
1953
|
+
const { toggleableCategories, allCategories } = useCategories();
|
|
1372
1954
|
const [tempPreferences, setTempPreferences] = (0, import_react2.useState)(() => {
|
|
1373
1955
|
const initialPrefs = { necessary: true };
|
|
1374
1956
|
toggleableCategories.forEach((category) => {
|
|
@@ -1393,43 +1975,126 @@ function PreferencesModal2({
|
|
|
1393
1975
|
setTempPreferences(preferences);
|
|
1394
1976
|
closePreferences();
|
|
1395
1977
|
};
|
|
1978
|
+
const modalTitleSx = (theme) => ({
|
|
1979
|
+
fontSize: designTokens?.typography?.fontSize?.modal ?? void 0,
|
|
1980
|
+
color: designTokens?.colors?.text ?? theme.palette.text.primary
|
|
1981
|
+
});
|
|
1982
|
+
const modalContentSx = (theme) => ({
|
|
1983
|
+
p: designTokens?.spacing?.padding?.modal ?? void 0,
|
|
1984
|
+
backgroundColor: designTokens?.colors?.background ?? theme.palette.background.paper,
|
|
1985
|
+
color: designTokens?.colors?.text ?? theme.palette.text.primary
|
|
1986
|
+
});
|
|
1396
1987
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_Dialog.default, { "aria-labelledby": "cookie-pref-title", open, onClose: handleCancel, ...DialogProps2, children: [
|
|
1397
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1398
|
-
|
|
1399
|
-
{
|
|
1400
|
-
id: "cookie-pref-title",
|
|
1401
|
-
sx: { fontSize: designTokens?.typography?.fontSize?.modal ?? void 0 },
|
|
1402
|
-
children: texts.modalTitle
|
|
1403
|
-
}
|
|
1404
|
-
),
|
|
1405
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_DialogContent.default, { dividers: true, sx: { p: designTokens?.spacing?.padding?.modal ?? void 0 }, children: [
|
|
1988
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_DialogTitle.default, { id: "cookie-pref-title", sx: modalTitleSx, children: texts.modalTitle }),
|
|
1989
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_DialogContent.default, { dividers: true, sx: modalContentSx, children: [
|
|
1406
1990
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1407
1991
|
import_Typography3.default,
|
|
1408
1992
|
{
|
|
1409
1993
|
variant: "body2",
|
|
1410
|
-
sx:
|
|
1994
|
+
sx: (theme) => ({
|
|
1995
|
+
mb: 2,
|
|
1996
|
+
fontSize: designTokens?.typography?.fontSize?.modal ?? void 0,
|
|
1997
|
+
color: designTokens?.colors?.text ?? theme.palette.text.primary
|
|
1998
|
+
}),
|
|
1411
1999
|
children: texts.modalIntro
|
|
1412
2000
|
}
|
|
1413
2001
|
),
|
|
1414
2002
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_FormGroup.default, { children: [
|
|
1415
|
-
toggleableCategories.map((category) =>
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
2003
|
+
toggleableCategories.map((category) => {
|
|
2004
|
+
const full = allCategories.find((c) => c.id === category.id);
|
|
2005
|
+
const namesFromGuidance = full?.cookies ?? [];
|
|
2006
|
+
const used = globalThis.__LGPD_USED_INTEGRATIONS__ || [];
|
|
2007
|
+
const descriptors = getCookiesInfoForCategory(category.id, used);
|
|
2008
|
+
const enrichedDescriptors = descriptors.map((desc) => {
|
|
2009
|
+
if (desc.purpose && desc.duration && desc.provider) {
|
|
2010
|
+
return desc;
|
|
2011
|
+
}
|
|
2012
|
+
return {
|
|
2013
|
+
name: desc.name,
|
|
2014
|
+
purpose: desc.purpose || "-",
|
|
2015
|
+
duration: desc.duration || "-",
|
|
2016
|
+
provider: desc.provider || "-"
|
|
2017
|
+
};
|
|
2018
|
+
});
|
|
2019
|
+
const merged = [
|
|
2020
|
+
...enrichedDescriptors,
|
|
2021
|
+
...namesFromGuidance.filter((n) => !enrichedDescriptors.find((d) => d.name === n)).map((n) => ({ name: n, purpose: "-", duration: "-", provider: "-" }))
|
|
2022
|
+
];
|
|
2023
|
+
let mergedFinal = merged;
|
|
2024
|
+
try {
|
|
2025
|
+
if (merged.length === 0) {
|
|
2026
|
+
const gmap = globalThis.__LGPD_INTEGRATIONS_MAP__ || {};
|
|
2027
|
+
const scriptRows = Object.entries(gmap).filter(([, cat]) => cat === category.id).map(([id]) => ({
|
|
2028
|
+
name: `(script) ${id}`,
|
|
2029
|
+
purpose: "Script de integra\xE7\xE3o ativo",
|
|
2030
|
+
duration: "-",
|
|
2031
|
+
provider: "-"
|
|
2032
|
+
}));
|
|
2033
|
+
if (scriptRows.length > 0) mergedFinal = scriptRows;
|
|
2034
|
+
}
|
|
2035
|
+
} catch {
|
|
2036
|
+
}
|
|
2037
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_Box2.default, { sx: { mb: 1 }, children: [
|
|
2038
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2039
|
+
import_FormControlLabel.default,
|
|
1420
2040
|
{
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
2041
|
+
control: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2042
|
+
import_Switch.default,
|
|
2043
|
+
{
|
|
2044
|
+
checked: tempPreferences[category.id] ?? false,
|
|
2045
|
+
onChange: (e) => setTempPreferences((prev) => ({
|
|
2046
|
+
...prev,
|
|
2047
|
+
[category.id]: e.target.checked
|
|
2048
|
+
}))
|
|
2049
|
+
}
|
|
2050
|
+
),
|
|
2051
|
+
label: `${category.name} - ${category.description}`
|
|
1426
2052
|
}
|
|
1427
2053
|
),
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
2054
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("details", { style: { marginLeft: 48 }, children: [
|
|
2055
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("summary", { children: "Ver detalhes" }),
|
|
2056
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_Box2.default, { sx: { mt: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("table", { style: { width: "100%", borderCollapse: "collapse" }, children: [
|
|
2057
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("tr", { children: [
|
|
2058
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { style: { textAlign: "left" }, children: "Cookie" }),
|
|
2059
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { style: { textAlign: "left" }, children: "Finalidade" }),
|
|
2060
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { style: { textAlign: "left" }, children: "Dura\xE7\xE3o" }),
|
|
2061
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { style: { textAlign: "left" }, children: "Fornecedor" })
|
|
2062
|
+
] }) }),
|
|
2063
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tbody", { children: mergedFinal.map((d, idx) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("tr", { children: [
|
|
2064
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { children: d.name }),
|
|
2065
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { children: d.purpose }),
|
|
2066
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { children: d.duration }),
|
|
2067
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { children: d.provider })
|
|
2068
|
+
] }, d.name + idx)) })
|
|
2069
|
+
] }) })
|
|
2070
|
+
] })
|
|
2071
|
+
] }, category.id);
|
|
2072
|
+
}),
|
|
2073
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_FormControlLabel.default, { control: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_Switch.default, { checked: true, disabled: true }), label: texts.necessaryAlwaysOn }),
|
|
2074
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("details", { style: { marginLeft: 48 }, children: [
|
|
2075
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("summary", { children: "Ver detalhes" }),
|
|
2076
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_Box2.default, { sx: { mt: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("table", { style: { width: "100%", borderCollapse: "collapse" }, children: [
|
|
2077
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("tr", { children: [
|
|
2078
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { style: { textAlign: "left" }, children: "Cookie" }),
|
|
2079
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { style: { textAlign: "left" }, children: "Finalidade" }),
|
|
2080
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { style: { textAlign: "left" }, children: "Dura\xE7\xE3o" }),
|
|
2081
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { style: { textAlign: "left" }, children: "Fornecedor" })
|
|
2082
|
+
] }) }),
|
|
2083
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tbody", { children: (() => {
|
|
2084
|
+
const used = globalThis.__LGPD_USED_INTEGRATIONS__ || [];
|
|
2085
|
+
const necessaryCookies = getCookiesInfoForCategory(
|
|
2086
|
+
"necessary",
|
|
2087
|
+
used
|
|
2088
|
+
);
|
|
2089
|
+
return necessaryCookies.map((d, idx) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("tr", { children: [
|
|
2090
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { children: d.name }),
|
|
2091
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { children: d.purpose || "-" }),
|
|
2092
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { children: d.duration || "-" }),
|
|
2093
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { children: d.provider || "-" })
|
|
2094
|
+
] }, d.name + idx));
|
|
2095
|
+
})() })
|
|
2096
|
+
] }) })
|
|
2097
|
+
] })
|
|
1433
2098
|
] })
|
|
1434
2099
|
] }),
|
|
1435
2100
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_DialogActions.default, { children: [
|
|
@@ -1439,10 +2104,11 @@ function PreferencesModal2({
|
|
|
1439
2104
|
!hideBranding && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Branding, { variant: "modal" })
|
|
1440
2105
|
] });
|
|
1441
2106
|
}
|
|
1442
|
-
var import_Button2, import_Dialog, import_DialogActions, import_DialogContent, import_DialogTitle, import_FormControlLabel, import_FormGroup, import_Switch, import_Typography3, import_react2, import_jsx_runtime7;
|
|
2107
|
+
var import_Box2, import_Button2, import_Dialog, import_DialogActions, import_DialogContent, import_DialogTitle, import_FormControlLabel, import_FormGroup, import_Switch, import_Typography3, import_react2, import_jsx_runtime7;
|
|
1443
2108
|
var init_PreferencesModal = __esm({
|
|
1444
2109
|
"src/components/PreferencesModal.tsx"() {
|
|
1445
2110
|
"use strict";
|
|
2111
|
+
import_Box2 = __toESM(require("@mui/material/Box"), 1);
|
|
1446
2112
|
import_Button2 = __toESM(require("@mui/material/Button"), 1);
|
|
1447
2113
|
import_Dialog = __toESM(require("@mui/material/Dialog"), 1);
|
|
1448
2114
|
import_DialogActions = __toESM(require("@mui/material/DialogActions"), 1);
|
|
@@ -1454,8 +2120,9 @@ var init_PreferencesModal = __esm({
|
|
|
1454
2120
|
import_Typography3 = __toESM(require("@mui/material/Typography"), 1);
|
|
1455
2121
|
import_react2 = require("react");
|
|
1456
2122
|
init_CategoriesContext();
|
|
1457
|
-
init_useConsent();
|
|
1458
2123
|
init_DesignContext();
|
|
2124
|
+
init_useConsent();
|
|
2125
|
+
init_cookieRegistry();
|
|
1459
2126
|
init_Branding();
|
|
1460
2127
|
import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1461
2128
|
}
|
|
@@ -1470,28 +2137,56 @@ __export(index_exports, {
|
|
|
1470
2137
|
ConsentScriptLoader: () => ConsentScriptLoader,
|
|
1471
2138
|
CookieBanner: () => CookieBanner,
|
|
1472
2139
|
DEFAULT_PROJECT_CATEGORIES: () => DEFAULT_PROJECT_CATEGORIES,
|
|
2140
|
+
EXPANDED_DEFAULT_TEXTS: () => EXPANDED_DEFAULT_TEXTS,
|
|
1473
2141
|
FloatingPreferencesButton: () => FloatingPreferencesButton,
|
|
2142
|
+
GUIDANCE_PRESETS: () => GUIDANCE_PRESETS,
|
|
2143
|
+
INTEGRATION_TEMPLATES: () => INTEGRATION_TEMPLATES,
|
|
1474
2144
|
LogLevel: () => LogLevel,
|
|
1475
2145
|
PreferencesModal: () => PreferencesModal2,
|
|
2146
|
+
TEXT_TEMPLATES: () => TEXT_TEMPLATES,
|
|
1476
2147
|
analyzeDeveloperConfiguration: () => analyzeDeveloperConfiguration,
|
|
2148
|
+
analyzeIntegrationCategories: () => analyzeIntegrationCategories,
|
|
2149
|
+
autoConfigureCategories: () => autoConfigureCategories,
|
|
2150
|
+
categorizeDiscoveredCookies: () => categorizeDiscoveredCookies,
|
|
2151
|
+
createClarityIntegration: () => createClarityIntegration,
|
|
2152
|
+
createCorporateIntegrations: () => createCorporateIntegrations,
|
|
1477
2153
|
createDefaultConsentTheme: () => createDefaultConsentTheme,
|
|
2154
|
+
createECommerceIntegrations: () => createECommerceIntegrations,
|
|
2155
|
+
createFacebookPixelIntegration: () => createFacebookPixelIntegration,
|
|
1478
2156
|
createGoogleAnalyticsIntegration: () => createGoogleAnalyticsIntegration,
|
|
1479
2157
|
createGoogleTagManagerIntegration: () => createGoogleTagManagerIntegration,
|
|
2158
|
+
createHotjarIntegration: () => createHotjarIntegration,
|
|
2159
|
+
createIntercomIntegration: () => createIntercomIntegration,
|
|
2160
|
+
createMixpanelIntegration: () => createMixpanelIntegration,
|
|
1480
2161
|
createProjectPreferences: () => createProjectPreferences,
|
|
2162
|
+
createSaaSIntegrations: () => createSaaSIntegrations,
|
|
1481
2163
|
createUserWayIntegration: () => createUserWayIntegration,
|
|
2164
|
+
createZendeskChatIntegration: () => createZendeskChatIntegration,
|
|
1482
2165
|
defaultConsentTheme: () => defaultConsentTheme,
|
|
1483
2166
|
defaultTexts: () => defaultTexts,
|
|
2167
|
+
detectConsentCookieName: () => detectConsentCookieName,
|
|
2168
|
+
discoverRuntimeCookies: () => discoverRuntimeCookies,
|
|
2169
|
+
extractCategoriesFromIntegrations: () => extractCategoriesFromIntegrations,
|
|
1484
2170
|
getAllProjectCategories: () => getAllProjectCategories,
|
|
2171
|
+
getCookiesInfoForCategory: () => getCookiesInfoForCategory,
|
|
1485
2172
|
loadScript: () => loadScript,
|
|
2173
|
+
logDeveloperGuidance: () => logDeveloperGuidance,
|
|
1486
2174
|
openPreferencesModal: () => openPreferencesModal,
|
|
2175
|
+
resolveTexts: () => resolveTexts,
|
|
2176
|
+
setCookieCatalogOverrides: () => setCookieCatalogOverrides,
|
|
2177
|
+
setCookieCategoryOverrides: () => setCookieCategoryOverrides,
|
|
1487
2178
|
setDebugLogging: () => setDebugLogging,
|
|
2179
|
+
suggestCategoryForScript: () => suggestCategoryForScript,
|
|
1488
2180
|
useCategories: () => useCategories,
|
|
1489
2181
|
useCategoryStatus: () => useCategoryStatus,
|
|
1490
2182
|
useConsent: () => useConsent,
|
|
1491
2183
|
useConsentHydration: () => useConsentHydration,
|
|
1492
2184
|
useConsentScriptLoader: () => useConsentScriptLoader,
|
|
1493
2185
|
useConsentTexts: () => useConsentTexts,
|
|
2186
|
+
useDeveloperGuidance: () => useDeveloperGuidance,
|
|
1494
2187
|
useOpenPreferencesModal: () => useOpenPreferencesModal,
|
|
2188
|
+
validateIntegrationCategories: () => validateIntegrationCategories,
|
|
2189
|
+
validateNecessaryClassification: () => validateNecessaryClassification,
|
|
1495
2190
|
validateProjectPreferences: () => validateProjectPreferences
|
|
1496
2191
|
});
|
|
1497
2192
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -1546,6 +2241,9 @@ function loadScript(id, src, category = null, attrs = {}) {
|
|
|
1546
2241
|
});
|
|
1547
2242
|
}
|
|
1548
2243
|
|
|
2244
|
+
// src/index.ts
|
|
2245
|
+
init_cookieDiscovery();
|
|
2246
|
+
|
|
1549
2247
|
// src/utils/theme.ts
|
|
1550
2248
|
var import_styles3 = require("@mui/material/styles");
|
|
1551
2249
|
function createDefaultConsentTheme() {
|
|
@@ -1619,14 +2317,233 @@ var defaultConsentTheme = () => createDefaultConsentTheme();
|
|
|
1619
2317
|
|
|
1620
2318
|
// src/utils/ConsentScriptLoader.tsx
|
|
1621
2319
|
var React5 = __toESM(require("react"), 1);
|
|
2320
|
+
init_CategoriesContext();
|
|
1622
2321
|
init_useConsent();
|
|
2322
|
+
|
|
2323
|
+
// src/utils/autoConfigureCategories.ts
|
|
2324
|
+
var FORBIDDEN_NECESSARY_SCRIPTS = /* @__PURE__ */ new Set([
|
|
2325
|
+
// Analytics & Performance
|
|
2326
|
+
"google-analytics",
|
|
2327
|
+
"google-tag-manager",
|
|
2328
|
+
"hotjar",
|
|
2329
|
+
"mixpanel",
|
|
2330
|
+
"clarity",
|
|
2331
|
+
"amplitude",
|
|
2332
|
+
"segment",
|
|
2333
|
+
// Marketing & Advertising
|
|
2334
|
+
"facebook-pixel",
|
|
2335
|
+
"twitter-pixel",
|
|
2336
|
+
"linkedin-insight",
|
|
2337
|
+
"pinterest-tag",
|
|
2338
|
+
"snapchat-pixel",
|
|
2339
|
+
"tiktok-pixel",
|
|
2340
|
+
"reddit-pixel",
|
|
2341
|
+
// Communication & Support
|
|
2342
|
+
"intercom",
|
|
2343
|
+
"zendesk-chat",
|
|
2344
|
+
"drift",
|
|
2345
|
+
"crisp",
|
|
2346
|
+
"freshchat",
|
|
2347
|
+
// A/B Testing & Optimization
|
|
2348
|
+
"optimizely",
|
|
2349
|
+
"vwo",
|
|
2350
|
+
"google-optimize",
|
|
2351
|
+
"unbounce",
|
|
2352
|
+
// Social & Content
|
|
2353
|
+
"youtube-embed",
|
|
2354
|
+
"vimeo-embed",
|
|
2355
|
+
"twitter-widget",
|
|
2356
|
+
"facebook-widget",
|
|
2357
|
+
"instagram-widget",
|
|
2358
|
+
// Accessibility (exceto scripts críticos)
|
|
2359
|
+
"userway"
|
|
2360
|
+
]);
|
|
2361
|
+
function analyzeIntegrationCategories(integrations) {
|
|
2362
|
+
const categoryMap = {};
|
|
2363
|
+
integrations.forEach((integration) => {
|
|
2364
|
+
const category = integration.category;
|
|
2365
|
+
if (!categoryMap[category]) {
|
|
2366
|
+
categoryMap[category] = [];
|
|
2367
|
+
}
|
|
2368
|
+
categoryMap[category].push(integration.id);
|
|
2369
|
+
});
|
|
2370
|
+
return categoryMap;
|
|
2371
|
+
}
|
|
2372
|
+
function autoConfigureCategories(originalConfig, integrations, options = {}) {
|
|
2373
|
+
const { warningOnly = false, silent = false } = options;
|
|
2374
|
+
const config = originalConfig || { enabledCategories: ["analytics"] };
|
|
2375
|
+
const categoryIntegrations = analyzeIntegrationCategories(integrations);
|
|
2376
|
+
const requiredCategories = Object.keys(categoryIntegrations);
|
|
2377
|
+
const currentCategories = new Set(config.enabledCategories || []);
|
|
2378
|
+
const missingCategories = requiredCategories.filter((cat) => !currentCategories.has(cat));
|
|
2379
|
+
let adjustedConfig = { ...config };
|
|
2380
|
+
let autoEnabledCategories = [];
|
|
2381
|
+
if (missingCategories.length > 0) {
|
|
2382
|
+
if (warningOnly) {
|
|
2383
|
+
if (!silent) {
|
|
2384
|
+
logMissingCategoriesWarning(missingCategories, categoryIntegrations);
|
|
2385
|
+
}
|
|
2386
|
+
} else {
|
|
2387
|
+
autoEnabledCategories = [...missingCategories];
|
|
2388
|
+
adjustedConfig = {
|
|
2389
|
+
...config,
|
|
2390
|
+
enabledCategories: [...currentCategories, ...missingCategories]
|
|
2391
|
+
};
|
|
2392
|
+
if (!silent) {
|
|
2393
|
+
logAutoEnabledCategories(autoEnabledCategories, categoryIntegrations);
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
return {
|
|
2398
|
+
originalConfig: config,
|
|
2399
|
+
adjustedConfig,
|
|
2400
|
+
autoEnabledCategories,
|
|
2401
|
+
missingCategories,
|
|
2402
|
+
wasAdjusted: autoEnabledCategories.length > 0,
|
|
2403
|
+
categoryIntegrations
|
|
2404
|
+
};
|
|
2405
|
+
}
|
|
2406
|
+
function logMissingCategoriesWarning(missingCategories, categoryIntegrations) {
|
|
2407
|
+
const isDev = process.env.NODE_ENV !== "production";
|
|
2408
|
+
if (!isDev) return;
|
|
2409
|
+
const PREFIX = "[\u{1F36A} LGPD-CONSENT AUTO-CONFIG]";
|
|
2410
|
+
console.group(`${PREFIX} \u26A0\uFE0F Categorias Requeridas N\xE3o Habilitadas`);
|
|
2411
|
+
missingCategories.forEach((category) => {
|
|
2412
|
+
const integrations = categoryIntegrations[category] || [];
|
|
2413
|
+
console.warn(
|
|
2414
|
+
`${PREFIX} Categoria '${category}' requerida por integra\xE7\xF5es: ${integrations.join(", ")}`
|
|
2415
|
+
);
|
|
2416
|
+
});
|
|
2417
|
+
const categoriesCode = missingCategories.map((c) => `'${c}'`).join(", ");
|
|
2418
|
+
console.warn(
|
|
2419
|
+
`${PREFIX} Para corrigir, adicione estas categorias ao ConsentProvider:`,
|
|
2420
|
+
`categories={{ enabledCategories: [...existingCategories, ${categoriesCode}] }}`
|
|
2421
|
+
);
|
|
2422
|
+
console.groupEnd();
|
|
2423
|
+
}
|
|
2424
|
+
function logAutoEnabledCategories(autoEnabledCategories, categoryIntegrations) {
|
|
2425
|
+
const isDev = process.env.NODE_ENV !== "production";
|
|
2426
|
+
if (!isDev) return;
|
|
2427
|
+
const PREFIX = "[\u{1F36A} LGPD-CONSENT AUTO-CONFIG]";
|
|
2428
|
+
console.group(`${PREFIX} \u2705 Categorias Auto-Habilitadas`);
|
|
2429
|
+
autoEnabledCategories.forEach((category) => {
|
|
2430
|
+
const integrations = categoryIntegrations[category] || [];
|
|
2431
|
+
console.info(
|
|
2432
|
+
`${PREFIX} Categoria '${category}' auto-habilitada para integra\xE7\xF5es: ${integrations.join(", ")}`
|
|
2433
|
+
);
|
|
2434
|
+
});
|
|
2435
|
+
console.info(`${PREFIX} \u{1F4A1} Essas categorias foram automaticamente adicionadas \xE0 configura\xE7\xE3o.`);
|
|
2436
|
+
console.info(`${PREFIX} \u{1F527} Para controle manual, especifique explicitamente no ConsentProvider.`);
|
|
2437
|
+
console.groupEnd();
|
|
2438
|
+
}
|
|
2439
|
+
function validateIntegrationCategories(integrations, enabledCategories) {
|
|
2440
|
+
const requiredCategories = integrations.map((i) => i.category);
|
|
2441
|
+
const enabledSet = new Set(enabledCategories);
|
|
2442
|
+
return requiredCategories.every((category) => enabledSet.has(category));
|
|
2443
|
+
}
|
|
2444
|
+
function extractCategoriesFromIntegrations(integrations) {
|
|
2445
|
+
const categories = /* @__PURE__ */ new Set();
|
|
2446
|
+
integrations.forEach((integration) => {
|
|
2447
|
+
categories.add(integration.category);
|
|
2448
|
+
});
|
|
2449
|
+
return Array.from(categories);
|
|
2450
|
+
}
|
|
2451
|
+
function validateNecessaryClassification(integrations, enabledCategories) {
|
|
2452
|
+
const warnings = [];
|
|
2453
|
+
const hasNecessaryCategory = enabledCategories.includes("necessary");
|
|
2454
|
+
if (!hasNecessaryCategory) {
|
|
2455
|
+
return warnings;
|
|
2456
|
+
}
|
|
2457
|
+
const problematicIntegrations = integrations.filter(
|
|
2458
|
+
(integration) => integration.category === "necessary" && FORBIDDEN_NECESSARY_SCRIPTS.has(integration.id)
|
|
2459
|
+
);
|
|
2460
|
+
if (problematicIntegrations.length > 0) {
|
|
2461
|
+
warnings.push(
|
|
2462
|
+
`\u26A0\uFE0F ATEN\xC7\xC3O GDPR/LGPD: As seguintes integra\xE7\xF5es NUNCA devem ser classificadas como 'necessary':`
|
|
2463
|
+
);
|
|
2464
|
+
problematicIntegrations.forEach((integration) => {
|
|
2465
|
+
warnings.push(
|
|
2466
|
+
` \u2022 '${integration.id}' (categoria: ${integration.category}) - Requer consentimento expl\xEDcito`
|
|
2467
|
+
);
|
|
2468
|
+
});
|
|
2469
|
+
warnings.push(
|
|
2470
|
+
`\u{1F4A1} Scripts 'necessary' executam SEM consentimento e podem resultar em multas.`,
|
|
2471
|
+
`\u{1F4DA} Apenas scripts de seguran\xE7a, autentica\xE7\xE3o ou core do site se qualificam.`,
|
|
2472
|
+
`\u{1F527} Mova estes scripts para categorias apropriadas (analytics, marketing, etc.)`
|
|
2473
|
+
);
|
|
2474
|
+
}
|
|
2475
|
+
return warnings;
|
|
2476
|
+
}
|
|
2477
|
+
|
|
2478
|
+
// src/utils/ConsentScriptLoader.tsx
|
|
1623
2479
|
init_logger();
|
|
1624
2480
|
function ConsentScriptLoader({
|
|
1625
2481
|
integrations,
|
|
1626
2482
|
reloadOnChange = false
|
|
1627
2483
|
}) {
|
|
1628
2484
|
const { preferences, consented } = useConsent();
|
|
2485
|
+
const categories = useCategories();
|
|
1629
2486
|
const loadedScripts = React5.useRef(/* @__PURE__ */ new Set());
|
|
2487
|
+
React5.useEffect(() => {
|
|
2488
|
+
try {
|
|
2489
|
+
const ids = (integrations || []).map((i) => i.id);
|
|
2490
|
+
const gt = globalThis;
|
|
2491
|
+
const current = Array.isArray(gt.__LGPD_USED_INTEGRATIONS__) ? gt.__LGPD_USED_INTEGRATIONS__ : [];
|
|
2492
|
+
const merged = Array.from(/* @__PURE__ */ new Set([...current, ...ids]));
|
|
2493
|
+
gt.__LGPD_USED_INTEGRATIONS__ = merged;
|
|
2494
|
+
try {
|
|
2495
|
+
const gmap = globalThis;
|
|
2496
|
+
const map = gmap.__LGPD_INTEGRATIONS_MAP__ || {};
|
|
2497
|
+
(integrations || []).forEach((i) => {
|
|
2498
|
+
map[i.id] = i.category;
|
|
2499
|
+
});
|
|
2500
|
+
gmap.__LGPD_INTEGRATIONS_MAP__ = map;
|
|
2501
|
+
} catch {
|
|
2502
|
+
}
|
|
2503
|
+
} catch {
|
|
2504
|
+
}
|
|
2505
|
+
}, [integrations]);
|
|
2506
|
+
React5.useEffect(() => {
|
|
2507
|
+
try {
|
|
2508
|
+
const required = Array.from(new Set((integrations || []).map((i) => i.category))).filter(
|
|
2509
|
+
Boolean
|
|
2510
|
+
);
|
|
2511
|
+
const gt = globalThis;
|
|
2512
|
+
const current = Array.isArray(gt.__LGPD_REQUIRED_CATEGORIES__) ? gt.__LGPD_REQUIRED_CATEGORIES__ : [];
|
|
2513
|
+
const merged = Array.from(/* @__PURE__ */ new Set([...current, ...required]));
|
|
2514
|
+
gt.__LGPD_REQUIRED_CATEGORIES__ = merged;
|
|
2515
|
+
if (typeof window !== "undefined" && typeof window.dispatchEvent === "function") {
|
|
2516
|
+
window.dispatchEvent(new CustomEvent("lgpd:requiredCategories"));
|
|
2517
|
+
}
|
|
2518
|
+
} catch {
|
|
2519
|
+
}
|
|
2520
|
+
}, [integrations]);
|
|
2521
|
+
React5.useEffect(() => {
|
|
2522
|
+
const isDev = process.env.NODE_ENV !== "production";
|
|
2523
|
+
if (!isDev || integrations.length === 0) return;
|
|
2524
|
+
const enabledCategories = categories.allCategories.map((cat) => cat.id);
|
|
2525
|
+
const isValid = validateIntegrationCategories(integrations, enabledCategories);
|
|
2526
|
+
if (!isValid) {
|
|
2527
|
+
autoConfigureCategories({ enabledCategories }, integrations, {
|
|
2528
|
+
warningOnly: true,
|
|
2529
|
+
silent: false
|
|
2530
|
+
});
|
|
2531
|
+
}
|
|
2532
|
+
const necessaryWarnings = validateNecessaryClassification(integrations, enabledCategories);
|
|
2533
|
+
if (necessaryWarnings.length > 0) {
|
|
2534
|
+
console.group("\u{1F6A8} [LGPD-CONSENT] VALIDA\xC7\xC3O DE COMPLIANCE");
|
|
2535
|
+
necessaryWarnings.forEach((warning) => {
|
|
2536
|
+
if (warning.startsWith("\u26A0\uFE0F")) {
|
|
2537
|
+
console.error(warning);
|
|
2538
|
+
} else if (warning.startsWith("\u{1F4A1}") || warning.startsWith("\u{1F4DA}") || warning.startsWith("\u{1F527}")) {
|
|
2539
|
+
console.warn(warning);
|
|
2540
|
+
} else {
|
|
2541
|
+
console.log(warning);
|
|
2542
|
+
}
|
|
2543
|
+
});
|
|
2544
|
+
console.groupEnd();
|
|
2545
|
+
}
|
|
2546
|
+
}, [integrations, categories]);
|
|
1630
2547
|
React5.useEffect(() => {
|
|
1631
2548
|
if (!consented) return;
|
|
1632
2549
|
integrations.forEach(async (integration) => {
|
|
@@ -1679,10 +2596,32 @@ function useConsentScriptLoader() {
|
|
|
1679
2596
|
|
|
1680
2597
|
// src/utils/scriptIntegrations.ts
|
|
1681
2598
|
function createGoogleAnalyticsIntegration(config) {
|
|
2599
|
+
const src = config.scriptUrl ?? `https://www.googletagmanager.com/gtag/js?id=${config.measurementId}`;
|
|
1682
2600
|
return {
|
|
1683
2601
|
id: "google-analytics",
|
|
1684
2602
|
category: "analytics",
|
|
1685
|
-
src
|
|
2603
|
+
src,
|
|
2604
|
+
cookies: ["_ga", "_ga_*", "_gid"],
|
|
2605
|
+
cookiesInfo: [
|
|
2606
|
+
{
|
|
2607
|
+
name: "_ga",
|
|
2608
|
+
purpose: "Identifica\xE7\xE3o \xFAnica de visitantes para an\xE1lise de tr\xE1fego",
|
|
2609
|
+
duration: "2 anos",
|
|
2610
|
+
provider: "Google Analytics"
|
|
2611
|
+
},
|
|
2612
|
+
{
|
|
2613
|
+
name: "_ga_*",
|
|
2614
|
+
purpose: "Rastreamento de sess\xF5es e eventos espec\xEDficos do stream GA4",
|
|
2615
|
+
duration: "2 anos",
|
|
2616
|
+
provider: "Google Analytics"
|
|
2617
|
+
},
|
|
2618
|
+
{
|
|
2619
|
+
name: "_gid",
|
|
2620
|
+
purpose: "Distin\xE7\xE3o de visitantes \xFAnicos em per\xEDodo de 24h",
|
|
2621
|
+
duration: "24 horas",
|
|
2622
|
+
provider: "Google Analytics"
|
|
2623
|
+
}
|
|
2624
|
+
],
|
|
1686
2625
|
init: () => {
|
|
1687
2626
|
if (typeof window !== "undefined") {
|
|
1688
2627
|
const w = window;
|
|
@@ -1699,29 +2638,30 @@ function createGoogleAnalyticsIntegration(config) {
|
|
|
1699
2638
|
};
|
|
1700
2639
|
}
|
|
1701
2640
|
function createGoogleTagManagerIntegration(config) {
|
|
2641
|
+
const src = config.scriptUrl ?? `https://www.googletagmanager.com/gtm.js?id=${config.containerId}`;
|
|
1702
2642
|
return {
|
|
1703
2643
|
id: "google-tag-manager",
|
|
1704
2644
|
category: "analytics",
|
|
1705
|
-
src
|
|
2645
|
+
src,
|
|
2646
|
+
cookies: ["_gcl_au"],
|
|
1706
2647
|
init: () => {
|
|
1707
2648
|
if (typeof window !== "undefined") {
|
|
1708
2649
|
const dataLayerName = config.dataLayerName || "dataLayer";
|
|
1709
2650
|
const w = window;
|
|
1710
2651
|
const layer = w[dataLayerName] ?? [];
|
|
1711
2652
|
w[dataLayerName] = layer;
|
|
1712
|
-
layer.push({
|
|
1713
|
-
"gtm.start": (/* @__PURE__ */ new Date()).getTime(),
|
|
1714
|
-
event: "gtm.js"
|
|
1715
|
-
});
|
|
2653
|
+
layer.push({ "gtm.start": (/* @__PURE__ */ new Date()).getTime(), event: "gtm.js" });
|
|
1716
2654
|
}
|
|
1717
2655
|
}
|
|
1718
2656
|
};
|
|
1719
2657
|
}
|
|
1720
2658
|
function createUserWayIntegration(config) {
|
|
2659
|
+
const src = config.scriptUrl ?? "https://cdn.userway.org/widget.js";
|
|
1721
2660
|
return {
|
|
1722
2661
|
id: "userway",
|
|
1723
2662
|
category: "functional",
|
|
1724
|
-
src
|
|
2663
|
+
src,
|
|
2664
|
+
cookies: ["_userway_*"],
|
|
1725
2665
|
init: () => {
|
|
1726
2666
|
if (typeof window !== "undefined") {
|
|
1727
2667
|
const w = window;
|
|
@@ -1737,10 +2677,463 @@ var COMMON_INTEGRATIONS = {
|
|
|
1737
2677
|
googleTagManager: createGoogleTagManagerIntegration,
|
|
1738
2678
|
userway: createUserWayIntegration
|
|
1739
2679
|
};
|
|
2680
|
+
function createFacebookPixelIntegration(config) {
|
|
2681
|
+
const src = config.scriptUrl ?? "https://connect.facebook.net/en_US/fbevents.js";
|
|
2682
|
+
return {
|
|
2683
|
+
id: "facebook-pixel",
|
|
2684
|
+
category: "marketing",
|
|
2685
|
+
src,
|
|
2686
|
+
cookies: ["_fbp", "fr"],
|
|
2687
|
+
init: () => {
|
|
2688
|
+
if (typeof window !== "undefined") {
|
|
2689
|
+
const w = window;
|
|
2690
|
+
if (!w.fbq) {
|
|
2691
|
+
const fbq = (...args) => {
|
|
2692
|
+
if (w.fbq && typeof w.fbq.callMethod === "function") {
|
|
2693
|
+
w.fbq.callMethod(...args);
|
|
2694
|
+
} else {
|
|
2695
|
+
fbq.queue = fbq.queue || [];
|
|
2696
|
+
fbq.queue.push(args);
|
|
2697
|
+
}
|
|
2698
|
+
};
|
|
2699
|
+
fbq.loaded = true;
|
|
2700
|
+
w.fbq = fbq;
|
|
2701
|
+
}
|
|
2702
|
+
w.fbq("init", config.pixelId, config.advancedMatching ?? {});
|
|
2703
|
+
if (config.autoTrack !== false) w.fbq("track", "PageView");
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
};
|
|
2707
|
+
}
|
|
2708
|
+
function createHotjarIntegration(config) {
|
|
2709
|
+
const v = config.version ?? 6;
|
|
2710
|
+
const src = config.scriptUrl ?? `https://static.hotjar.com/c/hotjar-${config.siteId}.js?sv=${v}`;
|
|
2711
|
+
return {
|
|
2712
|
+
id: "hotjar",
|
|
2713
|
+
category: "analytics",
|
|
2714
|
+
src,
|
|
2715
|
+
cookies: [
|
|
2716
|
+
"_hjSession_*",
|
|
2717
|
+
"_hjSessionUser_*",
|
|
2718
|
+
"_hjFirstSeen",
|
|
2719
|
+
"_hjIncludedInSessionSample",
|
|
2720
|
+
"_hjAbsoluteSessionInProgress"
|
|
2721
|
+
],
|
|
2722
|
+
cookiesInfo: [
|
|
2723
|
+
{
|
|
2724
|
+
name: "_hjSession_*",
|
|
2725
|
+
purpose: "Identifica\xE7\xE3o \xFAnica da sess\xE3o de grava\xE7\xE3o e heatmaps",
|
|
2726
|
+
duration: "30 minutos",
|
|
2727
|
+
provider: "Hotjar"
|
|
2728
|
+
},
|
|
2729
|
+
{
|
|
2730
|
+
name: "_hjSessionUser_*",
|
|
2731
|
+
purpose: "Identifica\xE7\xE3o persistente do usu\xE1rio entre sess\xF5es",
|
|
2732
|
+
duration: "365 dias",
|
|
2733
|
+
provider: "Hotjar"
|
|
2734
|
+
},
|
|
2735
|
+
{
|
|
2736
|
+
name: "_hjFirstSeen",
|
|
2737
|
+
purpose: "Detec\xE7\xE3o de primeira visita do usu\xE1rio ao site",
|
|
2738
|
+
duration: "Sess\xE3o",
|
|
2739
|
+
provider: "Hotjar"
|
|
2740
|
+
},
|
|
2741
|
+
{
|
|
2742
|
+
name: "_hjIncludedInSessionSample",
|
|
2743
|
+
purpose: "Indica se a sess\xE3o est\xE1 inclu\xEDda na amostra de grava\xE7\xE3o",
|
|
2744
|
+
duration: "30 minutos",
|
|
2745
|
+
provider: "Hotjar"
|
|
2746
|
+
},
|
|
2747
|
+
{
|
|
2748
|
+
name: "_hjAbsoluteSessionInProgress",
|
|
2749
|
+
purpose: "Detecta se uma sess\xE3o absoluta est\xE1 em progresso",
|
|
2750
|
+
duration: "30 minutos",
|
|
2751
|
+
provider: "Hotjar"
|
|
2752
|
+
}
|
|
2753
|
+
],
|
|
2754
|
+
init: () => {
|
|
2755
|
+
if (typeof window !== "undefined") {
|
|
2756
|
+
const w = window;
|
|
2757
|
+
w._hjSettings = { hjid: config.siteId, hjsv: v };
|
|
2758
|
+
if (!w.hj) {
|
|
2759
|
+
const hj = (...args) => {
|
|
2760
|
+
hj.q = hj.q || [];
|
|
2761
|
+
hj.q.push(args);
|
|
2762
|
+
};
|
|
2763
|
+
w.hj = hj;
|
|
2764
|
+
}
|
|
2765
|
+
if (config.debug && typeof console !== "undefined" && typeof console.info === "function") {
|
|
2766
|
+
console.info("[Hotjar] initialized with siteId", config.siteId);
|
|
2767
|
+
}
|
|
2768
|
+
}
|
|
2769
|
+
}
|
|
2770
|
+
};
|
|
2771
|
+
}
|
|
2772
|
+
function createMixpanelIntegration(config) {
|
|
2773
|
+
const src = config.scriptUrl ?? "https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";
|
|
2774
|
+
return {
|
|
2775
|
+
id: "mixpanel",
|
|
2776
|
+
category: "analytics",
|
|
2777
|
+
src,
|
|
2778
|
+
cookies: ["mp_*"],
|
|
2779
|
+
cookiesInfo: [
|
|
2780
|
+
{
|
|
2781
|
+
name: "mp_*",
|
|
2782
|
+
purpose: "Rastreamento de eventos e propriedades do usu\xE1rio para analytics",
|
|
2783
|
+
duration: "1 ano",
|
|
2784
|
+
provider: "Mixpanel"
|
|
2785
|
+
}
|
|
2786
|
+
],
|
|
2787
|
+
init: () => {
|
|
2788
|
+
if (typeof window !== "undefined") {
|
|
2789
|
+
const w = window;
|
|
2790
|
+
w.mixpanel = w.mixpanel || { init: () => void 0 };
|
|
2791
|
+
if (w.mixpanel && typeof w.mixpanel.init === "function") {
|
|
2792
|
+
try {
|
|
2793
|
+
w.mixpanel.init(config.token, config.config ?? {}, config.api_host);
|
|
2794
|
+
} catch (error) {
|
|
2795
|
+
if (typeof console !== "undefined" && typeof console.warn === "function") {
|
|
2796
|
+
console.warn("[Mixpanel] Failed to initialize:", error);
|
|
2797
|
+
}
|
|
2798
|
+
}
|
|
2799
|
+
}
|
|
2800
|
+
}
|
|
2801
|
+
}
|
|
2802
|
+
};
|
|
2803
|
+
}
|
|
2804
|
+
function createClarityIntegration(config) {
|
|
2805
|
+
const src = config.scriptUrl ?? `https://www.clarity.ms/tag/${config.projectId}`;
|
|
2806
|
+
return {
|
|
2807
|
+
id: "clarity",
|
|
2808
|
+
category: "analytics",
|
|
2809
|
+
src,
|
|
2810
|
+
cookies: ["_clck", "_clsk", "CLID", "ANONCHK", "MR", "MUID", "SM"],
|
|
2811
|
+
init: () => {
|
|
2812
|
+
if (typeof window !== "undefined" && typeof config.upload !== "undefined") {
|
|
2813
|
+
const w = window;
|
|
2814
|
+
if (typeof w.clarity === "function") {
|
|
2815
|
+
try {
|
|
2816
|
+
w.clarity("set", "upload", config.upload);
|
|
2817
|
+
} catch (error) {
|
|
2818
|
+
if (typeof console !== "undefined" && typeof console.warn === "function") {
|
|
2819
|
+
console.warn("[Clarity] Failed to configure upload setting:", error);
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
}
|
|
2823
|
+
}
|
|
2824
|
+
}
|
|
2825
|
+
};
|
|
2826
|
+
}
|
|
2827
|
+
function createIntercomIntegration(config) {
|
|
2828
|
+
const src = config.scriptUrl ?? `https://widget.intercom.io/widget/${config.app_id}`;
|
|
2829
|
+
return {
|
|
2830
|
+
id: "intercom",
|
|
2831
|
+
category: "functional",
|
|
2832
|
+
src,
|
|
2833
|
+
cookies: ["intercom-id-*", "intercom-session-*"],
|
|
2834
|
+
init: () => {
|
|
2835
|
+
if (typeof window !== "undefined") {
|
|
2836
|
+
const w = window;
|
|
2837
|
+
if (typeof w.Intercom === "function") {
|
|
2838
|
+
try {
|
|
2839
|
+
w.Intercom("boot", { app_id: config.app_id });
|
|
2840
|
+
} catch (error) {
|
|
2841
|
+
if (typeof console !== "undefined" && typeof console.warn === "function") {
|
|
2842
|
+
console.warn("[Intercom] Failed to boot:", error);
|
|
2843
|
+
}
|
|
2844
|
+
}
|
|
2845
|
+
}
|
|
2846
|
+
}
|
|
2847
|
+
}
|
|
2848
|
+
};
|
|
2849
|
+
}
|
|
2850
|
+
function createZendeskChatIntegration(config) {
|
|
2851
|
+
const src = config.scriptUrl ?? `https://static.zdassets.com/ekr/snippet.js?key=${config.key}`;
|
|
2852
|
+
return {
|
|
2853
|
+
id: "zendesk-chat",
|
|
2854
|
+
category: "functional",
|
|
2855
|
+
src,
|
|
2856
|
+
cookies: ["__zlcmid", "_zendesk_shared_session"],
|
|
2857
|
+
init: () => {
|
|
2858
|
+
if (typeof window !== "undefined") {
|
|
2859
|
+
const w = window;
|
|
2860
|
+
if (typeof w.zE === "function") {
|
|
2861
|
+
try {
|
|
2862
|
+
w.zE("webWidget", "identify", { key: config.key });
|
|
2863
|
+
} catch (error) {
|
|
2864
|
+
if (typeof console !== "undefined" && typeof console.warn === "function") {
|
|
2865
|
+
console.warn("[Zendesk] Failed to identify:", error);
|
|
2866
|
+
}
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
};
|
|
2872
|
+
}
|
|
2873
|
+
function createECommerceIntegrations(cfg) {
|
|
2874
|
+
const list = [];
|
|
2875
|
+
if (cfg.googleAnalytics) list.push(createGoogleAnalyticsIntegration(cfg.googleAnalytics));
|
|
2876
|
+
if (cfg.facebookPixel) list.push(createFacebookPixelIntegration(cfg.facebookPixel));
|
|
2877
|
+
if (cfg.hotjar) list.push(createHotjarIntegration(cfg.hotjar));
|
|
2878
|
+
if (cfg.userway) list.push(createUserWayIntegration(cfg.userway));
|
|
2879
|
+
return list;
|
|
2880
|
+
}
|
|
2881
|
+
function createSaaSIntegrations(cfg) {
|
|
2882
|
+
const list = [];
|
|
2883
|
+
if (cfg.googleAnalytics) list.push(createGoogleAnalyticsIntegration(cfg.googleAnalytics));
|
|
2884
|
+
if (cfg.mixpanel) list.push(createMixpanelIntegration(cfg.mixpanel));
|
|
2885
|
+
if (cfg.intercom) list.push(createIntercomIntegration(cfg.intercom));
|
|
2886
|
+
if (cfg.hotjar) list.push(createHotjarIntegration(cfg.hotjar));
|
|
2887
|
+
return list;
|
|
2888
|
+
}
|
|
2889
|
+
function createCorporateIntegrations(cfg) {
|
|
2890
|
+
const list = [];
|
|
2891
|
+
if (cfg.googleAnalytics) list.push(createGoogleAnalyticsIntegration(cfg.googleAnalytics));
|
|
2892
|
+
if (cfg.clarity) list.push(createClarityIntegration(cfg.clarity));
|
|
2893
|
+
if (cfg.zendesk) list.push(createZendeskChatIntegration(cfg.zendesk));
|
|
2894
|
+
if (cfg.userway) list.push(createUserWayIntegration(cfg.userway));
|
|
2895
|
+
return list;
|
|
2896
|
+
}
|
|
2897
|
+
var INTEGRATION_TEMPLATES = {
|
|
2898
|
+
ecommerce: {
|
|
2899
|
+
essential: ["google-analytics", "facebook-pixel"],
|
|
2900
|
+
optional: ["hotjar", "userway"],
|
|
2901
|
+
categories: ["analytics", "marketing", "functional"]
|
|
2902
|
+
},
|
|
2903
|
+
saas: {
|
|
2904
|
+
essential: ["google-analytics", "mixpanel"],
|
|
2905
|
+
optional: ["intercom", "hotjar"],
|
|
2906
|
+
categories: ["analytics", "functional"]
|
|
2907
|
+
},
|
|
2908
|
+
corporate: {
|
|
2909
|
+
essential: ["google-analytics"],
|
|
2910
|
+
optional: ["userway", "zendesk-chat", "clarity"],
|
|
2911
|
+
categories: ["analytics", "functional"]
|
|
2912
|
+
}
|
|
2913
|
+
};
|
|
2914
|
+
function suggestCategoryForScript(name) {
|
|
2915
|
+
const n = name.toLowerCase();
|
|
2916
|
+
if (n.includes("facebook") || n.includes("pixel") || n.includes("ads")) return ["marketing"];
|
|
2917
|
+
if (n.includes("hotjar") || n.includes("mixpanel") || n.includes("clarity")) return ["analytics"];
|
|
2918
|
+
if (n.includes("intercom") || n.includes("zendesk") || n.includes("chat")) return ["functional"];
|
|
2919
|
+
return ["analytics"];
|
|
2920
|
+
}
|
|
2921
|
+
|
|
2922
|
+
// src/types/advancedTexts.ts
|
|
2923
|
+
var EXPANDED_DEFAULT_TEXTS = {
|
|
2924
|
+
// Textos adicionais
|
|
2925
|
+
confirm: "Confirmar",
|
|
2926
|
+
cancel: "Cancelar",
|
|
2927
|
+
loading: "Carregando...",
|
|
2928
|
+
// Feedback
|
|
2929
|
+
feedback: {
|
|
2930
|
+
saveSuccess: "Prefer\xEAncias salvas com sucesso!",
|
|
2931
|
+
saveError: "Erro ao salvar prefer\xEAncias. Tente novamente.",
|
|
2932
|
+
consentUpdated: "Consentimento atualizado.",
|
|
2933
|
+
cookiesRejected: "Cookies opcionais rejeitados.",
|
|
2934
|
+
settingsReset: "Configura\xE7\xF5es resetadas."
|
|
2935
|
+
},
|
|
2936
|
+
// Acessibilidade
|
|
2937
|
+
accessibility: {
|
|
2938
|
+
bannerLabel: "Banner de consentimento de cookies",
|
|
2939
|
+
modalLabel: "Modal de prefer\xEAncias de cookies",
|
|
2940
|
+
keyboardNavigation: "Use Tab para navegar, Enter para selecionar",
|
|
2941
|
+
toggleState: {
|
|
2942
|
+
enabled: "Habilitado",
|
|
2943
|
+
disabled: "Desabilitado"
|
|
2944
|
+
},
|
|
2945
|
+
liveRegion: "Regi\xE3o de an\xFAncios din\xE2micos"
|
|
2946
|
+
},
|
|
2947
|
+
// Categorias
|
|
2948
|
+
categories: {
|
|
2949
|
+
necessary: {
|
|
2950
|
+
name: "Cookies Necess\xE1rios",
|
|
2951
|
+
description: "Essenciais para o funcionamento b\xE1sico do site",
|
|
2952
|
+
examples: "Sess\xE3o, seguran\xE7a, prefer\xEAncias de idioma"
|
|
2953
|
+
},
|
|
2954
|
+
analytics: {
|
|
2955
|
+
name: "Cookies de Analytics",
|
|
2956
|
+
description: "Ajudam a entender como os visitantes usam o site",
|
|
2957
|
+
examples: "Google Analytics, contadores de p\xE1gina"
|
|
2958
|
+
},
|
|
2959
|
+
marketing: {
|
|
2960
|
+
name: "Cookies de Marketing",
|
|
2961
|
+
description: "Usados para personalizar an\xFAncios e ofertas",
|
|
2962
|
+
examples: "Facebook Pixel, Google Ads, remarketing"
|
|
2963
|
+
},
|
|
2964
|
+
functional: {
|
|
2965
|
+
name: "Cookies Funcionais",
|
|
2966
|
+
description: "Melhoram a funcionalidade e personaliza\xE7\xE3o",
|
|
2967
|
+
examples: "Chat, mapas, v\xEDdeos embarcados"
|
|
2968
|
+
},
|
|
2969
|
+
performance: {
|
|
2970
|
+
name: "Cookies de Performance",
|
|
2971
|
+
description: "Coletam informa\xE7\xF5es sobre velocidade e estabilidade",
|
|
2972
|
+
examples: "Monitoramento de erro, otimiza\xE7\xE3o de velocidade"
|
|
2973
|
+
}
|
|
2974
|
+
},
|
|
2975
|
+
// Contextos específicos
|
|
2976
|
+
contexts: {
|
|
2977
|
+
ecommerce: {
|
|
2978
|
+
cartAbandonment: "Lembramos dos produtos no seu carrinho",
|
|
2979
|
+
personalizedOffers: "Ofertas personalizadas baseadas no seu hist\xF3rico",
|
|
2980
|
+
paymentSecurity: "Seguran\xE7a adicional no processo de pagamento",
|
|
2981
|
+
productRecommendations: "Sugest\xF5es de produtos relevantes"
|
|
2982
|
+
},
|
|
2983
|
+
saas: {
|
|
2984
|
+
userAnalytics: "An\xE1lise de uso para melhorar funcionalidades",
|
|
2985
|
+
performanceMonitoring: "Monitoramento de performance da aplica\xE7\xE3o",
|
|
2986
|
+
featureUsage: "Estat\xEDsticas de uso de recursos",
|
|
2987
|
+
customerSupport: "Suporte ao cliente mais eficiente"
|
|
2988
|
+
},
|
|
2989
|
+
government: {
|
|
2990
|
+
citizenServices: "Melhoria dos servi\xE7os ao cidad\xE3o",
|
|
2991
|
+
dataProtection: "Prote\xE7\xE3o rigorosa dos dados pessoais",
|
|
2992
|
+
transparency: "Transpar\xEAncia no uso de dados",
|
|
2993
|
+
accessibility: "Recursos de acessibilidade digital"
|
|
2994
|
+
},
|
|
2995
|
+
education: {
|
|
2996
|
+
studentProgress: "Acompanhamento do progresso educacional",
|
|
2997
|
+
learningAnalytics: "Analytics para melhorar o aprendizado",
|
|
2998
|
+
accessibility: "Recursos educacionais acess\xEDveis",
|
|
2999
|
+
parentalConsent: "Consentimento parental quando necess\xE1rio"
|
|
3000
|
+
}
|
|
3001
|
+
},
|
|
3002
|
+
// Variações de tom
|
|
3003
|
+
variants: {
|
|
3004
|
+
formal: {
|
|
3005
|
+
bannerMessage: "Este s\xEDtio eletr\xF4nico utiliza cookies para otimizar a experi\xEAncia de navega\xE7\xE3o.",
|
|
3006
|
+
acceptAll: "Concordar com todos os cookies",
|
|
3007
|
+
declineAll: "Recusar cookies opcionais",
|
|
3008
|
+
modalTitle: "Configura\xE7\xE3o de Cookies"
|
|
3009
|
+
},
|
|
3010
|
+
casual: {
|
|
3011
|
+
bannerMessage: "\u{1F36A} Ei! Usamos cookies para tornar sua experi\xEAncia ainda melhor!",
|
|
3012
|
+
acceptAll: "Aceitar tudo",
|
|
3013
|
+
declineAll: "S\xF3 o essencial",
|
|
3014
|
+
modalTitle: "Seus Cookies"
|
|
3015
|
+
},
|
|
3016
|
+
concise: {
|
|
3017
|
+
bannerMessage: "Usamos cookies. Voc\xEA aceita?",
|
|
3018
|
+
acceptAll: "Sim",
|
|
3019
|
+
declineAll: "N\xE3o",
|
|
3020
|
+
modalTitle: "Cookies"
|
|
3021
|
+
},
|
|
3022
|
+
detailed: {
|
|
3023
|
+
bannerMessage: "Utilizamos cookies e tecnologias similares para melhorar sua experi\xEAncia de navega\xE7\xE3o, personalizar conte\xFAdo, analisar tr\xE1fego e oferecer funcionalidades de redes sociais.",
|
|
3024
|
+
acceptAll: "Aceitar todos os cookies e tecnologias",
|
|
3025
|
+
declineAll: "Recusar todos os cookies opcionais",
|
|
3026
|
+
modalTitle: "Centro de Prefer\xEAncias de Privacidade"
|
|
3027
|
+
}
|
|
3028
|
+
},
|
|
3029
|
+
// Internacionalização simplificada (apenas textos básicos)
|
|
3030
|
+
i18n: {
|
|
3031
|
+
en: {
|
|
3032
|
+
bannerMessage: "We use cookies to enhance your experience.",
|
|
3033
|
+
acceptAll: "Accept All",
|
|
3034
|
+
declineAll: "Decline",
|
|
3035
|
+
preferences: "Preferences",
|
|
3036
|
+
modalTitle: "Cookie Preferences",
|
|
3037
|
+
modalIntro: "Customize your cookie preferences below.",
|
|
3038
|
+
save: "Save Preferences",
|
|
3039
|
+
necessaryAlwaysOn: "Necessary cookies (always active)"
|
|
3040
|
+
},
|
|
3041
|
+
es: {
|
|
3042
|
+
bannerMessage: "Utilizamos cookies para mejorar su experiencia.",
|
|
3043
|
+
acceptAll: "Aceptar Todo",
|
|
3044
|
+
declineAll: "Rechazar",
|
|
3045
|
+
preferences: "Preferencias",
|
|
3046
|
+
modalTitle: "Preferencias de Cookies",
|
|
3047
|
+
modalIntro: "Personalice sus preferencias de cookies a continuaci\xF3n.",
|
|
3048
|
+
save: "Guardar Preferencias",
|
|
3049
|
+
necessaryAlwaysOn: "Cookies necess\xE1rias (sempre ativas)"
|
|
3050
|
+
},
|
|
3051
|
+
fr: {
|
|
3052
|
+
bannerMessage: "Nous utilisons des cookies pour am\xE9liorer votre exp\xE9rience.",
|
|
3053
|
+
acceptAll: "Tout Accepter",
|
|
3054
|
+
declineAll: "Refuser",
|
|
3055
|
+
preferences: "Pr\xE9f\xE9rences",
|
|
3056
|
+
modalTitle: "Pr\xE9f\xE9rences des Cookies",
|
|
3057
|
+
modalIntro: "Personnalisez vos pr\xE9f\xE9rences de cookies ci-dessous.",
|
|
3058
|
+
save: "Enregistrer les Pr\xE9f\xE9rences",
|
|
3059
|
+
necessaryAlwaysOn: "Cookies n\xE9cessaires (toujours actifs)"
|
|
3060
|
+
}
|
|
3061
|
+
},
|
|
3062
|
+
// Textos técnicos
|
|
3063
|
+
technical: {
|
|
3064
|
+
sessionCookies: "Cookies de sess\xE3o s\xE3o tempor\xE1rios e expiram quando voc\xEA fecha o navegador.",
|
|
3065
|
+
persistentCookies: "Cookies persistentes permanecem no seu dispositivo at\xE9 expirarem ou serem removidos.",
|
|
3066
|
+
thirdPartyCookies: "Cookies de terceiros s\xE3o definidos por dom\xEDnios diferentes do site que voc\xEA est\xE1 visitando.",
|
|
3067
|
+
browserSettings: "Voc\xEA pode gerenciar cookies nas configura\xE7\xF5es do seu navegador.",
|
|
3068
|
+
disablingImpact: "Desabilitar cookies pode afetar a funcionalidade do site."
|
|
3069
|
+
},
|
|
3070
|
+
// Cookie details
|
|
3071
|
+
cookieDetails: {
|
|
3072
|
+
tableHeaders: {
|
|
3073
|
+
name: "Nome",
|
|
3074
|
+
purpose: "Finalidade",
|
|
3075
|
+
duration: "Dura\xE7\xE3o",
|
|
3076
|
+
provider: "Fornecedor",
|
|
3077
|
+
type: "Tipo"
|
|
3078
|
+
},
|
|
3079
|
+
noCookies: "Nenhum cookie encontrado para esta categoria.",
|
|
3080
|
+
toggleDetails: {
|
|
3081
|
+
expand: "Ver detalhes",
|
|
3082
|
+
collapse: "Ocultar detalhes"
|
|
3083
|
+
}
|
|
3084
|
+
}
|
|
3085
|
+
};
|
|
3086
|
+
function resolveTexts(texts, options = {}) {
|
|
3087
|
+
const { language = "pt", variant } = options;
|
|
3088
|
+
let resolved = { ...texts };
|
|
3089
|
+
if (variant && texts.variants?.[variant]) {
|
|
3090
|
+
resolved = { ...resolved, ...texts.variants[variant] };
|
|
3091
|
+
}
|
|
3092
|
+
if (language !== "pt" && texts.i18n?.[language]) {
|
|
3093
|
+
resolved = { ...resolved, ...texts.i18n[language] };
|
|
3094
|
+
}
|
|
3095
|
+
return resolved;
|
|
3096
|
+
}
|
|
3097
|
+
var TEXT_TEMPLATES = {
|
|
3098
|
+
ecommerce: {
|
|
3099
|
+
...EXPANDED_DEFAULT_TEXTS,
|
|
3100
|
+
bannerMessage: "Utilizamos cookies para personalizar ofertas e melhorar sua experi\xEAncia de compra.",
|
|
3101
|
+
acceptAll: "Aceitar e continuar",
|
|
3102
|
+
variants: {
|
|
3103
|
+
casual: {
|
|
3104
|
+
bannerMessage: "\u{1F6D2} Usamos cookies para encontrar as melhores ofertas para voc\xEA!",
|
|
3105
|
+
acceptAll: "Quero ofertas personalizadas!"
|
|
3106
|
+
}
|
|
3107
|
+
}
|
|
3108
|
+
},
|
|
3109
|
+
saas: {
|
|
3110
|
+
...EXPANDED_DEFAULT_TEXTS,
|
|
3111
|
+
bannerMessage: "Utilizamos cookies para otimizar o desempenho da aplica\xE7\xE3o e sua experi\xEAncia.",
|
|
3112
|
+
acceptAll: "Aceitar e otimizar",
|
|
3113
|
+
variants: {
|
|
3114
|
+
formal: {
|
|
3115
|
+
bannerMessage: "Esta aplica\xE7\xE3o utiliza cookies para an\xE1lise de performance e melhoria cont\xEDnua da experi\xEAncia do usu\xE1rio.",
|
|
3116
|
+
acceptAll: "Autorizar coleta de dados de uso"
|
|
3117
|
+
}
|
|
3118
|
+
}
|
|
3119
|
+
},
|
|
3120
|
+
government: {
|
|
3121
|
+
...EXPANDED_DEFAULT_TEXTS,
|
|
3122
|
+
bannerMessage: "Este portal utiliza cookies em conformidade com a LGPD para melhorar os servi\xE7os p\xFAblicos.",
|
|
3123
|
+
acceptAll: "Aceitar em conformidade",
|
|
3124
|
+
variants: {
|
|
3125
|
+
formal: {
|
|
3126
|
+
bannerMessage: "Este s\xEDtio eletr\xF4nico do governo utiliza cookies estritamente necess\xE1rios e opcionais, em conformidade com a Lei Geral de Prote\xE7\xE3o de Dados.",
|
|
3127
|
+
acceptAll: "Concordar com o uso de cookies"
|
|
3128
|
+
}
|
|
3129
|
+
}
|
|
3130
|
+
}
|
|
3131
|
+
};
|
|
1740
3132
|
|
|
1741
3133
|
// src/index.ts
|
|
1742
3134
|
init_developerGuidance();
|
|
1743
3135
|
init_logger();
|
|
3136
|
+
init_cookieRegistry();
|
|
1744
3137
|
init_CookieBanner();
|
|
1745
3138
|
init_FloatingPreferencesButton();
|
|
1746
3139
|
init_ConsentContext();
|
|
@@ -1753,27 +3146,55 @@ init_categoryUtils();
|
|
|
1753
3146
|
ConsentScriptLoader,
|
|
1754
3147
|
CookieBanner,
|
|
1755
3148
|
DEFAULT_PROJECT_CATEGORIES,
|
|
3149
|
+
EXPANDED_DEFAULT_TEXTS,
|
|
1756
3150
|
FloatingPreferencesButton,
|
|
3151
|
+
GUIDANCE_PRESETS,
|
|
3152
|
+
INTEGRATION_TEMPLATES,
|
|
1757
3153
|
LogLevel,
|
|
1758
3154
|
PreferencesModal,
|
|
3155
|
+
TEXT_TEMPLATES,
|
|
1759
3156
|
analyzeDeveloperConfiguration,
|
|
3157
|
+
analyzeIntegrationCategories,
|
|
3158
|
+
autoConfigureCategories,
|
|
3159
|
+
categorizeDiscoveredCookies,
|
|
3160
|
+
createClarityIntegration,
|
|
3161
|
+
createCorporateIntegrations,
|
|
1760
3162
|
createDefaultConsentTheme,
|
|
3163
|
+
createECommerceIntegrations,
|
|
3164
|
+
createFacebookPixelIntegration,
|
|
1761
3165
|
createGoogleAnalyticsIntegration,
|
|
1762
3166
|
createGoogleTagManagerIntegration,
|
|
3167
|
+
createHotjarIntegration,
|
|
3168
|
+
createIntercomIntegration,
|
|
3169
|
+
createMixpanelIntegration,
|
|
1763
3170
|
createProjectPreferences,
|
|
3171
|
+
createSaaSIntegrations,
|
|
1764
3172
|
createUserWayIntegration,
|
|
3173
|
+
createZendeskChatIntegration,
|
|
1765
3174
|
defaultConsentTheme,
|
|
1766
3175
|
defaultTexts,
|
|
3176
|
+
detectConsentCookieName,
|
|
3177
|
+
discoverRuntimeCookies,
|
|
3178
|
+
extractCategoriesFromIntegrations,
|
|
1767
3179
|
getAllProjectCategories,
|
|
3180
|
+
getCookiesInfoForCategory,
|
|
1768
3181
|
loadScript,
|
|
3182
|
+
logDeveloperGuidance,
|
|
1769
3183
|
openPreferencesModal,
|
|
3184
|
+
resolveTexts,
|
|
3185
|
+
setCookieCatalogOverrides,
|
|
3186
|
+
setCookieCategoryOverrides,
|
|
1770
3187
|
setDebugLogging,
|
|
3188
|
+
suggestCategoryForScript,
|
|
1771
3189
|
useCategories,
|
|
1772
3190
|
useCategoryStatus,
|
|
1773
3191
|
useConsent,
|
|
1774
3192
|
useConsentHydration,
|
|
1775
3193
|
useConsentScriptLoader,
|
|
1776
3194
|
useConsentTexts,
|
|
3195
|
+
useDeveloperGuidance,
|
|
1777
3196
|
useOpenPreferencesModal,
|
|
3197
|
+
validateIntegrationCategories,
|
|
3198
|
+
validateNecessaryClassification,
|
|
1778
3199
|
validateProjectPreferences
|
|
1779
3200
|
});
|