style: clean up code formatting and remove trailing whitespace

refactor: reorganize imports and fix type imports
This commit is contained in:
Evandro Fonseca Junior committed 2025-11-11 03:08:36 -03:00
1 parent d3704602fd
commit 47c04de6fe
232 files changed
+7140 -4798

No files matched your search

+185 -163
View File
@@ -1,7 +1,7 @@
import { z } from "zod";
import validator from "validator";
import { isValidDocument } from "./validators/document-validator";
import sanitizeHtml from "sanitize-html";
import validator from "validator";
import { z } from "zod";
import { isValidDocument } from "./validators/document-validator";
/**
* Schemas de validação usando Zod
@@ -59,7 +59,7 @@ export const nameSchema = z
.max(100, "Nome deve ter no máximo 100 caracteres")
.refine(
(name) => /^[A-Za-zÀ-ÿ\s'-]+$/.test(name.trim()),
"Nome deve conter apenas letras, espaços e acentos"
"Nome deve conter apenas letras, espaços e acentos",
)
.transform((name) => name.trim());
@@ -82,7 +82,7 @@ export const donationTierSchema = z.enum(
["coffee", "snack", "lunch", "custom"],
{
message: "Tier de doação inválido",
}
},
);
// Schema para valor customizado
@@ -123,7 +123,7 @@ export const createDonationSchema = z
{
message: "customAmount é obrigatório quando tier é 'custom'",
path: ["customAmount"],
}
},
)
.refine(
(data) => {
@@ -136,7 +136,7 @@ export const createDonationSchema = z
{
message: "Valor deve estar entre R$ 5,00 e R$ 100.000,00",
path: ["customAmount"],
}
},
);
// Schema para verificação de status
@@ -160,7 +160,7 @@ export const usernameSchema = z
.max(50, "Username deve ter no máximo 50 caracteres")
.regex(
/^[a-zA-Z0-9_]+$/,
"Username deve conter apenas letras, números e underscore"
"Username deve conter apenas letras, números e underscore",
)
.transform((username) => username.toLowerCase().trim());
@@ -181,7 +181,7 @@ export const passwordSchema = z
{
message:
"Senha deve conter pelo menos 1 letra maiúscula, 1 letra minúscula e 1 número",
}
},
);
// Schema para servidor/personagem no registro
@@ -211,7 +211,10 @@ const subscriptionTierFeatureSchema = z.object({
.string()
.min(2, "featureKey deve ter no mínimo 2 caracteres")
.max(100, "featureKey deve ter no máximo 100 caracteres")
.regex(featureKeyRegex, "featureKey deve conter apenas letras, números, ponto, hífen ou underscore")
.regex(
featureKeyRegex,
"featureKey deve conter apenas letras, números, ponto, hífen ou underscore",
)
.transform((key) => key.trim().toLowerCase()),
label: z
.string()
@@ -238,7 +241,10 @@ export const createSubscriptionTierSchema = z
.string()
.min(2, "Slug deve ter no mínimo 2 caracteres")
.max(50, "Slug deve ter no máximo 50 caracteres")
.regex(tierSlugRegex, "Slug deve conter apenas letras minúsculas, números e hífen")
.regex(
tierSlugRegex,
"Slug deve conter apenas letras minúsculas, números e hífen",
)
.transform((value) => value.trim().toLowerCase()),
description: z
.string()
@@ -267,7 +273,7 @@ export const createSubscriptionTierSchema = z
{
message: "Preço anual deve ser maior ou igual ao mensal",
path: ["priceYearly"],
}
},
);
export const updateSubscriptionTierSchema = createSubscriptionTierSchema
@@ -277,7 +283,10 @@ export const updateSubscriptionTierSchema = createSubscriptionTierSchema
.string()
.min(2, "Slug deve ter no mínimo 2 caracteres")
.max(50, "Slug deve ter no máximo 50 caracteres")
.regex(tierSlugRegex, "Slug deve conter apenas letras minúsculas, números e hífen")
.regex(
tierSlugRegex,
"Slug deve conter apenas letras minúsculas, números e hífen",
)
.transform((value) => value.trim().toLowerCase())
.optional(),
features: z
@@ -285,7 +294,7 @@ export const updateSubscriptionTierSchema = createSubscriptionTierSchema
subscriptionTierFeatureSchema.extend({
featureId: z.number().int().positive().optional(),
_delete: z.boolean().optional(),
})
}),
)
.max(50)
.optional(),
@@ -299,17 +308,17 @@ export const assignSubscriptionTierSchema = z
.string()
.min(2, "Slug deve ter no mínimo 2 caracteres")
.max(50, "Slug deve ter no máximo 50 caracteres")
.regex(tierSlugRegex, "Slug deve conter apenas letras minúsculas, números e hífen")
.regex(
tierSlugRegex,
"Slug deve conter apenas letras minúsculas, números e hífen",
)
.transform((value) => value.trim().toLowerCase())
.optional(),
})
.refine(
(data) => data.tierId !== undefined || data.tierSlug !== undefined,
{
message: "Informe tierId ou tierSlug",
path: ["tierId"],
}
);
.refine((data) => data.tierId !== undefined || data.tierSlug !== undefined, {
message: "Informe tierId ou tierSlug",
path: ["tierId"],
});
// Schema para registro de usuário
export const registerSchema = z.object({
@@ -361,159 +370,172 @@ export const characterSchema = z.object({
// ============================================
// Schema para criar anúncio (listing)
export const createListingSchema = z.object({
item_id: z.number().int().positive("ID do item deve ser positivo").optional(), // ID legado (SQLite) - opcional
item_id_unified: z.number().int().positive("ID unificado do item deve ser positivo").optional(), // ID unificado da tabela items - preferido
item_name: z
.string()
.min(1, "Nome do item é obrigatório")
.max(255, "Nome do item deve ter no máximo 255 caracteres")
.transform((name) => name.trim()),
quantity: z
.number()
.int()
.positive("Quantidade deve ser maior que zero")
.default(1),
server_name: z
.string()
.min(1, "Nome do servidor é obrigatório")
.max(50, "Nome do servidor deve ter no máximo 50 caracteres")
.transform((name) => name.trim()),
price_pix: z
.number()
.positive("Preço PIX deve ser positivo")
.optional()
.nullable(),
price_tibia_coins: z
.number()
.int()
.min(0, "Preço em Tibia Coins deve ser não negativo")
.optional()
.nullable(),
price_gold_coins: z
.number()
.int()
.min(0, "Preço em Gold Coins deve ser não negativo")
.optional()
.nullable(),
is_auction: z.boolean().optional().default(false),
auction_ends_at: z
.string()
.datetime("Data de término do leilão inválida")
.optional()
.nullable()
.transform((val) => (val ? new Date(val) : null)),
description: z
.string()
.max(5000, "Descrição deve ter no máximo 5000 caracteres")
.optional()
.nullable()
.transform((val) => val?.trim() || null),
// Campos para troca por item
trade_item_id: z
.number()
.int()
.positive("ID do item de troca deve ser positivo")
.optional()
.nullable(),
trade_item_name: z
.string()
.min(1, "Nome do item de troca é obrigatório se trade_item_id for fornecido")
.max(255, "Nome do item de troca deve ter no máximo 255 caracteres")
.optional()
.nullable()
.transform((name) => name?.trim() || null),
trade_item_quantity: z
.number()
.int()
.positive("Quantidade do item de troca deve ser maior que zero")
.optional()
.nullable()
.default(1),
})
.refine(
(data) => {
// Pelo menos um ID (item_id ou item_id_unified) deve ser fornecido
if (!data.item_id && !data.item_id_unified) {
return false;
}
return true;
},
{
message: "Pelo menos um ID do item (item_id ou item_id_unified) deve ser fornecido",
path: ["item_id"],
}
)
.refine(
(data) => {
// Se trade_item_id for fornecido, trade_item_name também deve ser
if (data.trade_item_id && !data.trade_item_name) {
return false;
}
return true;
},
{
message: "Nome do item de troca é obrigatório quando ID é fornecido",
path: ["trade_item_name"],
}
)
.refine(
(data) => {
// Pelo menos um preço ou troca por item deve ser fornecido
return (
data.price_pix !== null ||
data.price_tibia_coins !== null ||
data.price_gold_coins !== null ||
data.trade_item_id !== null
);
},
{
message: "Pelo menos um método de pagamento (PIX, Tibia Coins ou Gold Coins) deve ser especificado",
path: ["price_pix"],
}
).refine(
(data) => {
// Se for leilão, deve ter data de término
if (data.is_auction && !data.auction_ends_at) {
return false;
}
return true;
},
{
message: "Data de término do leilão é obrigatória quando is_auction é true",
path: ["auction_ends_at"],
}
);
export const createListingSchema = z
.object({
item_id: z
.number()
.int()
.positive("ID do item deve ser positivo")
.optional(), // ID legado (SQLite) - opcional
item_id_unified: z
.number()
.int()
.positive("ID unificado do item deve ser positivo")
.optional(), // ID unificado da tabela items - preferido
item_name: z
.string()
.min(1, "Nome do item é obrigatório")
.max(255, "Nome do item deve ter no máximo 255 caracteres")
.transform((name) => name.trim()),
quantity: z
.number()
.int()
.positive("Quantidade deve ser maior que zero")
.default(1),
server_name: z
.string()
.min(1, "Nome do servidor é obrigatório")
.max(50, "Nome do servidor deve ter no máximo 50 caracteres")
.transform((name) => name.trim()),
price_pix: z
.number()
.positive("Preço PIX deve ser positivo")
.optional()
.nullable(),
price_tibia_coins: z
.number()
.int()
.min(0, "Preço em Tibia Coins deve ser não negativo")
.optional()
.nullable(),
price_gold_coins: z
.number()
.int()
.min(0, "Preço em Gold Coins deve ser não negativo")
.optional()
.nullable(),
is_auction: z.boolean().optional().default(false),
auction_ends_at: z
.string()
.datetime("Data de término do leilão inválida")
.optional()
.nullable()
.transform((val) => (val ? new Date(val) : null)),
description: z
.string()
.max(5000, "Descrição deve ter no máximo 5000 caracteres")
.optional()
.nullable()
.transform((val) => val?.trim() || null),
// Campos para troca por item
trade_item_id: z
.number()
.int()
.positive("ID do item de troca deve ser positivo")
.optional()
.nullable(),
trade_item_name: z
.string()
.min(
1,
"Nome do item de troca é obrigatório se trade_item_id for fornecido",
)
.max(255, "Nome do item de troca deve ter no máximo 255 caracteres")
.optional()
.nullable()
.transform((name) => name?.trim() || null),
trade_item_quantity: z
.number()
.int()
.positive("Quantidade do item de troca deve ser maior que zero")
.optional()
.nullable()
.default(1),
})
.refine(
(data) => {
// Pelo menos um ID (item_id ou item_id_unified) deve ser fornecido
if (!data.item_id && !data.item_id_unified) {
return false;
}
return true;
},
{
message:
"Pelo menos um ID do item (item_id ou item_id_unified) deve ser fornecido",
path: ["item_id"],
},
)
.refine(
(data) => {
// Se trade_item_id for fornecido, trade_item_name também deve ser
if (data.trade_item_id && !data.trade_item_name) {
return false;
}
return true;
},
{
message: "Nome do item de troca é obrigatório quando ID é fornecido",
path: ["trade_item_name"],
},
)
.refine(
(data) => {
// Pelo menos um preço ou troca por item deve ser fornecido
return (
data.price_pix !== null ||
data.price_tibia_coins !== null ||
data.price_gold_coins !== null ||
data.trade_item_id !== null
);
},
{
message:
"Pelo menos um método de pagamento (PIX, Tibia Coins ou Gold Coins) deve ser especificado",
path: ["price_pix"],
},
)
.refine(
(data) => {
// Se for leilão, deve ter data de término
if (data.is_auction && !data.auction_ends_at) {
return false;
}
return true;
},
{
message:
"Data de término do leilão é obrigatória quando is_auction é true",
path: ["auction_ends_at"],
},
);
// Schema para atualizar anúncio
export const updateListingSchema = z.object({
quantity: z.number().int().positive().optional(),
price_pix: z.number().positive().optional().nullable(),
price_tibia_coins: z.number().int().min(0).optional().nullable(),
price_gold_coins: z.number().int().min(0).optional().nullable(),
description: z.string().max(5000).optional().nullable(),
listing_status: z
.enum(["active", "sold", "cancelled", "in_escrow", "expired"])
.optional(),
}).refine(
(data) => {
export const updateListingSchema = z
.object({
quantity: z.number().int().positive().optional(),
price_pix: z.number().positive().optional().nullable(),
price_tibia_coins: z.number().int().min(0).optional().nullable(),
price_gold_coins: z.number().int().min(0).optional().nullable(),
description: z.string().max(5000).optional().nullable(),
listing_status: z
.enum(["active", "sold", "cancelled", "in_escrow", "expired"])
.optional(),
})
.refine((data) => {
// Se atualizando preços, pelo menos um deve ser fornecido ou manter existentes
const hasPrice =
const _hasPrice =
data.price_pix !== undefined ||
data.price_tibia_coins !== undefined ||
data.price_gold_coins !== undefined;
return true; // Permite atualizar sem especificar preços (mantém existentes)
}
);
});
// Schema para criar lance (bid)
export const bidSchema = z.object({
listing_id: z.number().int().positive("ID do anúncio deve ser positivo"),
bid_amount: z.number().positive("Valor do lance deve ser positivo"),
bid_type: z
.enum(["pix", "tibia_coins", "gold_coins"])
.optional()
.nullable(),
bid_type: z.enum(["pix", "tibia_coins", "gold_coins"]).optional().nullable(),
});
// ============================================