169 lines
3.9 KiB
TypeScript
169 lines
3.9 KiB
TypeScript
import { db } from '@/lib/db';
|
|
import { users } from '@/lib/db/schema';
|
|
import { eq, like } from 'drizzle-orm';
|
|
import { generateId, ApiError } from './index';
|
|
|
|
export interface CreateUserData {
|
|
email: string;
|
|
username: string;
|
|
displayName: string;
|
|
avatarUrl?: string;
|
|
bio?: string;
|
|
}
|
|
|
|
export interface UpdateUserData {
|
|
username?: string;
|
|
displayName?: string;
|
|
avatarUrl?: string;
|
|
bio?: string;
|
|
}
|
|
|
|
// Create a new user
|
|
export async function createUser(data: CreateUserData) {
|
|
try {
|
|
const userId = generateId();
|
|
const now = new Date();
|
|
|
|
const [user] = await db.insert(users).values({
|
|
id: userId,
|
|
email: data.email,
|
|
username: data.username,
|
|
displayName: data.displayName,
|
|
avatarUrl: data.avatarUrl,
|
|
bio: data.bio,
|
|
isAdmin: false,
|
|
isModerator: false,
|
|
createdAt: now,
|
|
updatedAt: now,
|
|
}).returning();
|
|
|
|
return user;
|
|
} catch (error) {
|
|
throw new ApiError(`Failed to create user: ${error}`, 500);
|
|
}
|
|
}
|
|
|
|
// Get user by ID
|
|
export async function getUserById(id: string) {
|
|
try {
|
|
const user = await db.query.users.findFirst({
|
|
where: eq(users.id, id),
|
|
with: {
|
|
scripts: {
|
|
where: eq(users.isAdmin, true) ? undefined : eq(users.id, id), // Only show own scripts unless admin
|
|
},
|
|
},
|
|
});
|
|
|
|
if (!user) {
|
|
throw new ApiError('User not found', 404);
|
|
}
|
|
|
|
return user;
|
|
} catch (error) {
|
|
if (error instanceof ApiError) throw error;
|
|
throw new ApiError(`Failed to get user: ${error}`, 500);
|
|
}
|
|
}
|
|
|
|
// Get user by email
|
|
export async function getUserByEmail(email: string) {
|
|
try {
|
|
const user = await db.query.users.findFirst({
|
|
where: eq(users.email, email),
|
|
});
|
|
|
|
return user;
|
|
} catch (error) {
|
|
throw new ApiError(`Failed to get user by email: ${error}`, 500);
|
|
}
|
|
}
|
|
|
|
// Get user by username
|
|
export async function getUserByUsername(username: string) {
|
|
try {
|
|
const user = await db.query.users.findFirst({
|
|
where: eq(users.username, username),
|
|
});
|
|
|
|
return user;
|
|
} catch (error) {
|
|
throw new ApiError(`Failed to get user by username: ${error}`, 500);
|
|
}
|
|
}
|
|
|
|
// Update user
|
|
export async function updateUser(id: string, data: UpdateUserData) {
|
|
try {
|
|
const updateData = {
|
|
...data,
|
|
updatedAt: new Date(),
|
|
};
|
|
|
|
const [updatedUser] = await db
|
|
.update(users)
|
|
.set(updateData)
|
|
.where(eq(users.id, id))
|
|
.returning();
|
|
|
|
return updatedUser;
|
|
} catch (error) {
|
|
throw new ApiError(`Failed to update user: ${error}`, 500);
|
|
}
|
|
}
|
|
|
|
// Update user permissions (admin only)
|
|
export async function updateUserPermissions(
|
|
id: string,
|
|
permissions: { isAdmin?: boolean; isModerator?: boolean }
|
|
) {
|
|
try {
|
|
const updateData = {
|
|
...permissions,
|
|
updatedAt: new Date(),
|
|
};
|
|
|
|
const [updatedUser] = await db
|
|
.update(users)
|
|
.set(updateData)
|
|
.where(eq(users.id, id))
|
|
.returning();
|
|
|
|
return updatedUser;
|
|
} catch (error) {
|
|
throw new ApiError(`Failed to update user permissions: ${error}`, 500);
|
|
}
|
|
}
|
|
|
|
// Search users
|
|
export async function searchUsers(query: string, limit: number = 20) {
|
|
try {
|
|
const searchResults = await db
|
|
.select()
|
|
.from(users)
|
|
.where(
|
|
like(users.username, `%${query}%`)
|
|
)
|
|
.limit(limit);
|
|
|
|
return searchResults;
|
|
} catch (error) {
|
|
throw new ApiError(`Failed to search users: ${error}`, 500);
|
|
}
|
|
}
|
|
|
|
// Get all users (admin only)
|
|
export async function getAllUsers(limit: number = 50, offset: number = 0) {
|
|
try {
|
|
const allUsers = await db
|
|
.select()
|
|
.from(users)
|
|
.limit(limit)
|
|
.offset(offset);
|
|
|
|
return allUsers;
|
|
} catch (error) {
|
|
throw new ApiError(`Failed to get all users: ${error}`, 500);
|
|
}
|
|
}
|