AddCartLineItem
Implements AddCartLineItem Unified Method.
Source
import type { AddCartLineItemArgs } from "@alokai/connect";
import { getNormalizers } from "@alokai/connect/integration-kit";
import { HttpStatusCode, ValidationError } from "@alokai/connect/middleware";
import type { Context } from "@vsf-enterprise/magento-api";
import { z } from "zod";
import { defineApi, query } from "@vsf-enterprise/unified-api-magento";
import { getCartId } from "@vsf-enterprise/unified-api-magento";
import { type Cart, isConfigurableProduct, type ProductWithTypeName } from "@vsf-enterprise/unified-api-magento/ecommerceTypes";
const addCartLineItemSchema = z.object({
productId: z.string(),
quantity: z.number().optional().default(1),
sku: z.string(),
});
async function getCartItem(context: Context, args: AddCartLineItemArgs) {
const { api } = await context.getApiClient();
const productData = await query(
api.productDetails({ filter: { sku: { eq: args.productId } }, pageSize: 1 }),
);
const selectedProduct = productData.products?.items?.[0] as ProductWithTypeName;
if (!selectedProduct) {
throw context.createHttpError({
message: "Product not found",
statusCode: HttpStatusCode.NOT_FOUND,
});
}
if (isConfigurableProduct(selectedProduct)) {
const variant = selectedProduct.variants
?.filter(Boolean)
.find((productVariant) => productVariant.product?.sku === args.sku);
if (!variant) {
throw context.createHttpError({
message: "Product not found",
statusCode: HttpStatusCode.NOT_FOUND,
});
}
const selected_options = (variant.attributes ?? [])
?.map((attribute) => attribute?.uid)
.filter(Boolean);
return { selected_options, sku: args.productId };
}
return { sku: args.sku as string };
}
export const addCartLineItem = defineApi.addCartLineItem(async (context, args) => {
const { api } = await context.getApiClient();
if (args?.cartId != null) {
throw context.createHttpError({
message: "Multiple carts feature is not available.",
statusCode: HttpStatusCode.FORBIDDEN,
});
}
const result = addCartLineItemSchema.safeParse(args);
if (!result.success) {
throw ValidationError.fromStandardSchemaError(result.error, "Missing required arguments");
}
const { productId, quantity, sku } = result.data;
const cartItem = await getCartItem(context, { productId, sku });
const cartId = getCartId(context);
const { normalizeCart } = getNormalizers(context);
const data = await query(
api.addProductsToCart({
cartId,
cartItems: [{ quantity, ...cartItem }],
}),
);
return normalizeCart(data?.addProductsToCart?.cart as Cart);
});