@gameroom/cli
Version:
A command line tool for Gameroom
131 lines (128 loc) • 6.29 kB
JavaScript
const axios = require('axios'),
cosmetic = require('cosmetic'),
Image = require('./Image'),
Variant = require('./Variant'),
{ conversions, spinner } = require('../../refs'),
{ appendHTMLBody, componentString, extractHTMLBody, extractHTMLText, generateHTML, getRequest, grGreen, shopifyCredentials, timeout, tryRepeatedly } = require('../../helpers')
module.exports = class Product {
constructor(data) {
if (!data) data = {}
this.body_html = data.body_html
this.created_at = data.created_at // read only
this.handle = data.handle
this.id = data.id // read only
this.images = data.images
this.metafields_global_title_tag = data.metafields_global_title_tag
this.metafields_global_description_tag = data.metafields_global_description_tag
this.options = data.options
this.product_type = data.product_type
this.published_at = data.published_at
this.published_scope = data.published_scope
this.tags = data.tags
this.template_suffix = data.template_suffix
this.title = data.title // required
this.created_at = data.created_at // read only
this.variants = data.variants
this.vendor = data.vendor
}
static async fromUnitExtended(unit) {
const title = componentString(unit.name, '-', unit.subname, unit.price ? '|' : null, unit.price)
const info = unit.info ? extractHTMLText(unit.info) : ''
const options_string = unit.options_string || ''
const body = info && options_string ? `${info}\n\n${options_string}` :
info ? info : options_string ? options_string : ''
const body_items = [...body.split('\n'), `Store ∙ ${unit.store}`, `Container ∙ ${unit.container}`, `Index ∙ ${unit.index}` ]
if (unit.altname) body_items.push(`Alternative Names ∙ ${unit.altname}`)
const store_tag = !unit.store ? null :
unit.store.includes('Grand Island') ? 'Grand Island' :
unit.store.includes('Lincoln') ? 'Lincoln' :
unit.store.includes('Omaha') ? 'Omaha' :
unit.store.includes('Warehouse') ? 'Warehouse' :
null
const tags = store_tag ? [ store_tag, ...unit.tags ] : unit.tags
const images = await Image.fromUnit(unit)
return new Product({
body_html: generateHTML(body_items),
handle: unit.id,
images,
metafields_global_title_tag: title,
metafields_global_description_tag: body,
product_type: unit.subtitle,
tags,
title: title,
variants: [
new Variant({
barcode: unit.identifier,
inventory_management: 'shopify',
grams: unit.weight * conversions.grams_per_ounce,
price: unit.amount * .01,
sku: componentString(unit.store, unit.container, unit.index)
})
]
})
}
static async delete(id) {
const { username, password, store_url } = shopifyCredentials()
const result = await tryRepeatedly(() => axios.delete(`/products/${id}.json`, {
auth: { username, password },
baseURL: `https://${store_url}/admin/api/2019-10`
}), (err) => spinner.warn(`error deleting ${cosmetic.green('shopify product')} ${id} ${err}`))
return result
}
static async getAll(spinner) {
const { username, password, store_url } = shopifyCredentials()
const limit = 250
let spinner_text = spinner ? spinner.text : null
const products = []
let done
while (!done) {
if (spinner) spinner.text = `${spinner_text} (${products.length})`
const result = await tryRepeatedly(() => axios.get(`/products.json`, {
auth: { username, password },
baseURL: `https://${store_url}/admin/api/2019-10`,
params: { limit, since_id: products.length > 0 ? products[products.length - 1].id : 0 },
}), (err) => spinner.warn(`error getting ${cosmetic.green('shopify products')} ${err}`))
const new_products = result && result.data && result.data.products ? result.data.products : []
products.push(...new_products)
done = new_products < limit
}
if (spinner) spinner.text = `${spinner_text} (${products.length})`
return products.reduce((a, i) => [...a, new Product(i)], [])
}
static async getWithHandle(handle) {
const { username, password, store_url } = shopifyCredentials()
const result = await tryRepeatedly(() => axios.get('/products.json', {
auth: { username, password },
baseURL: `https://${store_url}/admin/api/2019-10`,
params: { handle }
}), (err) => spinner.warn(`error getting ${cosmetic.green('shopify product')} with handle ${handle} ${err}`))
return result && result.data && result.data.products && result.data.products[0] ? new Product(result.data.products[0]) : null
}
static async getWithId(id) {
const { username, password, store_url } = shopifyCredentials()
const result = await tryRepeatedly(() => axios.get(`/products/${id}.json`, {
auth: { username, password },
baseURL: `https://${store_url}/admin/api/2019-10`
}), (err) => spinner.warn(`error getting ${cosmetic.green('shopify product')} with id ${id} ${err}`))
return result && result.data && result.data.product ? new Product(result.data.product) : null
}
async save() {
const { username, password, store_url } = shopifyCredentials()
const result = await tryRepeatedly(() => axios.post('/products.json', { product: this }, {
auth: { username, password },
baseURL: `https://${store_url}/admin/api/2019-10`,
}), (err) => spinner.warn(`error saving ${cosmetic.green('shopify product')} with handle ${this.handle} ${err}`))
return result && result.data && result.data.product ? new Product(result.data.product) : null
}
async updateFromUnitExtended(unit) {
const { username, password, store_url } = shopifyCredentials()
const product = await Product.fromUnitExtended(unit)
// delete product.images
product.variants[0].id = this.variants[0].id
const result = await tryRepeatedly(() => axios.put(`/products/${this.id}.json`, { product }, {
auth: { username, password },
baseURL: `https://${store_url}/admin/api/2019-10`
}), (err) => spinner.warn(`error updating ${cosmetic.green('shopify product')} from ${grGreen(unit.id)}${err}`))
return result && result.data && result.data.product ? new Product(result.data.product) : null
}
}