@hagicode/hagilight-core 0.7.1-dev.80.1.bc52dbd → 0.7.1-dev.82.1.769c313

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.
package/README.md CHANGED
@@ -35,6 +35,10 @@ import { resolveSiteLinks } from '@hagicode/hagilight-core/links';
35
35
  const links = resolveSiteLinks('en-US');
36
36
  ```
37
37
 
38
+ ## Promotion platforms
39
+
40
+ The shared banner (`PromotoBanner`, `loadActivePromotions`) displays only promotions whose `platforms` array in Index's `/promote.json` includes `web`, in addition to being enabled, inside their activation window, and matched with `/promote_content.json`. This follows the `platforms` flag documented in the Index README. An entry whose `platforms` is missing, empty, or not an array of strings is not displayed, other values such as `hagicode` are ignored, and matching is exact (`Web` does not match). When no promotion remains, the banner shows its site fallback or stays hidden, as before.
41
+
38
42
  ## Google Analytics click events
39
43
 
40
44
  `GoogleAnalytics` also reports clicks on the key links and download buttons that the shared components render. There is nothing to configure: events follow the same rules as page views, so they are sent only on production pages where Google Analytics is enabled, never on the Starlight 404 page, and silently skipped when `gtag` is missing (development builds, blocked scripts).
@@ -19,6 +19,7 @@ interface PromotionFlag {
19
19
  on: boolean;
20
20
  startTime?: string;
21
21
  endTime?: string;
22
+ platforms: string[];
22
23
  }
23
24
  interface PromotionContent {
24
25
  id: string;
@@ -2,6 +2,7 @@ const INDEX_ORIGIN = 'https://index.hagicode.com';
2
2
  const CATALOG_URL = `${INDEX_ORIGIN}/index-catalog.json`;
3
3
  const FLAGS_URL = `${INDEX_ORIGIN}/promote.json`;
4
4
  const CONTENT_URL = `${INDEX_ORIGIN}/promote_content.json`;
5
+ const DISPLAY_PLATFORM = 'web';
5
6
  function isRecord(value) {
6
7
  return typeof value === 'object' && value !== null && !Array.isArray(value);
7
8
  }
@@ -65,6 +66,9 @@ function isSafeLink(value) {
65
66
  return false;
66
67
  }
67
68
  }
69
+ function parsePlatforms(value) {
70
+ return Array.isArray(value) && value.every((platform) => typeof platform === 'string') ? value : [];
71
+ }
68
72
  export function parsePromotionFlags(payload) {
69
73
  if (!isRecord(payload) || !Array.isArray(payload.promotes))
70
74
  return [];
@@ -76,6 +80,7 @@ export function parsePromotionFlags(payload) {
76
80
  on: item.on,
77
81
  startTime: nonEmptyString(item.startTime) ? item.startTime.trim() : undefined,
78
82
  endTime: nonEmptyString(item.endTime) ? item.endTime.trim() : undefined,
83
+ platforms: parsePlatforms(item.platforms),
79
84
  }];
80
85
  });
81
86
  }
@@ -147,7 +152,7 @@ export function normalizeActivePromotions(flags, content, locale, now = Date.now
147
152
  const contentById = new Map(content.map((item) => [item.id, item]));
148
153
  return flags.flatMap((flag) => {
149
154
  const item = contentById.get(flag.id);
150
- if (!isActive(flag, now) || !item)
155
+ if (!isActive(flag, now) || !flag.platforms?.includes(DISPLAY_PLATFORM) || !item)
151
156
  return [];
152
157
  const title = localized(item.title, locale);
153
158
  const description = localized(item.description, locale);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hagicode/hagilight-core",
3
- "version": "0.7.1-dev.80.1.bc52dbd",
3
+ "version": "0.7.1-dev.82.1.769c313",
4
4
  "type": "module",
5
5
  "description": "Shared TypeScript utilities, components, and assets for HagiCode Astro and Starlight sites",
6
6
  "repository": {