← back to Dw Silver Mylar Rename
lib.mjs
46 lines
// Shared lib: token load, GraphQL client, transform.
import { readFileSync } from 'node:fs';
const ENV = readFileSync(process.env.HOME + '/Projects/secrets-manager/.env', 'utf8');
function envVal(k) {
const m = ENV.match(new RegExp('^' + k + '=(.*)$', 'm'));
return m ? m[1].trim().replace(/^["']|["']$/g, '') : undefined;
}
// Prefer FULL access (write_products); fall back to admin token.
export const TOKEN = envVal('SHOPIFY_FULL_ACCESS_TOKEN') || envVal('SHOPIFY_ADMIN_TOKEN');
export const TOKEN_NAME = envVal('SHOPIFY_FULL_ACCESS_TOKEN') ? 'SHOPIFY_FULL_ACCESS_TOKEN' : 'SHOPIFY_ADMIN_TOKEN';
export const DOMAIN = 'designer-laboratory-sandbox.myshopify.com';
export const API = '2024-10';
const GQL = `https://${DOMAIN}/admin/api/${API}/graphql.json`;
if (!TOKEN) { console.error('NO SHOPIFY TOKEN FOUND'); process.exit(1); }
export async function gql(query, variables = {}) {
for (let attempt = 0; attempt < 6; attempt++) {
const res = await fetch(GQL, {
method: 'POST',
headers: { 'X-Shopify-Access-Token': TOKEN, 'Content-Type': 'application/json' },
body: JSON.stringify({ query, variables }),
});
if (res.status === 429 || res.status >= 500) {
await new Promise(r => setTimeout(r, 2000 * (attempt + 1)));
continue;
}
const j = await res.json();
if (j.errors) throw new Error('GQL errors: ' + JSON.stringify(j.errors));
// throttle courtesy
const cost = j.extensions?.cost?.throttleStatus;
if (cost && cost.currentlyAvailable < 200) await new Promise(r => setTimeout(r, 800));
return j.data;
}
throw new Error('GQL retries exhausted');
}
// SUBSTRING swap: case-insensitive match, normalized replacement, preserve surrounding text.
export const RE = /silver mylar/gi;
export function swap(s) {
if (s == null) return s;
return s.replace(RE, 'Silver Metallic');
}
export function has(s) { return s != null && /silver mylar/i.test(s); }