@wix/web5-core 1.63.15 → 1.63.16

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.
@@ -1 +1 @@
1
- {"version":3,"names":["_markdownBlocks","require","_parts","_parseUtils","_entityLinkParser","_linkTypes","blockElementToPartType","element","startsWith","findNode","node","type","Array","isArray","children","child","found","extractTableCellLabel","parsed","url","parseWeb5Url","Web5UrlType","ICON","alt","value","map","join","tableCellMeta","cell","label","trim","link","href","undefined","image","imageUrl","iconParsed","ENTITY","entityType","entityId","iconHint","path","resolveSource","block","astNode","cursors","n","content","extractContent","md","extractContentMarkdown","markdown","cursor","get","astNodeIndex","target","i","length","set","text","buildListItems","listNode","item","itemParts","nodesToParts","isComplex","part","role","meta","parts","buildMeta","sourceNode","level","depth","lm","linkMetadata","title","isEntity","img","src","iconImg","iconUrl","web5Match","match","items","ordered","rows","headerRow","headerCells","columnLabels","featureColumnLabel","dataRows","slice","row","cells","firstCell","values","feature","columns","raw","kind","parseCalloutTag","htmlCommentMetadata","nodes","enrichedBlocks","convertToBlockElements","typeCounts","childCursors","Map","count","source","deriveRole","allComplex","every","it","push"],"sources":["../../../src/match/astToParts.ts"],"sourcesContent":["import type { RootContent } from 'mdast';\nimport { convertToBlockElements } from '../markdownBlocks';\nimport type {\n EnrichedBlockElement,\n BlockElement,\n} from '../patternValidator/types';\nimport {\n type Part,\n type PartType,\n extractContent,\n extractContentMarkdown,\n deriveRole,\n} from '../parts/parts';\nimport { parseCalloutTag } from '../component/componentDefinitions/parse-utils';\nimport { parseWeb5Url } from '../utils/entityLinkParser';\nimport { Web5UrlType } from '../types/link-types';\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction blockElementToPartType(element: BlockElement | string): PartType {\n if (typeof element === 'string' && element.startsWith('list{')) {\n return 'list';\n }\n switch (element) {\n case 'h1':\n case 'h2':\n case 'h3':\n case 'h4':\n case 'h5':\n case 'h6':\n return 'heading';\n case 't':\n return 'text';\n case 'link':\n return 'link';\n case 'image':\n return 'image';\n case 'icon':\n return 'icon';\n case 'list':\n return 'list';\n case 'table':\n return 'table';\n case 'blockquote':\n return 'blockquote';\n case 'callout':\n return 'callout';\n case 'html_comment':\n return 'htmlComment';\n case 'thematicBreak':\n return 'thematicBreak';\n default:\n return 'text';\n }\n}\n\n/** Find a descendant node of a given type */\nfunction findNode(node: any, type: string): any {\n if (!node) {\n return null;\n }\n if (node.type === type) {\n return node;\n }\n if (Array.isArray(node.children)) {\n for (const child of node.children) {\n const found = findNode(child, type);\n if (found) {\n return found;\n }\n }\n }\n return null;\n}\n\nfunction extractTableCellLabel(node: any): string {\n if (!node) {\n return '';\n }\n if (node.type === 'image') {\n const parsed =\n typeof node.url === 'string' ? parseWeb5Url(node.url) : null;\n return parsed?.type === Web5UrlType.ICON ? '' : node.alt || '';\n }\n if (typeof node.value === 'string') {\n return node.value;\n }\n if (Array.isArray(node.children)) {\n return node.children.map(extractTableCellLabel).join('');\n }\n return '';\n}\n\nfunction tableCellMeta(cell: any): {\n label: string;\n href?: string;\n entityType?: string;\n entityId?: string;\n iconHint?: string;\n} {\n const label = extractTableCellLabel(cell).trim();\n const link = findNode(cell, 'link');\n const href = typeof link?.url === 'string' ? link.url : undefined;\n const parsed = href ? parseWeb5Url(href) : null;\n const image = findNode(cell, 'image');\n const imageUrl = typeof image?.url === 'string' ? image.url : '';\n const iconParsed = imageUrl ? parseWeb5Url(imageUrl) : null;\n\n return {\n label,\n ...(href ? { href } : {}),\n ...(parsed?.type === Web5UrlType.ENTITY\n ? {\n entityType: parsed.entityType,\n entityId: parsed.entityId,\n }\n : {}),\n ...(iconParsed?.type === Web5UrlType.ICON\n ? { iconHint: iconParsed.path }\n : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Source resolution — maps each enriched block back to its specific AST child\n// ---------------------------------------------------------------------------\n\ninterface ResolvedSource {\n content: string;\n markdown?: string;\n node: any;\n}\n\n/**\n * For non-paragraph nodes the whole AST node is the source.\n * For paragraphs, walk children with a cursor so that each block\n * (link, image, text-run) resolves to its own specific child(ren).\n */\nfunction resolveSource(\n block: EnrichedBlockElement,\n astNode: RootContent,\n cursors: Map<number, number>,\n): ResolvedSource {\n const n = astNode as any;\n\n if (n.type !== 'paragraph') {\n const content = extractContent(astNode);\n const md = extractContentMarkdown(astNode);\n return { content, markdown: md !== content ? md : undefined, node: n };\n }\n\n const children: any[] = n.children || [];\n const cursor = cursors.get(block.astNodeIndex) || 0;\n\n if (\n block.element === 'link' ||\n block.element === 'image' ||\n block.element === 'icon'\n ) {\n const target = block.element === 'icon' ? 'image' : block.element;\n for (let i = cursor; i < children.length; i++) {\n const found =\n children[i].type === target\n ? children[i]\n : findNode(children[i], target);\n if (found) {\n cursors.set(block.astNodeIndex, i + 1);\n return { content: extractContent(found), node: found };\n }\n }\n return { content: '', node: n };\n }\n\n if (block.element === 't') {\n let text = '';\n let md = '';\n let i = cursor;\n for (; i < children.length; i++) {\n const child = children[i];\n if (child.type === 'link' || child.type === 'image') {\n break;\n }\n // Also stop at formatting wrappers that contain links/images\n if (findNode(child, 'link') || findNode(child, 'image')) {\n break;\n }\n text += extractContent(child);\n md += extractContentMarkdown(child);\n }\n cursors.set(block.astNodeIndex, i);\n // Preserve markdown when it differs from plain text (has inline formatting)\n return { content: text, markdown: md !== text ? md : undefined, node: n };\n }\n\n return { content: extractContent(astNode), node: n };\n}\n\n// ---------------------------------------------------------------------------\n// Meta extraction — uses the resolved source node, not the whole parent\n// ---------------------------------------------------------------------------\n\n/**\n * Decompose list items into ListItemParts, each carrying nested Part[] in meta.\n * Reuses nodesToParts to resolve each item's inline content (links, images, text, etc.).\n */\nfunction buildListItems(listNode: any): Part[] {\n return (listNode.children || []).map((item: any) => {\n const itemParts = nodesToParts(item.children || []);\n\n // A \"complex\" item has more than plain text (e.g. links, images, mixed\n // inline elements). In that case content is meaningless — the real data\n // lives inside the nested parts.\n const isComplex =\n itemParts.length > 1 ||\n (itemParts.length === 1 && itemParts[0].type !== 'text');\n\n const part: Part = {\n type: 'listItem',\n role: 'list-item',\n content: isComplex ? '' : extractContent(item).trim(),\n };\n if (itemParts.length > 0) {\n const markdown = extractContentMarkdown(item).trim();\n part.meta = {\n parts: itemParts,\n // Always store markdown so consumers can access the original formatting\n // (e.g. **bold** titles). For simple items, content already has plain\n // text; markdown preserves inline formatting.\n ...(markdown ? { markdown } : {}),\n };\n }\n return part;\n });\n}\n\nfunction buildMeta(\n type: PartType,\n sourceNode: any,\n block: EnrichedBlockElement,\n): Record<string, unknown> | undefined {\n if (!sourceNode) {\n return undefined;\n }\n switch (type) {\n case 'heading':\n return { level: sourceNode.depth };\n case 'link': {\n const link =\n sourceNode.type === 'link' ? sourceNode : findNode(sourceNode, 'link');\n const lm = block.linkMetadata;\n return {\n href: lm?.url || link?.url || '',\n ...(link?.title ? { title: link.title } : {}),\n ...(lm?.entityType\n ? { isEntity: true, entityType: lm.entityType }\n : {}),\n };\n }\n case 'image': {\n const img =\n sourceNode.type === 'image'\n ? sourceNode\n : findNode(sourceNode, 'image');\n return img\n ? { src: img.url || '', ...(img.alt ? { alt: img.alt } : {}) }\n : undefined;\n }\n case 'icon': {\n const iconImg =\n sourceNode.type === 'image'\n ? sourceNode\n : findNode(sourceNode, 'image');\n const iconUrl: string = iconImg?.url || '';\n const web5Match = iconUrl.match(/^web5:\\/\\/icon\\/(.+)/);\n const iconHint = web5Match?.[1] || '';\n return iconHint ? { iconHint } : undefined;\n }\n case 'list': {\n const items = buildListItems(sourceNode);\n return { ordered: !!sourceNode.ordered, items };\n }\n case 'table': {\n const rows: any[] = sourceNode.children || [];\n if (rows.length === 0) {\n return undefined;\n }\n const headerRow = rows[0];\n const headerCells: ReturnType<typeof tableCellMeta>[] = (\n headerRow?.children || []\n ).map((cell: any) => tableCellMeta(cell));\n const columnLabels = headerCells.map((cell) => cell.label);\n const featureColumnLabel = columnLabels[0] || 'Feature';\n const dataRows = rows.slice(1).map((row: any) => {\n const cells = row.children || [];\n const firstCell = tableCellMeta(cells[0]);\n const values = cells\n .slice(1)\n .map((cell: any) => extractContent(cell).trim());\n return {\n feature: firstCell.label || '',\n ...(firstCell.iconHint ? { iconHint: firstCell.iconHint } : {}),\n values,\n };\n });\n return {\n columnLabels: columnLabels.slice(1),\n columns: headerCells.slice(1),\n featureColumnLabel,\n rows: dataRows,\n };\n }\n case 'callout': {\n const raw = extractContent(sourceNode).trim();\n const { kind } = parseCalloutTag(raw);\n return kind ? { kind } : undefined;\n }\n case 'htmlComment':\n return block.htmlCommentMetadata\n ? { ...block.htmlCommentMetadata }\n : undefined;\n default:\n return undefined;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Convert markdown AST nodes into a flat array of `Part` objects.\n *\n * Each enriched block element becomes one `Part`. When a single AST node\n * (e.g. a paragraph) produces multiple blocks (link + image + text), each\n * block becomes a separate Part with content resolved from its specific\n * child within the paragraph.\n *\n * @param nodes - Markdown AST nodes (typically a slice of `root.children`)\n * @returns Ordered array of Part objects\n */\nexport function nodesToParts(nodes: RootContent[]): Part[] {\n if (!nodes || nodes.length === 0) {\n return [];\n }\n\n const enrichedBlocks = convertToBlockElements(nodes);\n const parts: Part[] = [];\n const typeCounts: Record<string, number> = {};\n const childCursors = new Map<number, number>();\n\n for (const block of enrichedBlocks) {\n const astNode = nodes[block.astNodeIndex];\n const type = blockElementToPartType(block.element);\n const count = (typeCounts[type] || 0) + 1;\n typeCounts[type] = count;\n\n const source = resolveSource(block, astNode, childCursors);\n\n const part: Part = {\n type,\n role: deriveRole(type, count),\n content: source.content.trim(),\n };\n const meta = buildMeta(type, source.node, block);\n if (meta) {\n part.meta = meta;\n }\n\n // Preserve original markdown when inline formatting exists (bold, italic, etc.)\n if (source.markdown) {\n part.meta = { ...part.meta, markdown: source.markdown.trim() };\n }\n\n // For lists whose items are all complex, the list-level content is\n // meaningless (just a concatenation of child text). Clear it so that\n // consumers rely on the structured items in meta instead.\n if (type === 'list' && meta) {\n const items = (meta.items as Part[]) || [];\n const allComplex =\n items.length > 0 && items.every((it) => it.content === '');\n if (allComplex) {\n part.content = '';\n }\n }\n\n parts.push(part);\n }\n\n return parts;\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_markdownBlocks","require","_parts","_parseUtils","_entityLinkParser","_linkTypes","blockElementToPartType","element","startsWith","findNode","node","type","Array","isArray","children","child","found","extractTableCellLabel","parsed","url","parseWeb5Url","Web5UrlType","ICON","alt","value","map","join","tableCellMeta","cell","label","trim","link","href","undefined","image","imageUrl","iconParsed","ENTITY","entityType","entityId","iconHint","path","resolveSource","block","astNode","cursors","n","content","extractContent","md","extractContentMarkdown","markdown","cursor","get","astNodeIndex","target","i","length","set","text","buildListItems","listNode","item","itemParts","nodesToParts","isComplex","part","role","meta","parts","buildMeta","sourceNode","level","depth","lm","linkMetadata","title","isEntity","img","src","iconImg","iconUrl","web5Match","match","items","ordered","rows","headerRow","headerCells","columnLabels","featureColumnLabel","dataRows","slice","row","cells","firstCell","values","feature","columns","raw","kind","parseCalloutTag","htmlCommentMetadata","nodes","enrichedBlocks","convertToBlockElements","typeCounts","childCursors","Map","seenNodes","Set","count","source","deriveRole","has","continuesNode","add","allComplex","every","it","push"],"sources":["../../../src/match/astToParts.ts"],"sourcesContent":["import type { RootContent } from 'mdast';\nimport { convertToBlockElements } from '../markdownBlocks';\nimport type {\n EnrichedBlockElement,\n BlockElement,\n} from '../patternValidator/types';\nimport {\n type Part,\n type PartType,\n extractContent,\n extractContentMarkdown,\n deriveRole,\n} from '../parts/parts';\nimport { parseCalloutTag } from '../component/componentDefinitions/parse-utils';\nimport { parseWeb5Url } from '../utils/entityLinkParser';\nimport { Web5UrlType } from '../types/link-types';\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction blockElementToPartType(element: BlockElement | string): PartType {\n if (typeof element === 'string' && element.startsWith('list{')) {\n return 'list';\n }\n switch (element) {\n case 'h1':\n case 'h2':\n case 'h3':\n case 'h4':\n case 'h5':\n case 'h6':\n return 'heading';\n case 't':\n return 'text';\n case 'link':\n return 'link';\n case 'image':\n return 'image';\n case 'icon':\n return 'icon';\n case 'list':\n return 'list';\n case 'table':\n return 'table';\n case 'blockquote':\n return 'blockquote';\n case 'callout':\n return 'callout';\n case 'html_comment':\n return 'htmlComment';\n case 'thematicBreak':\n return 'thematicBreak';\n default:\n return 'text';\n }\n}\n\n/** Find a descendant node of a given type */\nfunction findNode(node: any, type: string): any {\n if (!node) {\n return null;\n }\n if (node.type === type) {\n return node;\n }\n if (Array.isArray(node.children)) {\n for (const child of node.children) {\n const found = findNode(child, type);\n if (found) {\n return found;\n }\n }\n }\n return null;\n}\n\nfunction extractTableCellLabel(node: any): string {\n if (!node) {\n return '';\n }\n if (node.type === 'image') {\n const parsed =\n typeof node.url === 'string' ? parseWeb5Url(node.url) : null;\n return parsed?.type === Web5UrlType.ICON ? '' : node.alt || '';\n }\n if (typeof node.value === 'string') {\n return node.value;\n }\n if (Array.isArray(node.children)) {\n return node.children.map(extractTableCellLabel).join('');\n }\n return '';\n}\n\nfunction tableCellMeta(cell: any): {\n label: string;\n href?: string;\n entityType?: string;\n entityId?: string;\n iconHint?: string;\n} {\n const label = extractTableCellLabel(cell).trim();\n const link = findNode(cell, 'link');\n const href = typeof link?.url === 'string' ? link.url : undefined;\n const parsed = href ? parseWeb5Url(href) : null;\n const image = findNode(cell, 'image');\n const imageUrl = typeof image?.url === 'string' ? image.url : '';\n const iconParsed = imageUrl ? parseWeb5Url(imageUrl) : null;\n\n return {\n label,\n ...(href ? { href } : {}),\n ...(parsed?.type === Web5UrlType.ENTITY\n ? {\n entityType: parsed.entityType,\n entityId: parsed.entityId,\n }\n : {}),\n ...(iconParsed?.type === Web5UrlType.ICON\n ? { iconHint: iconParsed.path }\n : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Source resolution — maps each enriched block back to its specific AST child\n// ---------------------------------------------------------------------------\n\ninterface ResolvedSource {\n content: string;\n markdown?: string;\n node: any;\n}\n\n/**\n * For non-paragraph nodes the whole AST node is the source.\n * For paragraphs, walk children with a cursor so that each block\n * (link, image, text-run) resolves to its own specific child(ren).\n */\nfunction resolveSource(\n block: EnrichedBlockElement,\n astNode: RootContent,\n cursors: Map<number, number>,\n): ResolvedSource {\n const n = astNode as any;\n\n if (n.type !== 'paragraph') {\n const content = extractContent(astNode);\n const md = extractContentMarkdown(astNode);\n return { content, markdown: md !== content ? md : undefined, node: n };\n }\n\n const children: any[] = n.children || [];\n const cursor = cursors.get(block.astNodeIndex) || 0;\n\n if (\n block.element === 'link' ||\n block.element === 'image' ||\n block.element === 'icon'\n ) {\n const target = block.element === 'icon' ? 'image' : block.element;\n for (let i = cursor; i < children.length; i++) {\n const found =\n children[i].type === target\n ? children[i]\n : findNode(children[i], target);\n if (found) {\n cursors.set(block.astNodeIndex, i + 1);\n return { content: extractContent(found), node: found };\n }\n }\n return { content: '', node: n };\n }\n\n if (block.element === 't') {\n let text = '';\n let md = '';\n let i = cursor;\n for (; i < children.length; i++) {\n const child = children[i];\n if (child.type === 'link' || child.type === 'image') {\n break;\n }\n // Also stop at formatting wrappers that contain links/images\n if (findNode(child, 'link') || findNode(child, 'image')) {\n break;\n }\n text += extractContent(child);\n md += extractContentMarkdown(child);\n }\n cursors.set(block.astNodeIndex, i);\n // Preserve markdown when it differs from plain text (has inline formatting)\n return { content: text, markdown: md !== text ? md : undefined, node: n };\n }\n\n return { content: extractContent(astNode), node: n };\n}\n\n// ---------------------------------------------------------------------------\n// Meta extraction — uses the resolved source node, not the whole parent\n// ---------------------------------------------------------------------------\n\n/**\n * Decompose list items into ListItemParts, each carrying nested Part[] in meta.\n * Reuses nodesToParts to resolve each item's inline content (links, images, text, etc.).\n */\nfunction buildListItems(listNode: any): Part[] {\n return (listNode.children || []).map((item: any) => {\n const itemParts = nodesToParts(item.children || []);\n\n // A \"complex\" item has more than plain text (e.g. links, images, mixed\n // inline elements). In that case content is meaningless — the real data\n // lives inside the nested parts.\n const isComplex =\n itemParts.length > 1 ||\n (itemParts.length === 1 && itemParts[0].type !== 'text');\n\n const part: Part = {\n type: 'listItem',\n role: 'list-item',\n content: isComplex ? '' : extractContent(item).trim(),\n };\n if (itemParts.length > 0) {\n const markdown = extractContentMarkdown(item).trim();\n part.meta = {\n parts: itemParts,\n // Always store markdown so consumers can access the original formatting\n // (e.g. **bold** titles). For simple items, content already has plain\n // text; markdown preserves inline formatting.\n ...(markdown ? { markdown } : {}),\n };\n }\n return part;\n });\n}\n\nfunction buildMeta(\n type: PartType,\n sourceNode: any,\n block: EnrichedBlockElement,\n): Record<string, unknown> | undefined {\n if (!sourceNode) {\n return undefined;\n }\n switch (type) {\n case 'heading':\n return { level: sourceNode.depth };\n case 'link': {\n const link =\n sourceNode.type === 'link' ? sourceNode : findNode(sourceNode, 'link');\n const lm = block.linkMetadata;\n return {\n href: lm?.url || link?.url || '',\n ...(link?.title ? { title: link.title } : {}),\n ...(lm?.entityType\n ? { isEntity: true, entityType: lm.entityType }\n : {}),\n };\n }\n case 'image': {\n const img =\n sourceNode.type === 'image'\n ? sourceNode\n : findNode(sourceNode, 'image');\n return img\n ? { src: img.url || '', ...(img.alt ? { alt: img.alt } : {}) }\n : undefined;\n }\n case 'icon': {\n const iconImg =\n sourceNode.type === 'image'\n ? sourceNode\n : findNode(sourceNode, 'image');\n const iconUrl: string = iconImg?.url || '';\n const web5Match = iconUrl.match(/^web5:\\/\\/icon\\/(.+)/);\n const iconHint = web5Match?.[1] || '';\n return iconHint ? { iconHint } : undefined;\n }\n case 'list': {\n const items = buildListItems(sourceNode);\n return { ordered: !!sourceNode.ordered, items };\n }\n case 'table': {\n const rows: any[] = sourceNode.children || [];\n if (rows.length === 0) {\n return undefined;\n }\n const headerRow = rows[0];\n const headerCells: ReturnType<typeof tableCellMeta>[] = (\n headerRow?.children || []\n ).map((cell: any) => tableCellMeta(cell));\n const columnLabels = headerCells.map((cell) => cell.label);\n const featureColumnLabel = columnLabels[0] || 'Feature';\n const dataRows = rows.slice(1).map((row: any) => {\n const cells = row.children || [];\n const firstCell = tableCellMeta(cells[0]);\n const values = cells\n .slice(1)\n .map((cell: any) => extractContent(cell).trim());\n return {\n feature: firstCell.label || '',\n ...(firstCell.iconHint ? { iconHint: firstCell.iconHint } : {}),\n values,\n };\n });\n return {\n columnLabels: columnLabels.slice(1),\n columns: headerCells.slice(1),\n featureColumnLabel,\n rows: dataRows,\n };\n }\n case 'callout': {\n const raw = extractContent(sourceNode).trim();\n const { kind } = parseCalloutTag(raw);\n return kind ? { kind } : undefined;\n }\n case 'htmlComment':\n return block.htmlCommentMetadata\n ? { ...block.htmlCommentMetadata }\n : undefined;\n default:\n return undefined;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Convert markdown AST nodes into a flat array of `Part` objects.\n *\n * Each enriched block element becomes one `Part`. When a single AST node\n * (e.g. a paragraph) produces multiple blocks (link + image + text), each\n * block becomes a separate Part with content resolved from its specific\n * child within the paragraph.\n *\n * @param nodes - Markdown AST nodes (typically a slice of `root.children`)\n * @returns Ordered array of Part objects\n */\nexport function nodesToParts(nodes: RootContent[]): Part[] {\n if (!nodes || nodes.length === 0) {\n return [];\n }\n\n const enrichedBlocks = convertToBlockElements(nodes);\n const parts: Part[] = [];\n const typeCounts: Record<string, number> = {};\n const childCursors = new Map<number, number>();\n // A paragraph carrying an inline link is unwrapped into several block\n // elements (`t`, `link`, `t`), so its parts are siblings with nothing to say\n // they came from one paragraph. Mark every part after the first of a given\n // AST node, so a consumer rebuilding prose can tell \"same paragraph, keep\n // going\" from \"next paragraph, break\". Only split nodes carry the flag —\n // plain paragraphs, headings and images stay meta-free.\n const seenNodes = new Set<number>();\n\n for (const block of enrichedBlocks) {\n const astNode = nodes[block.astNodeIndex];\n const type = blockElementToPartType(block.element);\n const count = (typeCounts[type] || 0) + 1;\n typeCounts[type] = count;\n\n const source = resolveSource(block, astNode, childCursors);\n\n const part: Part = {\n type,\n role: deriveRole(type, count),\n content: source.content.trim(),\n };\n const meta = buildMeta(type, source.node, block);\n if (meta) {\n part.meta = meta;\n }\n\n // Preserve original markdown when inline formatting exists (bold, italic, etc.)\n if (source.markdown) {\n part.meta = { ...part.meta, markdown: source.markdown.trim() };\n }\n\n if (seenNodes.has(block.astNodeIndex)) {\n part.meta = { ...part.meta, continuesNode: true };\n }\n seenNodes.add(block.astNodeIndex);\n\n // For lists whose items are all complex, the list-level content is\n // meaningless (just a concatenation of child text). Clear it so that\n // consumers rely on the structured items in meta instead.\n if (type === 'list' && meta) {\n const items = (meta.items as Part[]) || [];\n const allComplex =\n items.length > 0 && items.every((it) => it.content === '');\n if (allComplex) {\n part.content = '';\n }\n }\n\n parts.push(part);\n }\n\n return parts;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,60 +1,67 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- import { headingMarkdown, bodyText, calloutFromParts } from './parse-utils.js';
2
+ import { headingMarkdown, bodyMarkdown } from './parse-utils.js';
3
3
  import { DIAGNOSTIC_TYPES } from '../diagnosticTypes.js';
4
4
  export class TextBlockSectionDefinition {
5
5
  constructor() {
6
6
  _defineProperty(this, "sectionType", 'textBlock');
7
- // The trailing callout is OPTIONAL. A heading plus running copy is the shape
8
- // stores emit constantly for explainer content, and requiring the blockquote
9
- // meant those blocks matched no definition at all and fell through to
10
- // `FallbackSectionDefinition` rendered as undifferentiated prose with no
11
- // section treatment. `parse()` already tolerates a missing callout (it only
12
- // rejects when title AND description are empty).
7
+ // A repeated body, not a single `t` a heading owns ALL the running copy
8
+ // beneath it. With one `t` the pattern took the heading and the FIRST
9
+ // paragraph only;
10
+ // because a pattern matches a PREFIX of the block, every later paragraph fell
11
+ // through to `FallbackSectionDefinition` and rendered as undifferentiated
12
+ // prose with no section treatment. Multi-paragraph explainer copy is the
13
+ // shape stores emit constantly, so most of the block was landing unstyled.
13
14
  //
14
- // NOTE for registry authors: with the callout optional this also matches a
15
- // bare `h2 > t`, and a pattern matches a PREFIX of the block. Register
15
+ // No callout in the grammar. A trailing blockquote is
16
+ // `CalloutSectionDefinition`'s (`html_comment? > callout+`) it sits above
17
+ // `textBlock` in `createSdkRegistry` and in every client registry, so once
18
+ // this pattern stops before the quote the parser's next iteration claims it
19
+ // as its own section. Keeping it here only duplicated that ownership.
20
+ //
21
+ // `link` is in the alternation because `convertToBlockElements` unwraps a
22
+ // paragraph into its inline nodes: `Try narrowing to [men](web5://ask/…)
23
+ // instead` emits `t link t`. With `t+` alone the run ended at that `link`,
24
+ // truncating the section at the first paragraph carrying an ask link — the
25
+ // exact shape DL #134 made the prompts emit. `parse()` uses `bodyMarkdown`,
26
+ // which keeps the link inline rather than deleting it the way `bodyText`
27
+ // does. Entity blocks are unaffected: their links are `link[entityType]` and
28
+ // every registry puts the entity definitions above this one.
29
+ //
30
+ // NOTE for registry authors: this still matches a bare `h2 > t`, so the
31
+ // prefix hazard is unchanged — if anything it claims MORE. Register
16
32
  // `textBlock` BELOW every definition whose block opens `h2 > t` — entity,
17
33
  // entityCollection, listItemsSection, featureCards, ctaBanner, comparison,
18
- // kpi, nextSteps. Above them it claims the heading + intro paragraph off the
34
+ // kpi, nextSteps. Above them it claims the heading + intro copy off the
19
35
  // front of the block and strands the list / links / table that follow
20
36
  // (`EntitySectionDefinition` allows `h2 > (t | callout)* > links…`, and
21
37
  // `listItemsSection` / `ctaBanner` are the same shape). `createSdkRegistry`
22
38
  // and the client registries in this repo order it that way; a client
23
39
  // registry living outside this repo has to do the same.
24
- _defineProperty(this, "patterns", ['html_comment? > h2 > t > callout?']);
40
+ _defineProperty(this, "patterns", ['html_comment? > h2 > (t | link)+']);
25
41
  _defineProperty(this, "defaults", {
26
42
  title: 'Text Block Title',
27
- description: 'Description text.',
28
- callout: {
29
- text: 'A key insight or quote.'
30
- }
43
+ description: 'Description text.'
31
44
  });
32
45
  _defineProperty(this, "fixtures", [{
33
46
  markdown: `## Choosing the Right Liquid Data Option
34
47
 
35
48
  Liquid Data Go is designed for brands that want affordable, scalable access to syndicated POS, shopper, and pricing insights with minimal setup and no data expertise required.
36
49
 
37
- > If you mainly need fast, packaged insights in one category, Liquid Data Go is usually the right fit; if you need to integrate many datasets and support multiple enterprise workflows, the broader Liquid Data platform and its solutions become more relevant.`,
50
+ It covers a single category out of the box, so a brand can stand up reporting without a data team and without negotiating a full platform contract first.
51
+
52
+ The broader Liquid Data platform becomes the better fit once you need to integrate many datasets and support multiple enterprise workflows.`,
38
53
  expected: {
39
54
  title: 'Choosing the Right Liquid Data Option',
40
- description: 'Liquid Data Go is designed for brands that want affordable, scalable access to syndicated POS, shopper, and pricing insights with minimal setup and no data expertise required.',
41
- callout: {
42
- text: 'If you mainly need fast, packaged insights in one category, Liquid Data Go is usually the right fit; if you need to integrate many datasets and support multiple enterprise workflows, the broader Liquid Data platform and its solutions become more relevant.'
43
- }
55
+ description: ['Liquid Data Go is designed for brands that want affordable, scalable access to syndicated POS, shopper, and pricing insights with minimal setup and no data expertise required.', 'It covers a single category out of the box, so a brand can stand up reporting without a data team and without negotiating a full platform contract first.', 'The broader Liquid Data platform becomes the better fit once you need to integrate many datasets and support multiple enterprise workflows.'].join('\n\n')
44
56
  }
45
57
  }, {
46
58
  markdown: `<!-- section: textBlock -->
47
59
  ## Key Takeaway
48
60
 
49
- The platform scales with your needs.
50
-
51
- > Start small with Go, then expand to the full suite as your data maturity grows.`,
61
+ The platform scales with your needs.`,
52
62
  expected: {
53
63
  title: 'Key Takeaway',
54
- description: 'The platform scales with your needs.',
55
- callout: {
56
- text: 'Start small with Go, then expand to the full suite as your data maturity grows.'
57
- }
64
+ description: 'The platform scales with your needs.'
58
65
  }
59
66
  }, {
60
67
  markdown: `## How to choose between a clinical serum and a nourishing dry oil
@@ -62,23 +69,20 @@ The platform scales with your needs.
62
69
  Clinically tested serums with patented actives target visible reduction of marks and uneven tone, while dry oils focus on broad nourishment and a satin finish.`,
63
70
  expected: {
64
71
  title: 'How to choose between a clinical serum and a nourishing dry oil',
65
- description: 'Clinically tested serums with patented actives target visible reduction of marks and uneven tone, while dry oils focus on broad nourishment and a satin finish.',
66
- callout: undefined
72
+ description: 'Clinically tested serums with patented actives target visible reduction of marks and uneven tone, while dry oils focus on broad nourishment and a satin finish.'
67
73
  }
68
74
  }]);
69
75
  }
70
76
  parse(parts, context) {
71
77
  const title = headingMarkdown(parts, 2) || '';
72
- const description = bodyText(parts) || '';
73
- const callout = calloutFromParts(parts);
78
+ const description = bodyMarkdown(parts) || '';
74
79
  if (!title && !description) {
75
80
  context == null || context.reportDiagnostic == null || context.reportDiagnostic(DIAGNOSTIC_TYPES.SECTION_REJECTED, 'textBlock: both title and description are empty');
76
81
  return null;
77
82
  }
78
83
  return {
79
84
  title,
80
- description,
81
- callout
85
+ description
82
86
  };
83
87
  }
84
88
  }
@@ -1 +1 @@
1
- {"version":3,"names":["headingMarkdown","bodyText","calloutFromParts","DIAGNOSTIC_TYPES","TextBlockSectionDefinition","constructor","_defineProperty","title","description","callout","text","markdown","expected","undefined","parse","parts","context","reportDiagnostic","SECTION_REJECTED"],"sources":["../../../../src/component/componentDefinitions/TextBlockSectionDefinition.ts"],"sourcesContent":["import type { Part } from '../../parts/parts';\nimport { headingMarkdown, bodyText, calloutFromParts } from './parse-utils';\nimport type {\n TextBlockCompProps,\n TextBlockSectionComponent,\n SectionFixture,\n} from '../types';\nimport type { SectionDefinition, ParseContext } from '../section-definition';\nimport { DIAGNOSTIC_TYPES } from '../diagnosticTypes';\n\nexport class TextBlockSectionDefinition\n implements SectionDefinition<TextBlockSectionComponent>\n{\n sectionType = 'textBlock' as const;\n // The trailing callout is OPTIONAL. A heading plus running copy is the shape\n // stores emit constantly for explainer content, and requiring the blockquote\n // meant those blocks matched no definition at all and fell through to\n // `FallbackSectionDefinition` rendered as undifferentiated prose with no\n // section treatment. `parse()` already tolerates a missing callout (it only\n // rejects when title AND description are empty).\n //\n // NOTE for registry authors: with the callout optional this also matches a\n // bare `h2 > t`, and a pattern matches a PREFIX of the block. Register\n // `textBlock` BELOW every definition whose block opens `h2 > t` — entity,\n // entityCollection, listItemsSection, featureCards, ctaBanner, comparison,\n // kpi, nextSteps. Above them it claims the heading + intro paragraph off the\n // front of the block and strands the list / links / table that follow\n // (`EntitySectionDefinition` allows `h2 > (t | callout)* > links…`, and\n // `listItemsSection` / `ctaBanner` are the same shape). `createSdkRegistry`\n // and the client registries in this repo order it that way; a client\n // registry living outside this repo has to do the same.\n patterns = ['html_comment? > h2 > t > callout?'];\n\n defaults: TextBlockCompProps = {\n title: 'Text Block Title',\n description: 'Description text.',\n callout: { text: 'A key insight or quote.' },\n };\n\n fixtures: SectionFixture<TextBlockCompProps>[] = [\n {\n markdown: `## Choosing the Right Liquid Data Option\n\nLiquid Data Go is designed for brands that want affordable, scalable access to syndicated POS, shopper, and pricing insights with minimal setup and no data expertise required.\n\n> If you mainly need fast, packaged insights in one category, Liquid Data Go is usually the right fit; if you need to integrate many datasets and support multiple enterprise workflows, the broader Liquid Data platform and its solutions become more relevant.`,\n expected: {\n title: 'Choosing the Right Liquid Data Option',\n description:\n 'Liquid Data Go is designed for brands that want affordable, scalable access to syndicated POS, shopper, and pricing insights with minimal setup and no data expertise required.',\n callout: {\n text: 'If you mainly need fast, packaged insights in one category, Liquid Data Go is usually the right fit; if you need to integrate many datasets and support multiple enterprise workflows, the broader Liquid Data platform and its solutions become more relevant.',\n },\n },\n },\n {\n markdown: `<!-- section: textBlock -->\n## Key Takeaway\n\nThe platform scales with your needs.\n\n> Start small with Go, then expand to the full suite as your data maturity grows.`,\n expected: {\n title: 'Key Takeaway',\n description: 'The platform scales with your needs.',\n callout: {\n text: 'Start small with Go, then expand to the full suite as your data maturity grows.',\n },\n },\n },\n {\n markdown: `## How to choose between a clinical serum and a nourishing dry oil\n\nClinically tested serums with patented actives target visible reduction of marks and uneven tone, while dry oils focus on broad nourishment and a satin finish.`,\n expected: {\n title: 'How to choose between a clinical serum and a nourishing dry oil',\n description:\n 'Clinically tested serums with patented actives target visible reduction of marks and uneven tone, while dry oils focus on broad nourishment and a satin finish.',\n callout: undefined,\n },\n },\n ];\n\n parse(parts: Part[], context?: ParseContext): TextBlockCompProps | null {\n const title = headingMarkdown(parts, 2) || '';\n const description = bodyText(parts) || '';\n const callout = calloutFromParts(parts);\n\n if (!title && !description) {\n context?.reportDiagnostic?.(\n DIAGNOSTIC_TYPES.SECTION_REJECTED,\n 'textBlock: both title and description are empty',\n );\n return null;\n }\n\n return { title, description, callout };\n }\n}\n"],"mappings":";AACA,SAASA,eAAe,EAAEC,QAAQ,EAAEC,gBAAgB,QAAQ,eAAe;AAO3E,SAASC,gBAAgB,QAAQ,oBAAoB;AAErD,OAAO,MAAMC,0BAA0B,CAEvC;EAAAC,YAAA;IAAAC,eAAA,sBACgB,WAAW;IACzB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IAAAA,eAAA,mBACW,CAAC,mCAAmC,CAAC;IAAAA,eAAA,mBAEjB;MAC7BC,KAAK,EAAE,kBAAkB;MACzBC,WAAW,EAAE,mBAAmB;MAChCC,OAAO,EAAE;QAAEC,IAAI,EAAE;MAA0B;IAC7C,CAAC;IAAAJ,eAAA,mBAEgD,CAC/C;MACEK,QAAQ,EAAE;AAChB;AACA;AACA;AACA,kQAAkQ;MAC5PC,QAAQ,EAAE;QACRL,KAAK,EAAE,uCAAuC;QAC9CC,WAAW,EACT,iLAAiL;QACnLC,OAAO,EAAE;UACPC,IAAI,EAAE;QACR;MACF;IACF,CAAC,EACD;MACEC,QAAQ,EAAE;AAChB;AACA;AACA;AACA;AACA,kFAAkF;MAC5EC,QAAQ,EAAE;QACRL,KAAK,EAAE,cAAc;QACrBC,WAAW,EAAE,sCAAsC;QACnDC,OAAO,EAAE;UACPC,IAAI,EAAE;QACR;MACF;IACF,CAAC,EACD;MACEC,QAAQ,EAAE;AAChB;AACA,gKAAgK;MAC1JC,QAAQ,EAAE;QACRL,KAAK,EAAE,iEAAiE;QACxEC,WAAW,EACT,iKAAiK;QACnKC,OAAO,EAAEI;MACX;IACF,CAAC,CACF;EAAA;EAEDC,KAAKA,CAACC,KAAa,EAAEC,OAAsB,EAA6B;IACtE,MAAMT,KAAK,GAAGP,eAAe,CAACe,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE;IAC7C,MAAMP,WAAW,GAAGP,QAAQ,CAACc,KAAK,CAAC,IAAI,EAAE;IACzC,MAAMN,OAAO,GAAGP,gBAAgB,CAACa,KAAK,CAAC;IAEvC,IAAI,CAACR,KAAK,IAAI,CAACC,WAAW,EAAE;MAC1BQ,OAAO,YAAPA,OAAO,CAAEC,gBAAgB,YAAzBD,OAAO,CAAEC,gBAAgB,CACvBd,gBAAgB,CAACe,gBAAgB,EACjC,iDACF,CAAC;MACD,OAAO,IAAI;IACb;IAEA,OAAO;MAAEX,KAAK;MAAEC,WAAW;MAAEC;IAAQ,CAAC;EACxC;AACF","ignoreList":[]}
1
+ {"version":3,"names":["headingMarkdown","bodyMarkdown","DIAGNOSTIC_TYPES","TextBlockSectionDefinition","constructor","_defineProperty","title","description","markdown","expected","join","parse","parts","context","reportDiagnostic","SECTION_REJECTED"],"sources":["../../../../src/component/componentDefinitions/TextBlockSectionDefinition.ts"],"sourcesContent":["import type { Part } from '../../parts/parts';\nimport { headingMarkdown, bodyMarkdown } from './parse-utils';\nimport type {\n TextBlockCompProps,\n TextBlockSectionComponent,\n SectionFixture,\n} from '../types';\nimport type { SectionDefinition, ParseContext } from '../section-definition';\nimport { DIAGNOSTIC_TYPES } from '../diagnosticTypes';\n\nexport class TextBlockSectionDefinition\n implements SectionDefinition<TextBlockSectionComponent>\n{\n sectionType = 'textBlock' as const;\n // A repeated body, not a single `t` — a heading owns ALL the running copy\n // beneath it. With one `t` the pattern took the heading and the FIRST\n // paragraph only;\n // because a pattern matches a PREFIX of the block, every later paragraph fell\n // through to `FallbackSectionDefinition` and rendered as undifferentiated\n // prose with no section treatment. Multi-paragraph explainer copy is the\n // shape stores emit constantly, so most of the block was landing unstyled.\n //\n // No callout in the grammar. A trailing blockquote is\n // `CalloutSectionDefinition`'s (`html_comment? > callout+`) it sits above\n // `textBlock` in `createSdkRegistry` and in every client registry, so once\n // this pattern stops before the quote the parser's next iteration claims it\n // as its own section. Keeping it here only duplicated that ownership.\n //\n // `link` is in the alternation because `convertToBlockElements` unwraps a\n // paragraph into its inline nodes: `Try narrowing to [men](web5://ask/…)\n // instead` emits `t link t`. With `t+` alone the run ended at that `link`,\n // truncating the section at the first paragraph carrying an ask link — the\n // exact shape DL #134 made the prompts emit. `parse()` uses `bodyMarkdown`,\n // which keeps the link inline rather than deleting it the way `bodyText`\n // does. Entity blocks are unaffected: their links are `link[entityType]` and\n // every registry puts the entity definitions above this one.\n //\n // NOTE for registry authors: this still matches a bare `h2 > t`, so the\n // prefix hazard is unchanged if anything it claims MORE. Register\n // `textBlock` BELOW every definition whose block opens `h2 > t` — entity,\n // entityCollection, listItemsSection, featureCards, ctaBanner, comparison,\n // kpi, nextSteps. Above them it claims the heading + intro copy off the\n // front of the block and strands the list / links / table that follow\n // (`EntitySectionDefinition` allows `h2 > (t | callout)* > links…`, and\n // `listItemsSection` / `ctaBanner` are the same shape). `createSdkRegistry`\n // and the client registries in this repo order it that way; a client\n // registry living outside this repo has to do the same.\n patterns = ['html_comment? > h2 > (t | link)+'];\n\n defaults: TextBlockCompProps = {\n title: 'Text Block Title',\n description: 'Description text.',\n };\n\n fixtures: SectionFixture<TextBlockCompProps>[] = [\n {\n markdown: `## Choosing the Right Liquid Data Option\n\nLiquid Data Go is designed for brands that want affordable, scalable access to syndicated POS, shopper, and pricing insights with minimal setup and no data expertise required.\n\nIt covers a single category out of the box, so a brand can stand up reporting without a data team and without negotiating a full platform contract first.\n\nThe broader Liquid Data platform becomes the better fit once you need to integrate many datasets and support multiple enterprise workflows.`,\n expected: {\n title: 'Choosing the Right Liquid Data Option',\n description: [\n 'Liquid Data Go is designed for brands that want affordable, scalable access to syndicated POS, shopper, and pricing insights with minimal setup and no data expertise required.',\n 'It covers a single category out of the box, so a brand can stand up reporting without a data team and without negotiating a full platform contract first.',\n 'The broader Liquid Data platform becomes the better fit once you need to integrate many datasets and support multiple enterprise workflows.',\n ].join('\\n\\n'),\n },\n },\n {\n markdown: `<!-- section: textBlock -->\n## Key Takeaway\n\nThe platform scales with your needs.`,\n expected: {\n title: 'Key Takeaway',\n description: 'The platform scales with your needs.',\n },\n },\n {\n markdown: `## How to choose between a clinical serum and a nourishing dry oil\n\nClinically tested serums with patented actives target visible reduction of marks and uneven tone, while dry oils focus on broad nourishment and a satin finish.`,\n expected: {\n title:\n 'How to choose between a clinical serum and a nourishing dry oil',\n description:\n 'Clinically tested serums with patented actives target visible reduction of marks and uneven tone, while dry oils focus on broad nourishment and a satin finish.',\n },\n },\n ];\n\n parse(parts: Part[], context?: ParseContext): TextBlockCompProps | null {\n const title = headingMarkdown(parts, 2) || '';\n const description = bodyMarkdown(parts) || '';\n\n if (!title && !description) {\n context?.reportDiagnostic?.(\n DIAGNOSTIC_TYPES.SECTION_REJECTED,\n 'textBlock: both title and description are empty',\n );\n return null;\n }\n\n return { title, description };\n }\n}\n"],"mappings":";AACA,SAASA,eAAe,EAAEC,YAAY,QAAQ,eAAe;AAO7D,SAASC,gBAAgB,QAAQ,oBAAoB;AAErD,OAAO,MAAMC,0BAA0B,CAEvC;EAAAC,YAAA;IAAAC,eAAA,sBACgB,WAAW;IACzB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IAAAA,eAAA,mBACW,CAAC,kCAAkC,CAAC;IAAAA,eAAA,mBAEhB;MAC7BC,KAAK,EAAE,kBAAkB;MACzBC,WAAW,EAAE;IACf,CAAC;IAAAF,eAAA,mBAEgD,CAC/C;MACEG,QAAQ,EAAE;AAChB;AACA;AACA;AACA;AACA;AACA,4IAA4I;MACtIC,QAAQ,EAAE;QACRH,KAAK,EAAE,uCAAuC;QAC9CC,WAAW,EAAE,CACX,iLAAiL,EACjL,2JAA2J,EAC3J,6IAA6I,CAC9I,CAACG,IAAI,CAAC,MAAM;MACf;IACF,CAAC,EACD;MACEF,QAAQ,EAAE;AAChB;AACA;AACA,qCAAqC;MAC/BC,QAAQ,EAAE;QACRH,KAAK,EAAE,cAAc;QACrBC,WAAW,EAAE;MACf;IACF,CAAC,EACD;MACEC,QAAQ,EAAE;AAChB;AACA,gKAAgK;MAC1JC,QAAQ,EAAE;QACRH,KAAK,EACH,iEAAiE;QACnEC,WAAW,EACT;MACJ;IACF,CAAC,CACF;EAAA;EAEDI,KAAKA,CAACC,KAAa,EAAEC,OAAsB,EAA6B;IACtE,MAAMP,KAAK,GAAGN,eAAe,CAACY,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE;IAC7C,MAAML,WAAW,GAAGN,YAAY,CAACW,KAAK,CAAC,IAAI,EAAE;IAE7C,IAAI,CAACN,KAAK,IAAI,CAACC,WAAW,EAAE;MAC1BM,OAAO,YAAPA,OAAO,CAAEC,gBAAgB,YAAzBD,OAAO,CAAEC,gBAAgB,CACvBZ,gBAAgB,CAACa,gBAAgB,EACjC,iDACF,CAAC;MACD,OAAO,IAAI;IACb;IAEA,OAAO;MAAET,KAAK;MAAEC;IAAY,CAAC;EAC/B;AACF","ignoreList":[]}
@@ -55,10 +55,11 @@ export function createSdkRegistry() {
55
55
  .register(new CalloutSectionDefinition()).register(new HtmlCommentSectionDefinition()).register(new CtaBannerSectionDefinition())
56
56
  // textBlock comes after every definition whose block opens `h2 > t`
57
57
  // (entity, listItems, featureCards, ctaBanner, comparison, …). Its
58
- // trailing callout is optional, so its pattern also matches a bare
59
- // `h2 > t`, and a pattern matches a PREFIX of the block — registered
60
- // above those it would claim the heading + intro paragraph and strand
61
- // the list / links / table that follow in a separate section.
58
+ // `h2 > t+` also matches a bare `h2 > t`, and a pattern matches a PREFIX
59
+ // of the block registered above those it would claim the heading +
60
+ // intro copy and strand the list / links / table that follow in a
61
+ // separate section. It stops before a trailing callout, which Callout
62
+ // (registered above) then claims on the parser's next iteration.
62
63
  .register(new TextBlockSectionDefinition()).register(new FallbackSectionDefinition()).register(new ErrorSectionDefinition());
63
64
  }
64
65
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["ComparisonSectionDefinition","TextBlockSectionDefinition","HeroSectionDefinition","HeroEntitySectionDefinition","KpiSectionDefinition","FeatureCardsSectionDefinition","EntitySectionDefinition","EntityCollectionSectionDefinition","CtaBannerSectionDefinition","CalloutSectionDefinition","NextStepsSectionDefinition","FeatureSection9PlusDefinition","ListItemsSectionDefinition","SkipNodesSectionDefinition","HtmlCommentSectionDefinition","SearchSectionDefinition","ErrorSectionDefinition","FallbackSectionDefinition","ComponentRegistry","createSdkRegistry","register"],"sources":["../../../../src/component/componentDefinitions/index.ts"],"sourcesContent":["export type { SectionDefinition } from '../section-definition';\nexport { ComparisonSectionDefinition } from './ComparisonSectionDefinition';\nexport { TextBlockSectionDefinition } from './TextBlockSectionDefinition';\nexport { HeroSectionDefinition } from './HeroSectionDefinition';\nexport { HeroEntitySectionDefinition } from './HeroEntitySectionDefinition';\nexport { KpiSectionDefinition } from './KpiSectionDefinition';\nexport { FeatureCardsSectionDefinition } from './FeatureCardsSectionDefinition';\nexport { EntitySectionDefinition } from './EntitySectionDefinition';\nexport { EntityCollectionSectionDefinition } from './EntityCollectionSectionDefinition';\nexport { CtaBannerSectionDefinition } from './CtaBannerSectionDefinition';\nexport { CalloutSectionDefinition } from './CalloutSectionDefinition';\nexport { NextStepsSectionDefinition } from './NextStepsSectionDefinition';\nexport { FeatureSection9PlusDefinition } from './FeatureSection9PlusDefinition';\nexport { ListItemsSectionDefinition } from './listItemsSectionDefinition';\nexport { SkipNodesSectionDefinition } from './SkipNodesSectionDefinition';\nexport { HtmlCommentSectionDefinition } from './HtmlCommentSectionDefinition';\nexport { SearchSectionDefinition } from './SearchSectionDefinition';\nexport { ErrorSectionDefinition } from './ErrorSectionDefinition';\nexport { FallbackSectionDefinition } from './FallbackSectionDefinition';\n\nimport { ComponentRegistry } from '../../registry';\nimport { SkipNodesSectionDefinition } from './SkipNodesSectionDefinition';\nimport { SearchSectionDefinition } from './SearchSectionDefinition';\nimport { KpiSectionDefinition } from './KpiSectionDefinition';\nimport { NextStepsSectionDefinition } from './NextStepsSectionDefinition';\nimport { EntitySectionDefinition } from './EntitySectionDefinition';\nimport { EntityCollectionSectionDefinition } from './EntityCollectionSectionDefinition';\nimport { HeroEntitySectionDefinition } from './HeroEntitySectionDefinition';\nimport { HeroSectionDefinition } from './HeroSectionDefinition';\nimport { FeatureCardsSectionDefinition } from './FeatureCardsSectionDefinition';\nimport { FeatureSection9PlusDefinition } from './FeatureSection9PlusDefinition';\nimport { ListItemsSectionDefinition } from './listItemsSectionDefinition';\nimport { ComparisonSectionDefinition } from './ComparisonSectionDefinition';\nimport { HtmlCommentSectionDefinition } from './HtmlCommentSectionDefinition';\nimport { CtaBannerSectionDefinition } from './CtaBannerSectionDefinition';\nimport { CalloutSectionDefinition } from './CalloutSectionDefinition';\nimport { FallbackSectionDefinition } from './FallbackSectionDefinition';\nimport { ErrorSectionDefinition } from './ErrorSectionDefinition';\nimport { TextBlockSectionDefinition } from './TextBlockSectionDefinition';\n\n/**\n * Creates an SDK registry with all section definitions registered in the\n * same priority order as the app registry (createAppRegistry.ts).\n * Registration order determines evaluation priority — first match wins.\n */\nexport function createSdkRegistry(): ComponentRegistry<null> {\n return (\n new ComponentRegistry<null>(null)\n .register(new SkipNodesSectionDefinition())\n .register(new SearchSectionDefinition())\n .register(new KpiSectionDefinition())\n .register(new NextStepsSectionDefinition())\n // Collection entities are claimed by their own definition first — it is a\n // strictly narrower match than EntitySectionDefinition, which would\n // otherwise swallow collection, product and article blocks alike.\n .register(new EntityCollectionSectionDefinition())\n .register(new EntitySectionDefinition())\n .register(new HeroEntitySectionDefinition())\n .register(new HeroSectionDefinition())\n .register(new FeatureCardsSectionDefinition())\n .register(new ListItemsSectionDefinition())\n .register(new FeatureSection9PlusDefinition())\n .register(new ComparisonSectionDefinition())\n // Callout sits above HtmlComment: a callout block opens with its own\n // `<!-- section:callout -->` descriptor, and HtmlComment's bare\n // `html_comment` pattern would match that comment alone. A pattern may\n // match a PREFIX of a block, so HtmlComment would claim the descriptor\n // and strand the prose below it in the fallback, unstyled.\n .register(new CalloutSectionDefinition())\n .register(new HtmlCommentSectionDefinition())\n .register(new CtaBannerSectionDefinition())\n // textBlock comes after every definition whose block opens `h2 > t`\n // (entity, listItems, featureCards, ctaBanner, comparison, …). Its\n // trailing callout is optional, so its pattern also matches a bare\n // `h2 > t`, and a pattern matches a PREFIX of the block — registered\n // above those it would claim the heading + intro paragraph and strand\n // the list / links / table that follow in a separate section.\n .register(new TextBlockSectionDefinition())\n .register(new FallbackSectionDefinition())\n .register(new ErrorSectionDefinition())\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["ComparisonSectionDefinition","TextBlockSectionDefinition","HeroSectionDefinition","HeroEntitySectionDefinition","KpiSectionDefinition","FeatureCardsSectionDefinition","EntitySectionDefinition","EntityCollectionSectionDefinition","CtaBannerSectionDefinition","CalloutSectionDefinition","NextStepsSectionDefinition","FeatureSection9PlusDefinition","ListItemsSectionDefinition","SkipNodesSectionDefinition","HtmlCommentSectionDefinition","SearchSectionDefinition","ErrorSectionDefinition","FallbackSectionDefinition","ComponentRegistry","createSdkRegistry","register"],"sources":["../../../../src/component/componentDefinitions/index.ts"],"sourcesContent":["export type { SectionDefinition } from '../section-definition';\nexport { ComparisonSectionDefinition } from './ComparisonSectionDefinition';\nexport { TextBlockSectionDefinition } from './TextBlockSectionDefinition';\nexport { HeroSectionDefinition } from './HeroSectionDefinition';\nexport { HeroEntitySectionDefinition } from './HeroEntitySectionDefinition';\nexport { KpiSectionDefinition } from './KpiSectionDefinition';\nexport { FeatureCardsSectionDefinition } from './FeatureCardsSectionDefinition';\nexport { EntitySectionDefinition } from './EntitySectionDefinition';\nexport { EntityCollectionSectionDefinition } from './EntityCollectionSectionDefinition';\nexport { CtaBannerSectionDefinition } from './CtaBannerSectionDefinition';\nexport { CalloutSectionDefinition } from './CalloutSectionDefinition';\nexport { NextStepsSectionDefinition } from './NextStepsSectionDefinition';\nexport { FeatureSection9PlusDefinition } from './FeatureSection9PlusDefinition';\nexport { ListItemsSectionDefinition } from './listItemsSectionDefinition';\nexport { SkipNodesSectionDefinition } from './SkipNodesSectionDefinition';\nexport { HtmlCommentSectionDefinition } from './HtmlCommentSectionDefinition';\nexport { SearchSectionDefinition } from './SearchSectionDefinition';\nexport { ErrorSectionDefinition } from './ErrorSectionDefinition';\nexport { FallbackSectionDefinition } from './FallbackSectionDefinition';\n\nimport { ComponentRegistry } from '../../registry';\nimport { SkipNodesSectionDefinition } from './SkipNodesSectionDefinition';\nimport { SearchSectionDefinition } from './SearchSectionDefinition';\nimport { KpiSectionDefinition } from './KpiSectionDefinition';\nimport { NextStepsSectionDefinition } from './NextStepsSectionDefinition';\nimport { EntitySectionDefinition } from './EntitySectionDefinition';\nimport { EntityCollectionSectionDefinition } from './EntityCollectionSectionDefinition';\nimport { HeroEntitySectionDefinition } from './HeroEntitySectionDefinition';\nimport { HeroSectionDefinition } from './HeroSectionDefinition';\nimport { FeatureCardsSectionDefinition } from './FeatureCardsSectionDefinition';\nimport { FeatureSection9PlusDefinition } from './FeatureSection9PlusDefinition';\nimport { ListItemsSectionDefinition } from './listItemsSectionDefinition';\nimport { ComparisonSectionDefinition } from './ComparisonSectionDefinition';\nimport { HtmlCommentSectionDefinition } from './HtmlCommentSectionDefinition';\nimport { CtaBannerSectionDefinition } from './CtaBannerSectionDefinition';\nimport { CalloutSectionDefinition } from './CalloutSectionDefinition';\nimport { FallbackSectionDefinition } from './FallbackSectionDefinition';\nimport { ErrorSectionDefinition } from './ErrorSectionDefinition';\nimport { TextBlockSectionDefinition } from './TextBlockSectionDefinition';\n\n/**\n * Creates an SDK registry with all section definitions registered in the\n * same priority order as the app registry (createAppRegistry.ts).\n * Registration order determines evaluation priority — first match wins.\n */\nexport function createSdkRegistry(): ComponentRegistry<null> {\n return (\n new ComponentRegistry<null>(null)\n .register(new SkipNodesSectionDefinition())\n .register(new SearchSectionDefinition())\n .register(new KpiSectionDefinition())\n .register(new NextStepsSectionDefinition())\n // Collection entities are claimed by their own definition first — it is a\n // strictly narrower match than EntitySectionDefinition, which would\n // otherwise swallow collection, product and article blocks alike.\n .register(new EntityCollectionSectionDefinition())\n .register(new EntitySectionDefinition())\n .register(new HeroEntitySectionDefinition())\n .register(new HeroSectionDefinition())\n .register(new FeatureCardsSectionDefinition())\n .register(new ListItemsSectionDefinition())\n .register(new FeatureSection9PlusDefinition())\n .register(new ComparisonSectionDefinition())\n // Callout sits above HtmlComment: a callout block opens with its own\n // `<!-- section:callout -->` descriptor, and HtmlComment's bare\n // `html_comment` pattern would match that comment alone. A pattern may\n // match a PREFIX of a block, so HtmlComment would claim the descriptor\n // and strand the prose below it in the fallback, unstyled.\n .register(new CalloutSectionDefinition())\n .register(new HtmlCommentSectionDefinition())\n .register(new CtaBannerSectionDefinition())\n // textBlock comes after every definition whose block opens `h2 > t`\n // (entity, listItems, featureCards, ctaBanner, comparison, …). Its\n // `h2 > t+` also matches a bare `h2 > t`, and a pattern matches a PREFIX\n // of the block — registered above those it would claim the heading +\n // intro copy and strand the list / links / table that follow in a\n // separate section. It stops before a trailing callout, which Callout\n // (registered above) then claims on the parser's next iteration.\n .register(new TextBlockSectionDefinition())\n .register(new FallbackSectionDefinition())\n .register(new ErrorSectionDefinition())\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -38,6 +38,42 @@ export function bodyText(parts) {
38
38
  return [...textParts, ...richTextParts].map(markdownOrText).filter(Boolean).join('\n\n');
39
39
  }
40
40
 
41
+ /**
42
+ * Body copy as markdown, with inline links intact and paragraph breaks kept.
43
+ *
44
+ * `bodyText` reads text parts only, so a paragraph carrying an inline link —
45
+ * `Try narrowing to [men](web5://ask/…) instead` — arrives as `t + link + t`
46
+ * and comes back as `"Try narrowing to\n\ninstead"`: label and url both
47
+ * deleted, and the sentence broken in two at the gap. That is DL #134's list
48
+ * bug in a different helper, and it is why an ask link in prose never reached
49
+ * the page.
50
+ *
51
+ * `inlinePartsToMarkdown` already rebuilds a run of inline parts with links
52
+ * intact, but it flattens to one line, which is wrong for multi-paragraph
53
+ * copy. So group first: `astToParts` marks every part after the first of a
54
+ * given AST node with `meta.continuesNode`, which is exactly "same paragraph,
55
+ * keep going". Parts without it open a new paragraph.
56
+ *
57
+ * Kept separate from `bodyText` deliberately — the other seven callers hand
58
+ * their result to consumers that do not render markdown, and would show a
59
+ * visitor a raw `[label](url)`.
60
+ */
61
+ export function bodyMarkdown(parts) {
62
+ const paragraphs = [];
63
+ for (const part of parts) {
64
+ var _part$meta;
65
+ if (part.type !== 'text' && part.type !== 'richText' && part.type !== 'link') {
66
+ continue;
67
+ }
68
+ if ((_part$meta = part.meta) != null && _part$meta.continuesNode && paragraphs.length > 0) {
69
+ paragraphs[paragraphs.length - 1].push(part);
70
+ } else {
71
+ paragraphs.push([part]);
72
+ }
73
+ }
74
+ return paragraphs.map(inlinePartsToMarkdown).map(paragraph => paragraph.trim()).filter(Boolean).join('\n\n');
75
+ }
76
+
41
77
  /**
42
78
  * Entity sections may be authored as one paragraph per entity:
43
79
  * `[Product](web5://entity/...) - why it matches`.
@@ -237,14 +273,14 @@ function appendInlineToken(current, token) {
237
273
  */
238
274
  export function inlinePartsToMarkdown(parts) {
239
275
  return parts.reduce((text, part) => {
240
- var _part$meta;
276
+ var _part$meta2;
241
277
  if (part.type === 'link') {
242
278
  var _meta2, _part$content;
243
279
  const href = ((_meta2 = part.meta) == null ? void 0 : _meta2.href) ?? '';
244
280
  const label = ((_part$content = part.content) == null ? void 0 : _part$content.trim()) ?? '';
245
281
  return appendInlineToken(text, href ? `[${label}](${href})` : label);
246
282
  }
247
- return appendInlineToken(text, ((_part$meta = part.meta) == null ? void 0 : _part$meta.markdown) ?? part.content ?? '');
283
+ return appendInlineToken(text, ((_part$meta2 = part.meta) == null ? void 0 : _part$meta2.markdown) ?? part.content ?? '');
248
284
  }, '');
249
285
  }
250
286
  export function extractListItemText(item) {
@@ -268,14 +304,14 @@ export function extractListItemText(item) {
268
304
  */
269
305
  export function partsToMarkdown(sectionParts) {
270
306
  const inline = part => {
271
- var _part$meta2;
272
- return ((_part$meta2 = part.meta) == null ? void 0 : _part$meta2.markdown) ?? part.content;
307
+ var _part$meta3;
308
+ return ((_part$meta3 = part.meta) == null ? void 0 : _part$meta3.markdown) ?? part.content;
273
309
  };
274
310
  const lines = [];
275
311
  for (const part of sectionParts) {
276
312
  if (part.type === 'heading') {
277
- var _part$meta3;
278
- const level = ((_part$meta3 = part.meta) == null ? void 0 : _part$meta3.level) ?? 2;
313
+ var _part$meta4;
314
+ const level = ((_part$meta4 = part.meta) == null ? void 0 : _part$meta4.level) ?? 2;
279
315
  lines.push(`${'#'.repeat(level)} ${inline(part)}`);
280
316
  } else if (part.type === 'text' || part.type === 'richText') {
281
317
  lines.push(inline(part));