@lenne.tech/nuxt-extensions 1.19.1 → 1.20.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/CLAUDE.md CHANGED
@@ -347,7 +347,7 @@ fields at `app:beforeMount` and restores them at `app:mounted`, dispatching a sy
347
347
  Handling" below).
348
348
  3. **Check existing composables** before creating new ones — this module may already provide what you need
349
349
  4. **Peer dependencies** (`better-auth`, `@better-auth/passkey`, `tus-js-client`) must be installed in the consuming project.
350
- `better-auth` and `@better-auth/passkey` are pinned to **`>=1.7.7 <1.8.0`** — deliberately not a caret.
350
+ `better-auth` and `@better-auth/passkey` are pinned to **`>=1.7.12 <1.8.0`** — deliberately not a caret.
351
351
  **They move in lock-step with `@lenne.tech/nest-server`.** better-auth is one protocol with two ends;
352
352
  this module is the client end, nest-server the server end, and both declare the *same* narrow range.
353
353
  Raising it means raising it in **both** framework repos and pinning the new version in **both** starters,
package/README.md CHANGED
@@ -29,8 +29,8 @@ Reusable Nuxt 4 composables, components, and Better-Auth integration for lenne.t
29
29
  |---|---|---|
30
30
  | Node | `>= 22` | |
31
31
  | Nuxt | `^4.0.0` | |
32
- | `better-auth` | `>=1.7.7 <1.8.0` | **required peer** — pin it, see below |
33
- | `@better-auth/passkey` | `>=1.7.7 <1.8.0` | optional peer, passkey/WebAuthn only |
32
+ | `better-auth` | `>=1.7.12 <1.8.0` | **required peer** — pin it, see below |
33
+ | `@better-auth/passkey` | `>=1.7.12 <1.8.0` | optional peer, passkey/WebAuthn only |
34
34
  | `tus-js-client` | `>=4.0.0` | optional peer, resumable uploads only |
35
35
  | `@lenne.tech/nest-server` | `>= 11.37.0` | **only if you use the backend** — see the lock-step rule |
36
36
 
@@ -38,7 +38,7 @@ Reusable Nuxt 4 composables, components, and Better-Auth integration for lenne.t
38
38
  better-auth is one protocol with two ends. This module is the client end and
39
39
  `@lenne.tech/nest-server` is the server end, and they must resolve the **same**
40
40
  better-auth minor. better-auth breaks in *minor* releases — 1.7 removed subpath
41
- exports and changed the 2FA response shape — so a caret (`^1.7.7`) would re-open the
41
+ exports and changed the 2FA response shape — so a caret (`^1.7.12`) would re-open the
42
42
  hole at 1.8. If the api and the app drift apart, 2FA activation fails at runtime with a
43
43
  generic client error while **both** projects' checks stay green: each is internally
44
44
  consistent, and only the assembled workspace has both halves.
@@ -46,17 +46,21 @@ consistent, and only the assembled workspace has both halves.
46
46
  Raising better-auth therefore means raising it in `@lenne.tech/nest-server` **and**
47
47
  `@lenne.tech/nuxt-extensions` in one step.
48
48
 
