mirror of
https://github.com/LukeHagar/better-auth.git
synced 2025-12-10 12:27:44 +00:00
fix: session inference breaking on some plugins
This commit is contained in:
13
dev/bun/_auth.ts
Normal file
13
dev/bun/_auth.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { betterAuth } from "better-auth";
|
||||
import { prismaAdapter } from "better-auth/adapters/prisma";
|
||||
import { twoFactor } from "better-auth/plugins";
|
||||
|
||||
export const auth = betterAuth({
|
||||
database: prismaAdapter(
|
||||
{},
|
||||
{
|
||||
provider: "mysql",
|
||||
},
|
||||
),
|
||||
plugins: [twoFactor()],
|
||||
});
|
||||
@@ -1,13 +0,0 @@
|
||||
import { betterAuth } from "better-auth";
|
||||
import { prismaAdapter } from "better-auth/adapters/prisma";
|
||||
import { twoFactor } from "better-auth/plugins";
|
||||
|
||||
export const auth = betterAuth({
|
||||
database: prismaAdapter(
|
||||
{},
|
||||
{
|
||||
provider: "mysql",
|
||||
},
|
||||
),
|
||||
plugins: [twoFactor()],
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { auth } from "./auth";
|
||||
import { auth } from "./_auth";
|
||||
|
||||
Bun.serve({
|
||||
fetch(request, server) {
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
"@types/react": "^18.3.3",
|
||||
"better-sqlite3": "^11.3.0",
|
||||
"drizzle-orm": "^0.33.0",
|
||||
"happy-dom": "^15.7.3",
|
||||
"happy-dom": "^15.7.4",
|
||||
"hono": "^4.5.4",
|
||||
"listhen": "^1.7.2",
|
||||
"mongodb": "^6.9.0",
|
||||
|
||||
@@ -1,40 +1,18 @@
|
||||
import type { BetterFetch } from "@better-fetch/fetch";
|
||||
import { atom } from "nanostores";
|
||||
import type { Auth as BetterAuth } from "../auth";
|
||||
import type { Prettify, UnionToIntersection } from "../types/helper";
|
||||
import type { InferSession, InferUser } from "../types/models";
|
||||
import type { BetterAuthClientPlugin, ClientOptions } from "./types";
|
||||
import type { Prettify } from "../types/helper";
|
||||
import type {
|
||||
ClientOptions,
|
||||
InferSessionFromClient,
|
||||
InferUserFromClient,
|
||||
} from "./types";
|
||||
import { useAuthQuery } from "./query";
|
||||
import type { BetterAuthPlugin } from "../plugins";
|
||||
|
||||
export function getSessionAtom<Option extends ClientOptions>(
|
||||
$fetch: BetterFetch,
|
||||
) {
|
||||
type Plugins = Option["plugins"] extends Array<BetterAuthClientPlugin>
|
||||
? Array<
|
||||
Option["plugins"][number] extends infer T
|
||||
? T extends BetterAuthClientPlugin
|
||||
? T["$InferServerPlugin"] extends infer U
|
||||
? U extends BetterAuthPlugin
|
||||
? U
|
||||
: never
|
||||
: never
|
||||
: never
|
||||
: never
|
||||
>
|
||||
: never;
|
||||
|
||||
type Auth = {
|
||||
handler: any;
|
||||
api: any;
|
||||
options: {
|
||||
database: any;
|
||||
plugins: Plugins;
|
||||
};
|
||||
};
|
||||
|
||||
type UserWithAdditionalFields = InferUser<Auth["options"]>;
|
||||
type SessionWithAdditionalFields = InferSession<Auth["options"]>;
|
||||
type UserWithAdditionalFields = InferUserFromClient<Option>;
|
||||
type SessionWithAdditionalFields = InferSessionFromClient<Option>;
|
||||
const $signal = atom<boolean>(false);
|
||||
const session = useAuthQuery<{
|
||||
user: Prettify<UserWithAdditionalFields>;
|
||||
@@ -47,8 +25,8 @@ export function getSessionAtom<Option extends ClientOptions>(
|
||||
_sessionSignal: $signal,
|
||||
$Infer: {} as {
|
||||
Session: {
|
||||
session: Prettify<SessionWithAdditionalFields>;
|
||||
user: Prettify<UserWithAdditionalFields>;
|
||||
session: SessionWithAdditionalFields;
|
||||
user: UserWithAdditionalFields;
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -5,10 +5,15 @@ import type {
|
||||
} from "@better-fetch/fetch";
|
||||
import type { BetterAuthPlugin } from "../types/plugins";
|
||||
import type { Atom } from "nanostores";
|
||||
import type { LiteralString, UnionToIntersection } from "../types/helper";
|
||||
import type {
|
||||
LiteralString,
|
||||
StripEmptyObjects,
|
||||
UnionToIntersection,
|
||||
} from "../types/helper";
|
||||
import type { Auth } from "../auth";
|
||||
import type { InferRoutes } from "./path-to-object";
|
||||
import type { InferSession, InferUser } from "../types";
|
||||
import type { InferSession, InferUser, Session, User } from "../types";
|
||||
import type { FieldAttribute, InferFieldOutput } from "../db";
|
||||
|
||||
export type AtomListener = {
|
||||
matcher: (path: string) => boolean;
|
||||
@@ -93,19 +98,43 @@ export type InferPluginsFromClient<O extends ClientOptions> =
|
||||
? Array<O["plugins"][number]["$InferServerPlugin"]>
|
||||
: undefined;
|
||||
|
||||
type InferAuthFromClient<O extends ClientOptions> = {
|
||||
handler: any;
|
||||
api: any;
|
||||
options: {
|
||||
database: any;
|
||||
plugins: InferPluginsFromClient<O>;
|
||||
export type InferSessionFromClient<O extends ClientOptions> = StripEmptyObjects<
|
||||
Session & UnionToIntersection<InferAdditionalFromClient<O, "session">>
|
||||
>;
|
||||
export type InferUserFromClient<O extends ClientOptions> = StripEmptyObjects<
|
||||
User & UnionToIntersection<InferAdditionalFromClient<O, "user">>
|
||||
>;
|
||||
|
||||
export type InferAdditionalFromClient<
|
||||
Options extends ClientOptions,
|
||||
Key extends string,
|
||||
> = Options["plugins"] extends Array<infer T>
|
||||
? T extends BetterAuthClientPlugin
|
||||
? T["$InferServerPlugin"] extends {
|
||||
schema: {
|
||||
[key in Key]: {
|
||||
fields: infer Field;
|
||||
};
|
||||
};
|
||||
|
||||
export type InferSessionFromClient<O extends ClientOptions> = InferSession<
|
||||
InferAuthFromClient<O> extends Auth ? InferAuthFromClient<O> : never
|
||||
>;
|
||||
|
||||
export type InferUserFromClient<O extends ClientOptions> = InferUser<
|
||||
InferAuthFromClient<O> extends Auth ? InferAuthFromClient<O> : never
|
||||
>;
|
||||
};
|
||||
}
|
||||
? Field extends Record<infer Key, FieldAttribute>
|
||||
? {
|
||||
[key in Key as Field[key]["required"] extends false
|
||||
? never
|
||||
: Field[key]["defaultValue"] extends
|
||||
| boolean
|
||||
| string
|
||||
| number
|
||||
| Date
|
||||
| Function
|
||||
? key
|
||||
: never]: InferFieldOutput<Field[key]>;
|
||||
} & {
|
||||
[key in Key as Field[key]["returned"] extends false
|
||||
? never
|
||||
: key]?: InferFieldOutput<Field[key]>;
|
||||
}
|
||||
: {}
|
||||
: {}
|
||||
: {}
|
||||
: {};
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
import type { BetterAuthClientPlugin, OAuthProviderList } from "../../types";
|
||||
|
||||
export const client = () => {
|
||||
return {
|
||||
id: "last-used",
|
||||
fetchPlugins: [
|
||||
{
|
||||
id: "last-used",
|
||||
name: "Last Used",
|
||||
init(url, options) {
|
||||
if (url.startsWith("/sign-in")) {
|
||||
let lastUsed = "";
|
||||
if (url === "/sign-in/social") {
|
||||
lastUsed = options?.body?.provider;
|
||||
} else {
|
||||
lastUsed = url.replace("/sign-in/", "");
|
||||
}
|
||||
localStorage.setItem("last-used", lastUsed);
|
||||
}
|
||||
return {
|
||||
url,
|
||||
options,
|
||||
};
|
||||
},
|
||||
},
|
||||
],
|
||||
} satisfies BetterAuthClientPlugin;
|
||||
};
|
||||
@@ -27,3 +27,9 @@ export type RequiredKeysOf<BaseType extends object> = Exclude<
|
||||
export type HasRequiredKeys<BaseType extends object> =
|
||||
RequiredKeysOf<BaseType> extends never ? false : true;
|
||||
export type WithoutEmpty<T> = T extends T ? ({} extends T ? never : T) : never;
|
||||
|
||||
export type StripEmptyObjects<T> = T extends { [K in keyof T]: never }
|
||||
? never
|
||||
: T extends object
|
||||
? { [K in keyof T as T[K] extends never ? never : K]: T[K] }
|
||||
: T;
|
||||
|
||||
@@ -2,7 +2,11 @@ import type { BetterAuthOptions } from ".";
|
||||
import type { Session, User } from "../db/schema";
|
||||
import type { Auth } from "../auth";
|
||||
import type { FieldAttribute, InferFieldOutput } from "../db";
|
||||
import type { Prettify, UnionToIntersection } from "./helper";
|
||||
import type {
|
||||
Prettify,
|
||||
StripEmptyObjects,
|
||||
UnionToIntersection,
|
||||
} from "./helper";
|
||||
import type { BetterAuthPlugin } from "./plugins";
|
||||
|
||||
type AdditionalSessionFields<Options extends BetterAuthOptions> =
|
||||
@@ -31,8 +35,7 @@ type AdditionalUserFields<Options extends BetterAuthOptions> =
|
||||
};
|
||||
}
|
||||
? Field extends Record<infer Key, FieldAttribute>
|
||||
? Prettify<
|
||||
{
|
||||
? {
|
||||
[key in Key as Field[key]["required"] extends false
|
||||
? never
|
||||
: Field[key]["defaultValue"] extends
|
||||
@@ -48,18 +51,21 @@ type AdditionalUserFields<Options extends BetterAuthOptions> =
|
||||
? never
|
||||
: key]?: InferFieldOutput<Field[key]>;
|
||||
}
|
||||
>
|
||||
: {}
|
||||
: {}
|
||||
: {};
|
||||
|
||||
export type InferUser<O extends BetterAuthOptions | Auth> = UnionToIntersection<
|
||||
StripEmptyObjects<
|
||||
Prettify<
|
||||
User &
|
||||
(O extends BetterAuthOptions
|
||||
? AdditionalUserFields<O>
|
||||
: O extends Auth
|
||||
? AdditionalUserFields<O["options"]>
|
||||
: {})
|
||||
>
|
||||
>
|
||||
>;
|
||||
|
||||
export type InferSession<O extends BetterAuthOptions | Auth> =
|
||||
|
||||
2
pnpm-lock.yaml
generated
2
pnpm-lock.yaml
generated
@@ -1271,7 +1271,7 @@ importers:
|
||||
specifier: ^0.33.0
|
||||
version: 0.33.0(@prisma/client@5.20.0)(@types/better-sqlite3@7.6.11)(@types/pg@8.11.10)(@types/react@18.3.9)(better-sqlite3@11.3.0)(kysely@0.27.4)(mysql2@3.11.3)(pg@8.13.0)(prisma@5.20.0)(react@18.3.1)
|
||||
happy-dom:
|
||||
specifier: ^15.7.3
|
||||
specifier: ^15.7.4
|
||||
version: 15.7.4
|
||||
hono:
|
||||
specifier: ^4.5.4
|
||||
|
||||
Reference in New Issue
Block a user