← back to Fineartamerica Price Sync
lib/shopify.js
66 lines
// Thin Shopify Admin REST client for the LIVE Designer Wallcoverings store.
// NOTE: designer-laboratory-sandbox.myshopify.com is the real, customer-facing
// production store despite the "sandbox" handle. Every variant price write here
// is customer-facing money — callers must gate writes (see sync.js --apply).
const fs = require('fs');
const SECRETS = '/Users/macstudio3/Projects/secrets-manager/.env';
const STORE = 'designer-laboratory-sandbox.myshopify.com';
const API = '2024-10';
const VENDOR = 'Steve Abrams Studios';
function env(key) {
const m = fs.readFileSync(SECRETS, 'utf8').match(new RegExp('^' + key + '=(.*)$', 'm'));
return m ? m[1].trim().replace(/^["']|["']$/g, '') : null;
}
const TOKEN = env('SHOPIFY_ADMIN_TOKEN');
async function shopify(path, opts = {}) {
const res = await fetch(`https://${STORE}/admin/api/${API}/${path}`, {
...opts,
headers: {
'X-Shopify-Access-Token': TOKEN,
'Content-Type': 'application/json',
...(opts.headers || {}),
},
});
const text = await res.text();
if (!res.ok) throw new Error(`Shopify ${res.status} ${path}: ${text.slice(0, 300)}`);
return { json: text ? JSON.parse(text) : null, headers: res.headers };
}
async function getProduct(id) {
const { json } = await shopify(`products/${id}.json`);
return json.product;
}
// All FAA-fulfilled products = vendor "Steve Abrams Studios" whose variants
// carry the FAA SKU signature. Paginates the vendor set.
async function listFaaProducts() {
const out = [];
let url = `products.json?vendor=${encodeURIComponent(VENDOR)}&limit=250`;
while (url) {
const { json, headers } = await shopify(url);
for (const p of json.products) {
const isFaa = (p.variants || []).some(v => v.sku && /artworkid\[/.test(v.sku) && /productid\[/.test(v.sku));
if (isFaa) out.push(p);
}
const link = headers.get('link') || '';
const next = link.match(/<[^>]*[?&]([^>]*page_info=[^>&]+)[^>]*>;\s*rel="next"/);
url = next ? `products.json?limit=250&${next[1]}` : null;
}
return out;
}
// Gated write. Returns the updated variant.
async function updateVariantPrice(variantId, price) {
const { json } = await shopify(`variants/${variantId}.json`, {
method: 'PUT',
body: JSON.stringify({ variant: { id: variantId, price: String(price) } }),
});
return json.variant;
}
module.exports = { shopify, getProduct, listFaaProducts, updateVariantPrice, STORE, VENDOR };