#!/usr/bin/env ts-node import path from 'path'; import fs from 'fs/promises'; import { gameDB } from "../routes/games/store"; async function main() { const gamesDir = path.resolve(__dirname, "../../db/games"); let files: string[] = []; try { files = await fs.readdir(gamesDir); } catch (e) { console.error("Failed to read games dir", gamesDir, e); process.exit(2); } if (!gameDB.db) { await gameDB.init(); } let db = gameDB.db; if (!db.sequelize) { console.error("DB did not expose sequelize; cannot proceed."); process.exit(4); } for (const f of files) { // ignore dotfiles and .bk backup files (we don't want to import backups) if (f.startsWith(".") || f.endsWith(".bk")) continue; const full = path.join(gamesDir, f); try { const stat = await fs.stat(full); if (!stat.isFile()) continue; const raw = await fs.readFile(full, "utf8"); const game = JSON.parse(raw); // Derive id from filename (strip .json if present) const idStr = f.endsWith(".json") ? f.slice(0, -5) : f; const id = isNaN(Number(idStr)) ? idStr : Number(idStr); // derive a friendly name from the saved game when present const nameCandidate = game && (game.name || game.id) ? String(game.name || game.id) : undefined; try { if (typeof id === "number") { // numeric filename: use the typed helper await db.saveGame(game); console.log(`Saved game id=${id}`); if (nameCandidate) { try { await db.sequelize.query("UPDATE games SET name=:name WHERE id=:id", { replacements: { id, name: nameCandidate }, }); } catch (_) { // ignore name update failure } } } else { // string filename: try to find an existing row by path and save via id; // otherwise insert a new row with path and the JSON game. let found: any[] = []; try { found = await db.sequelize.query("SELECT id FROM games WHERE path=:path", { replacements: { path: idStr }, type: db.Sequelize.QueryTypes.SELECT, }); } catch (qe) { found = []; } if (found && found.length) { const foundId = found[0].id; await db.saveGame(game); console.log(`Saved game path=${idStr} -> id=${foundId}`); if (nameCandidate) { try { await db.sequelize.query("UPDATE games SET name=:name WHERE id=:id", { replacements: { id: foundId, name: nameCandidate }, }); } catch (_) { // ignore } } } else { // ensure state column exists before inserting a new row try { await db.sequelize.query("ALTER TABLE games ADD COLUMN state TEXT"); } catch (_) { // ignore } const payload = JSON.stringify(game); if (nameCandidate) { await db.sequelize.query("INSERT INTO games (path, state, name) VALUES(:path, :state, :name)", { replacements: { path: idStr, state: payload, name: nameCandidate }, }); } else { await db.sequelize.query("INSERT INTO games (path, state) VALUES(:path, :state)", { replacements: { path: idStr, state: payload }, }); } console.log(`Inserted game path=${idStr}`); } } } catch (e) { console.error("Failed to save game", idStr, e); } } catch (e) { console.error("Failed to read/parse", full, e); } } console.log("Import complete"); process.exit(0); } main();