import { z } from "zod"; const BestBuyProductSchema = z.object({ sku: z.number(), name: z.string(), salePrice: z.number().nullable(), regularPrice: z.number(), customerReviewAverage: z.number().nullable(), customerReviewCount: z.number().nullable(), image: z.string().nullable(), url: z.string(), longDescription: z.string().nullable(), }); export type BestBuyProduct = z.infer; export async function fetchBestBuyProduct( searchTerm: string, apiKey: string, ): Promise { const fields = "sku,name,salePrice,regularPrice,customerReviewAverage,customerReviewCount,image,url,longDescription"; const searchUrl = `https://api.bestbuy.com/v1/products((search=${encodeURIComponent(searchTerm)}))?apiKey=${apiKey}&format=json&show=${fields}&pageSize=5`; const res = await fetch(searchUrl); if (!res.ok) { console.warn( `[bestbuy] HTTP ${res.status} for "${searchTerm}"`, ); return null; } const data = await res.json(); if (!data.products?.length) { console.warn(`[bestbuy] No results for "${searchTerm}"`); return null; } try { return BestBuyProductSchema.parse(data.products[0]); } catch { console.warn(`[bestbuy] Parse error for "${searchTerm}"`); return null; } } export async function fetchAllBestBuy( searchTerms: { name: string; term: string }[], apiKey: string, ): Promise> { const results = new Map(); for (const { name, term } of searchTerms) { const product = await fetchBestBuyProduct(term, apiKey); if (product) { results.set(name, product); } await new Promise((r) => setTimeout(r, 250)); } return results; }