← back to Dw Image Shrink
enum-attached-rest.js
25 lines
// Authoritative attached-image set from REST: every product image's
// admin_graphql_api_id (= the MediaImage gid that matches the Files list).
// Unioned with the GraphQL set in orphan-diff so no truly-attached image is ever
// flagged as an orphan. READ-ONLY.
import fs from 'fs';
import https from 'https';
const SHOP='designer-laboratory-sandbox.myshopify.com';
const ATOK=fs.readFileSync('/Users/macstudio3/Projects/secrets-manager/.env','utf8').split('\n').find(l=>l.startsWith('SHOPIFY_ADMIN_TOKEN=')).split('=').slice(1).join('=').replace(/["' ]/g,'');
const OUT='/Users/macstudio3/Projects/dw-image-shrink/attached-gids-rest.txt';
const sleep=ms=>new Promise(r=>setTimeout(r,ms));
function raw(path){return new Promise((res,rej)=>{const req=https.request({method:'GET',host:SHOP,path,headers:{'X-Shopify-Access-Token':ATOK}},r=>{let d='';r.on('data',c=>d+=c).on('end',()=>res({status:r.statusCode,retryAfter:r.headers['retry-after'],limit:r.headers['x-shopify-shop-api-call-limit']||'',link:r.headers.link||'',json:(()=>{try{return JSON.parse(d)}catch(e){return{}}})()}));});req.on('error',rej);req.end();});}
async function api(path){for(let a=0;a<12;a++){const r=await raw(path);if(r.status===429){await sleep((parseFloat(r.retryAfter)||2)*1000);continue;}const[u,m]=(r.limit||'0/40').split('/').map(Number);await sleep(u>(m*0.5)?400:120);return r;}return{json:{},link:''};}
const out=fs.createWriteStream(OUT);
let url='/admin/api/2024-10/products.json?limit=250&fields=id,images', page=0, imgs=0;
while(url){
const {json,link}=await api(url);
let buf='';
for(const p of json.products||[]) for(const im of p.images||[]){ const g=(im.admin_graphql_api_id||'').split('/').pop(); if(g){buf+=g+'\n';imgs++;} }
if(buf) out.write(buf);
page++; if(page%40===0) console.log(`page ${page} | attached-gids(rest) ${imgs}`);
const m=link.match(/<([^>]+)>;\s*rel="next"/); url=m?m[1].replace('https://'+SHOP,''):null;
}
out.end();
console.log(`DONE: ${imgs} attached MediaImage gids (REST) → attached-gids-rest.txt`);