49
- **Why the floor is 1.7.7:** better-auth below 1.7.7 is affected by
49
+ **Why the floor is 1.7.12:** better-auth before 1.7.12 verifies JWTs with the algorithm named
50
+ in the token's own header instead of the algorithm of the stored key
51
+ ([#11925](https://github.com/better-auth/better-auth/pull/11925)). Below 1.7.7 it is also
52
+ affected by
50
53
  [GHSA-965c-763c-88jm](https://github.com/better-auth/better-auth/security/advisories/GHSA-965c-763c-88jm)
51
- (critical): the OAuth state can be used as a magic link to sign in as another user. The flaw
52
- is in the server end, so your API must run 1.7.7 too, and the pin below keeps both halves on it.
54
+ (critical): the OAuth state can be used as a magic link to sign in as another user. Both flaws
55
+ are in the server end, so your API must run 1.7.12 too (`@lenne.tech/nest-server` 12.0.0
56
+ declares the same range), and the pin below keeps both halves on it.
53
57
 
54
58
  ## Installation
55
59
 
56
60
  ```bash
57
- npm install @lenne.tech/nuxt-extensions better-auth@1.7.7
61
+ npm install @lenne.tech/nuxt-extensions better-auth@1.7.12
58
62
  # Optional: For passkey support
59
- npm install @better-auth/passkey@1.7.7
63
+ npm install @better-auth/passkey@1.7.12
60
64
  # Optional: For TUS file uploads
61
65
  npm install tus-js-client
62
66
  ```
@@ -66,8 +70,8 @@ In a fullstack monorepo, pin it workspace-wide so the api and the app cannot dri
66
70
  ```yaml
67
71
  # pnpm-workspace.yaml
68
72
  overrides:
69
- better-auth: 1.7.7
70
- '@better-auth/passkey': 1.7.7
73
+ better-auth: 1.7.12
74
+ '@better-auth/passkey': 1.7.12
71
75
  ```
72
76
 
73
77
  ## Features
package/dist/module.d.mts CHANGED
@@ -1,12 +1,12 @@
1
- import * as _nuxt_schema from '@nuxt/schema';
1
+ import * as nuxt_schema from 'nuxt/schema';
2
2
  import { LtExtensionsModuleOptions } from '../dist/runtime/types/index.js';
3
3
  export * from '../dist/runtime/types/index.js';
4
4
 
5
5
  declare const name = "@lenne.tech/nuxt-extensions";
6
- declare const version = "1.19.1";
6
+ declare const version = "1.20.1";
7
7
  declare const configKey = "ltExtensions";
8
8
  declare const DEFAULT_LT_AUTH_STATE_COOKIE = "lt-auth-state";
9
9
  declare const DEFAULT_LT_JWT_TOKEN_COOKIE = "lt-jwt-token";
10
- declare const _default: _nuxt_schema.NuxtModule<LtExtensionsModuleOptions, LtExtensionsModuleOptions, false>;
10
+ declare const _default: nuxt_schema.NuxtModule<LtExtensionsModuleOptions, LtExtensionsModuleOptions, false>;
11
11
 
12
12
  export { DEFAULT_LT_AUTH_STATE_COOKIE, DEFAULT_LT_JWT_TOKEN_COOKIE, configKey, _default as default, name, version };
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.19.1",
4
+ "version": "1.20.1",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.3",
7
7
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -2,7 +2,7 @@ import { defineNuxtModule, createResolver, tryResolveModule, addImports, addComp
2
2
  import { pathToFileURL } from 'node:url';
3
3
 
4
4
  const name = "@lenne.tech/nuxt-extensions";
5
- const version = "1.19.1";
5
+ const version = "1.20.1";
6
6
  const configKey = "ltExtensions";
7
7
  const DEFAULT_LT_AUTH_STATE_COOKIE = "lt-auth-state";
8
8
  const DEFAULT_LT_JWT_TOKEN_COOKIE = "lt-jwt-token";
@@ -493,7 +493,7 @@ export function useLtAuth() {
493
493
  }
494
494
  if (import.meta.client && !featuresFetched.value) {
495
495
  featuresFetched.value = true;
496
- fetchFeatures();
496
+ void fetchFeatures();
497
497
  }
498
498
  return {
499
499
  // Auth state
@@ -173,7 +173,7 @@ export function useLtTusUpload(defaultOptions = {}) {
173
173
  const tusUpload = tusUploads.value.get(id);
174
174
  if (item && tusUpload && item.status !== "uploading") {
175
175
  updateItem(id, { startedAt: /* @__PURE__ */ new Date(), status: "uploading" });
176
- tusUpload.findPreviousUploads().then((previousUploads) => {
176
+ void tusUpload.findPreviousUploads().then((previousUploads) => {
177
177
  const previousUpload = previousUploads[0];
178
178
  if (previousUpload) {
179
179
  tusUpload.resumeFromPreviousUpload(previousUpload);
@@ -191,7 +191,7 @@ export function useLtTusUpload(defaultOptions = {}) {
191
191
  function pauseUpload(id) {
192
192
  const tusUpload = tusUploads.value.get(id);
193
193
  if (tusUpload) {
194
- tusUpload.abort();
194
+ void tusUpload.abort();
195
195
  updateItem(id, { status: "paused" });
196
196
  }
197
197
  }
@@ -207,7 +207,7 @@ export function useLtTusUpload(defaultOptions = {}) {
207
207
  function cancelUpload(id) {
208
208
  const tusUpload = tusUploads.value.get(id);
209
209
  if (tusUpload) {
210
- tusUpload.abort();
210
+ void tusUpload.abort();
211
211
  }
212
212
  tusUploads.value.delete(id);
213
213
  const newMap = new Map(uploadItems.value);
@@ -59,7 +59,7 @@ export function createLtAuthClient(config = {}) {
59
59
  plugins.push(
60
60
  twoFactorClient({
61
61
  onTwoFactorRedirect() {
62
- navigateTo(twoFactorRedirectPath);
62
+ void navigateTo(twoFactorRedirectPath);
63
63
  }
64
64
  })
65
65
  );
@@ -117,6 +117,8 @@ export default defineNuxtPlugin((nuxtApp) => {
117
117
  const currentPath = router?.currentRoute?.value?.fullPath;
118
118
  const redirectQuery = currentPath && currentPath !== loginPath ? `?redirect=${encodeURIComponent(currentPath)}` : "";
119
119
  window.location.href = loginPath + redirectQuery;
120
+ } catch (error) {
121
+ console.error("[LtAuth Interceptor] Handling a 401 failed:", error);
120
122
  } finally {
121
123
  if (loggingOut) {
122
124
  setTimeout(() => {
@@ -139,7 +141,7 @@ export default defineNuxtPlugin((nuxtApp) => {
139
141
  options.onResponseError(context);
140
142
  }
141
143
  if (context.response?.status === 401) {
142
- handleUnauthorized(url);
144
+ void handleUnauthorized(url);
143
145
  }
144
146
  }
145
147
  });
@@ -149,7 +151,7 @@ export default defineNuxtPlugin((nuxtApp) => {
149
151
  const response = await originalNativeFetch(input, init);
150
152
  if (response.status === 401) {
151
153
  const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
152
- handleUnauthorized(url);
154
+ void handleUnauthorized(url);
153
155
  }
154
156
  return response;
155
157
  };
@@ -66,6 +66,7 @@
66
66
  *
67
67
  * Default on; opt out with `ltExtensions.formLabelAssociation.enabled: false`.
68
68
  */
69
+ import type { ObjectPlugin, Plugin } from '#app';
69
70
  /**
70
71
  * Re-point every dangling field label at the control in its own field.
71
72
  *
@@ -123,5 +124,5 @@ export declare function repairFieldAssociations(root: Document | ParentNode): {
123
124
  groups: number;
124
125
  labels: number;
125
126
  };
126
- declare const _default: import("nuxt/app").Plugin<Record<string, unknown>> & import("nuxt/app").ObjectPlugin<Record<string, unknown>>;
127
+ declare const _default: Plugin & ObjectPlugin;
127
128
  export default _default;
@@ -51,6 +51,7 @@
51
51
  * browsers do not raise the on-screen keyboard for it. Preserving the entry avoids all of
52
52
  * that, because the field is never anything other than a normal, editable field.
53
53
  */
54
+ import type { ObjectPlugin, Plugin } from '#app';
54
55
  type EditableField = HTMLInputElement | HTMLTextAreaElement;
55
56
  /**
56
57
  * Collect fields the user edited before hydration.
@@ -67,5 +68,5 @@ export declare function collectEditedFields(root: ParentNode): Map<EditableField
67
68
  * @returns `true` when a value was actually restored.
68
69
  */
69
70
  export declare function restoreField(field: EditableField, value: string): boolean;
70
- declare const _default: import("nuxt/app").Plugin<Record<string, unknown>> & import("nuxt/app").ObjectPlugin<Record<string, unknown>>;
71
+ declare const _default: Plugin & ObjectPlugin;
71
72
  export default _default;
@@ -114,7 +114,7 @@ export async function waitForElement(page, selector, options = {}) {
114
114
  resolve();
115
115
  return;
116
116
  }
117
- Promise.all(el.getAnimations().map((a) => a.finished)).then(() => resolve());
117
+ void Promise.allSettled(el.getAnimations().map((a) => a.finished)).then(() => resolve());
118
118
  });
119
119
  });
120
120
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lenne.tech/nuxt-extensions",
3
- "version": "1.19.1",
3
+ "version": "1.20.1",
4
4
  "description": "Reusable Nuxt 4 composables, components, and Better-Auth integration for lenne.tech projects",
5
5
  "repository": {
6
6
  "type": "git",
@@ -51,17 +51,17 @@
51
51
  "prepack": "node scripts/sync-module-version.mjs && nuxt-module-build build",
52
52
  "c": "pnpm run check",
53
53
  "check": "node scripts/check.mjs",
54
- "check:raw": "pnpm install --frozen-lockfile && pnpm audit && pnpm run check:suppressions && pnpm peers check && pnpm run format:check && pnpm run lint && pnpm run version:check && pnpm run dev:prepare && pnpm test:types && pnpm test && pnpm run build && pnpm run check:manifest",
55
- "check:fix": "pnpm install && pnpm audit --fix && pnpm run check:suppressions && pnpm peers check && pnpm run format && pnpm run lint:fix && pnpm run version:sync && pnpm test:types && pnpm test && pnpm run build && pnpm run check:manifest",
56
- "check:naf": "pnpm install && pnpm peers check && pnpm run format && pnpm run lint:fix && pnpm run version:sync && pnpm test:types && pnpm test && pnpm run build && pnpm run check:manifest",
54
+ "check:raw": "pnpm install --frozen-lockfile && pnpm audit && pnpm run check:suppressions && pnpm peers check && pnpm run format:check && pnpm run dev:prepare && pnpm run lint && pnpm run version:check && pnpm test:types && pnpm test && pnpm run build && pnpm run check:manifest",
55
+ "check:fix": "pnpm install && pnpm audit --fix && pnpm run check:suppressions && pnpm peers check && pnpm run format && pnpm run dev:prepare && pnpm run lint:fix && pnpm run version:sync && pnpm test:types && pnpm test && pnpm run build && pnpm run check:manifest",
56
+ "check:naf": "pnpm install && pnpm peers check && pnpm run format && pnpm run dev:prepare && pnpm run lint:fix && pnpm run version:sync && pnpm test:types && pnpm test && pnpm run build && pnpm run check:manifest",
57
57
  "cf": "pnpm run check:fix",
58
58
  "cnaf": "pnpm run check:naf",
59
59
  "dev": "pnpm dev:prepare && nuxt dev playground",
60
60
  "dev:build": "nuxt build playground",
61
61
  "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxt prepare playground",
62
62
  "build": "nuxt-module-build build",
63
- "lint": "oxlint src/ scripts/",
64
- "lint:fix": "oxlint --fix src/ scripts/",
63
+ "lint": "oxlint --type-aware src/ scripts/",
64
+ "lint:fix": "oxlint --type-aware --fix src/ scripts/",
65
65
  "format": "oxfmt --write src/",
66
66
  "format:check": "oxfmt --check src/",
67
67
  "version:sync": "node scripts/sync-module-version.mjs",
@@ -70,7 +70,7 @@
70
70
  "test:watch": "vitest watch",
71
71
  "test:coverage": "vitest run --coverage",
72
72
  "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit",
73
- "release": "pnpm format:check && pnpm lint && pnpm run version:check && pnpm test:types && pnpm test && pnpm run check:consumer && pnpm prepack",
73
+ "release": "pnpm format:check && pnpm run dev:prepare && pnpm lint && pnpm run version:check && pnpm test:types && pnpm test && pnpm run check:consumer && pnpm prepack",
74
74
  "check:consumer": "node scripts/check-consumer-build.mjs",
75
75
  "check:manifest": "node scripts/check-package-manifest.mjs",
76
76
  "check:suppressions": "node scripts/check-suppressions.mjs"
@@ -79,9 +79,9 @@
79
79
  "@nuxt/kit": "^4.0.0"
80
80
  },
81
81
  "peerDependencies": {
82
- "@better-auth/passkey": ">=1.7.7 <1.8.0",
82
+ "@better-auth/passkey": ">=1.7.12 <1.8.0",
83
83
  "@playwright/test": ">=1.0.0",
84
- "better-auth": ">=1.7.7 <1.8.0",
84
+ "better-auth": ">=1.7.12 <1.8.0",
85
85
  "nuxt": "^4.0.0",
86
86
  "tus-js-client": ">=4.0.0"
87
87
  },
@@ -100,24 +100,25 @@
100
100
  }
101
101
  },
102
102
  "devDependencies": {
103
- "@better-auth/passkey": "1.7.7",
103
+ "@better-auth/passkey": "1.7.12",
104
104
  "@nuxt/module-builder": "1.0.3",
105
- "@nuxt/schema": "4.6.1",
106
- "@nuxt/ui": "4.11.3",
107
- "@playwright/test": "1.64.0",
105
+ "@nuxt/schema": "4.6.3",
106
+ "@nuxt/ui": "4.12.0",
107
+ "@playwright/test": "1.64.1",
108
108
  "@types/node": "26.6.5",
109
- "@vitest/coverage-v8": "5.0.3",
110
- "@vue/server-renderer": "3.5.43",
111
- "better-auth": "1.7.7",
109
+ "@vitest/coverage-v8": "5.0.5",
110
+ "@vue/server-renderer": "3.5.44",
111
+ "better-auth": "1.7.12",
112
112
  "cross-spawn": "7.0.6",
113
- "happy-dom": "20.14.6",
114
- "nuxt": "4.6.1",
115
- "oxfmt": "0.72.0",
116
- "oxlint": "1.87.0",
117
- "reka-ui": "2.10.5",
113
+ "happy-dom": "21.0.4",
114
+ "nuxt": "4.6.3",
115
+ "oxfmt": "0.75.0",
116
+ "oxlint": "1.90.0",
117
+ "oxlint-tsgolint": "7.0.2005",
118
+ "reka-ui": "2.11.0",
118
119
  "tus-js-client": "4.3.1",
119
120
  "typescript": "5.9.3",
120
- "vitest": "5.0.3",
121
+ "vitest": "5.0.5",
121
122
  "vue-tsc": "3.3.13"
122
123
  },
123
124
  "keywords": [
@@ -137,5 +138,5 @@
137
138
  "node": ">= 22",
138
139
  "pnpm": "^11.0.0"
139
140
  },
140
- "packageManager": "pnpm@11.28.5+sha512.484563d30b4c2ad27cb48aa94ff2b302dbcebc8ff6bf28816c2589886e146ce7f76f354f3bc1a438e6f5e9768c302aa0a6f7add8232903cd4cf81426cbc14d9e"
141
+ "packageManager": "pnpm@11.28.9+sha512.35421cea2720eca3f5ad722b67e8ef18f4d3cd4745ed2fcfeb0dc288d4e9437fad3870d91ee6e83f268f0f6f7e0f62723317b19617bb45ee4333172ef51159f8"
141
142
  }