react-lgpd-consent 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -50,7 +50,6 @@ function analyzeDeveloperConfiguration(config) {
50
50
  description: "Essenciais para funcionamento b\xE1sico do site",
51
51
  essential: true,
52
52
  uiRequired: false
53
- // Não precisa de toggle (sempre ativo)
54
53
  });
55
54
  const enabledCategories = finalConfig.enabledCategories || [];
56
55
  const categoryNames = {
@@ -84,13 +83,10 @@ function analyzeDeveloperConfiguration(config) {
84
83
  description: categoryInfo.description,
85
84
  essential: false,
86
85
  uiRequired: true
87
- // Precisa de toggle na UI
88
86
  });
89
87
  }
90
88
  });
91
- const totalToggleable = guidance.activeCategoriesInfo.filter(
92
- (c) => c.uiRequired
93
- ).length;
89
+ const totalToggleable = guidance.activeCategoriesInfo.filter((c) => c.uiRequired).length;
94
90
  if (totalToggleable === 0) {
95
91
  guidance.suggestions.push(
96
92
  'Apenas cookies necess\xE1rios est\xE3o configurados. Para compliance completo LGPD, considere adicionar categorias como "analytics" ou "functional" conforme uso real.'
@@ -98,78 +94,66 @@ function analyzeDeveloperConfiguration(config) {
98
94
  }
99
95
  if (totalToggleable > 5) {
100
96
  guidance.warnings.push(
101
- `${totalToggleable} categorias opcionais detectadas. UI com muitas op\xE7\xF5es pode ' +
102
- 'prejudicar experi\xEAncia do usu\xE1rio. Considere agrupar categorias similares.`
97
+ `${totalToggleable} categorias opcionais detectadas. UI com muitas op\xE7\xF5es pode prejudicar experi\xEAncia do usu\xE1rio. Considere agrupar categorias similares.`
103
98
  );
104
99
  }
105
100
  return guidance;
106
101
  }
107
102
  function logDeveloperGuidance(guidance, disableGuidanceProp) {
108
- if (disableGuidanceProp) {
109
- return;
110
- }
111
- const isProduction = (
112
- // 1. NODE_ENV de bundlers (Vite, webpack, etc.)
113
- typeof globalThis.process !== "undefined" && globalThis.process.env?.NODE_ENV === "production" || // 2. Flag customizada para desabilitar logs
114
- typeof globalThis !== "undefined" && globalThis.__LGPD_PRODUCTION__ === true || // 3. Flag de desenvolvimento desabilitada via window global (legado)
115
- typeof window !== "undefined" && window.__LGPD_DISABLE_GUIDANCE__ === true
116
- );
117
- if (isProduction) return;
103
+ const nodeEnv = typeof globalThis.process !== "undefined" ? globalThis.process.env?.NODE_ENV : void 0;
104
+ const isProd = nodeEnv === "production" || globalThis.__LGPD_PRODUCTION__ === true && typeof globalThis !== "undefined";
105
+ const isDisabled = !!disableGuidanceProp || globalThis.__LGPD_DISABLE_GUIDANCE__ === true && typeof globalThis !== "undefined";
106
+ if (isProd || isDisabled) return;
118
107
  const PREFIX = "[\u{1F36A} LGPD-CONSENT]";
119
108
  if (guidance.warnings.length > 0) {
120
109
  console.group(`${PREFIX} \u26A0\uFE0F Avisos de Configura\xE7\xE3o`);
121
- guidance.warnings.forEach((warning) => console.warn(`${PREFIX} ${warning}`));
110
+ guidance.warnings.forEach((msg) => console.warn(`${PREFIX} ${msg}`));
122
111
  console.groupEnd();
123
112
  }
124
113
  if (guidance.suggestions.length > 0) {
125
114
  console.group(`${PREFIX} \u{1F4A1} Sugest\xF5es`);
126
- guidance.suggestions.forEach(
127
- (suggestion) => console.info(`${PREFIX} ${suggestion}`)
128
- );
115
+ guidance.suggestions.forEach((msg) => console.info(`${PREFIX} ${msg}`));
129
116
  console.groupEnd();
130
117
  }
131
118
  if (guidance.usingDefaults) {
132
119
  console.warn(
133
- // Changed from console.info to console.warn
134
120
  `${PREFIX} \u{1F4CB} Usando configura\xE7\xE3o padr\xE3o. Para personalizar, use a prop "categories" no ConsentProvider.`
135
121
  );
136
122
  }
137
- console.group(`${PREFIX} \u{1F527} Categorias Ativas (para UI customizada)`);
138
- console.table(
139
- guidance.activeCategoriesInfo.map((cat) => ({
140
- ID: cat.id,
141
- Nome: cat.name,
142
- "Toggle UI?": cat.uiRequired ? "\u2705 SIM" : "\u274C N\xC3O (sempre ativo)",
143
- "Essencial?": cat.essential ? "\u{1F512} SIM" : "\u2699\uFE0F N\xC3O"
144
- }))
145
- );
146
- console.info(
147
- `${PREFIX} \u2139\uFE0F Use estes dados para criar componentes customizados adequados.`
148
- );
149
- console.groupEnd();
123
+ const rows = guidance.activeCategoriesInfo.map((cat) => ({
124
+ ID: cat.id,
125
+ Nome: cat.name,
126
+ "Toggle UI?": cat.uiRequired ? "\u2705 SIM" : "\u274C N\xC3O (sempre ativo)",
127
+ "Essencial?": cat.essential ? "\u{1F512} SIM" : "\u2699\uFE0F N\xC3O"
128
+ }));
129
+ if (typeof console.table === "function") {
130
+ console.group(`${PREFIX} \u{1F527} Categorias Ativas (para UI customizada)`);
131
+ console.table(rows);
132
+ console.info(`${PREFIX} \u2139\uFE0F Use estes dados para criar componentes customizados adequados.`);
133
+ console.groupEnd();
134
+ } else {
135
+ console.log(`${PREFIX} \u{1F527} Categorias Ativas (para UI customizada)`, rows);
136
+ console.info(`${PREFIX} \u2139\uFE0F Use estes dados para criar componentes customizados adequados.`);
137
+ }
150
138
  }
151
139
  function useDeveloperGuidance(config, disableGuidanceProp) {
152
- const guidance = analyzeDeveloperConfiguration(config);
153
- const stringifiedConfig = React.useMemo(
154
- () => JSON.stringify(config),
155
- [config]
156
- );
157
- React.useEffect(() => {
158
- if (disableGuidanceProp === true) {
159
- return;
140
+ const guidance = import_react.default.useMemo(() => {
141
+ return analyzeDeveloperConfiguration(config);
142
+ }, [config]);
143
+ import_react.default.useEffect(() => {
144
+ if (!disableGuidanceProp) {
145
+ logDeveloperGuidance(guidance, disableGuidanceProp);
160
146
  }
161
- logDeveloperGuidance(guidance, disableGuidanceProp);
162
- }, [guidance, stringifiedConfig, disableGuidanceProp]);
147
+ }, [guidance, disableGuidanceProp]);
163
148
  return guidance;
164
149
  }
165
- var React, DEFAULT_PROJECT_CATEGORIES;
150
+ var import_react, DEFAULT_PROJECT_CATEGORIES;
166
151
  var init_developerGuidance = __esm({
167
152
  "src/utils/developerGuidance.ts"() {
168
153
  "use strict";
169
- React = __toESM(require("react"), 1);
154
+ import_react = __toESM(require("react"), 1);
170
155
  DEFAULT_PROJECT_CATEGORIES = {
171
156
  enabledCategories: ["analytics"]
172
- // Só analytics além de necessary
173
157
  };
174
158
  }
175
159
  });
@@ -178,15 +162,12 @@ var init_developerGuidance = __esm({
178
162
  function CategoriesProvider({
179
163
  children,
180
164
  config,
181
- // NOVO: configuração completa
182
165
  disableDeveloperGuidance
183
166
  }) {
184
167
  const contextValue = React2.useMemo(() => {
185
168
  const finalConfig = config || DEFAULT_PROJECT_CATEGORIES;
186
169
  const guidance = analyzeDeveloperConfiguration(config);
187
- const toggleableCategories = guidance.activeCategoriesInfo.filter(
188
- (cat) => cat.uiRequired
189
- );
170
+ const toggleableCategories = guidance.activeCategoriesInfo.filter((cat) => cat.uiRequired);
190
171
  return {
191
172
  config: finalConfig,
192
173
  guidance,
@@ -226,17 +207,12 @@ var init_CategoriesContext = __esm({
226
207
  React2 = __toESM(require("react"), 1);
227
208
  init_developerGuidance();
228
209
  import_jsx_runtime = require("react/jsx-runtime");
229
- CategoriesContext = React2.createContext(
230
- null
231
- );
210
+ CategoriesContext = React2.createContext(null);
232
211
  }
233
212
  });
234
213
 
235
214
  // src/utils/SafeThemeProvider.tsx
236
- function SafeThemeProvider({
237
- theme,
238
- children
239
- }) {
215
+ function SafeThemeProvider({ theme, children }) {
240
216
  const safeTheme = React3.useMemo(() => createSafeTheme(theme), [theme]);
241
217
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_styles.ThemeProvider, { theme: safeTheme, children });
242
218
  }
@@ -326,16 +302,12 @@ var init_SafeThemeProvider = __esm({
326
302
  function setDebugLogging(enabled, level = 2 /* INFO */) {
327
303
  logger.setEnabled(enabled);
328
304
  logger.setLevel(level);
329
- logger.info(
330
- `Debug logging ${enabled ? "enabled" : "disabled"} with level ${LogLevel[level]}`
331
- );
305
+ logger.info(`Debug logging ${enabled ? "enabled" : "disabled"} with level ${LogLevel[level]}`);
332
306
  }
333
- var IS_DEVELOPMENT, LOG_PREFIX, LogLevel, ConsentLogger, logger;
307
+ var LogLevel, _ConsentLogger, ConsentLogger, logger;
334
308
  var init_logger = __esm({
335
309
  "src/utils/logger.ts"() {
336
310
  "use strict";
337
- IS_DEVELOPMENT = typeof window !== "undefined" && window.__REACT_DEVTOOLS_GLOBAL_HOOK__ || typeof globalThis !== "undefined" && globalThis.process?.env?.NODE_ENV === "development";
338
- LOG_PREFIX = "[react-lgpd-consent]";
339
311
  LogLevel = /* @__PURE__ */ ((LogLevel2) => {
340
312
  LogLevel2[LogLevel2["ERROR"] = 0] = "ERROR";
341
313
  LogLevel2[LogLevel2["WARN"] = 1] = "WARN";
@@ -343,38 +315,93 @@ var init_logger = __esm({
343
315
  LogLevel2[LogLevel2["DEBUG"] = 3] = "DEBUG";
344
316
  return LogLevel2;
345
317
  })(LogLevel || {});
346
- ConsentLogger = class {
318
+ _ConsentLogger = class _ConsentLogger {
347
319
  constructor() {
348
- this.enabled = IS_DEVELOPMENT;
320
+ this.enabled = _ConsentLogger.IS_DEVELOPMENT;
349
321
  this.level = 2 /* INFO */;
350
322
  }
323
+ /**
324
+ * Habilita ou desabilita o sistema de logging.
325
+ * @param {boolean} enabled Se `true`, os logs serão exibidos; caso contrário, serão suprimidos.
326
+ */
351
327
  setEnabled(enabled) {
352
328
  this.enabled = enabled;
353
329
  }
330
+ /**
331
+ * Define o nível mínimo de severidade para os logs.
332
+ * Mensagens com severidade menor que o nível definido não serão exibidas.
333
+ * @param {LogLevel} level O nível mínimo de severidade (ex: `LogLevel.DEBUG` para ver todos os logs).
334
+ */
354
335
  setLevel(level) {
355
336
  this.level = level;
356
337
  }
338
+ /**
339
+ * Registra uma mensagem de erro.
340
+ * @param {...any[]} args Os argumentos a serem logados.
341
+ */
357
342
  error(...args) {
358
343
  if (this.enabled && this.level >= 0 /* ERROR */) {
359
- console.error(LOG_PREFIX, "[ERROR]", ...args);
344
+ console.error(_ConsentLogger.LOG_PREFIX, "[ERROR]", ...args);
360
345
  }
361
346
  }
347
+ /**
348
+ * Registra uma mensagem de aviso.
349
+ * @param {...any[]} args Os argumentos a serem logados.
350
+ */
362
351
  warn(...args) {
363
352
  if (this.enabled && this.level >= 1 /* WARN */) {
364
- console.warn(LOG_PREFIX, "[WARN]", ...args);
353
+ console.warn(_ConsentLogger.LOG_PREFIX, "[WARN]", ...args);
365
354
  }
366
355
  }
356
+ /**
357
+ * Registra uma mensagem informativa.
358
+ * @param {...any[]} args Os argumentos a serem logados.
359
+ */
367
360
  info(...args) {
368
361
  if (this.enabled && this.level >= 2 /* INFO */) {
369
- console.info(LOG_PREFIX, "[INFO]", ...args);
362
+ console.info(_ConsentLogger.LOG_PREFIX, "[INFO]", ...args);
370
363
  }
371
364
  }
365
+ /**
366
+ * Registra uma mensagem de depuração.
367
+ * @param {...any[]} args Os argumentos a serem logados.
368
+ */
372
369
  debug(...args) {
373
370
  if (this.enabled && this.level >= 3 /* DEBUG */) {
374
- console.debug(LOG_PREFIX, "[DEBUG]", ...args);
371
+ console.debug(_ConsentLogger.LOG_PREFIX, "[DEBUG]", ...args);
372
+ }
373
+ }
374
+ /**
375
+ * Inicia um grupo de logs no console.
376
+ * @param {...any[]} args Os argumentos para o título do grupo.
377
+ */
378
+ group(...args) {
379
+ if (this.enabled && this.level >= 3 /* DEBUG */) {
380
+ console.group(_ConsentLogger.LOG_PREFIX, ...args);
381
+ }
382
+ }
383
+ /**
384
+ * Finaliza o grupo de logs mais recente no console.
385
+ */
386
+ groupEnd() {
387
+ if (this.enabled && this.level >= 3 /* DEBUG */) {
388
+ console.groupEnd();
389
+ }
390
+ }
391
+ /**
392
+ * Exibe dados tabulares no console.
393
+ * @param {any} tabularData Os dados a serem exibidos na tabela.
394
+ * @param {string[]} [properties] Um array opcional de propriedades para exibir.
395
+ */
396
+ table(tabularData, properties) {
397
+ if (this.enabled && this.level >= 3 /* DEBUG */) {
398
+ console.table(tabularData, properties);
375
399
  }
376
400
  }
377
- // Logs específicos para troubleshooting
401
+ /**
402
+ * Registra informações sobre a compatibilidade do tema Material-UI.
403
+ * @param {any} themeInfo Objeto com informações do tema.
404
+ */
378
405
  themeCompatibility(themeInfo) {
379
406
  this.debug("Theme compatibility check:", {
380
407
  hasTheme: !!themeInfo,
@@ -384,6 +411,11 @@ var init_logger = __esm({
384
411
  hasDuration: !!themeInfo?.transitions?.duration
385
412
  });
386
413
  }
414
+ /**
415
+ * Registra mudanças no estado de consentimento.
416
+ * @param {string} action A ação que causou a mudança de estado.
417
+ * @param {any} state O estado atual do consentimento.
418
+ */
387
419
  consentState(action, state) {
388
420
  this.debug(`Consent state change [${action}]:`, {
389
421
  consented: state.consented,
@@ -391,6 +423,12 @@ var init_logger = __esm({
391
423
  preferencesCount: Object.keys(state.preferences || {}).length
392
424
  });
393
425
  }
426
+ /**
427
+ * Registra operações de cookie (leitura, escrita, remoção).
428
+ * @param {'read' | 'write' | 'delete'} operation O tipo de operação de cookie.
429
+ * @param {string} cookieName O nome do cookie.
430
+ * @param {any} [data] Os dados do cookie, se aplicável.
431
+ */
394
432
  cookieOperation(operation, cookieName, data) {
395
433
  this.debug(`Cookie ${operation}:`, {
396
434
  name: cookieName,
@@ -398,22 +436,38 @@ var init_logger = __esm({
398
436
  dataSize: data ? JSON.stringify(data).length : 0
399
437
  });
400
438
  }
439
+ /**
440
+ * Registra a renderização de um componente.
441
+ * @param {string} componentName O nome do componente.
442
+ * @param {any} [props] As propriedades do componente.
443
+ */
401
444
  componentRender(componentName, props) {
402
445
  this.debug(`Component render [${componentName}]:`, {
403
446
  hasProps: !!props,
404
447
  propsKeys: props ? Object.keys(props) : []
405
448
  });
406
449
  }
450
+ /**
451
+ * Registra o status de carregamento de scripts de integração.
452
+ * @param {string} scriptName O nome do script.
453
+ * @param {'load' | 'remove'} action A ação realizada (carregar ou remover).
454
+ * @param {boolean} success Se a operação foi bem-sucedida.
455
+ */
407
456
  scriptIntegration(scriptName, action, success) {
408
- this.info(
409
- `Script ${action} [${scriptName}]:`,
410
- success ? "SUCCESS" : "FAILED"
411
- );
457
+ this.info(`Script ${action} [${scriptName}]:`, success ? "SUCCESS" : "FAILED");
412
458
  }
459
+ /**
460
+ * Registra chamadas à API interna da biblioteca.
461
+ * @param {string} method O nome do método da API chamado.
462
+ * @param {any} [params] Os parâmetros passados para o método.
463
+ */
413
464
  apiUsage(method, params) {
414
465
  this.debug(`API call [${method}]:`, params);
415
466
  }
416
467
  };
468
+ _ConsentLogger.IS_DEVELOPMENT = typeof globalThis !== "undefined" && globalThis.process?.env?.NODE_ENV === "development";
469
+ _ConsentLogger.LOG_PREFIX = "[react-lgpd-consent]";
470
+ ConsentLogger = _ConsentLogger;
417
471
  logger = new ConsentLogger();
418
472
  }
419
473
  });
@@ -438,9 +492,7 @@ function readConsentCookie(name = DEFAULT_COOKIE_OPTS.name) {
438
492
  return migrateLegacyCookie(data);
439
493
  }
440
494
  if (data.version !== COOKIE_SCHEMA_VERSION) {
441
- logger.warn(
442
- `Cookie version mismatch: ${data.version} != ${COOKIE_SCHEMA_VERSION}`
443
- );
495
+ logger.warn(`Cookie version mismatch: ${data.version} != ${COOKIE_SCHEMA_VERSION}`);
444
496
  return null;
445
497
  }
446
498
  return data;
@@ -457,12 +509,9 @@ function migrateLegacyCookie(legacyData) {
457
509
  consented: legacyData.consented || false,
458
510
  preferences: legacyData.preferences || { necessary: true },
459
511
  consentDate: now,
460
- // Não temos o original, usar data atual
461
512
  lastUpdate: now,
462
513
  source: "banner",
463
- // Assumir origem banner
464
514
  isModalOpen: false
465
- // Nunca persistir estado de UI
466
515
  };
467
516
  } catch {
468
517
  return null;
@@ -480,11 +529,9 @@ function writeConsentCookie(state, config, opts, source = "banner") {
480
529
  consented: state.consented,
481
530
  preferences: state.preferences,
482
531
  consentDate: state.consentDate || now,
483
- // Preservar data original ou usar atual
484
532
  lastUpdate: now,
485
533
  source,
486
534
  projectConfig: config
487
- // isModalOpen NÃO é persistido (campo de UI apenas)
488
535
  };
489
536
  logger.cookieOperation("write", o.name, cookieData);
490
537
  import_js_cookie.default.set(o.name, JSON.stringify(cookieData), {
@@ -553,6 +600,64 @@ function validateProjectPreferences(preferences, config) {
553
600
  });
554
601
  return validPreferences;
555
602
  }
603
+ function getAllProjectCategories(config) {
604
+ const allCategories = [
605
+ {
606
+ id: "necessary",
607
+ name: "Necess\xE1rios",
608
+ description: "Cookies essenciais para funcionamento b\xE1sico do site",
609
+ essential: true
610
+ }
611
+ ];
612
+ const enabledCategories = config?.enabledCategories || [];
613
+ enabledCategories.forEach((category) => {
614
+ if (category !== "necessary") {
615
+ allCategories.push(getDefaultCategoryDefinition(category));
616
+ }
617
+ });
618
+ return allCategories;
619
+ }
620
+ function getDefaultCategoryDefinition(category) {
621
+ const definitions = {
622
+ necessary: {
623
+ id: "necessary",
624
+ name: "Necess\xE1rios",
625
+ description: "Cookies essenciais para funcionamento b\xE1sico do site",
626
+ essential: true
627
+ },
628
+ analytics: {
629
+ id: "analytics",
630
+ name: "An\xE1lise e Estat\xEDsticas",
631
+ description: "Cookies para an\xE1lise de uso e estat\xEDsticas do site",
632
+ essential: false
633
+ },
634
+ functional: {
635
+ id: "functional",
636
+ name: "Funcionalidades",
637
+ description: "Cookies para funcionalidades extras como prefer\xEAncias e idioma",
638
+ essential: false
639
+ },
640
+ marketing: {
641
+ id: "marketing",
642
+ name: "Marketing e Publicidade",
643
+ description: "Cookies para publicidade direcionada e marketing",
644
+ essential: false
645
+ },
646
+ social: {
647
+ id: "social",
648
+ name: "Redes Sociais",
649
+ description: "Cookies para integra\xE7\xE3o com redes sociais e compartilhamento",
650
+ essential: false
651
+ },
652
+ personalization: {
653
+ id: "personalization",
654
+ name: "Personaliza\xE7\xE3o",
655
+ description: "Cookies para personaliza\xE7\xE3o de conte\xFAdo e experi\xEAncia",
656
+ essential: false
657
+ }
658
+ };
659
+ return definitions[category];
660
+ }
556
661
  var init_categoryUtils = __esm({
557
662
  "src/utils/categoryUtils.ts"() {
558
663
  "use strict";
@@ -754,74 +859,59 @@ function CookieBanner({
754
859
  fontFamily: designTokens?.typography?.fontFamily
755
860
  };
756
861
  const bannerContent = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_Paper.default, { elevation: 3, sx: bannerStyle, ...PaperProps, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_Stack.default, { spacing: 1, children: [
757
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
758
- import_Typography2.default,
759
- {
760
- variant: "body2",
761
- sx: { fontSize: designTokens?.typography?.fontSize?.banner },
762
- children: [
763
- texts.bannerMessage,
764
- " ",
765
- policyLinkUrl && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
766
- import_Link2.default,
767
- {
768
- href: policyLinkUrl,
769
- underline: "hover",
770
- target: "_blank",
771
- rel: "noopener noreferrer",
772
- sx: { color: designTokens?.colors?.primary },
773
- children: texts.policyLink ?? "Saiba mais"
774
- }
775
- )
776
- ]
777
- }
778
- ),
779
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
780
- import_Stack.default,
781
- {
782
- direction: { xs: "column", sm: "row" },
783
- spacing: 1,
784
- justifyContent: "flex-end",
785
- children: [
786
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
787
- import_Button.default,
788
- {
789
- variant: "outlined",
790
- onClick: () => {
791
- logger.apiUsage("rejectAll", { source: "banner" });
792
- rejectAll();
793
- },
794
- sx: { color: designTokens?.colors?.secondary },
795
- children: texts.declineAll
796
- }
797
- ),
798
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
799
- import_Button.default,
800
- {
801
- variant: "contained",
802
- onClick: () => {
803
- logger.apiUsage("acceptAll", { source: "banner" });
804
- acceptAll();
805
- },
806
- sx: { backgroundColor: designTokens?.colors?.primary },
807
- children: texts.acceptAll
808
- }
809
- ),
810
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
811
- import_Button.default,
812
- {
813
- variant: "text",
814
- onClick: () => {
815
- logger.apiUsage("openPreferences", { source: "banner" });
816
- openPreferences();
817
- },
818
- sx: { color: designTokens?.colors?.text },
819
- children: texts.preferences
820
- }
821
- )
822
- ]
823
- }
824
- ),
862
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_Typography2.default, { variant: "body2", sx: { fontSize: designTokens?.typography?.fontSize?.banner }, children: [
863
+ texts.bannerMessage,
864
+ " ",
865
+ policyLinkUrl && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
866
+ import_Link2.default,
867
+ {
868
+ href: policyLinkUrl,
869
+ underline: "hover",
870
+ target: "_blank",
871
+ rel: "noopener noreferrer",
872
+ sx: { color: designTokens?.colors?.primary },
873
+ children: texts.policyLink ?? "Saiba mais"
874
+ }
875
+ )
876
+ ] }),
877
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_Stack.default, { direction: { xs: "column", sm: "row" }, spacing: 1, justifyContent: "flex-end", children: [
878
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
879
+ import_Button.default,
880
+ {
881
+ variant: "outlined",
882
+ onClick: () => {
883
+ logger.apiUsage("rejectAll", { source: "banner" });
884
+ rejectAll();
885
+ },
886
+ sx: { color: designTokens?.colors?.secondary },
887
+ children: texts.declineAll
888
+ }
889
+ ),
890
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
891
+ import_Button.default,
892
+ {
893
+ variant: "contained",
894
+ onClick: () => {
895
+ logger.apiUsage("acceptAll", { source: "banner" });
896
+ acceptAll();
897
+ },
898
+ sx: { backgroundColor: designTokens?.colors?.primary },
899
+ children: texts.acceptAll
900
+ }
901
+ ),
902
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
903
+ import_Button.default,
904
+ {
905
+ variant: "text",
906
+ onClick: () => {
907
+ logger.apiUsage("openPreferences", { source: "banner" });
908
+ openPreferences();
909
+ },
910
+ sx: { color: designTokens?.colors?.text },
911
+ children: texts.preferences
912
+ }
913
+ )
914
+ ] }),
825
915
  !hideBranding && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Branding, { variant: "banner" })
826
916
  ] }) });
827
917
  const positionStyle = {
@@ -994,43 +1084,26 @@ function createFullConsentState(consented, preferences, source, projectConfig, i
994
1084
  };
995
1085
  }
996
1086
  function reducer(state, action) {
997
- log.debug("State transition:", {
998
- action: action.type,
999
- currentState: state.consented
1000
- });
1087
+ logger.consentState(action.type, state);
1001
1088
  switch (action.type) {
1002
1089
  case "ACCEPT_ALL": {
1003
1090
  const prefs = createProjectPreferences(action.config, true);
1004
- const newState = createFullConsentState(
1005
- true,
1006
- prefs,
1007
- "banner",
1008
- action.config,
1009
- false,
1010
- state
1011
- );
1012
- log.info("User accepted all cookies", {
1091
+ const newState = createFullConsentState(true, prefs, "banner", action.config, false, state);
1092
+ logger.info("User accepted all cookies", {
1013
1093
  preferences: newState.preferences
1014
1094
  });
1015
1095
  return newState;
1016
1096
  }
1017
1097
  case "REJECT_ALL": {
1018
1098
  const prefs = createProjectPreferences(action.config, false);
1019
- const newState = createFullConsentState(
1020
- true,
1021
- prefs,
1022
- "banner",
1023
- action.config,
1024
- false,
1025
- state
1026
- );
1027
- log.info("User rejected all cookies", {
1099
+ const newState = createFullConsentState(true, prefs, "banner", action.config, false, state);
1100
+ logger.info("User rejected all cookies", {
1028
1101
  preferences: newState.preferences
1029
1102
  });
1030
1103
  return newState;
1031
1104
  }
1032
1105
  case "SET_CATEGORY":
1033
- log.debug("Category preference changed", {
1106
+ logger.debug("Category preference changed", {
1034
1107
  category: action.category,
1035
1108
  value: action.value
1036
1109
  });
@@ -1043,26 +1116,12 @@ function reducer(state, action) {
1043
1116
  lastUpdate: (/* @__PURE__ */ new Date()).toISOString()
1044
1117
  };
1045
1118
  case "SET_PREFERENCES":
1046
- log.info("Preferences saved", { preferences: action.preferences });
1047
- return createFullConsentState(
1048
- true,
1049
- action.preferences,
1050
- "modal",
1051
- action.config,
1052
- false,
1053
- state
1054
- );
1119
+ logger.info("Preferences saved", { preferences: action.preferences });
1120
+ return createFullConsentState(true, action.preferences, "modal", action.config, false, state);
1055
1121
  case "OPEN_MODAL":
1056
1122
  return { ...state, isModalOpen: true };
1057
1123
  case "CLOSE_MODAL":
1058
- return createFullConsentState(
1059
- true,
1060
- state.preferences,
1061
- "modal",
1062
- action.config,
1063
- false,
1064
- state
1065
- );
1124
+ return createFullConsentState(true, state.preferences, "modal", action.config, false, state);
1066
1125
  case "RESET": {
1067
1126
  return createFullConsentState(
1068
1127
  false,
@@ -1090,12 +1149,9 @@ function reducer(state, action) {
1090
1149
  function ConsentProvider({
1091
1150
  initialState,
1092
1151
  categories,
1093
- // Nova prop para configuração de categorias
1094
1152
  texts: textsProp,
1095
1153
  theme,
1096
1154
  designTokens,
1097
- scriptIntegrations,
1098
- // eslint-disable-line no-unused-vars
1099
1155
  PreferencesModalComponent,
1100
1156
  preferencesModalProps = {},
1101
1157
  CookieBannerComponent,
@@ -1110,18 +1166,12 @@ function ConsentProvider({
1110
1166
  disableDeveloperGuidance,
1111
1167
  children
1112
1168
  }) {
1113
- const texts = React5.useMemo(
1114
- () => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }),
1115
- [textsProp]
1116
- );
1169
+ const texts = React5.useMemo(() => ({ ...DEFAULT_TEXTS, ...textsProp ?? {} }), [textsProp]);
1117
1170
  const cookie = React5.useMemo(
1118
1171
  () => ({ ...DEFAULT_COOKIE_OPTS, ...cookieOpts ?? {} }),
1119
1172
  [cookieOpts]
1120
1173
  );
1121
- const appliedTheme = React5.useMemo(
1122
- () => theme || defaultConsentTheme,
1123
- [theme]
1124
- );
1174
+ const appliedTheme = React5.useMemo(() => theme || defaultConsentTheme, [theme]);
1125
1175
  const finalCategoriesConfig = React5.useMemo(() => {
1126
1176
  if (categories) return categories;
1127
1177
  return DEFAULT_PROJECT_CATEGORIES;
@@ -1153,8 +1203,7 @@ function ConsentProvider({
1153
1203
  setIsHydrated(true);
1154
1204
  }, [cookie.name, initialState, finalCategoriesConfig]);
1155
1205
  React5.useEffect(() => {
1156
- if (state.consented)
1157
- writeConsentCookie(state, finalCategoriesConfig, cookie);
1206
+ if (state.consented) writeConsentCookie(state, finalCategoriesConfig, cookie);
1158
1207
  }, [state, cookie, finalCategoriesConfig]);
1159
1208
  const prevConsented = React5.useRef(state.consented);
1160
1209
  React5.useEffect(() => {
@@ -1243,14 +1292,12 @@ function ConsentProvider({
1243
1292
  }
1244
1293
  function useConsentStateInternal() {
1245
1294
  const ctx = React5.useContext(StateCtx);
1246
- if (!ctx)
1247
- throw new Error("useConsentState must be used within ConsentProvider");
1295
+ if (!ctx) throw new Error("useConsentState must be used within ConsentProvider");
1248
1296
  return ctx;
1249
1297
  }
1250
1298
  function useConsentActionsInternal() {
1251
1299
  const ctx = React5.useContext(ActionsCtx);
1252
- if (!ctx)
1253
- throw new Error("useConsentActions must be used within ConsentProvider");
1300
+ if (!ctx) throw new Error("useConsentActions must be used within ConsentProvider");
1254
1301
  return ctx;
1255
1302
  }
1256
1303
  function useConsentTextsInternal() {
@@ -1260,7 +1307,7 @@ function useConsentTextsInternal() {
1260
1307
  function useConsentHydrationInternal() {
1261
1308
  return React5.useContext(HydrationCtx);
1262
1309
  }
1263
- var React5, import_jsx_runtime7, log, PreferencesModal, DEFAULT_TEXTS, StateCtx, ActionsCtx, TextsCtx, HydrationCtx;
1310
+ var React5, import_jsx_runtime7, PreferencesModal, DEFAULT_TEXTS, StateCtx, ActionsCtx, TextsCtx, HydrationCtx, defaultTexts;
1264
1311
  var init_ConsentContext = __esm({
1265
1312
  "src/context/ConsentContext.tsx"() {
1266
1313
  "use strict";
@@ -1273,21 +1320,10 @@ var init_ConsentContext = __esm({
1273
1320
  init_DesignContext();
1274
1321
  init_developerGuidance();
1275
1322
  init_useConsent();
1323
+ init_logger();
1276
1324
  init_CookieBanner();
1277
1325
  init_FloatingPreferencesButton();
1278
1326
  import_jsx_runtime7 = require("react/jsx-runtime");
1279
- log = {
1280
- debug: (message, data) => {
1281
- if (typeof window !== "undefined" && window.__REACT_DEVTOOLS_GLOBAL_HOOK__) {
1282
- console.debug("[react-lgpd-consent] [DEBUG]", message, data);
1283
- }
1284
- },
1285
- info: (message, data) => {
1286
- if (typeof window !== "undefined" && window.__REACT_DEVTOOLS_GLOBAL_HOOK__) {
1287
- console.info("[react-lgpd-consent] [INFO]", message, data);
1288
- }
1289
- }
1290
- };
1291
1327
  PreferencesModal = React5.lazy(
1292
1328
  () => Promise.resolve().then(() => (init_PreferencesModal(), PreferencesModal_exports)).then((m) => ({
1293
1329
  default: m.PreferencesModal
@@ -1334,6 +1370,7 @@ var init_ConsentContext = __esm({
1334
1370
  ActionsCtx = React5.createContext(null);
1335
1371
  TextsCtx = React5.createContext(DEFAULT_TEXTS);
1336
1372
  HydrationCtx = React5.createContext(false);
1373
+ defaultTexts = DEFAULT_TEXTS;
1337
1374
  }
1338
1375
  });
1339
1376
 
@@ -1368,7 +1405,7 @@ function openPreferencesModal() {
1368
1405
  if (globalOpenPreferences) {
1369
1406
  globalOpenPreferences();
1370
1407
  } else {
1371
- console.warn(
1408
+ logger.warn(
1372
1409
  "openPreferencesModal: ConsentProvider n\xE3o foi inicializado ou n\xE3o est\xE1 dispon\xEDvel."
1373
1410
  );
1374
1411
  }
@@ -1384,6 +1421,7 @@ var init_useConsent = __esm({
1384
1421
  "src/hooks/useConsent.ts"() {
1385
1422
  "use strict";
1386
1423
  init_ConsentContext();
1424
+ init_logger();
1387
1425
  globalOpenPreferences = null;
1388
1426
  }
1389
1427
  });
@@ -1400,16 +1438,14 @@ function PreferencesModal2({
1400
1438
  const { preferences, setPreferences, closePreferences, isModalOpen } = useConsent();
1401
1439
  const texts = useConsentTexts();
1402
1440
  const { toggleableCategories } = useCategories();
1403
- const [tempPreferences, setTempPreferences] = (0, import_react.useState)(
1404
- () => {
1405
- const initialPrefs = { necessary: true };
1406
- toggleableCategories.forEach((category) => {
1407
- initialPrefs[category.id] = preferences[category.id] ?? false;
1408
- });
1409
- return initialPrefs;
1410
- }
1411
- );
1412
- (0, import_react.useEffect)(() => {
1441
+ const [tempPreferences, setTempPreferences] = (0, import_react2.useState)(() => {
1442
+ const initialPrefs = { necessary: true };
1443
+ toggleableCategories.forEach((category) => {
1444
+ initialPrefs[category.id] = preferences[category.id] ?? false;
1445
+ });
1446
+ return initialPrefs;
1447
+ });
1448
+ (0, import_react2.useEffect)(() => {
1413
1449
  if (isModalOpen) {
1414
1450
  const syncedPrefs = { necessary: true };
1415
1451
  toggleableCategories.forEach((category) => {
@@ -1426,54 +1462,39 @@ function PreferencesModal2({
1426
1462
  setTempPreferences(preferences);
1427
1463
  closePreferences();
1428
1464
  };
1429
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1430
- import_Dialog.default,
1431
- {
1432
- "aria-labelledby": "cookie-pref-title",
1433
- open,
1434
- onClose: handleCancel,
1435
- ...DialogProps2,
1436
- children: [
1437
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_DialogTitle.default, { id: "cookie-pref-title", children: texts.modalTitle }),
1438
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_DialogContent.default, { dividers: true, children: [
1439
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_Typography3.default, { variant: "body2", sx: { mb: 2 }, children: texts.modalIntro }),
1440
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_FormGroup.default, { children: [
1441
- toggleableCategories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1442
- import_FormControlLabel.default,
1443
- {
1444
- control: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1445
- import_Switch.default,
1446
- {
1447
- checked: tempPreferences[category.id] ?? false,
1448
- onChange: (e) => setTempPreferences((prev) => ({
1449
- ...prev,
1450
- [category.id]: e.target.checked
1451
- }))
1452
- }
1453
- ),
1454
- label: `${category.name} - ${category.description}`
1455
- },
1456
- category.id
1457
- )),
1458
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1459
- import_FormControlLabel.default,
1465
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_Dialog.default, { "aria-labelledby": "cookie-pref-title", open, onClose: handleCancel, ...DialogProps2, children: [
1466
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_DialogTitle.default, { id: "cookie-pref-title", children: texts.modalTitle }),
1467
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_DialogContent.default, { dividers: true, children: [
1468
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_Typography3.default, { variant: "body2", sx: { mb: 2 }, children: texts.modalIntro }),
1469
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_FormGroup.default, { children: [
1470
+ toggleableCategories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1471
+ import_FormControlLabel.default,
1472
+ {
1473
+ control: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1474
+ import_Switch.default,
1460
1475
  {
1461
- control: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_Switch.default, { checked: true, disabled: true }),
1462
- label: texts.necessaryAlwaysOn
1476
+ checked: tempPreferences[category.id] ?? false,
1477
+ onChange: (e) => setTempPreferences((prev) => ({
1478
+ ...prev,
1479
+ [category.id]: e.target.checked
1480
+ }))
1463
1481
  }
1464
- )
1465
- ] })
1466
- ] }),
1467
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_DialogActions.default, { children: [
1468
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_Button2.default, { variant: "outlined", onClick: handleCancel, children: texts.close }),
1469
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_Button2.default, { variant: "contained", onClick: handleSave, children: texts.save })
1470
- ] }),
1471
- !hideBranding && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Branding, { variant: "modal" })
1472
- ]
1473
- }
1474
- );
1482
+ ),
1483
+ label: `${category.name} - ${category.description}`
1484
+ },
1485
+ category.id
1486
+ )),
1487
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_FormControlLabel.default, { control: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_Switch.default, { checked: true, disabled: true }), label: texts.necessaryAlwaysOn })
1488
+ ] })
1489
+ ] }),
1490
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_DialogActions.default, { children: [
1491
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_Button2.default, { variant: "outlined", onClick: handleCancel, children: texts.close }),
1492
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_Button2.default, { variant: "contained", onClick: handleSave, children: texts.save })
1493
+ ] }),
1494
+ !hideBranding && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Branding, { variant: "modal" })
1495
+ ] });
1475
1496
  }
1476
- var import_Button2, import_Dialog, import_DialogActions, import_DialogContent, import_DialogTitle, import_FormControlLabel, import_FormGroup, import_Switch, import_Typography3, import_react, import_jsx_runtime8;
1497
+ var import_Button2, import_Dialog, import_DialogActions, import_DialogContent, import_DialogTitle, import_FormControlLabel, import_FormGroup, import_Switch, import_Typography3, import_react2, import_jsx_runtime8;
1477
1498
  var init_PreferencesModal = __esm({
1478
1499
  "src/components/PreferencesModal.tsx"() {
1479
1500
  "use strict";
@@ -1486,7 +1507,7 @@ var init_PreferencesModal = __esm({
1486
1507
  import_FormGroup = __toESM(require("@mui/material/FormGroup"), 1);
1487
1508
  import_Switch = __toESM(require("@mui/material/Switch"), 1);
1488
1509
  import_Typography3 = __toESM(require("@mui/material/Typography"), 1);
1489
- import_react = require("react");
1510
+ import_react2 = require("react");
1490
1511
  init_CategoriesContext();
1491
1512
  init_useConsent();
1492
1513
  init_Branding();
@@ -1501,14 +1522,19 @@ __export(index_exports, {
1501
1522
  ConsentGate: () => ConsentGate,
1502
1523
  ConsentProvider: () => ConsentProvider,
1503
1524
  ConsentScriptLoader: () => ConsentScriptLoader,
1525
+ CookieBanner: () => CookieBanner,
1504
1526
  DEFAULT_PROJECT_CATEGORIES: () => DEFAULT_PROJECT_CATEGORIES,
1527
+ FloatingPreferencesButton: () => FloatingPreferencesButton,
1505
1528
  LogLevel: () => LogLevel,
1506
1529
  PreferencesModal: () => PreferencesModal2,
1507
1530
  analyzeDeveloperConfiguration: () => analyzeDeveloperConfiguration,
1508
1531
  createGoogleAnalyticsIntegration: () => createGoogleAnalyticsIntegration,
1509
1532
  createGoogleTagManagerIntegration: () => createGoogleTagManagerIntegration,
1533
+ createProjectPreferences: () => createProjectPreferences,
1510
1534
  createUserWayIntegration: () => createUserWayIntegration,
1511
1535
  defaultConsentTheme: () => defaultConsentTheme,
1536
+ defaultTexts: () => defaultTexts,
1537
+ getAllProjectCategories: () => getAllProjectCategories,
1512
1538
  loadScript: () => loadScript,
1513
1539
  openPreferencesModal: () => openPreferencesModal,
1514
1540
  setDebugLogging: () => setDebugLogging,
@@ -1518,7 +1544,8 @@ __export(index_exports, {
1518
1544
  useConsentHydration: () => useConsentHydration,
1519
1545
  useConsentScriptLoader: () => useConsentScriptLoader,
1520
1546
  useConsentTexts: () => useConsentTexts,
1521
- useOpenPreferencesModal: () => useOpenPreferencesModal
1547
+ useOpenPreferencesModal: () => useOpenPreferencesModal,
1548
+ validateProjectPreferences: () => validateProjectPreferences
1522
1549
  });
1523
1550
  module.exports = __toCommonJS(index_exports);
1524
1551
  init_PreferencesModal();
@@ -1578,6 +1605,7 @@ init_theme();
1578
1605
  // src/utils/ConsentScriptLoader.tsx
1579
1606
  var React6 = __toESM(require("react"), 1);
1580
1607
  init_useConsent();
1608
+ init_logger();
1581
1609
  function ConsentScriptLoader({
1582
1610
  integrations,
1583
1611
  reloadOnChange = false
@@ -1603,7 +1631,7 @@ function ConsentScriptLoader({
1603
1631
  }
1604
1632
  loadedScripts.current.add(integration.id);
1605
1633
  } catch (error) {
1606
- console.error(`\u274C Failed to load script: ${integration.id}`, error);
1634
+ logger.error(`\u274C Failed to load script: ${integration.id}`, error);
1607
1635
  }
1608
1636
  }
1609
1637
  });
@@ -1615,14 +1643,12 @@ function useConsentScriptLoader() {
1615
1643
  return React6.useCallback(
1616
1644
  async (integration) => {
1617
1645
  if (!consented) {
1618
- console.warn(
1619
- `\u26A0\uFE0F Cannot load script ${integration.id}: No consent given`
1620
- );
1646
+ logger.warn(`\u26A0\uFE0F Cannot load script ${integration.id}: No consent given`);
1621
1647
  return false;
1622
1648
  }
1623
1649
  const shouldLoad = preferences[integration.category];
1624
1650
  if (!shouldLoad) {
1625
- console.warn(
1651
+ logger.warn(
1626
1652
  `\u26A0\uFE0F Cannot load script ${integration.id}: Category '${integration.category}' not consented`
1627
1653
  );
1628
1654
  return false;
@@ -1640,7 +1666,7 @@ function useConsentScriptLoader() {
1640
1666
  }
1641
1667
  return true;
1642
1668
  } catch (error) {
1643
- console.error(`\u274C Failed to load script: ${integration.id}`, error);
1669
+ logger.error(`\u274C Failed to load script: ${integration.id}`, error);
1644
1670
  return false;
1645
1671
  }
1646
1672
  },
@@ -1690,8 +1716,7 @@ function createUserWayIntegration(config) {
1690
1716
  return {
1691
1717
  id: "userway",
1692
1718
  category: "functional",
1693
- // Categoria mais apropriada para acessibilidade
1694
- src: `https://cdn.userway.org/widget.js`,
1719
+ src: "https://cdn.userway.org/widget.js",
1695
1720
  init: () => {
1696
1721
  if (typeof window !== "undefined") {
1697
1722
  window.UserWayWidgetApp = window.UserWayWidgetApp || {};
@@ -1710,20 +1735,29 @@ var COMMON_INTEGRATIONS = {
1710
1735
  // src/index.ts
1711
1736
  init_developerGuidance();
1712
1737
  init_logger();
1738
+ init_CookieBanner();
1739
+ init_FloatingPreferencesButton();
1740
+ init_ConsentContext();
1741
+ init_categoryUtils();
1713
1742
  // Annotate the CommonJS export names for ESM import in node:
1714
1743
  0 && (module.exports = {
1715
1744
  COMMON_INTEGRATIONS,
1716
1745
  ConsentGate,
1717
1746
  ConsentProvider,
1718
1747
  ConsentScriptLoader,
1748
+ CookieBanner,
1719
1749
  DEFAULT_PROJECT_CATEGORIES,
1750
+ FloatingPreferencesButton,
1720
1751
  LogLevel,
1721
1752
  PreferencesModal,
1722
1753
  analyzeDeveloperConfiguration,
1723
1754
  createGoogleAnalyticsIntegration,
1724
1755
  createGoogleTagManagerIntegration,
1756
+ createProjectPreferences,
1725
1757
  createUserWayIntegration,
1726
1758
  defaultConsentTheme,
1759
+ defaultTexts,
1760
+ getAllProjectCategories,
1727
1761
  loadScript,
1728
1762
  openPreferencesModal,
1729
1763
  setDebugLogging,
@@ -1733,5 +1767,6 @@ init_logger();
1733
1767
  useConsentHydration,
1734
1768
  useConsentScriptLoader,
1735
1769
  useConsentTexts,
1736
- useOpenPreferencesModal
1770
+ useOpenPreferencesModal,
1771
+ validateProjectPreferences
1737
1772
  });