@reddoorla/maintenance 0.74.0 → 0.75.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1829,6 +1829,86 @@ function buildFeedResolvers(feeds, mediaLibrary, base2) {
1829
1829
  };
1830
1830
  }
1831
1831
 
1832
+ // src/blux/products.ts
1833
+ var CANONICAL_CATEGORIES = ["Upholstered", "Case", "Exterior", "Metal", "Finishes"];
1834
+ var CATEGORY_ALIASES = {
1835
+ upholstrered: "Upholstered",
1836
+ upholsered: "Upholstered"
1837
+ };
1838
+ var SUBCATEGORY_ALIASES = {
1839
+ banuette: "Banquette",
1840
+ "benches & ottomans": "Ottomans & Benches",
1841
+ miscellaneous: "Misc."
1842
+ };
1843
+ function cleanWs(s) {
1844
+ return String(s ?? "").replace(/\s+/g, " ").trim();
1845
+ }
1846
+ function titleCase(s) {
1847
+ return s.replace(/\b\w/g, (c) => c.toUpperCase());
1848
+ }
1849
+ function normalizeCategory(raw) {
1850
+ const cleaned = cleanWs(raw);
1851
+ if (!cleaned) return "";
1852
+ const lower = cleaned.toLowerCase();
1853
+ if (CATEGORY_ALIASES[lower]) return CATEGORY_ALIASES[lower];
1854
+ const canon = CANONICAL_CATEGORIES.find((c) => c.toLowerCase() === lower);
1855
+ return canon ?? titleCase(lower);
1856
+ }
1857
+ function normalizeSubCategory(raw) {
1858
+ const cleaned = cleanWs(raw);
1859
+ if (!cleaned) return "";
1860
+ const lower = cleaned.toLowerCase();
1861
+ if (SUBCATEGORY_ALIASES[lower]) return SUBCATEGORY_ALIASES[lower];
1862
+ return titleCase(lower);
1863
+ }
1864
+ function productSlug(record) {
1865
+ const url = typeof record.url === "string" ? record.url.trim() : "";
1866
+ if (url) return url.replace(/^\/+products\/+/i, "").replace(/^\/+|\/+$/g, "");
1867
+ return String(record.title ?? "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
1868
+ }
1869
+ function mediaUuid(media) {
1870
+ if (media && typeof media === "object") {
1871
+ const m = media.media;
1872
+ if (typeof m === "string" && m) return m;
1873
+ }
1874
+ return void 0;
1875
+ }
1876
+ function imageFor(uuid, resolveImage) {
1877
+ if (!uuid) return void 0;
1878
+ const url = resolveImage(uuid);
1879
+ return url ? { assetId: uuid, url } : void 0;
1880
+ }
1881
+ function materializeProducts(records, resolveImage) {
1882
+ const bySlug = /* @__PURE__ */ new Map();
1883
+ for (const r of records) {
1884
+ const slug = productSlug(r);
1885
+ if (!slug) continue;
1886
+ const gallery = [];
1887
+ if (Array.isArray(r.items)) {
1888
+ for (const it of r.items) {
1889
+ const img2 = imageFor(mediaUuid(it?.media), resolveImage);
1890
+ if (img2) gallery.push(img2);
1891
+ }
1892
+ }
1893
+ const image = imageFor(mediaUuid(r.media), resolveImage);
1894
+ const product = {
1895
+ slug,
1896
+ title: cleanWs(r.title),
1897
+ category: normalizeCategory(r.category),
1898
+ subCategory: normalizeSubCategory(r.sub_category),
1899
+ dimensions: String(r.dimensions ?? ""),
1900
+ tags: Array.isArray(r.tags) ? r.tags.filter((t) => typeof t === "string") : [],
1901
+ disabled: r.disabled === true,
1902
+ gallery,
1903
+ // `exactOptionalPropertyTypes`: omit the key rather than set undefined.
1904
+ ...image ? { image } : {}
1905
+ };
1906
+ const existing = bySlug.get(slug);
1907
+ if (!existing || existing.disabled && !product.disabled) bySlug.set(slug, product);
1908
+ }
1909
+ return [...bySlug.values()];
1910
+ }
1911
+
1832
1912
  // src/blux/emit/block-styles.ts
1833
1913
  function blockStylesByIndex(siteJson, pageIndex = 0) {
1834
1914
  const out = /* @__PURE__ */ new Map();
@@ -3036,6 +3116,20 @@ assets: ${r.assetsUploaded} uploaded, ${r.assetsReused} reused | documents: ${r.
3036
3116
  const siteConfig = buildSiteConfig(siteJson, resolveLogo, resolveSocialHref);
3037
3117
  await writeFile(join(outDir, "site-config.json"), JSON.stringify(siteConfig, null, 2) + "\n");
3038
3118
  }
3119
+ {
3120
+ const feeds = siteJson.feeds ?? {};
3121
+ const productFeed = Object.values(feeds).find((f) => f?.publish === "products");
3122
+ if (productFeed && Array.isArray(productFeed.items)) {
3123
+ const base2 = feedAssetBase([...htmlByUid.values()], ir.meta.bluxSiteId);
3124
+ const mediaMeta = siteJson.media ?? {};
3125
+ const resolveImage = (uuid) => {
3126
+ const ext = extFor(mediaMeta[uuid]?.type, mediaMeta[uuid]?.name);
3127
+ return ext ? `${base2}${uuid}.${ext}` : null;
3128
+ };
3129
+ const products = materializeProducts(productFeed.items, resolveImage);
3130
+ await writeFile(join(outDir, "products.json"), JSON.stringify(products, null, 2) + "\n");
3131
+ }
3132
+ }
3039
3133
  let faviconLine = "";
3040
3134
  if (ir.meta.favicon?.sourceUrl) {
3041
3135
  const { assetId, sourceUrl } = ir.meta.favicon;
@@ -3083,4 +3177,4 @@ skipped (no html): ${missing.map((d) => d.where).join(", ")}` : "") + faviconLin
3083
3177
  export {
3084
3178
  runBluxCommand
3085
3179
  };
3086
- //# sourceMappingURL=blux-OL5HKP26.js.map
3180
+ //# sourceMappingURL=blux-C24OVDDW.js.map