← 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&quot; 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&quot; 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`);