← back to Tk10630 Sku Suffix Canary
shopify.mjs
54 lines
// Read-only Shopify Admin GraphQL helper (shared by query + canary).
import { readFileSync } from 'node:fs';
function loadEnv() {
const txt = readFileSync(`${process.env.HOME}/Projects/secrets-manager/.env`, 'utf8');
const env = {};
for (const line of txt.split('\n')) {
const m = line.match(/^([A-Z0-9_]+)=(.*)$/);
if (m) env[m[1]] = m[2].replace(/^["']|["']$/g, '');
}
return env;
}
const env = loadEnv();
export const STORE = env.SHOPIFY_STORE_DOMAIN;
// Token selection: default SHOPIFY_ADMIN_TOKEN; override via SHOPIFY_TOKEN_VAR
// (e.g. SHOPIFY_TOKEN_VAR=SHOPIFY_FULL_ACCESS_TOKEN for the write_inventory variant phase).
const TOKEN_VAR = process.env.SHOPIFY_TOKEN_VAR || 'SHOPIFY_ADMIN_TOKEN';
const TOKEN = env[TOKEN_VAR];
export const TOKEN_NAME = TOKEN_VAR;
const API = '2024-10';
export async function gql(query, variables = {}) {
const res = await fetch(`https://${STORE}/admin/api/${API}/graphql.json`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Access-Token': TOKEN,
},
body: JSON.stringify({ query, variables }),
});
const json = await res.json();
if (json.errors) throw new Error('GraphQL errors: ' + JSON.stringify(json.errors));
const throttle = json.extensions?.cost?.throttleStatus;
return { data: json.data, throttle };
}
export async function getProductByHandle(handle) {
const q = `query($h:String!){
productByHandle(handle:$h){
id title handle status vendor productType
variants(first:50){
nodes{
id title sku price
selectedOptions{ name value }
inventoryItem{ id sku }
}
}
}
}`;
const { data } = await gql(q, { h: handle });
return data.productByHandle;
}