← 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[];
}