← back to Dw Unbuyable Recovery Pilot
tk10978-rebelwalls/archive-rollback.mjs
27 lines
#!/usr/bin/env node
// TK-10978 — REVERSE the Rebel Walls RS-orphan archive. For each product in
// data/archive-prestate.jsonl, restore its prior status (active). Idempotent:
// skips any product already back at its prior status.
// Usage: node archive-rollback.mjs [--live] default = dry-run (lists what it would restore).
import { readFileSync } from 'node:fs';
import { execSync } from 'child_process';
const LIVE = process.argv.includes('--live');
const TOKEN = execSync(`grep -E '^SHOPIFY_ADMIN_TOKEN=' ${process.env.HOME}/Projects/secrets-manager/.env|cut -d= -f2-`).toString().trim();
const DOMAIN = 'designer-laboratory-sandbox.myshopify.com', API = '2024-10';
const REST = `https://${DOMAIN}/admin/api/${API}`;
const hdr = { 'X-Shopify-Access-Token': TOKEN, 'Content-Type': 'application/json' };
const lines = readFileSync(new URL('./data/archive-prestate.jsonl', import.meta.url).pathname, 'utf8').trim().split('\n').map(JSON.parse);
const sleep = ms => new Promise(r => setTimeout(r, ms));
async function api(path, opts={}) { for(let a=0;a<6;a++){const r=await fetch(`${REST}${path}`,{headers:hdr,...opts}); if(r.status===429){await sleep(2500);continue;} return {status:r.status,json:await r.json().catch(()=>({}))};} return {status:429,json:{}}; }
let n=0, skip=0;
for (const l of lines) {
const g = await api(`/products/${l.pid}.json`);
const cur = g.json.product?.status;
if (cur === l.prior_status) { console.log('skip', l.pid, `already ${cur}`); skip++; continue; }
if (!LIVE) { console.log('WOULD RESTORE', l.pid, `${cur} -> ${l.prior_status}`, l.title); continue; }
const up = await api(`/products/${l.pid}.json`, { method:'PUT', body: JSON.stringify({ product:{ id:Number(l.pid), status:l.prior_status } }) });
if (up.status===200){ n++; console.log('restored', l.pid, `-> ${l.prior_status}`, l.title); } else { console.log('ERR', l.pid, up.status); }
await sleep(500);
}
console.log(LIVE ? `\nrestored ${n}, skipped ${skip} (of ${lines.length})` : `\ndry-run complete (${lines.length} in prestate)`);