@lenne.tech/nuxt-extensions 1.5.1 → 1.5.3

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/CLAUDE.md ADDED
@@ -0,0 +1,115 @@
1
+ # @lenne.tech/nuxt-extensions
2
+
3
+ Reusable Nuxt 4 module providing composables, components, utilities, and Better Auth integration for lenne.tech projects.
4
+
5
+ ## Architecture
6
+
7
+ ```
8
+ src/
9
+ ├── module.ts # Nuxt module entry point (auto-imports, plugin registration)
10
+ ├── runtime/
11
+ │ ├── composables/ # Auto-imported composables
12
+ │ ├── components/ # Auto-imported components
13
+ │ ├── lib/ # Library exports (auth-client, helpers)
14
+ │ ├── middleware/ # Route middleware (auth)
15
+ │ ├── plugins/ # Nuxt plugins (auth initialization)
16
+ │ ├── server/ # Nitro server routes (auth proxy)
17
+ │ ├── testing/ # Playwright test helpers
18
+ │ ├── types/ # TypeScript type definitions
19
+ │ └── utils/ # Auto-imported utility functions
20
+ ```
21
+
22
+ ## Key Composables
23
+
24
+ | Composable | Purpose |
25
+ |-----------|---------|
26
+ | `useBetterAuth()` | Authentication state, login, logout, session management |
27
+ | `useAuthClient()` | Raw Better Auth client access |
28
+ | `useTusUpload()` | TUS resumable file uploads |
29
+
30
+ ## Module Configuration
31
+
32
+ Configure in `nuxt.config.ts`:
33
+
34
+ ```typescript
35
+ export default defineNuxtConfig({
36
+ modules: ['@lenne.tech/nuxt-extensions'],
37
+ lennetech: {
38
+ // API base URL for auth proxy
39
+ apiUrl: 'http://localhost:3000',
40
+ // Enable/disable features
41
+ betterAuth: true,
42
+ tusUpload: true,
43
+ }
44
+ })
45
+ ```
46
+
47
+ ## Authentication (Better Auth)
48
+
49
+ - SSR-safe session management via `useBetterAuth()`
50
+ - Auth proxy server route at `/api/auth/**` (proxies to backend)
51
+ - Middleware `auth` for protected routes
52
+ - Passkey (WebAuthn) support via `@better-auth/passkey` peer dependency
53
+ - 2FA (TOTP) support built-in
54
+
55
+ ### Auth Flow
56
+
57
+ 1. Frontend calls `useBetterAuth().signIn()` / `.signUp()`
58
+ 2. Request goes through Nitro proxy at `/api/auth/**`
59
+ 3. Proxy forwards to backend Better Auth endpoints
60
+ 4. Session cookie set via `httpOnly` cookie (SSR-safe)
61
+
62
+ ## Testing Helpers
63
+
64
+ Import from `@lenne.tech/nuxt-extensions/testing`:
65
+
66
+ ```typescript
67
+ import { createTestUser, loginTestUser } from '@lenne.tech/nuxt-extensions/testing';
68
+ ```
69
+
70
+ ## Authentication Cookie Rules
71
+
72
+ The `useLtAuth()` composable manages the `lt-auth-state` cookie for authentication state. Projects that implement custom auth middleware MUST follow these rules:
73
+
74
+ ### DO:
75
+ - Use `useLtAuth()` for all auth state management (login, logout, session validation)
76
+ - In custom auth middleware, read `lt-auth-state` via `document.cookie` (client) or `useCookie('lt-auth-state')` (server) — but ONLY for reading, never writing
77
+ - Let `setUser()` and `clearUser()` handle all cookie mutations
78
+
79
+ ### DON'T:
80
+ - Don't manually set `lt-auth-state` via `document.cookie` outside of `useLtAuth()`
81
+ - Don't call `useCookie('lt-auth-state')` with different options than `useLtAuth()` uses (`maxAge: 604800, sameSite: 'lax'`)
82
+ - Don't URL-decode or JSON-parse the cookie value manually on the server — `useCookie` handles this automatically
83
+ - Don't write to `authState.value` from custom middleware — this generates a `Set-Cookie` header in the SSR response that may overwrite the browser's cookie
84
+
85
+ ### How Auth Cookies Work:
86
+ 1. `setUser()` writes the cookie via both `useCookie().value` (for SSR sync) and `document.cookie` (for immediate availability)
87
+ 2. On SSR, `useCookie` reads the cookie from the HTTP Cookie header, URL-decodes it, and parses the JSON
88
+ 3. If `useLtAuth()` can't find a valid user in the cookie on the server, it initializes with `{user: null}` — this is intentional and correct
89
+ 4. The `iam.session_token` httpOnly cookie (set by Better Auth) is the actual session identifier — `lt-auth-state` is a convenience cache for the client-side middleware
90
+
91
+ ### Custom Auth Middleware Pattern:
92
+ ```typescript
93
+ // CORRECT — read-only check, no cookie mutation
94
+ export default defineNuxtRouteMiddleware((to) => {
95
+ if (import.meta.client) {
96
+ const cookie = document.cookie.split('; ').find(r => r.startsWith('lt-auth-state='));
97
+ if (cookie) {
98
+ const value = decodeURIComponent(cookie.split('=').slice(1).join('='));
99
+ const state = JSON.parse(value);
100
+ if (state?.user) return; // Authenticated
101
+ }
102
+ } else {
103
+ const authCookie = useCookie<{ user: unknown } | null>('lt-auth-state');
104
+ if (authCookie.value?.user) return; // Authenticated
105
+ }
106
+ return navigateTo('/auth/login');
107
+ });
108
+ ```
109
+
110
+ ## Development Rules
111
+
112
+ 1. **ALWAYS read source code** in `dist/runtime/` to understand available composables and components
113
+ 2. **Use `useBetterAuth()`** for authentication — never implement auth manually
114
+ 3. **Check existing composables** before creating new ones — this module may already provide what you need
115
+ 4. **Peer dependencies** (`better-auth`, `@better-auth/passkey`, `tus-js-client`) must be installed in the consuming project
package/dist/module.d.mts CHANGED
@@ -6,7 +6,7 @@ export { LtAuthModuleOptions, LtErrorTranslationModuleOptions, LtExtensionsModul
6
6
  export { LtErrorTranslationResponse, LtParsedError, UseLtErrorTranslationReturn } from '../dist/runtime/types/error.js';
7
7
 
8
8
  declare const name = "@lenne.tech/nuxt-extensions";
9
- declare const version = "1.4.0";
9
+ declare const version = "1.5.2";
10
10
  declare const configKey = "ltExtensions";
11
11
  declare const _default: _nuxt_schema.NuxtModule<LtExtensionsModuleOptions, LtExtensionsModuleOptions, false>;
12
12
 
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "configKey": "ltExtensions",
3
3
  "name": "@lenne.tech/nuxt-extensions",
4
- "version": "1.4.0",
4
+ "version": "1.5.2",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { defineNuxtModule, createResolver, addImports, addComponent, addPlugin, addRouteMiddleware } from '@nuxt/kit';
2
2
 
3
3
  const name = "@lenne.tech/nuxt-extensions";
4
- const version = "1.4.0";
4
+ const version = "1.5.2";
5
5
  const configKey = "ltExtensions";
6
6
  const defaultOptions = {
7
7
  auth: {
@@ -465,7 +465,7 @@ export declare function createLtAuthClient(config?: LtAuthClientConfig): {
465
465
  */
466
466
  passkey: any;
467
467
  social: <FetchOptions extends import("better-auth").ClientFetchOption<Partial<{
468
- provider: (string & {}) | "linear" | "huggingface" | "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "railway" | "vercel";
468
+ provider: (string & {}) | "linear" | "huggingface" | "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "railway" | "vercel" | "wechat";
469
469
  callbackURL?: string | undefined;
470
470
  newUserCallbackURL?: string | undefined;
471
471
  errorCallbackURL?: string | undefined;
@@ -489,7 +489,7 @@ export declare function createLtAuthClient(config?: LtAuthClientConfig): {
489
489
  loginHint?: string | undefined;
490
490
  additionalData?: Record<string, any> | undefined;
491
491
  }> & Record<string, any>, Partial<Record<string, any>> & Record<string, any>, Record<string, any> | undefined>>(data_0: import("better-auth").Prettify<{
492
- provider: (string & {}) | "linear" | "huggingface" | "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "railway" | "vercel";
492
+ provider: (string & {}) | "linear" | "huggingface" | "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "railway" | "vercel" | "wechat";
493
493
  callbackURL?: string | undefined;
494
494
  newUserCallbackURL?: string | undefined;
495
495
  errorCallbackURL?: string | undefined;
@@ -8,5 +8,6 @@
8
8
  * - needsSetup === true AND route != setupPath -> redirect to setupPath
9
9
  * - needsSetup === false AND route === setupPath -> redirect to loginPath
10
10
  */
11
- declare const _default: import("nuxt/app").RouteMiddleware;
11
+ import type { RouteMiddleware } from "#app";
12
+ declare const _default: RouteMiddleware;
12
13
  export default _default;
@@ -4,5 +4,6 @@
4
4
  * Automatically loads error translations on app start.
5
5
  * Provides global helper methods: $ltTranslateError, $ltShowErrorToast
6
6
  */
7
- declare const _default: import("nuxt/app").Plugin<Record<string, unknown>> & import("nuxt/app").ObjectPlugin<Record<string, unknown>>;
7
+ import type { ObjectPlugin, Plugin } from "#app";
8
+ declare const _default: Plugin & ObjectPlugin;
8
9
  export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lenne.tech/nuxt-extensions",
3
- "version": "1.5.1",
3
+ "version": "1.5.3",
4
4
  "description": "Reusable Nuxt 4 composables, components, and Better-Auth integration for lenne.tech projects",
5
5
  "repository": {
6
6
  "type": "git",
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "author": "lenne.Tech <info@lenne.tech> (https://lenne.tech)",
14
14
  "license": "MIT",
15
- "packageManager": "pnpm@10.32.1",
15
+ "packageManager": "pnpm@10.33.0",
16
16
  "type": "module",
17
17
  "exports": {
18
18
  ".": {
@@ -43,7 +43,8 @@
43
43
  }
44
44
  },
45
45
  "files": [
46
- "dist"
46
+ "dist",
47
+ "CLAUDE.md"
47
48
  ],
48
49
  "scripts": {
49
50
  "prepare": "git config core.hooksPath .githooks",
@@ -93,22 +94,22 @@
93
94
  }
94
95
  },
95
96
  "devDependencies": {
96
- "@better-auth/passkey": "1.5.5",
97
- "@nuxt/devtools": "3.2.3",
97
+ "@better-auth/passkey": "1.5.6",
98
+ "@nuxt/devtools": "3.2.4",
98
99
  "@nuxt/module-builder": "1.0.2",
99
100
  "@nuxt/schema": "4.4.2",
100
- "@playwright/test": "1.58.2",
101
- "@types/node": "25.5.0",
102
- "@vitest/coverage-v8": "4.1.0",
103
- "better-auth": "1.5.5",
104
- "happy-dom": "20.8.4",
101
+ "@playwright/test": "1.59.1",
102
+ "@types/node": "25.5.2",
103
+ "@vitest/coverage-v8": "4.1.2",
104
+ "better-auth": "1.5.6",
105
+ "happy-dom": "20.8.9",
105
106
  "nuxt": "4.4.2",
106
- "oxfmt": "0.40.0",
107
- "oxlint": "1.55.0",
107
+ "oxfmt": "0.43.0",
108
+ "oxlint": "1.58.0",
108
109
  "tus-js-client": "4.3.1",
109
110
  "typescript": "5.9.3",
110
- "vitest": "4.1.0",
111
- "vue-tsc": "3.2.5"
111
+ "vitest": "4.1.2",
112
+ "vue-tsc": "3.2.6"
112
113
  },
113
114
  "pnpm": {
114
115
  "onlyBuiltDependencies": [
@@ -116,13 +117,23 @@
116
117
  "esbuild"
117
118
  ],
118
119
  "overrides": {
119
- "minimatch@>=5.0.0 <5.1.8": "5.1.8",
120
- "minimatch@>=9.0.0 <9.0.7": "9.0.7",
121
- "minimatch@>=10.0.0 <10.2.3": "10.2.3",
120
+ "brace-expansion@<2.0.3": ">=2.0.3",
121
+ "brace-expansion@>=4.0.0 <5.0.5": ">=5.0.5",
122
+ "defu@<=6.1.4": ">=6.1.5",
123
+ "h3@<1.15.9": ">=1.15.9",
124
+ "lodash@<=4.17.23": ">=4.18.0",
125
+ "minimatch@>=5.0.0 <5.1.9": "5.1.9",
126
+ "minimatch@>=9.0.0 <9.0.9": "9.0.9",
127
+ "minimatch@>=10.0.0 <10.2.5": "10.2.5",
128
+ "node-forge@<1.4.0": ">=1.4.0",
129
+ "picomatch@<2.3.2": ">=2.3.2",
130
+ "picomatch@>=4.0.0 <4.0.4": ">=4.0.4",
122
131
  "rollup@>=4.0.0 <4.59.0": ">=4.59.0",
123
- "serialize-javascript@<=7.0.2": ">=7.0.3",
132
+ "serialize-javascript@<7.0.5": ">=7.0.5",
133
+ "srvx@<0.11.13": ">=0.11.13",
124
134
  "svgo@=4.0.0": ">=4.0.1",
125
- "tar@<7.5.11": "7.5.11"
135
+ "tar@<7.5.11": "7.5.11",
136
+ "yaml@>=2.0.0 <2.8.3": ">=2.8.3"
126
137
  }
127
138
  },
128
139
  "keywords": [