mirror of
https://github.com/better-auth/better-auth.git
synced 2026-05-25 08:31:37 -05:00
chore: fix type inference when user and custom session plugins are combined (#8448)
This commit is contained in:
@@ -41,6 +41,28 @@ type ReplaceAuthUserAndSession<
|
||||
InferSessionFromClient<ClientOpts>
|
||||
>;
|
||||
|
||||
type MergeCustomSessionField<
|
||||
R extends object,
|
||||
Field extends "user" | "session",
|
||||
InferType,
|
||||
> = Field extends keyof R
|
||||
? {
|
||||
[K in Field]: KeepNullishFromOriginal<
|
||||
R[K],
|
||||
NonNullable<R[K]> & InferType
|
||||
>;
|
||||
}
|
||||
: {};
|
||||
|
||||
type MergeCustomSessionWithInferred<
|
||||
R,
|
||||
ClientOpts extends BetterAuthClientOptions,
|
||||
> = R extends object
|
||||
? Omit<R, "user" | "session"> &
|
||||
MergeCustomSessionField<R, "user", InferUserFromClient<ClientOpts>> &
|
||||
MergeCustomSessionField<R, "session", InferSessionFromClient<ClientOpts>>
|
||||
: never;
|
||||
|
||||
type RefineAuthResponse<
|
||||
Data,
|
||||
ClientOpts extends BetterAuthClientOptions,
|
||||
@@ -194,7 +216,10 @@ export type InferRoute<API, COpts extends BetterAuthClientOptions> =
|
||||
Meta extends {
|
||||
CUSTOM_SESSION: boolean;
|
||||
}
|
||||
? NonNullable<Awaited<R>>
|
||||
? MergeCustomSessionWithInferred<
|
||||
NonNullable<Awaited<R>>,
|
||||
COpts
|
||||
>
|
||||
: T["path"] extends "/get-session"
|
||||
? {
|
||||
user: InferUserFromClient<COpts>;
|
||||
|
||||
@@ -3,6 +3,7 @@ import { createAuthClient } from "../../client";
|
||||
import { parseSetCookieHeader } from "../../cookies";
|
||||
import { getTestInstance } from "../../test-utils/test-instance";
|
||||
import type { BetterAuthOptions } from "../../types";
|
||||
import { inferAdditionalFields } from "../additional-fields/client";
|
||||
import { admin } from "../admin";
|
||||
import { adminClient } from "../admin/client";
|
||||
import { multiSession } from "../multi-session";
|
||||
@@ -300,4 +301,81 @@ describe("Custom Session Plugin Tests", async () => {
|
||||
};
|
||||
}>();
|
||||
});
|
||||
|
||||
it("should not add user/session to client getSession type when custom session omits them", async () => {
|
||||
const { auth } = await getTestInstance({
|
||||
plugins: [
|
||||
customSession(async () => {
|
||||
return {
|
||||
custom: {
|
||||
field: "field",
|
||||
},
|
||||
};
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
const client = createAuthClient({
|
||||
plugins: [customSessionClient<typeof auth>()],
|
||||
});
|
||||
|
||||
type SessionData = typeof client.$Infer.Session;
|
||||
|
||||
// When custom session omits user/session, the client type must not claim they exist
|
||||
expectTypeOf<SessionData>().toEqualTypeOf<{
|
||||
custom: {
|
||||
field: string;
|
||||
};
|
||||
}>();
|
||||
|
||||
// Verify user and session are not in the type
|
||||
expectTypeOf<keyof SessionData>().toEqualTypeOf<"custom">();
|
||||
});
|
||||
|
||||
it("should infer both customSessionClient and inferAdditionalFields when combined", async () => {
|
||||
const { auth } = await getTestInstance({
|
||||
user: {
|
||||
additionalFields: {
|
||||
role: {
|
||||
type: "string",
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
customSession(async ({ user, session }) => {
|
||||
return {
|
||||
user: {
|
||||
firstName: user.name.split(" ")[0],
|
||||
lastName: user.name.split(" ")[1],
|
||||
},
|
||||
session,
|
||||
customData: { message: "hello" },
|
||||
};
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
const client = createAuthClient({
|
||||
plugins: [
|
||||
customSessionClient<typeof auth>(),
|
||||
inferAdditionalFields<typeof auth>(),
|
||||
],
|
||||
});
|
||||
|
||||
type SessionData = typeof client.$Infer.Session;
|
||||
type User = SessionData["user"];
|
||||
|
||||
expectTypeOf<User>().toMatchObjectType<{
|
||||
id: string;
|
||||
firstName: string | undefined;
|
||||
lastName: string | undefined;
|
||||
role?: string | undefined | null;
|
||||
}>();
|
||||
|
||||
type CustomData = SessionData["customData"];
|
||||
expectTypeOf<CustomData>().toMatchObjectType<{
|
||||
message: string;
|
||||
}>();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user