/** * Export all application tables from the local (source) database to a JSON * file, preserving column types for the matching import-data.mjs script. * * Usage (from apps/api, against the local DB in .env): * node scripts/export-data.mjs */ import { PrismaClient } from '@prisma/client'; import { writeFileSync } from 'node:fs'; const TABLES = [ 'users', 'countries', 'categories', 'tag_groups', 'tags', 'positions', 'origin_goods', 'origin_good_variants', 'origin_good_details', 'goods', 'good_tags', 'sync_logs', ]; const prisma = new PrismaClient(); // Serialize values losslessly; import side uses information_schema to restore types. function serialize(value) { if (value === null || value === undefined) return null; if (typeof value === 'bigint') return value.toString(); if (value instanceof Date) return value.toISOString(); if (typeof value === 'object' && Buffer.isBuffer(value)) return value.toString('base64'); if (typeof value === 'object') return JSON.stringify(value); // jsonb return value; } async function main() { const out = process.argv[2]; if (!out) { console.error('Usage: node scripts/export-data.mjs '); process.exit(1); } const dump = { exportedAt: new Date().toISOString(), tables: {} }; for (const table of TABLES) { const rows = await prisma.$queryRawUnsafe(`SELECT * FROM "${table}"`); dump.tables[table] = rows.map((row) => { const o = {}; for (const [k, v] of Object.entries(row)) o[k] = serialize(v); return o; }); console.log(`${table}: ${rows.length} rows`); } writeFileSync(out, JSON.stringify(dump)); console.log(`Wrote ${out}`); } main() .catch((e) => { console.error(e); process.exit(1); }) .finally(() => prisma.$disconnect());