react-lgpd-consent 0.3.7 → 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 +113 -0
- package/QUICKSTART.en.md +77 -0
- package/QUICKSTART.md +351 -1
- package/README.en.md +20 -0
- package/README.md +31 -0
- package/dist/{PreferencesModal-3KKTKVII.js → PreferencesModal-RNRD3JKB.js} +1 -1
- package/dist/{chunk-TKN3PNIW.js → chunk-VOQUCGOA.js} +916 -226
- package/dist/index.cjs +1712 -261
- package/dist/index.d.cts +1814 -227
- package/dist/index.d.ts +1814 -227
- package/dist/index.js +738 -8
- package/package.json +50 -22
package/dist/index.cjs
CHANGED
|
@@ -30,185 +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
|
-
enabledCategories.forEach((categoryId) => {
|
|
78
|
-
const categoryInfo = categoryNames[categoryId];
|
|
79
|
-
if (categoryInfo) {
|
|
80
|
-
guidance.activeCategoriesInfo.push({
|
|
81
|
-
id: categoryId,
|
|
82
|
-
name: categoryInfo.name,
|
|
83
|
-
description: categoryInfo.description,
|
|
84
|
-
essential: false,
|
|
85
|
-
uiRequired: true
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
const totalToggleable = guidance.activeCategoriesInfo.filter((c) => c.uiRequired).length;
|
|
90
|
-
if (totalToggleable === 0) {
|
|
91
|
-
guidance.suggestions.push(
|
|
92
|
-
'Apenas cookies necess\xE1rios est\xE3o configurados. Para compliance completo LGPD, considere adicionar categorias como "analytics" ou "functional" conforme uso real.'
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
if (totalToggleable > 5) {
|
|
96
|
-
guidance.warnings.push(
|
|
97
|
-
`${totalToggleable} categorias opcionais detectadas. UI com muitas op\xE7\xF5es pode prejudicar experi\xEAncia do usu\xE1rio. Considere agrupar categorias similares.`
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
return guidance;
|
|
101
42
|
}
|
|
102
|
-
function
|
|
103
|
-
|
|
104
|
-
const nodeEnv = typeof gt.process !== "undefined" ? gt.process?.env?.NODE_ENV : void 0;
|
|
105
|
-
const isProd = nodeEnv === "production" || gt.__LGPD_PRODUCTION__ === true;
|
|
106
|
-
const isDisabled = !!disableGuidanceProp || gt.__LGPD_DISABLE_GUIDANCE__ === true;
|
|
107
|
-
if (isProd || isDisabled) return;
|
|
108
|
-
const PREFIX = "[\u{1F36A} LGPD-CONSENT]";
|
|
109
|
-
if (guidance.warnings.length > 0) {
|
|
110
|
-
console.group(`${PREFIX} \u26A0\uFE0F Avisos de Configura\xE7\xE3o`);
|
|
111
|
-
guidance.warnings.forEach((msg) => console.warn(`${PREFIX} ${msg}`));
|
|
112
|
-
console.groupEnd();
|
|
113
|
-
}
|
|
114
|
-
if (guidance.suggestions.length > 0) {
|
|
115
|
-
console.group(`${PREFIX} \u{1F4A1} Sugest\xF5es`);
|
|
116
|
-
guidance.suggestions.forEach((msg) => console.info(`${PREFIX} ${msg}`));
|
|
117
|
-
console.groupEnd();
|
|
118
|
-
}
|
|
119
|
-
if (guidance.usingDefaults) {
|
|
120
|
-
console.warn(
|
|
121
|
-
`${PREFIX} \u{1F4CB} Usando configura\xE7\xE3o padr\xE3o. Para personalizar, use a prop "categories" no ConsentProvider.`
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
const rows = guidance.activeCategoriesInfo.map((cat) => ({
|
|
125
|
-
ID: cat.id,
|
|
126
|
-
Nome: cat.name,
|
|
127
|
-
"Toggle UI?": cat.uiRequired ? "\u2705 SIM" : "\u274C N\xC3O (sempre ativo)",
|
|
128
|
-
"Essencial?": cat.essential ? "\u{1F512} SIM" : "\u2699\uFE0F N\xC3O"
|
|
129
|
-
}));
|
|
130
|
-
if (typeof console.table === "function") {
|
|
131
|
-
console.group(`${PREFIX} \u{1F527} Categorias Ativas (para UI customizada)`);
|
|
132
|
-
console.table(rows);
|
|
133
|
-
console.info(`${PREFIX} \u2139\uFE0F Use estes dados para criar componentes customizados adequados.`);
|
|
134
|
-
console.groupEnd();
|
|
135
|
-
} else {
|
|
136
|
-
console.log(`${PREFIX} \u{1F527} Categorias Ativas (para UI customizada)`, rows);
|
|
137
|
-
console.info(`${PREFIX} \u2139\uFE0F Use estes dados para criar componentes customizados adequados.`);
|
|
138
|
-
}
|
|
43
|
+
function setCookieCategoryOverrides(map) {
|
|
44
|
+
COOKIE_CATEGORY_OVERRIDES = { ...COOKIE_CATEGORY_OVERRIDES, ...map };
|
|
139
45
|
}
|
|
140
|
-
function
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
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
|
+
});
|
|
71
|
+
}
|
|
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
|
+
});
|
|
147
80
|
}
|
|
148
|
-
}
|
|
149
|
-
return
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
150
83
|
}
|
|
151
|
-
var
|
|
152
|
-
var
|
|
153
|
-
"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"() {
|
|
154
87
|
"use strict";
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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: []
|
|
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
|
+
]
|
|
158
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 = {};
|
|
159
216
|
}
|
|
160
217
|
});
|
|
161
218
|
|
|
162
|
-
// src/
|
|
163
|
-
function
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
};
|
|
178
|
-
}, [config]);
|
|
179
|
-
React2.useEffect(() => {
|
|
180
|
-
logDeveloperGuidance(contextValue.guidance, disableDeveloperGuidance);
|
|
181
|
-
}, [contextValue.guidance, disableDeveloperGuidance]);
|
|
182
|
-
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;
|
|
183
234
|
}
|
|
184
|
-
function
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
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 {
|
|
190
259
|
}
|
|
191
|
-
return
|
|
260
|
+
return null;
|
|
192
261
|
}
|
|
193
|
-
function
|
|
194
|
-
const
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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;
|
|
203
288
|
}
|
|
204
|
-
var
|
|
205
|
-
|
|
206
|
-
"src/context/CategoriesContext.tsx"() {
|
|
289
|
+
var init_cookieDiscovery = __esm({
|
|
290
|
+
"src/utils/cookieDiscovery.ts"() {
|
|
207
291
|
"use strict";
|
|
208
|
-
|
|
209
|
-
init_developerGuidance();
|
|
210
|
-
import_jsx_runtime = require("react/jsx-runtime");
|
|
211
|
-
CategoriesContext = React2.createContext(null);
|
|
292
|
+
init_cookieRegistry();
|
|
212
293
|
}
|
|
213
294
|
});
|
|
214
295
|
|
|
@@ -493,6 +574,497 @@ var init_cookieUtils = __esm({
|
|
|
493
574
|
}
|
|
494
575
|
});
|
|
495
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
|
+
|
|
496
1068
|
// src/utils/categoryUtils.ts
|
|
497
1069
|
function createProjectPreferences(config, defaultValue = false) {
|
|
498
1070
|
const preferences = {
|
|
@@ -505,6 +1077,12 @@ function createProjectPreferences(config, defaultValue = false) {
|
|
|
505
1077
|
preferences[category] = defaultValue;
|
|
506
1078
|
}
|
|
507
1079
|
});
|
|
1080
|
+
const customCategories = config?.customCategories || [];
|
|
1081
|
+
customCategories.forEach((cat) => {
|
|
1082
|
+
if (cat.id && cat.id !== "necessary") {
|
|
1083
|
+
preferences[cat.id] = defaultValue;
|
|
1084
|
+
}
|
|
1085
|
+
});
|
|
508
1086
|
return preferences;
|
|
509
1087
|
}
|
|
510
1088
|
function validateProjectPreferences(preferences, config) {
|
|
@@ -518,6 +1096,13 @@ function validateProjectPreferences(preferences, config) {
|
|
|
518
1096
|
validPreferences[category] = preferences[category];
|
|
519
1097
|
}
|
|
520
1098
|
});
|
|
1099
|
+
const customCategories = config?.customCategories || [];
|
|
1100
|
+
customCategories.forEach((cat) => {
|
|
1101
|
+
const id = cat.id;
|
|
1102
|
+
if (id && id !== "necessary" && preferences[id] !== void 0) {
|
|
1103
|
+
validPreferences[id] = preferences[id];
|
|
1104
|
+
}
|
|
1105
|
+
});
|
|
521
1106
|
return validPreferences;
|
|
522
1107
|
}
|
|
523
1108
|
function getAllProjectCategories(config) {
|
|
@@ -535,6 +1120,12 @@ function getAllProjectCategories(config) {
|
|
|
535
1120
|
allCategories.push(getDefaultCategoryDefinition(category));
|
|
536
1121
|
}
|
|
537
1122
|
});
|
|
1123
|
+
const customCategories = config?.customCategories || [];
|
|
1124
|
+
customCategories.forEach((cat) => {
|
|
1125
|
+
if (cat.id && cat.id !== "necessary") {
|
|
1126
|
+
allCategories.push({ ...cat, essential: !!cat.essential });
|
|
1127
|
+
}
|
|
1128
|
+
});
|
|
538
1129
|
return allCategories;
|
|
539
1130
|
}
|
|
540
1131
|
function getDefaultCategoryDefinition(category) {
|
|
@@ -567,40 +1158,20 @@ function getDefaultCategoryDefinition(category) {
|
|
|
567
1158
|
id: "social",
|
|
568
1159
|
name: "Redes Sociais",
|
|
569
1160
|
description: "Cookies para integra\xE7\xE3o com redes sociais e compartilhamento",
|
|
570
|
-
essential: false
|
|
571
|
-
},
|
|
572
|
-
personalization: {
|
|
573
|
-
id: "personalization",
|
|
574
|
-
name: "Personaliza\xE7\xE3o",
|
|
575
|
-
description: "Cookies para personaliza\xE7\xE3o de conte\xFAdo e experi\xEAncia",
|
|
576
|
-
essential: false
|
|
577
|
-
}
|
|
578
|
-
};
|
|
579
|
-
return definitions[category];
|
|
580
|
-
}
|
|
581
|
-
var init_categoryUtils = __esm({
|
|
582
|
-
"src/utils/categoryUtils.ts"() {
|
|
583
|
-
"use strict";
|
|
584
|
-
}
|
|
585
|
-
});
|
|
586
|
-
|
|
587
|
-
// src/context/DesignContext.tsx
|
|
588
|
-
function DesignProvider({
|
|
589
|
-
tokens,
|
|
590
|
-
children
|
|
591
|
-
}) {
|
|
592
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DesignContext.Provider, { value: tokens, children });
|
|
593
|
-
}
|
|
594
|
-
function useDesignTokens() {
|
|
595
|
-
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];
|
|
596
1171
|
}
|
|
597
|
-
var
|
|
598
|
-
|
|
599
|
-
"src/context/DesignContext.tsx"() {
|
|
1172
|
+
var init_categoryUtils = __esm({
|
|
1173
|
+
"src/utils/categoryUtils.ts"() {
|
|
600
1174
|
"use strict";
|
|
601
|
-
React3 = __toESM(require("react"), 1);
|
|
602
|
-
import_jsx_runtime2 = require("react/jsx-runtime");
|
|
603
|
-
DesignContext = React3.createContext(void 0);
|
|
604
1175
|
}
|
|
605
1176
|
});
|
|
606
1177
|
|
|
@@ -678,6 +1249,7 @@ var init_Branding = __esm({
|
|
|
678
1249
|
// src/components/CookieBanner.tsx
|
|
679
1250
|
function CookieBanner({
|
|
680
1251
|
policyLinkUrl,
|
|
1252
|
+
termsLinkUrl,
|
|
681
1253
|
debug,
|
|
682
1254
|
blocking = true,
|
|
683
1255
|
hideBranding = false,
|
|
@@ -697,15 +1269,15 @@ function CookieBanner({
|
|
|
697
1269
|
hideBranding
|
|
698
1270
|
});
|
|
699
1271
|
if (!open) return null;
|
|
700
|
-
const bannerStyle = {
|
|
1272
|
+
const bannerStyle = (theme) => ({
|
|
701
1273
|
p: designTokens?.spacing?.padding?.banner ?? 2,
|
|
702
1274
|
maxWidth: 720,
|
|
703
1275
|
mx: "auto",
|
|
704
|
-
backgroundColor: designTokens?.colors?.background,
|
|
705
|
-
color: designTokens?.colors?.text,
|
|
1276
|
+
backgroundColor: designTokens?.colors?.background ?? theme.palette.background?.paper,
|
|
1277
|
+
color: designTokens?.colors?.text ?? theme.palette.text?.primary,
|
|
706
1278
|
borderRadius: designTokens?.spacing?.borderRadius?.banner,
|
|
707
1279
|
fontFamily: designTokens?.typography?.fontFamily
|
|
708
|
-
};
|
|
1280
|
+
});
|
|
709
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: [
|
|
710
1282
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_Typography2.default, { variant: "body2", sx: { fontSize: designTokens?.typography?.fontSize?.banner }, children: [
|
|
711
1283
|
texts.bannerMessage,
|
|
@@ -771,27 +1343,51 @@ function CookieBanner({
|
|
|
771
1343
|
width: designTokens?.layout?.width?.desktop ?? "100%",
|
|
772
1344
|
p: 2
|
|
773
1345
|
};
|
|
774
|
-
let backdropColor = "rgba(0, 0, 0, 0.4)";
|
|
775
1346
|
const backdropToken = designTokens?.layout?.backdrop;
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
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) {
|
|
782
1378
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
783
1379
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
784
1380
|
import_Box.default,
|
|
785
1381
|
{
|
|
786
|
-
sx: {
|
|
1382
|
+
sx: (theme) => ({
|
|
787
1383
|
position: "fixed",
|
|
788
1384
|
top: 0,
|
|
789
1385
|
left: 0,
|
|
790
1386
|
right: 0,
|
|
791
1387
|
bottom: 0,
|
|
792
|
-
backgroundColor:
|
|
1388
|
+
backgroundColor: resolveBackdropColor(theme),
|
|
793
1389
|
zIndex: 1299
|
|
794
|
-
}
|
|
1390
|
+
})
|
|
795
1391
|
}
|
|
796
1392
|
),
|
|
797
1393
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_Box.default, { sx: positionStyle, children: bannerContent })
|
|
@@ -1023,7 +1619,9 @@ function ConsentProvider({
|
|
|
1023
1619
|
onPreferencesSaved,
|
|
1024
1620
|
cookie: cookieOpts,
|
|
1025
1621
|
disableDeveloperGuidance,
|
|
1026
|
-
|
|
1622
|
+
guidanceConfig,
|
|
1623
|
+
children,
|
|
1624
|
+
disableDiscoveryLog
|
|
1027
1625
|
}) {
|
|
1028
1626
|
const texts = React4.useMemo(() => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }), [textsProp]);
|
|
1029
1627
|
const cookie = React4.useMemo(
|
|
@@ -1035,7 +1633,15 @@ function ConsentProvider({
|
|
|
1035
1633
|
if (categories) return categories;
|
|
1036
1634
|
return DEFAULT_PROJECT_CATEGORIES;
|
|
1037
1635
|
}, [categories]);
|
|
1038
|
-
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]);
|
|
1039
1645
|
const boot = React4.useMemo(() => {
|
|
1040
1646
|
if (initialState) return { ...initialState, isModalOpen: false };
|
|
1041
1647
|
return createFullConsentState(
|
|
@@ -1119,6 +1725,7 @@ function ConsentProvider({
|
|
|
1119
1725
|
{
|
|
1120
1726
|
config: finalCategoriesConfig,
|
|
1121
1727
|
disableDeveloperGuidance,
|
|
1728
|
+
disableDiscoveryLog,
|
|
1122
1729
|
children: [
|
|
1123
1730
|
children,
|
|
1124
1731
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(React4.Suspense, { fallback: null, children: PreferencesModalComponent ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
@@ -1208,19 +1815,19 @@ function useConsentTextsInternal() {
|
|
|
1208
1815
|
function useConsentHydrationInternal() {
|
|
1209
1816
|
return React4.useContext(HydrationCtx);
|
|
1210
1817
|
}
|
|
1211
|
-
var
|
|
1818
|
+
var import_styles2, React4, import_jsx_runtime6, PreferencesModal, DEFAULT_TEXTS, StateCtx, ActionsCtx, TextsCtx, HydrationCtx, defaultTexts;
|
|
1212
1819
|
var init_ConsentContext = __esm({
|
|
1213
1820
|
"src/context/ConsentContext.tsx"() {
|
|
1214
1821
|
"use strict";
|
|
1215
|
-
React4 = __toESM(require("react"), 1);
|
|
1216
1822
|
import_styles2 = require("@mui/material/styles");
|
|
1217
|
-
|
|
1823
|
+
React4 = __toESM(require("react"), 1);
|
|
1218
1824
|
init_categoryUtils();
|
|
1219
|
-
|
|
1220
|
-
init_DesignContext();
|
|
1221
|
-
init_developerGuidance();
|
|
1825
|
+
init_cookieUtils();
|
|
1222
1826
|
init_useConsent();
|
|
1827
|
+
init_developerGuidance();
|
|
1223
1828
|
init_logger();
|
|
1829
|
+
init_CategoriesContext();
|
|
1830
|
+
init_DesignContext();
|
|
1224
1831
|
init_CookieBanner();
|
|
1225
1832
|
init_FloatingPreferencesButton();
|
|
1226
1833
|
import_jsx_runtime6 = require("react/jsx-runtime");
|
|
@@ -1297,25 +1904,30 @@ function useConsentTexts() {
|
|
|
1297
1904
|
function useConsentHydration() {
|
|
1298
1905
|
return useConsentHydrationInternal();
|
|
1299
1906
|
}
|
|
1907
|
+
function _registerGlobalOpenPreferences(openPreferences) {
|
|
1908
|
+
globalOpenPreferences = openPreferences;
|
|
1909
|
+
}
|
|
1910
|
+
function _unregisterGlobalOpenPreferences() {
|
|
1911
|
+
globalOpenPreferences = null;
|
|
1912
|
+
}
|
|
1300
1913
|
function useOpenPreferencesModal() {
|
|
1301
|
-
const
|
|
1302
|
-
|
|
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;
|
|
1303
1921
|
}
|
|
1304
1922
|
function openPreferencesModal() {
|
|
1305
1923
|
if (globalOpenPreferences) {
|
|
1306
1924
|
globalOpenPreferences();
|
|
1307
1925
|
} else {
|
|
1308
1926
|
logger.warn(
|
|
1309
|
-
"openPreferencesModal
|
|
1927
|
+
"openPreferencesModal called but no ConsentProvider is mounted. Make sure ConsentProvider is rendered before calling this function."
|
|
1310
1928
|
);
|
|
1311
1929
|
}
|
|
1312
1930
|
}
|
|
1313
|
-
function _registerGlobalOpenPreferences(openPreferences) {
|
|
1314
|
-
globalOpenPreferences = openPreferences;
|
|
1315
|
-
}
|
|
1316
|
-
function _unregisterGlobalOpenPreferences() {
|
|
1317
|
-
globalOpenPreferences = null;
|
|
1318
|
-
}
|
|
1319
1931
|
var globalOpenPreferences;
|
|
1320
1932
|
var init_useConsent = __esm({
|
|
1321
1933
|
"src/hooks/useConsent.ts"() {
|
|
@@ -1338,7 +1950,7 @@ function PreferencesModal2({
|
|
|
1338
1950
|
const { preferences, setPreferences, closePreferences, isModalOpen } = useConsent();
|
|
1339
1951
|
const texts = useConsentTexts();
|
|
1340
1952
|
const designTokens = useDesignTokens();
|
|
1341
|
-
const { toggleableCategories } = useCategories();
|
|
1953
|
+
const { toggleableCategories, allCategories } = useCategories();
|
|
1342
1954
|
const [tempPreferences, setTempPreferences] = (0, import_react2.useState)(() => {
|
|
1343
1955
|
const initialPrefs = { necessary: true };
|
|
1344
1956
|
toggleableCategories.forEach((category) => {
|
|
@@ -1363,43 +1975,126 @@ function PreferencesModal2({
|
|
|
1363
1975
|
setTempPreferences(preferences);
|
|
1364
1976
|
closePreferences();
|
|
1365
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
|
+
});
|
|
1366
1987
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_Dialog.default, { "aria-labelledby": "cookie-pref-title", open, onClose: handleCancel, ...DialogProps2, children: [
|
|
1367
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1368
|
-
|
|
1369
|
-
{
|
|
1370
|
-
id: "cookie-pref-title",
|
|
1371
|
-
sx: { fontSize: designTokens?.typography?.fontSize?.modal ?? void 0 },
|
|
1372
|
-
children: texts.modalTitle
|
|
1373
|
-
}
|
|
1374
|
-
),
|
|
1375
|
-
/* @__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: [
|
|
1376
1990
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1377
1991
|
import_Typography3.default,
|
|
1378
1992
|
{
|
|
1379
1993
|
variant: "body2",
|
|
1380
|
-
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
|
+
}),
|
|
1381
1999
|
children: texts.modalIntro
|
|
1382
2000
|
}
|
|
1383
2001
|
),
|
|
1384
2002
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_FormGroup.default, { children: [
|
|
1385
|
-
toggleableCategories.map((category) =>
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
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,
|
|
1390
2040
|
{
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
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}`
|
|
1396
2052
|
}
|
|
1397
2053
|
),
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
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
|
+
] })
|
|
1403
2098
|
] })
|
|
1404
2099
|
] }),
|
|
1405
2100
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_DialogActions.default, { children: [
|
|
@@ -1409,10 +2104,11 @@ function PreferencesModal2({
|
|
|
1409
2104
|
!hideBranding && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Branding, { variant: "modal" })
|
|
1410
2105
|
] });
|
|
1411
2106
|
}
|
|
1412
|
-
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;
|
|
1413
2108
|
var init_PreferencesModal = __esm({
|
|
1414
2109
|
"src/components/PreferencesModal.tsx"() {
|
|
1415
2110
|
"use strict";
|
|
2111
|
+
import_Box2 = __toESM(require("@mui/material/Box"), 1);
|
|
1416
2112
|
import_Button2 = __toESM(require("@mui/material/Button"), 1);
|
|
1417
2113
|
import_Dialog = __toESM(require("@mui/material/Dialog"), 1);
|
|
1418
2114
|
import_DialogActions = __toESM(require("@mui/material/DialogActions"), 1);
|
|
@@ -1424,8 +2120,9 @@ var init_PreferencesModal = __esm({
|
|
|
1424
2120
|
import_Typography3 = __toESM(require("@mui/material/Typography"), 1);
|
|
1425
2121
|
import_react2 = require("react");
|
|
1426
2122
|
init_CategoriesContext();
|
|
1427
|
-
init_useConsent();
|
|
1428
2123
|
init_DesignContext();
|
|
2124
|
+
init_useConsent();
|
|
2125
|
+
init_cookieRegistry();
|
|
1429
2126
|
init_Branding();
|
|
1430
2127
|
import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1431
2128
|
}
|
|
@@ -1440,28 +2137,56 @@ __export(index_exports, {
|
|
|
1440
2137
|
ConsentScriptLoader: () => ConsentScriptLoader,
|
|
1441
2138
|
CookieBanner: () => CookieBanner,
|
|
1442
2139
|
DEFAULT_PROJECT_CATEGORIES: () => DEFAULT_PROJECT_CATEGORIES,
|
|
2140
|
+
EXPANDED_DEFAULT_TEXTS: () => EXPANDED_DEFAULT_TEXTS,
|
|
1443
2141
|
FloatingPreferencesButton: () => FloatingPreferencesButton,
|
|
2142
|
+
GUIDANCE_PRESETS: () => GUIDANCE_PRESETS,
|
|
2143
|
+
INTEGRATION_TEMPLATES: () => INTEGRATION_TEMPLATES,
|
|
1444
2144
|
LogLevel: () => LogLevel,
|
|
1445
2145
|
PreferencesModal: () => PreferencesModal2,
|
|
2146
|
+
TEXT_TEMPLATES: () => TEXT_TEMPLATES,
|
|
1446
2147
|
analyzeDeveloperConfiguration: () => analyzeDeveloperConfiguration,
|
|
2148
|
+
analyzeIntegrationCategories: () => analyzeIntegrationCategories,
|
|
2149
|
+
autoConfigureCategories: () => autoConfigureCategories,
|
|
2150
|
+
categorizeDiscoveredCookies: () => categorizeDiscoveredCookies,
|
|
2151
|
+
createClarityIntegration: () => createClarityIntegration,
|
|
2152
|
+
createCorporateIntegrations: () => createCorporateIntegrations,
|
|
1447
2153
|
createDefaultConsentTheme: () => createDefaultConsentTheme,
|
|
2154
|
+
createECommerceIntegrations: () => createECommerceIntegrations,
|
|
2155
|
+
createFacebookPixelIntegration: () => createFacebookPixelIntegration,
|
|
1448
2156
|
createGoogleAnalyticsIntegration: () => createGoogleAnalyticsIntegration,
|
|
1449
2157
|
createGoogleTagManagerIntegration: () => createGoogleTagManagerIntegration,
|
|
2158
|
+
createHotjarIntegration: () => createHotjarIntegration,
|
|
2159
|
+
createIntercomIntegration: () => createIntercomIntegration,
|
|
2160
|
+
createMixpanelIntegration: () => createMixpanelIntegration,
|
|
1450
2161
|
createProjectPreferences: () => createProjectPreferences,
|
|
2162
|
+
createSaaSIntegrations: () => createSaaSIntegrations,
|
|
1451
2163
|
createUserWayIntegration: () => createUserWayIntegration,
|
|
2164
|
+
createZendeskChatIntegration: () => createZendeskChatIntegration,
|
|
1452
2165
|
defaultConsentTheme: () => defaultConsentTheme,
|
|
1453
2166
|
defaultTexts: () => defaultTexts,
|
|
2167
|
+
detectConsentCookieName: () => detectConsentCookieName,
|
|
2168
|
+
discoverRuntimeCookies: () => discoverRuntimeCookies,
|
|
2169
|
+
extractCategoriesFromIntegrations: () => extractCategoriesFromIntegrations,
|
|
1454
2170
|
getAllProjectCategories: () => getAllProjectCategories,
|
|
2171
|
+
getCookiesInfoForCategory: () => getCookiesInfoForCategory,
|
|
1455
2172
|
loadScript: () => loadScript,
|
|
2173
|
+
logDeveloperGuidance: () => logDeveloperGuidance,
|
|
1456
2174
|
openPreferencesModal: () => openPreferencesModal,
|
|
2175
|
+
resolveTexts: () => resolveTexts,
|
|
2176
|
+
setCookieCatalogOverrides: () => setCookieCatalogOverrides,
|
|
2177
|
+
setCookieCategoryOverrides: () => setCookieCategoryOverrides,
|
|
1457
2178
|
setDebugLogging: () => setDebugLogging,
|
|
2179
|
+
suggestCategoryForScript: () => suggestCategoryForScript,
|
|
1458
2180
|
useCategories: () => useCategories,
|
|
1459
2181
|
useCategoryStatus: () => useCategoryStatus,
|
|
1460
2182
|
useConsent: () => useConsent,
|
|
1461
2183
|
useConsentHydration: () => useConsentHydration,
|
|
1462
2184
|
useConsentScriptLoader: () => useConsentScriptLoader,
|
|
1463
2185
|
useConsentTexts: () => useConsentTexts,
|
|
2186
|
+
useDeveloperGuidance: () => useDeveloperGuidance,
|
|
1464
2187
|
useOpenPreferencesModal: () => useOpenPreferencesModal,
|
|
2188
|
+
validateIntegrationCategories: () => validateIntegrationCategories,
|
|
2189
|
+
validateNecessaryClassification: () => validateNecessaryClassification,
|
|
1465
2190
|
validateProjectPreferences: () => validateProjectPreferences
|
|
1466
2191
|
});
|
|
1467
2192
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -1516,6 +2241,9 @@ function loadScript(id, src, category = null, attrs = {}) {
|
|
|
1516
2241
|
});
|
|
1517
2242
|
}
|
|
1518
2243
|
|
|
2244
|
+
// src/index.ts
|
|
2245
|
+
init_cookieDiscovery();
|
|
2246
|
+
|
|
1519
2247
|
// src/utils/theme.ts
|
|
1520
2248
|
var import_styles3 = require("@mui/material/styles");
|
|
1521
2249
|
function createDefaultConsentTheme() {
|
|
@@ -1589,14 +2317,233 @@ var defaultConsentTheme = () => createDefaultConsentTheme();
|
|
|
1589
2317
|
|
|
1590
2318
|
// src/utils/ConsentScriptLoader.tsx
|
|
1591
2319
|
var React5 = __toESM(require("react"), 1);
|
|
2320
|
+
init_CategoriesContext();
|
|
1592
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
|
|
1593
2479
|
init_logger();
|
|
1594
2480
|
function ConsentScriptLoader({
|
|
1595
2481
|
integrations,
|
|
1596
2482
|
reloadOnChange = false
|
|
1597
2483
|
}) {
|
|
1598
2484
|
const { preferences, consented } = useConsent();
|
|
2485
|
+
const categories = useCategories();
|
|
1599
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]);
|
|
1600
2547
|
React5.useEffect(() => {
|
|
1601
2548
|
if (!consented) return;
|
|
1602
2549
|
integrations.forEach(async (integration) => {
|
|
@@ -1649,10 +2596,32 @@ function useConsentScriptLoader() {
|
|
|
1649
2596
|
|
|
1650
2597
|
// src/utils/scriptIntegrations.ts
|
|
1651
2598
|
function createGoogleAnalyticsIntegration(config) {
|
|
2599
|
+
const src = config.scriptUrl ?? `https://www.googletagmanager.com/gtag/js?id=${config.measurementId}`;
|
|
1652
2600
|
return {
|
|
1653
2601
|
id: "google-analytics",
|
|
1654
2602
|
category: "analytics",
|
|
1655
|
-
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
|
+
],
|
|
1656
2625
|
init: () => {
|
|
1657
2626
|
if (typeof window !== "undefined") {
|
|
1658
2627
|
const w = window;
|
|
@@ -1669,29 +2638,30 @@ function createGoogleAnalyticsIntegration(config) {
|
|
|
1669
2638
|
};
|
|
1670
2639
|
}
|
|
1671
2640
|
function createGoogleTagManagerIntegration(config) {
|
|
2641
|
+
const src = config.scriptUrl ?? `https://www.googletagmanager.com/gtm.js?id=${config.containerId}`;
|
|
1672
2642
|
return {
|
|
1673
2643
|
id: "google-tag-manager",
|
|
1674
2644
|
category: "analytics",
|
|
1675
|
-
src
|
|
2645
|
+
src,
|
|
2646
|
+
cookies: ["_gcl_au"],
|
|
1676
2647
|
init: () => {
|
|
1677
2648
|
if (typeof window !== "undefined") {
|
|
1678
2649
|
const dataLayerName = config.dataLayerName || "dataLayer";
|
|
1679
2650
|
const w = window;
|
|
1680
2651
|
const layer = w[dataLayerName] ?? [];
|
|
1681
2652
|
w[dataLayerName] = layer;
|
|
1682
|
-
layer.push({
|
|
1683
|
-
"gtm.start": (/* @__PURE__ */ new Date()).getTime(),
|
|
1684
|
-
event: "gtm.js"
|
|
1685
|
-
});
|
|
2653
|
+
layer.push({ "gtm.start": (/* @__PURE__ */ new Date()).getTime(), event: "gtm.js" });
|
|
1686
2654
|
}
|
|
1687
2655
|
}
|
|
1688
2656
|
};
|
|
1689
2657
|
}
|
|
1690
2658
|
function createUserWayIntegration(config) {
|
|
2659
|
+
const src = config.scriptUrl ?? "https://cdn.userway.org/widget.js";
|
|
1691
2660
|
return {
|
|
1692
2661
|
id: "userway",
|
|
1693
2662
|
category: "functional",
|
|
1694
|
-
src
|
|
2663
|
+
src,
|
|
2664
|
+
cookies: ["_userway_*"],
|
|
1695
2665
|
init: () => {
|
|
1696
2666
|
if (typeof window !== "undefined") {
|
|
1697
2667
|
const w = window;
|
|
@@ -1707,10 +2677,463 @@ var COMMON_INTEGRATIONS = {
|
|
|
1707
2677
|
googleTagManager: createGoogleTagManagerIntegration,
|
|
1708
2678
|
userway: createUserWayIntegration
|
|
1709
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
|
+
};
|
|
1710
3132
|
|
|
1711
3133
|
// src/index.ts
|
|
1712
3134
|
init_developerGuidance();
|
|
1713
3135
|
init_logger();
|
|
3136
|
+
init_cookieRegistry();
|
|
1714
3137
|
init_CookieBanner();
|
|
1715
3138
|
init_FloatingPreferencesButton();
|
|
1716
3139
|
init_ConsentContext();
|
|
@@ -1723,27 +3146,55 @@ init_categoryUtils();
|
|
|
1723
3146
|
ConsentScriptLoader,
|
|
1724
3147
|
CookieBanner,
|
|
1725
3148
|
DEFAULT_PROJECT_CATEGORIES,
|
|
3149
|
+
EXPANDED_DEFAULT_TEXTS,
|
|
1726
3150
|
FloatingPreferencesButton,
|
|
3151
|
+
GUIDANCE_PRESETS,
|
|
3152
|
+
INTEGRATION_TEMPLATES,
|
|
1727
3153
|
LogLevel,
|
|
1728
3154
|
PreferencesModal,
|
|
3155
|
+
TEXT_TEMPLATES,
|
|
1729
3156
|
analyzeDeveloperConfiguration,
|
|
3157
|
+
analyzeIntegrationCategories,
|
|
3158
|
+
autoConfigureCategories,
|
|
3159
|
+
categorizeDiscoveredCookies,
|
|
3160
|
+
createClarityIntegration,
|
|
3161
|
+
createCorporateIntegrations,
|
|
1730
3162
|
createDefaultConsentTheme,
|
|
3163
|
+
createECommerceIntegrations,
|
|
3164
|
+
createFacebookPixelIntegration,
|
|
1731
3165
|
createGoogleAnalyticsIntegration,
|
|
1732
3166
|
createGoogleTagManagerIntegration,
|
|
3167
|
+
createHotjarIntegration,
|
|
3168
|
+
createIntercomIntegration,
|
|
3169
|
+
createMixpanelIntegration,
|
|
1733
3170
|
createProjectPreferences,
|
|
3171
|
+
createSaaSIntegrations,
|
|
1734
3172
|
createUserWayIntegration,
|
|
3173
|
+
createZendeskChatIntegration,
|
|
1735
3174
|
defaultConsentTheme,
|
|
1736
3175
|
defaultTexts,
|
|
3176
|
+
detectConsentCookieName,
|
|
3177
|
+
discoverRuntimeCookies,
|
|
3178
|
+
extractCategoriesFromIntegrations,
|
|
1737
3179
|
getAllProjectCategories,
|
|
3180
|
+
getCookiesInfoForCategory,
|
|
1738
3181
|
loadScript,
|
|
3182
|
+
logDeveloperGuidance,
|
|
1739
3183
|
openPreferencesModal,
|
|
3184
|
+
resolveTexts,
|
|
3185
|
+
setCookieCatalogOverrides,
|
|
3186
|
+
setCookieCategoryOverrides,
|
|
1740
3187
|
setDebugLogging,
|
|
3188
|
+
suggestCategoryForScript,
|
|
1741
3189
|
useCategories,
|
|
1742
3190
|
useCategoryStatus,
|
|
1743
3191
|
useConsent,
|
|
1744
3192
|
useConsentHydration,
|
|
1745
3193
|
useConsentScriptLoader,
|
|
1746
3194
|
useConsentTexts,
|
|
3195
|
+
useDeveloperGuidance,
|
|
1747
3196
|
useOpenPreferencesModal,
|
|
3197
|
+
validateIntegrationCategories,
|
|
3198
|
+
validateNecessaryClassification,
|
|
1748
3199
|
validateProjectPreferences
|
|
1749
3200
|
});
|