@onmax/nuxt-better-auth 0.0.2-alpha.29 → 0.0.2-alpha.30

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.
Files changed (30) hide show
  1. package/dist/module.d.mts +1 -1
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +208 -7
  4. package/dist/runtime/app/composables/useAction.d.ts +2 -0
  5. package/dist/runtime/app/composables/useAction.js +6 -0
  6. package/dist/runtime/app/composables/useAuthAsyncData.d.ts +6 -0
  7. package/dist/runtime/app/composables/useAuthAsyncData.js +16 -0
  8. package/dist/runtime/app/composables/useAuthClientAction.d.ts +5 -0
  9. package/dist/runtime/app/composables/useAuthClientAction.js +15 -0
  10. package/dist/runtime/app/composables/useAuthRequestFetch.d.ts +11 -0
  11. package/dist/runtime/app/composables/useAuthRequestFetch.js +4 -0
  12. package/dist/runtime/app/composables/useSignIn.d.ts +16 -0
  13. package/dist/runtime/app/composables/{useUserSignIn.js → useSignIn.js} +2 -2
  14. package/dist/runtime/app/composables/{useUserSignUp.d.ts → useSignUp.d.ts} +1 -1
  15. package/dist/runtime/app/composables/{useUserSignUp.js → useSignUp.js} +2 -2
  16. package/dist/runtime/app/composables/useUserSession.js +84 -10
  17. package/dist/runtime/app/internal/auth-action-error.d.ts +1 -0
  18. package/dist/runtime/app/internal/auth-action-error.js +2 -1
  19. package/dist/runtime/app/internal/auth-action-handles.d.ts +4 -0
  20. package/dist/runtime/app/internal/auth-action-handles.js +31 -1
  21. package/dist/runtime/app/middleware/auth.global.js +34 -9
  22. package/dist/runtime/server/api/_better-auth/config.get.d.ts +9 -9
  23. package/dist/runtime/server/utils/auth.d.ts +3 -1
  24. package/dist/runtime/server/utils/session.d.ts +1 -1
  25. package/dist/runtime/server/utils/session.js +18 -18
  26. package/dist/runtime/types/augment.d.ts +2 -0
  27. package/dist/runtime/types.d.ts +5 -2
  28. package/dist/types.d.mts +1 -1
  29. package/package.json +23 -37
  30. package/dist/runtime/app/composables/useUserSignIn.d.ts +0 -5
package/dist/module.d.mts CHANGED
@@ -3,7 +3,7 @@ import { Nuxt } from '@nuxt/schema';
3
3
  import { BetterAuthModuleOptions } from '../dist/runtime/config.js';
4
4
  export { BetterAuthModuleOptions, defineClientAuth, defineServerAuth } from '../dist/runtime/config.js';
5
5
  import { BetterAuthOptions } from 'better-auth';
6
- export { AppSession, Auth, AuthActionError, AuthMeta, AuthMode, AuthRouteRules, AuthSession, AuthUser, InferSession, InferUser, RequireSessionOptions, ServerAuthContext, UserMatch } from '../dist/runtime/types.js';
6
+ export { AppSession, Auth, AuthActionError, AuthMeta, AuthMode, AuthRouteRules, AuthSession, AuthSocialProviderId, AuthUser, InferSession, InferUser, RequireSessionOptions, ServerAuthContext, UserMatch } from '../dist/runtime/types.js';
7
7
 
