@tokenoftrust/storefront-runner 3.11.0 → 3.11.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.
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* The question/answer pairs a page visibly carries, for a declared FAQPage node
|
|
3
3
|
* (lib/content/seo/structuredData.ts). Derived from the rendered content itself, so the markup can never
|
|
4
4
|
* claim an answer the page does not show: a heading phrased as a question, answered by the text
|
|
5
|
-
* up to the next heading
|
|
5
|
+
* up to the next heading, or a details/summary pair whose summary is the question and whose
|
|
6
|
+
* remaining text is the answer. A summary need not end in ?. Fewer than two pairs is not an FAQ.
|
|
6
7
|
*/
|
|
7
8
|
import type { ProseSection } from "@/lib/content/prose";
|
|
8
9
|
import { plainText } from "@/lib/content/richtext";
|
|
@@ -29,7 +30,17 @@ function atLeastTwo(items: FaqItem[]): FaqItem[] {
|
|
|
29
30
|
return answered.length >= MIN_PAIRS ? answered : [];
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
/**
|
|
33
|
+
/** One details element: its summary is the question, the rest of the element is the answer. */
|
|
34
|
+
function detailsPair(block: string): FaqItem | null {
|
|
35
|
+
const summary = /<summary\b[^>]*>[\s\S]*?<\/summary>/i.exec(block);
|
|
36
|
+
if (!summary) return null;
|
|
37
|
+
const q = textOf(summary[0]);
|
|
38
|
+
const at = summary.index ?? 0;
|
|
39
|
+
const rest = block.slice(0, at) + block.slice(at + summary[0].length);
|
|
40
|
+
return { q, a: textOf(rest) };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** FAQ pairs from sanitized body HTML: question-phrased h2–h4, plus every details/summary pair. */
|
|
33
44
|
export function faqFromHtml(html: string | undefined): FaqItem[] {
|
|
34
45
|
if (!html) return [];
|
|
35
46
|
const parts = html.split(/(<h[2-4][^>]*>[\s\S]*?<\/h[2-4]>)/i);
|
|
@@ -38,6 +49,10 @@ export function faqFromHtml(html: string | undefined): FaqItem[] {
|
|
|
38
49
|
const q = textOf(parts[i]!);
|
|
39
50
|
if (isQuestion(q)) items.push({ q, a: textOf(parts[i + 1] ?? "") });
|
|
40
51
|
}
|
|
52
|
+
for (const block of html.matchAll(/<details\b[^>]*>[\s\S]*?<\/details>/gi)) {
|
|
53
|
+
const pair = detailsPair(block[0]);
|
|
54
|
+
if (pair) items.push(pair);
|
|
55
|
+
}
|
|
41
56
|
return atLeastTwo(items);
|
|
42
57
|
}
|
|
43
58
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokenoftrust/storefront-runner",
|
|
3
|
-
"version": "3.11.
|
|
3
|
+
"version": "3.11.1",
|
|
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",
|