← back to All Designerwallcoverings

scripts/adapters/woo-public.js

47 lines

// adapters/woo-public.js — PUBLIC-STOCK adapter for WooCommerce storefronts (WIRED, but the
// coverage file keeps these vendors DIMMED — live_capable:false — until a per-site verification
// confirms the WooCommerce Store API is exposed. Kept here so enabling is a one-flag change.)
//
// Reads the WooCommerce Store API (`/wp-json/wc/store/products?slug=<slug>`) in-page via the same
// Browserbase mechanism; `stock_status` = 'instock' | 'outofstock' | 'onbackorder'.
// PUBLIC-SAFE: availability only; price:null (vendor DTC, not our retail).
const { resolveCatalogUrl, releaseSession } = require('./resolve');

async function run({ sku, pool, newSession, catalogTable, log }) {
  let sessionOpened = false, browser = null, session = null, bb = null;
  try {
    const r = await resolveCatalogUrl(pool, catalogTable, sku);
    if (r.error) return { available: false, reason: r.error };
    const url = r.product_url;
    const m = /^https?:\/\/([^/]+)\/product\/([^/?#]+)/i.exec(url);
    if (!m) return { available: false, reason: 'not a WooCommerce product URL' };
    const [, host, slug] = m;
    const api = `https://${host}/wp-json/wc/store/products?slug=${encodeURIComponent(slug)}`;

    const sess = await newSession();
    ({ browser, session, bb } = sess); const page = sess.page;
    sessionOpened = true;
    log('bb session', session && session.id, '→', api);

    await page.goto(api, { waitUntil: 'domcontentloaded', timeout: 45000 });
    const txt = await page.evaluate(() => document.body && document.body.innerText).catch(() => null);
    let data = null; try { data = JSON.parse(txt); } catch { data = null; }
    const item = Array.isArray(data) ? data[0] : (data && data.id ? data : null);
    if (!item) return { available: false, session_opened: true, reason: 'WooCommerce Store API not exposed / no match' };

    const st = String(item.stock_status || '').toLowerCase();
    const in_stock = st === 'instock' ? true : st === 'outofstock' ? false : (st === 'onbackorder' ? false : null);
    return {
      available: true, session_opened: true, vendor: null,
      in_stock, lead_time: st === 'onbackorder' ? 'backorder' : null, price: null,
      raw_stock_label: st || 'unknown', as_of: new Date().toISOString(), source: 'woo-public-live',
    };
  } catch (e) {
    return { available: false, session_opened: sessionOpened, reason: 'live scrape error: ' + (e.message || e) };
  } finally {
    await releaseSession({ browser, bb, session });
  }
}

module.exports = { run };