style: clean up code formatting and remove trailing whitespace
refactor: reorganize imports and fix type imports
This commit is contained in:
1 parent
d3704602fd
commit
47c04de6fe
232 files changed
+7140
-4798
No files matched your search
+57
-30
@@ -30,7 +30,7 @@ function getDatabase() {
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
Database = require("better-sqlite3");
|
||||
} catch (err) {
|
||||
} catch (_err) {
|
||||
// Retorna null para permitir fallback silencioso (API responde vazio ao invés de 500)
|
||||
return null as any;
|
||||
}
|
||||
@@ -41,7 +41,10 @@ function getDatabase() {
|
||||
}
|
||||
|
||||
// Tenta deduzir ordenação segura a partir do parâmetro de sort
|
||||
function getOrderBy(sort: SearchParams["sort"], vocation?: string): { sql: string; bindings: any[] } {
|
||||
function getOrderBy(
|
||||
sort: SearchParams["sort"],
|
||||
_vocation?: string,
|
||||
): { sql: string; bindings: any[] } {
|
||||
// Ordenação sem prioridade de vocação (filtro de voc estrito cuida apenas do WHERE)
|
||||
switch (sort) {
|
||||
case "level-asc":
|
||||
@@ -54,7 +57,6 @@ function getOrderBy(sort: SearchParams["sort"], vocation?: string): { sql: strin
|
||||
return { sql: "weight DESC, name ASC", bindings: [] };
|
||||
case "category":
|
||||
return { sql: "category ASC, name ASC", bindings: [] };
|
||||
case "name":
|
||||
default:
|
||||
return { sql: "name ASC", bindings: [] };
|
||||
}
|
||||
@@ -107,17 +109,22 @@ export function searchItems<T = any>(params: SearchParams): SearchResult<T> {
|
||||
bindings.push(...rarities.map((r) => r.toLowerCase()));
|
||||
}
|
||||
|
||||
const { sql: orderBy, bindings: orderBindings } = getOrderBy(sort, vocation);
|
||||
const { sql: orderBy, bindings: orderBindings } = getOrderBy(
|
||||
sort,
|
||||
vocation,
|
||||
);
|
||||
|
||||
// Seleciona de múltiplas tabelas (PT) unificando shape padronizado
|
||||
const allTables = db
|
||||
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name <> 'sqlite_sequence'")
|
||||
.prepare(
|
||||
"SELECT name FROM sqlite_master WHERE type='table' AND name <> 'sqlite_sequence'",
|
||||
)
|
||||
.all() as { name: string }[];
|
||||
// Filtra por categorias solicitadas (EN → PT); caso vazio, usa todas
|
||||
const allowedPt = new Set(
|
||||
(categories.length > 0
|
||||
categories.length > 0
|
||||
? categories.map((en) => enToPtCategoryMap[en] || en)
|
||||
: allTables.map((t) => t.name))
|
||||
: allTables.map((t) => t.name),
|
||||
);
|
||||
const candidateTables = allTables
|
||||
.map((t) => t.name)
|
||||
@@ -128,9 +135,16 @@ export function searchItems<T = any>(params: SearchParams): SearchResult<T> {
|
||||
for (const t of candidateTables) {
|
||||
try {
|
||||
const cols = db.prepare(`PRAGMA table_info(${t})`).all() as any[];
|
||||
const colNames = new Set(cols.map((c) => (c?.name || "").toLowerCase()));
|
||||
const colNames = new Set(
|
||||
cols.map((c) => (c?.name || "").toLowerCase()),
|
||||
);
|
||||
// Requer colunas mínimas
|
||||
if (!colNames.has("id") || !colNames.has("nome") || !colNames.has("image_url")) continue;
|
||||
if (
|
||||
!colNames.has("id") ||
|
||||
!colNames.has("nome") ||
|
||||
!colNames.has("image_url")
|
||||
)
|
||||
continue;
|
||||
// Se filtro de vocação foi solicitado e a tabela não possui coluna 'voc', ignora esta tabela
|
||||
if (vocation && !colNames.has("voc")) {
|
||||
continue;
|
||||
@@ -147,16 +161,22 @@ export function searchItems<T = any>(params: SearchParams): SearchResult<T> {
|
||||
tableWhere.push("REPLACE(LOWER(voc), ' ', '') = REPLACE(?, ' ', '')");
|
||||
unionBindings.push(sel);
|
||||
}
|
||||
const whereSqlTbl = tableWhere.length ? `WHERE ${tableWhere.join(" AND ")}` : "";
|
||||
const whereSqlTbl = tableWhere.length
|
||||
? `WHERE ${tableWhere.join(" AND ")}`
|
||||
: "";
|
||||
// category: derivamos do nome da tabela (pt)
|
||||
const levelCol = colNames.has("nivel") || colNames.has("lvl")
|
||||
? `COALESCE(${colNames.has("nivel") ? "nivel" : "NULL"}, ${colNames.has("lvl") ? "lvl" : "NULL"})`
|
||||
: "NULL";
|
||||
const weightCol = colNames.has("peso") || colNames.has("peso_em_oz")
|
||||
? `COALESCE(${colNames.has("peso") ? "peso" : "NULL"}, ${colNames.has("peso_em_oz") ? "peso_em_oz" : "NULL"})`
|
||||
: "NULL";
|
||||
const levelCol =
|
||||
colNames.has("nivel") || colNames.has("lvl")
|
||||
? `COALESCE(${colNames.has("nivel") ? "nivel" : "NULL"}, ${colNames.has("lvl") ? "lvl" : "NULL"})`
|
||||
: "NULL";
|
||||
const weightCol =
|
||||
colNames.has("peso") || colNames.has("peso_em_oz")
|
||||
? `COALESCE(${colNames.has("peso") ? "peso" : "NULL"}, ${colNames.has("peso_em_oz") ? "peso_em_oz" : "NULL"})`
|
||||
: "NULL";
|
||||
const slotsCol = colNames.has("slots") ? "slots" : "NULL";
|
||||
const skillCol = colNames.has("skill_para_usar") ? "skill_para_usar" : "NULL";
|
||||
const skillCol = colNames.has("skill_para_usar")
|
||||
? "skill_para_usar"
|
||||
: "NULL";
|
||||
// Campos extras opcionais por tabela (ex.: aljavas)
|
||||
const extraCols = [
|
||||
"lvl",
|
||||
@@ -178,8 +198,8 @@ export function searchItems<T = any>(params: SearchParams): SearchResult<T> {
|
||||
${levelCol} AS level,
|
||||
${weightCol} AS weight,
|
||||
${slotsCol} AS slots,
|
||||
${skillCol} AS skill${extraSelect ? ",\n " + extraSelect : ""}
|
||||
FROM ${t} ${whereSqlTbl}`
|
||||
${skillCol} AS skill${extraSelect ? `,\n ${extraSelect}` : ""}
|
||||
FROM ${t} ${whereSqlTbl}`,
|
||||
);
|
||||
} catch (e) {
|
||||
console.warn(`[items-db] Ignorando tabela ${t}:`, (e as any)?.message);
|
||||
@@ -193,12 +213,14 @@ export function searchItems<T = any>(params: SearchParams): SearchResult<T> {
|
||||
|
||||
const unionSql = selects.join(" UNION ALL ");
|
||||
// Contagem total
|
||||
const totalStmt = db.prepare(`SELECT COUNT(1) as cnt FROM (${unionSql}) AS u`);
|
||||
const totalStmt = db.prepare(
|
||||
`SELECT COUNT(1) as cnt FROM (${unionSql}) AS u`,
|
||||
);
|
||||
const totalRow = totalStmt.get(...unionBindings) as { cnt: number };
|
||||
const total = totalRow?.cnt ?? 0;
|
||||
|
||||
const selectStmt = db.prepare(
|
||||
`SELECT * FROM (${unionSql}) AS u ORDER BY ${orderBy} LIMIT ? OFFSET ?`
|
||||
`SELECT * FROM (${unionSql}) AS u ORDER BY ${orderBy} LIMIT ? OFFSET ?`,
|
||||
);
|
||||
const items = selectStmt.all(...unionBindings, safePageSize, offset) as T[];
|
||||
|
||||
@@ -225,28 +247,33 @@ export function getItemById(itemId: number, itemName?: string): any | null {
|
||||
try {
|
||||
// Buscar em todas as tabelas de categorias
|
||||
const tables = db
|
||||
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'")
|
||||
.prepare(
|
||||
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'",
|
||||
)
|
||||
.all() as { name: string }[];
|
||||
|
||||
for (const table of tables) {
|
||||
try {
|
||||
let item: any = null;
|
||||
|
||||
|
||||
// Se itemName foi fornecido, buscar por ID E NOME (case-insensitive)
|
||||
if (itemName) {
|
||||
item = db.prepare(`SELECT * FROM ${table.name} WHERE id = ? AND LOWER(nome) = LOWER(?)`).get(itemId, itemName);
|
||||
item = db
|
||||
.prepare(
|
||||
`SELECT * FROM ${table.name} WHERE id = ? AND LOWER(nome) = LOWER(?)`,
|
||||
)
|
||||
.get(itemId, itemName);
|
||||
} else {
|
||||
// Se não há nome, buscar apenas por ID (comportamento antigo)
|
||||
item = db.prepare(`SELECT * FROM ${table.name} WHERE id = ?`).get(itemId);
|
||||
item = db
|
||||
.prepare(`SELECT * FROM ${table.name} WHERE id = ?`)
|
||||
.get(itemId);
|
||||
}
|
||||
|
||||
|
||||
if (item) {
|
||||
return item;
|
||||
}
|
||||
} catch (err) {
|
||||
// Ignorar erros de tabelas que não têm coluna 'id' ou 'nome'
|
||||
continue;
|
||||
}
|
||||
} catch (_err) {}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
Reference in new issue
Block a user