← back to Designer Wallcoverings
onboarding/sangetsu-lilycolor/lily-feed-recon.cjs
55 lines
#!/usr/bin/env node
/**
* Lilycolor feed-first recon — READ-ONLY.
* Pulls the live Shopify products.json feed and reports counts, SKU prefixes,
* and grasscloth/cane candidates. Does NOT write anywhere, does NOT touch Shopify/dw_unified.
*
* Usage: node lily-feed-recon.cjs [maxPages]
*/
const https = require('https');
const BASE = 'https://shop.lilycolor.co.jp/products.json';
const maxPages = parseInt(process.argv[2] || '6', 10);
function get(url) {
return new Promise((resolve, reject) => {
https.get(url, { headers: { 'User-Agent': 'Mozilla/5.0 (DW-recon)' } }, (res) => {
let body = '';
res.on('data', (c) => (body += c));
res.on('end', () => {
try { resolve(JSON.parse(body)); } catch (e) { reject(e); }
});
}).on('error', reject);
});
}
(async () => {
const all = [];
for (let page = 1; page <= maxPages; page++) {
const d = await get(`${BASE}?limit=250&page=${page}`);
const ps = (d && d.products) || [];
if (!ps.length) break;
all.push(...ps);
process.stderr.write(`page ${page}: +${ps.length} (total ${all.length})\n`);
}
const prefixes = {};
const naturals = [];
for (const p of all) {
for (const v of p.variants || []) {
const m = String(v.sku || '').match(/^([A-Za-z]+)/);
if (m) prefixes[m[1].toUpperCase()] = (prefixes[m[1].toUpperCase()] || 0) + 1;
}
if (/グラスクロス|麻|籐|cane|grass|和紙|織物/i.test(p.title)) {
naturals.push({ title: p.title, handle: p.handle });
}
}
console.log(JSON.stringify({
totalProducts: all.length,
pagesPulled: Math.min(maxPages, Math.ceil(all.length / 250)),
variantSkuPrefixes: prefixes,
naturalTextureCandidates: naturals.slice(0, 40),
}, null, 2));
})().catch((e) => { console.error('FAILED:', e.message); process.exit(1); });