← back to Fm Wallpaper Sync
sync.mjs
56 lines
#!/usr/bin/env node
// Nightly: pull ALL live FileMaker WALLPAPER records → /tmp/fm_wallpaper_full.csv
// Reuses the filemaker-mcp Claris-ID client. Read-only against FileMaker.
// Creds are read live from ~/.claude.json (no secret duplication).
import fs from 'fs';
import os from 'os';
import path from 'path';
const cfg = JSON.parse(fs.readFileSync(path.join(os.homedir(), '.claude.json'), 'utf8'));
const env = cfg.mcpServers?.filemaker?.env || {};
for (const [k, v] of Object.entries(env)) if (v != null) process.env[k] = String(v);
const fm = await import('/Users/macstudio3/Projects/filemaker-mcp/src/fm-client.js');
const DB = 'WALLPAPER', LAYOUT = 'Basic List of Fields', PAGE = 1000;
const OUT = process.argv[2] || '/tmp/fm_wallpaper_full.csv';
// FM field name -> CSV column
const F = [
['combo sku','combo_sku'], ['Series','series'], ['JS Pattern','js_pattern'],
['Mfr Pattern','mfr_pattern'], ['Supplier','supplier'], ['JPG Name','jpg_name'],
['Width','width'], ['Border','border'], ['Repeat','repeat'], ['Five Ten Code','five_ten'],
['Account #','account'], ['Line','line'], ['Minimum','minimum'],
['Date Line Put Up:','date_line'], ['Page','page'],
['Retail Price','retail'], ['Cost','cost'], ['Net Price','net'],
];
const HEADER = [...F.map(x => x[1]), 'record_id'];
const q = s => '"' + String(s ?? '').replace(/"/g, '""') + '"';
const out = fs.createWriteStream(OUT);
out.write(HEADER.join(',') + '\n');
let offset = 1, total = null, pages = 0, written = 0;
const t0 = Date.now();
while (true) {
let res, tries = 0;
while (true) {
try { res = await fm.listRecords(DB, LAYOUT, { limit: PAGE, offset }); break; }
catch (e) { if (++tries >= 4) throw e; await new Promise(r => setTimeout(r, 1500 * tries)); }
}
total = res?.dataInfo?.totalRecordCount ?? total;
const recs = res?.records || [];
if (!recs.length) break;
for (const r of recs) {
const fd = r.fieldData || {};
const row = F.map(([fmName]) => q(fd[fmName])).concat(q(r.recordId));
out.write(row.join(',') + '\n');
written++;
}
pages++; offset += PAGE;
if (pages % 25 === 0) console.error(` page ${pages} offset ${offset - 1}/${total} written=${written} ${((Date.now()-t0)/1000|0)}s`);
if (total && offset > total) break;
}
await new Promise(r => out.end(r));
console.error(`PULL DONE pages=${pages} total=${total} written=${written} -> ${OUT} (${((Date.now()-t0)/1000|0)}s)`);