@wix/web5-core 1.59.0 → 1.61.0
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/dist/cjs/component/componentDefinitions/ComparisonSectionDefinition.js +33 -1
- package/dist/cjs/component/componentDefinitions/ComparisonSectionDefinition.js.map +1 -1
- package/dist/cjs/component/componentDefinitions/FeatureSection9PlusDefinition.js +9 -5
- package/dist/cjs/component/componentDefinitions/FeatureSection9PlusDefinition.js.map +1 -1
- package/dist/cjs/component/componentDefinitions/listItemsSectionDefinition.js +10 -5
- package/dist/cjs/component/componentDefinitions/listItemsSectionDefinition.js.map +1 -1
- package/dist/cjs/component/componentDefinitions/parse-utils.js +45 -8
- package/dist/cjs/component/componentDefinitions/parse-utils.js.map +1 -1
- package/dist/cjs/component/componentParser.js +15 -0
- package/dist/cjs/component/componentParser.js.map +1 -1
- package/dist/cjs/component/section-definition.js +14 -0
- package/dist/cjs/component/section-definition.js.map +1 -1
- package/dist/cjs/components/ui/MarkdownText.js +41 -42
- package/dist/cjs/components/ui/MarkdownText.js.map +1 -1
- package/dist/cjs/components/ui/UnifiedLink.js +22 -10
- package/dist/cjs/components/ui/UnifiedLink.js.map +1 -1
- package/dist/cjs/index.js +5 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/styles/base-tokens.css +0 -26
- package/dist/cjs/styles/tailwind-theme.css +0 -17
- package/dist/cjs/utils/markdownPreprocessor.js +162 -8
- package/dist/cjs/utils/markdownPreprocessor.js.map +1 -1
- package/dist/esm/component/componentDefinitions/ComparisonSectionDefinition.js +34 -1
- package/dist/esm/component/componentDefinitions/ComparisonSectionDefinition.js.map +1 -1
- package/dist/esm/component/componentDefinitions/FeatureSection9PlusDefinition.js +10 -6
- package/dist/esm/component/componentDefinitions/FeatureSection9PlusDefinition.js.map +1 -1
- package/dist/esm/component/componentDefinitions/listItemsSectionDefinition.js +11 -6
- package/dist/esm/component/componentDefinitions/listItemsSectionDefinition.js.map +1 -1
- package/dist/esm/component/componentDefinitions/parse-utils.js +44 -8
- package/dist/esm/component/componentDefinitions/parse-utils.js.map +1 -1
- package/dist/esm/component/componentParser.js +15 -0
- package/dist/esm/component/componentParser.js.map +1 -1
- package/dist/esm/component/section-definition.js +13 -1
- package/dist/esm/component/section-definition.js.map +1 -1
- package/dist/esm/components/ui/MarkdownText.js +8 -9
- package/dist/esm/components/ui/MarkdownText.js.map +1 -1
- package/dist/esm/components/ui/UnifiedLink.js +7 -1
- package/dist/esm/components/ui/UnifiedLink.js.map +1 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/styles/base-tokens.css +0 -26
- package/dist/esm/styles/tailwind-theme.css +0 -17
- package/dist/esm/utils/markdownPreprocessor.js +160 -8
- package/dist/esm/utils/markdownPreprocessor.js.map +1 -1
- package/dist/types/component/componentDefinitions/ComparisonSectionDefinition.d.ts +2 -2
- package/dist/types/component/componentDefinitions/ComparisonSectionDefinition.d.ts.map +1 -1
- package/dist/types/component/componentDefinitions/FeatureSection9PlusDefinition.d.ts.map +1 -1
- package/dist/types/component/componentDefinitions/listItemsSectionDefinition.d.ts.map +1 -1
- package/dist/types/component/componentDefinitions/parse-utils.d.ts +10 -0
- package/dist/types/component/componentDefinitions/parse-utils.d.ts.map +1 -1
- package/dist/types/component/componentParser.d.ts.map +1 -1
- package/dist/types/component/section-definition.d.ts +13 -1
- package/dist/types/component/section-definition.d.ts.map +1 -1
- package/dist/types/components/ui/MarkdownText.d.ts +13 -0
- package/dist/types/components/ui/MarkdownText.d.ts.map +1 -1
- package/dist/types/components/ui/UnifiedLink.d.ts +1 -1
- package/dist/types/components/ui/UnifiedLink.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/utils/markdownPreprocessor.d.ts +30 -5
- package/dist/types/utils/markdownPreprocessor.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/styles/base-tokens.css +0 -26
- package/src/styles/tailwind-theme.css +0 -17
|
@@ -203,6 +203,42 @@ export function parseKpiItem(markdown) {
|
|
|
203
203
|
description
|
|
204
204
|
};
|
|
205
205
|
}
|
|
206
|
+
|
|
207
|
+
/** Join inline tokens the way prose reads: single spaces, none before punctuation. */
|
|
208
|
+
function appendInlineToken(current, token) {
|
|
209
|
+
const trimmed = token.trim();
|
|
210
|
+
if (!trimmed) {
|
|
211
|
+
return current;
|
|
212
|
+
}
|
|
213
|
+
if (!current) {
|
|
214
|
+
return trimmed;
|
|
215
|
+
}
|
|
216
|
+
if (/^[,.;:!?)]/.test(trimmed)) {
|
|
217
|
+
return `${current}${trimmed}`;
|
|
218
|
+
}
|
|
219
|
+
return `${current} ${trimmed}`;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Serialize a run of inline parts back to markdown, preserving links.
|
|
224
|
+
*
|
|
225
|
+
* Concatenating `part.content` alone silently deletes links: a `link` part
|
|
226
|
+
* keeps its label in `content` and its url in `meta.href`, so a filter that
|
|
227
|
+
* reads only text parts turns `Read the [pricing page](/pricing) first` into
|
|
228
|
+
* `Read the first` — url and label both vanish, with nothing in the output to
|
|
229
|
+
* show anything was lost.
|
|
230
|
+
*/
|
|
231
|
+
export function inlinePartsToMarkdown(parts) {
|
|
232
|
+
return parts.reduce((text, part) => {
|
|
233
|
+
if (part.type === 'link') {
|
|
234
|
+
var _meta2, _part$content;
|
|
235
|
+
const href = ((_meta2 = part.meta) == null ? void 0 : _meta2.href) ?? '';
|
|
236
|
+
const label = ((_part$content = part.content) == null ? void 0 : _part$content.trim()) ?? '';
|
|
237
|
+
return appendInlineToken(text, href ? `[${label}](${href})` : label);
|
|
238
|
+
}
|
|
239
|
+
return appendInlineToken(text, part.content ?? '');
|
|
240
|
+
}, '');
|
|
241
|
+
}
|
|
206
242
|
export function extractListItemText(item) {
|
|
207
243
|
var _item$meta2;
|
|
208
244
|
if (item.content) {
|
|
@@ -302,8 +338,8 @@ export function extractEntityRefs(parts) {
|
|
|
302
338
|
var _list$meta4, _item$meta4;
|
|
303
339
|
const itemParts = ((_item$meta4 = item.meta) == null ? void 0 : _item$meta4.parts) ?? [];
|
|
304
340
|
const entityLinks = itemParts.filter(p => {
|
|
305
|
-
var
|
|
306
|
-
return p.type === 'link' && isEntityHref((
|
|
341
|
+
var _meta3;
|
|
342
|
+
return p.type === 'link' && isEntityHref((_meta3 = p.meta) == null ? void 0 : _meta3.href);
|
|
307
343
|
});
|
|
308
344
|
for (const link of entityLinks) {
|
|
309
345
|
const parsed = parseEntityUrl(link.meta.href);
|
|
@@ -362,18 +398,18 @@ export function extractEntityRefs(parts) {
|
|
|
362
398
|
if (linkIndex >= 0) {
|
|
363
399
|
// Scan following parts for description, image, callout, and list items
|
|
364
400
|
for (let j = linkIndex + 1; j < parts.length; j++) {
|
|
365
|
-
var
|
|
401
|
+
var _meta4, _p$content3;
|
|
366
402
|
const p = parts[j];
|
|
367
403
|
// Stop at next entity link
|
|
368
|
-
if (p.type === 'link' && isEntityHref((
|
|
404
|
+
if (p.type === 'link' && isEntityHref((_meta4 = p.meta) == null ? void 0 : _meta4.href)) {
|
|
369
405
|
break;
|
|
370
406
|
}
|
|
371
407
|
if (p.type === 'text' && (_p$content3 = p.content) != null && _p$content3.trim()) {
|
|
372
408
|
const text = markdownOrText(p);
|
|
373
409
|
description = description ? `${description} ${text}` : text;
|
|
374
410
|
} else if (p.type === 'image' && !markdownImageUrl) {
|
|
375
|
-
var
|
|
376
|
-
markdownImageUrl = (
|
|
411
|
+
var _meta5;
|
|
412
|
+
markdownImageUrl = (_meta5 = p.meta) == null ? void 0 : _meta5.src;
|
|
377
413
|
} else if ((p.type === 'callout' || p.type === 'blockquote') && !callout) {
|
|
378
414
|
var _p$meta4;
|
|
379
415
|
const raw = ((_p$meta4 = p.meta) == null || (_p$meta4 = _p$meta4.markdown) == null ? void 0 : _p$meta4.trim()) || str(p);
|
|
@@ -385,8 +421,8 @@ export function extractEntityRefs(parts) {
|
|
|
385
421
|
};
|
|
386
422
|
}
|
|
387
423
|
} else if (p.type === 'list') {
|
|
388
|
-
for (const item of ((
|
|
389
|
-
var
|
|
424
|
+
for (const item of ((_meta6 = p.meta) == null ? void 0 : _meta6.items) ?? []) {
|
|
425
|
+
var _meta6;
|
|
390
426
|
const text = extractListItemText(item);
|
|
391
427
|
if (text) {
|
|
392
428
|
features.push(text);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["getPartsByType","getHeading","getImages","getLinks","parseWeb5Url","Web5UrlType","isWeb5EntityUrl","str","p","_p$content","content","trim","markdownOrText","_p$meta","meta","markdown","normalizeEntityDescription","description","replace","stripMarkdown","md","headingText","parts","level","heading","headingMarkdown","_meta$markdown","bodyText","textParts","richTextParts","map","filter","Boolean","join","entitySectionBodyText","firstEntityLinkIndex","findIndex","_meta","type","isEntityHref","href","sectionParts","slice","linksToHeroButtons","links","length","lists","flatMap","l","_l$meta","items","item","_item$meta","i","_l$content","id","text","variant","onClick","firstImageSrc","_img$meta","images","img","src","undefined","firstLink","_link$content","link","blockquoteText","bqs","_p$meta2","calloutFromParts","_p$meta3","calloutParts","raw","parsed","parseCalloutTag","kind","listToMarkdown","lines","list","_list$meta","extractListItemText","push","parseEntityUrl","url","trimmedUrl","ENTITY","entityType","entityId","parseTableValue","value","normalized","toLowerCase","parseKpiItem","trimmed","boldMatch","match","title","afterBold","indexOf","_item$meta2","partsToMarkdown","inline","part","_part$meta","_part$meta2","repeat","_list$meta2","_item$meta3","toUpperCase","generatePartId","Math","random","toString","extractNestedListItems","itemParts","nestedLists","features","nested","_list$meta3","extractEntityRefs","entities","_list$meta4","_item$meta4","entityLinks","_meta2","_link$content2","_images$","_p$content2","callout","_calloutParts$0$meta","parsed2","linkText","entityUrl","markdownImageUrl","markdownFeatures","topLinks","_l$meta2","some","e","_link$content3","linkIndex","j","_meta3","_p$content3","_meta4","_p$meta4","parsedCallout","_meta5"],"sources":["../../../../src/component/componentDefinitions/parse-utils.ts"],"sourcesContent":["import type {\n Part,\n ListPart,\n LinkPart,\n ListItemPart,\n ImagePart,\n} from '../../parts/parts';\nimport {\n getPartsByType,\n getHeading,\n getImages,\n getLinks,\n} from '../../parts/parts';\nimport { parseWeb5Url } from '../../utils/entityLinkParser';\nimport { Web5UrlType, isWeb5EntityUrl } from '../../types/link-types';\nimport type { Callout } from '../../types/callout';\nimport type { HeroButton } from '../types';\n\nfunction str(p: Part | undefined): string {\n return p?.content?.trim() ?? '';\n}\n\nfunction markdownOrText(p: Part): string {\n return ((p.meta?.markdown as string)?.trim() || str(p)).trim();\n}\n\nfunction normalizeEntityDescription(description: string): string {\n return description\n .replace(/^[\\s\\u2013\\u2014-]+/, '')\n .replace(/^[:\\s]+/, '')\n .trim();\n}\n\n/** Strip basic markdown formatting to get plain text */\nexport function stripMarkdown(md: string): string {\n return md\n .replace(/\\*\\*(.+?)\\*\\*/g, '$1')\n .replace(/__(.+?)__/g, '$1')\n .replace(/\\*(.+?)\\*/g, '$1')\n .replace(/_(.+?)_/g, '$1')\n .replace(/~~(.+?)~~/g, '$1')\n .replace(/`(.+?)`/g, '$1')\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1')\n .trim();\n}\n\nexport function headingText(parts: Part[], level?: number): string {\n const heading = getHeading(parts, level);\n return str(heading);\n}\n\n/** Like headingText but preserves inline markdown formatting (bold, italic, etc.) */\nexport function headingMarkdown(parts: Part[], level?: number): string {\n const heading = getHeading(parts, level);\n if (!heading) {\n return '';\n }\n const meta = heading.meta as Record<string, unknown>;\n return (meta?.markdown as string)?.trim() || str(heading);\n}\n\nexport function bodyText(parts: Part[]): string {\n const textParts = getPartsByType<Part>(parts, 'text');\n const richTextParts = getPartsByType<Part>(parts, 'richText');\n return [...textParts, ...richTextParts]\n .map(markdownOrText)\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/**\n * Entity sections may be authored as one paragraph per entity:\n * `[Product](web5://entity/...) - why it matches`.\n * In that shape, text after the first entity link is item copy rather than\n * section copy, so only keep prose that appears before the first entity link.\n */\nexport function entitySectionBodyText(parts: Part[]): string {\n const firstEntityLinkIndex = parts.findIndex(\n (p) => p.type === 'link' && isEntityHref((p as LinkPart).meta?.href),\n );\n const sectionParts =\n firstEntityLinkIndex >= 0 ? parts.slice(0, firstEntityLinkIndex) : parts;\n\n return sectionParts\n .filter((p) => p.type === 'text' || p.type === 'richText')\n .map(markdownOrText)\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/** Build HeroButton[] from link parts — aligned to HeroSection1Button shape */\nexport function linksToHeroButtons(parts: Part[]): HeroButton[] {\n let links = getLinks(parts);\n if (!links.length) {\n const lists = getPartsByType<ListPart>(parts, 'list');\n links = lists.flatMap((l) =>\n (l.meta?.items ?? []).flatMap((item) =>\n ((item.meta?.parts ?? []) as Part[]).filter(\n (p): p is LinkPart => p.type === 'link',\n ),\n ),\n );\n }\n return links.map(\n (l, i): HeroButton => ({\n id: `btn-${i}`,\n text: l.content?.trim() || 'Learn more',\n variant: i === 0 ? 'primary' : 'secondary',\n onClick: l.meta.href,\n }),\n );\n}\n\n/** Return just the src URL string of the first image part */\nexport function firstImageSrc(parts: Part[]): string | undefined {\n const images = getImages(parts);\n const img = images[0];\n return img?.meta?.src || undefined;\n}\n\n/** Return the first link as { text, href } */\nexport function firstLink(\n parts: Part[],\n): { text: string; href: string } | undefined {\n const links = getLinks(parts);\n const link = links[0];\n if (!link) {\n return undefined;\n }\n return { text: link.content?.trim() || '', href: link.meta.href };\n}\n\n/** Extract text content from blockquote parts, preserving markdown formatting when available */\nexport function blockquoteText(parts: Part[]): string | undefined {\n const bqs = getPartsByType<Part>(parts, 'blockquote');\n if (bqs.length === 0) {\n return undefined;\n }\n const text = bqs\n .map((p) => (p.meta?.markdown as string)?.trim() || str(p))\n .filter(Boolean)\n .join('\\n');\n return text || undefined;\n}\n\n/** Extract first callout from parts as a Callout object */\nexport function calloutFromParts(parts: Part[]): Callout | undefined {\n const calloutParts = getPartsByType<Part>(parts, 'callout');\n if (calloutParts.length === 0) {\n return undefined;\n }\n const p = calloutParts[0];\n const raw = (p.meta?.markdown as string)?.trim() || str(p);\n const parsed = parseCalloutTag(raw);\n return parsed.text ? { text: parsed.text, kind: parsed.kind } : undefined;\n}\n\n/** Convert list parts to a markdown-like string */\nexport function listToMarkdown(parts: Part[]): string | undefined {\n const lists = getPartsByType<ListPart>(parts, 'list');\n if (lists.length === 0) {\n return undefined;\n }\n const lines: string[] = [];\n for (const list of lists) {\n const items = list.meta?.items ?? [];\n for (const item of items) {\n const text = extractListItemText(item);\n if (text) {\n lines.push(`- ${text}`);\n }\n }\n }\n return lines.length > 0 ? lines.join('\\n') : undefined;\n}\n\n/**\n * Parse a web5://entity/ URL into entityType and entityId.\n * Delegates to the central `parseWeb5Url` parser.\n */\nexport function parseEntityUrl(\n url: string,\n): { entityType: string; entityId: string } | null {\n const trimmedUrl = url?.trim();\n if (!trimmedUrl || !isWeb5EntityUrl(trimmedUrl)) {\n return null;\n }\n const parsed = parseWeb5Url(trimmedUrl);\n if (\n parsed?.type !== Web5UrlType.ENTITY ||\n !parsed.entityType ||\n !parsed.entityId\n ) {\n return null;\n }\n return { entityType: parsed.entityType, entityId: parsed.entityId };\n}\n\n/**\n * Parse a table cell value into boolean or string.\n * Ported from web50-server-ui comparisonSectionParser.tsx.\n */\nexport function parseTableValue(value: string): boolean | string {\n const normalized = value.trim().toLowerCase();\n\n if (\n normalized === 'true' ||\n normalized === 'yes' ||\n normalized === '✓' ||\n normalized === 'check' ||\n normalized === 'y'\n ) {\n return true;\n }\n if (\n normalized === 'false' ||\n normalized === 'no' ||\n normalized === '✗' ||\n normalized === 'x' ||\n normalized === 'n' ||\n normalized === ''\n ) {\n return false;\n }\n\n return value.trim();\n}\n\n/**\n * Parse a KPI item from markdown text.\n * The first **bold** segment becomes the title; everything after it (leading \":\" stripped) is the description.\n */\nexport function parseKpiItem(\n markdown: string,\n): { title: string; description: string } | null {\n const trimmed = markdown.trim();\n if (!trimmed) {\n return null;\n }\n const boldMatch = trimmed.match(/\\*\\*(.+?)\\*\\*/);\n if (!boldMatch) {\n return null;\n }\n const title = boldMatch[1].trim();\n const afterBold = trimmed.slice(\n trimmed.indexOf(boldMatch[0]) + boldMatch[0].length,\n );\n const description = afterBold.replace(/^[:\\s]+/, '').trim();\n return { title, description };\n}\n\nexport function extractListItemText(item: ListItemPart): string {\n if (item.content) {\n return item.content;\n }\n if (item.meta?.parts) {\n return (item.meta.parts as Part[])\n .map((p) => p.content)\n .filter(Boolean)\n .join(' ');\n }\n return '';\n}\n\n/**\n * Reconstruct markdown-like content from parts.\n *\n * `part.content` is the *plain* text — `nodesToParts` strips inline\n * formatting and preserves the original markdown (bold, italic, links) in\n * `part.meta.markdown` when they differ. Prefer it so markdown-rendering\n * consumers (e.g. the fallback section's ReactMarkdown) keep `**bold**`.\n */\nexport function partsToMarkdown(sectionParts: Part[]): string {\n const inline = (part: Part): string =>\n (part.meta?.markdown as string | undefined) ?? part.content;\n const lines: string[] = [];\n for (const part of sectionParts) {\n if (part.type === 'heading') {\n const level = (part.meta as { level: number })?.level ?? 2;\n lines.push(`${'#'.repeat(level)} ${inline(part)}`);\n } else if (part.type === 'text' || part.type === 'richText') {\n lines.push(inline(part));\n } else if (part.type === 'list') {\n const list = part as ListPart;\n for (const item of list.meta?.items ?? []) {\n lines.push(\n `- ${(item.meta?.markdown as string | undefined) ?? extractListItemText(item)}`,\n );\n }\n } else if (part.type === 'blockquote' || part.type === 'callout') {\n lines.push(`> ${inline(part)}`);\n }\n }\n return lines.join('\\n\\n');\n}\n\n/**\n * Extract callout kind tag from blockquote text.\n * Handles [!NOTE], [!TIP], [!IMPORTANT], [!WARNING], [!CAUTION] GFM syntax.\n */\nexport function parseCalloutTag(text: string): { text: string; kind?: string } {\n const match = text.match(/^\\[!(\\w+)\\]\\s*(.*)/s);\n if (match) {\n return { kind: match[1].toUpperCase(), text: match[2].trim() };\n }\n return { text: text.trim() };\n}\n\n/** Generate a simple unique ID */\nexport function generatePartId(): string {\n return Math.random().toString(36).slice(2, 10);\n}\n\nfunction isEntityHref(href: string | undefined): boolean {\n return !!href && isWeb5EntityUrl(href);\n}\n\nexport interface EntityRef {\n entityId: string;\n entityType: string;\n linkText: string;\n entityUrl: string;\n description: string;\n markdownImageUrl?: string;\n markdownFeatures?: string[];\n callout?: Callout;\n}\n\n/**\n * Extract text from nested list items within a list item's parts.\n */\nfunction extractNestedListItems(itemParts: Part[]): string[] {\n const nestedLists = itemParts.filter((p): p is ListPart => p.type === 'list');\n const features: string[] = [];\n for (const list of nestedLists) {\n for (const nested of list.meta?.items ?? []) {\n const text = extractListItemText(nested);\n if (text) {\n features.push(text);\n }\n }\n }\n return features;\n}\n\n/**\n * Extract entity references from list items containing web5://entity/ links.\n * Also extracts markdownFeatures from nested list items within each entity item.\n */\nexport function extractEntityRefs(parts: Part[]): EntityRef[] {\n const entities: EntityRef[] = [];\n const lists = getPartsByType<ListPart>(parts, 'list');\n\n for (const list of lists) {\n for (const item of list.meta?.items ?? []) {\n const itemParts = (item.meta?.parts ?? []) as Part[];\n const entityLinks = itemParts.filter(\n (p): p is LinkPart =>\n p.type === 'link' && isEntityHref((p as LinkPart).meta?.href),\n );\n\n for (const link of entityLinks) {\n const parsed = parseEntityUrl(link.meta.href);\n if (parsed) {\n const images = itemParts.filter(\n (p): p is ImagePart => p.type === 'image',\n );\n const textParts = itemParts.filter(\n (p) => p.type === 'text' && p.content?.trim(),\n );\n const description = normalizeEntityDescription(\n textParts.map(markdownOrText).join(' '),\n );\n const features = extractNestedListItems(itemParts);\n const calloutParts = itemParts.filter(\n (p) => p.type === 'callout' || p.type === 'blockquote',\n );\n let callout: Callout | undefined;\n if (calloutParts.length > 0) {\n const raw =\n (calloutParts[0].meta?.markdown as string)?.trim() ||\n str(calloutParts[0]);\n const parsed2 = parseCalloutTag(raw);\n if (parsed2.text) {\n callout = { text: parsed2.text, kind: parsed2.kind };\n }\n }\n entities.push({\n entityId: parsed.entityId,\n entityType: parsed.entityType,\n linkText: link.content?.trim() || '',\n entityUrl: link.meta.href,\n description,\n markdownImageUrl: images[0]?.meta?.src,\n markdownFeatures: features.length > 0 ? features : undefined,\n callout,\n });\n }\n }\n }\n }\n\n // Also check top-level links (with surrounding context for description/image/list)\n const topLinks = getLinks(parts).filter((l) => isEntityHref(l.meta?.href));\n for (const link of topLinks) {\n const parsed = parseEntityUrl(link.meta.href);\n if (parsed && !entities.some((e) => e.entityId === parsed.entityId)) {\n // Look for description text and image after this link in the parts array\n const linkIndex = parts.indexOf(link);\n let description = '';\n let markdownImageUrl: string | undefined;\n let callout: Callout | undefined;\n const features: string[] = [];\n\n if (linkIndex >= 0) {\n // Scan following parts for description, image, callout, and list items\n for (let j = linkIndex + 1; j < parts.length; j++) {\n const p = parts[j];\n // Stop at next entity link\n if (p.type === 'link' && isEntityHref((p as LinkPart).meta?.href)) {\n break;\n }\n if (p.type === 'text' && p.content?.trim()) {\n const text = markdownOrText(p);\n description = description\n ? `${description} ${text}`\n : text;\n } else if (p.type === 'image' && !markdownImageUrl) {\n markdownImageUrl = (p as ImagePart).meta?.src;\n } else if (\n (p.type === 'callout' || p.type === 'blockquote') &&\n !callout\n ) {\n const raw = (p.meta?.markdown as string)?.trim() || str(p);\n const parsedCallout = parseCalloutTag(raw);\n if (parsedCallout.text) {\n callout = { text: parsedCallout.text, kind: parsedCallout.kind };\n }\n } else if (p.type === 'list') {\n for (const item of (p as ListPart).meta?.items ?? []) {\n const text = extractListItemText(item);\n if (text) {\n features.push(text);\n }\n }\n }\n }\n }\n\n entities.push({\n entityId: parsed.entityId,\n entityType: parsed.entityType,\n linkText: link.content?.trim() || '',\n entityUrl: link.meta.href,\n description: normalizeEntityDescription(description),\n markdownImageUrl,\n markdownFeatures: features.length > 0 ? features : undefined,\n callout,\n });\n }\n }\n\n return entities;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["getPartsByType","getHeading","getImages","getLinks","parseWeb5Url","Web5UrlType","isWeb5EntityUrl","str","p","_p$content","content","trim","markdownOrText","_p$meta","meta","markdown","normalizeEntityDescription","description","replace","stripMarkdown","md","headingText","parts","level","heading","headingMarkdown","_meta$markdown","bodyText","textParts","richTextParts","map","filter","Boolean","join","entitySectionBodyText","firstEntityLinkIndex","findIndex","_meta","type","isEntityHref","href","sectionParts","slice","linksToHeroButtons","links","length","lists","flatMap","l","_l$meta","items","item","_item$meta","i","_l$content","id","text","variant","onClick","firstImageSrc","_img$meta","images","img","src","undefined","firstLink","_link$content","link","blockquoteText","bqs","_p$meta2","calloutFromParts","_p$meta3","calloutParts","raw","parsed","parseCalloutTag","kind","listToMarkdown","lines","list","_list$meta","extractListItemText","push","parseEntityUrl","url","trimmedUrl","ENTITY","entityType","entityId","parseTableValue","value","normalized","toLowerCase","parseKpiItem","trimmed","boldMatch","match","title","afterBold","indexOf","appendInlineToken","current","token","test","inlinePartsToMarkdown","reduce","part","_meta2","_part$content","label","_item$meta2","partsToMarkdown","inline","_part$meta","_part$meta2","repeat","_list$meta2","_item$meta3","toUpperCase","generatePartId","Math","random","toString","extractNestedListItems","itemParts","nestedLists","features","nested","_list$meta3","extractEntityRefs","entities","_list$meta4","_item$meta4","entityLinks","_meta3","_link$content2","_images$","_p$content2","callout","_calloutParts$0$meta","parsed2","linkText","entityUrl","markdownImageUrl","markdownFeatures","topLinks","_l$meta2","some","e","_link$content3","linkIndex","j","_meta4","_p$content3","_meta5","_p$meta4","parsedCallout","_meta6"],"sources":["../../../../src/component/componentDefinitions/parse-utils.ts"],"sourcesContent":["import type {\n Part,\n ListPart,\n LinkPart,\n ListItemPart,\n ImagePart,\n} from '../../parts/parts';\nimport {\n getPartsByType,\n getHeading,\n getImages,\n getLinks,\n} from '../../parts/parts';\nimport { parseWeb5Url } from '../../utils/entityLinkParser';\nimport { Web5UrlType, isWeb5EntityUrl } from '../../types/link-types';\nimport type { Callout } from '../../types/callout';\nimport type { HeroButton } from '../types';\n\nfunction str(p: Part | undefined): string {\n return p?.content?.trim() ?? '';\n}\n\nfunction markdownOrText(p: Part): string {\n return ((p.meta?.markdown as string)?.trim() || str(p)).trim();\n}\n\nfunction normalizeEntityDescription(description: string): string {\n return description\n .replace(/^[\\s\\u2013\\u2014-]+/, '')\n .replace(/^[:\\s]+/, '')\n .trim();\n}\n\n/** Strip basic markdown formatting to get plain text */\nexport function stripMarkdown(md: string): string {\n return md\n .replace(/\\*\\*(.+?)\\*\\*/g, '$1')\n .replace(/__(.+?)__/g, '$1')\n .replace(/\\*(.+?)\\*/g, '$1')\n .replace(/_(.+?)_/g, '$1')\n .replace(/~~(.+?)~~/g, '$1')\n .replace(/`(.+?)`/g, '$1')\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1')\n .trim();\n}\n\nexport function headingText(parts: Part[], level?: number): string {\n const heading = getHeading(parts, level);\n return str(heading);\n}\n\n/** Like headingText but preserves inline markdown formatting (bold, italic, etc.) */\nexport function headingMarkdown(parts: Part[], level?: number): string {\n const heading = getHeading(parts, level);\n if (!heading) {\n return '';\n }\n const meta = heading.meta as Record<string, unknown>;\n return (meta?.markdown as string)?.trim() || str(heading);\n}\n\nexport function bodyText(parts: Part[]): string {\n const textParts = getPartsByType<Part>(parts, 'text');\n const richTextParts = getPartsByType<Part>(parts, 'richText');\n return [...textParts, ...richTextParts]\n .map(markdownOrText)\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/**\n * Entity sections may be authored as one paragraph per entity:\n * `[Product](web5://entity/...) - why it matches`.\n * In that shape, text after the first entity link is item copy rather than\n * section copy, so only keep prose that appears before the first entity link.\n */\nexport function entitySectionBodyText(parts: Part[]): string {\n const firstEntityLinkIndex = parts.findIndex(\n (p) => p.type === 'link' && isEntityHref((p as LinkPart).meta?.href),\n );\n const sectionParts =\n firstEntityLinkIndex >= 0 ? parts.slice(0, firstEntityLinkIndex) : parts;\n\n return sectionParts\n .filter((p) => p.type === 'text' || p.type === 'richText')\n .map(markdownOrText)\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/** Build HeroButton[] from link parts — aligned to HeroSection1Button shape */\nexport function linksToHeroButtons(parts: Part[]): HeroButton[] {\n let links = getLinks(parts);\n if (!links.length) {\n const lists = getPartsByType<ListPart>(parts, 'list');\n links = lists.flatMap((l) =>\n (l.meta?.items ?? []).flatMap((item) =>\n ((item.meta?.parts ?? []) as Part[]).filter(\n (p): p is LinkPart => p.type === 'link',\n ),\n ),\n );\n }\n return links.map(\n (l, i): HeroButton => ({\n id: `btn-${i}`,\n text: l.content?.trim() || 'Learn more',\n variant: i === 0 ? 'primary' : 'secondary',\n onClick: l.meta.href,\n }),\n );\n}\n\n/** Return just the src URL string of the first image part */\nexport function firstImageSrc(parts: Part[]): string | undefined {\n const images = getImages(parts);\n const img = images[0];\n return img?.meta?.src || undefined;\n}\n\n/** Return the first link as { text, href } */\nexport function firstLink(\n parts: Part[],\n): { text: string; href: string } | undefined {\n const links = getLinks(parts);\n const link = links[0];\n if (!link) {\n return undefined;\n }\n return { text: link.content?.trim() || '', href: link.meta.href };\n}\n\n/** Extract text content from blockquote parts, preserving markdown formatting when available */\nexport function blockquoteText(parts: Part[]): string | undefined {\n const bqs = getPartsByType<Part>(parts, 'blockquote');\n if (bqs.length === 0) {\n return undefined;\n }\n const text = bqs\n .map((p) => (p.meta?.markdown as string)?.trim() || str(p))\n .filter(Boolean)\n .join('\\n');\n return text || undefined;\n}\n\n/** Extract first callout from parts as a Callout object */\nexport function calloutFromParts(parts: Part[]): Callout | undefined {\n const calloutParts = getPartsByType<Part>(parts, 'callout');\n if (calloutParts.length === 0) {\n return undefined;\n }\n const p = calloutParts[0];\n const raw = (p.meta?.markdown as string)?.trim() || str(p);\n const parsed = parseCalloutTag(raw);\n return parsed.text ? { text: parsed.text, kind: parsed.kind } : undefined;\n}\n\n/** Convert list parts to a markdown-like string */\nexport function listToMarkdown(parts: Part[]): string | undefined {\n const lists = getPartsByType<ListPart>(parts, 'list');\n if (lists.length === 0) {\n return undefined;\n }\n const lines: string[] = [];\n for (const list of lists) {\n const items = list.meta?.items ?? [];\n for (const item of items) {\n const text = extractListItemText(item);\n if (text) {\n lines.push(`- ${text}`);\n }\n }\n }\n return lines.length > 0 ? lines.join('\\n') : undefined;\n}\n\n/**\n * Parse a web5://entity/ URL into entityType and entityId.\n * Delegates to the central `parseWeb5Url` parser.\n */\nexport function parseEntityUrl(\n url: string,\n): { entityType: string; entityId: string } | null {\n const trimmedUrl = url?.trim();\n if (!trimmedUrl || !isWeb5EntityUrl(trimmedUrl)) {\n return null;\n }\n const parsed = parseWeb5Url(trimmedUrl);\n if (\n parsed?.type !== Web5UrlType.ENTITY ||\n !parsed.entityType ||\n !parsed.entityId\n ) {\n return null;\n }\n return { entityType: parsed.entityType, entityId: parsed.entityId };\n}\n\n/**\n * Parse a table cell value into boolean or string.\n * Ported from web50-server-ui comparisonSectionParser.tsx.\n */\nexport function parseTableValue(value: string): boolean | string {\n const normalized = value.trim().toLowerCase();\n\n if (\n normalized === 'true' ||\n normalized === 'yes' ||\n normalized === '✓' ||\n normalized === 'check' ||\n normalized === 'y'\n ) {\n return true;\n }\n if (\n normalized === 'false' ||\n normalized === 'no' ||\n normalized === '✗' ||\n normalized === 'x' ||\n normalized === 'n' ||\n normalized === ''\n ) {\n return false;\n }\n\n return value.trim();\n}\n\n/**\n * Parse a KPI item from markdown text.\n * The first **bold** segment becomes the title; everything after it (leading \":\" stripped) is the description.\n */\nexport function parseKpiItem(\n markdown: string,\n): { title: string; description: string } | null {\n const trimmed = markdown.trim();\n if (!trimmed) {\n return null;\n }\n const boldMatch = trimmed.match(/\\*\\*(.+?)\\*\\*/);\n if (!boldMatch) {\n return null;\n }\n const title = boldMatch[1].trim();\n const afterBold = trimmed.slice(\n trimmed.indexOf(boldMatch[0]) + boldMatch[0].length,\n );\n const description = afterBold.replace(/^[:\\s]+/, '').trim();\n return { title, description };\n}\n\n/** Join inline tokens the way prose reads: single spaces, none before punctuation. */\nfunction appendInlineToken(current: string, token: string): string {\n const trimmed = token.trim();\n if (!trimmed) {\n return current;\n }\n if (!current) {\n return trimmed;\n }\n if (/^[,.;:!?)]/.test(trimmed)) {\n return `${current}${trimmed}`;\n }\n return `${current} ${trimmed}`;\n}\n\n/**\n * Serialize a run of inline parts back to markdown, preserving links.\n *\n * Concatenating `part.content` alone silently deletes links: a `link` part\n * keeps its label in `content` and its url in `meta.href`, so a filter that\n * reads only text parts turns `Read the [pricing page](/pricing) first` into\n * `Read the first` — url and label both vanish, with nothing in the output to\n * show anything was lost.\n */\nexport function inlinePartsToMarkdown(parts: Part[]): string {\n return parts.reduce((text, part) => {\n if (part.type === 'link') {\n const href = (part as LinkPart).meta?.href ?? '';\n const label = part.content?.trim() ?? '';\n return appendInlineToken(text, href ? `[${label}](${href})` : label);\n }\n return appendInlineToken(text, part.content ?? '');\n }, '');\n}\n\nexport function extractListItemText(item: ListItemPart): string {\n if (item.content) {\n return item.content;\n }\n if (item.meta?.parts) {\n return (item.meta.parts as Part[])\n .map((p) => p.content)\n .filter(Boolean)\n .join(' ');\n }\n return '';\n}\n\n/**\n * Reconstruct markdown-like content from parts.\n *\n * `part.content` is the *plain* text — `nodesToParts` strips inline\n * formatting and preserves the original markdown (bold, italic, links) in\n * `part.meta.markdown` when they differ. Prefer it so markdown-rendering\n * consumers (e.g. the fallback section's ReactMarkdown) keep `**bold**`.\n */\nexport function partsToMarkdown(sectionParts: Part[]): string {\n const inline = (part: Part): string =>\n (part.meta?.markdown as string | undefined) ?? part.content;\n const lines: string[] = [];\n for (const part of sectionParts) {\n if (part.type === 'heading') {\n const level = (part.meta as { level: number })?.level ?? 2;\n lines.push(`${'#'.repeat(level)} ${inline(part)}`);\n } else if (part.type === 'text' || part.type === 'richText') {\n lines.push(inline(part));\n } else if (part.type === 'list') {\n const list = part as ListPart;\n for (const item of list.meta?.items ?? []) {\n lines.push(\n `- ${(item.meta?.markdown as string | undefined) ?? extractListItemText(item)}`,\n );\n }\n } else if (part.type === 'blockquote' || part.type === 'callout') {\n lines.push(`> ${inline(part)}`);\n }\n }\n return lines.join('\\n\\n');\n}\n\n/**\n * Extract callout kind tag from blockquote text.\n * Handles [!NOTE], [!TIP], [!IMPORTANT], [!WARNING], [!CAUTION] GFM syntax.\n */\nexport function parseCalloutTag(text: string): { text: string; kind?: string } {\n const match = text.match(/^\\[!(\\w+)\\]\\s*(.*)/s);\n if (match) {\n return { kind: match[1].toUpperCase(), text: match[2].trim() };\n }\n return { text: text.trim() };\n}\n\n/** Generate a simple unique ID */\nexport function generatePartId(): string {\n return Math.random().toString(36).slice(2, 10);\n}\n\nfunction isEntityHref(href: string | undefined): boolean {\n return !!href && isWeb5EntityUrl(href);\n}\n\nexport interface EntityRef {\n entityId: string;\n entityType: string;\n linkText: string;\n entityUrl: string;\n description: string;\n markdownImageUrl?: string;\n markdownFeatures?: string[];\n callout?: Callout;\n}\n\n/**\n * Extract text from nested list items within a list item's parts.\n */\nfunction extractNestedListItems(itemParts: Part[]): string[] {\n const nestedLists = itemParts.filter((p): p is ListPart => p.type === 'list');\n const features: string[] = [];\n for (const list of nestedLists) {\n for (const nested of list.meta?.items ?? []) {\n const text = extractListItemText(nested);\n if (text) {\n features.push(text);\n }\n }\n }\n return features;\n}\n\n/**\n * Extract entity references from list items containing web5://entity/ links.\n * Also extracts markdownFeatures from nested list items within each entity item.\n */\nexport function extractEntityRefs(parts: Part[]): EntityRef[] {\n const entities: EntityRef[] = [];\n const lists = getPartsByType<ListPart>(parts, 'list');\n\n for (const list of lists) {\n for (const item of list.meta?.items ?? []) {\n const itemParts = (item.meta?.parts ?? []) as Part[];\n const entityLinks = itemParts.filter(\n (p): p is LinkPart =>\n p.type === 'link' && isEntityHref((p as LinkPart).meta?.href),\n );\n\n for (const link of entityLinks) {\n const parsed = parseEntityUrl(link.meta.href);\n if (parsed) {\n const images = itemParts.filter(\n (p): p is ImagePart => p.type === 'image',\n );\n const textParts = itemParts.filter(\n (p) => p.type === 'text' && p.content?.trim(),\n );\n const description = normalizeEntityDescription(\n textParts.map(markdownOrText).join(' '),\n );\n const features = extractNestedListItems(itemParts);\n const calloutParts = itemParts.filter(\n (p) => p.type === 'callout' || p.type === 'blockquote',\n );\n let callout: Callout | undefined;\n if (calloutParts.length > 0) {\n const raw =\n (calloutParts[0].meta?.markdown as string)?.trim() ||\n str(calloutParts[0]);\n const parsed2 = parseCalloutTag(raw);\n if (parsed2.text) {\n callout = { text: parsed2.text, kind: parsed2.kind };\n }\n }\n entities.push({\n entityId: parsed.entityId,\n entityType: parsed.entityType,\n linkText: link.content?.trim() || '',\n entityUrl: link.meta.href,\n description,\n markdownImageUrl: images[0]?.meta?.src,\n markdownFeatures: features.length > 0 ? features : undefined,\n callout,\n });\n }\n }\n }\n }\n\n // Also check top-level links (with surrounding context for description/image/list)\n const topLinks = getLinks(parts).filter((l) => isEntityHref(l.meta?.href));\n for (const link of topLinks) {\n const parsed = parseEntityUrl(link.meta.href);\n if (parsed && !entities.some((e) => e.entityId === parsed.entityId)) {\n // Look for description text and image after this link in the parts array\n const linkIndex = parts.indexOf(link);\n let description = '';\n let markdownImageUrl: string | undefined;\n let callout: Callout | undefined;\n const features: string[] = [];\n\n if (linkIndex >= 0) {\n // Scan following parts for description, image, callout, and list items\n for (let j = linkIndex + 1; j < parts.length; j++) {\n const p = parts[j];\n // Stop at next entity link\n if (p.type === 'link' && isEntityHref((p as LinkPart).meta?.href)) {\n break;\n }\n if (p.type === 'text' && p.content?.trim()) {\n const text = markdownOrText(p);\n description = description\n ? `${description} ${text}`\n : text;\n } else if (p.type === 'image' && !markdownImageUrl) {\n markdownImageUrl = (p as ImagePart).meta?.src;\n } else if (\n (p.type === 'callout' || p.type === 'blockquote') &&\n !callout\n ) {\n const raw = (p.meta?.markdown as string)?.trim() || str(p);\n const parsedCallout = parseCalloutTag(raw);\n if (parsedCallout.text) {\n callout = { text: parsedCallout.text, kind: parsedCallout.kind };\n }\n } else if (p.type === 'list') {\n for (const item of (p as ListPart).meta?.items ?? []) {\n const text = extractListItemText(item);\n if (text) {\n features.push(text);\n }\n }\n }\n }\n }\n\n entities.push({\n entityId: parsed.entityId,\n entityType: parsed.entityType,\n linkText: link.content?.trim() || '',\n entityUrl: link.meta.href,\n description: normalizeEntityDescription(description),\n markdownImageUrl,\n markdownFeatures: features.length > 0 ? features : undefined,\n callout,\n });\n }\n }\n\n return entities;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -28,6 +28,7 @@ import { preprocessMarkdown } from '../utils/markdownPreprocessor.js';
|
|
|
28
28
|
import { getIntentFromMarkdown } from '../utils/intentExtractor.js';
|
|
29
29
|
import { getContextualImageFilename } from '../utils/contentKeywordMatcher.js';
|
|
30
30
|
import { createPageSection } from '../utils/propsExtractor.js';
|
|
31
|
+
import { DROP_SECTION } from './section-definition.js';
|
|
31
32
|
function isEntityCompProps(props) {
|
|
32
33
|
return typeof props === 'object' && props !== null && Array.isArray(props.items);
|
|
33
34
|
}
|
|
@@ -322,6 +323,20 @@ export function tryParseComponent(nodes, sectionIndex, context) {
|
|
|
322
323
|
} : undefined
|
|
323
324
|
};
|
|
324
325
|
let props = definition.parse(parts, parseContext);
|
|
326
|
+
|
|
327
|
+
// The definition claimed the block and then decided its content is not
|
|
328
|
+
// worth rendering. Consume the nodes and emit no component — returning
|
|
329
|
+
// `null` here instead would let the same heading and table fall through
|
|
330
|
+
// to the raw-markdown fallback, which is the outcome the drop exists to
|
|
331
|
+
// avoid.
|
|
332
|
+
if (props === DROP_SECTION) {
|
|
333
|
+
if (trace) {
|
|
334
|
+
logMatchDebug(` ${sectionType}: matched ${parsedNodes} node(s) but parse() dropped the section — rendering nothing`);
|
|
335
|
+
}
|
|
336
|
+
return {
|
|
337
|
+
parsedCount: parsedNodes
|
|
338
|
+
};
|
|
339
|
+
}
|
|
325
340
|
if (props === null) {
|
|
326
341
|
if (trace) {
|
|
327
342
|
logMatchDebug(` ${sectionType}: pattern matched ${parsedNodes} node(s) but parse() returned null — falling through`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","validatePattern","nodesToParts","isWeb5ImageUrl","findInvalidWeb5Links","DIAGNOSTIC_TYPES","ComponentTracking","isMatchDebugEnabled","logMatchDebug","DiagnosticsCollector","parseAstToMarkdown","parseMarkdownToAst","preprocessMarkdown","getIntentFromMarkdown","getContextualImageFilename","createPageSection","isEntityCompProps","props","Array","isArray","items","ENRICHABLE_ENTITY_SECTION_TYPES","Set","isItemsFromContentSection","sectionType","semantic","serverSectionId","has","normalizedSemantic","toLowerCase","replace","normalizedId","includes","mergeSectionsWithStableReferences","existingSections","newSections","length","merged","i","_existing$sourceMarkd","_updated$sourceMarkdo","existing","updated","push","existingLength","sourceMarkdown","updatedLength","component","componentOptions","debugProps","isSkeleton","newSectionsToAdd","slice","combineAdjacentGeneralTextSections","sections","registry","placement","placementId","combined","currentSection","sectionsToCombine","j","mergedSection","mergeGeneralTextSections","index","Error","mergedSourceMarkdown","map","section","filter","markdown","trim","join","mergedProps","FallbackComponent","resolveSection","mergedComponent","createElement","componentName","displayName","name","parseMarkdownToComponents","pageMarkdown","options","_clientConfig$feature","clientConfig","enrichEntityProps","clientId","intentInfo","providedIntent","payload","disableContextualImages","explicitDisableImages","preprocessedMarkdown","diagnostics","preprocessDiagnostics","knownIntents","getKnownIntents","validIntents","undefined","allNodes","children","nodes","tracking","diagnosticsCollector","d","report","diagnosticType","type","sectionIndex","details","original","normalized","features","disableContextualImagesEnrichment","context","intent","currentGlobalIndex","startIndex","parsedCount","tryParseComponent","endIndex","addRange","splice","link","label","reason","LEGACY_PROTOCOL_LINK","INVALID_LINK_FORMAT","BROKEN_WEB5_LINK","nodeType","url","combinedSections","definitions","getAllDefinitions","allowedKeywords","allowedImageSearchKeywords","baseParseContext","getContextualImage","contentParts","result","filename","getComponentCount","setMeta","key","value","getMeta","trace","n","definition","isPlacementOnly","pattern","patterns","_parts$find","_context$intent","valid","error","parsedNodes","astEndIndex","maxNodes","maxConsumedNodes","matchedNodes","parts","parseContext","reportDiagnostic","parse","leadingHtmlCommentMeta","find","p","meta","id","singleInstance","isNullComponent","nullComponent","Component","resolvedSectionOptions","resolveSectionOptions","patternValidation","astStartIndex"],"sources":["../../../src/component/componentParser.ts"],"sourcesContent":["/**\n * Markdown → component orchestrator. Lifted from\n * `web50-server-ui/src/utils/componentParser.ts` per DL #088 B9.5.\n *\n * The lift replaces three app-side singletons with options:\n * - `getAppRegistry()` → `options.registry`\n * - `getClientConfigSync(clientId)` → `options.clientConfig`\n * - `setLastDiagnosticsCollector(...)` → returned in the result object\n *\n * Adds a `placement` option that flows into every `registry.resolveSection`\n * call so the placement bundle can pick the placement variant of each section.\n *\n * The app-side `componentParser.ts` is a thin wrapper around this orchestrator\n * that pre-binds its singletons and a product-payload enrichment callback.\n */\nimport type { RootContent } from 'mdast';\nimport React from 'react';\n\nimport { validatePattern } from '../patternValidator';\nimport { nodesToParts } from '../match/astToParts';\nimport { isWeb5ImageUrl } from '../types/link-types';\nimport { findInvalidWeb5Links } from '../utils/web5LinkValidator';\nimport { DIAGNOSTIC_TYPES, type DiagnosticType } from './diagnosticTypes';\nimport { ComponentTracking } from '../utils/componentTracking';\nimport { isMatchDebugEnabled, logMatchDebug } from '../utils/matchDebug';\nimport { DiagnosticsCollector } from '../utils/diagnosticsCollector';\nimport {\n parseAstToMarkdown,\n parseMarkdownToAst,\n} from '../utils/unifiedMarkdownParser';\nimport { preprocessMarkdown } from '../utils/markdownPreprocessor';\nimport {\n getIntentFromMarkdown,\n type IntentInfo,\n} from '../utils/intentExtractor';\nimport { getContextualImageFilename } from '../utils/contentKeywordMatcher';\nimport { createPageSection } from '../utils/propsExtractor';\nimport type { PageSection } from '../types/page-section';\nimport type { ApiPayloadItem } from '../types/entity';\nimport type { ComponentRegistry } from '../registry';\nimport type { EntityCompProps, GeneralTextCompProps } from './types';\nimport type { SectionDefinition, ParseContext } from './section-definition';\nimport type {\n EnrichEntityProps,\n ParserClientConfig,\n ParserContext,\n} from './parser-types';\n\nexport type { ComponentMatch, ParserContext } from './parser-types';\n\nexport interface ParseMarkdownOptions {\n /** Required — replaces the app-side `getAppRegistry()` singleton. */\n registry: ComponentRegistry<React.FC<any>>;\n /** Replaces `getClientConfigSync(clientId)` — caller resolves it first. */\n clientConfig?: ParserClientConfig | null;\n /** When true, resolveSection prefers placement variants (DL #088 D3.1). */\n placement?: boolean;\n /**\n * Placement slot id (the `data-web5-placement` value) — forwarded to\n * `resolveSection` so a section can resolve a per-placement variant. Only\n * meaningful with `placement: true`.\n */\n placementId?: string;\n /** App-specific payload-to-entity enrichment; omitted by the placement bundle. */\n enrichEntityProps?: EnrichEntityProps;\n /** Reuse an existing collector (e.g. for streaming) instead of creating one. */\n diagnosticsCollector?: DiagnosticsCollector;\n clientId?: string;\n intentInfo?: IntentInfo | null;\n payload?: ApiPayloadItem[];\n disableContextualImages?: boolean;\n}\n\nexport interface ParseMarkdownResult {\n sections: PageSection[];\n tracking: ComponentTracking;\n diagnosticsCollector: DiagnosticsCollector;\n}\n\nfunction isEntityCompProps(props: unknown): props is EntityCompProps {\n return (\n typeof props === 'object' &&\n props !== null &&\n Array.isArray((props as EntityCompProps).items)\n );\n}\n\n/**\n * Section types whose props are `EntityCompProps` and therefore participate in\n * payload enrichment. `entityCollection` is `entity` narrowed to collection\n * links — it produces the same props and arrives under the same\n * `semantic: items` descriptor, so leaving it out would silently strip its\n * items of their catalog data (image, title) and render the section blank.\n */\nconst ENRICHABLE_ENTITY_SECTION_TYPES = new Set(['entity', 'entityCollection']);\n\nfunction isItemsFromContentSection(\n sectionType: string,\n semantic?: string,\n serverSectionId?: string,\n): boolean {\n if (!ENRICHABLE_ENTITY_SECTION_TYPES.has(sectionType)) {\n return false;\n }\n const normalizedSemantic = semantic?.toLowerCase().replace(/_/g, '-');\n const normalizedId = serverSectionId?.toLowerCase().replace(/_/g, '-');\n return (\n normalizedSemantic === 'items' ||\n normalizedSemantic === 'items-from-content' ||\n normalizedId?.includes('items-from-content') === true\n );\n}\n\n/**\n * Merges new sections with existing sections, maintaining stable references\n * for unchanged sections to prevent unnecessary rerenders.\n */\nexport function mergeSectionsWithStableReferences(\n existingSections: PageSection[],\n newSections: PageSection[],\n): PageSection[] {\n if (existingSections.length === 0) {\n return newSections;\n }\n if (newSections.length < existingSections.length) {\n return newSections;\n }\n\n const merged: PageSection[] = [];\n\n for (let i = 0; i < existingSections.length; i++) {\n const existing = existingSections[i];\n const updated = newSections[i];\n\n if (!updated) {\n merged.push(existing);\n continue;\n }\n\n const existingLength = existing.sourceMarkdown?.length || 0;\n const updatedLength = updated.sourceMarkdown?.length || 0;\n\n if (existingLength === updatedLength) {\n existing.sourceMarkdown = updated.sourceMarkdown;\n existing.component = updated.component;\n existing.componentOptions = updated.componentOptions;\n existing.debugProps = updated.debugProps;\n // V3 (DL #106): a skeleton and its real section both have empty\n // sourceMarkdown, so without carrying this flag the slot would stay a\n // skeleton forever (its real component never rendering).\n existing.isSkeleton = updated.isSkeleton;\n merged.push(existing);\n } else {\n merged.push(updated);\n }\n }\n\n if (newSections.length > existingSections.length) {\n const newSectionsToAdd = newSections.slice(existingSections.length);\n merged.push(...newSectionsToAdd);\n }\n\n return merged;\n}\n\nfunction combineAdjacentGeneralTextSections(\n sections: PageSection[],\n registry: ComponentRegistry<React.FC<any>>,\n placement?: boolean,\n placementId?: string,\n): PageSection[] {\n if (sections.length === 0) {\n return sections;\n }\n\n const combined: PageSection[] = [];\n let i = 0;\n\n while (i < sections.length) {\n const currentSection = sections[i];\n if (currentSection.sectionType === 'fallback') {\n const sectionsToCombine: PageSection[] = [currentSection];\n let j = i + 1;\n\n while (j < sections.length && sections[j].sectionType === 'fallback') {\n sectionsToCombine.push(sections[j]);\n j++;\n }\n\n if (sectionsToCombine.length > 1) {\n const mergedSection = mergeGeneralTextSections(\n sectionsToCombine,\n combined.length,\n registry,\n placement,\n placementId,\n );\n combined.push(mergedSection);\n i = j;\n } else {\n combined.push(currentSection);\n i++;\n }\n } else {\n combined.push(currentSection);\n i++;\n }\n }\n\n return combined;\n}\n\nfunction mergeGeneralTextSections(\n sections: PageSection[],\n index: number,\n registry: ComponentRegistry<React.FC<any>>,\n placement?: boolean,\n placementId?: string,\n): PageSection {\n if (sections.length === 0) {\n throw new Error('Cannot merge empty sections array');\n }\n if (sections.length === 1) {\n return sections[0];\n }\n\n const mergedSourceMarkdown = sections\n .map((section) => section.sourceMarkdown || '')\n .filter((markdown) => markdown.trim().length > 0)\n .join('\\n\\n');\n\n const mergedProps: GeneralTextCompProps = {\n markdown: mergedSourceMarkdown,\n };\n\n const FallbackComponent = registry.resolveSection('fallback', {\n placement,\n placementId,\n });\n const mergedComponent = React.createElement(FallbackComponent, mergedProps);\n\n return createPageSection({\n sectionType: 'fallback',\n componentName:\n (FallbackComponent as React.FC).displayName || FallbackComponent.name,\n index,\n component: mergedComponent,\n sourceMarkdown: mergedSourceMarkdown,\n debugProps: mergedProps,\n });\n}\n\nexport function parseMarkdownToComponents(\n pageMarkdown: string,\n options: ParseMarkdownOptions,\n): ParseMarkdownResult {\n const {\n registry,\n clientConfig,\n placement,\n placementId,\n enrichEntityProps,\n clientId,\n intentInfo: providedIntent,\n payload,\n disableContextualImages: explicitDisableImages,\n } = options;\n\n const { markdown: preprocessedMarkdown, diagnostics: preprocessDiagnostics } =\n preprocessMarkdown(pageMarkdown);\n\n // Validate the emitted intent against this client's own registered intents\n // (its taxonomy), falling back to core's DEFAULT_INTENTS when the registry\n // declares none.\n const knownIntents = registry.getKnownIntents();\n const intentInfo =\n providedIntent ??\n getIntentFromMarkdown(preprocessedMarkdown, {\n validIntents: knownIntents.length > 0 ? knownIntents : undefined,\n });\n\n const allNodes: RootContent[] = [\n ...parseMarkdownToAst(preprocessedMarkdown).children,\n ];\n const nodes: RootContent[] = [...allNodes];\n\n const sections: PageSection[] = [];\n const tracking = new ComponentTracking();\n const diagnosticsCollector =\n options.diagnosticsCollector ?? new DiagnosticsCollector();\n\n for (const d of preprocessDiagnostics) {\n diagnosticsCollector.report({\n diagnosticType: d.type as DiagnosticType,\n sectionType: 'preprocessor',\n sectionIndex: -1,\n details: `${d.original} → ${d.normalized}`,\n });\n }\n\n const disableContextualImages =\n explicitDisableImages ??\n clientConfig?.features?.disableContextualImagesEnrichment ??\n false;\n\n const context: ParserContext = {\n registry,\n clientConfig,\n placement,\n placementId,\n enrichEntityProps,\n clientId,\n intent: intentInfo,\n tracking,\n disableContextualImages,\n diagnosticsCollector,\n payload,\n };\n let currentGlobalIndex = 0;\n\n while (nodes.length > 0) {\n const startIndex = currentGlobalIndex;\n const { section, parsedCount } = tryParseComponent(\n nodes,\n sections.length,\n context,\n );\n\n if (!parsedCount) {\n break;\n }\n\n if (section) {\n section.sourceMarkdown = parseAstToMarkdown(nodes.slice(0, parsedCount));\n sections.push(section);\n\n const endIndex = startIndex + parsedCount;\n tracking.addRange(\n section.sectionType,\n startIndex,\n endIndex,\n sections.length - 1,\n );\n } else {\n const endIndex = startIndex + parsedCount;\n tracking.addRange('', startIndex, endIndex, -1);\n }\n\n currentGlobalIndex += parsedCount;\n nodes.splice(0, parsedCount);\n }\n\n for (const link of findInvalidWeb5Links(allNodes)) {\n let diagnosticType: DiagnosticType;\n let label: string;\n switch (link.reason) {\n case 'legacy':\n diagnosticType = DIAGNOSTIC_TYPES.LEGACY_PROTOCOL_LINK;\n label = 'legacy protocol';\n break;\n case 'empty':\n diagnosticType = DIAGNOSTIC_TYPES.INVALID_LINK_FORMAT;\n label = 'empty href';\n break;\n default:\n diagnosticType = DIAGNOSTIC_TYPES.BROKEN_WEB5_LINK;\n label = 'web5://';\n break;\n }\n diagnosticsCollector.report({\n diagnosticType,\n sectionType: 'parser',\n sectionIndex: -1,\n details: `Invalid ${label} URL in ${link.nodeType}: ${link.url}`.slice(\n 0,\n 200,\n ),\n });\n }\n\n const combinedSections = combineAdjacentGeneralTextSections(\n sections,\n registry,\n placement,\n placementId,\n );\n\n return {\n sections: combinedSections,\n tracking,\n diagnosticsCollector,\n };\n}\n\nexport function tryParseComponent(\n nodes: RootContent[],\n sectionIndex: number,\n context: ParserContext,\n): { section?: PageSection; parsedCount?: number } {\n if (!nodes?.length) {\n return {};\n }\n\n const registry = context.registry;\n const placement = context.placement;\n const placementId = context.placementId;\n const definitions = registry.getAllDefinitions();\n\n const clientConfig = context.clientConfig ?? null;\n const allowedKeywords = clientConfig?.allowedImageSearchKeywords ?? [];\n const disableContextualImages = context.disableContextualImages ?? false;\n\n const baseParseContext: ParseContext = {\n getContextualImage:\n disableContextualImages || allowedKeywords.length === 0\n ? undefined\n : (contentParts) => {\n const result = getContextualImageFilename(\n contentParts,\n allowedKeywords,\n '',\n context.tracking,\n );\n return isWeb5ImageUrl(result.filename) ? result : null;\n },\n getComponentCount: context.tracking\n ? (sectionType) => context.tracking!.getComponentCount(sectionType)\n : undefined,\n setMeta: context.tracking\n ? (sectionType, key, value) =>\n context.tracking!.setMeta(sectionType, key, value)\n : undefined,\n getMeta: context.tracking\n ? (sectionType, key) => context.tracking!.getMeta(sectionType, key)\n : undefined,\n };\n\n // Debug-only trace (`?web5DebugMatch=1`). The registry order line doubles as\n // a \"is my definition even registered?\" check — a definition missing from it\n // never reached `register()` (stale client bundle / web5-core version skew).\n const trace = isMatchDebugEnabled();\n if (trace) {\n logMatchDebug(\n `block #${sectionIndex} [${nodes.map((n) => n.type).join(', ')}]`,\n );\n logMatchDebug(\n ` registry order: ${definitions.map((d) => d.sectionType).join(' > ')}`,\n );\n }\n\n for (const { sectionType, definition } of definitions) {\n // Placement-only definitions (registered with `{ placement: true }`\n // variants and no non-placement variant) must not match in a non-placement\n // render (the main app) — their markdown should fall through to the generic\n // sections there. Skip them unless this is a placement parse.\n if (!placement && registry.isPlacementOnly(sectionType)) {\n if (trace) {\n logMatchDebug(` ${sectionType}: skipped (placement-only)`);\n }\n continue;\n }\n for (const pattern of definition.patterns) {\n const result = validatePattern(nodes, pattern);\n if (!result.valid) {\n if (trace) {\n logMatchDebug(\n ` ${sectionType}: no match — ${\n result.error ?? 'pattern did not match'\n }\\n pattern: ${pattern}`,\n );\n }\n continue;\n }\n\n let parsedNodes =\n result.astEndIndex !== undefined && result.astEndIndex >= 0\n ? result.astEndIndex + 1\n : result.endIndex >= 0\n ? result.endIndex + 1\n : 1;\n\n const maxNodes = (\n definition as SectionDefinition & { maxConsumedNodes?: number }\n ).maxConsumedNodes;\n if (typeof maxNodes === 'number' && parsedNodes > maxNodes) {\n parsedNodes = maxNodes;\n }\n\n const matchedNodes = nodes.slice(0, parsedNodes);\n const parts = nodesToParts(matchedNodes);\n const parseContext: ParseContext = {\n ...baseParseContext,\n reportDiagnostic: context.diagnosticsCollector\n ? (type, details) => {\n context.diagnosticsCollector!.report({\n diagnosticType: type,\n sectionType,\n sectionIndex,\n details: details.slice(0, 200),\n });\n }\n : undefined,\n };\n let props = definition.parse(parts, parseContext);\n\n if (props === null) {\n if (trace) {\n logMatchDebug(\n ` ${sectionType}: pattern matched ${parsedNodes} node(s) but parse() returned null — falling through`,\n );\n }\n continue;\n }\n\n if (trace) {\n logMatchDebug(\n ` ${sectionType}: MATCHED ${parsedNodes} node(s) via ${pattern}`,\n );\n }\n\n const leadingHtmlCommentMeta = parts.find(\n (p) => p.type === 'htmlComment' && p.meta,\n )?.meta;\n const semantic = leadingHtmlCommentMeta?.semantic as string | undefined;\n const serverSectionId = leadingHtmlCommentMeta?.id as string | undefined;\n\n if (\n isEntityCompProps(props) &&\n isItemsFromContentSection(sectionType, semantic, serverSectionId) &&\n context.enrichEntityProps\n ) {\n props = context.enrichEntityProps(props, {\n payload: context.payload,\n clientConfig,\n sectionType,\n semantic,\n serverSectionId,\n });\n }\n\n if (\n definition.singleInstance &&\n context.tracking &&\n context.tracking.getComponentCount(sectionType) > 0\n ) {\n if (trace) {\n logMatchDebug(\n ` ${sectionType}: dropped (singleInstance, already rendered once)`,\n );\n }\n continue;\n }\n\n const isNullComponent =\n (definition as SectionDefinition & { nullComponent?: boolean })\n .nullComponent === true;\n if (isNullComponent) {\n return { parsedCount: parsedNodes };\n }\n\n const intent = context.intent?.intent;\n const Component = registry.resolveSection(sectionType, {\n intent,\n semantic,\n placement,\n placementId,\n });\n const resolvedSectionOptions = registry.resolveSectionOptions(\n sectionType,\n { intent, semantic, placement, placementId },\n );\n const component = React.createElement(Component, props);\n const componentName =\n Component.displayName || Component.name || undefined;\n\n const section = createPageSection({\n sectionType,\n componentName,\n semantic,\n componentOptions: resolvedSectionOptions?.componentOptions,\n index: sectionIndex,\n id: serverSectionId,\n component,\n sourceMarkdown: '',\n debugProps: {\n ...props,\n patternValidation: {\n astStartIndex: result.astStartIndex,\n astEndIndex: result.astEndIndex,\n endIndex: result.endIndex,\n },\n },\n });\n\n return { section, parsedCount: parsedNodes };\n }\n }\n\n if (trace) {\n logMatchDebug(' no definition claimed this block');\n }\n\n return {};\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["React","validatePattern","nodesToParts","isWeb5ImageUrl","findInvalidWeb5Links","DIAGNOSTIC_TYPES","ComponentTracking","isMatchDebugEnabled","logMatchDebug","DiagnosticsCollector","parseAstToMarkdown","parseMarkdownToAst","preprocessMarkdown","getIntentFromMarkdown","getContextualImageFilename","createPageSection","DROP_SECTION","isEntityCompProps","props","Array","isArray","items","ENRICHABLE_ENTITY_SECTION_TYPES","Set","isItemsFromContentSection","sectionType","semantic","serverSectionId","has","normalizedSemantic","toLowerCase","replace","normalizedId","includes","mergeSectionsWithStableReferences","existingSections","newSections","length","merged","i","_existing$sourceMarkd","_updated$sourceMarkdo","existing","updated","push","existingLength","sourceMarkdown","updatedLength","component","componentOptions","debugProps","isSkeleton","newSectionsToAdd","slice","combineAdjacentGeneralTextSections","sections","registry","placement","placementId","combined","currentSection","sectionsToCombine","j","mergedSection","mergeGeneralTextSections","index","Error","mergedSourceMarkdown","map","section","filter","markdown","trim","join","mergedProps","FallbackComponent","resolveSection","mergedComponent","createElement","componentName","displayName","name","parseMarkdownToComponents","pageMarkdown","options","_clientConfig$feature","clientConfig","enrichEntityProps","clientId","intentInfo","providedIntent","payload","disableContextualImages","explicitDisableImages","preprocessedMarkdown","diagnostics","preprocessDiagnostics","knownIntents","getKnownIntents","validIntents","undefined","allNodes","children","nodes","tracking","diagnosticsCollector","d","report","diagnosticType","type","sectionIndex","details","original","normalized","features","disableContextualImagesEnrichment","context","intent","currentGlobalIndex","startIndex","parsedCount","tryParseComponent","endIndex","addRange","splice","link","label","reason","LEGACY_PROTOCOL_LINK","INVALID_LINK_FORMAT","BROKEN_WEB5_LINK","nodeType","url","combinedSections","definitions","getAllDefinitions","allowedKeywords","allowedImageSearchKeywords","baseParseContext","getContextualImage","contentParts","result","filename","getComponentCount","setMeta","key","value","getMeta","trace","n","definition","isPlacementOnly","pattern","patterns","_parts$find","_context$intent","valid","error","parsedNodes","astEndIndex","maxNodes","maxConsumedNodes","matchedNodes","parts","parseContext","reportDiagnostic","parse","leadingHtmlCommentMeta","find","p","meta","id","singleInstance","isNullComponent","nullComponent","Component","resolvedSectionOptions","resolveSectionOptions","patternValidation","astStartIndex"],"sources":["../../../src/component/componentParser.ts"],"sourcesContent":["/**\n * Markdown → component orchestrator. Lifted from\n * `web50-server-ui/src/utils/componentParser.ts` per DL #088 B9.5.\n *\n * The lift replaces three app-side singletons with options:\n * - `getAppRegistry()` → `options.registry`\n * - `getClientConfigSync(clientId)` → `options.clientConfig`\n * - `setLastDiagnosticsCollector(...)` → returned in the result object\n *\n * Adds a `placement` option that flows into every `registry.resolveSection`\n * call so the placement bundle can pick the placement variant of each section.\n *\n * The app-side `componentParser.ts` is a thin wrapper around this orchestrator\n * that pre-binds its singletons and a product-payload enrichment callback.\n */\nimport type { RootContent } from 'mdast';\nimport React from 'react';\n\nimport { validatePattern } from '../patternValidator';\nimport { nodesToParts } from '../match/astToParts';\nimport { isWeb5ImageUrl } from '../types/link-types';\nimport { findInvalidWeb5Links } from '../utils/web5LinkValidator';\nimport { DIAGNOSTIC_TYPES, type DiagnosticType } from './diagnosticTypes';\nimport { ComponentTracking } from '../utils/componentTracking';\nimport { isMatchDebugEnabled, logMatchDebug } from '../utils/matchDebug';\nimport { DiagnosticsCollector } from '../utils/diagnosticsCollector';\nimport {\n parseAstToMarkdown,\n parseMarkdownToAst,\n} from '../utils/unifiedMarkdownParser';\nimport { preprocessMarkdown } from '../utils/markdownPreprocessor';\nimport {\n getIntentFromMarkdown,\n type IntentInfo,\n} from '../utils/intentExtractor';\nimport { getContextualImageFilename } from '../utils/contentKeywordMatcher';\nimport { createPageSection } from '../utils/propsExtractor';\nimport type { PageSection } from '../types/page-section';\nimport type { ApiPayloadItem } from '../types/entity';\nimport type { ComponentRegistry } from '../registry';\nimport type { EntityCompProps, GeneralTextCompProps } from './types';\nimport type { SectionDefinition, ParseContext } from './section-definition';\nimport { DROP_SECTION } from './section-definition';\nimport type {\n EnrichEntityProps,\n ParserClientConfig,\n ParserContext,\n} from './parser-types';\n\nexport type { ComponentMatch, ParserContext } from './parser-types';\n\nexport interface ParseMarkdownOptions {\n /** Required — replaces the app-side `getAppRegistry()` singleton. */\n registry: ComponentRegistry<React.FC<any>>;\n /** Replaces `getClientConfigSync(clientId)` — caller resolves it first. */\n clientConfig?: ParserClientConfig | null;\n /** When true, resolveSection prefers placement variants (DL #088 D3.1). */\n placement?: boolean;\n /**\n * Placement slot id (the `data-web5-placement` value) — forwarded to\n * `resolveSection` so a section can resolve a per-placement variant. Only\n * meaningful with `placement: true`.\n */\n placementId?: string;\n /** App-specific payload-to-entity enrichment; omitted by the placement bundle. */\n enrichEntityProps?: EnrichEntityProps;\n /** Reuse an existing collector (e.g. for streaming) instead of creating one. */\n diagnosticsCollector?: DiagnosticsCollector;\n clientId?: string;\n intentInfo?: IntentInfo | null;\n payload?: ApiPayloadItem[];\n disableContextualImages?: boolean;\n}\n\nexport interface ParseMarkdownResult {\n sections: PageSection[];\n tracking: ComponentTracking;\n diagnosticsCollector: DiagnosticsCollector;\n}\n\nfunction isEntityCompProps(props: unknown): props is EntityCompProps {\n return (\n typeof props === 'object' &&\n props !== null &&\n Array.isArray((props as EntityCompProps).items)\n );\n}\n\n/**\n * Section types whose props are `EntityCompProps` and therefore participate in\n * payload enrichment. `entityCollection` is `entity` narrowed to collection\n * links — it produces the same props and arrives under the same\n * `semantic: items` descriptor, so leaving it out would silently strip its\n * items of their catalog data (image, title) and render the section blank.\n */\nconst ENRICHABLE_ENTITY_SECTION_TYPES = new Set(['entity', 'entityCollection']);\n\nfunction isItemsFromContentSection(\n sectionType: string,\n semantic?: string,\n serverSectionId?: string,\n): boolean {\n if (!ENRICHABLE_ENTITY_SECTION_TYPES.has(sectionType)) {\n return false;\n }\n const normalizedSemantic = semantic?.toLowerCase().replace(/_/g, '-');\n const normalizedId = serverSectionId?.toLowerCase().replace(/_/g, '-');\n return (\n normalizedSemantic === 'items' ||\n normalizedSemantic === 'items-from-content' ||\n normalizedId?.includes('items-from-content') === true\n );\n}\n\n/**\n * Merges new sections with existing sections, maintaining stable references\n * for unchanged sections to prevent unnecessary rerenders.\n */\nexport function mergeSectionsWithStableReferences(\n existingSections: PageSection[],\n newSections: PageSection[],\n): PageSection[] {\n if (existingSections.length === 0) {\n return newSections;\n }\n if (newSections.length < existingSections.length) {\n return newSections;\n }\n\n const merged: PageSection[] = [];\n\n for (let i = 0; i < existingSections.length; i++) {\n const existing = existingSections[i];\n const updated = newSections[i];\n\n if (!updated) {\n merged.push(existing);\n continue;\n }\n\n const existingLength = existing.sourceMarkdown?.length || 0;\n const updatedLength = updated.sourceMarkdown?.length || 0;\n\n if (existingLength === updatedLength) {\n existing.sourceMarkdown = updated.sourceMarkdown;\n existing.component = updated.component;\n existing.componentOptions = updated.componentOptions;\n existing.debugProps = updated.debugProps;\n // V3 (DL #106): a skeleton and its real section both have empty\n // sourceMarkdown, so without carrying this flag the slot would stay a\n // skeleton forever (its real component never rendering).\n existing.isSkeleton = updated.isSkeleton;\n merged.push(existing);\n } else {\n merged.push(updated);\n }\n }\n\n if (newSections.length > existingSections.length) {\n const newSectionsToAdd = newSections.slice(existingSections.length);\n merged.push(...newSectionsToAdd);\n }\n\n return merged;\n}\n\nfunction combineAdjacentGeneralTextSections(\n sections: PageSection[],\n registry: ComponentRegistry<React.FC<any>>,\n placement?: boolean,\n placementId?: string,\n): PageSection[] {\n if (sections.length === 0) {\n return sections;\n }\n\n const combined: PageSection[] = [];\n let i = 0;\n\n while (i < sections.length) {\n const currentSection = sections[i];\n if (currentSection.sectionType === 'fallback') {\n const sectionsToCombine: PageSection[] = [currentSection];\n let j = i + 1;\n\n while (j < sections.length && sections[j].sectionType === 'fallback') {\n sectionsToCombine.push(sections[j]);\n j++;\n }\n\n if (sectionsToCombine.length > 1) {\n const mergedSection = mergeGeneralTextSections(\n sectionsToCombine,\n combined.length,\n registry,\n placement,\n placementId,\n );\n combined.push(mergedSection);\n i = j;\n } else {\n combined.push(currentSection);\n i++;\n }\n } else {\n combined.push(currentSection);\n i++;\n }\n }\n\n return combined;\n}\n\nfunction mergeGeneralTextSections(\n sections: PageSection[],\n index: number,\n registry: ComponentRegistry<React.FC<any>>,\n placement?: boolean,\n placementId?: string,\n): PageSection {\n if (sections.length === 0) {\n throw new Error('Cannot merge empty sections array');\n }\n if (sections.length === 1) {\n return sections[0];\n }\n\n const mergedSourceMarkdown = sections\n .map((section) => section.sourceMarkdown || '')\n .filter((markdown) => markdown.trim().length > 0)\n .join('\\n\\n');\n\n const mergedProps: GeneralTextCompProps = {\n markdown: mergedSourceMarkdown,\n };\n\n const FallbackComponent = registry.resolveSection('fallback', {\n placement,\n placementId,\n });\n const mergedComponent = React.createElement(FallbackComponent, mergedProps);\n\n return createPageSection({\n sectionType: 'fallback',\n componentName:\n (FallbackComponent as React.FC).displayName || FallbackComponent.name,\n index,\n component: mergedComponent,\n sourceMarkdown: mergedSourceMarkdown,\n debugProps: mergedProps,\n });\n}\n\nexport function parseMarkdownToComponents(\n pageMarkdown: string,\n options: ParseMarkdownOptions,\n): ParseMarkdownResult {\n const {\n registry,\n clientConfig,\n placement,\n placementId,\n enrichEntityProps,\n clientId,\n intentInfo: providedIntent,\n payload,\n disableContextualImages: explicitDisableImages,\n } = options;\n\n const { markdown: preprocessedMarkdown, diagnostics: preprocessDiagnostics } =\n preprocessMarkdown(pageMarkdown);\n\n // Validate the emitted intent against this client's own registered intents\n // (its taxonomy), falling back to core's DEFAULT_INTENTS when the registry\n // declares none.\n const knownIntents = registry.getKnownIntents();\n const intentInfo =\n providedIntent ??\n getIntentFromMarkdown(preprocessedMarkdown, {\n validIntents: knownIntents.length > 0 ? knownIntents : undefined,\n });\n\n const allNodes: RootContent[] = [\n ...parseMarkdownToAst(preprocessedMarkdown).children,\n ];\n const nodes: RootContent[] = [...allNodes];\n\n const sections: PageSection[] = [];\n const tracking = new ComponentTracking();\n const diagnosticsCollector =\n options.diagnosticsCollector ?? new DiagnosticsCollector();\n\n for (const d of preprocessDiagnostics) {\n diagnosticsCollector.report({\n diagnosticType: d.type as DiagnosticType,\n sectionType: 'preprocessor',\n sectionIndex: -1,\n details: `${d.original} → ${d.normalized}`,\n });\n }\n\n const disableContextualImages =\n explicitDisableImages ??\n clientConfig?.features?.disableContextualImagesEnrichment ??\n false;\n\n const context: ParserContext = {\n registry,\n clientConfig,\n placement,\n placementId,\n enrichEntityProps,\n clientId,\n intent: intentInfo,\n tracking,\n disableContextualImages,\n diagnosticsCollector,\n payload,\n };\n let currentGlobalIndex = 0;\n\n while (nodes.length > 0) {\n const startIndex = currentGlobalIndex;\n const { section, parsedCount } = tryParseComponent(\n nodes,\n sections.length,\n context,\n );\n\n if (!parsedCount) {\n break;\n }\n\n if (section) {\n section.sourceMarkdown = parseAstToMarkdown(nodes.slice(0, parsedCount));\n sections.push(section);\n\n const endIndex = startIndex + parsedCount;\n tracking.addRange(\n section.sectionType,\n startIndex,\n endIndex,\n sections.length - 1,\n );\n } else {\n const endIndex = startIndex + parsedCount;\n tracking.addRange('', startIndex, endIndex, -1);\n }\n\n currentGlobalIndex += parsedCount;\n nodes.splice(0, parsedCount);\n }\n\n for (const link of findInvalidWeb5Links(allNodes)) {\n let diagnosticType: DiagnosticType;\n let label: string;\n switch (link.reason) {\n case 'legacy':\n diagnosticType = DIAGNOSTIC_TYPES.LEGACY_PROTOCOL_LINK;\n label = 'legacy protocol';\n break;\n case 'empty':\n diagnosticType = DIAGNOSTIC_TYPES.INVALID_LINK_FORMAT;\n label = 'empty href';\n break;\n default:\n diagnosticType = DIAGNOSTIC_TYPES.BROKEN_WEB5_LINK;\n label = 'web5://';\n break;\n }\n diagnosticsCollector.report({\n diagnosticType,\n sectionType: 'parser',\n sectionIndex: -1,\n details: `Invalid ${label} URL in ${link.nodeType}: ${link.url}`.slice(\n 0,\n 200,\n ),\n });\n }\n\n const combinedSections = combineAdjacentGeneralTextSections(\n sections,\n registry,\n placement,\n placementId,\n );\n\n return {\n sections: combinedSections,\n tracking,\n diagnosticsCollector,\n };\n}\n\nexport function tryParseComponent(\n nodes: RootContent[],\n sectionIndex: number,\n context: ParserContext,\n): { section?: PageSection; parsedCount?: number } {\n if (!nodes?.length) {\n return {};\n }\n\n const registry = context.registry;\n const placement = context.placement;\n const placementId = context.placementId;\n const definitions = registry.getAllDefinitions();\n\n const clientConfig = context.clientConfig ?? null;\n const allowedKeywords = clientConfig?.allowedImageSearchKeywords ?? [];\n const disableContextualImages = context.disableContextualImages ?? false;\n\n const baseParseContext: ParseContext = {\n getContextualImage:\n disableContextualImages || allowedKeywords.length === 0\n ? undefined\n : (contentParts) => {\n const result = getContextualImageFilename(\n contentParts,\n allowedKeywords,\n '',\n context.tracking,\n );\n return isWeb5ImageUrl(result.filename) ? result : null;\n },\n getComponentCount: context.tracking\n ? (sectionType) => context.tracking!.getComponentCount(sectionType)\n : undefined,\n setMeta: context.tracking\n ? (sectionType, key, value) =>\n context.tracking!.setMeta(sectionType, key, value)\n : undefined,\n getMeta: context.tracking\n ? (sectionType, key) => context.tracking!.getMeta(sectionType, key)\n : undefined,\n };\n\n // Debug-only trace (`?web5DebugMatch=1`). The registry order line doubles as\n // a \"is my definition even registered?\" check — a definition missing from it\n // never reached `register()` (stale client bundle / web5-core version skew).\n const trace = isMatchDebugEnabled();\n if (trace) {\n logMatchDebug(\n `block #${sectionIndex} [${nodes.map((n) => n.type).join(', ')}]`,\n );\n logMatchDebug(\n ` registry order: ${definitions.map((d) => d.sectionType).join(' > ')}`,\n );\n }\n\n for (const { sectionType, definition } of definitions) {\n // Placement-only definitions (registered with `{ placement: true }`\n // variants and no non-placement variant) must not match in a non-placement\n // render (the main app) — their markdown should fall through to the generic\n // sections there. Skip them unless this is a placement parse.\n if (!placement && registry.isPlacementOnly(sectionType)) {\n if (trace) {\n logMatchDebug(` ${sectionType}: skipped (placement-only)`);\n }\n continue;\n }\n for (const pattern of definition.patterns) {\n const result = validatePattern(nodes, pattern);\n if (!result.valid) {\n if (trace) {\n logMatchDebug(\n ` ${sectionType}: no match — ${\n result.error ?? 'pattern did not match'\n }\\n pattern: ${pattern}`,\n );\n }\n continue;\n }\n\n let parsedNodes =\n result.astEndIndex !== undefined && result.astEndIndex >= 0\n ? result.astEndIndex + 1\n : result.endIndex >= 0\n ? result.endIndex + 1\n : 1;\n\n const maxNodes = (\n definition as SectionDefinition & { maxConsumedNodes?: number }\n ).maxConsumedNodes;\n if (typeof maxNodes === 'number' && parsedNodes > maxNodes) {\n parsedNodes = maxNodes;\n }\n\n const matchedNodes = nodes.slice(0, parsedNodes);\n const parts = nodesToParts(matchedNodes);\n const parseContext: ParseContext = {\n ...baseParseContext,\n reportDiagnostic: context.diagnosticsCollector\n ? (type, details) => {\n context.diagnosticsCollector!.report({\n diagnosticType: type,\n sectionType,\n sectionIndex,\n details: details.slice(0, 200),\n });\n }\n : undefined,\n };\n let props = definition.parse(parts, parseContext);\n\n // The definition claimed the block and then decided its content is not\n // worth rendering. Consume the nodes and emit no component — returning\n // `null` here instead would let the same heading and table fall through\n // to the raw-markdown fallback, which is the outcome the drop exists to\n // avoid.\n if (props === DROP_SECTION) {\n if (trace) {\n logMatchDebug(\n ` ${sectionType}: matched ${parsedNodes} node(s) but parse() dropped the section — rendering nothing`,\n );\n }\n return { parsedCount: parsedNodes };\n }\n\n if (props === null) {\n if (trace) {\n logMatchDebug(\n ` ${sectionType}: pattern matched ${parsedNodes} node(s) but parse() returned null — falling through`,\n );\n }\n continue;\n }\n\n if (trace) {\n logMatchDebug(\n ` ${sectionType}: MATCHED ${parsedNodes} node(s) via ${pattern}`,\n );\n }\n\n const leadingHtmlCommentMeta = parts.find(\n (p) => p.type === 'htmlComment' && p.meta,\n )?.meta;\n const semantic = leadingHtmlCommentMeta?.semantic as string | undefined;\n const serverSectionId = leadingHtmlCommentMeta?.id as string | undefined;\n\n if (\n isEntityCompProps(props) &&\n isItemsFromContentSection(sectionType, semantic, serverSectionId) &&\n context.enrichEntityProps\n ) {\n props = context.enrichEntityProps(props, {\n payload: context.payload,\n clientConfig,\n sectionType,\n semantic,\n serverSectionId,\n });\n }\n\n if (\n definition.singleInstance &&\n context.tracking &&\n context.tracking.getComponentCount(sectionType) > 0\n ) {\n if (trace) {\n logMatchDebug(\n ` ${sectionType}: dropped (singleInstance, already rendered once)`,\n );\n }\n continue;\n }\n\n const isNullComponent =\n (definition as SectionDefinition & { nullComponent?: boolean })\n .nullComponent === true;\n if (isNullComponent) {\n return { parsedCount: parsedNodes };\n }\n\n const intent = context.intent?.intent;\n const Component = registry.resolveSection(sectionType, {\n intent,\n semantic,\n placement,\n placementId,\n });\n const resolvedSectionOptions = registry.resolveSectionOptions(\n sectionType,\n { intent, semantic, placement, placementId },\n );\n const component = React.createElement(Component, props);\n const componentName =\n Component.displayName || Component.name || undefined;\n\n const section = createPageSection({\n sectionType,\n componentName,\n semantic,\n componentOptions: resolvedSectionOptions?.componentOptions,\n index: sectionIndex,\n id: serverSectionId,\n component,\n sourceMarkdown: '',\n debugProps: {\n ...props,\n patternValidation: {\n astStartIndex: result.astStartIndex,\n astEndIndex: result.astEndIndex,\n endIndex: result.endIndex,\n },\n },\n });\n\n return { section, parsedCount: parsedNodes };\n }\n }\n\n if (trace) {\n logMatchDebug(' no definition claimed this block');\n }\n\n return {};\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,2 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Sentinel a `parse()` may return: this block IS mine — consume its nodes — but
|
|
3
|
+
* render nothing.
|
|
4
|
+
*
|
|
5
|
+
* Distinct from `null`, which *rejects* the match and lets the block fall through
|
|
6
|
+
* to the next definition, and ultimately to `FallbackSectionDefinition`, which
|
|
7
|
+
* would re-render the same heading and table as raw markdown. Return this instead
|
|
8
|
+
* when a section matched but its content is unusable and showing a degraded
|
|
9
|
+
* version is worse than showing nothing at all.
|
|
10
|
+
*/
|
|
11
|
+
export const DROP_SECTION = Symbol('web5:drop-section');
|
|
12
|
+
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2
14
|
//# sourceMappingURL=section-definition.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["../../../src/component/section-definition.ts"],"sourcesContent":["import type { FC } from 'react';\nimport type { Part } from '../parts/parts';\nimport type { PropsOf, SectionFixture } from './types';\nimport type { DiagnosticType } from './diagnosticTypes';\n\nexport interface ContextualImageResult {\n filename: string;\n alt: string;\n isFromText: boolean;\n}\n\nexport interface ParseContext {\n /** Returns a contextual image://keyword URL based on content keywords. null = no match. */\n getContextualImage?: (\n contentParts: (string | undefined | null)[],\n ) => ContextualImageResult | null;\n /** Returns how many times a given sectionType has been matched so far in this parse run. */\n getComponentCount?: (sectionType: string) => number;\n /** Store a value scoped to a sectionType for the duration of the parse run. */\n setMeta?: (sectionType: string, key: string, value: unknown) => void;\n /** Retrieve a value previously stored via setMeta. */\n getMeta?: (sectionType: string, key: string) => unknown;\n /** Report a markdown diagnostic (e.g. broken link, invalid format). */\n reportDiagnostic?: (type: DiagnosticType, details: string) => void;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface SectionDefinition<T extends FC<any> = FC<any>> {\n sectionType: string;\n patterns: string[];\n singleInstance?: boolean;\n /** Cap the number of AST nodes consumed per match (e.g., 1 for the fallback parser). */\n maxConsumedNodes?: number;\n defaults?: PropsOf<T>;\n fixtures: SectionFixture<PropsOf<T>>[];\n parse(parts: Part[], context?: ParseContext): PropsOf<T> | null;\n}\n"],"mappings":"","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["DROP_SECTION","Symbol"],"sources":["../../../src/component/section-definition.ts"],"sourcesContent":["import type { FC } from 'react';\nimport type { Part } from '../parts/parts';\nimport type { PropsOf, SectionFixture } from './types';\nimport type { DiagnosticType } from './diagnosticTypes';\n\nexport interface ContextualImageResult {\n filename: string;\n alt: string;\n isFromText: boolean;\n}\n\nexport interface ParseContext {\n /** Returns a contextual image://keyword URL based on content keywords. null = no match. */\n getContextualImage?: (\n contentParts: (string | undefined | null)[],\n ) => ContextualImageResult | null;\n /** Returns how many times a given sectionType has been matched so far in this parse run. */\n getComponentCount?: (sectionType: string) => number;\n /** Store a value scoped to a sectionType for the duration of the parse run. */\n setMeta?: (sectionType: string, key: string, value: unknown) => void;\n /** Retrieve a value previously stored via setMeta. */\n getMeta?: (sectionType: string, key: string) => unknown;\n /** Report a markdown diagnostic (e.g. broken link, invalid format). */\n reportDiagnostic?: (type: DiagnosticType, details: string) => void;\n}\n\n/**\n * Sentinel a `parse()` may return: this block IS mine — consume its nodes — but\n * render nothing.\n *\n * Distinct from `null`, which *rejects* the match and lets the block fall through\n * to the next definition, and ultimately to `FallbackSectionDefinition`, which\n * would re-render the same heading and table as raw markdown. Return this instead\n * when a section matched but its content is unusable and showing a degraded\n * version is worse than showing nothing at all.\n */\nexport const DROP_SECTION: unique symbol = Symbol('web5:drop-section');\nexport type DropSection = typeof DROP_SECTION;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface SectionDefinition<T extends FC<any> = FC<any>> {\n sectionType: string;\n patterns: string[];\n singleInstance?: boolean;\n /** Cap the number of AST nodes consumed per match (e.g., 1 for the fallback parser). */\n maxConsumedNodes?: number;\n defaults?: PropsOf<T>;\n fixtures: SectionFixture<PropsOf<T>>[];\n parse(parts: Part[], context?: ParseContext): PropsOf<T> | null | DropSection;\n}\n"],"mappings":"AA0BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMA,YAA2B,GAAGC,MAAM,CAAC,mBAAmB,CAAC;;AAGtE","ignoreList":[]}
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import ReactMarkdown from 'react-markdown';
|
|
3
3
|
import remarkGfm from 'remark-gfm';
|
|
4
4
|
import { parseWeb5Url, validateLinkUrl } from '../../utils/entityLinkParser.js';
|
|
5
|
+
import { fixMalformedLinks } from '../../utils/markdownPreprocessor.js';
|
|
5
6
|
import { Web5UrlType } from '../../types/link-types.js';
|
|
6
7
|
import { cn } from '../../lib/utils.js';
|
|
7
8
|
import { useWeb5Link } from '../../hooks/useWeb5Link.js';
|
|
@@ -24,7 +25,8 @@ export const MarkdownText = _ref => {
|
|
|
24
25
|
let {
|
|
25
26
|
children: markdownChildren,
|
|
26
27
|
className = '',
|
|
27
|
-
codeClassName = 'bg-muted px-1 py-0.5 rounded text-xs font-mono'
|
|
28
|
+
codeClassName = 'bg-muted px-1 py-0.5 rounded text-xs font-mono',
|
|
29
|
+
inline = false
|
|
28
30
|
} = _ref;
|
|
29
31
|
const {
|
|
30
32
|
isActionRegistered
|
|
@@ -32,11 +34,6 @@ export const MarkdownText = _ref => {
|
|
|
32
34
|
const {
|
|
33
35
|
reportDiagnostic
|
|
34
36
|
} = useComponentDependencies();
|
|
35
|
-
|
|
36
|
-
// Fix malformed markdown links with space between ] and ( e.g. [text] (url) → [text](url)
|
|
37
|
-
const fixMalformedLinks = markdown => {
|
|
38
|
-
return markdown.replace(/\]\s+\(/g, '](');
|
|
39
|
-
};
|
|
40
37
|
const processedMarkdown = fixMalformedLinks(markdownChildren);
|
|
41
38
|
// Custom URL transform: only render valid URLs (react-markdown v9+ strips non-http by default)
|
|
42
39
|
const urlTransform = url => {
|
|
@@ -46,8 +43,10 @@ export const MarkdownText = _ref => {
|
|
|
46
43
|
}
|
|
47
44
|
return validated;
|
|
48
45
|
};
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
const Wrapper = inline ? 'span' : 'div';
|
|
47
|
+
const wrapperClassName = inline ? className || undefined : cn('prose prose-slate max-w-none', className);
|
|
48
|
+
return /*#__PURE__*/React.createElement(Wrapper, {
|
|
49
|
+
className: wrapperClassName
|
|
51
50
|
}, /*#__PURE__*/React.createElement(ReactMarkdown, {
|
|
52
51
|
remarkPlugins: [remarkGfm],
|
|
53
52
|
urlTransform: urlTransform,
|
|
@@ -56,7 +55,7 @@ export const MarkdownText = _ref => {
|
|
|
56
55
|
let {
|
|
57
56
|
children
|
|
58
57
|
} = _ref2;
|
|
59
|
-
return /*#__PURE__*/React.createElement("p", {
|
|
58
|
+
return inline ? /*#__PURE__*/React.createElement(React.Fragment, null, children) : /*#__PURE__*/React.createElement("p", {
|
|
60
59
|
className: "mb-4 leading-relaxed"
|
|
61
60
|
}, children);
|
|
62
61
|
},
|