8
8
  interface RuntimeDefineServerAuthFn {
9
9
  (...args: unknown[]): unknown;
package/dist/module.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onmax/nuxt-better-auth",
3
- "version": "0.0.2-alpha.29",
3
+ "version": "0.0.2-alpha.30",
4
4
  "configKey": "auth",
5
5
  "compatibility": {
6
6
  "nuxt": ">=4.0.0"
package/dist/module.mjs CHANGED
@@ -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.0.2-alpha.29";
13
+ const version = "0.0.2-alpha.30";
14
14
 
15
15
  function resolveDatabaseProvider(input) {
16
16
  const enabledProviders = Object.entries(input.providers).filter(([_id, provider]) => provider.isEnabled?.(input.context) ?? true);
@@ -88,7 +88,8 @@ async function registerDevtools(input) {
88
88
  }
89
89
  function registerRouteRulesMetaHook(nuxt) {
90
90
  nuxt.hook("pages:extend", (pages) => {
91
- const routeRules = nuxt.options.routeRules || {};
91
+ const options = nuxt.options;
92
+ const routeRules = options.nitro?.routeRules || options.routeRules || {};
92
93
  if (!Object.keys(routeRules).length)
93
94
  return;
94
95
  const matcher = toRouteMatcher(createRouter({ routes: routeRules }));
@@ -162,7 +163,7 @@ function setupRuntimeConfig(input) {
162
163
  const siteUrl = nuxt.options.runtimeConfig.public.siteUrl;
163
164
  if (!siteUrl)
164
165
  consola.warn("clientOnly mode: set runtimeConfig.public.siteUrl (or NUXT_PUBLIC_SITE_URL) to your frontend URL");
165
- consola.info("clientOnly mode enabled - server utilities (serverAuth, getAppSession, getUserSession, requireUserSession) are not available");
166
+ consola.info("clientOnly mode enabled - server utilities (serverAuth, getRequestSession, getUserSession, requireUserSession) are not available");
166
167
  return { useHubKV, secondaryStorageEnabled };
167
168
  }
168
169
  const currentSecret = nuxt.options.runtimeConfig.betterAuthSecret;
@@ -203,7 +204,10 @@ async function generateDrizzleSchema(authOptions, dialect, schemaOptions) {
203
204
  adapterConfig: { usePlural: schemaOptions?.usePlural ?? false }
204
205
  }
205
206
  };
206
- const result = await generateDrizzleSchema$1({ adapter, options });
207
+ const result = await generateDrizzleSchema$1({
208
+ adapter,
209
+ options
210
+ });
207
211
  if (!result.code) {
208
212
  throw new Error(`Schema generation returned empty result for ${dialect}`);
209
213
  }
@@ -254,7 +258,7 @@ async function loadUserAuthConfig(configPath, throwOnError = false) {
254
258
 
255
259
  function resolveSchemaSecondaryStorageInjection(hubSecondaryStorage, userHasSecondaryStorage, isProduction) {
256
260
  if (hubSecondaryStorage === true)
257
- return { inject: true };
261
+ return { inject: false };
258
262
  if (hubSecondaryStorage !== "custom")
259
263
  return { inject: false };
260
264
  if (userHasSecondaryStorage)
@@ -541,11 +545,191 @@ declare module '@onmax/nuxt-better-auth/config' {
541
545
  export function defineServerAuth<const R>(config: (ctx: _AugmentedServerAuthContext) => R & ServerAuthConfig): (ctx: _AugmentedServerAuthContext) => R
542
546
  export function defineServerAuth<const R>(config: R & ServerAuthConfig): (ctx: _AugmentedServerAuthContext) => R
543
547
  }
548
+ `
549
+ }, { nuxt: true, nitro: true, node: true });
550
+ addTypeTemplate({
551
+ filename: "types/nuxt-better-auth-social-providers.d.ts",
552
+ getContents: () => `
553
+ import type createServerAuth from '${serverConfigPath}'
554
+
555
+ type _RawConfig = ReturnType<typeof createServerAuth>
556
+ type _RawSocialProviders = _RawConfig extends { socialProviders: infer S } ? S : _RawConfig extends { socialProviders?: infer S } ? S : {}
557
+ type _SocialProviderIds = Extract<keyof NonNullable<_RawSocialProviders>, string>
558
+
559
+ declare module '#nuxt-better-auth' {
560
+ interface AuthSocialProviderRegistry {
561
+ ids: _SocialProviderIds
562
+ }
563
+ }
544
564
  `
545
565
  }, { nuxt: true, nitro: true, node: true });
546
566
  addTypeTemplate({
547
567
  filename: "types/nuxt-better-auth-nitro.d.ts",
548
568
  getContents: () => `
569
+ import type createServerAuth from '${serverConfigPath}'
570
+ import type { BetterAuthOptions } from 'better-auth'
571
+ import type { getEndpoints } from 'better-auth/api'
572
+ import type { Serialize, Simplify } from 'nitropack/types'
573
+ import type { FetchError } from 'ofetch'
574
+
575
+ type _RawConfig = ReturnType<typeof createServerAuth>
576
+ type _RawPlugins = _RawConfig extends { plugins: infer P } ? P : _RawConfig extends { plugins?: infer P } ? P : []
577
+ type _Config = Omit<BetterAuthOptions, 'plugins'> & Omit<_RawConfig, 'plugins'> & {
578
+ plugins?: _RawPlugins
579
+ }
580
+
581
+ type _AuthApi = ReturnType<typeof getEndpoints<_Config>>['api']
582
+ type _NormalizeMethod<M extends string> = M extends '*' ? 'default' : Lowercase<M>
583
+ type _RouteMethodFromOption<M> = M extends readonly (infer T)[]
584
+ ? _NormalizeMethod<Extract<T, string>>
585
+ : M extends string
586
+ ? _NormalizeMethod<M>
587
+ : 'default'
588
+ type _RouteMethodFromEndpoint<E> = E extends { options: { method: infer M } } ? _RouteMethodFromOption<M> : 'default'
589
+ type _RoutePathFromEndpoint<E> = E extends { path: infer P extends string }
590
+ ? string extends P
591
+ ? never
592
+ : \`/api/auth\${P}\`
593
+ : never
594
+ type _RouteResponseFromEndpoint<E> = E extends (...args: any[]) => Promise<infer R> ? Simplify<Serialize<Awaited<R>>> : never
595
+ type _RouteDefaultResponse<E> = never
596
+ type _UnionToIntersection<U> = (U extends unknown ? (value: U) => void : never) extends (value: infer I) => void ? I : never
597
+
598
+ type _CoreAuthInternalApi = {
599
+ [K in keyof _AuthApi as _RoutePathFromEndpoint<_AuthApi[K]>]: {
600
+ [M in _RouteMethodFromEndpoint<_AuthApi[K]> | 'default']: M extends 'default' ? _RouteDefaultResponse<_AuthApi[K]> : _RouteResponseFromEndpoint<_AuthApi[K]>
601
+ }
602
+ }
603
+ type _PluginEndpointMaps<Plugins> = Plugins extends readonly (infer Plugin)[]
604
+ ? Plugin extends { endpoints: infer Endpoints extends Record<string, unknown> }
605
+ ? {
606
+ [K in keyof Endpoints as _RoutePathFromEndpoint<Endpoints[K]>]: {
607
+ [M in _RouteMethodFromEndpoint<Endpoints[K]> | 'default']: M extends 'default' ? _RouteDefaultResponse<Endpoints[K]> : _RouteResponseFromEndpoint<Endpoints[K]>
608
+ }
609
+ }
610
+ : {}
611
+ : Plugins extends (infer Plugin)[]
612
+ ? Plugin extends { endpoints: infer Endpoints extends Record<string, unknown> }
613
+ ? {
614
+ [K in keyof Endpoints as _RoutePathFromEndpoint<Endpoints[K]>]: {
615
+ [M in _RouteMethodFromEndpoint<Endpoints[K]> | 'default']: M extends 'default' ? _RouteDefaultResponse<Endpoints[K]> : _RouteResponseFromEndpoint<Endpoints[K]>
616
+ }
617
+ }
618
+ : {}
619
+ : {}
620
+ type _PluginAuthInternalApi = _UnionToIntersection<_PluginEndpointMaps<_RawPlugins>>
621
+ type _GeneratedAuthInternalApi = _CoreAuthInternalApi & _PluginAuthInternalApi
622
+
623
+ type _RoutePathToRequestPath<Path extends string> = Path extends \`\${infer Prefix}:\${string}/\${infer Rest}\`
624
+ ? \`\${Prefix}\${string}/\${_RoutePathToRequestPath<Rest>}\`
625
+ : Path extends \`\${infer Prefix}:\${string}\`
626
+ ? \`\${Prefix}\${string}\`
627
+ : Path
628
+ type _AuthApiPatternPath = Extract<keyof _GeneratedAuthInternalApi, string>
629
+ type _AuthApiRequestPath = _RoutePathToRequestPath<_AuthApiPatternPath>
630
+ type _AuthPatternFromRequestPath<Path extends string> = {
631
+ [Pattern in _AuthApiPatternPath]: Path extends _RoutePathToRequestPath<Pattern> ? Pattern : never
632
+ }[_AuthApiPatternPath]
633
+ type _AuthEndpointMethod<Path extends _AuthApiRequestPath> = Extract<keyof _GeneratedAuthInternalApi[_AuthPatternFromRequestPath<Path>], string>
634
+
635
+ type _AuthFetchMethod<Path extends _AuthApiRequestPath> = Extract<Exclude<import('nitropack/types').NitroFetchOptions<Path>['method'], undefined>, string>
636
+ type _AuthFetchDefaultMethod<Path extends _AuthApiRequestPath> = 'get'
637
+ type _AuthFetchResolvedMethod<Path extends _AuthApiRequestPath, Method extends string> = Lowercase<Method> extends _AuthEndpointMethod<Path>
638
+ ? Lowercase<Method>
639
+ : never
640
+ type _AuthFetchResult<Path extends _AuthApiRequestPath, Method extends string> = _GeneratedAuthInternalApi[_AuthPatternFromRequestPath<Path>][_AuthFetchResolvedMethod<Path, Method>]
641
+
642
+ declare module '#nuxt-better-auth' {
643
+ export type AuthApiInternalRoutes = _GeneratedAuthInternalApi
644
+ export type AuthApiEndpointPatternPath = _AuthApiPatternPath
645
+ export type AuthApiEndpointPath = _AuthApiRequestPath
646
+ export type AuthApiEndpointMethod<Path extends AuthApiEndpointPath> = _AuthEndpointMethod<Path>
647
+ export type AuthApiEndpointResponse<
648
+ Path extends AuthApiEndpointPath,
649
+ Method extends AuthApiEndpointMethod<Path> = AuthApiEndpointMethod<Path>,
650
+ > = AuthApiInternalRoutes[_AuthPatternFromRequestPath<Path>][Method]
651
+ }
652
+
653
+ declare module 'nuxt/dist/app/composables/fetch' {
654
+ export function useFetch<
655
+ ErrorT = FetchError,
656
+ Path extends import('#nuxt-better-auth').AuthApiEndpointPath = import('#nuxt-better-auth').AuthApiEndpointPath,
657
+ Method extends _AuthFetchMethod<Path> = _AuthFetchDefaultMethod<Path>,
658
+ _ResT = _AuthFetchResult<Path, Method>,
659
+ DataT = _ResT,
660
+ PickKeys extends import('nuxt/dist/app/composables/asyncData').KeysOf<DataT> = import('nuxt/dist/app/composables/asyncData').KeysOf<DataT>,
661
+ DefaultT = undefined,
662
+ >(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>
663
+ export function useFetch<
664
+ ErrorT = FetchError,
665
+ Path extends import('#nuxt-better-auth').AuthApiEndpointPath = import('#nuxt-better-auth').AuthApiEndpointPath,
666
+ Method extends _AuthFetchMethod<Path> = _AuthFetchDefaultMethod<Path>,
667
+ _ResT = _AuthFetchResult<Path, Method>,
668
+ DataT = _ResT,
669
+ PickKeys extends import('nuxt/dist/app/composables/asyncData').KeysOf<DataT> = import('nuxt/dist/app/composables/asyncData').KeysOf<DataT>,
670
+ DefaultT = DataT,
671
+ >(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>
672
+
673
+ export function useLazyFetch<
674
+ ErrorT = FetchError,
675
+ Path extends import('#nuxt-better-auth').AuthApiEndpointPath = import('#nuxt-better-auth').AuthApiEndpointPath,
676
+ Method extends _AuthFetchMethod<Path> = _AuthFetchDefaultMethod<Path>,
677
+ _ResT = _AuthFetchResult<Path, Method>,
678
+ DataT = _ResT,
679
+ PickKeys extends import('nuxt/dist/app/composables/asyncData').KeysOf<DataT> = import('nuxt/dist/app/composables/asyncData').KeysOf<DataT>,
680
+ DefaultT = undefined,
681
+ >(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>
682
+ export function useLazyFetch<
683
+ ErrorT = FetchError,
684
+ Path extends import('#nuxt-better-auth').AuthApiEndpointPath = import('#nuxt-better-auth').AuthApiEndpointPath,
685
+ Method extends _AuthFetchMethod<Path> = _AuthFetchDefaultMethod<Path>,
686
+ _ResT = _AuthFetchResult<Path, Method>,
687
+ DataT = _ResT,
688
+ PickKeys extends import('nuxt/dist/app/composables/asyncData').KeysOf<DataT> = import('nuxt/dist/app/composables/asyncData').KeysOf<DataT>,
689
+ DefaultT = DataT,
690
+ >(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>
691
+ }
692
+
693
+ declare module 'nuxt/app' {
694
+ export function useFetch<
695
+ ErrorT = FetchError,
696
+ Path extends import('#nuxt-better-auth').AuthApiEndpointPath = import('#nuxt-better-auth').AuthApiEndpointPath,
697
+ Method extends _AuthFetchMethod<Path> = _AuthFetchDefaultMethod<Path>,
698
+ _ResT = _AuthFetchResult<Path, Method>,
699
+ DataT = _ResT,
700
+ PickKeys extends import('nuxt/dist/app/composables/asyncData').KeysOf<DataT> = import('nuxt/dist/app/composables/asyncData').KeysOf<DataT>,
701
+ DefaultT = undefined,
702
+ >(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>
703
+ export function useFetch<
704
+ ErrorT = FetchError,
705
+ Path extends import('#nuxt-better-auth').AuthApiEndpointPath = import('#nuxt-better-auth').AuthApiEndpointPath,
706
+ Method extends _AuthFetchMethod<Path> = _AuthFetchDefaultMethod<Path>,
707
+ _ResT = _AuthFetchResult<Path, Method>,
708
+ DataT = _ResT,
709
+ PickKeys extends import('nuxt/dist/app/composables/asyncData').KeysOf<DataT> = import('nuxt/dist/app/composables/asyncData').KeysOf<DataT>,
710
+ DefaultT = DataT,
711
+ >(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>
712
+
713
+ export function useLazyFetch<
714
+ ErrorT = FetchError,
715
+ Path extends import('#nuxt-better-auth').AuthApiEndpointPath = import('#nuxt-better-auth').AuthApiEndpointPath,
716
+ Method extends _AuthFetchMethod<Path> = _AuthFetchDefaultMethod<Path>,
717
+ _ResT = _AuthFetchResult<Path, Method>,
718
+ DataT = _ResT,
719
+ PickKeys extends import('nuxt/dist/app/composables/asyncData').KeysOf<DataT> = import('nuxt/dist/app/composables/asyncData').KeysOf<DataT>,
720
+ DefaultT = undefined,
721
+ >(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>
722
+ export function useLazyFetch<
723
+ ErrorT = FetchError,
724
+ Path extends import('#nuxt-better-auth').AuthApiEndpointPath = import('#nuxt-better-auth').AuthApiEndpointPath,
725
+ Method extends _AuthFetchMethod<Path> = _AuthFetchDefaultMethod<Path>,
726
+ _ResT = _AuthFetchResult<Path, Method>,
727
+ DataT = _ResT,
728
+ PickKeys extends import('nuxt/dist/app/composables/asyncData').KeysOf<DataT> = import('nuxt/dist/app/composables/asyncData').KeysOf<DataT>,
729
+ DefaultT = DataT,
730
+ >(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>
731
+ }
732
+
549
733
  declare module 'nitropack' {
550
734
  interface NitroRouteRules {
551
735
  auth?: import('${runtimeTypesPath}').AuthMeta
@@ -553,6 +737,7 @@ declare module 'nitropack' {
553
737
  interface NitroRouteConfig {
554
738
  auth?: import('${runtimeTypesPath}').AuthMeta
555
739
  }
740
+ interface InternalApi extends _GeneratedAuthInternalApi {}
556
741
  }
557
742
  declare module 'nitropack/types' {
558
743
  interface NitroRouteRules {
@@ -561,6 +746,7 @@ declare module 'nitropack/types' {
561
746
  interface NitroRouteConfig {
562
747
  auth?: import('${runtimeTypesPath}').AuthMeta
563
748
  }
749
+ interface InternalApi extends _GeneratedAuthInternalApi {}
564
750
  }
565
751
  export {}
566
752
  `
@@ -572,10 +758,10 @@ function registerSharedTypeTemplates(input) {
572
758
  getContents: () => `
573
759
  import type { AppSession } from '${input.runtimeTypesAugmentPath}'
574
760
  export * from '${input.runtimeTypesAugmentPath}'
575
- export type { AuthMeta, AuthMode, AuthRouteRules, Auth, InferUser, InferSession } from '${input.runtimeTypesPath}'
761
+ export type { AuthMeta, AuthMode, AuthRouteRules, AuthSocialProviderId, Auth, InferUser, InferSession } from '${input.runtimeTypesPath}'
576
762
  declare module 'h3' {
577
763
  interface H3EventContext {
578
- appSession?: AppSession | null
764
+ requestSession?: AppSession | null
579
765
  }
580
766
  }
581
767
  `
@@ -766,6 +952,21 @@ export { schema }
766
952
  runtimeTypesPath: resolver.resolve("./runtime/types"),
767
953
  clientConfigPath
768
954
  });
955
+ const runtimeRouteRulesSource = nuxt.options.nitro?.routeRules || nuxt.options.routeRules || {};
956
+ const authRouteRules = Object.fromEntries(
957
+ Object.entries(runtimeRouteRulesSource).flatMap(([path, rule]) => {
958
+ if (!rule || typeof rule !== "object" || !("auth" in rule))
959
+ return [];
960
+ return [[path, { auth: rule.auth }]];
961
+ })
962
+ );
963
+ const authRouteRulesTemplate = addTemplate({
964
+ filename: "better-auth/route-rules.mjs",
965
+ getContents: () => `export const authRouteRules = ${JSON.stringify(authRouteRules, null, 2)}
966
+ `,
967
+ write: true
968
+ });
969
+ nuxt.options.alias["#auth/route-rules"] = authRouteRulesTemplate.dst;
769
970
  registerTemplateHmrHook(nuxt);
770
971
  registerServerRuntime({ clientOnly, resolve: resolver.resolve });
771
972
  registerAuthMiddlewareHook(nuxt, resolver.resolve);
@@ -0,0 +1,2 @@
1
+ import type { UserAuthActionHandle } from '../internal/auth-action-handles.js';
2
+ export declare function useAction<TArgs extends unknown[], TResult>(runner: (...args: TArgs) => Promise<TResult>): UserAuthActionHandle<TArgs, TResult>;
@@ -0,0 +1,6 @@
1
+ import { createActionHandle } from "../internal/auth-action-handles.js";
2
+ export function useAction(runner) {
3
+ if (typeof runner !== "function")
4
+ throw new TypeError("useAction(runner) requires an async function");
5
+ return createActionHandle(() => runner);
6
+ }
@@ -0,0 +1,6 @@
1
+ import type { AsyncDataOptions } from '#app';
2
+ import { useAuthRequestFetch } from './useAuthRequestFetch.js';
3
+ export interface UseAuthAsyncDataOptions<T> extends Omit<AsyncDataOptions<T | null>, 'default'> {
4
+ requireAuth?: boolean;
5
+ }
6
+ export declare function useAuthAsyncData<T>(key: string, fetcher: (requestFetch: ReturnType<typeof useAuthRequestFetch>) => Promise<T>, options?: UseAuthAsyncDataOptions<T>): any;
@@ -0,0 +1,16 @@
1
+ import { useAsyncData } from "#imports";
2
+ import { useAuthRequestFetch } from "./useAuthRequestFetch.js";
3
+ import { useUserSession } from "./useUserSession.js";
4
+ export function useAuthAsyncData(key, fetcher, options = {}) {
5
+ const requestFetch = useAuthRequestFetch();
6
+ const { loggedIn } = useUserSession();
7
+ const { requireAuth = true, ...asyncDataOptions } = options;
8
+ return useAsyncData(key, async () => {
9
+ if (requireAuth && !loggedIn.value)
10
+ return null;
11
+ return await fetcher(requestFetch);
12
+ }, {
13
+ default: () => null,
14
+ ...asyncDataOptions
15
+ });
16
+ }
@@ -0,0 +1,5 @@
1
+ import type { UserAuthActionHandle } from '../internal/auth-action-handles.js';
2
+ import type { UseUserSessionReturn } from './useUserSession.js';
3
+ type AppAuthClient = NonNullable<UseUserSessionReturn['client']>;
4
+ export declare function useAuthClientAction<TArgs extends unknown[], TResult>(select: (client: AppAuthClient) => (...args: TArgs) => Promise<TResult>): UserAuthActionHandle<TArgs, TResult>;
5
+ export {};
@@ -0,0 +1,15 @@
1
+ import { useUserSession } from "#imports";
2
+ import { useAction } from "./useAction.js";
3
+ export function useAuthClientAction(select) {
4
+ if (typeof select !== "function")
5
+ throw new TypeError("useAuthClientAction(select) requires a selector function");
6
+ return useAction(async (...args) => {
7
+ const { client } = useUserSession();
8
+ if (!client)
9
+ throw new Error("Auth client is unavailable. This action can only run on client-side.");
10
+ const method = select(client);
11
+ if (typeof method !== "function")
12
+ throw new TypeError("useAuthClientAction(select) must resolve to a function");
13
+ return method(...args);
14
+ });
15
+ }
@@ -0,0 +1,11 @@
1
+ import type { AuthApiEndpointMethod, AuthApiEndpointPath, AuthApiEndpointResponse } from '#nuxt-better-auth';
2
+ import type { NitroFetchOptions } from 'nitropack/types';
3
+ import { useRequestFetch } from '#imports';
4
+ type AuthRequestFetchExtractedMethod<Options> = Options extends undefined ? 'get' : Lowercase<Extract<Exclude<Options extends {
5
+ method?: infer Method;
6
+ } ? Method : never, undefined>, string>> extends infer NormalizedMethod extends string ? NormalizedMethod : 'get';
7
+ type AuthRequestFetchMethodFromOptions<Path extends AuthApiEndpointPath, Options> = NitroFetchOptions<Path> extends Options ? 'get' : AuthRequestFetchExtractedMethod<Options>;
8
+ type AuthRequestFetchResolvedMethod<Path extends AuthApiEndpointPath, Options> = Extract<AuthRequestFetchMethodFromOptions<Path, Options>, AuthApiEndpointMethod<Path>> extends infer Method extends string ? Method : never;
9
+ type AuthRequestFetch = <Path extends AuthApiEndpointPath, Options extends NitroFetchOptions<Path> = NitroFetchOptions<Path>>(request: Path, opts?: Options) => Promise<AuthApiEndpointResponse<Path, Extract<AuthRequestFetchResolvedMethod<Path, Options>, AuthApiEndpointMethod<Path>>>>;
10
+ export declare function useAuthRequestFetch(): AuthRequestFetch & ReturnType<typeof useRequestFetch>;
11
+ export {};
@@ -0,0 +1,4 @@
1
+ import { useRequestFetch } from "#imports";
2
+ export function useAuthRequestFetch() {
3
+ return useRequestFetch();
4
+ }
@@ -0,0 +1,16 @@
1
+ import type { AppAuthClient, AuthSocialProviderRegistry } from '#nuxt-better-auth';
2
+ import type { ActionHandleFor } from '../internal/auth-action-handles.js';
3
+ type SignIn = NonNullable<AppAuthClient>['signIn'];
4
+ type AuthSocialProviderId = AuthSocialProviderRegistry extends {
5
+ ids: infer T;
6
+ } ? Extract<T, string> : never;
7
+ type TypedSocialMethod<Method> = Method extends (data: infer Data, ...rest: infer Rest) => Promise<infer Result> ? (data: Omit<Extract<Data, Record<string, unknown>>, 'provider'> & {
8
+ provider: AuthSocialProviderId;
9
+ }, ...rest: Rest) => Promise<Result> : Method;
10
+ type SignInWithTypedSocial = Omit<SignIn, 'social'> & (SignIn extends {
11
+ social: infer SocialMethod;
12
+ } ? {
13
+ social: TypedSocialMethod<SocialMethod>;
14
+ } : unknown);
15
+ export declare function useSignIn<MethodKey extends keyof SignInWithTypedSocial>(method: MethodKey): ActionHandleFor<SignInWithTypedSocial[MethodKey]>;
16
+ export {};
@@ -1,8 +1,8 @@
1
1
  import { useUserSession } from "#imports";
2
2
  import { createActionHandles } from "../internal/auth-action-handles.js";
3
- export function useUserSignIn(method) {
3
+ export function useSignIn(method) {
4
4
  if (method === void 0 || method === null)
5
- throw new TypeError("useUserSignIn(method) requires a sign-in method key");
5
+ throw new TypeError("useSignIn(method) requires a sign-in method key");
6
6
  const handles = createActionHandles(() => useUserSession().signIn, "signIn");
7
7
  return handles[method];
8
8
  }
@@ -1,5 +1,5 @@
1
1
  import type { AppAuthClient } from '#nuxt-better-auth';
2
2
  import type { ActionHandleFor } from '../internal/auth-action-handles.js';
3
3
  type SignUp = NonNullable<AppAuthClient>['signUp'];
4
- export declare function useUserSignUp<MethodKey extends keyof SignUp>(method: MethodKey): ActionHandleFor<SignUp[MethodKey]>;
4
+ export declare function useSignUp<MethodKey extends keyof SignUp>(method: MethodKey): ActionHandleFor<SignUp[MethodKey]>;
5
5
  export {};
@@ -1,8 +1,8 @@
1
1
  import { useUserSession } from "#imports";
2
2
  import { createActionHandles } from "../internal/auth-action-handles.js";
3
- export function useUserSignUp(method) {
3
+ export function useSignUp(method) {
4
4
  if (method === void 0 || method === null)
5
- throw new TypeError("useUserSignUp(method) requires a sign-up method key");
5
+ throw new TypeError("useSignUp(method) requires a sign-up method key");
6
6
  const handles = createActionHandles(() => useUserSession().signUp, "signUp");
7
7
  return handles[method];
8
8
  }
@@ -1,5 +1,5 @@
1
1
  import createAppAuthClient from "#auth/client";
2
- import { computed, navigateTo, nextTick, useNuxtApp, useRequestHeaders, useRequestURL, useRuntimeConfig, useState, watch } from "#imports";
2
+ import { computed, navigateTo, nextTick, useNuxtApp, useRequestFetch, useRequestHeaders, useRequestURL, useRuntimeConfig, useState, watch } from "#imports";
3
3
  import { normalizeAuthActionError } from "../internal/auth-action-error.js";
4
4
  let _sessionSignalListenerBound = false;
5
5
  let _client = null;
@@ -39,13 +39,23 @@ export function useUserSession() {
39
39
  const runtimeFlags = getRuntimeFlags();
40
40
  const runtimeConfig = useRuntimeConfig();
41
41
  const requestURL = useRequestURL();
42
+ const nuxtApp = useNuxtApp();
42
43
  const client = runtimeFlags.client ? getClient(runtimeConfig.public.siteUrl || requestURL.origin) : null;
43
44
  const session = useState("auth:session", () => null);
44
45
  const user = useState("auth:user", () => null);
45
46
  const authReady = useState("auth:ready", () => false);
47
+ const prerenderReadyResetQueued = useState("auth:prerender-ready-reset-queued", () => false);
48
+ const hydrationReconcileQueued = useState("auth:hydration-reconcile-queued", () => false);
46
49
  const ready = computed(() => authReady.value);
47
50
  const loggedIn = computed(() => Boolean(session.value && user.value));
48
- const nuxtApp = useNuxtApp();
51
+ const isPrerenderedPayload = computed(() => Boolean(nuxtApp.payload.prerenderedAt || nuxtApp.payload.isCached));
52
+ const isPrerenderHydrationEmptySnapshot = computed(() => {
53
+ if (!runtimeFlags.client)
54
+ return false;
55
+ if (!nuxtApp.isHydrating || !nuxtApp.payload.serverRendered || !isPrerenderedPayload.value)
56
+ return false;
57
+ return !session.value && !user.value;
58
+ });
49
59
  const skipHydratedSsrGetSession = computed(() => {
50
60
  const authConfig = runtimeConfig.public.auth;
51
61
  return Boolean(authConfig?.session?.skipHydratedSsrGetSession);
@@ -57,10 +67,21 @@ export function useUserSession() {
57
67
  return false;
58
68
  if (!nuxtApp.payload.serverRendered)
59
69
  return false;
60
- if (nuxtApp.payload.prerenderedAt || nuxtApp.payload.isCached)
70
+ if (isPrerenderedPayload.value)
61
71
  return false;
62
72
  return Boolean(session.value && user.value);
63
73
  });
74
+ if (isPrerenderHydrationEmptySnapshot.value && authReady.value && !prerenderReadyResetQueued.value) {
75
+ prerenderReadyResetQueued.value = true;
76
+ nuxtApp.hook("app:suspense:resolve", () => {
77
+ try {
78
+ if (!session.value && !user.value && authReady.value)
79
+ authReady.value = false;
80
+ } finally {
81
+ prerenderReadyResetQueued.value = false;
82
+ }
83
+ });
84
+ }
64
85
  if (shouldSkipInitialClientSessionFetch.value && !authReady.value)
65
86
  authReady.value = true;
66
87
  function clearSession() {
@@ -97,14 +118,28 @@ export function useUserSession() {
97
118
  watch(
98
119
  () => clientSession.value,
99
120
  (newSession) => {
121
+ const shouldWaitForPrerenderResolution = isPrerenderHydrationEmptySnapshot.value && !newSession?.data?.session && !newSession?.data?.user;
122
+ if (shouldWaitForPrerenderResolution)
123
+ return;
100
124
  if (newSession?.data?.session && newSession?.data?.user) {
101
125
  const { token: _, ...safeSession } = newSession.data.session;
102
126
  session.value = safeSession;
103
127
  user.value = newSession.data.user;
104
- } else if (!newSession?.isPending) {
128
+ } else if (!newSession?.isPending && !newSession?.isRefetching) {
129
+ const isHydrationEmptySnapshot = nuxtApp.isHydrating && nuxtApp.payload.serverRendered && Boolean(session.value && user.value) && !newSession?.data?.session && !newSession?.data?.user;
130
+ if (isHydrationEmptySnapshot) {
131
+ if (!hydrationReconcileQueued.value) {
132
+ hydrationReconcileQueued.value = true;
133
+ nuxtApp.hook("app:mounted", async () => {
134
+ await fetchSession({ force: true });
135
+ hydrationReconcileQueued.value = false;
136
+ });
137
+ }
138
+ return;
139
+ }
105
140
  clearSession();
106
141
  }
107
- if (!authReady.value && !newSession?.isPending)
142
+ if (!authReady.value && !newSession?.isPending && !newSession?.isRefetching)
108
143
  authReady.value = true;
109
144
  },
110
145
  { immediate: true, deep: true }
@@ -152,6 +187,19 @@ export function useUserSession() {
152
187
  await navigateTo(target);
153
188
  };
154
189
  }
190
+ function withFallbackSocialCallbackURL(data) {
191
+ const callbackURL = resolvePostAuthRedirect();
192
+ if (!callbackURL)
193
+ return data;
194
+ if (!isRecord(data))
195
+ return { callbackURL };
196
+ if (typeof data.callbackURL === "string")
197
+ return data;
198
+ return {
199
+ ...data,
200
+ callbackURL
201
+ };
202
+ }
155
203
  function wrapOnSuccess(cb) {
156
204
  return async (ctx) => {
157
205
  await fetchSession({ force: true });
@@ -161,12 +209,15 @@ export function useUserSession() {
161
209
  await cb(ctx);
162
210
  };
163
211
  }
164
- function wrapAuthMethod(method) {
212
+ function wrapAuthMethod(method, wrapOptions = {}) {
165
213
  return (async (...args) => {
166
- const data = args[0];
214
+ const originalData = args[0];
167
215
  const options = args[1];
216
+ const data = wrapOptions.transformData?.(originalData, options) ?? originalData;
168
217
  const dataRecord = isRecord(data) ? data : void 0;
169
218
  const optionsRecord = isRecord(options) ? options : void 0;
219
+ if (wrapOptions.shouldSkipSessionSync?.(data, options))
220
+ return method(data, options);
170
221
  const fetchOptions = isRecord(dataRecord?.fetchOptions) ? dataRecord.fetchOptions : void 0;
171
222
  const nestedOnSuccess = fetchOptions?.onSuccess;
172
223
  const topLevelOnSuccess = optionsRecord?.onSuccess;
@@ -219,7 +270,15 @@ export function useUserSession() {
219
270
  const method = targetRecord[prop];
220
271
  if (typeof method !== "function")
221
272
  return method;
222
- return wrapAuthMethod((...args) => targetRecord[prop](...args));
273
+ const shouldSkipSessionSync = prop === "social" ? (data) => {
274
+ const socialData = isRecord(data) ? data : void 0;
275
+ return socialData?.disableRedirect !== true;
276
+ } : void 0;
277
+ const transformData = prop === "social" ? withFallbackSocialCallbackURL : void 0;
278
+ return wrapAuthMethod(
279
+ (...args) => targetRecord[prop](...args),
280
+ { shouldSkipSessionSync, transformData }
281
+ );
223
282
  }
224
283
  }) : new Proxy({}, {
225
284
  get: (_, prop) => {
@@ -241,8 +300,23 @@ export function useUserSession() {
241
300
  });
242
301
  async function fetchSession(options = {}) {
243
302
  if (runtimeFlags.server) {
244
- if (!authReady.value)
245
- authReady.value = true;
303
+ try {
304
+ const headers = options.headers || useRequestHeaders(["cookie"]);
305
+ const requestFetch = useRequestFetch();
306
+ const data = await requestFetch("/api/auth/get-session", { headers });
307
+ if (data?.session && data?.user) {
308
+ const { token: _, ...safeSession } = data.session;
309
+ session.value = safeSession;
310
+ user.value = data.user;
311
+ } else {
312
+ clearSession();
313
+ }
314
+ } catch {
315
+ clearSession();
316
+ } finally {
317
+ if (!authReady.value)
318
+ authReady.value = true;
319
+ }
246
320
  return;
247
321
  }
248
322
  if (client) {
@@ -1,2 +1,3 @@
1
1
  import type { AuthActionError } from '../../types.js';
2
+ export declare const DEFAULT_AUTH_ACTION_ERROR_MESSAGE = "Request failed. Please try again.";
2
3
  export declare function normalizeAuthActionError(error: unknown): AuthActionError;
@@ -1,3 +1,4 @@
1
+ export const DEFAULT_AUTH_ACTION_ERROR_MESSAGE = "Request failed. Please try again.";
1
2
  function isRecord(value) {
2
3
  return Boolean(value && typeof value === "object");
3
4
  }
@@ -8,7 +9,7 @@ function getMessage(value) {
8
9
  return value;
9
10
  if (isRecord(value) && typeof value.message === "string")
10
11
  return value.message;
11
- return "Request failed. Please try again.";
12
+ return DEFAULT_AUTH_ACTION_ERROR_MESSAGE;
12
13
  }
13
14
  function getCode(value) {
14
15
  if (!isRecord(value))
@@ -7,8 +7,12 @@ export interface UserAuthActionHandle<TArgs extends unknown[], TResult> {
7
7
  data: Ref<TResult | null>;
8
8
  error: Ref<AuthActionError | null>;
9
9
  }
10
+ export interface CreateActionHandleOptions {
11
+ keepPendingOnRedirect?: boolean;
12
+ }
10
13
  export type ActionHandleFor<T> = T extends (...args: infer A) => Promise<infer R> ? UserAuthActionHandle<A, R> : never;
11
14
  export type ActionHandleMap<T> = {
12
15
  [K in keyof T]: ActionHandleFor<T[K]>;
13
16
  };
17
+ export declare function createActionHandle<TArgs extends unknown[], TResult>(getMethod: () => (...args: TArgs) => Promise<TResult>, options?: CreateActionHandleOptions): UserAuthActionHandle<TArgs, TResult>;
14
18
  export declare function createActionHandles<T extends object>(getTarget: () => T, targetName: string): ActionHandleMap<T>;
@@ -10,7 +10,23 @@ function isErrorResult(value) {
10
10
  return false;
11
11
  return Boolean(value.error);
12
12
  }
13
- function createActionHandle(getMethod) {
13
+ function isRedirectResult(value) {
14
+ if (!isRecord(value))
15
+ return false;
16
+ return value.redirect === true && typeof value.url === "string" && value.url.length > 0;
17
+ }
18
+ function getRedirectResult(value) {
19
+ if (isRedirectResult(value))
20
+ return value;
21
+ if (!isRecord(value))
22
+ return null;
23
+ const nested = value.data;
24
+ if (isRedirectResult(nested))
25
+ return nested;
26
+ return null;
27
+ }
28
+ const REDIRECT_PENDING_FALLBACK_MS = 1e4;
29
+ export function createActionHandle(getMethod, options = {}) {
14
30
  const status = ref("idle");
15
31
  const data = ref(null);
16
32
  const error = ref(null);
@@ -32,6 +48,20 @@ function createActionHandle(getMethod) {
32
48
  return;
33
49
  }
34
50
  if (callId === latestCallId) {
51
+ if (options.keepPendingOnRedirect !== false) {
52
+ const redirectResult = getRedirectResult(result);
53
+ if (redirectResult) {
54
+ status.value = "pending";
55
+ data.value = result;
56
+ error.value = null;
57
+ setTimeout(() => {
58
+ if (callId !== latestCallId || status.value !== "pending")
59
+ return;
60
+ status.value = "success";
61
+ }, REDIRECT_PENDING_FALLBACK_MS);
62
+ return;
63
+ }
64
+ }
35
65
  status.value = "success";
36
66
  data.value = result;
37
67
  error.value = null;
@@ -1,16 +1,24 @@
1
1
  import { createError, defineNuxtRouteMiddleware, getRouteRules, navigateTo, useNuxtApp, useRequestHeaders, useRuntimeConfig, useUserSession } from "#imports";
2
+ import { defu } from "defu";
3
+ import { createRouter, toRouteMatcher } from "radix3";
2
4
  import { matchesUser } from "../../utils/match-user.js";
5
+ let authRouteRulesPromise = null;
6
+ let routeRulesMatcherPromise = null;
3
7
  export default defineNuxtRouteMiddleware(async (to) => {
4
8
  const nuxtApp = useNuxtApp();
5
- if (import.meta.client) {
6
- const isPrerendered = nuxtApp.payload.prerenderedAt || nuxtApp.payload.isCached;
7
- if (isPrerendered && nuxtApp.isHydrating)
8
- return;
9
- }
10
9
  if (to.meta.auth === void 0) {
11
- const rules = await getRouteRules({ path: to.path });
12
- if (rules.auth !== void 0)
13
- to.meta.auth = rules.auth;
10
+ const routeRulesMatcher = await getRouteRulesMatcher();
11
+ const matches = routeRulesMatcher?.matchAll(to.path);
12
+ if (matches?.length) {
13
+ const merged = defu({}, ...matches.reverse());
14
+ if (merged.auth !== void 0)
15
+ to.meta.auth = merged.auth;
16
+ }
17
+ if (to.meta.auth === void 0) {
18
+ const rules = await getRouteRules({ path: to.path });
19
+ if (rules.auth !== void 0)
20
+ to.meta.auth = rules.auth;
21
+ }
14
22
  }
15
23
  const auth = to.meta.auth;
16
24
  if (auth === void 0 || auth === false)
@@ -19,7 +27,8 @@ export default defineNuxtRouteMiddleware(async (to) => {
19
27
  const { fetchSession, user, loggedIn } = useUserSession();
20
28
  if (!loggedIn.value) {
21
29
  const headers = import.meta.server ? useRequestHeaders(["cookie"]) : void 0;
22
- await fetchSession({ headers });
30
+ const isHydratedPrerenderPayload = (import.meta.client || !import.meta.server) && nuxtApp.isHydrating && Boolean(nuxtApp.payload.prerenderedAt || nuxtApp.payload.isCached);
31
+ await fetchSession({ headers, ...isHydratedPrerenderPayload ? { force: true } : {} });
23
32
  }
24
33
  const mode = typeof auth === "string" ? auth : auth?.only ?? "user";
25
34
  const redirectTo = typeof auth === "object" ? auth.redirectTo : void 0;
@@ -71,3 +80,19 @@ function resolveLoginRedirect(input) {
71
80
  queryObj[redirectQueryKey] = route.fullPath;
72
81
  return { to: { path, query: queryObj, ...hash ? { hash: `#${hash}` } : {} }, external: false };
73
82
  }
83
+ async function getAuthRouteRules() {
84
+ if (!authRouteRulesPromise) {
85
+ authRouteRulesPromise = import("#auth/route-rules").then((mod) => mod.authRouteRules || {}).catch(() => ({}));
86
+ }
87
+ return await authRouteRulesPromise;
88
+ }
89
+ async function getRouteRulesMatcher() {
90
+ if (!routeRulesMatcherPromise) {
91
+ routeRulesMatcherPromise = getAuthRouteRules().then((authRouteRules) => {
92
+ if (!Object.keys(authRouteRules).length)
93
+ return null;
94
+ return toRouteMatcher(createRouter({ routes: authRouteRules }));
95
+ });
96
+ }
97
+ return await routeRulesMatcherPromise;
98
+ }
@@ -14,22 +14,22 @@ declare const _default: import("h3").EventHandler<import("h3").EventHandlerReque
14
14
  databaseProvider: "none" | "nuxthub";
15
15
  };
16
16
  server: {
17
- baseURL: string | undefined;
18
- basePath: string;
17
+ baseURL: any;
18
+ basePath: any;
19
19
  socialProviders: string[];
20
- plugins: string[];
21
- trustedOrigins: string[];
22
- configuredTrustedOrigins: string[];
20
+ plugins: any;
21
+ trustedOrigins: any;
22
+ configuredTrustedOrigins: any;
23
23
  session: {
24
24
  expiresIn: string;
25
25
  updateAge: string;
26
- cookieCache: boolean;
26
+ cookieCache: any;
27
27
  };
28
28
  emailAndPassword: boolean;
29
- rateLimit: boolean;
29
+ rateLimit: any;
30
30
  advanced: {
31
- useSecureCookies: string | boolean;
32
- disableCSRFCheck: boolean;
31
+ useSecureCookies: any;
32
+ disableCSRFCheck: any;
33
33
  };
34
34
  };
35
35
  };
@@ -1,6 +1,8 @@
1
1
  import type { H3Event } from 'h3';
2
+ import createServerAuth from '#auth/server';
2
3
  import { betterAuth } from 'better-auth';
3
- type AuthInstance = ReturnType<typeof betterAuth>;
4
+ type AuthOptions = ReturnType<typeof createServerAuth>;
5
+ type AuthInstance = ReturnType<typeof betterAuth<AuthOptions>>;
4
6
  /** Returns Better Auth instance. Caches per resolved host (or single instance when siteUrl is explicit). */
5
7
  export declare function serverAuth(event?: H3Event): AuthInstance;
6
8
  export {};
@@ -1,5 +1,5 @@
1
1
  import type { AppSession, RequireSessionOptions } from '#nuxt-better-auth';
2
2
  import type { H3Event } from 'h3';
3
- export declare function getAppSession(event: H3Event): Promise<AppSession | null>;
3
+ export declare function getRequestSession(event: H3Event): Promise<AppSession | null>;
4
4
  export declare function getUserSession(event: H3Event): Promise<AppSession | null>;
5
5
  export declare function requireUserSession(event: H3Event, options?: RequireSessionOptions): Promise<AppSession>;
@@ -1,16 +1,16 @@
1
1
  import { createError } from "h3";
2
2
  import { matchesUser } from "../../utils/match-user.js";
3
3
  import { serverAuth } from "./auth.js";
4
- const appSessionLoadKey = Symbol.for("nuxt-better-auth.appSessionLoad");
5
- const fallbackAppSessionContext = /* @__PURE__ */ new WeakMap();
6
- function getAppSessionContext(event) {
4
+ const requestSessionLoadKey = Symbol.for("nuxt-better-auth.requestSessionLoad");
5
+ const fallbackRequestSessionContext = /* @__PURE__ */ new WeakMap();
6
+ function getRequestSessionContext(event) {
7
7
  const eventWithContext = event;
8
8
  if (eventWithContext.context && typeof eventWithContext.context === "object")
9
9
  return eventWithContext.context;
10
- let context = fallbackAppSessionContext.get(event);
10
+ let context = fallbackRequestSessionContext.get(event);
11
11
  if (!context) {
12
12
  context = {};
13
- fallbackAppSessionContext.set(event, context);
13
+ fallbackRequestSessionContext.set(event, context);
14
14
  }
15
15
  return context;
16
16
  }
@@ -18,34 +18,34 @@ function loadSession(event) {
18
18
  const auth = serverAuth(event);
19
19
  return auth.api.getSession({ headers: event.headers });
20
20
  }
21
- export async function getAppSession(event) {
22
- const context = getAppSessionContext(event);
23
- if (context.appSession !== void 0)
24
- return context.appSession;
25
- const inFlight = context[appSessionLoadKey];
21
+ export async function getRequestSession(event) {
22
+ const context = getRequestSessionContext(event);
23
+ if (context.requestSession !== void 0)
24
+ return context.requestSession;
25
+ const inFlight = context[requestSessionLoadKey];
26
26
  if (inFlight)
27
27
  return inFlight;
28
28
  const load = loadSession(event);
29
- context[appSessionLoadKey] = load;
29
+ context[requestSessionLoadKey] = load;
30
30
  try {
31
31
  const session = await load;
32
- context.appSession = session;
32
+ context.requestSession = session;
33
33
  return session;
34
34
  } finally {
35
- delete context[appSessionLoadKey];
35
+ delete context[requestSessionLoadKey];
36
36
  }
37
37
  }
38
38
  export async function getUserSession(event) {
39
- const context = getAppSessionContext(event);
40
- if (context.appSession !== void 0)
41
- return context.appSession;
42
- const inFlight = context[appSessionLoadKey];
39
+ const context = getRequestSessionContext(event);
40
+ if (context.requestSession !== void 0)
41
+ return context.requestSession;
42
+ const inFlight = context[requestSessionLoadKey];
43
43
  if (inFlight)
44
44
  return inFlight;
45
45
  return loadSession(event);
46
46
  }
47
47
  export async function requireUserSession(event, options) {
48
- const session = await getAppSession(event);
48
+ const session = await getRequestSession(event);
49
49
  if (!session)
50
50
  throw createError({ statusCode: 401, statusMessage: "Authentication required" });
51
51
  if (options?.user) {
@@ -22,6 +22,8 @@ export interface ServerAuthContext {
22
22
  runtimeConfig: Record<string, unknown>;
23
23
  db: unknown;
24
24
  }
25
+ export interface AuthSocialProviderRegistry {
26
+ }
25
27
  export interface UserSessionComposable {
26
28
  client: unknown;
27
29
  user: Ref<AuthUser | null>;
@@ -1,6 +1,9 @@
1
- import type { AuthUser, UserMatch } from '#nuxt-better-auth';
1
+ import type { AuthSocialProviderRegistry, AuthUser, UserMatch } from '#nuxt-better-auth';
2
2
  import type { NitroRouteRules } from 'nitropack/types';
3
- export type { AppSession, AuthSession, AuthUser, RequireSessionOptions, ServerAuthContext, UserMatch, UserSessionComposable } from './types/augment.js';
3
+ export type { AppSession, AuthSession, AuthSocialProviderRegistry, AuthUser, RequireSessionOptions, ServerAuthContext, UserMatch, UserSessionComposable } from './types/augment.js';
4
+ export type AuthSocialProviderId = AuthSocialProviderRegistry extends {
5
+ ids: infer T;
6
+ } ? Extract<T, string> : never;
4
7
  export type { Auth, InferPluginTypes, InferSessionFromClient as InferSession, InferUserFromClient as InferUser } from 'better-auth';
5
8
  export interface AuthActionError {
6
9
  message: string;
package/dist/types.d.mts CHANGED
@@ -6,6 +6,6 @@ export type ModuleOptions = typeof Module extends NuxtModule<infer O> ? Partial<
6
6
 
7
7
  export { type BetterAuthModuleOptions, type defineClientAuth, type defineServerAuth } from '../dist/runtime/config.js'
8
8
 
9
- export { type AppSession, type Auth, type AuthActionError, type AuthMeta, type AuthMode, type AuthRouteRules, type AuthSession, type AuthUser, type InferSession, type InferUser, type RequireSessionOptions, type ServerAuthContext, type UserMatch } from '../dist/runtime/types.js'
9
+ export { type AppSession, type Auth, type AuthActionError, type AuthMeta, type AuthMode, type AuthRouteRules, type AuthSession, type AuthSocialProviderId, type AuthUser, type InferSession, type InferUser, type RequireSessionOptions, type ServerAuthContext, type UserMatch } from '../dist/runtime/types.js'
10
10
 
11
11
  export { default } from './module.mjs'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@onmax/nuxt-better-auth",
3
3
  "type": "module",
4
- "version": "0.0.2-alpha.29",
4
+ "version": "0.0.2-alpha.30",
5
5
  "packageManager": "pnpm@10.15.1",
6
6
  "description": "Nuxt module for Better Auth integration with NuxtHub, route protection, session management, and role-based access",
7
7
  "author": "onmax",
@@ -70,56 +70,42 @@
70
70
  }
71
71
  },
72
72
  "dependencies": {
73
- "@better-auth/cli": "^1.5.0-beta.3",
74
- "@nuxt/kit": "^4.2.2",
75
- "@nuxt/ui": "^4.2.1",
73
+ "@better-auth/cli": "1.5.0-beta.13",
74
+ "@nuxt/kit": "^4.3.1",
75
+ "@nuxt/ui": "^4.5.0",
76
76
  "defu": "^6.1.4",
77
- "jiti": "^2.4.2",
77
+ "jiti": "^2.6.1",
78
78
  "pathe": "^2.0.3",
79
79
  "radix3": "^1.1.2",
80
80
  "std-env": "^3.10.0"
81
81
  },
82
82
  "devDependencies": {
83
- "@antfu/eslint-config": "^4.12.0",
84
- "@libsql/client": "^0.15.15",
85
- "@nuxt/devtools": "^3.1.1",
86
- "@nuxt/devtools-kit": "^3.1.1",
83
+ "@antfu/eslint-config": "^7.6.1",
84
+ "@libsql/client": "^0.17.0",
85
+ "@libsql/linux-x64-gnu": "0.5.22",
86
+ "@nuxt/devtools": "^3.2.2",
87
+ "@nuxt/devtools-kit": "^3.2.2",
87
88
  "@nuxt/module-builder": "^1.0.2",
88
- "@nuxt/schema": "^4.2.2",
89
- "@nuxt/test-utils": "^3.21.0",
90
- "@nuxthub/core": "^0.10.5",
89
+ "@nuxt/schema": "^4.3.1",
90
+ "@nuxt/test-utils": "^4.0.0",
91
+ "@nuxthub/core": "^0.10.6",
91
92
  "@types/better-sqlite3": "^7.6.13",
92
93
  "@types/node": "latest",
93
- "better-auth": "^1.5.0-beta.3",
94
- "better-sqlite3": "^11.9.1",
95
- "bumpp": "^10.3.2",
94
+ "better-auth": "1.5.0",
95
+ "better-sqlite3": "^12.6.2",
96
+ "bumpp": "^10.4.1",
96
97
  "changelogen": "^0.6.2",
97
98
  "consola": "^3.4.2",
98
- "drizzle-kit": "^0.31.8",
99
- "drizzle-orm": "^0.38.4",
100
- "eslint": "^9.39.1",
99
+ "drizzle-kit": "^0.31.9",
100
+ "drizzle-orm": "^0.45.1",
101
+ "eslint": "^10.0.2",
101
102
  "npm-agentskills": "https://pkg.pr.new/onmax/npm-agentskills@394499e",
102
- "nuxt": "^4.2.2",
103
+ "nuxt": "^4.3.1",
103
104
  "tinyexec": "^1.0.2",
104
105
  "typescript": "~5.9.3",
105
- "vitest": "^4.0.15",
106
- "vitest-package-exports": "^0.1.1",
107
- "vue-tsc": "^3.1.7",
106
+ "vitest": "^4.0.18",
107
+ "vitest-package-exports": "^1.2.0",
108
+ "vue-tsc": "^3.2.5",
108
109
  "yaml": "^2.8.2"
109
- },
110
- "pnpm": {
111
- "onlyBuiltDependencies": [
112
- "@parcel/watcher",
113
- "better-sqlite3",
114
- "esbuild",
115
- "sharp",
116
- "workerd"
117
- ],
118
- "patchedDependencies": {
119
- "@peculiar/x509@1.14.2": "patches/@peculiar__x509@1.14.2.patch"
120
- },
121
- "overrides": {
122
- "reka-ui": "^2.6.1"
123
- }
124
110
  }
125
111
  }
@@ -1,5 +0,0 @@
1
- import type { AppAuthClient } from '#nuxt-better-auth';
2
- import type { ActionHandleFor } from '../internal/auth-action-handles.js';
3
- type SignIn = NonNullable<AppAuthClient>['signIn'];
4
- export declare function useUserSignIn<MethodKey extends keyof SignIn>(method: MethodKey): ActionHandleFor<SignIn[MethodKey]>;
5
- export {};