@frigear-nu/cookie-consent 0.0.6 → 0.0.8

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/module.d.mts CHANGED
@@ -1,12 +1,12 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
+ import { Translated } from '@frigear-nu/ui/translated';
3
+ export { Translated } from '@frigear-nu/ui/translated';
2
4
 
3
- /** A string, or a map of locale code -> string (`{ da: '...', en: '...' }`). */
4
- type Localized = string | Record<string, string>;
5
5
  /** A cookie (or similar storage entry) set under a category - listed in the preferences dialog for GDPR transparency. */
6
6
  interface ConsentCookie {
7
7
  name: string;
8
8
  provider?: string;
9
- purpose?: Localized;
9
+ purpose?: Translated;
10
10
  /** Human readable, e.g. `'1 year'` or `'Session'`. */
11
11
  duration?: string;
12
12
  }
@@ -17,9 +17,9 @@ interface ConsentCategory {
17
17
  /** Pre-selected state in the preferences dialog. Never applied without the user saving. Default `false`. */
18
18
  defaultEnabled?: boolean;
19
19
  /** Defaults to the i18n key `cookieConsent.categories.<key>.label`. */
20
- label?: Localized;
20
+ label?: Translated;
21
21
  /** Defaults to the i18n key `cookieConsent.categories.<key>.description`. */
22
- description?: Localized;
22
+ description?: Translated;
23
23
  cookies?: ConsentCookie[];
24
24
  }
