@iterant/site-runtime 3.11.1 → 3.11.2

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.
@@ -50,7 +50,7 @@ runtime and says so.
50
50
 
51
51
  <!-- generated: available libraries -->
52
52
 
53
- _Generated from package.json by scripts/generate-kit-table.mjs. Runtime 3.11.1._
53
+ _Generated from package.json by scripts/generate-kit-table.mjs. Runtime 3.11.2._
54
54
 
55
55
  **Toolchain** (this package owns the version; do NOT declare these):
56
56
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iterant/site-runtime",
3
- "version": "3.11.1",
3
+ "version": "3.11.2",
4
4
  "type": "module",
5
5
  "description": "The platform layer every Iterant brand site runs on: content grammar, collection schemas, SEO head and JSON-LD, layout core, Astro config preset, dev integrations and the verify gates.",
6
6
  "scripts": {
@@ -29,6 +29,26 @@ export function sitemapPageAllowed(
29
29
  }
30
30
  }
31
31
 
32
+ /** The serialize step's URL work, extracted so it can be tested: resolve the
33
+ * placeholder origin against the real site, then drop a URL this build has
34
+ * already emitted. The integration de-duplicates by exact string before
35
+ * serialize runs, so a route that is both a page entry and a prerendered
36
+ * shell arrives twice, under the crawl's real origin and under ours, and
37
+ * becomes one URL only here. Returning nothing drops the item. */
38
+ export function resolveSitemapUrl(
39
+ url: string,
40
+ site: string,
41
+ emitted: Set<string>,
42
+ ): string | undefined {
43
+ const resolved =
44
+ site && url.startsWith(PLACEHOLDER)
45
+ ? site + url.slice(PLACEHOLDER.length)
46
+ : url;
47
+ if (emitted.has(resolved)) return undefined;
48
+ emitted.add(resolved);
49
+ return resolved;
50
+ }
51
+
32
52
  export type SitemapWithCustomPagesOptions = SitemapOptions &
33
53
  SitemapPathsOptions;
34
54
 
@@ -36,6 +56,8 @@ export function sitemapWithCustomPages(
36
56
  options: SitemapWithCustomPagesOptions = {},
37
57
  ): AstroIntegration[] {
38
58
  let resolvedSite = "";
59
+ // Emptied per build in astro:config:done.
60
+ const emitted = new Set<string>();
39
61
  const { pagesDir, root, ...sitemapOptions } = options;
40
62
  const userSerialize = sitemapOptions.serialize;
41
63
  const userFilter = sitemapOptions.filter;
@@ -87,6 +109,7 @@ export function sitemapWithCustomPages(
87
109
  }
88
110
  },
89
111
  "astro:config:done": ({ config }) => {
112
+ emitted.clear();
90
113
  if (config.site) {
91
114
  resolvedSite = String(config.site).replace(/\/$/, "");
92
115
  }
@@ -100,9 +123,9 @@ export function sitemapWithCustomPages(
100
123
  sitemapPageAllowed(page, denied) &&
101
124
  (userFilter ? userFilter(page) : true),
102
125
  serialize(item) {
103
- if (resolvedSite && item.url.startsWith(PLACEHOLDER)) {
104
- item.url = resolvedSite + item.url.slice(PLACEHOLDER.length);
105
- }
126
+ const url = resolveSitemapUrl(item.url, resolvedSite, emitted);
127
+ if (!url) return undefined;
128
+ item.url = url;
106
129
  return userSerialize ? userSerialize(item) : item;
107
130
  },
108
131
  }),