import { Session } from "better-auth"; import * as v from "valibot"; export type { Session } from "better-auth"; export type ModifiedSession = Session & { isCurrent?: boolean }; // User role enum export enum UserRoleMap { user = "user", admin = "admin", } // User role schema export const userRoleSchema = v.picklist(["user", "admin"]); export type UserRole = v.InferOutput; // User schema export const userSchema = v.object({ id: v.string(), name: v.string(), email: v.string(), emailVerified: v.boolean(), image: v.optional(v.string()), createdAt: v.date(), updatedAt: v.date(), username: v.optional(v.string()), displayUsername: v.optional(v.string()), role: v.optional(v.string()), banned: v.optional(v.boolean()), banReason: v.optional(v.string()), banExpires: v.optional(v.date()), onboardingDone: v.optional(v.boolean()), last2FAVerifiedAt: v.optional(v.date()), parentId: v.optional(v.string()), }); export type User = v.InferOutput; // Account schema export const accountSchema = v.object({ id: v.string(), accountId: v.string(), providerId: v.string(), userId: v.string(), accessToken: v.string(), refreshToken: v.string(), idToken: v.string(), accessTokenExpiresAt: v.date(), refreshTokenExpiresAt: v.date(), scope: v.string(), password: v.string(), createdAt: v.date(), updatedAt: v.date(), }); export type Account = v.InferOutput; // Ensure account exists schema export const ensureAccountExistsSchema = v.object({ userId: v.string(), }); export type EnsureAccountExists = v.InferOutput< typeof ensureAccountExistsSchema >; // Ban info schema export const banInfoSchema = v.object({ banned: v.boolean(), reason: v.optional(v.string()), expires: v.optional(v.date()), }); export type BanInfo = v.InferOutput; // Ban user schema export const banUserSchema = v.object({ userId: v.string(), reason: v.string(), banExpiresAt: v.date(), }); export type BanUser = v.InferOutput; // Check username availability schema export const checkUsernameSchema = v.object({ username: v.string(), }); export type CheckUsername = v.InferOutput; // Rotate password schema export const rotatePasswordSchema = v.object({ userId: v.string(), password: v.string(), }); export type RotatePassword = v.InferOutput; // View Model specific types // Search and filter types export const searchFieldSchema = v.picklist(["email", "name", "username"]); export type SearchField = v.InferOutput; export const searchOperatorSchema = v.picklist([ "contains", "starts_with", "ends_with", ]); export type SearchOperator = v.InferOutput; export const filterOperatorSchema = v.picklist([ "eq", "ne", "lt", "lte", "gt", "gte", ]); export type FilterOperator = v.InferOutput; export const sortDirectionSchema = v.picklist(["asc", "desc"]); export type SortDirection = v.InferOutput; // Users query state export const usersQueryStateSchema = v.object({ // searching searchValue: v.optional(v.string()), searchField: v.optional(searchFieldSchema), searchOperator: v.optional(searchOperatorSchema), // pagination limit: v.pipe(v.number(), v.integer()), offset: v.pipe(v.number(), v.integer()), // sorting sortBy: v.optional(v.string()), sortDirection: v.optional(sortDirectionSchema), // filtering filterField: v.optional(v.string()), filterValue: v.optional(v.union([v.string(), v.number(), v.boolean()])), filterOperator: v.optional(filterOperatorSchema), }); export type UsersQueryState = v.InferOutput; // UI View Model types export const banExpiryModeSchema = v.picklist([ "never", "1d", "7d", "30d", "custom", ]); export type BanExpiryMode = v.InferOutput; export const createUserFormSchema = v.object({ email: v.string(), password: v.string(), name: v.string(), role: v.union([userRoleSchema, v.array(userRoleSchema)]), }); export type CreateUserForm = v.InferOutput;