// Toom-Adapter (Muster wie OBI: Produktseite → Preis via JSON-LD + Markt-Status-Heuristik). // TODO: products{} mit echten Produkt-URLs/Artikelnummern füllen; Per-Markt-Endpoint ergänzen. const UA = 'KuehlfinderBot/0.1 (+https://kuehlfinder.de/bot)'; export const meta = { id: 'toom', name: 'Toom', kind: 'baumarkt' }; export const products = { /* 'portasplit': 'https://www....' */ }; function jsonld(html){const o=[];const re=/]+application\/ld\+json[^>]*>([\s\S]*?)<\/script>/gi;let m;while((m=re.exec(html))){try{o.push(JSON.parse(m[1]));}catch{}}return o;} function offer(ld){for(const n of (Array.isArray(ld)?ld:[ld])){const g=n['@graph']||[n];for(const x of g){if(x&&(x['@type']==='Product'||x.offers)){const of=Array.isArray(x.offers)?x.offers[0]:x.offers;if(of)return{price:Number(of.price??of.lowPrice),availability:String(of.availability||'')};}}}return null;} export async function fetchProduct(productId,{marketId}={}){ const url=products[productId]; if(!url) return null; const res=await fetch(url,{headers:{'User-Agent':UA,'Accept-Language':'de-DE'}}); if(!res.ok) throw new Error('Toom '+res.status); const html=await res.text(); const o=jsonld(html).map(offer).find(Boolean); const inStore=/vorrätig|verfügbar/i.test(html)&&!/nicht (vorrätig|verfügbar)/i.test(html); const price=o?.price ?? Number((html.match(/(\d{2,4})[,.](\d{2})\s*€/)||[])[0]?.replace(/[^\d,]/g,'').replace(',','.')); return { productId, source:'toom', marketId:marketId??null, price: price||null, availability: inStore?'in_stock':(o&&/InStock/i.test(o.availability)?'online_available':'out_of_stock'), checkedAt:new Date().toISOString(), url }; } export async function fetchStores(){ return []; }