← back to Newmor Onboard
scripts/build-theme.mjs
99 lines
import fs from 'node:fs';
import assert from 'node:assert/strict';
import crypto from 'node:crypto';
import {ROOT,save} from './shopify.mjs';
const base=`${ROOT}/data/live-2026-09-09/theme/`;
const changes=[];
const priorPath=`${ROOT}/data/live-2026-09-09/theme-change-plan.json`;
const prior=fs.existsSync(priorPath)?JSON.parse(fs.readFileSync(priorPath)).changes:[];
const appliedPath=`${ROOT}/data/live-2026-09-09/theme-apply-journal.json`;
const applied=fs.existsSync(appliedPath)?JSON.parse(fs.readFileSync(appliedPath)).receipts:[];
const hash=s=>crypto.createHash('sha256').update(s).digest('hex');
function patch(key,fn){
const before=fs.readFileSync(base+key,'utf8'); const after=fn(before);
assert.notEqual(before,after); const path=`${ROOT}/theme-work/${key}`;
fs.mkdirSync(path.substring(0,path.lastIndexOf('/')),{recursive:true});fs.writeFileSync(path,after);
const old=prior.find(c=>c.key===key);
const lastApplied=applied?.find(c=>c.key===key)?.sha256||old?.previous_after_sha256;
changes.push({key,before_sha256:hash(before),after_sha256:hash(after),...(lastApplied&&lastApplied!==hash(after)?{previous_after_sha256:lastApplied}:{})});
}
function once(s,from,to){assert.equal(s.split(from).length,2,`Expected one match: ${from.slice(0,80)}`);return s.replace(from,to);}
patch('snippets/dw-quote-only-cta.liquid',s=>{
s=once(s,'<p class="dw-quote-badge-title">Active Pattern — Sold by the Yard</p>\n <p class="dw-quote-badge-sub">54" wide · Yardage pricing by quote</p>',`{% if product.vendor == 'Newmor Wallcoverings' %}
<p class="dw-quote-badge-title">Newmor Showroom Line</p>
<p class="dw-quote-badge-sub">Contact our showroom for availability and project pricing.</p>
{% else %}
<p class="dw-quote-badge-title">Active Pattern — Sold by the Yard</p>
<p class="dw-quote-badge-sub">54" wide · Yardage pricing by quote</p>
{% endif %}`);
s=once(s,' <!-- Modal -->',` {% if product.vendor == 'Newmor Wallcoverings' %}
<p class="dw-showroom-contact"><a href="tel:+18883734564">Call the showroom</a> · <a href="mailto:info@designerwallcoverings.com?subject={{ product.selected_or_first_available_variant.sku | prepend: 'Newmor inquiry: ' | url_encode }}">Email about this colorway</a></p>
<div data-surface-pick-up hidden></div>
{% render 'modal', modal_id: 'surface-pick-up', modal_class: 'surface-pick-up-modal' %}
{% endif %}
<!-- Modal -->`);
return s;
});
patch('snippets/product-list-item.liquid',s=>{
s=once(s," if product_hover == 'quick-shop' and template.name != 'password' and product.variants_count <= 250"," if product_hover == 'quick-shop' and template.name != 'password' and product.variants_count <= 250 and product.vendor != 'Newmor Wallcoverings'");
s=once(s,' <p class="product-list-item-price">',` {% if item.vendor == 'Newmor Wallcoverings' %}
<p class="product-list-item-price" data-newmor-showroom>Showroom inquiry</p>
{% else %}
<p class="product-list-item-price">`);
return once(s,' {% endif %}\n </div>\n\n</article>',` {% endif %}
{% endif %}
</div>
</article>`);
});
patch('sections/predictive-search.liquid',s=>{
s=once(s,' <p class="predictive-search-results-list__product-item-price">',` {% if product.vendor == 'Newmor Wallcoverings' %}
<p class="predictive-search-results-list__product-item-price" data-newmor-showroom>Showroom inquiry</p>
{% else %}
<p class="predictive-search-results-list__product-item-price">`);
return once(s,' {%- endif -%}\n </div>\n </div>',` {%- endif -%}
{% endif %}
</div>
</div>`);
});
patch('layout/theme.liquid',s=>{
const nwCandidates=JSON.parse(fs.readFileSync(`${ROOT}/data/newmor-showroom-plan-2026-09-08.json`)).candidates;
const handles=nwCandidates.map(p=>p.handle),ids=nwCandidates.map(p=>p.id.split('/').at(-1));
const selectors=ids.map(id=>`.boost-sd__product-item[data-product-id="${id}"]`).concat(handles.map(h=>`.boost-sd__product-item:has(a[href*="/products/${h}"])`)).join(',');
const guard=fs.readFileSync(`${ROOT}/scripts/newmor-boost-guard.js`,'utf8');
s=once(s,"{% render 'boost-infinite-override' %}",`<style>:is(${selectors}) :is(.boost-sd__product-price,.boost-sd__format-currency,button,[class*="quick-view"],[class*="quick-add"]){display:none!important}</style>\n{% render 'boost-infinite-override' %}`);
s=once(s,"{% render 'boost-infinite-override' %}",`{% render 'boost-infinite-override' %}
{% if collection.current_vendor == 'Newmor Wallcoverings' %}
<script>
// Boost requests JSON for Shopify's virtual vendors collection. Use the existing Newmor collection's real metadata.
(function(){var original=window.fetch;window.fetch=function(input,init){var raw=typeof input==='string'?input:input&&input.url;var u=new URL(raw,location.origin);var method=(init&&init.method)||(input&&input.method)||'GET';if(method.toUpperCase()==='GET'&&u.origin===location.origin&&u.pathname==='/collections/vendors.json'){u.pathname='/collections/newmor-wallcoverings.json';input=typeof input==='string'?u.href:new Request(u.href,input);}return original.call(this,input,init);};})();
</script>
{% endif %}`);
s=once(s,' <div class="site-overlay" data-site-overlay></div>',` <script>window.__nwApprovedHandles=${JSON.stringify(handles)};window.__nwApprovedIds=${JSON.stringify(ids)};\n${guard}\n</script>\n <div class="site-overlay" data-site-overlay></div>`);
s=once(s,' {{ content_for_layout }}',` {% if request.page_type == 'collection' and collection.current_vendor == 'Newmor Wallcoverings' or request.page_type == 'collection' and collection.handle == 'newmor-wallcoverings' or request.page_type == 'collection' and collection.handle == 'newmor-wallcovering' %}
{% section 'collection' %}
{% else %}
{% if request.page_type == 'search' %}{% section 'collection' %}{% endif %}
{{ content_for_layout }}
{% endif %}`);
s=once(s,' "offers": {',` {% if product.vendor == 'Newmor Wallcoverings' %}
"url": {{ canonical_url | json }}
{% else %}
"offers": {`);
return once(s,' "priceValidUntil": {{ year_from_now | json }}\n }',' "priceValidUntil": {{ year_from_now | json }}\n }\n {% endif %}');
});
patch('snippets/product.liquid',s=>once(s," {% if product != blank %}\n {% form 'product'",` {% if product.vendor == 'Newmor Wallcoverings' %}
<div data-product-form>
{% render 'product-form-content', product: product, form: nil, show_social_media_icons: show_social_media_icons, show_payment_button: false %}
</div>
{% elsif product != blank %}
{% form 'product'`));
patch('sections/collection.liquid',s=>{
const split=s.indexOf('{% schema %}');assert(split>0);
const ids=JSON.parse(fs.readFileSync(`${ROOT}/data/newmor-showroom-plan-2026-09-08.json`)).candidates.map(p=>p.id.split('/').at(-1)).join(',');
const block=fs.readFileSync(`${ROOT}/scripts/newmor-discovery.liquid`,'utf8');
return `{% if request.page_type == 'search' or collection.current_vendor == 'Newmor Wallcoverings' or collection.handle == 'newmor-wallcoverings' or collection.handle == 'newmor-wallcovering' %}\n{% assign nw_allowed = '${ids}' | split: ',' %}\n${block}\n{% else %}\n${s.slice(0,split)}\n{% endif %}\n${s.slice(split)}`;
});
save('data/live-2026-09-09/theme-change-plan.json',{theme_id:145121607731,scope:'Newmor Wallcoverings only; other vendor branches preserved',changes});
console.log(`Prepared ${changes.length} guarded assets`);