Files
wehub-resource-sync e7738de6d2
CI / Deep Native Runtime Cases (1/6) (push) Has been skipped
CI / Native Preflight (push) Failing after 1s
CI / Native Runtime Cases (1/2) (push) Failing after 0s
CI / Native Runtime Cases (2/2) (push) Failing after 1s
CI / Native Metadata Reports (push) Failing after 0s
CI / Native Direct Backend Artifacts (push) Failing after 0s
CI / Native Sanitizer Smoke (push) Failing after 1s
CI / Command Contract Snapshots (push) Failing after 1s
CI / Deep Conformance Suite (push) Has been skipped
CI / Graph Build Perf (push) Failing after 1s
CI / Deep Native Preflight (push) Has been skipped
CI / Deep Native Runtime Cases (2/6) (push) Has been skipped
CI / Deep Native Runtime Cases (3/6) (push) Has been skipped
CI / Conformance Suite (push) Failing after 1s
CI / Workspace Checks (push) Failing after 0s
CI / Deep Native Runtime Cases (5/6) (push) Has been skipped
CI / Deep Native Runtime Cases (6/6) (push) Has been skipped
CI / Deep Native Runtime Cases (4/6) (push) Has been skipped
CI / Deep Graph Build Perf (push) Has been skipped
chore: import upstream snapshot with attribution
2026-07-13 12:29:30 +08:00

63 lines
2.1 KiB
TypeScript

// Rewrites ```json-render fenced code blocks into custom elements carrying
// base64-encoded JSON, so the docs can embed structured React components
// without switching the pipeline to MDX. Runs before rehype-pretty-code so the
// block is never treated as a normal code fence.
type HastNode = {
type?: string;
tagName?: string;
value?: string;
properties?: Record<string, unknown>;
children?: HastNode[];
};
function getNodeText(node?: HastNode): string {
if (!node) return "";
if (node.type === "text") return node.value ?? "";
if (!Array.isArray(node.children)) return "";
return node.children.map(getNodeText).join("");
}
function getCodeLanguage(node: HastNode): string {
const className = node.properties?.className;
const classes = Array.isArray(className)
? className
: typeof className === "string"
? className.split(/\s+/)
: [];
const languageClass = classes.find(
(value) => typeof value === "string" && value.startsWith("language-"),
);
return typeof languageClass === "string" ? languageClass.slice("language-".length) : "";
}
function visit(node: HastNode | undefined, callback: (node: HastNode) => void): void {
if (!node) return;
callback(node);
if (Array.isArray(node.children)) {
for (const child of node.children) visit(child, callback);
}
}
export function rehypeJsonRender(): (tree: HastNode) => void {
return (tree: HastNode) => {
visit(tree, (node) => {
if (node.type !== "element" || node.tagName !== "pre") return;
const code = node.children?.find(
(child) => child.type === "element" && child.tagName === "code",
);
if (!code || getCodeLanguage(code) !== "json-render") return;
const raw = getNodeText(code).replace(/\n$/, "");
let tagName = "agentchat";
try {
const parsed = JSON.parse(raw) as { type?: string };
if (parsed.type === "flow") tagName = "flowchart";
} catch {}
node.tagName = tagName;
node.properties = { value: Buffer.from(raw, "utf8").toString("base64") };
node.children = [];
});
};
}