← back to Designer Wallcoverings
TK-00134 TaskC: make cleanWallpaper() brand-aware + derived-word-safe across all 12 helper copies (preserve 17 brands, skip wallpapered/wallpapering, case-preserving)
818dd15e9dcebba30078af076e666c99ef886365 · 2026-07-27 18:22:53 -0700 · Steve Abrams
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
M DW-Programming/ImportNewSkufromURL/lib/banned-words.tsM DW-Programming/ShopifyCalendarNext/scripts/rescan-scheduled-posts.tsM DW-Programming/anna-french-shopify-push.jsM DW-Programming/as-creation-shopify-push.jsM DW-Programming/command54-shopify-push.jsM DW-Programming/hollywood-shopify-push.jsM DW-Programming/justindavid-shopify-push.jsM DW-Programming/launch-versace-vi.jsM DW-Programming/push-versace-vi.jsM DW-Programming/versace-dry-run.jsM shopify/scripts/anna-french-enrich.jsM shopify/scripts/zoffany-full-monty-20.js
Diff
commit 818dd15e9dcebba30078af076e666c99ef886365
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon Jul 27 18:22:53 2026 -0700
TK-00134 TaskC: make cleanWallpaper() brand-aware + derived-word-safe across all 12 helper copies (preserve 17 brands, skip wallpapered/wallpapering, case-preserving)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
.../ImportNewSkufromURL/lib/banned-words.ts | 39 ++++++++++++++++------
.../scripts/rescan-scheduled-posts.ts | 19 ++++++++---
DW-Programming/anna-french-shopify-push.js | 20 ++++++++---
DW-Programming/as-creation-shopify-push.js | 20 ++++++++---
DW-Programming/command54-shopify-push.js | 20 ++++++++---
DW-Programming/hollywood-shopify-push.js | 20 ++++++++---
DW-Programming/justindavid-shopify-push.js | 20 ++++++++---
DW-Programming/launch-versace-vi.js | 20 ++++++++---
DW-Programming/push-versace-vi.js | 20 ++++++++---
DW-Programming/versace-dry-run.js | 17 +++++++++-
shopify/scripts/anna-french-enrich.js | 15 ++++++++-
shopify/scripts/zoffany-full-monty-20.js | 20 ++++++++---
12 files changed, 202 insertions(+), 48 deletions(-)
diff --git a/DW-Programming/ImportNewSkufromURL/lib/banned-words.ts b/DW-Programming/ImportNewSkufromURL/lib/banned-words.ts
index 221692c5..0bf1aed9 100644
--- a/DW-Programming/ImportNewSkufromURL/lib/banned-words.ts
+++ b/DW-Programming/ImportNewSkufromURL/lib/banned-words.ts
@@ -9,19 +9,38 @@
/** Replace the banned word "Wallpaper(s)" with "Wallcovering(s)", matching the
* source casing — ALL-CAPS, Title Case, and lower-case (custhom etc. emit
* "VALE WALLPAPER"; the case-sensitive version missed those). */
+// Brand names that legitimately END in "Wallpaper" and must be PRESERVED verbatim
+// (mirrors /tmp/wp_transform.py BRANDS — TK-00134). Blanket-replacing the generic
+// word would corrupt these (e.g. "Malibu Wallpaper" → "Malibu Wallcovering").
+const WALLPAPER_BRANDS = [
+ 'Apartment', 'Boråstapeter', 'China Seas', 'DW Exclusive', 'Edge', 'Fentucci',
+ 'Grasscloth', 'Laura Ashley', 'Malibu', 'MC Escher', 'Missoni', 'Nicolette Mayer',
+ 'PS Removable', 'Ralph Lauren', 'Roberto Cavalli', 'Scalamandre', 'Schumacher',
+];
+const _brandRe = new RegExp(
+ '(' + WALLPAPER_BRANDS.map(b => b.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|') + ')\\s+Wallpaper',
+ 'gi',
+);
+// Generic word, case-preserving, but NOT derived words (wallpapered / wallpapering).
+const _wordRe = /\bWallpaper(s?)\b(?!ed|ing)/gi;
+
export function cleanWallpaper(str: string | null | undefined): string {
if (!str) return str || '';
- const swap = (base: string) => (m: string) => {
- if (m === m.toUpperCase()) return base.toUpperCase(); // WALLPAPER → WALLCOVERING
- if (m[0] === m[0].toUpperCase()) return base; // Wallpaper → Wallcovering
- return base.toLowerCase(); // wallpaper → wallcovering
- };
- return str
- .replace(/\bWalls\s+Wallpapers?\b/gi, 'Wallcoverings')
- .replace(/\bwallpapers\b/gi, swap('Wallcoverings'))
- .replace(/\bwallpaper\b/gi, swap('Wallcovering'));
+ const SENT = '\u0000';
+ const hold: string[] = [];
+ // 1. protect brand phrases behind sentinel placeholders so the generic swap can't touch them
+ let out = str.replace(_brandRe, (m) => { hold.push(m); return `${SENT}${hold.length - 1}${SENT}`; });
+ // 2. case-preserving generic swap (WALLPAPER->WALLCOVERING, Wallpaper->Wallcovering, wallpaper->wallcovering)
+ out = out.replace(_wordRe, (m, plural) => {
+ const base = plural ? 'wallcoverings' : 'wallcovering';
+ if (m === m.toUpperCase()) return base.toUpperCase();
+ if (m[0] === m[0].toUpperCase()) return base[0].toUpperCase() + base.slice(1);
+ return base;
+ });
+ // 3. restore the protected brand phrases verbatim
+ hold.forEach((h, i) => { out = out.split(`${SENT}${i}${SENT}`).join(h); });
+ return out;
}
-
/** Clean all banned words from a free-text string (name/color/title). */
export function cleanBannedWords(str: string | null | undefined): string {
return cleanWallpaper(str);
diff --git a/DW-Programming/ShopifyCalendarNext/scripts/rescan-scheduled-posts.ts b/DW-Programming/ShopifyCalendarNext/scripts/rescan-scheduled-posts.ts
index 83619667..b7701287 100644
--- a/DW-Programming/ShopifyCalendarNext/scripts/rescan-scheduled-posts.ts
+++ b/DW-Programming/ShopifyCalendarNext/scripts/rescan-scheduled-posts.ts
@@ -85,10 +85,21 @@ Return ONLY valid JSON:
// POST-PROCESSING: Remove "Wallpaper" from ALL text fields
const cleanWallpaper = (str: string) => {
if (!str) return str;
- return str
- .replace(/\bWallpaper\b/gi, 'Wallcovering')
- .replace(/\bWalls Wallpaper\b/gi, 'Wallcoverings')
- .replace(/\bWallpapers\b/gi, 'Wallcoverings');
+ // Brand-aware + derived-word-safe (TK-00134): preserve the 17 brands, skip wallpapered/wallpapering
+ const WALLPAPER_BRANDS = ['Apartment','Bor\u00e5stapeter','China Seas','DW Exclusive','Edge','Fentucci','Grasscloth','Laura Ashley','Malibu','MC Escher','Missoni','Nicolette Mayer','PS Removable','Ralph Lauren','Roberto Cavalli','Scalamandre','Schumacher'];
+ const brandRe = new RegExp('(' + WALLPAPER_BRANDS.map((b) => b.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|') + ')\\s+Wallpaper', 'gi');
+ const wordRe = /\bWallpaper(s?)\b(?!ed|ing)/gi;
+ const SENT = '\u0000';
+ const hold: string[] = [];
+ let out = String(str).replace(brandRe, (m) => { hold.push(m); return SENT + (hold.length - 1) + SENT; });
+ out = out.replace(wordRe, (m, plural) => {
+ const base = plural ? 'wallcoverings' : 'wallcovering';
+ if (m === m.toUpperCase()) return base.toUpperCase();
+ if (m[0] === m[0].toUpperCase()) return base[0].toUpperCase() + base.slice(1);
+ return base;
+ });
+ hold.forEach((h, i) => { out = out.split(SENT + i + SENT).join(h); });
+ return out;
};
if (parsed.architecturalTitle) parsed.architecturalTitle = cleanWallpaper(parsed.architecturalTitle);
diff --git a/DW-Programming/anna-french-shopify-push.js b/DW-Programming/anna-french-shopify-push.js
index 9183cf74..27f75ee6 100644
--- a/DW-Programming/anna-french-shopify-push.js
+++ b/DW-Programming/anna-french-shopify-push.js
@@ -42,10 +42,22 @@ function toTitleCase(str) {
function cleanWallpaper(str) {
if (!str) return str;
- return str
- .replace(/\bWallpaper\b/gi, 'Wallcovering')
- .replace(/\bWalls Wallpaper\b/gi, 'Wallcoverings')
- .replace(/\bWallpapers\b/gi, 'Wallcoverings');
+ // Brand-aware + derived-word-safe (TK-00134): preserve the 17 brands ending in
+ // "Wallpaper", skip wallpapered/wallpapering, case-preserving generic swap.
+ const WALLPAPER_BRANDS = ['Apartment','Bor\u00e5stapeter','China Seas','DW Exclusive','Edge','Fentucci','Grasscloth','Laura Ashley','Malibu','MC Escher','Missoni','Nicolette Mayer','PS Removable','Ralph Lauren','Roberto Cavalli','Scalamandre','Schumacher'];
+ const brandRe = new RegExp('(' + WALLPAPER_BRANDS.map(function(b){return b.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');}).join('|') + ')\\s+Wallpaper','gi');
+ const wordRe = /\bWallpaper(s?)\b(?!ed|ing)/gi;
+ const SENT = '\u0000';
+ const hold = [];
+ let out = String(str).replace(brandRe, function(m){ hold.push(m); return SENT + (hold.length-1) + SENT; });
+ out = out.replace(wordRe, function(m, plural){
+ const base = plural ? 'wallcoverings' : 'wallcovering';
+ if (m === m.toUpperCase()) return base.toUpperCase();
+ if (m[0] === m[0].toUpperCase()) return base[0].toUpperCase() + base.slice(1);
+ return base;
+ });
+ hold.forEach(function(h,i){ out = out.split(SENT + i + SENT).join(h); });
+ return out;
}
function shopifyRest(method, path, body) {
diff --git a/DW-Programming/as-creation-shopify-push.js b/DW-Programming/as-creation-shopify-push.js
index 84a97f21..98c25c0e 100644
--- a/DW-Programming/as-creation-shopify-push.js
+++ b/DW-Programming/as-creation-shopify-push.js
@@ -57,10 +57,22 @@ function toTitleCase(str) {
function cleanWallpaper(str) {
if (!str) return str;
- return str
- .replace(/\bWallpaper\b/gi, 'Wallcovering')
- .replace(/\bWalls Wallpaper\b/gi, 'Wallcoverings')
- .replace(/\bWallpapers\b/gi, 'Wallcoverings');
+ // Brand-aware + derived-word-safe (TK-00134): preserve the 17 brands ending in
+ // "Wallpaper", skip wallpapered/wallpapering, case-preserving generic swap.
+ const WALLPAPER_BRANDS = ['Apartment','Bor\u00e5stapeter','China Seas','DW Exclusive','Edge','Fentucci','Grasscloth','Laura Ashley','Malibu','MC Escher','Missoni','Nicolette Mayer','PS Removable','Ralph Lauren','Roberto Cavalli','Scalamandre','Schumacher'];
+ const brandRe = new RegExp('(' + WALLPAPER_BRANDS.map(function(b){return b.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');}).join('|') + ')\\s+Wallpaper','gi');
+ const wordRe = /\bWallpaper(s?)\b(?!ed|ing)/gi;
+ const SENT = '\u0000';
+ const hold = [];
+ let out = String(str).replace(brandRe, function(m){ hold.push(m); return SENT + (hold.length-1) + SENT; });
+ out = out.replace(wordRe, function(m, plural){
+ const base = plural ? 'wallcoverings' : 'wallcovering';
+ if (m === m.toUpperCase()) return base.toUpperCase();
+ if (m[0] === m[0].toUpperCase()) return base[0].toUpperCase() + base.slice(1);
+ return base;
+ });
+ hold.forEach(function(h,i){ out = out.split(SENT + i + SENT).join(h); });
+ return out;
}
function parseJsonb(val) {
diff --git a/DW-Programming/command54-shopify-push.js b/DW-Programming/command54-shopify-push.js
index 6b1ee129..ed4b849f 100644
--- a/DW-Programming/command54-shopify-push.js
+++ b/DW-Programming/command54-shopify-push.js
@@ -126,10 +126,22 @@ function toTitleCase(str) {
function cleanWallpaper(str) {
if (!str) return str;
- return str
- .replace(/\bWallpaper\b/gi, 'Wallcovering')
- .replace(/\bWalls Wallpaper\b/gi, 'Wallcoverings')
- .replace(/\bWallpapers\b/gi, 'Wallcoverings');
+ // Brand-aware + derived-word-safe (TK-00134): preserve the 17 brands ending in
+ // "Wallpaper", skip wallpapered/wallpapering, case-preserving generic swap.
+ const WALLPAPER_BRANDS = ['Apartment','Bor\u00e5stapeter','China Seas','DW Exclusive','Edge','Fentucci','Grasscloth','Laura Ashley','Malibu','MC Escher','Missoni','Nicolette Mayer','PS Removable','Ralph Lauren','Roberto Cavalli','Scalamandre','Schumacher'];
+ const brandRe = new RegExp('(' + WALLPAPER_BRANDS.map(function(b){return b.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');}).join('|') + ')\\s+Wallpaper','gi');
+ const wordRe = /\bWallpaper(s?)\b(?!ed|ing)/gi;
+ const SENT = '\u0000';
+ const hold = [];
+ let out = String(str).replace(brandRe, function(m){ hold.push(m); return SENT + (hold.length-1) + SENT; });
+ out = out.replace(wordRe, function(m, plural){
+ const base = plural ? 'wallcoverings' : 'wallcovering';
+ if (m === m.toUpperCase()) return base.toUpperCase();
+ if (m[0] === m[0].toUpperCase()) return base[0].toUpperCase() + base.slice(1);
+ return base;
+ });
+ hold.forEach(function(h,i){ out = out.split(SENT + i + SENT).join(h); });
+ return out;
}
function parseJsonb(val) {
diff --git a/DW-Programming/hollywood-shopify-push.js b/DW-Programming/hollywood-shopify-push.js
index 27f7ad77..70197b04 100644
--- a/DW-Programming/hollywood-shopify-push.js
+++ b/DW-Programming/hollywood-shopify-push.js
@@ -48,10 +48,22 @@ function toTitleCase(str) {
function cleanWallpaper(str) {
if (!str) return str;
- return str
- .replace(/\bWallpaper\b/gi, 'Wallcovering')
- .replace(/\bWalls Wallpaper\b/gi, 'Wallcoverings')
- .replace(/\bWallpapers\b/gi, 'Wallcoverings');
+ // Brand-aware + derived-word-safe (TK-00134): preserve the 17 brands ending in
+ // "Wallpaper", skip wallpapered/wallpapering, case-preserving generic swap.
+ const WALLPAPER_BRANDS = ['Apartment','Bor\u00e5stapeter','China Seas','DW Exclusive','Edge','Fentucci','Grasscloth','Laura Ashley','Malibu','MC Escher','Missoni','Nicolette Mayer','PS Removable','Ralph Lauren','Roberto Cavalli','Scalamandre','Schumacher'];
+ const brandRe = new RegExp('(' + WALLPAPER_BRANDS.map(function(b){return b.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');}).join('|') + ')\\s+Wallpaper','gi');
+ const wordRe = /\bWallpaper(s?)\b(?!ed|ing)/gi;
+ const SENT = '\u0000';
+ const hold = [];
+ let out = String(str).replace(brandRe, function(m){ hold.push(m); return SENT + (hold.length-1) + SENT; });
+ out = out.replace(wordRe, function(m, plural){
+ const base = plural ? 'wallcoverings' : 'wallcovering';
+ if (m === m.toUpperCase()) return base.toUpperCase();
+ if (m[0] === m[0].toUpperCase()) return base[0].toUpperCase() + base.slice(1);
+ return base;
+ });
+ hold.forEach(function(h,i){ out = out.split(SENT + i + SENT).join(h); });
+ return out;
}
function parseJsonb(val) {
diff --git a/DW-Programming/justindavid-shopify-push.js b/DW-Programming/justindavid-shopify-push.js
index eb75f63f..b3d35e7b 100644
--- a/DW-Programming/justindavid-shopify-push.js
+++ b/DW-Programming/justindavid-shopify-push.js
@@ -98,10 +98,22 @@ function toTitleCase(str) {
function cleanWallpaper(str) {
if (!str) return str;
- return str
- .replace(/\bWallpaper\b/gi, 'Wallcovering')
- .replace(/\bWalls Wallpaper\b/gi, 'Wallcoverings')
- .replace(/\bWallpapers\b/gi, 'Wallcoverings');
+ // Brand-aware + derived-word-safe (TK-00134): preserve the 17 brands ending in
+ // "Wallpaper", skip wallpapered/wallpapering, case-preserving generic swap.
+ const WALLPAPER_BRANDS = ['Apartment','Bor\u00e5stapeter','China Seas','DW Exclusive','Edge','Fentucci','Grasscloth','Laura Ashley','Malibu','MC Escher','Missoni','Nicolette Mayer','PS Removable','Ralph Lauren','Roberto Cavalli','Scalamandre','Schumacher'];
+ const brandRe = new RegExp('(' + WALLPAPER_BRANDS.map(function(b){return b.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');}).join('|') + ')\\s+Wallpaper','gi');
+ const wordRe = /\bWallpaper(s?)\b(?!ed|ing)/gi;
+ const SENT = '\u0000';
+ const hold = [];
+ let out = String(str).replace(brandRe, function(m){ hold.push(m); return SENT + (hold.length-1) + SENT; });
+ out = out.replace(wordRe, function(m, plural){
+ const base = plural ? 'wallcoverings' : 'wallcovering';
+ if (m === m.toUpperCase()) return base.toUpperCase();
+ if (m[0] === m[0].toUpperCase()) return base[0].toUpperCase() + base.slice(1);
+ return base;
+ });
+ hold.forEach(function(h,i){ out = out.split(SENT + i + SENT).join(h); });
+ return out;
}
function mapProductType(category) {
diff --git a/DW-Programming/launch-versace-vi.js b/DW-Programming/launch-versace-vi.js
index 7cc2444e..b1f040c5 100644
--- a/DW-Programming/launch-versace-vi.js
+++ b/DW-Programming/launch-versace-vi.js
@@ -36,10 +36,22 @@ function toTitleCase(str) {
function cleanWallpaper(str) {
if (!str) return str;
- return str
- .replace(/\bWallpaper\b/gi, 'Wallcovering')
- .replace(/\bWalls Wallpaper\b/gi, 'Wallcoverings')
- .replace(/\bWallpapers\b/gi, 'Wallcoverings');
+ // Brand-aware + derived-word-safe (TK-00134): preserve the 17 brands ending in
+ // "Wallpaper", skip wallpapered/wallpapering, case-preserving generic swap.
+ const WALLPAPER_BRANDS = ['Apartment','Bor\u00e5stapeter','China Seas','DW Exclusive','Edge','Fentucci','Grasscloth','Laura Ashley','Malibu','MC Escher','Missoni','Nicolette Mayer','PS Removable','Ralph Lauren','Roberto Cavalli','Scalamandre','Schumacher'];
+ const brandRe = new RegExp('(' + WALLPAPER_BRANDS.map(function(b){return b.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');}).join('|') + ')\\s+Wallpaper','gi');
+ const wordRe = /\bWallpaper(s?)\b(?!ed|ing)/gi;
+ const SENT = '\u0000';
+ const hold = [];
+ let out = String(str).replace(brandRe, function(m){ hold.push(m); return SENT + (hold.length-1) + SENT; });
+ out = out.replace(wordRe, function(m, plural){
+ const base = plural ? 'wallcoverings' : 'wallcovering';
+ if (m === m.toUpperCase()) return base.toUpperCase();
+ if (m[0] === m[0].toUpperCase()) return base[0].toUpperCase() + base.slice(1);
+ return base;
+ });
+ hold.forEach(function(h,i){ out = out.split(SENT + i + SENT).join(h); });
+ return out;
}
// ─── Pattern Name Cleanup ───────────────────────────────────────────
diff --git a/DW-Programming/push-versace-vi.js b/DW-Programming/push-versace-vi.js
index d1a28372..1f9a10cf 100644
--- a/DW-Programming/push-versace-vi.js
+++ b/DW-Programming/push-versace-vi.js
@@ -35,10 +35,22 @@ function toTitleCase(str) {
function cleanWallpaper(str) {
if (!str) return str;
- return str
- .replace(/\bWallpaper\b/gi, 'Wallcovering')
- .replace(/\bWalls Wallpaper\b/gi, 'Wallcoverings')
- .replace(/\bWallpapers\b/gi, 'Wallcoverings');
+ // Brand-aware + derived-word-safe (TK-00134): preserve the 17 brands ending in
+ // "Wallpaper", skip wallpapered/wallpapering, case-preserving generic swap.
+ const WALLPAPER_BRANDS = ['Apartment','Bor\u00e5stapeter','China Seas','DW Exclusive','Edge','Fentucci','Grasscloth','Laura Ashley','Malibu','MC Escher','Missoni','Nicolette Mayer','PS Removable','Ralph Lauren','Roberto Cavalli','Scalamandre','Schumacher'];
+ const brandRe = new RegExp('(' + WALLPAPER_BRANDS.map(function(b){return b.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');}).join('|') + ')\\s+Wallpaper','gi');
+ const wordRe = /\bWallpaper(s?)\b(?!ed|ing)/gi;
+ const SENT = '\u0000';
+ const hold = [];
+ let out = String(str).replace(brandRe, function(m){ hold.push(m); return SENT + (hold.length-1) + SENT; });
+ out = out.replace(wordRe, function(m, plural){
+ const base = plural ? 'wallcoverings' : 'wallcovering';
+ if (m === m.toUpperCase()) return base.toUpperCase();
+ if (m[0] === m[0].toUpperCase()) return base[0].toUpperCase() + base.slice(1);
+ return base;
+ });
+ hold.forEach(function(h,i){ out = out.split(SENT + i + SENT).join(h); });
+ return out;
}
function buildTitle(patternName, colorName) {
diff --git a/DW-Programming/versace-dry-run.js b/DW-Programming/versace-dry-run.js
index fe9f23a3..a230735e 100644
--- a/DW-Programming/versace-dry-run.js
+++ b/DW-Programming/versace-dry-run.js
@@ -14,7 +14,22 @@ function toTitleCase(str) {
function cleanWallpaper(str) {
if (!str) return str;
- return str.replace(/\bWallpaper\b/gi, 'Wallcovering').replace(/\bWallpapers\b/gi, 'Wallcoverings');
+ // Brand-aware + derived-word-safe (TK-00134): preserve the 17 brands ending in
+ // "Wallpaper", skip wallpapered/wallpapering, case-preserving generic swap.
+ const WALLPAPER_BRANDS = ['Apartment','Bor\u00e5stapeter','China Seas','DW Exclusive','Edge','Fentucci','Grasscloth','Laura Ashley','Malibu','MC Escher','Missoni','Nicolette Mayer','PS Removable','Ralph Lauren','Roberto Cavalli','Scalamandre','Schumacher'];
+ const brandRe = new RegExp('(' + WALLPAPER_BRANDS.map(function(b){return b.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');}).join('|') + ')\\s+Wallpaper','gi');
+ const wordRe = /\bWallpaper(s?)\b(?!ed|ing)/gi;
+ const SENT = '\u0000';
+ const hold = [];
+ let out = String(str).replace(brandRe, function(m){ hold.push(m); return SENT + (hold.length-1) + SENT; });
+ out = out.replace(wordRe, function(m, plural){
+ const base = plural ? 'wallcoverings' : 'wallcovering';
+ if (m === m.toUpperCase()) return base.toUpperCase();
+ if (m[0] === m[0].toUpperCase()) return base[0].toUpperCase() + base.slice(1);
+ return base;
+ });
+ hold.forEach(function(h,i){ out = out.split(SENT + i + SENT).join(h); });
+ return out;
}
(async () => {
diff --git a/shopify/scripts/anna-french-enrich.js b/shopify/scripts/anna-french-enrich.js
index f842e174..13d333bd 100644
--- a/shopify/scripts/anna-french-enrich.js
+++ b/shopify/scripts/anna-french-enrich.js
@@ -101,7 +101,20 @@ function titleCase(s) {
}
const cleanWallpaper = (s) => {
if (!s) return s;
- let out = String(s).replace(/\bWalls Wallpaper\b/gi, 'Wallcoverings').replace(/\bWallpapers\b/gi, 'Wallcoverings').replace(/\bWallpaper\b/gi, 'Wallcovering');
+ // Brand-aware + derived-word-safe wallpaper swap (TK-00134) — preserve the 17 brands, skip wallpapered/wallpapering
+ const WALLPAPER_BRANDS = ['Apartment','Bor\u00e5stapeter','China Seas','DW Exclusive','Edge','Fentucci','Grasscloth','Laura Ashley','Malibu','MC Escher','Missoni','Nicolette Mayer','PS Removable','Ralph Lauren','Roberto Cavalli','Scalamandre','Schumacher'];
+ const brandRe = new RegExp('(' + WALLPAPER_BRANDS.map(function(b){return b.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');}).join('|') + ')\\s+Wallpaper','gi');
+ const wordRe = /\bWallpaper(s?)\b(?!ed|ing)/gi;
+ const SENT = '\u0000';
+ const hold = [];
+ let out = String(s).replace(brandRe, function(m){ hold.push(m); return SENT + (hold.length-1) + SENT; });
+ out = out.replace(wordRe, function(m, plural){
+ const base = plural ? 'wallcoverings' : 'wallcovering';
+ if (m === m.toUpperCase()) return base.toUpperCase();
+ if (m[0] === m[0].toUpperCase()) return base[0].toUpperCase() + base.slice(1);
+ return base;
+ });
+ hold.forEach(function(h,i){ out = out.split(SENT + i + SENT).join(h); });
out = out.replace(/\bBrowse the Thibaut[^.]*\.\s*/gi, '').replace(/\bThibaut\b/gi, 'Anna French').replace(/\bYork Wallcoverings\b/gi, 'Anna French').replace(/\bYork\b/gi, 'Anna French');
return out.replace(/\s+/g, ' ').trim();
};
diff --git a/shopify/scripts/zoffany-full-monty-20.js b/shopify/scripts/zoffany-full-monty-20.js
index 8f5e8cff..558b42d2 100644
--- a/shopify/scripts/zoffany-full-monty-20.js
+++ b/shopify/scripts/zoffany-full-monty-20.js
@@ -89,10 +89,22 @@ function toTitleCase(str) {
function cleanWallpaper(str) {
if (!str) return str;
- return str
- .replace(/\bWallpaper\b/gi, 'Wallcovering')
- .replace(/\bWalls Wallpaper\b/gi, 'Wallcoverings')
- .replace(/\bWallpapers\b/gi, 'Wallcoverings');
+ // Brand-aware + derived-word-safe (TK-00134): preserve the 17 brands ending in
+ // "Wallpaper", skip wallpapered/wallpapering, case-preserving generic swap.
+ const WALLPAPER_BRANDS = ['Apartment','Bor\u00e5stapeter','China Seas','DW Exclusive','Edge','Fentucci','Grasscloth','Laura Ashley','Malibu','MC Escher','Missoni','Nicolette Mayer','PS Removable','Ralph Lauren','Roberto Cavalli','Scalamandre','Schumacher'];
+ const brandRe = new RegExp('(' + WALLPAPER_BRANDS.map(function(b){return b.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');}).join('|') + ')\\s+Wallpaper','gi');
+ const wordRe = /\bWallpaper(s?)\b(?!ed|ing)/gi;
+ const SENT = '\u0000';
+ const hold = [];
+ let out = String(str).replace(brandRe, function(m){ hold.push(m); return SENT + (hold.length-1) + SENT; });
+ out = out.replace(wordRe, function(m, plural){
+ const base = plural ? 'wallcoverings' : 'wallcovering';
+ if (m === m.toUpperCase()) return base.toUpperCase();
+ if (m[0] === m[0].toUpperCase()) return base[0].toUpperCase() + base.slice(1);
+ return base;
+ });
+ hold.forEach(function(h,i){ out = out.split(SENT + i + SENT).join(h); });
+ return out;
}
function cleanHtml(str) {
← d33e8553 TK-135: gated apply script (metafield color_palette + color:
·
back to Designer Wallcoverings
·
auto-save: 2026-07-27T18:22:43 (15 files) — shopify/scripts/ 930575df →