@ribajs/shopify
Version:
Shopify extension for Riba.js
307 lines • 25 kB
JavaScript
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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