@ribajs/shopify
Version:
Shopify extension for Riba.js
131 lines (118 loc) • 3.43 kB
text/typescript
import { HttpService } from "@ribajs/core";
import { ShopifyProduct, ShopifyProductVariant } from "../interfaces/index.js";
export interface ProductsCache {
[handle: string]: ShopifyProduct;
}
export class ShopifyProductService {
/**
* Get product object by handle
* @param handle product handle
*/
public static get(handle: string): Promise<ShopifyProduct> {
if (this.cache[handle]) {
return new Promise((resolve) => {
resolve(this.cache[handle]);
});
} else {
return HttpService.getJSON<ShopifyProduct>(`/products/${handle}.js`).then(
(res) => {
const product = res.body;
this.cache[handle] = product;
return this.cache[handle];
},
);
}
}
/**
* Check if the option values fits to the current variant.
* @param variant
* @param optionValues
* @return Returns true if the option values fitting to the variant
*/
public static fitsVariantOptions(
variant: ShopifyProductVariant,
optionValues: string[],
) {
let fit = true;
// position0 is the option index starting on 0
for (const position0 in optionValues) {
if (optionValues[position0]) {
const optionValue = optionValues[position0];
fit = fit && variant.options.indexOf(optionValue.toString()) > -1;
}
}
return fit;
}
/**
* Get product variant of (selected) option values
* @param optionValues (selected) option values
*/
public static getVariantOfOptions(
product: ShopifyProduct,
optionValues: string[],
) {
let result: ShopifyProductVariant | null = null;
if (product) {
for (const i in product.variants) {
if (product.variants[i]) {
result = null;
const variant = product.variants[i];
const fits = this.fitsVariantOptions(variant, optionValues);
if (fits) {
result = variant;
break;
}
}
}
}
return result;
}
/**
* Get variant object by variant id
* @param id Variant id
*/
public static getVariant(product: ShopifyProduct, id: number) {
const result =
product.variants.find((variant) => variant.id === id) || null;
return result;
}
/**
* Get product option by name
* @param product product which holds the options
* @param name option name
*/
public static getOption(product: ShopifyProduct, name: string) {
const result = product.options.find(
(option) => option.name.toLowerCase() === name.toLowerCase(),
);
return result;
}
/**
* Get product option which includes a substring
* @param product product which holds the options
* @param name option name
*/
public static getOptionIncludes(
product: ShopifyProduct,
searchSubstr: string,
) {
const result = product.options.find((option) =>
option.name.includes(searchSubstr),
);
return result;
}
/**
* Prepare product, remove protocol from featured_image, lowercase the option names
* @param product product object
*/
public static prepare(product: ShopifyProduct) {
// remove protocol
product.featured_image.replace(/(^\w+:|^)\/\//, "//");
// all option names to lower case
for (const option of product.options) {
option.name = option.name.toLowerCase();
}
return product;
}
protected static cache: ProductsCache = {};
}