feat(ecommerce): migrate Ari Shopping to Next.js 15 headless storefront v4
Build and Push Frontend / build (push) Failing after 5m39s

This commit is contained in:
2026-07-19 19:37:41 -05:00
parent 383b644929
commit f263a9cc55
76 changed files with 1607 additions and 0 deletions
@@ -0,0 +1,45 @@
import type { CatalogProvider, Product } from "@/lib/headless/types";
interface ShopifyGraphQLResponse<T> {
data?: T;
errors?: Array<{ message: string }>;
}
async function shopifyFetch<T>(query: string, variables: Record<string, unknown> = {}): Promise<T> {
const url = process.env.SHOPIFY_STOREFRONT_URL;
const token = process.env.SHOPIFY_STOREFRONT_TOKEN;
if (!url || !token) throw new Error("Shopify Storefront API no está configurada.");
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Shopify-Storefront-Access-Token": token,
},
body: JSON.stringify({ query, variables }),
next: { revalidate: 300 },
});
if (!response.ok) throw new Error(`Shopify respondió HTTP ${response.status}`);
const payload = (await response.json()) as ShopifyGraphQLResponse<T>;
if (payload.errors?.length) throw new Error(payload.errors.map((error) => error.message).join("; "));
if (!payload.data) throw new Error("Shopify no devolvió datos.");
return payload.data;
}
function notImplemented(): never {
throw new Error("Completa el mapeo Shopify → Product en lib/headless/providers/shopify.ts.");
}
export const shopifyCatalogProvider: CatalogProvider = {
async getProducts() {
await shopifyFetch<{ products: unknown }>(`query Products { products(first: 24) { nodes { id title handle } } }`);
return notImplemented();
},
async getProductBySlug(): Promise<Product | null> {
return notImplemented();
},
async searchProducts(): Promise<Product[]> {
return notImplemented();
},
};