← 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); });