25
25
  interface ConsentMessages {
@@ -49,13 +49,23 @@ interface ModuleOptions {
49
49
  excludeRoutes?: string[];
50
50
  /** Collapse the banner into a round button once scrolled this many px (`true` = 80, `false` = never). Default `true`. */
51
51
  collapseOnScroll?: boolean | number;
52
- /** Link to the cookie/privacy policy shown in the banner. */
53
- policyUrl?: string;
52
+ /** Link to the cookie/privacy policy shown in the banner. A string, or a map of locale code -> URL (`{ da: '/da/gdpr', en: '/gdpr' }`). */
53
+ policyUrl?: Translated;
54
+ /**
55
+ * Text of the policy link in the banner (the "Read more" link). A string or a `{ da, en }` map.
56
+ * Defaults to the i18n key `cookieConsent.policy`.
57
+ */
58
+ policyLabel?: Translated;
54
59
  /**
55
60
  * Store the consent on the signed-in user (`@frigear-nu/users` + `@nuxthub/core` required).
56
61
  * Default: `true` when `@frigear-nu/users` is installed.
57
62
  */
58
63
  persistToUser?: boolean;
64
+ /**
65
+ * Iconify name (`collection:name`) of the icon on the banner badge and the collapsed button. Default `lucide:cookie`.
66
+ * The module adds it to Nuxt Icon's client bundle, because Nuxt Icon does not scan `node_modules` for icons.
67
+ */
68
+ icon?: string;
59
69
  }
60
70
  interface PublicModuleOptions {
61
71
  cookieName: string;
@@ -64,8 +74,10 @@ interface PublicModuleOptions {
64
74
  categories: ConsentCategory[];
65
75
  excludeRoutes: string[];
66
76
  collapseThreshold: number | false;
67
- policyUrl?: string;
77
+ policyUrl?: Translated;
78
+ policyLabel?: Translated;
68
79
  persistToUser: boolean;
80
+ icon: string;
69
81
  }
70
82
  /** What is stored in the consent cookie and (for signed-in users) in the database. */
71
83
  interface ConsentState {
@@ -125,4 +137,4 @@ declare module 'nitropack' {
125
137
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
126
138
 
127
139
  export { _default as default };
128
- export type { ConsentCategory, ConsentCookie, ConsentMessages, ConsentState, Localized, ModuleOptions, PublicModuleOptions };
140
+ export type { ConsentCategory, ConsentCookie, ConsentMessages, ConsentState, ModuleOptions, PublicModuleOptions };
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@frigear-nu/cookie-consent",
3
3
  "configKey": "cookieConsent",
4
- "version": "0.0.6",
4
+ "version": "0.0.8",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.3",
7
7
  "unbuild": "unknown"
package/dist/module.mjs CHANGED
@@ -1,22 +1,29 @@
1
1
  import { defineNuxtModule, createResolver, hasNuxtModule, addImports, addServerImports, addComponentsDir, addServerHandler } from '@nuxt/kit';
2
- import { registerModule, registerLocales, extendDatabaseTable } from '@frigear-nu/module-kit/utils';
2
+ import { registerModule, registerTailwindSource, registerLocales, extendDatabaseTable } from '@frigear-nu/module-kit/utils';
3
3
  import { mergeCategories, DEFAULT_CATEGORIES, computeVersion } from '../dist/runtime/utils/consent.js';
4
4
 
5
5
  const DEFAULT_MAX_AGE = 60 * 60 * 24 * 180;
6
+ const DEFAULT_ICON = "lucide:cookie";
6
7
  const module$1 = defineNuxtModule({
7
8
  meta: { name: "@frigear-nu/cookie-consent", configKey: "cookieConsent" },
8
9
  defaults: {
9
10
  cookieName: "cookie-consent",
10
11
  maxAge: DEFAULT_MAX_AGE,
11
12
  excludeRoutes: ["/authorize"],
12
- collapseOnScroll: true
13
+ collapseOnScroll: true,
14
+ icon: DEFAULT_ICON
13
15
  },
14
16
  moduleDependencies: {
15
- "@frigear-nu/module-kit": { version: ">=0.0.1" }
17
+ "@frigear-nu/module-kit": { version: ">=0.0.1" },
18
+ // Declared (optional) so they are set up first and `hasNuxtModule` below does not depend on the module order:
19
+ // with `users` the consent is also stored on the signed-in user.
20
+ "@frigear-nu/auth": { version: ">=0.0.1", optional: true },
21
+ "@frigear-nu/users": { version: ">=0.0.1", optional: true }
16
22
  },
17
23
  async setup(options, nuxt) {
18
24
  registerModule("@frigear-nu/cookie-consent", nuxt);
19
25
  const resolver = createResolver(import.meta.url);
26
+ registerTailwindSource(nuxt, resolver.resolve("./runtime/app"));
20
27
  registerLocales(nuxt, resolver.resolve("./runtime/i18n/lang"));
21
28
  const persistToUser = (options.persistToUser ?? true) && hasNuxtModule("@frigear-nu/users");
22
29
  addImports([
@@ -28,7 +35,7 @@ const module$1 = defineNuxtModule({
28
35
  { name: "getCookieConsent", from: resolver.resolve("./runtime/server/utils/consent") },
29
36
  { name: "hasCookieConsent", from: resolver.resolve("./runtime/server/utils/consent") }
30
37
  ]);
31
- addComponentsDir({ path: resolver.resolve("./runtime/app/components") });
38
+ addComponentsDir({ path: resolver.resolve("./runtime/app/components"), priority: -1 });
32
39
  if (persistToUser) {
33
40
  addServerHandler({ route: "/api/cookie-consent", method: "get", handler: resolver.resolve("./runtime/server/routes/cookie-consent/index.get") });
34
41
  addServerHandler({ route: "/api/cookie-consent", method: "post", handler: resolver.resolve("./runtime/server/routes/cookie-consent/index.post") });
@@ -38,6 +45,10 @@ const module$1 = defineNuxtModule({
38
45
  file: (dialect) => `./runtime/server/db/schema.${dialect}`
39
46
  });
40
47
  }
48
+ const icon = options.icon || DEFAULT_ICON;
49
+ nuxt.hook("icon:clientBundleIcons", ((icons) => {
50
+ icons.add(icon.replace(/^i[-:]/, ""));
51
+ }));
41
52
  nuxt.hook("modules:done", async () => {
42
53
  const categories = mergeCategories(
43
54
  options.categories ?? DEFAULT_CATEGORIES,
@@ -52,7 +63,9 @@ const module$1 = defineNuxtModule({
52
63
  excludeRoutes: options.excludeRoutes ?? [],
53
64
  collapseThreshold: options.collapseOnScroll === false ? false : typeof options.collapseOnScroll === "number" ? options.collapseOnScroll : 80,
54
65
  policyUrl: options.policyUrl,
55
- persistToUser
66
+ policyLabel: options.policyLabel,
67
+ persistToUser,
68
+ icon
56
69
  };
57
70
  });
58
71
  }
@@ -1,7 +1,7 @@
1
1
  <script setup>
2
2
  import { useWindowScroll } from "@vueuse/core";
3
- const { config, hasResponded, acceptAll, rejectAll, openPreferences, hydrateFromUser } = useCookieConsent();
4
- const { t } = useConsentT();
3
+ const { config, hasResponded, hydrateFromUser } = useCookieConsent();
4
+ const { t, policyUrl } = useConsentT();
5
5
  const route = useRoute();
6
6
  const excluded = computed(() => config.excludeRoutes.includes(route.path));
7
7
  const open = computed(() => !hasResponded.value && !excluded.value);
@@ -21,69 +21,58 @@ onMounted(() => {
21
21
 
22
22
  <template>
23
23
  <ClientOnly>
24
- <Transition name="cookie-fab">
24
+ <Transition
25
+ enter-active-class="transition duration-200 ease-out"
26
+ leave-active-class="transition duration-200 ease-out"
27
+ enter-from-class="scale-50 opacity-0"
28
+ leave-to-class="scale-50 opacity-0"
29
+ >
25
30
  <button
26
31
  v-if="open && collapsed"
27
- class="cc-fab"
32
+ class="fixed bottom-4 left-4 z-50 flex size-14 cursor-pointer items-center justify-center rounded-full border border-default bg-default shadow-[0_10px_25px_rgb(0_0_0/0.3)] hover:opacity-90"
28
33
  :aria-label="t('expand')"
29
34
  data-testid="cookie-consent-fab"
30
35
  @click="isManuallyExpanded = true"
31
36
  >
32
37
  <UIcon
33
- name="i-lucide-cookie"
34
- class="cc-fab-icon"
38
+ :name="config.icon"
39
+ class="size-7 text-primary"
35
40
  />
36
41
  </button>
37
42
  </Transition>
38
43
 
39
- <Transition name="cookie-slide">
44
+ <Transition
45
+ enter-active-class="transition duration-300 ease-out"
46
+ leave-active-class="transition duration-300 ease-out"
47
+ enter-from-class="translate-y-full opacity-0"
48
+ leave-to-class="translate-y-full opacity-0"
49
+ >
40
50
  <div
41
51
  v-if="open && !collapsed"
42
- class="cc-wrap"
52
+ class="pointer-events-none fixed inset-x-0 bottom-0 z-50 flex justify-center"
43
53
  role="dialog"
44
54
  :aria-label="t('preferencesTitle')"
45
55
  data-testid="cookie-consent-banner"
46
56
  >
47
- <div class="cc-banner">
48
- <div class="cc-badge">
57
+ <div class="pointer-events-auto relative w-[92vw] rounded-t-2xl border border-primary/70 bg-default text-default shadow-[0_-8px_30px_rgb(0_0_0/0.25)]">
58
+ <div class="absolute -top-3.5 left-4 flex items-center justify-center rounded-full border border-primary/70 bg-default p-1">
49
59
  <UIcon
50
- name="i-lucide-cookie"
51
- class="cc-badge-icon"
60
+ :name="config.icon"
61
+ class="size-5 text-primary"
52
62
  />
53
63
  </div>
54
- <div class="cc-content">
55
- <p class="cc-text">
64
+ <div class="flex flex-col items-center justify-between gap-4 px-4 pb-4 pt-5 sm:flex-row">
65
+ <p class="text-sm text-muted">
56
66
  {{ t("description") }}
57
67
  <NuxtLink
58
- v-if="config.policyUrl"
59
- :to="config.policyUrl"
60
- class="cc-link"
68
+ v-if="policyUrl"
69
+ :to="policyUrl"
70
+ class="underline"
61
71
  >
62
72
  {{ t("policy") }}
63
73
  </NuxtLink>
64
74
  </p>
65
- <div class="cc-actions">
66
- <UButton
67
- color="neutral"
68
- variant="ghost"
69
- :label="t('preferences')"
70
- data-testid="cookie-consent-preferences"
71
- @click="openPreferences"
72
- />
73
- <UButton
74
- color="neutral"
75
- variant="outline"
76
- :label="t('reject')"
77
- data-testid="cookie-consent-reject"
78
- @click="rejectAll"
79
- />
80
- <UButton
81
- color="primary"
82
- :label="t('accept')"
83
- data-testid="cookie-consent-accept"
84
- @click="acceptAll"
85
- />
86
- </div>
75
+ <CookieConsentBannerActions />
87
76
  </div>
88
77
  </div>
89
78
  </div>
@@ -92,7 +81,3 @@ onMounted(() => {
92
81
  <CookieConsentPreferences />
93
82
  </ClientOnly>
94
83
  </template>
95
-
96
- <style scoped>
97
- .cc-wrap{display:flex;inset:auto 0 0 0;justify-content:center;pointer-events:none;position:fixed;z-index:50}.cc-banner{border-radius:1rem 1rem 0 0;box-shadow:0 -8px 30px rgba(0,0,0,.25);color:var(--ui-text);pointer-events:auto;position:relative;width:92vw}.cc-badge,.cc-banner{background:var(--ui-bg);border:1px solid color-mix(in oklab,var(--ui-primary) 70%,transparent)}.cc-badge{align-items:center;border-radius:9999px;display:flex;justify-content:center;left:1rem;padding:.25rem;position:absolute;top:-.875rem}.cc-badge-icon{color:var(--ui-primary);height:1.25rem;width:1.25rem}.cc-content{align-items:center;display:flex;flex-direction:column;gap:1rem;justify-content:space-between;padding:1.25rem 1rem 1rem}.cc-text{color:var(--ui-text-muted);font-size:.875rem;margin:0}.cc-link{text-decoration:underline}.cc-actions{display:flex;flex-shrink:0;flex-wrap:wrap;gap:.5rem}@media (min-width:640px){.cc-content{flex-direction:row}}.cc-fab{align-items:center;background:var(--ui-bg);border:1px solid var(--ui-border);border-radius:9999px;bottom:1rem;box-shadow:0 10px 25px rgba(0,0,0,.3);cursor:pointer;display:flex;height:3.5rem;justify-content:center;left:1rem;position:fixed;width:3.5rem;z-index:50}.cc-fab:hover{opacity:.9}.cc-fab-icon{color:var(--ui-primary);height:1.75rem;width:1.75rem}.cookie-slide-enter-active,.cookie-slide-leave-active{transition:transform .3s ease,opacity .3s ease}.cookie-slide-enter-from,.cookie-slide-leave-to{opacity:0;transform:translateY(100%)}.cookie-fab-enter-active,.cookie-fab-leave-active{transition:opacity .2s ease,transform .2s ease}.cookie-fab-enter-from,.cookie-fab-leave-to{opacity:0;transform:scale(.5)}
98
- </style>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,29 @@
1
+ <script setup>
2
+ const { acceptAll, rejectAll, openPreferences } = useCookieConsent();
3
+ const { t } = useConsentT();
4
+ </script>
5
+
6
+ <template>
7
+ <div class="flex shrink-0 flex-wrap gap-2">
8
+ <UButton
9
+ color="neutral"
10
+ variant="ghost"
11
+ :label="t('preferences')"
12
+ data-testid="cookie-consent-preferences"
13
+ @click="openPreferences"
14
+ />
15
+ <UButton
16
+ color="neutral"
17
+ variant="outline"
18
+ :label="t('reject')"
19
+ data-testid="cookie-consent-reject"
20
+ @click="rejectAll"
21
+ />
22
+ <UButton
23
+ color="primary"
24
+ :label="t('accept')"
25
+ data-testid="cookie-consent-accept"
26
+ @click="acceptAll"
27
+ />
28
+ </div>
29
+ </template>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -6,14 +6,10 @@ const { t } = useConsentT();
6
6
  <template>
7
7
  <button
8
8
  type="button"
9
- :class="['cc-manage', { 'cc-manage-text': !$slots.default }]"
9
+ :class="['cursor-pointer', { underline: !$slots.default }]"
10
10
  data-testid="cookie-consent-manage"
11
11
  @click="openPreferences"
12
12
  >
13
13
  <slot>{{ t("manage") }}</slot>
14
14
  </button>
15
15
  </template>
16
-
17
- <style scoped>
18
- .cc-manage{background:none;border:0;color:inherit;cursor:pointer;padding:0}.cc-manage-text{text-decoration:underline}
19
- </style>
@@ -19,26 +19,26 @@ watch(isPreferencesOpen, (isOpen) => {
19
19
  >
20
20
  <template #body>
21
21
  <div
22
- class="cc-list"
22
+ class="flex flex-col gap-4"
23
23
  data-testid="cookie-consent-preferences-dialog"
24
24
  >
25
25
  <div
26
26
  v-for="category in categories"
27
27
  :key="category.key"
28
- class="cc-item"
28
+ class="rounded-lg border border-default p-3"
29
29
  >
30
- <div class="cc-row">
30
+ <div class="flex items-start justify-between gap-4">
31
31
  <div>
32
- <p class="cc-label">
32
+ <p class="font-medium">
33
33
  {{ label(category) }}
34
34
  </p>
35
- <p class="cc-desc">
35
+ <p class="text-sm text-muted">
36
36
  {{ description(category) }}
37
37
  </p>
38
38
  </div>
39
39
  <span
40
40
  v-if="category.required"
41
- class="cc-required"
41
+ class="shrink-0 text-xs text-muted"
42
42
  >{{ t("required") }}</span>
43
43
  <USwitch
44
44
  v-else
@@ -49,12 +49,12 @@ watch(isPreferencesOpen, (isOpen) => {
49
49
  </div>
50
50
  <details
51
51
  v-if="category.cookies?.length"
52
- class="cc-details"
52
+ class="mt-2 text-sm"
53
53
  >
54
- <summary class="cc-summary">
54
+ <summary class="cursor-pointer text-muted">
55
55
  {{ t("cookies") }} ({{ category.cookies.length }})
56
56
  </summary>
57
- <ul class="cc-cookies">
57
+ <ul class="mt-1 flex list-none flex-col gap-1 p-0">
58
58
  <li
59
59
  v-for="cookie in category.cookies"
60
60
  :key="cookie.name"
@@ -64,7 +64,7 @@ watch(isPreferencesOpen, (isOpen) => {
64
64
  <span v-if="cookie.duration"> · {{ cookie.duration }}</span>
65
65
  <span
66
66
  v-if="cookie.purpose"
67
- class="cc-purpose"
67
+ class="block text-muted"
68
68
  >{{ localize(cookie.purpose) }}</span>
69
69
  </li>
70
70
  </ul>
@@ -73,7 +73,7 @@ watch(isPreferencesOpen, (isOpen) => {
73
73
  </div>
74
74
  </template>
75
75
  <template #footer>
76
- <div class="cc-footer">
76
+ <div class="flex w-full flex-wrap justify-end gap-2">
77
77
  <UButton
78
78
  color="neutral"
79
79
  variant="outline"
@@ -96,7 +96,3 @@ watch(isPreferencesOpen, (isOpen) => {
96
96
  </template>
97
97
  </UModal>
98
98
  </template>
99
-
100
- <style scoped>
101
- .cc-list{display:flex;flex-direction:column;gap:1rem}.cc-item{border:1px solid var(--ui-border);border-radius:.5rem;padding:.75rem}.cc-row{align-items:flex-start;display:flex;gap:1rem;justify-content:space-between}.cc-label{font-weight:500;margin:0}.cc-desc{font-size:.875rem;margin:0}.cc-desc,.cc-purpose,.cc-required,.cc-summary{color:var(--ui-text-muted)}.cc-required{flex-shrink:0;font-size:.75rem}.cc-details{font-size:.875rem;margin-top:.5rem}.cc-summary{cursor:pointer}.cc-cookies{display:flex;flex-direction:column;gap:.25rem;list-style:none;margin:.25rem 0 0;padding:0}.cc-purpose{display:block}.cc-footer{display:flex;flex-wrap:wrap;gap:.5rem;justify-content:flex-end;width:100%}
102
- </style>
@@ -1,8 +1,11 @@
1
- import type { ConsentCategory, ConsentMessages, Localized } from '../../../types.js';
1
+ import type { ConsentCategory, ConsentMessages, Translated } from '../../../types.js';
2
2
  export declare function useConsentT(): {
3
3
  locale: any;
4
+ /** The policy link target for the current locale, if `policyUrl` is set. */
5
+ policyUrl: any;
6
+ /** The `policyLabel` option wins over the translated `policy` text. */
4
7
  t: (key: keyof ConsentMessages) => any;
5
8
  label: (category: ConsentCategory) => string;
6
9
  description: (category: ConsentCategory) => string;
7
- localize: (value: Localized | undefined, fallback?: string) => string;
10
+ localize: (value: Translated | undefined, fallback?: string) => string;
8
11
  };
@@ -21,6 +21,7 @@ const EN_CATEGORIES = {
21
21
  export function useConsentT() {
22
22
  const tm = useModuleT("cookieConsent");
23
23
  const nuxtApp = useNuxtApp();
24
+ const { policyLabel, policyUrl } = useRuntimeConfig().public.cookieConsent ?? {};
24
25
  const locale = computed(() => nuxtApp.$i18n?.locale?.value ?? "en");
25
26
  function categoryText(category, field) {
26
27
  const explicit = category[field];
@@ -29,7 +30,10 @@ export function useConsentT() {
29
30
  }
30
31
  return {
31
32
  locale,
32
- t: (key) => tm(key, EN[key]),
33
+ /** The policy link target for the current locale, if `policyUrl` is set. */
34
+ policyUrl: computed(() => localize(policyUrl, locale.value) || void 0),
35
+ /** The `policyLabel` option wins over the translated `policy` text. */
36
+ t: (key) => key === "policy" && policyLabel ? localize(policyLabel, locale.value) : tm(key, EN[key]),
33
37
  label: (category) => categoryText(category, "label"),
34
38
  description: (category) => categoryText(category, "description"),
35
39
  localize: (value, fallback = "") => localize(value, locale.value, fallback)
@@ -1,7 +1,7 @@
1
1
  import { db, schema } from "@nuxthub/db";
2
2
  import { eq } from "drizzle-orm";
3
3
  export default defineEventHandler(async (event) => {
4
- const { user } = await requireUserSession(event);
4
+ const user = await requireUser(event, { sessionOnly: true });
5
5
  const [row] = await db.select({
6
6
  acceptedAt: schema.users.cookieConsentAcceptedAt,
7
7
  version: schema.users.cookieConsentVersion,
@@ -8,7 +8,7 @@ const bodySchema = z.object({
8
8
  version: z.string()
9
9
  });
10
10
  export default defineEventHandler(async (event) => {
11
- const { user } = await requireUserSession(event);
11
+ const user = await requireUser(event, { sessionOnly: true });
12
12
  const config = getCookieConsentConfig(event);
13
13
  const body = await readValidatedBody(event, bodySchema.parse);
14
14
  if (body.version !== config.version) {
@@ -1,4 +1,4 @@
1
- import type { ConsentCategory, ConsentState } from '../../types.js';
1
+ import type { ConsentCategory, ConsentState, Translated } from '../../types.js';
2
2
  export declare const DEFAULT_CATEGORIES: ConsentCategory[];
3
3
  /** Merges categories by key: earlier labels win, cookies are concatenated, `required` is sticky. */
4
4
  export declare function mergeCategories(...lists: ConsentCategory[][]): ConsentCategory[];
@@ -15,4 +15,4 @@ export declare function rejectAllChoices(categories: ConsentCategory[]): Record<
15
15
  * The old app's `accepted` / `rejected` strings are migrated.
16
16
  */
17
17
  export declare function normalizeConsent(raw: unknown, categories: ConsentCategory[], version: string, now?: number): ConsentState | null;
18
- export declare function localize(value: string | Record<string, string> | undefined, locale: string, fallback?: string): string;
18
+ export declare function localize(value: Translated | undefined, locale: string, fallback?: string): string;
@@ -1,3 +1,3 @@
1
1
  export { extendCookieConsent, defineConsentCategory } from './extend.js';
2
2
  export { DEFAULT_CATEGORIES, mergeCategories, computeVersion, buildConsent, normalizeConsent, acceptAllChoices, rejectAllChoices, localize, } from './consent.js';
3
- export type { ConsentCategory, ConsentCookie, ConsentState, Localized } from '../../types.js';
3
+ export type { ConsentCategory, ConsentCookie, ConsentState, Translated } from '../../types.js';
package/dist/types.d.mts CHANGED
@@ -1,3 +1,5 @@
1
+ export { type Translated } from '@frigear-nu/ui/translated'
2
+
1
3
  export { default } from './module.mjs'
2
4
 
3
- export { type ConsentCategory, type ConsentCookie, type ConsentMessages, type ConsentState, type Localized, type ModuleOptions, type PublicModuleOptions } from './module.mjs'
5
+ export { type ConsentCategory, type ConsentCookie, type ConsentMessages, type ConsentState, type ModuleOptions, type PublicModuleOptions } from './module.mjs'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frigear-nu/cookie-consent",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "GDPR cookie consent banner with categories - modules contribute categories (extendCookieConsent), apps gate scripts on consent, and the choice is stored as proof on the user.",
5
5
  "homepage": "https://docs.frigear.dev/modules/cookie-consent",
6
6
  "repository": {
@@ -30,7 +30,8 @@
30
30
  "playground"
31
31
  ],
32
32
  "dependencies": {
33
- "@frigear-nu/module-kit": "0.1.6",
33
+ "@frigear-nu/module-kit": "1.0.0",
34
+ "@frigear-nu/ui": "0.0.8",
34
35
  "@libsql/client": "^0.18.0",
35
36
  "@nuxt/kit": "^4.6.0",
36
37
  "@vueuse/core": "^15.0.0",
@@ -39,6 +40,7 @@
39
40
  "zod": "^4.6.5"
40
41
  },
41
42
  "peerDependencies": {
43
+ "@frigear-nu/auth": ">=0.0.1",
42
44
  "@frigear-nu/users": ">=0.0.1",
43
45
  "@nuxthub/core": "^0.10.8",
44
46
  "@nuxt/ui": "^4.10.0"
@@ -50,12 +52,16 @@
50
52
  "@frigear-nu/users": {
51
53
  "optional": true
52
54
  },
55
+ "@frigear-nu/auth": {
56
+ "optional": true
57
+ },
53
58
  "@nuxthub/core": {
54
59
  "optional": true
55
60
  }
56
61
  },
57
62
  "devDependencies": {
58
- "@frigear-nu/users": "1.0.8",
63
+ "@frigear-nu/auth": "0.0.4",
64
+ "@frigear-nu/users": "1.0.10",
59
65
  "@nuxt/devtools": "^3.4.2",
60
66
  "@nuxt/eslint-config": "^1.17.0",
61
67
  "@nuxt/module-builder": "^1.0.3",