UNPKG

@bigcommerce/stencil-utils

Version:

Utility library used by BigCommerce Stencil Framework themes

373 lines (326 loc) 9.88 kB
import BodlEventsCart from '../bodl/emitters/cart'; import Base from './base'; import Hooks from '../hooks'; export default class extends Base { constructor(version) { super(version); this.bodlEventsCart = null; } getBodlEventsCart() { if (!this.bodlEventsCart) { this.bodlEventsCart = new BodlEventsCart(); } return this.bodlEventsCart; } /** * Get a collection of Carts. For now, this will only return an array of a single cart as multiple carts per session * are not currently supported. * * @param options * @param {Function} callback */ getCarts(options = {}, callback) { let url = '/api/storefront/carts'; if (options.includeOptions) { url = this.includeOptions(url); } this.makeRequest(url, 'GET', options, true, (err, response) => { callback(err, response); }); } /** * Get the current Cart's details, either with or without Product Option selections. * Can also be used to get a particular cart provided a cartId in the options. * * @param options * @param {Function} callback */ getCart(options = {}, callback) { /* If no cart ID is provided, get the collection of carts and return the first one */ if (!options.cartId) { return this.getCarts(options, (err, response) => callback(err, response[0])); } let url = `/api/storefront/carts/${options.cartId}`; if (options.includeOptions) { url = this.includeOptions(url); } this.makeRequest(url, 'GET', options, true, (err, response) => { callback(err, response); }); } /** * Get the summary for the current primary cart. This summary does not include the full details of the cart, but * the response time is much faster and it's appropriate for summary use cases. * * @param options * @param {Function} callback */ getCartSummary(options = {}, callback) { const url = '/api/storefront/cart-summary'; this.makeRequest(url, 'GET', options, true, (err, response) => { callback(err, response); }); } /** * Add the parameters to a URL needed to get product option details on cart line items * @param url */ includeOptions(url) { return `${url}?include=lineItems.physicalItems.options,lineItems.digitalItems.options`; } /** * Get a sum of the cart line item quantities * * @param options * @param {Function} callback */ getCartQuantity(options = {}, callback) { this.getCartSummary(options, (err, response) => { if (err) { return callback(err); } let quantity = 0; if (response && response.status !== 204 && response.total_quantity) { quantity = response.total_quantity; } callback(null, quantity); }); } /** * Enhance with Big Open Data Layer events * * @param {FormData} formData * @param {Function} callback * @param {Object} [requestOptions] - optional */ itemAdd(formData, callback, requestOptions = {}) { this.handleItemAdd(formData, (err, response) => { if (!err) { this.getBodlEventsCart().emitAddItem(response); } callback(err, response); }, requestOptions); } /** * Add item to cart with options (variants) * * @param {FormData} formData * @param {Function} callback * @param {Object} [requestOptions] - optional */ handleItemAdd(formData, callback, requestOptions = {}) { const { baseUrl } = requestOptions; this.remoteRequest('/cart/add', 'POST', { formData, baseUrl }, (err, response) => { const emitData = { err, response, }; Hooks.emit('cart-item-add-remote', emitData); callback(err, response); }); } /** * Update cart item quantity * * @param {String|Object} itemId * @param {Number|Function} qty * @param {Function|null} callback */ itemUpdate(itemId, qty, callback) { let callbackArg = callback; let items; if (Array.isArray(itemId) && typeof qty === 'function') { callbackArg = qty; items = itemId; } else { items = [ { id: itemId, quantity: qty, }, ]; } this.update(items, (err, response) => { const emitData = { items, err, response, }; if (qty === 0 && !err) { this.getBodlEventsCart().emitRemoveItem(response); } Hooks.emit('cart-item-update-remote', emitData); callbackArg(err, response); }); } /** * Enhance with Big Open Data Layer events * * @param {String} itemId * @param {Function} callback */ itemRemove(itemId, callback) { this.handleItemRemove(itemId, (err, response) => { if (!err) { this.getBodlEventsCart().emitRemoveItem(response); } callback(err, response); }); } /** * Remove cart items * * Calls the internal update function with quantity: 0 * * @param {String} itemId * @param {Function} callback */ handleItemRemove(itemId, callback) { const items = [ { id: itemId, quantity: 0, }, ]; this.update(items, (err, response) => { const emitData = { items, err, response, }; Hooks.emit('cart-item-remove-remote', emitData); callback(err, response); }); } /** * Get giftwrapping options * @param {String} itemId * @param {Object|Function} options * @param {Function|null} callback */ getItemGiftWrappingOptions(itemId, options, callback) { let opts = options || {}; let callbackArg = callback; if (typeof opts === 'function') { callbackArg = opts; opts = {}; } this.remoteRequest(`/gift-wrapping/${itemId}`, 'GET', opts, callbackArg); } /** * Submit giftwrapping options * * @param {String} itemId * @param {Function} callback */ submitItemGiftWrappingOption(itemId, params, callback) { this.remoteRequest(`/gift-wrapping/${itemId}`, 'POST', { params }, callback); } /** * Update cart items * * @param {Array} items * @param {Function} callback */ update(items, callback) { const payload = { items, }; this.remoteRequest('/cart/update', 'POST', { params: payload }, callback); } /** * POST form data to /cart.php * * @param {FormData} formData * @param {Function} callback */ postFormData(formData, callback) { this.makeRequest('/cart.php', 'POST', { formData }, false, callback); } /** * Get cart content * * @param {Object} options * @param {Function} callback */ getContent(options, callback) { let opts = options || {}; let callbackArg = callback; if (typeof opts === 'function') { callbackArg = opts; opts = {}; } this.makeRequest('/cart.php', 'GET', opts, false, callbackArg); } /** * Get cart shipping quote * * @param {Object} params * @param {String|Array|Object} renderWith * @param {Function} callback * @param {Object} [requestOptions] */ getShippingQuotes(params, renderWith, callback, requestOptions = {}) { let callbackArg = callback; let renderWithArg = renderWith; let requestOptionsArg = requestOptions; if (typeof callbackArg !== 'function') { // renderWith was omitted — shift remaining args: callback → requestOptions requestOptionsArg = callbackArg || {}; callbackArg = renderWithArg; renderWithArg = null; } const options = { ...requestOptionsArg, params, }; if (renderWithArg) { options.template = renderWithArg; } this.remoteRequest('/shipping-quote', 'GET', options, callbackArg); } /** * Submit shipping quote based on quoteId * * @param {Number} quoteId * @param {Function} callback */ submitShippingQuote(quoteId, callback) { const options = { params: { shipping_method: quoteId, }, }; this.remoteRequest('/shipping-quote', 'POST', options, callback); } /** * Apply a coupon code or gift certificate to the cart * * @param {String} code * @param {Function} callback */ applyCode(code, callback) { const options = { params: { code, }, }; this.remoteRequest('/apply-code', 'POST', options, callback); } /** * Apply a coupon code or gift certificate to the cart * * @param {Number} code * @param {Function} callback */ applyGiftCertificate(code, callback) { const options = { params: { code, }, }; this.remoteRequest('/gift-certificates', 'POST', options, callback); } }