@stacklist-app/brandkit 1.3.2 → 1.3.3

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.
Files changed (2) hide show
  1. package/dist/engine.js +18 -3
  2. package/package.json +1 -1
package/dist/engine.js CHANGED
@@ -13,6 +13,18 @@
13
13
  var BASE = (typeof window !== 'undefined' && window.__BRANDKIT_BASE__)
14
14
  ? (String(window.__BRANDKIT_BASE__).replace(/\/+$/, '') || '.') : '.';
15
15
 
16
+ // Resolve a config-relative asset path (logo variants, brand.headerLogo/
17
+ // sidebarLogo) against BASE. Without this, a guide served from a base path
18
+ // with no trailing slash (e.g. /brand, not /brand/) resolves "logos/x.svg"
19
+ // relative to /brand -> /logos/x.svg -> 404. Absolute and data: URIs pass
20
+ // through untouched. Used for every <img> src and download href built from a
21
+ // config path so previews and downloads behave the same under a basePath.
22
+ function assetUrl(file) {
23
+ if (!file) return file;
24
+ if (/^([a-z]+:)?\/\//i.test(file) || file.indexOf('data:') === 0) return file;
25
+ return (BASE && BASE !== '.') ? BASE + '/' + file.replace(/^\/+/, '') : file;
26
+ }
27
+
16
28
  // Reveal the FOUC-gated shell. index.html hides .layout (opacity:0) until this
17
29
  // runs, so the default theme never flashes before the real brand paints. The
18
30
  // class is added once the first render pass below completes. Idempotent.
@@ -395,7 +407,7 @@
395
407
 
396
408
  return (
397
409
  '<div class="logo-card ' + bgClass + '" style="' + bgStyle + '" data-logo-idx="' + idx + '">' +
398
- '<img src="' + previewSrc + '" alt="' + logo.name + '">' +
410
+ '<img src="' + esc(assetUrl(previewSrc)) + '" alt="' + logo.name + '">' +
399
411
  '<div class="logo-name">' + logo.name + '</div>' +
400
412
  '<div class="logo-description">' + (logo.description || '') + '</div>' +
401
413
  '<div class="logo-controls">' +
@@ -436,6 +448,9 @@
436
448
 
437
449
  var filePath = logoData.variants[format];
438
450
  if (!filePath) return;
451
+ // Resolve against BASE so downloads work under a non-trailing-slash
452
+ // basePath, exactly as the previews above do.
453
+ filePath = assetUrl(filePath);
439
454
 
440
455
  var slug = cfg.brand.name || 'brand';
441
456
  var namePart = logoData.name.toLowerCase()
@@ -899,7 +914,7 @@
899
914
  var wordmark = document.getElementById('header-wordmark');
900
915
  if (wordmark) {
901
916
  if (cfg.brand.headerLogo) {
902
- wordmark.innerHTML = '<img class="header-logo" src="' + esc(cfg.brand.headerLogo) +
917
+ wordmark.innerHTML = '<img class="header-logo" src="' + esc(assetUrl(cfg.brand.headerLogo)) +
903
918
  '" alt="' + esc(cfg.brand.name || 'Logo') + '">';
904
919
  } else {
905
920
  wordmark.textContent = cfg.brand.name;
@@ -1005,7 +1020,7 @@
1005
1020
  var sidebarBrand = document.querySelector('.sidebar-brand');
1006
1021
  if (sidebarBrand) {
1007
1022
  if (cfg.brand.sidebarLogo) {
1008
- sidebarBrand.innerHTML = '<img class="sidebar-logo" src="' + esc(cfg.brand.sidebarLogo) +
1023
+ sidebarBrand.innerHTML = '<img class="sidebar-logo" src="' + esc(assetUrl(cfg.brand.sidebarLogo)) +
1009
1024
  '" alt="' + esc(cfg.brand.name || 'Logo') + '">';
1010
1025
  } else {
1011
1026
  sidebarBrand.textContent = cfg.brand.name || 'Brand';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stacklist-app/brandkit",
3
- "version": "1.3.2",
3
+ "version": "1.3.3",
4
4
  "description": "Config-driven brand guide that bolts onto any website. Zero dependencies.",
5
5
  "main": "lib/resolve.js",
6
6
  "bin": {