← back to Dw Domain Fleet
scripts/pull-catalog.js
60 lines
#!/usr/bin/env node
/**
* pull-catalog.js — pull the full live designerwallcoverings.com Shopify catalog
* into data/catalog.json. All 66 fleet sites filter from this single snapshot.
*
* Live /products.json image URLs are guaranteed 200 at fetch time (dw-site-build
* standing rule: dw_unified snapshots have ~97% stale image URLs).
*/
const fs = require('fs');
const path = require('path');
const https = require('https');
const OUT = path.join(__dirname, '..', 'data', 'catalog.json');
function get(url) {
return new Promise((resolve, reject) => {
https.get(url, { headers: { 'User-Agent': 'dw-domain-fleet/1.0' } }, (res) => {
let body = '';
res.on('data', (c) => (body += c));
res.on('end', () => {
try { resolve(JSON.parse(body)); }
catch (e) { reject(new Error('bad JSON from ' + url)); }
});
}).on('error', reject);
});
}
(async () => {
const all = [];
for (let page = 1; page <= 60; page++) {
const url = `https://designerwallcoverings.com/products.json?limit=250&page=${page}`;
let data;
try { data = await get(url); }
catch (e) { console.error(`page ${page}: ${e.message}`); break; }
const prods = (data && data.products) || [];
if (!prods.length) break;
for (const p of prods) {
const img = (p.images && p.images[0] && p.images[0].src) || '';
const v0 = (p.variants && p.variants[0]) || {};
all.push({
id: p.id,
title: p.title || '',
handle: p.handle || '',
vendor: p.vendor || '',
product_type: p.product_type || '',
tags: Array.isArray(p.tags) ? p.tags : String(p.tags || '').split(',').map(s => s.trim()).filter(Boolean),
image_url: img,
sku: v0.sku || '',
price: v0.price || '',
created_at: p.created_at || '',
updated_at: p.updated_at || ''
});
}
process.stdout.write(`page ${page}: +${prods.length} (total ${all.length})\r`);
await new Promise(r => setTimeout(r, 250));
}
fs.writeFileSync(OUT, JSON.stringify(all));
console.log(`\nWrote ${all.length} products → ${OUT}`);
})();