@lenne.tech/nuxt-extensions 1.0.0 → 1.0.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 lenne.Tech GmbH
3
+ Copyright (c) 2026 lenne.Tech GmbH
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/dist/module.d.mts CHANGED
@@ -1,6 +1,8 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
2
  import { LtExtensionsModuleOptions } from '../dist/runtime/types/index.js';
3
- export { LtExtensionsModuleOptions } from '../dist/runtime/types/index.js';
3
+ export { LtAuthClientConfig, LtAuthMode, LtAuthResponse, LtAuthState, LtPasskeyAuthResult, LtPasskeyRegisterResult, LtUser, UseLtAuthReturn } from '../dist/runtime/types/auth.js';
4
+ export { LtFileInfo, LtUploadItem, LtUploadOptions, LtUploadProgress, LtUploadStatus, UseLtFileReturn, UseLtTusUploadReturn } from '../dist/runtime/types/upload.js';
5
+ export { LtAuthModuleOptions, LtExtensionsModuleOptions, LtExtensionsPublicRuntimeConfig, LtI18nModuleOptions, LtTusModuleOptions } from '../dist/runtime/types/module.js';
4
6
 
5
7
  declare const name = "@lenne.tech/nuxt-extensions";
6
8
  declare const version = "1.0.0";
package/dist/module.mjs CHANGED
@@ -103,15 +103,18 @@ const module$1 = defineNuxtModule({
103
103
  addPlugin(resolve("./runtime/plugins/auth-interceptor.client"));
104
104
  }
105
105
  if (resolvedOptions.i18n?.autoMerge) {
106
- nuxt.hook("i18n:registerModule", (register) => {
107
- register({
108
- langDir: resolve("./runtime/locales"),
109
- locales: [
110
- { code: "en", file: "en.json" },
111
- { code: "de", file: "de.json" }
112
- ]
113
- });
114
- });
106
+ nuxt.hook(
107
+ "i18n:registerModule",
108
+ (register) => {
109
+ register({
110
+ langDir: resolve("./runtime/locales"),
111
+ locales: [
112
+ { code: "en", file: "en.json" },
113
+ { code: "de", file: "de.json" }
114
+ ]
115
+ });
116
+ }
117
+ );
115
118
  }
116
119
  nuxt.options.build.transpile.push(resolve("./runtime"));
117
120
  nuxt.options.build.transpile.push("tus-js-client");
@@ -6,7 +6,9 @@ const props = defineProps({
6
6
  </script>
7
7
 
8
8
  <template>
9
- <div :style="`--start-duration: ${props.startDuration}ms; --leave-duration: ${props.leaveDuration}ms;`">
9
+ <div
10
+ :style="`--start-duration: ${props.startDuration}ms; --leave-duration: ${props.leaveDuration}ms;`"
11
+ >
10
12
  <Transition
11
13
  enter-active-class="transition ease-out duration-[--start-duration]"
12
14
  enter-from-class="transform opacity-0"
@@ -6,7 +6,9 @@ const props = defineProps({
6
6
  </script>
7
7
 
8
8
  <template>
9
- <div :style="`--start-duration: ${props.startDuration}ms; --leave-duration: ${props.leaveDuration}ms;`">
9
+ <div
10
+ :style="`--start-duration: ${props.startDuration}ms; --leave-duration: ${props.leaveDuration}ms;`"
11
+ >
10
12
  <Transition
11
13
  enter-active-class="transition ease-out duration-[--start-duration]"
12
14
  enter-from-class="transform opacity-0 scale-95"
@@ -9,7 +9,7 @@
9
9
  * - If session cookie works -> use cookies
10
10
  * - If cookies fail (401) -> switch to JWT mode
11
11
  */
12
- import type { UseLtAuthReturn } from '../../types/index.js';
12
+ import type { UseLtAuthReturn } from "../../types/index.js";
13
13
  /**
14
14
  * Better Auth composable with Cookie/JWT dual-mode authentication
15
15
  *
@@ -81,7 +81,13 @@ export function useLtAuth() {
81
81
  const maxAge = 60 * 60 * 24 * 7;
82
82
  document.cookie = `lt-auth-state=${encodeURIComponent(JSON.stringify(clearedState))}; path=/; max-age=${maxAge}; samesite=lax`;
83
83
  document.cookie = `lt-jwt-token=; path=/; max-age=0`;
84
- const sessionCookieNames = ["better-auth.session_token", "better-auth.session", "__Secure-better-auth.session_token", "session_token", "session"];
84
+ const sessionCookieNames = [
85
+ "better-auth.session_token",
86
+ "better-auth.session",
87
+ "__Secure-better-auth.session_token",
88
+ "session_token",
89
+ "session"
90
+ ];
85
91
  for (const name of sessionCookieNames) {
86
92
  document.cookie = `${name}=; path=/; max-age=0`;
87
93
  document.cookie = `${name}=; path=/api; max-age=0`;
@@ -244,11 +250,17 @@ export function useLtAuth() {
244
250
  isLoading.value = true;
245
251
  try {
246
252
  const apiBase = getApiBase();
247
- const optionsResponse = await fetchWithAuth(`${apiBase}/passkey/generate-authenticate-options`, {
248
- method: "GET"
249
- });
253
+ const optionsResponse = await fetchWithAuth(
254
+ `${apiBase}/passkey/generate-authenticate-options`,
255
+ {
256
+ method: "GET"
257
+ }
258
+ );
250
259
  if (!optionsResponse.ok) {
251
- return { success: false, error: t("lt.auth.passkeyError", "Konnte Passkey-Optionen nicht laden") };
260
+ return {
261
+ success: false,
262
+ error: t("lt.auth.passkeyError", "Konnte Passkey-Optionen nicht laden")
263
+ };
252
264
  }
253
265
  const options = await optionsResponse.json();
254
266
  const challengeBuffer = ltBase64UrlToUint8Array(options.challenge).buffer;
@@ -284,7 +296,10 @@ export function useLtAuth() {
284
296
  });
285
297
  const result = await authResponse.json();
286
298
  if (!authResponse.ok) {
287
- return { success: false, error: result.message || t("lt.auth.passkeyFailed", "Passkey-Anmeldung fehlgeschlagen") };
299
+ return {
300
+ success: false,
301
+ error: result.message || t("lt.auth.passkeyFailed", "Passkey-Anmeldung fehlgeschlagen")
302
+ };
288
303
  }
289
304
  if (result.user) {
290
305
  setUser(result.user, "cookie");
@@ -300,9 +315,15 @@ export function useLtAuth() {
300
315
  return { success: true, user: result.user, session: result.session };
301
316
  } catch (err) {
302
317
  if (err instanceof Error && err.name === "NotAllowedError") {
303
- return { success: false, error: t("lt.auth.passkeyAborted", "Passkey-Authentifizierung wurde abgebrochen") };
318
+ return {
319
+ success: false,
320
+ error: t("lt.auth.passkeyAborted", "Passkey-Authentifizierung wurde abgebrochen")
321
+ };
304
322
  }
305
- return { success: false, error: err instanceof Error ? err.message : t("lt.auth.passkeyFailed", "Passkey-Anmeldung fehlgeschlagen") };
323
+ return {
324
+ success: false,
325
+ error: err instanceof Error ? err.message : t("lt.auth.passkeyFailed", "Passkey-Anmeldung fehlgeschlagen")
326
+ };
306
327
  } finally {
307
328
  isLoading.value = false;
308
329
  }
@@ -316,7 +337,10 @@ export function useLtAuth() {
316
337
  });
317
338
  if (!optionsResponse.ok) {
318
339
  const error = await optionsResponse.json().catch(() => ({}));
319
- return { success: false, error: error.message || t("lt.auth.registerOptionsError", "Konnte Registrierungsoptionen nicht laden") };
340
+ return {
341
+ success: false,
342
+ error: error.message || t("lt.auth.registerOptionsError", "Konnte Registrierungsoptionen nicht laden")
343
+ };
320
344
  }
321
345
  const options = await optionsResponse.json();
322
346
  const challengeBuffer = ltBase64UrlToUint8Array(options.challenge).buffer;
@@ -341,7 +365,10 @@ export function useLtAuth() {
341
365
  }
342
366
  });
343
367
  if (!credential) {
344
- return { success: false, error: t("lt.auth.passkeyCreationAborted", "Passkey-Erstellung abgebrochen") };
368
+ return {
369
+ success: false,
370
+ error: t("lt.auth.passkeyCreationAborted", "Passkey-Erstellung abgebrochen")
371
+ };
345
372
  }
346
373
  const attestationResponse = credential.response;
347
374
  const credentialBody = {
@@ -367,14 +394,23 @@ export function useLtAuth() {
367
394
  });
368
395
  const result = await registerResponse.json();
369
396
  if (!registerResponse.ok) {
370
- return { success: false, error: result.message || t("lt.auth.passkeyRegisterFailed", "Passkey-Registrierung fehlgeschlagen") };
397
+ return {
398
+ success: false,
399
+ error: result.message || t("lt.auth.passkeyRegisterFailed", "Passkey-Registrierung fehlgeschlagen")
400
+ };
371
401
  }
372
402
  return { success: true, passkey: result };
373
403
  } catch (err) {
374
404
  if (err instanceof Error && err.name === "NotAllowedError") {
375
- return { success: false, error: t("lt.auth.passkeyCreationAborted", "Passkey-Erstellung wurde abgebrochen") };
405
+ return {
406
+ success: false,
407
+ error: t("lt.auth.passkeyCreationAborted", "Passkey-Erstellung wurde abgebrochen")
408
+ };
376
409
  }
377
- return { success: false, error: err instanceof Error ? err.message : t("lt.auth.passkeyRegisterFailed", "Passkey-Registrierung fehlgeschlagen") };
410
+ return {
411
+ success: false,
412
+ error: err instanceof Error ? err.message : t("lt.auth.passkeyRegisterFailed", "Passkey-Registrierung fehlgeschlagen")
413
+ };
378
414
  } finally {
379
415
  isLoading.value = false;
380
416
  }
@@ -1,5 +1,5 @@
1
- export { useLtAuth } from './auth/use-lt-auth.js';
2
- export { useLtAuthClient, ltAuthClient } from './use-lt-auth-client.js';
3
- export { useLtTusUpload } from './use-lt-tus-upload.js';
4
- export { useLtFile } from './use-lt-file.js';
5
- export { useLtShare, type UseLtShareReturn } from './use-lt-share.js';
1
+ export { useLtAuth } from "./auth/use-lt-auth.js";
2
+ export { useLtAuthClient, ltAuthClient } from "./use-lt-auth-client.js";
3
+ export { useLtTusUpload } from "./use-lt-tus-upload.js";
4
+ export { useLtFile } from "./use-lt-file.js";
5
+ export { useLtShare, type UseLtShareReturn } from "./use-lt-share.js";
@@ -16,7 +16,7 @@
16
16
  * await authClient.passkey.listUserPasskeys();
17
17
  * ```
18
18
  */
19
- import { type LtAuthClient } from '../lib/auth-client.js';
19
+ import { type LtAuthClient } from "../lib/auth-client.js";
20
20
  /**
21
21
  * Returns the Better-Auth client singleton
22
22
  *
@@ -6,7 +6,7 @@
6
6
  * - URL generation for file access
7
7
  * - File size and duration formatting
8
8
  */
9
- import type { UseLtFileReturn } from '../types/index.js';
9
+ import type { UseLtFileReturn } from "../types/index.js";
10
10
  /**
11
11
  * File utilities composable
12
12
  *
@@ -32,7 +32,10 @@ export function useLtShare() {
32
32
  const toast = useToast();
33
33
  toast.add({
34
34
  color: "success",
35
- description: t("lt.share.copiedDescription", "Der Link wurde in die Zwischenablage kopiert."),
35
+ description: t(
36
+ "lt.share.copiedDescription",
37
+ "Der Link wurde in die Zwischenablage kopiert."
38
+ ),
36
39
  title: t("lt.share.copied", "Link kopiert")
37
40
  });
38
41
  } catch {
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * @see https://tus.io/
8
8
  */
9
- import type { LtUploadOptions, UseLtTusUploadReturn } from '../types/index.js';
9
+ import type { LtUploadOptions, UseLtTusUploadReturn } from "../types/index.js";
10
10
  /**
11
11
  * TUS Upload composable with pause/resume support
12
12
  *
@@ -135,7 +135,13 @@ export function useLtTusUpload(defaultOptions = {}) {
135
135
  file,
136
136
  id,
137
137
  metadata: defaultConfig.metadata,
138
- progress: { bytesTotal: file.size, bytesUploaded: 0, percentage: 0, remainingTime: 0, speed: 0 },
138
+ progress: {
139
+ bytesTotal: file.size,
140
+ bytesUploaded: 0,
141
+ percentage: 0,
142
+ remainingTime: 0,
143
+ speed: 0
144
+ },
139
145
  status: "idle"
140
146
  };
141
147
  const newMap = new Map(uploadItems.value);
@@ -7,7 +7,7 @@
7
7
  * SECURITY: Passwords are hashed with SHA256 client-side to prevent
8
8
  * plain text password transmission over the network.
9
9
  */
10
- import type { LtAuthClientConfig } from '../types/index.js';
10
+ import type { LtAuthClientConfig } from "../types/index.js";
11
11
  /**
12
12
  * Creates a configured Better-Auth client with password hashing
13
13
  *
@@ -58,8 +58,14 @@ export function createLtAuthClient(config = {}) {
58
58
  */
59
59
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
60
  changePassword: async (params, options) => {
61
- const [hashedCurrent, hashedNew] = await Promise.all([ltSha256(params.currentPassword), ltSha256(params.newPassword)]);
62
- return baseClient.changePassword?.({ currentPassword: hashedCurrent, newPassword: hashedNew }, options);
61
+ const [hashedCurrent, hashedNew] = await Promise.all([
62
+ ltSha256(params.currentPassword),
63
+ ltSha256(params.newPassword)
64
+ ]);
65
+ return baseClient.changePassword?.(
66
+ { currentPassword: hashedCurrent, newPassword: hashedNew },
67
+ options
68
+ );
63
69
  },
64
70
  /**
65
71
  * Reset password with token (new password is hashed before sending)
@@ -67,7 +73,10 @@ export function createLtAuthClient(config = {}) {
67
73
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
68
74
  resetPassword: async (params, options) => {
69
75
  const hashedPassword = await ltSha256(params.newPassword);
70
- return baseClient.resetPassword?.({ newPassword: hashedPassword, token: params.token }, options);
76
+ return baseClient.resetPassword?.(
77
+ { newPassword: hashedPassword, token: params.token },
78
+ options
79
+ );
71
80
  },
72
81
  // Override signIn to hash password (keep passkey method from plugin)
73
82
  signIn: {
@@ -127,7 +136,10 @@ export function createLtAuthClient(config = {}) {
127
136
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
128
137
  generateBackupCodes: async (params, options) => {
129
138
  const hashedPassword = await ltSha256(params.password);
130
- return baseClient.twoFactor.generateBackupCodes({ password: hashedPassword }, options);
139
+ return baseClient.twoFactor.generateBackupCodes(
140
+ { password: hashedPassword },
141
+ options
142
+ );
131
143
  },
132
144
  /**
133
145
  * Verify TOTP code (pass through to base client)
@@ -11,7 +11,7 @@
11
11
  *
12
12
  * The state is persisted in cookies for SSR compatibility.
13
13
  */
14
- import type { LtAuthMode } from '../types/index.js';
14
+ import type { LtAuthMode } from "../types/index.js";
15
15
  /**
16
16
  * Get the current auth mode from cookie
17
17
  */
@@ -1,2 +1,2 @@
1
- export { attemptLtJwtSwitch, createLtAuthFetch, getLtApiBase, getLtAuthMode, getLtJwtToken, isLtAuthenticated, ltAuthFetch, setLtAuthMode, setLtJwtToken, } from './auth-state.js';
2
- export { createLtAuthClient, type LtAuthClient } from './auth-client.js';
1
+ export { attemptLtJwtSwitch, createLtAuthFetch, getLtApiBase, getLtAuthMode, getLtJwtToken, isLtAuthenticated, ltAuthFetch, setLtAuthMode, setLtJwtToken, } from "./auth-state.js";
2
+ export { createLtAuthClient, type LtAuthClient } from "./auth-client.js";
@@ -9,6 +9,6 @@
9
9
  * Note: This is a client-only plugin (.client.ts) since auth state
10
10
  * management only makes sense in the browser context.
11
11
  */
12
- import type { NuxtApp } from '#app';
12
+ import type { NuxtApp } from "#app";
13
13
  declare const _default: (nuxtApp: NuxtApp) => void;
14
14
  export default _default;
@@ -6,7 +6,13 @@ export default (nuxtApp) => {
6
6
  const loginPath = runtimeConfig.loginPath || "/auth/login";
7
7
  const configuredPublicPaths = runtimeConfig.interceptor?.publicPaths || [];
8
8
  let isHandling401 = false;
9
- const defaultPublicPaths = ["/auth/login", "/auth/register", "/auth/forgot-password", "/auth/reset-password", "/auth/2fa"];
9
+ const defaultPublicPaths = [
10
+ "/auth/login",
11
+ "/auth/register",
12
+ "/auth/forgot-password",
13
+ "/auth/reset-password",
14
+ "/auth/2fa"
15
+ ];
10
16
  const publicAuthPaths = [.../* @__PURE__ */ new Set([...defaultPublicPaths, ...configuredPublicPaths])];
11
17
  function isPublicAuthRoute() {
12
18
  const route = nuxtApp.$router?.currentRoute?.value;
@@ -1,3 +1,3 @@
1
1
  {
2
- "extends": "../../../.nuxt/tsconfig.server.json",
2
+ "extends": "../../../.nuxt/tsconfig.server.json"
3
3
  }
@@ -1,4 +1,4 @@
1
- import type { ComputedRef, Ref } from 'vue';
1
+ import type { ComputedRef, Ref } from "vue";
2
2
  /**
3
3
  * User type for Better Auth session
4
4
  * Compatible with @lenne.tech/nest-server IAM module
@@ -20,7 +20,7 @@ export interface LtUser {
20
20
  * - 'cookie': Primary mode using HttpOnly session cookies (more secure)
21
21
  * - 'jwt': Fallback mode using JWT tokens in Authorization header
22
22
  */
23
- export type LtAuthMode = 'cookie' | 'jwt';
23
+ export type LtAuthMode = "cookie" | "jwt";
24
24
  /**
25
25
  * Stored auth state (persisted in cookie for SSR compatibility)
26
26
  */
@@ -1,3 +1,3 @@
1
- export type { LtAuthClientConfig, LtAuthMode, LtAuthResponse, LtAuthState, LtPasskeyAuthResult, LtPasskeyRegisterResult, LtUser, UseLtAuthReturn, } from './auth.js';
2
- export type { LtFileInfo, LtUploadItem, LtUploadOptions, LtUploadProgress, LtUploadStatus, UseLtFileReturn, UseLtTusUploadReturn, } from './upload.js';
3
- export type { LtAuthModuleOptions, LtExtensionsModuleOptions, LtExtensionsPublicRuntimeConfig, LtI18nModuleOptions, LtTusModuleOptions, } from './module.js';
1
+ export type { LtAuthClientConfig, LtAuthMode, LtAuthResponse, LtAuthState, LtPasskeyAuthResult, LtPasskeyRegisterResult, LtUser, UseLtAuthReturn, } from "./auth.js";
2
+ export type { LtFileInfo, LtUploadItem, LtUploadOptions, LtUploadProgress, LtUploadStatus, UseLtFileReturn, UseLtTusUploadReturn, } from "./upload.js";
3
+ export type { LtAuthModuleOptions, LtExtensionsModuleOptions, LtExtensionsPublicRuntimeConfig, LtI18nModuleOptions, LtTusModuleOptions, } from "./module.js";
@@ -78,11 +78,11 @@ export interface LtExtensionsPublicRuntimeConfig {
78
78
  };
79
79
  };
80
80
  }
81
- declare module 'nuxt/schema' {
81
+ declare module "nuxt/schema" {
82
82
  interface PublicRuntimeConfig extends LtExtensionsPublicRuntimeConfig {
83
83
  }
84
84
  }
85
- declare module '@nuxt/schema' {
85
+ declare module "@nuxt/schema" {
86
86
  interface PublicRuntimeConfig extends LtExtensionsPublicRuntimeConfig {
87
87
  }
88
88
  }
@@ -1,8 +1,8 @@
1
- import type { ComputedRef } from 'vue';
1
+ import type { ComputedRef } from "vue";
2
2
  /**
3
3
  * Status of an upload item
4
4
  */
5
- export type LtUploadStatus = 'completed' | 'error' | 'idle' | 'paused' | 'uploading';
5
+ export type LtUploadStatus = "completed" | "error" | "idle" | "paused" | "uploading";
6
6
  /**
7
7
  * Progress information for an upload
8
8
  */
@@ -1,2 +1,2 @@
1
- export { ltArrayBufferToBase64Url, ltBase64UrlToUint8Array, ltSha256 } from './crypto.js';
2
- export { tw } from './tw.js';
1
+ export { ltArrayBufferToBase64Url, ltBase64UrlToUint8Array, ltSha256 } from "./crypto.js";
2
+ export { tw } from "./tw.js";
package/dist/types.d.mts CHANGED
@@ -4,6 +4,10 @@ import type { default as Module } from './module.mjs'
4
4
 
5
5
  export type ModuleOptions = typeof Module extends NuxtModule<infer O> ? Partial<O> : Record<string, any>
6
6
 
7
- export { type LtExtensionsModuleOptions } from '../dist/runtime/types/index.js'
7
+ export { type LtAuthClientConfig, type LtAuthMode, type LtAuthResponse, type LtAuthState, type LtPasskeyAuthResult, type LtPasskeyRegisterResult, type LtUser, type UseLtAuthReturn } from '../dist/runtime/types/auth.js'
8
+
9
+ export { type LtFileInfo, type LtUploadItem, type LtUploadOptions, type LtUploadProgress, type LtUploadStatus, type UseLtFileReturn, type UseLtTusUploadReturn } from '../dist/runtime/types/upload.js'
10
+
11
+ export { type LtAuthModuleOptions, type LtExtensionsModuleOptions, type LtExtensionsPublicRuntimeConfig, type LtI18nModuleOptions, type LtTusModuleOptions } from '../dist/runtime/types/module.js'
8
12
 
9
13
  export { type configKey, default, type name, type version } from './module.mjs'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lenne.tech/nuxt-extensions",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Reusable Nuxt 4 composables, components, and Better-Auth integration for lenne.tech projects",
5
5
  "repository": {
6
6
  "type": "git",
@@ -39,11 +39,13 @@
39
39
  "build": "nuxt-module-build build",
40
40
  "lint": "oxlint src/",
41
41
  "lint:fix": "oxlint --fix src/",
42
+ "format": "oxfmt --write src/",
43
+ "format:check": "oxfmt --check src/",
42
44
  "test": "vitest run",
43
45
  "test:watch": "vitest watch",
44
46
  "test:coverage": "vitest run --coverage",
45
47
  "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit",
46
- "release": "npm run lint && npm run test && npm run prepack"
48
+ "release": "npm run format:check && npm run lint && npm run test && npm run prepack"
47
49
  },
48
50
  "dependencies": {
49
51
  "@nuxt/kit": "4.2.2"
@@ -77,6 +79,7 @@
77
79
  "better-auth": "1.4.10",
78
80
  "happy-dom": "20.3.7",
79
81
  "nuxt": "4.2.2",
82
+ "oxfmt": "0.26.0",
80
83
  "oxlint": "0.17.0",
81
84
  "tus-js-client": "4.3.1",
82
85
  "typescript": "5.9.3",