@nuxtjs/better-auth 0.2.4 → 0.3.0

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.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxtjs/better-auth",
3
- "version": "0.2.4",
3
+ "version": "0.3.0",
4
4
  "configKey": "auth",
5
5
  "compatibility": {
6
6
  "nuxt": ">=4.0.0"
package/dist/module.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { existsSync, statSync, writeFileSync, readFileSync } from 'node:fs';
2
2
  import { mkdir, writeFile } from 'node:fs/promises';
3
- import { getLayerDirectories, updateTemplates, addServerImportsDir, addServerImports, addServerScanDir, addServerHandler, addImportsDir, addPlugin, addComponentsDir, extendPages, addTemplate, hasNuxtModule, addTypeTemplate, defineNuxtModule, createResolver } from '@nuxt/kit';
3
+ import { getLayerDirectories, updateTemplates, addServerImports, addServerScanDir, addServerHandler, addImports, addPlugin, addComponentsDir, extendPages, addTemplate, hasNuxtModule, addTypeTemplate, defineNuxtModule, createResolver } from '@nuxt/kit';
4
4
  import { consola as consola$1 } from 'consola';
5
5
  import { isAbsolute, join, resolve, relative, dirname } from 'pathe';
6
6
  import { defu } from 'defu';
@@ -10,7 +10,7 @@ import { randomBytes } from 'node:crypto';
10
10
  import { isCI, isTest } from 'std-env';
11
11
  export { defineClientAuth, defineServerAuth } from '../dist/runtime/config.js';
12
12
 
13
- const version = "0.2.4";
13
+ const version = "0.3.0";
14
14
 
15
15
  const CONFIG_EXTENSIONS = [".ts", ".js"];
16
16
  const CONFIG_EXTENSION_RE$1 = /\.(?:ts|js)$/;
@@ -177,13 +177,31 @@ function registerTemplateHmrHook(nuxt) {
177
177
  function registerServerRuntime(input) {
178
178
  const { clientOnly, resolve } = input;
179
179
  if (!clientOnly) {
180
- addServerImportsDir(resolve("./runtime/server/utils"));
181
- addServerImports([{ name: "defineServerAuth", from: resolve("./runtime/config") }]);
180
+ addServerImports([
181
+ { name: "defineServerAuth", from: resolve("./runtime/config") },
182
+ { name: "serverAuth", from: resolve("./runtime/server/utils/auth") },
183
+ ...["getRequestSession", "getUserSession", "setRequestSession", "refreshSessionCookieCache", "setSessionCookie", "createSession", "requireUserSession"].map((name) => ({ name, from: resolve("./runtime/server/utils/session") }))
184
+ ]);
182
185
  addServerScanDir(resolve("./runtime/server/middleware"));
183
186
  addServerHandler({ route: "/api/auth/**", handler: resolve("./runtime/server/api/auth/[...all]") });
184
187
  }
185
- addImportsDir(resolve("./runtime/app/composables"));
186
- addImportsDir(resolve("./runtime/utils"));
188
+ addImports([
189
+ "runWithSessionRefresh",
190
+ "useAction",
191
+ "useAuthAsyncData",
192
+ "useAuthClient",
193
+ "useAuthClientAction",
194
+ "useAuthRequestFetch",
195
+ "useSignIn",
196
+ "useSignOut",
197
+ "useSignUp",
198
+ "useUserSession",
199
+ "useUserSessionState"
200
+ ].map((name) => ({ name, from: resolve("./runtime/composables") })));
201
+ addImports([
202
+ ...["SignOutOptions", "UseUserSessionReturn", "UseUserSessionStateReturn"].map((name) => ({ name, type: true, from: resolve("./runtime/composables") })),
203
+ { name: "UseAuthAsyncDataOptions", type: true, from: resolve("./runtime/app/composables/useAuthAsyncData") }
204
+ ]);
187
205
  if (!clientOnly)
188
206
  addPlugin({ src: resolve("./runtime/app/plugins/session.server"), mode: "server" });
189
207
  addPlugin({ src: resolve("./runtime/app/plugins/session.client"), mode: "client" });
@@ -202,8 +220,7 @@ function registerPrepareTypesHook(input) {
202
220
  const projectReferenceTypePaths = [
203
221
  join(nuxt.options.buildDir, "types/nitro-imports.d.ts"),
204
222
  join(nuxt.options.buildDir, "types/auth-database.d.ts"),
205
- join(nuxt.options.buildDir, "types/auth-schema.d.ts"),
206
- join(nuxt.options.buildDir, "types/auth-secondary-storage.d.ts")
223
+ join(nuxt.options.buildDir, "types/auth-schema.d.ts")
207
224
  ];
208
225
  if (hasHubDb)
209
226
  projectReferenceTypePaths.push(join(nuxt.options.buildDir, "hub/db.d.ts"));
@@ -213,7 +230,6 @@ function registerPrepareTypesHook(input) {
213
230
  "#auth/client": nuxt.options.alias["#auth/client"],
214
231
  "#auth/database": nuxt.options.alias["#auth/database"],
215
232
  "#auth/schema": nuxt.options.alias["#auth/schema"],
216
- "#auth/secondary-storage": nuxt.options.alias["#auth/secondary-storage"],
217
233
  "#auth/route-rules": nuxt.options.alias["#auth/route-rules"]
218
234
  };
219
235
  for (const [key, value] of Object.entries(exactNodeAliases)) {
@@ -668,9 +684,6 @@ ${plugins.imports}
668
684
  export default extendClientAuth(createAppAuthClient, [${plugins.names}])
669
685
  `;
670
686
  }
671
- function buildSecondaryStorageCode() {
672
- return "export function createSecondaryStorage() { return undefined }";
673
- }
674
687
  function buildDatabaseCode(input) {
675
688
  if (input.provider === "nuxthub") {
676
689
  if (input.hubDialect === "postgresql") {
@@ -946,6 +959,21 @@ async function resolveAuthModuleSetup(input, dependencies = {}) {
946
959
  };
947
960
  }
948
961
 
962
+ function buildNuxtFetchFallback(name) {
963
+ const options = "import('nuxt/app').UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, ReqT, Method>";
964
+ return ["undefined", "DataT"].map((defaultType) => `
965
+ export function ${name}<
966
+ ResT = void,
967
+ ErrorT = _NuxtFetchError,
968
+ ReqT extends NitroFetchRequest = NitroFetchRequest,
969
+ const Method extends _NuxtFetchMethod<ReqT> = ResT extends void ? 'get' extends _NuxtFetchMethod<ReqT> ? 'get' : _NuxtFetchMethod<ReqT> : _NuxtFetchMethod<ReqT>,
970
+ _ResT = ResT extends void ? import('nuxt/app').FetchResult<ReqT, Method> : ResT,
971
+ DataT = _ResT,
972
+ PickKeys extends _NuxtKeysOf<DataT> = _NuxtKeysOf<DataT>,
973
+ DefaultT = ${defaultType},
974
+ >(request: import('vue').Ref<ReqT> | ReqT | (() => ReqT), opts?: ${name === "useLazyFetch" ? `Omit<${options}, 'lazy'>` : options}): import('nuxt/app').AsyncData<_NuxtPickFrom<DataT, PickKeys> | DefaultT, ErrorT | undefined>
975
+ `).join("");
976
+ }
949
977
  function registerServerTypeTemplates(input) {
950
978
  const { serverConfigPath, hasHubDb, runtimeTypesPath, sharedServerConfigSafe, h3TypesPath, nitroTypesPath } = input;
951
979
  const routeRuleAugmentations = (nitroTypesPath === "nitro/types" ? [nitroTypesPath] : ["nitropack", nitroTypesPath]).map((moduleName) => `declare module '${moduleName}' {
@@ -957,14 +985,6 @@ function registerServerTypeTemplates(input) {
957
985
  }
958
986
  }`).join("\n");
959
987
  const serverConfigTypeTemplateOptions = sharedServerConfigSafe ? { nuxt: true, nitro: true, node: true, shared: true } : { nuxt: true, nitro: true, node: true };
960
- addTypeTemplate({
961
- filename: "types/auth-secondary-storage.d.ts",
962
- getContents: () => `
963
- declare module '#auth/secondary-storage' {
964
- export function createSecondaryStorage(): undefined
965
- }
966
- `
967
- }, { nitro: true });
968
988
  addTypeTemplate({
969
989
  filename: "types/auth-database.d.ts",
970
990
  getContents: () => `
@@ -999,7 +1019,6 @@ declare module '#auth/schema' {
999
1019
  /// <reference path="./nitro-imports.d.ts" />
1000
1020
  /// <reference path="./auth-database.d.ts" />
1001
1021
  /// <reference path="./auth-schema.d.ts" />
1002
- /// <reference path="./auth-secondary-storage.d.ts" />
1003
1022
  ${hasHubDb ? '/// <reference path="../hub/db.d.ts" />' : ""}
1004
1023
 
1005
1024
  export {}
@@ -1024,7 +1043,7 @@ declare module '@nuxtjs/better-auth/config' {
1024
1043
  filename: "types/nuxt-better-auth-infer.d.ts",
1025
1044
  getContents: () => `
1026
1045
  import type { BetterAuthOptions, BetterAuthPlugin, InferPluginTypes, UnionToIntersection } from 'better-auth'
1027
- import type { InferFieldsOutput } from 'better-auth/db'
1046
+ import type { InferFieldsInputClient, InferFieldsOutput } from 'better-auth/db'
1028
1047
  import type createServerAuth from '${serverConfigPath}'
1029
1048
 
1030
1049
  type _RawConfig = ReturnType<typeof createServerAuth>
@@ -1048,11 +1067,24 @@ type _InferModelFieldsFromOptions<C, M extends 'user' | 'session'> = C extends {
1048
1067
  ? InferFieldsOutput<F>
1049
1068
  : {}
1050
1069
 
1070
+ type _UserFields = NonNullable<NonNullable<BetterAuthOptions['user']>['additionalFields']>
1071
+
1072
+ type _InferUserInputFromPlugins<P> = P extends readonly (infer Plugin)[]
1073
+ ? UnionToIntersection<Plugin extends { schema: { user: { fields: infer F extends _UserFields } } } ? InferFieldsInputClient<F> : {}>
1074
+ : {}
1075
+
1076
+ type _UserInputFallback = Partial<_InferUserInputFromPlugins<_RawPlugins> & (
1077
+ _RawConfig extends { user: { additionalFields: infer F extends _UserFields } }
1078
+ ? InferFieldsInputClient<F>
1079
+ : {}
1080
+ )>
1081
+
1051
1082
  type _UserFallback = _InferModelFieldsFromPlugins<_RawPlugins, 'user'> & _InferModelFieldsFromOptions<_RawConfig, 'user'>
1052
1083
  type _SessionFallback = _InferModelFieldsFromPlugins<_RawPlugins, 'session'> & _InferModelFieldsFromOptions<_RawConfig, 'session'>
1053
1084
 
1054
1085
  declare module '#nuxt-better-auth' {
1055
1086
  interface AuthUser extends _UserFallback {}
1087
+ interface AuthUserUpdateInput extends _UserInputFallback {}
1056
1088
  interface AuthSession extends _SessionFallback {}
1057
1089
  type PluginTypes = InferPluginTypes<_Config>
1058
1090
  }
@@ -1080,8 +1112,10 @@ declare module '#nuxt-better-auth' {
1080
1112
  import type createServerAuth from '${serverConfigPath}'
1081
1113
  import type { BetterAuthOptions } from 'better-auth'
1082
1114
  import type { getEndpoints } from 'better-auth/api'
1083
- import type { Serialize, Simplify } from '${nitroTypesPath}'
1084
- import type { FetchError } from 'ofetch'
1115
+ import type { AvailableRouterMethod, NitroFetchRequest, Serialize, Simplify } from '${nitroTypesPath}'
1116
+ import type { useFetch as _NuxtUseFetch } from '#app/composables/fetch'
1117
+
1118
+ type _NuxtFetchError = NonNullable<ReturnType<typeof _NuxtUseFetch<void>>['error']['value']>
1085
1119
 
1086
1120
  type _RawConfig = ReturnType<typeof createServerAuth>
1087
1121
  type _RawPlugins = _RawConfig extends { plugins: infer P } ? P : _RawConfig extends { plugins?: infer P } ? P : []
@@ -1143,7 +1177,11 @@ type _AuthPatternFromRequestPath<Path extends string> = {
1143
1177
  }[_AuthApiPatternPath]
1144
1178
  type _AuthEndpointMethod<Path extends _AuthApiRequestPath> = Extract<keyof _GeneratedAuthInternalApi[_AuthPatternFromRequestPath<Path>], string>
1145
1179
 
1146
- type _AuthFetchMethod<Path extends _AuthApiRequestPath> = Extract<Exclude<import('${nitroTypesPath}').NitroFetchOptions<Path>['method'], undefined>, string>
1180
+ type _NuxtKeysOf<T> = Array<T extends T ? keyof T extends string ? keyof T : never : never>
1181
+ type _NuxtPickFrom<T, Keys extends string[]> = T extends unknown[] ? T : T extends Record<string, any> ? keyof T extends Keys[number] ? T : Keys[number] extends never ? T : Pick<T, Keys[number]> : T
1182
+ type _NuxtFetchMethod<ReqT extends NitroFetchRequest> = AvailableRouterMethod<ReqT> | Uppercase<AvailableRouterMethod<ReqT>>
1183
+
1184
+ type _AuthFetchMethod = _NuxtFetchMethod<string>
1147
1185
  type _AuthFetchDefaultMethod<Path extends _AuthApiRequestPath> = 'get'
1148
1186
  type _AuthFetchResolvedMethod<Path extends _AuthApiRequestPath, Method extends string> = Lowercase<Method> extends _AuthEndpointMethod<Path>
1149
1187
  ? Lowercase<Method>
@@ -1161,88 +1199,50 @@ declare module '#nuxt-better-auth' {
1161
1199
  > = AuthApiInternalRoutes[_AuthPatternFromRequestPath<Path>][Method]
1162
1200
  }
1163
1201
 
1164
- declare module 'nuxt/dist/app/composables/fetch' {
1165
- export function useFetch<
1166
- ErrorT = FetchError,
1167
- Path extends import('#nuxt-better-auth').AuthApiEndpointPath = import('#nuxt-better-auth').AuthApiEndpointPath,
1168
- Method extends _AuthFetchMethod<Path> = _AuthFetchDefaultMethod<Path>,
1169
- _ResT = _AuthFetchResult<Path, Method>,
1170
- DataT = _ResT,
1171
- PickKeys extends import('nuxt/dist/app/composables/asyncData').KeysOf<DataT> = import('nuxt/dist/app/composables/asyncData').KeysOf<DataT>,
1172
- DefaultT = undefined,
1173
- >(request: import('vue').Ref<Path> | Path | (() => Path), opts?: import('nuxt/dist/app/composables/fetch').UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, Path, Method>): import('nuxt/dist/app/composables/asyncData').AsyncData<import('nuxt/dist/app/composables/asyncData').PickFrom<DataT, PickKeys> | DefaultT, ErrorT | undefined>
1174
- export function useFetch<
1175
- ErrorT = FetchError,
1176
- Path extends import('#nuxt-better-auth').AuthApiEndpointPath = import('#nuxt-better-auth').AuthApiEndpointPath,
1177
- Method extends _AuthFetchMethod<Path> = _AuthFetchDefaultMethod<Path>,
1178
- _ResT = _AuthFetchResult<Path, Method>,
1179
- DataT = _ResT,
1180
- PickKeys extends import('nuxt/dist/app/composables/asyncData').KeysOf<DataT> = import('nuxt/dist/app/composables/asyncData').KeysOf<DataT>,
1181
- DefaultT = DataT,
1182
- >(request: import('vue').Ref<Path> | Path | (() => Path), opts?: import('nuxt/dist/app/composables/fetch').UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, Path, Method>): import('nuxt/dist/app/composables/asyncData').AsyncData<import('nuxt/dist/app/composables/asyncData').PickFrom<DataT, PickKeys> | DefaultT, ErrorT | undefined>
1183
- export function useFetch(request: string | import('vue').Ref<string> | (() => string), opts?: any): any
1184
-
1185
- export function useLazyFetch<
1186
- ErrorT = FetchError,
1187
- Path extends import('#nuxt-better-auth').AuthApiEndpointPath = import('#nuxt-better-auth').AuthApiEndpointPath,
1188
- Method extends _AuthFetchMethod<Path> = _AuthFetchDefaultMethod<Path>,
1189
- _ResT = _AuthFetchResult<Path, Method>,
1190
- DataT = _ResT,
1191
- PickKeys extends import('nuxt/dist/app/composables/asyncData').KeysOf<DataT> = import('nuxt/dist/app/composables/asyncData').KeysOf<DataT>,
1192
- DefaultT = undefined,
1193
- >(request: import('vue').Ref<Path> | Path | (() => Path), opts?: Omit<import('nuxt/dist/app/composables/fetch').UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, Path, Method>, 'lazy'>): import('nuxt/dist/app/composables/asyncData').AsyncData<import('nuxt/dist/app/composables/asyncData').PickFrom<DataT, PickKeys> | DefaultT, ErrorT | undefined>
1194
- export function useLazyFetch<
1195
- ErrorT = FetchError,
1196
- Path extends import('#nuxt-better-auth').AuthApiEndpointPath = import('#nuxt-better-auth').AuthApiEndpointPath,
1197
- Method extends _AuthFetchMethod<Path> = _AuthFetchDefaultMethod<Path>,
1198
- _ResT = _AuthFetchResult<Path, Method>,
1199
- DataT = _ResT,
1200
- PickKeys extends import('nuxt/dist/app/composables/asyncData').KeysOf<DataT> = import('nuxt/dist/app/composables/asyncData').KeysOf<DataT>,
1201
- DefaultT = DataT,
1202
- >(request: import('vue').Ref<Path> | Path | (() => Path), opts?: Omit<import('nuxt/dist/app/composables/fetch').UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, Path, Method>, 'lazy'>): import('nuxt/dist/app/composables/asyncData').AsyncData<import('nuxt/dist/app/composables/asyncData').PickFrom<DataT, PickKeys> | DefaultT, ErrorT | undefined>
1203
- export function useLazyFetch(request: string | import('vue').Ref<string> | (() => string), opts?: any): any
1204
- }
1205
-
1206
1202
  declare module 'nuxt/app' {
1207
1203
  export function useFetch<
1208
- ErrorT = FetchError,
1204
+ ResT = void,
1205
+ ErrorT = _NuxtFetchError,
1209
1206
  Path extends import('#nuxt-better-auth').AuthApiEndpointPath = import('#nuxt-better-auth').AuthApiEndpointPath,
1210
- Method extends _AuthFetchMethod<Path> = _AuthFetchDefaultMethod<Path>,
1211
- _ResT = _AuthFetchResult<Path, Method>,
1207
+ const Method extends _AuthFetchMethod = _AuthFetchDefaultMethod<Path>,
1208
+ _ResT = ResT extends void ? _AuthFetchResult<Path, Method> : ResT,
1212
1209
  DataT = _ResT,
1213
- PickKeys extends import('nuxt/dist/app/composables/asyncData').KeysOf<DataT> = import('nuxt/dist/app/composables/asyncData').KeysOf<DataT>,
1210
+ PickKeys extends _NuxtKeysOf<DataT> = _NuxtKeysOf<DataT>,
1214
1211
  DefaultT = undefined,
1215
- >(request: import('vue').Ref<Path> | Path | (() => Path), opts?: import('nuxt/dist/app/composables/fetch').UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, Path, Method>): import('nuxt/dist/app/composables/asyncData').AsyncData<import('nuxt/dist/app/composables/asyncData').PickFrom<DataT, PickKeys> | DefaultT, ErrorT | undefined>
1212
+ >(request: import('vue').Ref<Path> | Path | (() => Path), opts?: import('nuxt/app').UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, Path, Method>): import('nuxt/app').AsyncData<_NuxtPickFrom<DataT, PickKeys> | DefaultT, ErrorT | undefined>
1216
1213
  export function useFetch<
1217
- ErrorT = FetchError,
1214
+ ResT = void,
1215
+ ErrorT = _NuxtFetchError,
1218
1216
  Path extends import('#nuxt-better-auth').AuthApiEndpointPath = import('#nuxt-better-auth').AuthApiEndpointPath,
1219
- Method extends _AuthFetchMethod<Path> = _AuthFetchDefaultMethod<Path>,
1220
- _ResT = _AuthFetchResult<Path, Method>,
1217
+ const Method extends _AuthFetchMethod = _AuthFetchDefaultMethod<Path>,
1218
+ _ResT = ResT extends void ? _AuthFetchResult<Path, Method> : ResT,
1221
1219
  DataT = _ResT,
1222
- PickKeys extends import('nuxt/dist/app/composables/asyncData').KeysOf<DataT> = import('nuxt/dist/app/composables/asyncData').KeysOf<DataT>,
1220
+ PickKeys extends _NuxtKeysOf<DataT> = _NuxtKeysOf<DataT>,
1223
1221
  DefaultT = DataT,
1224
- >(request: import('vue').Ref<Path> | Path | (() => Path), opts?: import('nuxt/dist/app/composables/fetch').UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, Path, Method>): import('nuxt/dist/app/composables/asyncData').AsyncData<import('nuxt/dist/app/composables/asyncData').PickFrom<DataT, PickKeys> | DefaultT, ErrorT | undefined>
1225
- export function useFetch(request: string | import('vue').Ref<string> | (() => string), opts?: any): any
1222
+ >(request: import('vue').Ref<Path> | Path | (() => Path), opts?: import('nuxt/app').UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, Path, Method>): import('nuxt/app').AsyncData<_NuxtPickFrom<DataT, PickKeys> | DefaultT, ErrorT | undefined>
1223
+ ${buildNuxtFetchFallback("useFetch")}
1226
1224
 
1227
1225
  export function useLazyFetch<
1228
- ErrorT = FetchError,
1226
+ ResT = void,
1227
+ ErrorT = _NuxtFetchError,
1229
1228
  Path extends import('#nuxt-better-auth').AuthApiEndpointPath = import('#nuxt-better-auth').AuthApiEndpointPath,
1230
- Method extends _AuthFetchMethod<Path> = _AuthFetchDefaultMethod<Path>,
1231
- _ResT = _AuthFetchResult<Path, Method>,
1229
+ const Method extends _AuthFetchMethod = _AuthFetchDefaultMethod<Path>,
1230
+ _ResT = ResT extends void ? _AuthFetchResult<Path, Method> : ResT,
1232
1231
  DataT = _ResT,
1233
- PickKeys extends import('nuxt/dist/app/composables/asyncData').KeysOf<DataT> = import('nuxt/dist/app/composables/asyncData').KeysOf<DataT>,
1232
+ PickKeys extends _NuxtKeysOf<DataT> = _NuxtKeysOf<DataT>,
1234
1233
  DefaultT = undefined,
1235
- >(request: import('vue').Ref<Path> | Path | (() => Path), opts?: Omit<import('nuxt/dist/app/composables/fetch').UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, Path, Method>, 'lazy'>): import('nuxt/dist/app/composables/asyncData').AsyncData<import('nuxt/dist/app/composables/asyncData').PickFrom<DataT, PickKeys> | DefaultT, ErrorT | undefined>
1234
+ >(request: import('vue').Ref<Path> | Path | (() => Path), opts?: Omit<import('nuxt/app').UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, Path, Method>, 'lazy'>): import('nuxt/app').AsyncData<_NuxtPickFrom<DataT, PickKeys> | DefaultT, ErrorT | undefined>
1236
1235
  export function useLazyFetch<
1237
- ErrorT = FetchError,
1236
+ ResT = void,
1237
+ ErrorT = _NuxtFetchError,
1238
1238
  Path extends import('#nuxt-better-auth').AuthApiEndpointPath = import('#nuxt-better-auth').AuthApiEndpointPath,
1239
- Method extends _AuthFetchMethod<Path> = _AuthFetchDefaultMethod<Path>,
1240
- _ResT = _AuthFetchResult<Path, Method>,
1239
+ const Method extends _AuthFetchMethod = _AuthFetchDefaultMethod<Path>,
1240
+ _ResT = ResT extends void ? _AuthFetchResult<Path, Method> : ResT,
1241
1241
  DataT = _ResT,
1242
- PickKeys extends import('nuxt/dist/app/composables/asyncData').KeysOf<DataT> = import('nuxt/dist/app/composables/asyncData').KeysOf<DataT>,
1242
+ PickKeys extends _NuxtKeysOf<DataT> = _NuxtKeysOf<DataT>,
1243
1243
  DefaultT = DataT,
1244
- >(request: import('vue').Ref<Path> | Path | (() => Path), opts?: Omit<import('nuxt/dist/app/composables/fetch').UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, Path, Method>, 'lazy'>): import('nuxt/dist/app/composables/asyncData').AsyncData<import('nuxt/dist/app/composables/asyncData').PickFrom<DataT, PickKeys> | DefaultT, ErrorT | undefined>
1245
- export function useLazyFetch(request: string | import('vue').Ref<string> | (() => string), opts?: any): any
1244
+ >(request: import('vue').Ref<Path> | Path | (() => Path), opts?: Omit<import('nuxt/app').UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, Path, Method>, 'lazy'>): import('nuxt/app').AsyncData<_NuxtPickFrom<DataT, PickKeys> | DefaultT, ErrorT | undefined>
1245
+ ${buildNuxtFetchFallback("useLazyFetch")}
1246
1246
  }
1247
1247
  export {}
1248
1248
  `
@@ -1284,6 +1284,8 @@ declare module '#nuxt-better-auth' {
1284
1284
  userAgent?: string | null
1285
1285
  }
1286
1286
 
1287
+ export type ClientAuthSession = Omit<AuthSession, 'token'>
1288
+
1287
1289
  export interface ServerAuthContext {
1288
1290
  runtimeConfig: Record<string, unknown>
1289
1291
  db: unknown
@@ -1293,15 +1295,20 @@ declare module '#nuxt-better-auth' {
1293
1295
  export interface AuthSocialProviderRegistry {}
1294
1296
  export type AuthSocialProviderId = AuthSocialProviderRegistry extends { ids: infer T } ? Extract<T, string> : never
1295
1297
 
1298
+ export interface AuthUserUpdateInput {
1299
+ name?: string
1300
+ image?: string | null
1301
+ }
1302
+
1296
1303
  export interface UserSessionComposable {
1297
1304
  user: Ref<AuthUser | null>
1298
- session: Ref<AuthSession | null>
1305
+ session: Ref<ClientAuthSession | null>
1299
1306
  loggedIn: ComputedRef<boolean>
1300
1307
  ready: ComputedRef<boolean>
1301
1308
  fetchSession: (options?: { headers?: HeadersInit, force?: boolean }) => Promise<void>
1302
1309
  waitForSession: () => Promise<void>
1303
1310
  signOut: (options?: { onSuccess?: () => void | Promise<void> }) => Promise<void>
1304
- updateUser: (updates: Partial<AuthUser>) => Promise<void>
1311
+ updateUser: (updates: AuthUserUpdateInput) => Promise<void>
1305
1312
  }
1306
1313
 
1307
1314
  export type UserMatch<T> = { [K in keyof T]?: T[K] | T[K][] }
@@ -1335,8 +1342,10 @@ export {}
1335
1342
  filename: "types/nuxt-better-auth-client.d.ts",
1336
1343
  getContents: () => `
1337
1344
  import type createAppAuthClient from '${input.clientConfigPath}'
1345
+ type _ClientUserUpdateInput = Omit<NonNullable<Parameters<ReturnType<typeof createAppAuthClient>['updateUser']>[0]>, 'fetchOptions'>
1338
1346
  declare module '#nuxt-better-auth' {
1339
1347
  export type AppAuthClient = ReturnType<typeof createAppAuthClient>
1348
+ interface AuthUserUpdateInput extends _ClientUserUpdateInput {}
1340
1349
  }
1341
1350
  `
1342
1351
  });
@@ -1456,12 +1465,6 @@ const module$1 = defineNuxtModule({
1456
1465
  nuxt.options.alias["#auth/server"] = serverConfigPath;
1457
1466
  nuxt.options.alias["#auth/client"] = clientConfigPath;
1458
1467
  if (!setup.clientOnly) {
1459
- const secondaryStorageTemplate = addTemplate({
1460
- filename: "better-auth/secondary-storage.mjs",
1461
- getContents: () => buildSecondaryStorageCode(),
1462
- write: true
1463
- });
1464
- nuxt.options.alias["#auth/secondary-storage"] = secondaryStorageTemplate.dst;
1465
1468
  const databaseTemplate = addTemplate({
1466
1469
  filename: "better-auth/database.mjs",
1467
1470
  getContents: () => setup.database.providerDefinition.buildDatabaseCode(setup.database.buildContext),
@@ -1,7 +1,7 @@
1
1
  declare var __VLS_1: {
2
2
  loggedIn: boolean;
3
3
  user: import("../../types.js").AuthUser | null;
4
- session: import("../../types.js").AuthSession | null;
4
+ session: import("../../types.js").ClientAuthSession | null;
5
5
  signOut: (options?: import("../composables/useUserSession.js").SignOutOptions) => Promise<void>;
6
6
  }, __VLS_3: {};
7
7
  type __VLS_Slots = {} & {
@@ -1,7 +1,7 @@
1
1
  declare var __VLS_1: {
2
2
  loggedIn: boolean;
3
3
  user: import("../../types.js").AuthUser | null;
4
- session: import("../../types.js").AuthSession | null;
4
+ session: import("../../types.js").ClientAuthSession | null;
5
5
  signOut: (options?: import("../composables/useUserSession.js").SignOutOptions) => Promise<void>;
6
6
  }, __VLS_3: {};
7
7
  type __VLS_Slots = {} & {
@@ -0,0 +1 @@
1
+ export declare function useSignOut(): import("../internal/auth-action-handles.js").UserAuthActionHandle<[options?: import("./useUserSession.js").SignOutOptions | undefined], void>;
@@ -0,0 +1,6 @@
1
+ import { useAction } from "./useAction.js";
2
+ import { useUserSession } from "./useUserSession.js";
3
+ export function useSignOut() {
4
+ const { signOut } = useUserSession();
5
+ return useAction(signOut);
6
+ }
@@ -1,10 +1,10 @@
1
1
  import type { ComputedRef, Ref } from 'vue';
2
- import type { AuthSession, AuthUser } from '#nuxt-better-auth';
2
+ import type { AuthUser, AuthUserUpdateInput, ClientAuthSession } from '#nuxt-better-auth';
3
3
  export interface SignOutOptions {
4
4
  onSuccess?: () => void | Promise<void>;
5
5
  }
6
6
  export interface UseUserSessionReturn {
7
- session: Ref<AuthSession | null>;
7
+ session: Ref<ClientAuthSession | null>;
8
8
  user: Ref<AuthUser | null>;
9
9
  loggedIn: ComputedRef<boolean>;
10
10
  ready: ComputedRef<boolean>;
@@ -14,7 +14,7 @@ export interface UseUserSessionReturn {
14
14
  headers?: HeadersInit;
15
15
  force?: boolean;
16
16
  }) => Promise<void>;
17
- updateUser: (updates: Partial<AuthUser>) => Promise<void>;
17
+ updateUser: (updates: AuthUserUpdateInput) => Promise<void>;
18
18
  }
19
19
  export declare function useUserSession(): UseUserSessionReturn;
20
20
  export declare function useAuthActionNamespaces(): {
@@ -7,6 +7,7 @@ import { createVueSafeAuthFacade, isAuthProxyProbeKey } from "../internal/vue-sa
7
7
  import { wrapAuthMethod } from "../internal/wrap-auth-method.js";
8
8
  import { getAuthRuntimeFlags, useRawAuthClient } from "./useAuthClient.js";
9
9
  let _signOutPromise = null;
10
+ const _sessionSyncApps = /* @__PURE__ */ new WeakSet();
10
11
  function createServerOnlyActionNamespace(path) {
11
12
  return new Proxy({}, {
12
13
  get(_target, prop) {
@@ -96,7 +97,7 @@ export function useUserSession() {
96
97
  hydrationReconcileQueued.value = false;
97
98
  });
98
99
  }
99
- if (runtimeFlags.client && rawClient) {
100
+ if (runtimeFlags.client && rawClient && !_sessionSyncApps.has(nuxtApp)) {
100
101
  const clientSession = rawClient.useSession();
101
102
  const initialClientSession = clientSession.value;
102
103
  const shouldReconcileInitialHydration = nuxtApp.isHydrating && nuxtApp.payload.serverRendered && Boolean(session.value && user.value) && !initialClientSession?.data?.session && !initialClientSession?.data?.user && !initialClientSession?.isPending && !initialClientSession?.isRefetching;
@@ -123,6 +124,7 @@ export function useUserSession() {
123
124
  authReady.value = true;
124
125
  }
125
126
  );
127
+ _sessionSyncApps.add(nuxtApp);
126
128
  }
127
129
  function waitForSession() {
128
130
  return new Promise((resolve) => {
@@ -150,7 +152,9 @@ export function useUserSession() {
150
152
  return;
151
153
  }
152
154
  _signOutPromise = (async () => {
153
- await rawClient.signOut();
155
+ const result = await rawClient.signOut();
156
+ if (isRecord(result) && result.error)
157
+ throw new Error(normalizeAuthActionError(result.error).message);
154
158
  clearSession();
155
159
  if (options?.onSuccess) {
156
160
  await options.onSuccess();
@@ -1,12 +1,13 @@
1
1
  import type { Ref } from 'vue';
2
- import type { AppAuthClient, AuthSession, AuthUser } from '#nuxt-better-auth';
2
+ import type { AppAuthClient, AuthSession, AuthUser, ClientAuthSession } from '#nuxt-better-auth';
3
3
  export declare function stripToken(session: AuthSession & {
4
4
  token?: string;
5
- }): AuthSession;
6
- export declare function fetchSessionServer(session: Ref<AuthSession | null>, user: Ref<AuthUser | null>, authReady: Ref<boolean>, options?: {
5
+ }): ClientAuthSession;
6
+ export declare function fetchSessionServer(session: Ref<ClientAuthSession | null>, user: Ref<AuthUser | null>, authReady: Ref<boolean>, options?: {
7
7
  headers?: HeadersInit;
8
+ force?: boolean;
8
9
  }): Promise<void>;
9
- export declare function fetchSessionClient(client: AppAuthClient, session: Ref<AuthSession | null>, user: Ref<AuthUser | null>, authReady: Ref<boolean>, options?: {
10
+ export declare function fetchSessionClient(client: AppAuthClient, session: Ref<ClientAuthSession | null>, user: Ref<AuthUser | null>, authReady: Ref<boolean>, options?: {
10
11
  headers?: HeadersInit;
11
12
  force?: boolean;
12
13
  }): Promise<void>;
@@ -1,3 +1,4 @@
1
+ import { parseJSON } from "better-auth/client";
1
2
  import { useRequestFetch, useRequestHeaders } from "#imports";
2
3
  import { normalizeAuthActionError } from "./auth-action-error.js";
3
4
  export function stripToken(session) {
@@ -14,7 +15,11 @@ export async function fetchSessionServer(session, user, authReady, options = {})
14
15
  try {
15
16
  const headers = options.headers || useRequestHeaders(["cookie"]);
16
17
  const requestFetch = useRequestFetch();
17
- const data = await requestFetch("/api/auth/get-session", { headers });
18
+ const data = await requestFetch("/api/auth/get-session", {
19
+ headers,
20
+ parseResponse: parseJSON,
21
+ ...options.force ? { query: { disableCookieCache: true } } : {}
22
+ });
18
23
  if (data?.session && data?.user) {
19
24
  session.value = stripToken(data.session);
20
25
  user.value = data.user;
@@ -33,7 +38,7 @@ export async function fetchSessionServer(session, user, authReady, options = {})
33
38
  export async function fetchSessionClient(client, session, user, authReady, options = {}) {
34
39
  try {
35
40
  const headers = options.headers || useRequestHeaders(["cookie"]);
36
- const fetchOptions = headers ? { headers } : void 0;
41
+ const fetchOptions = { ...headers ? { headers } : {}, throw: false };
37
42
  const query = options.force ? { disableCookieCache: true } : void 0;
38
43
  const result = await client.getSession({ query }, fetchOptions);
39
44
  const data = result.data;
@@ -1,3 +1,4 @@
1
+ import { parseJSON } from "better-auth/client";
1
2
  import { defineNuxtPlugin, useRequestEvent, useRequestHeaders, useState } from "#imports";
2
3
  export default defineNuxtPlugin({
3
4
  name: "auth:session-init",
@@ -10,7 +11,7 @@ export default defineNuxtPlugin({
10
11
  if (event) {
11
12
  try {
12
13
  const headers = useRequestHeaders(["cookie"]);
13
- const data = await $fetch("/api/auth/get-session", { headers });
14
+ const data = await $fetch("/api/auth/get-session", { headers, parseResponse: parseJSON });
14
15
  if (data?.session && data?.user) {
15
16
  const { token: _, ...safeSession } = data.session;
16
17
  session.value = safeSession;
@@ -5,6 +5,7 @@ export { useAuthClient } from './app/composables/useAuthClient.js';
5
5
  export { useAuthClientAction } from './app/composables/useAuthClientAction.js';
6
6
  export { useAuthRequestFetch } from './app/composables/useAuthRequestFetch.js';
7
7
  export { useSignIn } from './app/composables/useSignIn.js';
8
+ export { useSignOut } from './app/composables/useSignOut.js';
8
9
  export { useSignUp } from './app/composables/useSignUp.js';
9
10
  export { useUserSession } from './app/composables/useUserSession.js';
10
11
  export type { SignOutOptions, UseUserSessionReturn } from './app/composables/useUserSession.js';
@@ -5,6 +5,7 @@ export { useAuthClient } from "./app/composables/useAuthClient.js";
5
5
  export { useAuthClientAction } from "./app/composables/useAuthClientAction.js";
6
6
  export { useAuthRequestFetch } from "./app/composables/useAuthRequestFetch.js";
7
7
  export { useSignIn } from "./app/composables/useSignIn.js";
8
+ export { useSignOut } from "./app/composables/useSignOut.js";
8
9
  export { useSignUp } from "./app/composables/useSignUp.js";
9
10
  export { useUserSession } from "./app/composables/useUserSession.js";
10
11
  export { useUserSessionState } from "./app/composables/useUserSessionState.js";
@@ -9,7 +9,9 @@ export type SchemaCasing = 'snake_case' | 'camelCase';
9
9
  export interface ClientAuthContext {
10
10
  siteUrl: string;
11
11
  }
12
- export type ServerAuthConfig = Omit<BetterAuthOptions, 'secret' | 'baseURL'> & {
12
+ export type ServerAuthConfig = Omit<BetterAuthOptions, 'secret' | 'baseURL' | 'basePath'> & {
13
+ /** The module registers its server handler at /api/auth. */
14
+ basePath?: '/api/auth';
13
15
  plugins?: readonly BetterAuthPlugin[];
14
16
  };
15
17
  export type ClientAuthConfig = Omit<BetterAuthClientOptions, 'baseURL'> & {
@@ -104,7 +106,7 @@ export interface AuthPrivateRuntimeConfig {
104
106
  hubSecondaryStorage: boolean | 'custom';
105
107
  }
106
108
  export declare function defineServerAuth<const R>(config: (ctx: ServerAuthContext) => R & ServerAuthConfig): (ctx: ServerAuthContext) => R;
107
- export declare function defineServerAuth<const R>(config: R & ServerAuthConfig): (ctx: ServerAuthContext) => R;
109
+ export declare function defineServerAuth<const R>(config: R & ServerAuthConfig & (R extends (...args: never[]) => unknown ? never : unknown)): (ctx: ServerAuthContext) => R;
108
110
  export declare function extendServerAuth<const R extends ServerAuthConfig, const P extends readonly BetterAuthPlugin[]>(createConfig: (ctx: ServerAuthContext) => R, plugins: P): (ctx: ServerAuthContext) => ExtendedServerAuthConfig<R, P>;
109
111
  export declare function defineClientAuth<T extends ClientAuthConfig>(config: T | ((ctx: ClientAuthContext) => T)): ClientAuthFactory<T>;
110
112
  export declare function extendClientAuth<T extends ClientAuthConfig, const P extends BetterAuthClientPlugin[]>(createClient: ClientAuthFactory<T>, plugins: P): ClientAuthFactory<ExtendedClientAuthConfig<T, P>>;
@@ -1,6 +1,11 @@
1
1
  import { createAuthClient } from "better-auth/vue";
2
2
  export function defineServerAuth(config) {
3
- return typeof config === "function" ? config : () => config;
3
+ return (ctx) => {
4
+ const resolved = typeof config === "function" ? config(ctx) : config;
5
+ if (resolved.basePath !== void 0 && resolved.basePath !== "/api/auth")
6
+ throw new Error("[nuxt-better-auth] Server basePath must be /api/auth. Remove basePath from defineServerAuth() or set it to /api/auth. External clientOnly backends may use a custom client basePath.");
7
+ return resolved;
8
+ };
4
9
  }
5
10
  export function extendServerAuth(createConfig, plugins) {
6
11
  return (ctx) => {
@@ -103,13 +103,13 @@ function getNitroOrigin() {
103
103
  return `${protocol}://${host}${portSuffix}`;
104
104
  }
105
105
  function resolveEnvironmentOrigin() {
106
- const nitroOrigin = getNitroOrigin();
106
+ const nitroOrigin = import.meta.dev ? getNitroOrigin() : void 0;
107
107
  if (nitroOrigin)
108
108
  return { origin: validateURL(nitroOrigin), source: "Nitro environment detection" };
109
109
  if (process.env.VERCEL_URL)
110
110
  return { origin: validateURL(`https://${process.env.VERCEL_URL}`), source: "VERCEL_URL" };
111
111
  if (process.env.CF_PAGES_URL)
112
- return { origin: validateURL(`https://${process.env.CF_PAGES_URL}`), source: "CF_PAGES_URL" };
112
+ return { origin: validateURL(process.env.CF_PAGES_URL), source: "CF_PAGES_URL" };
113
113
  if (process.env.URL)
114
114
  return { origin: validateURL(process.env.URL.startsWith("http") ? process.env.URL : `https://${process.env.URL}`), source: "URL" };
115
115
  return void 0;
@@ -124,7 +124,7 @@ function getBaseURL(event) {
124
124
  const configuredSiteUrl = resolveConfiguredSiteUrl(config);
125
125
  if (configuredSiteUrl)
126
126
  return configuredSiteUrl;
127
- const eventOrigin = resolveEventOrigin(event);
127
+ const eventOrigin = import.meta.dev ? resolveEventOrigin(event) : void 0;
128
128
  if (eventOrigin) {
129
129
  logInferredBaseURL(eventOrigin, "request origin");
130
130
  return eventOrigin;
@@ -139,7 +139,7 @@ function getBaseURL(event) {
139
139
  logInferredBaseURL(devFallback.origin, devFallback.source);
140
140
  return devFallback.origin;
141
141
  }
142
- throw new Error("siteUrl required. Set NUXT_PUBLIC_SITE_URL.");
142
+ throw new Error("siteUrl required in production. Set NUXT_PUBLIC_SITE_URL to the public application URL or provide VERCEL_URL, CF_PAGES_URL, or URL.");
143
143
  }
144
144
  function dedupeOrigins(origins) {
145
145
  return [...new Set(origins)];
@@ -8,10 +8,6 @@ declare module '#imports' {
8
8
  export function useRuntimeConfig(): any
9
9
  }
10
10
 
11
- declare module '#auth/secondary-storage' {
12
- export function createSecondaryStorage(...args: any[]): any
13
- }
14
-
15
11
  declare module '#auth/schema' {
16
12
  export const schema: any
17
13
  }
@@ -18,6 +18,7 @@ export interface AuthSession {
18
18
  ipAddress?: string | null;
19
19
  userAgent?: string | null;
20
20
  }
21
+ export type ClientAuthSession = Omit<AuthSession, 'token'>;
21
22
  export interface ServerAuthContext {
22
23
  runtimeConfig: Record<string, unknown>;
23
24
  db: unknown;
@@ -25,9 +26,13 @@ export interface ServerAuthContext {
25
26
  }
26
27
  export interface AuthSocialProviderRegistry {
27
28
  }
29
+ export interface AuthUserUpdateInput {
30
+ name?: string;
31
+ image?: string | null;
32
+ }
28
33
  export interface UserSessionComposable {
29
34
  user: Ref<AuthUser | null>;
30
- session: Ref<AuthSession | null>;
35
+ session: Ref<ClientAuthSession | null>;
31
36
  loggedIn: ComputedRef<boolean>;
32
37
  ready: ComputedRef<boolean>;
33
38
  fetchSession: (options?: {
@@ -38,7 +43,7 @@ export interface UserSessionComposable {
38
43
  signOut: (options?: {
39
44
  onSuccess?: () => void | Promise<void>;
40
45
  }) => Promise<void>;
41
- updateUser: (updates: Partial<AuthUser>) => Promise<void>;
46
+ updateUser: (updates: AuthUserUpdateInput) => Promise<void>;
42
47
  }
43
48
  export type UserMatch<T> = {
44
49
  [K in keyof T]?: T[K] | T[K][];
@@ -1,5 +1,5 @@
1
1
  import type { AuthSocialProviderRegistry, AuthUser, UserMatch } from '#nuxt-better-auth';
2
- export type { AppSession, AuthSession, AuthSocialProviderRegistry, AuthUser, RequireSessionOptions, ServerAuthContext, UserMatch, UserSessionComposable } from './types/augment.js';
2
+ export type { AppSession, AuthSession, AuthSocialProviderRegistry, AuthUser, AuthUserUpdateInput, ClientAuthSession, RequireSessionOptions, ServerAuthContext, UserMatch, UserSessionComposable } from './types/augment.js';
3
3
  export type AuthSocialProviderId = AuthSocialProviderRegistry extends {
4
4
  ids: infer T;
5
5
  } ? Extract<T, string> : never;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nuxtjs/better-auth",
3
3
  "type": "module",
4
- "version": "0.2.4",
4
+ "version": "0.3.0",
5
5
  "description": "Nuxt module for Better Auth integration with NuxtHub, route protection, session management, and role-based access",
6
6
  "author": "onmax",
7
7
  "license": "MIT",
@@ -81,7 +81,7 @@
81
81
  "@types/node": "^24.13.3",
82
82
  "better-auth": "1.7.1",
83
83
  "better-call": "1.4.0",
84
- "better-sqlite3": "^12.6.2",
84
+ "better-sqlite3": "^12.11.1",
85
85
  "drizzle-kit": "^0.31.10",
86
86
  "drizzle-orm": "^0.45.2",
87
87
  "eslint": "^10.8.1",