← back to Sanderson Onboard
scripts/rollback_sdg.mjs
31 lines
// rollback_sdg.mjs — reverse an SDG activation. Default: unpublish + set DRAFT (soft, reversible).
// --delete: hard delete the product. --pid=N single, or --all reads pilot/restore-map.jsonl.
import fs from 'node:fs';
const env = fs.readFileSync('/Users/macstudio3/Projects/secrets-manager/.env', 'utf8');
const STORE = (env.match(/^SHOPIFY_STORE=(.+)$/m) || [])[1].trim();
const TOKEN = (env.match(/^SHOPIFY_FULL_ACCESS_TOKEN=(.+)$/m) || [])[1].trim(); // TK-10979 DTD-A: match forward path so undo has write scope (bridge; target=capability-scoped token)
const REST = `https://${STORE}/admin/api/2024-10`;
const H = { 'X-Shopify-Access-Token': TOKEN, 'Content-Type': 'application/json' };
const DELETE = process.argv.includes('--delete');
const ALL = process.argv.includes('--all');
const PID = (process.argv.find(a => a.startsWith('--pid=')) || '').split('=')[1];
const sleep = ms => new Promise(r => setTimeout(r, ms));
async function one(pid) {
if (DELETE) {
const r = await fetch(`${REST}/products/${pid}.json`, { method: 'DELETE', headers: H });
console.log(` ${pid} DELETE ${r.status}`); return;
}
const r = await fetch(`${REST}/products/${pid}.json`, { method: 'PUT', headers: H, body: JSON.stringify({ product: { id: pid, status: 'draft', published: false } }) });
console.log(` ${pid} -> draft/unpublished ${r.status}`);
}
async function main() {
let pids = [];
if (PID) pids = [PID];
else if (ALL) pids = fs.readFileSync(new URL('../pilot/restore-map.jsonl', import.meta.url).pathname, 'utf8').trim().split('\n').filter(Boolean).map(l => JSON.parse(l).pid);
else { console.error('need --pid=N or --all'); process.exit(1); }
console.log(`rollback ${pids.length} products (${DELETE ? 'DELETE' : 'draft+unpublish'})`);
for (const p of pids) { await one(p); await sleep(300); }
}
main();