Infer `AuthUser` / `AuthSession` from `auth.ts`: plugin and `additionalFields` columns are missing from `c.get('user')`, `getUser()` and `requireAuth()`
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 53/100
- Tipo de issue
- Error
- Claridad
- Bastante claro
- Estado de actividad
- Activo
- Stack tecnológico
- typescript
- Área
- backend, developer-experience
Línea de trabajo
Start with packages/void/src/runtime/auth.ts and the CloudContextVariables definitions in packages/void/src/runtime/handler.ts; trace how AuthUser and AuthSession flow into getUser(), getSession() and requireAuth(c). Check how .void/env.d.ts generates inferred types and use the Better Auth config type and the issue’s reproduction to verify the expected fields appear. Done when those APIs type the configured plugin and additional fields correctly.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Description
AuthUser and AuthSession are always Better Auth's base shapes, whatever auth.ts configures. Fields added by plugins (role and banned from admin(), impersonatedBy on the session) or by user.additionalFields are present at runtime but missing from the types of c.get('user'), c.get('session'), getUser(), getSession() and requireAuth(c).
The app can't fix this itself:
- Redeclaring
useronCloudContextVariablesfails with TS2717, because the property already has a different type. AuthUseris a type alias, so it can't be augmented.
A cast at every read is the only option.
Void already has the information. defineAuth<T>(config: T): T keeps the config type, and .void/better-auth-schema.ts is generated with the plugin columns.
Steps to reproduce
-
Enable auth and add
auth.tswith a plugin and a custom field:// auth.ts import { admin } from 'better-auth/plugins/admin'; import { defineAuth } from 'void/auth'; export default defineAuth(({ defaults }) => ({ ...defaults, plugins: [admin()], user: { additionalFields: { plan: { type: 'string', required: false } } }, })); -
Read the fields on the server:
import { defineHandler } from 'void'; import { getUser } from 'void/auth'; export const loader = defineHandler((c) => ({ role: c.get('user')?.role, plan: getUser()?.plan, })); -
Run
tsc.
Actual behavior
error TS2339: Property 'role' does not exist on type '{ id: string; createdAt: Date; updatedAt: Date; email: string; emailVerified: boolean; name: string; image?: string | null | undefined; }'.
error TS2339: Property 'plan' does not exist on type '{ id: string; createdAt: Date; updatedAt: Date; email: string; emailVerified: boolean; name: string; image?: string | null | undefined; }'.
Trying to override the type:
declare module 'void' {
interface CloudContextVariables {
user: (AuthUser & { role: string | null }) | null;
}
}
error TS2717: Subsequent property declarations must have the same type. Property 'user' must be of type '{ id: string; … } | null', but here has type '… | null'.
Expected behavior
c.get('user'), getUser() and requireAuth(c) include role, banned, banReason, banExpires and plan. c.get('session') and getSession() include impersonatedBy.
Cause
packages/void/src/runtime/auth.ts (main @ a6de7829bf, lines 6–7):
export type AuthUser = User;
export type AuthSession = Session;
User and Session come from better-auth without any options, so they're the base shapes. CloudContextVariables (runtime/handler.ts lines 29–31), AuthState, getUser, getSession and requireAuth are all typed from them.
Possible fix
Better Auth can already infer both types from the config type. This type-checks with the auth.ts above, and both role and plan are present:
import type { Auth } from 'better-auth';
import type config from './auth';
type Options = ReturnType<typeof config>;
type User = Auth<Options>['$Infer']['Session']['user']; // includes role, banned, plan
type Session = Auth<Options>['$Infer']['Session']['session']; // includes impersonatedBy
Void could generate this the way .void/env.d.ts augments ValidatedEnv and CloudBindings:
- Make
AuthUserandAuthSessioninterfaces:export interface AuthUser extends User {}. - Generate
.void/auth.d.tswhenauth.tsexists:
declare module 'void/auth' {
interface AuthUser extends _InferredUser {}
interface AuthSession extends _InferredSession {}
}
Everything typed from AuthUser, including CloudContextVariables, would then pick up the fields.
Workaround
Cast in one helper:
import { userTable } from '@auth-schema'; // .void/better-auth-schema.ts
type User = typeof userTable.$inferSelect;
export function getCurrentUser(c: CloudContext): User | null {
return c.get('user') as User | null;
}
Environment
- void 1.2.1, better-auth 1.7.11
- TypeScript 7.0.2, vite-plus 1.3.0, Node 22.23.3, macOS 26.6
- Lenguaje dominante
- TypeScript
- Estrellas
- 402
- Forks
- 32
- Merge medio
- 8 h 32 min
- PR fusionados (30 d)
- 111
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de voidzero-dev/void
-
Dev: `better-auth/client/plugins` fails to resolve when auth is enabled (the `better-auth/client` alias matches it as a prefix)Posiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
voidzero-dev/void#565 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
voidzero-dev/void#529 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 1/5 1-3 horas Aptitud para principiantes 78/100
voidzero-dev/void#428 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 55/100
voidzero-dev/void#564 ·
Los mantenedores suelen responder en 1 día
-
Navigation commit failure leaves the loading state active and causes inconsistent internal stateAbierto
Dificultad 4/5 3-5 días Aptitud para principiantes 48/100
voidzero-dev/void#562 ·
Los mantenedores suelen responder en 1 día
Todos los issues de voidzero-dev/void
Issues similares
-
[Bug]: REST API URL starting with "http" but no scheme (e.g. httpbin.org/get) is not given an http:// prefixPosiblemente ocupada @ItsDeadlyProgrammer la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
appsmithorg/appsmith#42471 · 1 comentario ·
Los mantenedores suelen responder en 2 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
ehmpathy/rhachet-roles-bhrain#705 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día
-
Status: Triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
mermaid-js/mermaid#8546 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
braintrustdata/braintrust-sdk-javascript#2659 ·
Los mantenedores suelen responder en 1 día