refactor(db): typed query helpers, shared test FormData helper
CI / check (push) Successful in 4m10s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m4s

Replace raw db.execute tuple casts with queryRows/rowsFrom/execResult/
affectedRows helpers from lib/db, drop redundant mysql2 casts on typed
query builders, and centralize per-test fakeForm into test/fake-form.
Update db mocks in tests so helpers resolve against mocked execute.
This commit is contained in:
openhands committed 2026-09-17 21:02:57 +02:00
1 parent 2e25b39364
commit 8638e81444
116 files changed
+866 -897

No files matched your search

+10 -15
View File
@@ -1,7 +1,7 @@
import { promises as fs } from "node:fs";
import { asc, sql } from "drizzle-orm";
import { numericValue } from "@/features/catalog/domain/offer-input";
import { CatalogPages, db } from "@/lib/db";
import { CatalogPages, db, queryRows } from "@/lib/db";
import { getFurnitureDataPath } from "@/lib/services/furni-data";
import { getHabboGamedataHotel } from "@/lib/services/habbo-gamedata-hotel";
@@ -140,12 +140,12 @@ export async function loadCatalogItemsData(
// Load items via raw query to work around pageId Int vs VARCHAR mismatch
const pageIdStr = String(pageId);
// CAST: live Habbo DBs often store page_id as VARCHAR while schema maps Int.
const [rawItems] = (await db.execute(sql`
const rawItems = await queryRows<Record<string, unknown>>(sql`
SELECT * FROM catalog_items
WHERE CAST(page_id AS CHAR) = ${pageIdStr}
ORDER BY order_number ASC, id ASC
`)) as unknown as [Record<string, unknown>[], unknown[]];
const items: RawItem[] = rawItems.map((r: Record<string, unknown>) => ({
`);
const items: RawItem[] = rawItems.map((r) => ({
id: Number(r.id),
itemIds: String(r.item_ids ?? ""),
pageId: numericValue(r.page_id, 0),
@@ -169,14 +169,9 @@ export async function loadCatalogItemsData(
.select({ id: CatalogPages.id, caption: CatalogPages.caption })
.from(CatalogPages)
.orderBy(asc(CatalogPages.caption)),
db
.execute(sql`
queryRows<{ interaction_type: string }>(sql`
SELECT DISTINCT interaction_type FROM items_base ORDER BY interaction_type ASC
`)
.then(
(result) =>
(result as unknown as [{ interaction_type: string }[], unknown[]])[0],
),
`),
getHabboGamedataHotel(),
]);
@@ -199,9 +194,9 @@ export async function loadCatalogItemsData(
// Raw query to work around ENUM('0','1') columns returning numeric values.
// baseItemIds is built from numeric splits + filter(n > 0); joined via sql.join.
const [baseItemRows] =
const baseItemRows =
baseItemIds.length > 0
? ((await db.execute(sql`
? await queryRows<Record<string, unknown>>(sql`
SELECT id, sprite_id, public_name, item_name, type, width, length,
stack_height, allow_stack, allow_sit, allow_lay, allow_walk,
allow_gift, allow_trade, allow_recycle, allow_marketplace_sell,
@@ -209,8 +204,8 @@ export async function loadCatalogItemsData(
vending_ids, customparams, effect_id_male, effect_id_female,
clothing_on_walk
FROM items_base WHERE id IN (${sql.join(baseItemIds, sql`, `)})
`)) as unknown as [Record<string, unknown>[], unknown[]])
: [[], []];
`)
: [];
const baseItems: BaseItem[] = baseItemRows.map((r) => ({
id: Number(r.id),