UNPKG

@ribajs/shopify

Version:

Shopify extension for Riba.js

307 lines 25 kB
import { HttpService } from "@ribajs/core"; import { EventDispatcher } from "@ribajs/events"; import { isObject, clone, getNumber } from "@ribajs/utils/src/type.js"; import { PQueue } from "./p-queue.service.js"; export class ShopifyCartService { static queue = new PQueue({ concurrency: 1 }); static cart = null; static shopifyCartEventDispatcher = new EventDispatcher("ShopifyCart"); static async updateExtern(options = this.requestOptionDefaults) { if (options.triggerOnStart) { this.triggerOnStart(); } const newCart = await this.refresh(); const oldCart = this.cart; this.cart = newCart; if (options.triggerOnChange) { if (oldCart?.total_price !== newCart?.total_price || oldCart?.item_count !== oldCart?.item_count) { this.triggerOnChange(this.cart); } } if (options.triggerOnComplete) { this.triggerOnComplete(); } } static async add(id, quantity = 1, properties = {}, options = this.requestOptionDefaults) { if (options.triggerOnStart) { this.triggerOnStart(); } const promise = this.queue.add(async () => { const body = { id, quantity }; if (Object.keys(properties).length !== 0) { body.properties = properties; } const lineItemRes = await HttpService.post(this.CART_POST_ADD_URL, body, "json"); if (lineItemRes.status >= 400) { throw lineItemRes.body; } const lineItem = lineItemRes.body; const cartRes = await HttpService.get(this.CART_GET_URL, {}, "json"); if (cartRes.status >= 400) { throw lineItemRes.body; } const cart = cartRes.body; if (options.triggerOnChange) { this.triggerOnChange(cart); } this.triggerAdd(id, quantity, properties); return lineItem; }); if (options.triggerOnComplete) { this.triggerOnComplete(); } return promise; } static async refresh() { const cartRes = await HttpService.get(this.CART_GET_URL, {}, "json"); let cart; if (typeof cartRes.body === "string") { cart = JSON.parse(cartRes.body); } else { cart = cartRes.body; } return cart; } static _get() { if (ShopifyCartService.cart !== null) { return new Promise((resolve) => { setTimeout(() => { if (ShopifyCartService.cart !== null) { return resolve(ShopifyCartService.cart); } else { return this._get(); } }, 0); }); } return ShopifyCartService.refresh(); } static get(options = this.requestOptionDefaults) { if (options.triggerOnStart) { this.triggerOnStart(); } const promise = this.queue.add(() => { return this._get(); }); if (options.triggerOnComplete) { this.triggerOnComplete(); } return promise; } static update(id, quantity, properties = {}, options = this.requestOptionDefaults) { if (options.triggerOnStart) { this.triggerOnStart(); } const promise = this.queue .add(() => { const body = { id, quantity }; if (Object.keys(properties).length !== 0) { body.properties = properties; } return HttpService.post(this.CART_POST_UPDATE_URL, body, "form"); }) .then((cart) => { return JSON.parse(cart); }) .then((cart) => { if (options.triggerOnChange) { this.triggerOnChange(cart); } return cart; }); if (options.triggerOnComplete) { this.triggerOnComplete(); } return promise; } static updates(updates, options = this.requestOptionDefaults) { if (options.triggerOnStart) { this.triggerOnStart(); } const promise = this.queue .add(() => { return HttpService.post(this.CART_POST_UPDATE_URL, { updates, }, "form"); }) .then((cart) => { return JSON.parse(cart); }) .then((cart) => { if (options.triggerOnChange) { this.triggerOnChange(cart); } return cart; }); if (options.triggerOnComplete) { this.triggerOnComplete(); } return promise; } static async change(id, quantity, properties = {}, options = this.requestOptionDefaults) { if (options.triggerOnStart) { this.triggerOnStart(); } const promise = this.queue.add(async () => { const body = { id, quantity }; if (Object.keys(properties).length !== 0) { body.properties = properties; } const cartRes = await HttpService.post(this.CART_POST_CHANGE_URL, body, "form"); let cart; if (typeof cartRes.body === "string") { cart = JSON.parse(cartRes.body); } else { cart = cartRes.body; } if (options.triggerOnChange) { this.triggerOnChange(cart); } return cart; }); if (options.triggerOnComplete) { this.triggerOnComplete(); } return promise; } static async changeLine(line, quantity, properties = {}, options = this.requestOptionDefaults) { if (options.triggerOnStart) { this.triggerOnStart(); } const promise = this.queue.add(async () => { const body = { line, quantity }; if (Object.keys(properties).length !== 0) { body.properties = properties; } const cartRes = await HttpService.post(this.CART_POST_CHANGE_URL, body, "form"); let cart; if (typeof cartRes.body === "string") { cart = JSON.parse(cartRes.body); } else { cart = cartRes.body; } if (options.triggerOnChange) { this.triggerOnChange(cart); } return cart; }); if (options.triggerOnComplete) { this.triggerOnComplete(); } return promise; } static async clear(options = this.requestOptionDefaults) { if (options.triggerOnStart) { this.triggerOnStart(); } const promise = this.queue.add(async () => { const cartRes = await HttpService.post(this.CART_POST_CLEAR_URL, {}, "form"); let cart; if (typeof cartRes.body === "string") { cart = JSON.parse(cartRes.body); } else { cart = cartRes.body; } if (options.triggerOnChange) { this.triggerOnChange(cart); } return cart; }); if (options.triggerOnComplete) { this.triggerOnComplete(); } return promise; } static async _getShippingRates(shippingAddress, normalize = true) { const res = await HttpService.get(this.CART_GET_SHIPPING_RATES_URL, { shipping_address: shippingAddress }, "json"); const shippingRates = res.body; if (isObject(shippingRates) && isObject(shippingRates.shipping_rates)) { if (normalize) { return this.normalizeShippingRates(shippingRates.shipping_rates); } return shippingRates.shipping_rates; } else { throw new Error("shipping_rates property not found: " + JSON.stringify(shippingRates)); } } static getShippingRates(shippingAddress, normalize = true, options = this.requestOptionDefaults) { if (options.triggerOnStart) { this.triggerOnStart(); } const promise = this.queue.add(() => { return this._getShippingRates(shippingAddress, normalize); }); if (options.triggerOnComplete) { this.triggerOnComplete(); } return promise; } static CART_POST_ADD_URL = "/cart/add.js"; static CART_GET_URL = "/cart.js"; static CART_POST_UPDATE_URL = "/cart/update.js"; static CART_POST_CHANGE_URL = "/cart/change.js"; static CART_POST_CLEAR_URL = "/cart/clear.js"; static CART_GET_SHIPPING_RATES_URL = "/cart/shipping_rates.json"; static requestOptionDefaults = { triggerOnStart: true, triggerOnComplete: true, triggerOnChange: true, }; static waitForComplete = false; static triggerOnComplete() { if (!this.waitForComplete) { this.waitForComplete = true; return this.queue.onIdle().then(() => { ShopifyCartService.shopifyCartEventDispatcher.trigger("ShopifyCart:request:complete", this.cart); this.waitForComplete = false; }); } } static triggerOnChange(cart) { this.cart = cart; ShopifyCartService.shopifyCartEventDispatcher.trigger("ShopifyCart:request:changed", this.cart); } static triggerOnStart() { if (this.queue.pending > 0) { return; } ShopifyCartService.shopifyCartEventDispatcher.trigger("ShopifyCart:request:start"); } static triggerAdd(id, quantity, properties) { ShopifyCartService.shopifyCartEventDispatcher.trigger("ShopifyCart:add", { id, quantity, properties, }); } static normalizeShippingRates(shippingRates) { const normalized = new Array(shippingRates.length); for (const i in shippingRates) { if (shippingRates[i]) { const shippingRate = shippingRates[i]; normalized[i] = clone(false, shippingRate); if (normalized[i] && normalized[i].price) { normalized[i].price = getNumber(normalized[i].price); if (normalized[i].price) { normalized[i].price *= 100; } else { console.warn(`Can't parse "${normalized[i].price}" to number`); } } else { console.warn(`price property not defined`, normalized[i]); } } } return normalized; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hvcGlmeS1jYXJ0LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvc2hvcGlmeS1jYXJ0LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUMzQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDakQsT0FBTyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDdkUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBbUI5QyxNQUFNLE9BQU8sa0JBQWtCO0lBQ3RCLE1BQU0sQ0FBQyxLQUFLLEdBQUcsSUFBSSxNQUFNLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUU5QyxNQUFNLENBQUMsSUFBSSxHQUE2QixJQUFJLENBQUM7SUFFN0MsTUFBTSxDQUFDLDBCQUEwQixHQUFHLElBQUksZUFBZSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBTXZFLE1BQU0sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUM5QixVQUFxQyxJQUFJLENBQUMscUJBQXFCO1FBRS9ELElBQUksT0FBTyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN4QixDQUFDO1FBRUQsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDckMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztRQUMxQixJQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQztRQUVwQixJQUFJLE9BQU8sQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUM1QixJQUNFLE9BQU8sRUFBRSxXQUFXLEtBQUssT0FBTyxFQUFFLFdBQVc7Z0JBQzdDLE9BQU8sRUFBRSxVQUFVLEtBQUss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