← back to Harlequin Pilot Publish
lib.mjs
64 lines
import fs from 'node:fs';
export const SHOP = 'designer-laboratory-sandbox.myshopify.com';
export const API = '2024-10';
export function token() {
const env = fs.readFileSync(process.env.HOME + '/Projects/secrets-manager/.env', 'utf8');
const m = env.match(/^SHOPIFY_ADMIN_TOKEN=(.+)$/m);
if (!m) throw new Error('SHOPIFY_ADMIN_TOKEN not found');
return m[1].trim().replace(/^["']|["']$/g, '');
}
const T = token();
export async function gql(query, variables = {}) {
const r = await fetch(`https://${SHOP}/admin/api/${API}/graphql.json`, {
method: 'POST',
headers: { 'X-Shopify-Access-Token': T, 'Content-Type': 'application/json' },
body: JSON.stringify({ query, variables }),
});
const j = await r.json();
if (j.errors) throw new Error('GraphQL errors: ' + JSON.stringify(j.errors));
return j.data;
}
export async function rest(path, method = 'GET', body = null) {
const opts = { method, headers: { 'X-Shopify-Access-Token': T, 'Content-Type': 'application/json' } };
if (body) opts.body = JSON.stringify(body);
const r = await fetch(`https://${SHOP}/admin/api/${API}/${path}`, opts);
const txt = await r.text();
let j; try { j = JSON.parse(txt); } catch { j = { _raw: txt }; }
return { status: r.status, json: j };
}
// Find a product by an exact variant SKU. Returns product gid + full variant list.
export async function findProductByVariantSku(sku) {
const q = `query($q:String!){
productVariants(first: 25, query: $q){
edges{ node{
id sku price
inventoryItem { id tracked }
product { id handle title status }
}}
}
}`;
const d = await gql(q, { q: `sku:${sku}` });
return d.productVariants.edges.map(e => e.node);
}
// Full product variant dump by product gid
export async function getProductVariants(productGid) {
const q = `query($id:ID!){
product(id:$id){
id handle title status
variants(first: 50){ edges{ node{
id title price sku
inventoryItem { id tracked }
}}}
}
}`;
const d = await gql(q, { id: productGid });
return d.product;
}