← back to Fix Live Board
Add reusable isShowroomVendor() primitive keyed off showroom-vendors.json (TK-11186)
9ba8420b6db99e9f93912a8ff8a74c6a8812e13a · 2026-09-03 11:19:31 -0700 · Steve Abrams
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BgCcr9t5zNGdb43pS4f1ks
Files touched
A config/showroom-vendor.cjs
Diff
commit 9ba8420b6db99e9f93912a8ff8a74c6a8812e13a
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Sep 3 11:19:31 2026 -0700
Add reusable isShowroomVendor() primitive keyed off showroom-vendors.json (TK-11186)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BgCcr9t5zNGdb43pS4f1ks
---
config/showroom-vendor.cjs | 59 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/config/showroom-vendor.cjs b/config/showroom-vendor.cjs
new file mode 100644
index 0000000..fa872fa
--- /dev/null
+++ b/config/showroom-vendor.cjs
@@ -0,0 +1,59 @@
+/**
+ * showroom-vendor.cjs — canonical `isShowroomVendor(vendor)` primitive. (TK-11186)
+ *
+ * Showroom-only vendors are "addressable but not discoverable": reachable via a
+ * direct /products/<handle> URL or on-site search, but HIDDEN from every push /
+ * browse surface and the Google feed. The one source of truth for WHICH vendors
+ * are showroom-only is the sibling `showroom-vendors.json` in this directory
+ * (currently ["Phillip Jeffries"]). NEVER hardcode a vendor name anywhere else —
+ * add/remove vendors by editing that JSON file only.
+ *
+ * Lives beside the list on purpose: one directory owns the showroom-vendor concept
+ * (list + logic). It is a plain CommonJS module so BOTH:
+ * - CommonJS callers: const { isShowroomVendor } = require('.../showroom-vendor.cjs')
+ * - ESM (.mjs) callers: import { createRequire } from 'node:module';
+ * const require = createRequire(import.meta.url);
+ * const { isShowroomVendor } = require('.../showroom-vendor.cjs');
+ * consume the SAME implementation and the SAME list.
+ *
+ * Reversible: delete this file / revert the commit. No side effects, read-only.
+ */
+'use strict';
+const fs = require('fs');
+const path = require('path');
+
+const LIST_PATH = path.join(__dirname, 'showroom-vendors.json');
+
+// Case-insensitive exact-match set, read once and memoized. Resilient: a missing or
+// malformed list yields an empty set (isShowroomVendor -> always false) rather than
+// throwing, so a config hiccup can never crash a feed build or a fleet server boot.
+let _set = null;
+function _load() {
+ if (_set) return _set;
+ try {
+ const raw = JSON.parse(fs.readFileSync(LIST_PATH, 'utf8'));
+ const arr = Array.isArray(raw) ? raw : [];
+ _set = new Set(arr.map(v => String(v == null ? '' : v).trim().toLowerCase()).filter(Boolean));
+ } catch {
+ _set = new Set();
+ }
+ return _set;
+}
+
+/** True iff `vendor` is on the showroom-only list (case-insensitive exact match). */
+function isShowroomVendor(vendor) {
+ if (vendor == null) return false;
+ return _load().has(String(vendor).trim().toLowerCase());
+}
+
+/** The raw showroom-vendor names, as authored in showroom-vendors.json. */
+function showroomVendors() {
+ try {
+ const raw = JSON.parse(fs.readFileSync(LIST_PATH, 'utf8'));
+ return Array.isArray(raw) ? raw.slice() : [];
+ } catch {
+ return [];
+ }
+}
+
+module.exports = { isShowroomVendor, showroomVendors, LIST_PATH };
← e6f437b board: movable/dockable nav — drag grip (float/move up-down-
·
back to Fix Live Board
·
showroom: add tag-aware isShowroomProduct primitive (TK-1130 2fe5fee →