feat: client Shopify Admin REST API (search + upload)

This commit is contained in:
2026-06-08 16:21:55 +02:00
parent c97a7faaa9
commit 9675366db9
+80
View File
@@ -0,0 +1,80 @@
const API_VERSION = '2024-01'
function getConfig() {
const domain = process.env.SHOPIFY_STORE_DOMAIN
const token = process.env.SHOPIFY_ADMIN_API_TOKEN
if (!domain || !token) {
throw new Error('SHOPIFY_STORE_DOMAIN et SHOPIFY_ADMIN_API_TOKEN requis')
}
return {
baseUrl: `https://${domain}/admin/api/${API_VERSION}`,
headers: {
'X-Shopify-Access-Token': token,
'Content-Type': 'application/json',
},
}
}
export type ShopifyProductResult =
| { found: false }
| { found: true; shopifyId: string; title: string }
/**
* Recherche un produit Shopify par sa référence.
* Tente d'abord par handle (ex: "ref-1042"), puis par titre exact.
*/
export async function searchProductByRef(ref: string): Promise<ShopifyProductResult> {
const { baseUrl, headers } = getConfig()
// Normalise la référence en handle Shopify (minuscules, tirets)
const handle = ref.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '')
const tryFetch = async (params: string) => {
const res = await fetch(`${baseUrl}/products.json?${params}&fields=id,title,handle&limit=1`, { headers })
if (!res.ok) throw new Error(`Shopify API error: ${res.status}`)
const data = await res.json()
return (data.products ?? []) as Array<{ id: number; title: string; handle: string }>
}
let products = await tryFetch(`handle=${encodeURIComponent(handle)}`)
if (products.length === 0) {
products = await tryFetch(`title=${encodeURIComponent(ref)}`)
}
if (products.length === 0) return { found: false }
return {
found: true,
shopifyId: String(products[0].id),
title: products[0].title,
}
}
/**
* Upload une image (base64) vers un produit Shopify via l'API REST.
* @param shopifyProductId — ID numérique du produit (string)
* @param imageBase64 — contenu JPEG encodé en base64 (sans le préfixe data:)
* @param filename — nom de fichier avec extension (ex: "REF-1042.jpg")
*/
export async function uploadProductImage(
shopifyProductId: string,
imageBase64: string,
filename: string,
): Promise<{ url: string }> {
const { baseUrl, headers } = getConfig()
const res = await fetch(`${baseUrl}/products/${shopifyProductId}/images.json`, {
method: 'POST',
headers,
body: JSON.stringify({ image: { attachment: imageBase64, filename } }),
})
if (!res.ok) {
const body = await res.text()
throw new Error(`Shopify upload error: ${res.status}${body}`)
}
const data = await res.json()
return { url: data.image.src as string }
}