Files
shd.build/scripts/isac-data-export.mjs
T
JB 548d19d9ea
Validate and deploy staging / validate (push) Successful in 27s
Validate and deploy staging / deploy (push) Successful in 52s
Add containerized staging deployment
2026-07-26 10:31:24 -04:00

49 lines
2.1 KiB
JavaScript

import { connect } from '@tursodatabase/database';
import { mkdir, readFile, writeFile } from 'node:fs/promises';
import { basename, dirname, join, resolve } from 'node:path';
import process from 'node:process';
import { ISAC_DATA_TABLES, quoteIdentifier } from './isac-data-tables.mjs';
const databasePath = resolve(process.env.TDR_DATABASE_PATH || './data/shd-build-development.db');
const iconDirectory = resolve(process.env.TDR_GAME_ICON_STORAGE_PATH || './data/game-icons');
const timestamp = new Date().toISOString().replaceAll(':', '-').replace(/\.\d{3}Z$/, 'Z');
const outputPath = resolve(process.argv[2] || `./data/backups/isac-data-${timestamp}.json`);
const database = await connect(databasePath);
const tables = [];
let totalRows = 0;
for (const name of ISAC_DATA_TABLES) {
const exists = await (await database.prepare(
"SELECT 1 AS present FROM sqlite_master WHERE type='table' AND name=?"
)).get(name);
if (!exists) throw new Error(`ISAC export requires missing table "${name}". Run the schema migration first.`);
const rows = await (await database.prepare(`SELECT * FROM ${quoteIdentifier(name)}`)).all();
tables.push({ name, rowCount: rows.length, rows });
totalRows += rows.length;
}
const icons = [];
const iconTable = tables.find((table) => table.name === 'game_data_icons');
for (const row of iconTable?.rows ?? []) {
if (typeof row.storage_key !== 'string' || !/^[a-z_]+-[0-9a-f-]{36}\.webp$/i.test(row.storage_key)) {
throw new Error(`Invalid game-data icon storage key "${String(row.storage_key)}".`);
}
const content = await readFile(join(iconDirectory, row.storage_key));
icons.push({ storageKey: row.storage_key, contentBase64: content.toString('base64') });
}
const snapshot = {
format: 'shd-build-isac-data',
version: 1,
createdAt: new Date().toISOString(),
sourceDatabase: basename(databasePath),
totalRows,
tables,
icons
};
await mkdir(dirname(outputPath), { recursive: true });
await writeFile(outputPath, `${JSON.stringify(snapshot, null, 2)}\n`, { encoding: 'utf8', flag: 'wx' });
console.log(`Exported ${totalRows} ISAC rows and ${icons.length} uploaded icons.`);
console.log(`ISAC snapshot: ${outputPath}`);