import { CommerceAPI, CommerceAPIOptions, CommerceAPIFetchOptions, } from 'lib/commerce/api'; import { GetAllProductsQuery } from '../schema'; import { getAllProductsQuery } from './operations/get-all-products'; type RecursivePartial = { [P in keyof T]?: RecursivePartial; }; export interface GetAllProductsResult { products: T extends GetAllProductsQuery ? T['site']['products']['edges'] : unknown; } export default class BigcommerceAPI implements CommerceAPI { commerceUrl: string; apiToken: string; constructor({ commerceUrl, apiToken }: CommerceAPIOptions) { this.commerceUrl = commerceUrl; this.apiToken = apiToken; } async fetch( query: string, { variables, preview }: CommerceAPIFetchOptions = {} ): Promise { const res = await fetch(this.commerceUrl + (preview ? '/preview' : ''), { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${this.apiToken}`, }, body: JSON.stringify({ query, variables, }), }); const json = await res.json(); if (json.errors) { console.error(json.errors); throw new Error('Failed to fetch API'); } return json.data; } async getAllProducts(opts: { query: string; }): Promise>; async getAllProducts(opts?: { query?: string; }): Promise>; async getAllProducts({ query = getAllProductsQuery, }: { query?: string } = {}): Promise< GetAllProductsResult> > { const data = await this.fetch>(query); return { products: data?.site?.products?.edges, }; } }