← back to Newmor Onboard
scripts/apply-theme.mjs
36 lines
import fs from 'node:fs';
import assert from 'node:assert/strict';
import {hash,transition} from './asset-transition.mjs';
import {ROOT,request,read,save} from './shopify.mjs';
const plan=read('data/live-2026-09-09/theme-change-plan.json');
const apply=process.argv.includes('--approved');const rollback=process.argv.includes('--rollback');
const themes=(await request('themes.json')).themes;
assert.equal(themes.find(t=>t.role==='main').id,plan.theme_id,'Active theme changed');
const receipts=[];
for(const c of plan.changes){
const path=`themes/${plan.theme_id}/assets.json`;
const assetURL=()=>path+`?asset[key]=${encodeURIComponent(c.key)}&_tk10670=${Date.now()}`;
const current=(await request(assetURL())).asset.value;
const wanted=fs.readFileSync(`${ROOT}/${rollback?'data/live-2026-09-09/theme':'theme-work'}/${c.key}`,'utf8');
const sourceHash=rollback?c.after_sha256:(c.previous_after_sha256&&hash(current)===c.previous_after_sha256?c.previous_after_sha256:c.before_sha256);
const targetHash=rollback?c.before_sha256:c.after_sha256;
const result=await transition({current,wanted,sourceHash,targetHash,apply,
write:async value=>{
save('data/live-2026-09-09/theme-apply-journal.json',{started_at:new Date().toISOString(),rollback,receipts,next_asset:c.key});
await request(path,'PUT',{asset:{key:c.key,value}});
},
readback:async()=> {
let value;
for(let attempt=0;attempt<5;attempt++){
value=(await request(assetURL())).asset.value;
if(hash(value)===targetHash)return value;
await new Promise(r=>setTimeout(r,1000));
}
return value;
}
});
receipts.push({key:c.key,at:new Date().toISOString(),sha256:targetHash,result});
if(apply)save('data/live-2026-09-09/theme-apply-journal.json',{rollback,receipts});
console.log(`${result}: ${c.key}`);
}