104 lines
2.7 KiB
TypeScript
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,
|
|
};
|
|
}
|