@tokenoftrust/storefront-runner 4.7.6 → 4.7.7
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.
|
@@ -169,9 +169,18 @@ export async function sitemapIndexResponse(context: APIContext): Promise<Respons
|
|
|
169
169
|
return new Response(renderSitemapIndexV1(context.locals.canonicalBase, children), { headers: XML_HEADERS });
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
+
/**
|
|
173
|
+
* The child path a request names: the last segment of the URL path. Read from the URL, never from
|
|
174
|
+
* `context.params`: a path-routed request (`/<domain>/sitemap-pages-1.xml`) reaches this endpoint
|
|
175
|
+
* through the middleware's rewrite, which leaves the catch-all's params on the context.
|
|
176
|
+
*/
|
|
177
|
+
export function sitemapChildPathOf(context: APIContext): string {
|
|
178
|
+
return `/${context.url.pathname.split("/").pop() ?? ""}`;
|
|
179
|
+
}
|
|
180
|
+
|
|
172
181
|
/** `/sitemap-<group>-<page>.xml`: one child's `<urlset>`, or 404 when the index names no such child. */
|
|
173
|
-
export async function sitemapChildResponse(context: APIContext
|
|
174
|
-
const named = parseSitemapChildPathV1(
|
|
182
|
+
export async function sitemapChildResponse(context: APIContext): Promise<Response> {
|
|
183
|
+
const named = parseSitemapChildPathV1(sitemapChildPathOf(context));
|
|
175
184
|
if (!named) return new Response("Not found", { status: 404, headers: { "content-type": "text/plain; charset=utf-8" } });
|
|
176
185
|
const children = await tenantSitemapChildren(context.locals);
|
|
177
186
|
const child = children.find((c) => c.group === named.group && c.page === named.page);
|
|
@@ -6,5 +6,5 @@ import type { APIContext } from "astro";
|
|
|
6
6
|
import { sitemapChildResponse } from "./_sitemap.js";
|
|
7
7
|
|
|
8
8
|
export function GET(context: APIContext): Promise<Response> {
|
|
9
|
-
return sitemapChildResponse(context
|
|
9
|
+
return sitemapChildResponse(context);
|
|
10
10
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokenoftrust/storefront-runner",
|
|
3
|
-
"version": "4.7.
|
|
3
|
+
"version": "4.7.7",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE",
|
|
5
5
|
"description": "World-shareable storefront runner: multi-tenant renderer on Astro/Cloudflare. No control plane.",
|
|
6
6
|
"packageManager": "pnpm@11.9.0",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, appendFileSync } from "node:fs";
|
|
19
19
|
import { dirname, join } from "node:path";
|
|
20
|
+
import { parseSitemapChildPathV1 } from "./sitemap-index.mjs";
|
|
20
21
|
|
|
21
22
|
/** Where `tot clone` puts each mounted space, relative to the root checkout: `spaces/<spaceId>/`. */
|
|
22
23
|
export const SPACES_DIR = "spaces";
|
|
@@ -26,7 +27,9 @@ export const TOPOLOGY_VERSION = 1;
|
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* Platform-owned paths no space serves (packages/public-runtime PUBLICATION_SPACE_RESERVED_MOUNTS;
|
|
29
|
-
* the ownership parity test holds the two equal).
|
|
30
|
+
* the ownership parity test holds the two equal). Child sitemaps (`/sitemap-<group>-<page>.xml`) are
|
|
31
|
+
* platform-owned too, recognized by `parseSitemapChildPathV1` (a byte-identical copy of
|
|
32
|
+
* packages/public-runtime/src/sitemap-index.mjs, pinned by test/sitemap-index-copy.test.mjs).
|
|
30
33
|
*/
|
|
31
34
|
export const PLATFORM_PATHS = Object.freeze([
|
|
32
35
|
"/.well-known", "/__evidence", "/__preview", "/_a", "/_astro", "/_style-guide", "/admin", "/api",
|
|
@@ -167,7 +170,9 @@ export function owningSpace(topology, urlPath) {
|
|
|
167
170
|
const path = normalizeRequestPath(urlPath);
|
|
168
171
|
if (path === null) return null;
|
|
169
172
|
const folded = path.toLowerCase();
|
|
170
|
-
if (PLATFORM_PATHS.some((reserved) => mountMatchesPath(reserved, folded))
|
|
173
|
+
if (PLATFORM_PATHS.some((reserved) => mountMatchesPath(reserved, folded)) || parseSitemapChildPathV1(folded) !== null) {
|
|
174
|
+
return { space: null, via: "platform" };
|
|
175
|
+
}
|
|
171
176
|
/** @type {{ space: TopologySpace, via: "mount"|"alias", mount: string } | null} */
|
|
172
177
|
let best = null;
|
|
173
178
|
for (const space of topology.spaces) {
|
|
@@ -44,8 +44,9 @@ export function sitemapChildPathV1(group, page) {
|
|
|
44
44
|
export function parseSitemapChildPathV1(path) {
|
|
45
45
|
if (typeof path !== "string") return null;
|
|
46
46
|
const match = CHILD_PATH.exec(path);
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
const group = match?.[1];
|
|
48
|
+
if (!match || group === undefined || !SITEMAP_GROUPS_V1.includes(group)) return null;
|
|
49
|
+
return { group, page: Number(match[2]) };
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
/** True for `/sitemap.xml` and for every well-formed child sitemap path. @param {string} path */
|
|
@@ -139,7 +140,7 @@ export function isSitemapIndexXmlV1(xml) {
|
|
|
139
140
|
*/
|
|
140
141
|
export function sitemapIndexLocsV1(xml) {
|
|
141
142
|
if (!isSitemapIndexXmlV1(xml)) return [];
|
|
142
|
-
return [...xml.matchAll(/<sitemap>\s*<loc>([^<]*)<\/loc>/g)].map((match) => match[1].trim());
|
|
143
|
+
return [...xml.matchAll(/<sitemap>\s*<loc>([^<]*)<\/loc>/g)].map((match) => (match[1] ?? "").trim());
|
|
143
144
|
}
|
|
144
145
|
|
|
145
146
|
/**
|