/**
* Shopify API Client
* Handles all communication with Shopify Admin API
*/
const SHOPIFY_STORE_URL = process.env.SHOPIFY_STORE_URL || '';
const SHOPIFY_ACCESS_TOKEN = process.env.SHOPIFY_ACCESS_TOKEN || '';
const API_VERSION = '2024-01';
interface ShopifyRequestOptions {
method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
body?: Record<string, any>;
params?: Record<string, string | number | boolean>;
}
function buildUrl(endpoint: string, params?: Record<string, string | number | boolean>): string {
const baseUrl = `https://${SHOPIFY_STORE_URL}/admin/api/${API_VERSION}/${endpoint}`;
if (!params) {
return baseUrl;
}
const searchParams = new URLSearchParams();
for (const [key, value] of Object.entries(params)) {
if (value !== undefined && value !== null) {
searchParams.append(key, String(value));
}
}
const queryString = searchParams.toString();
return queryString ? `${baseUrl}?${queryString}` : baseUrl;
}
export async function shopifyRequest<T = any>(
endpoint: string,
options: ShopifyRequestOptions = {}
): Promise<T> {
const { method = 'GET', body, params } = options;
const url = buildUrl(endpoint, params);
const fetchOptions: RequestInit = {
method,
headers: {
'X-Shopify-Access-Token': SHOPIFY_ACCESS_TOKEN,
'Content-Type': 'application/json',
},
body: body && method !== 'GET' ? JSON.stringify(body) : undefined,
};
const response = await fetch(url, fetchOptions);
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Shopify API error: ${response.status} - ${errorText}`);
}
return response.json();
}
export function validateConfig(): boolean {
if (!SHOPIFY_STORE_URL) {
throw new Error('Missing SHOPIFY_STORE_URL environment variable');
}
if (!SHOPIFY_ACCESS_TOKEN) {
throw new Error('Missing SHOPIFY_ACCESS_TOKEN environment variable');
}
return true;
}