← back to Fineartamerica Price Sync
bin/faa-fetch-all.js
46 lines
#!/usr/bin/env node
// Fetch FAA costs for EVERY FAA-signature product on the store (free HTTP).
// Framed cost is artwork-independent (verified: same size/frame/mat/finish =>
// same price across artworks), so we price each distinct config SIGNATURE once
// and map it onto every variant's configKey — ~36 fetches instead of ~468.
const { openSession, priceFramedConfig } = require('../lib/faa-http');
const { parseSku, configKey } = require('../lib/parse-sku');
const { loadCache, saveCache } = require('../lib/faa-cost');
const { listFaaProducts } = require('../lib/shopify');
// Per-artwork page URL — size ladders are artwork-aspect-specific, so each
// artwork needs its own configurator session (verified: seeding all off one
// artwork drops the odd-aspect sizes like 24x30/32x40).
const artUrl = id => `https://fineartamerica.com/art/${id}`;
(async () => {
const ps = await listFaaProducts();
const byArtwork = new Map(); // artworkid -> distinct cfgs (deduped)
let total = 0;
for (const p of ps) for (const v of p.variants) {
const c = parseSku(v.sku); if (!c) continue;
total++;
const a = c.artworkid || 'NONE';
if (!byArtwork.has(a)) byArtwork.set(a, new Map());
byArtwork.get(a).set(configKey(c), c);
}
console.log(`${ps.length} FAA products, ${total} variants across ${byArtwork.size} artworks`);
const cache = loadCache();
let priced = 0, failed = 0;
for (const [artworkId, cfgs] of byArtwork) {
const s = await openSession(artUrl(artworkId));
let a = 0, f = 0;
for (const c of cfgs.values()) {
if (c.productid !== 'printframed') { f++; continue; }
const cost = await priceFramedConfig(s, c);
if (cost != null) { cache[configKey(c)] = cost; a++; } else f++;
}
priced += a; failed += f;
console.log(` artwork ${artworkId}: ${a} priced, ${f} failed`);
saveCache(cache); // checkpoint after each artwork
}
console.log(`\npriced ${priced} variants (${failed} failed) across ${byArtwork.size} artworks. ($0 — free HTTP)`);
})().catch(e => { console.error(e); process.exit(1); });