Vue Storefront is now Alokai! Learn More
AddCartLineItem

AddCartLineItem

Implements AddCartLineItem Unified Method.

Source

/* eslint-disable max-statements */
import { getCartFromContext, defineApi } from "@vsf-enterprise/unified-api-bigcommerce";
import { getNormalizedCart } from "@/commons/cart";
import { CartIncludeEnum, Product, ProductVariant } from "@vsf-enterprise/bigcommerce-api";

export const addCartLineItem = defineApi.addCartLineItem(async (context, args) => {
  if (args.cartId != null) {
    throw { statusCode: 400, message: "Multiple carts feature is not available." };
  }
  const cart = await getCartFromContext(context);
  const cartId = cart.id as string;

  const { productId, sku, quantity = 1 } = args;

  const { data: products } = await context.api.getProducts({
    id: Number(productId),
    include_fields: "variants,base_variant_id,sku", // reduce payload
    include: "variants", // this is never returned by default in the response
  });

  if (products.length === 0) {
    throw { statusCode: 404, message: "Product not found" };
  }

  const variant_id = await getVariantIdFromSku(products[0]!, sku);

  const { data } = await context.api.addCartItems({
    cartId,
    data: {
      line_items: [{ product_id: Number(productId), quantity, variant_id }],
    },
    include: CartIncludeEnum.LineItemsPhysicalItemsOptions,
  });

  return await getNormalizedCart(context, data);
});

async function getVariantIdFromSku(
  product: Product,
  sku: string | null,
): Promise<number | undefined> {
  const variants = product.variants ?? [];

  if (!sku || product.sku === sku) {
    return product.base_variant_id ?? variants[0]?.id;
  }

  if (variants.length > 0) {
    return findVariant(variants, sku).id;
  }
}

function findVariant(variants: ProductVariant[], sku: string): ProductVariant {
  const variantWithSpecifiedSku = variants.find((variant) => variant.sku === sku);

  if (!variantWithSpecifiedSku) {
    throw { statusCode: 404, message: "Variant with given sku not found" };
  }

  return variantWithSpecifiedSku;
}