← back to Designer Portfolio Pages
src/stevesTool.ts
84 lines
import type { PatternSnapshot } from "./schemas.js";
const SHOPIFY_STORE = "designer-laboratory-sandbox.myshopify.com";
const SHOPIFY_TOKEN = (process.env.SHOPIFY_ADMIN_TOKEN || '');
function shopifyApiUrl(endpoint: string): string {
return `https://${SHOPIFY_STORE}/admin/api/2024-01/${endpoint}`;
}
function shopifyHeaders(): Record<string, string> {
return {
"X-Shopify-Access-Token": SHOPIFY_TOKEN,
"Content-Type": "application/json"
};
}
function mapProduct(p: any): PatternSnapshot | null {
const image = p.images?.[0];
if (!image?.src) return null;
const tags = typeof p.tags === "string"
? p.tags.split(",").map((t: string) => t.trim()).filter(Boolean).slice(0, 6)
: [];
return {
id: String(p.id),
name: p.title || "Untitled",
imageUrl: image.src,
productUrl: `https://${SHOPIFY_STORE}/products/${p.handle}`,
tags
};
}
/**
* Search Shopify products by title query.
*/
export async function getPatternsByQuery(q: string): Promise<PatternSnapshot[]> {
const query = q.trim();
// If empty query, return recent products with images
const titleFilter = query ? `&title=${encodeURIComponent(query)}` : "";
const url = shopifyApiUrl(`products.json?limit=40&status=active&fields=id,title,handle,tags,images${titleFilter}`);
const res = await fetch(url, { headers: shopifyHeaders() });
if (!res.ok) {
throw new Error(`Shopify search failed: ${res.status} ${res.statusText}`);
}
const data = await res.json();
const products = (data.products ?? [])
.map(mapProduct)
.filter((p: PatternSnapshot | null): p is PatternSnapshot => p !== null);
return products;
}
/**
* Fetch specific Shopify products by their IDs.
*/
export async function getPatternsByIds(ids: string[]): Promise<PatternSnapshot[]> {
const unique = [...new Set(ids.map(s => s.trim()).filter(Boolean))];
if (!unique.length) return [];
// Shopify allows fetching by comma-separated IDs
const idsParam = unique.join(",");
const url = shopifyApiUrl(`products.json?ids=${idsParam}&fields=id,title,handle,tags,images`);
const res = await fetch(url, { headers: shopifyHeaders() });
if (!res.ok) {
throw new Error(`Shopify fetch by IDs failed: ${res.status} ${res.statusText}`);
}
const data = await res.json();
const products = (data.products ?? [])
.map(mapProduct)
.filter((p: PatternSnapshot | null): p is PatternSnapshot => p !== null);
// Preserve requested order
const map = new Map(products.map((p: PatternSnapshot) => [p.id, p]));
return unique.map(id => map.get(id)).filter(Boolean) as PatternSnapshot[];
}