Files
domain-wall/packages/logic/domains/user/data/entities.ts
2025-10-20 17:07:41 +03:00

104 lines
2.7 KiB
TypeScript

import { UserRoleMap } from "../../../core/enums";
import { paginationModel } from "../../../core/pagination.utils";
import { encodeCursor } from "../../../core/string.utils";
import z from "zod";
const usernameModel = z
.string()
.min(2)
.max(128)
.regex(/^[a-zA-Z0-9_-]+$/, {
message:
"Username can only contain letters, numbers, underscores, and hyphens.",
});
export const emailModel = z.string().email().min(5).max(128);
export const discountPercentModel = z
.number()
.min(0)
.max(100)
.default(0)
.nullish();
const roleModel = z.enum(Object.values(UserRoleMap) as [string, ...string[]]);
export const createUserPayloadModel = z.object({
username: usernameModel,
email: emailModel,
password: z.string().min(8).max(128),
role: roleModel,
});
export type CreateUserPayloadModel = z.infer<typeof createUserPayloadModel>;
export type GetUserByPayload = { id?: string; username?: string };
export const updateUserInfoInputModel = z.object({
email: emailModel,
username: usernameModel,
discountPercent: discountPercentModel,
banned: z.boolean().nullable().optional(),
});
export type UpdateUserInfoInputModel = z.infer<typeof updateUserInfoInputModel>;
export const userModel = updateUserInfoInputModel.merge(
z.object({
id: z.coerce.string(),
role: roleModel.nullable().optional(),
discountPercent: discountPercentModel,
createdAt: z.coerce.date(),
updatedAt: z.coerce.date(),
parentId: z.coerce.string().nullable().optional(),
}),
);
export type UserModel = z.infer<typeof userModel>;
export const limitedUserModel = userModel.pick({
id: true,
username: true,
email: true,
});
export type LimitedUserModel = z.infer<typeof limitedUserModel>;
export const userFullModel = userModel.merge(
z.object({
banned: z.boolean(),
banReason: z.string().optional(),
banExpires: z.date().optional(),
twoFactorEnabled: z.boolean().default(false),
}),
);
export type UserFullModel = z.infer<typeof userFullModel>;
export const usersCursorModel = z.object({
firstItemUsername: z.string(),
lastItemUsername: z.string(),
query: z.string().default(""),
});
export type UsersCursorModel = z.infer<typeof usersCursorModel>;
export function getDefaultUsersCursor() {
return usersCursorModel.parse({
firstItemUsername: "",
lastItemUsername: "",
query: "",
});
}
export const paginatedUserModel = paginationModel.merge(
z.object({ data: z.array(userModel) }),
);
export type PaginatedUserModel = z.infer<typeof paginatedUserModel>;
export function getDefaultPaginatedUserModel(): PaginatedUserModel {
return {
data: [],
cursor: encodeCursor<UsersCursorModel>(getDefaultUsersCursor()),
limit: 20,
asc: true,
totalItemCount: 0,
totalPages: 0,
page: 0,
};
}