@immediately-run/sdk 0.33.0 → 0.35.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.
Files changed (149) hide show
  1. package/dist/MDXProvider.js +1 -0
  2. package/dist/MDXProvider.js.map +1 -1
  3. package/dist/TinkerableContext.js +1 -0
  4. package/dist/TinkerableContext.js.map +1 -1
  5. package/dist/auth.js +1 -0
  6. package/dist/auth.js.map +1 -1
  7. package/dist/boot.js +1 -0
  8. package/dist/boot.js.map +1 -1
  9. package/dist/catalog.js +1 -0
  10. package/dist/catalog.js.map +1 -1
  11. package/dist/chunk-VHAA22YE.js +14 -0
  12. package/dist/chunk-VHAA22YE.js.map +1 -0
  13. package/dist/components/Admonition.js +1 -0
  14. package/dist/components/Admonition.js.map +1 -1
  15. package/dist/components/FileRouter.js +1 -0
  16. package/dist/components/FileRouter.js.map +1 -1
  17. package/dist/components/HeadingAnchor.js +1 -0
  18. package/dist/components/HeadingAnchor.js.map +1 -1
  19. package/dist/components/Include.js +1 -0
  20. package/dist/components/Include.js.map +1 -1
  21. package/dist/components/Link.js +1 -0
  22. package/dist/components/Link.js.map +1 -1
  23. package/dist/components/MDXComponents.js +1 -0
  24. package/dist/components/MDXComponents.js.map +1 -1
  25. package/dist/components/MainContent.js +1 -0
  26. package/dist/components/MainContent.js.map +1 -1
  27. package/dist/components/MountImage.js +1 -0
  28. package/dist/components/MountImage.js.map +1 -1
  29. package/dist/components/Routes.js +1 -0
  30. package/dist/components/Routes.js.map +1 -1
  31. package/dist/components/ScrollAfterNavigation.js +1 -0
  32. package/dist/components/ScrollAfterNavigation.js.map +1 -1
  33. package/dist/components/WikiLink.js +1 -0
  34. package/dist/components/WikiLink.js.map +1 -1
  35. package/dist/components/defaults.js +1 -0
  36. package/dist/components/defaults.js.map +1 -1
  37. package/dist/components/errors.js +1 -0
  38. package/dist/components/errors.js.map +1 -1
  39. package/dist/contextUtils.js +1 -0
  40. package/dist/contextUtils.js.map +1 -1
  41. package/dist/contribute.js +1 -0
  42. package/dist/contribute.js.map +1 -1
  43. package/dist/debug.js +1 -0
  44. package/dist/debug.js.map +1 -1
  45. package/dist/diagnostics.js +1 -0
  46. package/dist/diagnostics.js.map +1 -1
  47. package/dist/dnd.js +1 -0
  48. package/dist/dnd.js.map +1 -1
  49. package/dist/editor.js +1 -0
  50. package/dist/editor.js.map +1 -1
  51. package/dist/editorContext.js +1 -0
  52. package/dist/editorContext.js.map +1 -1
  53. package/dist/formFactor.js +1 -0
  54. package/dist/formFactor.js.map +1 -1
  55. package/dist/fs.js +1 -0
  56. package/dist/fs.js.map +1 -1
  57. package/dist/hooks.js +1 -0
  58. package/dist/hooks.js.map +1 -1
  59. package/dist/hostRuntime.js +1 -0
  60. package/dist/hostRuntime.js.map +1 -1
  61. package/dist/index.cjs +2 -0
  62. package/dist/index.cjs.map +1 -1
  63. package/dist/index.d.cts +1 -0
  64. package/dist/index.d.ts +1 -0
  65. package/dist/index.js +1 -0
  66. package/dist/index.js.map +1 -1
  67. package/dist/injectedBundler.js +1 -0
  68. package/dist/injectedBundler.js.map +1 -1
  69. package/dist/ipc.js +1 -0
  70. package/dist/ipc.js.map +1 -1
  71. package/dist/irMarkers.js +1 -0
  72. package/dist/irMarkers.js.map +1 -1
  73. package/dist/launch.cjs +95 -0
  74. package/dist/launch.cjs.map +1 -0
  75. package/dist/launch.d.cts +76 -0
  76. package/dist/launch.d.ts +76 -0
  77. package/dist/launch.js +69 -0
  78. package/dist/launch.js.map +1 -0
  79. package/dist/llm.js +1 -0
  80. package/dist/llm.js.map +1 -1
  81. package/dist/loading.js +1 -0
  82. package/dist/loading.js.map +1 -1
  83. package/dist/markers.js +1 -0
  84. package/dist/markers.js.map +1 -1
  85. package/dist/moduleCache.js +1 -0
  86. package/dist/moduleCache.js.map +1 -1
  87. package/dist/mountMatch.js +1 -0
  88. package/dist/mountMatch.js.map +1 -1
  89. package/dist/mounts.js +1 -0
  90. package/dist/mounts.js.map +1 -1
  91. package/dist/netFetch.js +1 -0
  92. package/dist/netFetch.js.map +1 -1
  93. package/dist/onFsChange.js +1 -0
  94. package/dist/onFsChange.js.map +1 -1
  95. package/dist/pathUtils.js +1 -0
  96. package/dist/pathUtils.js.map +1 -1
  97. package/dist/protocolStream.js +1 -0
  98. package/dist/protocolStream.js.map +1 -1
  99. package/dist/pushChannel.js +1 -0
  100. package/dist/pushChannel.js.map +1 -1
  101. package/dist/ready.js +1 -0
  102. package/dist/ready.js.map +1 -1
  103. package/dist/region.js +1 -0
  104. package/dist/region.js.map +1 -1
  105. package/dist/routeMatch.js +1 -0
  106. package/dist/routeMatch.js.map +1 -1
  107. package/dist/routing.js +1 -0
  108. package/dist/routing.js.map +1 -1
  109. package/dist/runtime.js +1 -0
  110. package/dist/runtime.js.map +1 -1
  111. package/dist/safeContent/SafeContent.js +1 -0
  112. package/dist/safeContent/SafeContent.js.map +1 -1
  113. package/dist/safeContent/index.js +1 -0
  114. package/dist/safeContent/index.js.map +1 -1
  115. package/dist/safeContent/mdastDeps.cjs +186 -1
  116. package/dist/safeContent/mdastDeps.js +186 -1
  117. package/dist/safeContent/parseSafeMdast.cjs +26 -17
  118. package/dist/safeContent/parseSafeMdast.cjs.map +1 -1
  119. package/dist/safeContent/parseSafeMdast.js +27 -21
  120. package/dist/safeContent/parseSafeMdast.js.map +1 -1
  121. package/dist/safeContent/renderMdast.js +1 -0
  122. package/dist/safeContent/renderMdast.js.map +1 -1
  123. package/dist/safeContent/sanitizeUrl.js +1 -0
  124. package/dist/safeContent/sanitizeUrl.js.map +1 -1
  125. package/dist/safeContent/wikilink.js +1 -0
  126. package/dist/safeContent/wikilink.js.map +1 -1
  127. package/dist/sandboxUtils.js +1 -0
  128. package/dist/sandboxUtils.js.map +1 -1
  129. package/dist/scrollToId.js +1 -0
  130. package/dist/scrollToId.js.map +1 -1
  131. package/dist/secrets.js +1 -0
  132. package/dist/secrets.js.map +1 -1
  133. package/dist/tasks.js +1 -0
  134. package/dist/tasks.js.map +1 -1
  135. package/dist/testing.js +1 -0
  136. package/dist/testing.js.map +1 -1
  137. package/dist/theme.js +1 -0
  138. package/dist/theme.js.map +1 -1
  139. package/dist/urlUtils.js +1 -0
  140. package/dist/urlUtils.js.map +1 -1
  141. package/dist/vcs.js +1 -0
  142. package/dist/vcs.js.map +1 -1
  143. package/dist/version.cjs +1 -1
  144. package/dist/version.cjs.map +1 -1
  145. package/dist/version.d.cts +1 -1
  146. package/dist/version.d.ts +1 -1
  147. package/dist/version.js +2 -1
  148. package/dist/version.js.map +1 -1
  149. package/package.json +2 -2
@@ -24,7 +24,10 @@ __export(mdastDeps_exports, {
24
24
  gfm: () => gfm,
25
25
  gfmFromMarkdown: () => gfmFromMarkdown,
26
26
  mdxJsx: () => mdxJsx,
27
- mdxJsxFromMarkdown: () => mdxJsxFromMarkdown
27
+ mdxJsxFromMarkdown: () => mdxJsxFromMarkdown,
28
+ remarkAdmonitions: () => remarkAdmonitions_default,
29
+ remarkHeadingAnchors: () => remarkHeadingAnchors_default,
30
+ remarkWikiLinks: () => remarkWikiLinks_default
28
31
  });
29
32
  module.exports = __toCommonJS(mdastDeps_exports);
30
33
 
@@ -10695,3 +10698,185 @@ function gfmFromMarkdown() {
10695
10698
  gfmTaskListItemFromMarkdown()
10696
10699
  ];
10697
10700
  }
10701
+
10702
+ // node_modules/@immediately-run/mdx-plugins/dist/index.js
10703
+ function textSlug(text4) {
10704
+ return text4.trim().toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
10705
+ }
10706
+ var LEADING_TOKEN = /^([A-Za-z0-9]+(?:\.[A-Za-z0-9]+)*)/;
10707
+ function sectionId(text4) {
10708
+ const m = text4.trim().match(LEADING_TOKEN);
10709
+ if (!m) return null;
10710
+ const token = m[1];
10711
+ const firstComponent = token.split(".")[0];
10712
+ const sectionLike = /\d/.test(firstComponent) || /^[A-Za-z]\./.test(token);
10713
+ if (!sectionLike) return null;
10714
+ return "sec-" + token.toLowerCase().replace(/\./g, "-");
10715
+ }
10716
+ function headingText(node2) {
10717
+ let out = "";
10718
+ const visit2 = (n) => {
10719
+ if (n.type === "text" || n.type === "inlineCode") {
10720
+ out += n.value ?? "";
10721
+ return;
10722
+ }
10723
+ if (n.type === "mdxJsxTextElement" || n.type === "mdxTextExpression") return;
10724
+ if (Array.isArray(n.children)) n.children.forEach(visit2);
10725
+ };
10726
+ if (Array.isArray(node2.children)) node2.children.forEach(visit2);
10727
+ return out;
10728
+ }
10729
+ function hasAuthorId(node2) {
10730
+ const id = node2.data?.hProperties?.id;
10731
+ return typeof id === "string" && id.length > 0;
10732
+ }
10733
+ function anchorNode(id) {
10734
+ return {
10735
+ type: "mdxJsxTextElement",
10736
+ name: "HeadingAnchor",
10737
+ attributes: [{ type: "mdxJsxAttribute", name: "id", value: id }],
10738
+ children: []
10739
+ };
10740
+ }
10741
+ var remarkHeadingAnchors = (options = {}) => (tree) => {
10742
+ const sectionEnabled = options.sectionIds !== false;
10743
+ const seen = /* @__PURE__ */ new Map();
10744
+ const root = tree;
10745
+ const children = root.children;
10746
+ if (!Array.isArray(children)) return;
10747
+ for (const node2 of children) {
10748
+ if (node2.type !== "heading") continue;
10749
+ if (hasAuthorId(node2)) continue;
10750
+ const text4 = headingText(node2);
10751
+ const slug = textSlug(text4);
10752
+ const sec = sectionEnabled ? sectionId(text4) : null;
10753
+ let baseId = sec ?? slug ?? "";
10754
+ if (baseId === "") baseId = "section";
10755
+ const n = seen.get(baseId) ?? 0;
10756
+ seen.set(baseId, n + 1);
10757
+ const id = n === 0 ? baseId : `${baseId}-${n}`;
10758
+ const hProperties = (node2.data ?? (node2.data = {})).hProperties ?? (node2.data.hProperties = {});
10759
+ hProperties.id = id;
10760
+ if (sec && slug && slug !== id) hProperties["data-slug"] = slug;
10761
+ node2.children = [anchorNode(id), ...node2.children ?? []];
10762
+ }
10763
+ };
10764
+ var remarkHeadingAnchors_default = remarkHeadingAnchors;
10765
+ var WIKILINK = /\[\[([^[\]]+)\]\]/g;
10766
+ function toWikiLink(inner) {
10767
+ const pipe = inner.indexOf("|");
10768
+ let target;
10769
+ let label;
10770
+ if (pipe === -1) {
10771
+ target = inner.trim();
10772
+ } else {
10773
+ label = inner.slice(0, pipe).trim();
10774
+ target = inner.slice(pipe + 1).trim();
10775
+ }
10776
+ if (target === "") return null;
10777
+ const attributes = [
10778
+ { type: "mdxJsxAttribute", name: "target", value: target }
10779
+ ];
10780
+ if (label) {
10781
+ attributes.push({ type: "mdxJsxAttribute", name: "label", value: label });
10782
+ }
10783
+ return {
10784
+ type: "mdxJsxTextElement",
10785
+ // inline (phrasing) — a wiki-link sits in a paragraph
10786
+ name: "WikiLink",
10787
+ attributes,
10788
+ children: []
10789
+ };
10790
+ }
10791
+ function splitTextNode(node2) {
10792
+ const value = node2.value;
10793
+ if (typeof value !== "string" || value.indexOf("[[") === -1) return null;
10794
+ const out = [];
10795
+ let lastIndex = 0;
10796
+ let produced = false;
10797
+ WIKILINK.lastIndex = 0;
10798
+ let match;
10799
+ while ((match = WIKILINK.exec(value)) !== null) {
10800
+ const wl = toWikiLink(match[1]);
10801
+ if (!wl) continue;
10802
+ if (match.index > lastIndex) {
10803
+ out.push({ type: "text", value: value.slice(lastIndex, match.index) });
10804
+ }
10805
+ out.push(wl);
10806
+ lastIndex = match.index + match[0].length;
10807
+ produced = true;
10808
+ }
10809
+ if (!produced) return null;
10810
+ if (lastIndex < value.length) {
10811
+ out.push({ type: "text", value: value.slice(lastIndex) });
10812
+ }
10813
+ return out;
10814
+ }
10815
+ function walk(node2) {
10816
+ const children = node2.children;
10817
+ if (!Array.isArray(children)) return;
10818
+ for (let i = 0; i < children.length; i++) {
10819
+ const child = children[i];
10820
+ if (child.type === "text") {
10821
+ const replacement = splitTextNode(child);
10822
+ if (replacement) {
10823
+ children.splice(i, 1, ...replacement);
10824
+ i += replacement.length - 1;
10825
+ }
10826
+ continue;
10827
+ }
10828
+ walk(child);
10829
+ }
10830
+ }
10831
+ var remarkWikiLinks = () => (tree) => {
10832
+ walk(tree);
10833
+ };
10834
+ var remarkWikiLinks_default = remarkWikiLinks;
10835
+ var MARKER = /^\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\][ \t]*(\r?\n|$)/i;
10836
+ function toAdmonition(blockquote) {
10837
+ const firstBlock = blockquote.children?.[0];
10838
+ if (!firstBlock || firstBlock.type !== "paragraph") return null;
10839
+ const inlines = firstBlock.children;
10840
+ const firstInline = inlines?.[0];
10841
+ if (!firstInline || firstInline.type !== "text" || typeof firstInline.value !== "string") {
10842
+ return null;
10843
+ }
10844
+ const match = MARKER.exec(firstInline.value);
10845
+ if (!match) return null;
10846
+ const consumedNewline = match[2] !== "";
10847
+ if (!consumedNewline && (inlines?.length ?? 0) > 1) return null;
10848
+ const type = match[1].toLowerCase();
10849
+ const rest = firstInline.value.slice(match[0].length);
10850
+ if (rest.length === 0) {
10851
+ inlines.shift();
10852
+ if (inlines.length === 0) blockquote.children.shift();
10853
+ } else {
10854
+ firstInline.value = rest;
10855
+ }
10856
+ return {
10857
+ type: "mdxJsxFlowElement",
10858
+ name: "Admonition",
10859
+ attributes: [{ type: "mdxJsxAttribute", name: "type", value: type }],
10860
+ children: blockquote.children ?? []
10861
+ };
10862
+ }
10863
+ function walk2(node2) {
10864
+ const children = node2.children;
10865
+ if (!Array.isArray(children)) return;
10866
+ for (let i = 0; i < children.length; i++) {
10867
+ const child = children[i];
10868
+ if (child.type === "blockquote") {
10869
+ const converted = toAdmonition(child);
10870
+ if (converted) {
10871
+ children[i] = converted;
10872
+ walk2(converted);
10873
+ continue;
10874
+ }
10875
+ }
10876
+ walk2(child);
10877
+ }
10878
+ }
10879
+ var remarkAdmonitions = () => (tree) => {
10880
+ walk2(tree);
10881
+ };
10882
+ var remarkAdmonitions_default = remarkAdmonitions;
@@ -10671,10 +10671,195 @@ function gfmFromMarkdown() {
10671
10671
  gfmTaskListItemFromMarkdown()
10672
10672
  ];
10673
10673
  }
10674
+
10675
+ // node_modules/@immediately-run/mdx-plugins/dist/index.js
10676
+ function textSlug(text4) {
10677
+ return text4.trim().toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
10678
+ }
10679
+ var LEADING_TOKEN = /^([A-Za-z0-9]+(?:\.[A-Za-z0-9]+)*)/;
10680
+ function sectionId(text4) {
10681
+ const m = text4.trim().match(LEADING_TOKEN);
10682
+ if (!m) return null;
10683
+ const token = m[1];
10684
+ const firstComponent = token.split(".")[0];
10685
+ const sectionLike = /\d/.test(firstComponent) || /^[A-Za-z]\./.test(token);
10686
+ if (!sectionLike) return null;
10687
+ return "sec-" + token.toLowerCase().replace(/\./g, "-");
10688
+ }
10689
+ function headingText(node2) {
10690
+ let out = "";
10691
+ const visit2 = (n) => {
10692
+ if (n.type === "text" || n.type === "inlineCode") {
10693
+ out += n.value ?? "";
10694
+ return;
10695
+ }
10696
+ if (n.type === "mdxJsxTextElement" || n.type === "mdxTextExpression") return;
10697
+ if (Array.isArray(n.children)) n.children.forEach(visit2);
10698
+ };
10699
+ if (Array.isArray(node2.children)) node2.children.forEach(visit2);
10700
+ return out;
10701
+ }
10702
+ function hasAuthorId(node2) {
10703
+ const id = node2.data?.hProperties?.id;
10704
+ return typeof id === "string" && id.length > 0;
10705
+ }
10706
+ function anchorNode(id) {
10707
+ return {
10708
+ type: "mdxJsxTextElement",
10709
+ name: "HeadingAnchor",
10710
+ attributes: [{ type: "mdxJsxAttribute", name: "id", value: id }],
10711
+ children: []
10712
+ };
10713
+ }
10714
+ var remarkHeadingAnchors = (options = {}) => (tree) => {
10715
+ const sectionEnabled = options.sectionIds !== false;
10716
+ const seen = /* @__PURE__ */ new Map();
10717
+ const root = tree;
10718
+ const children = root.children;
10719
+ if (!Array.isArray(children)) return;
10720
+ for (const node2 of children) {
10721
+ if (node2.type !== "heading") continue;
10722
+ if (hasAuthorId(node2)) continue;
10723
+ const text4 = headingText(node2);
10724
+ const slug = textSlug(text4);
10725
+ const sec = sectionEnabled ? sectionId(text4) : null;
10726
+ let baseId = sec ?? slug ?? "";
10727
+ if (baseId === "") baseId = "section";
10728
+ const n = seen.get(baseId) ?? 0;
10729
+ seen.set(baseId, n + 1);
10730
+ const id = n === 0 ? baseId : `${baseId}-${n}`;
10731
+ const hProperties = (node2.data ?? (node2.data = {})).hProperties ?? (node2.data.hProperties = {});
10732
+ hProperties.id = id;
10733
+ if (sec && slug && slug !== id) hProperties["data-slug"] = slug;
10734
+ node2.children = [anchorNode(id), ...node2.children ?? []];
10735
+ }
10736
+ };
10737
+ var remarkHeadingAnchors_default = remarkHeadingAnchors;
10738
+ var WIKILINK = /\[\[([^[\]]+)\]\]/g;
10739
+ function toWikiLink(inner) {
10740
+ const pipe = inner.indexOf("|");
10741
+ let target;
10742
+ let label;
10743
+ if (pipe === -1) {
10744
+ target = inner.trim();
10745
+ } else {
10746
+ label = inner.slice(0, pipe).trim();
10747
+ target = inner.slice(pipe + 1).trim();
10748
+ }
10749
+ if (target === "") return null;
10750
+ const attributes = [
10751
+ { type: "mdxJsxAttribute", name: "target", value: target }
10752
+ ];
10753
+ if (label) {
10754
+ attributes.push({ type: "mdxJsxAttribute", name: "label", value: label });
10755
+ }
10756
+ return {
10757
+ type: "mdxJsxTextElement",
10758
+ // inline (phrasing) — a wiki-link sits in a paragraph
10759
+ name: "WikiLink",
10760
+ attributes,
10761
+ children: []
10762
+ };
10763
+ }
10764
+ function splitTextNode(node2) {
10765
+ const value = node2.value;
10766
+ if (typeof value !== "string" || value.indexOf("[[") === -1) return null;
10767
+ const out = [];
10768
+ let lastIndex = 0;
10769
+ let produced = false;
10770
+ WIKILINK.lastIndex = 0;
10771
+ let match;
10772
+ while ((match = WIKILINK.exec(value)) !== null) {
10773
+ const wl = toWikiLink(match[1]);
10774
+ if (!wl) continue;
10775
+ if (match.index > lastIndex) {
10776
+ out.push({ type: "text", value: value.slice(lastIndex, match.index) });
10777
+ }
10778
+ out.push(wl);
10779
+ lastIndex = match.index + match[0].length;
10780
+ produced = true;
10781
+ }
10782
+ if (!produced) return null;
10783
+ if (lastIndex < value.length) {
10784
+ out.push({ type: "text", value: value.slice(lastIndex) });
10785
+ }
10786
+ return out;
10787
+ }
10788
+ function walk(node2) {
10789
+ const children = node2.children;
10790
+ if (!Array.isArray(children)) return;
10791
+ for (let i = 0; i < children.length; i++) {
10792
+ const child = children[i];
10793
+ if (child.type === "text") {
10794
+ const replacement = splitTextNode(child);
10795
+ if (replacement) {
10796
+ children.splice(i, 1, ...replacement);
10797
+ i += replacement.length - 1;
10798
+ }
10799
+ continue;
10800
+ }
10801
+ walk(child);
10802
+ }
10803
+ }
10804
+ var remarkWikiLinks = () => (tree) => {
10805
+ walk(tree);
10806
+ };
10807
+ var remarkWikiLinks_default = remarkWikiLinks;
10808
+ var MARKER = /^\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\][ \t]*(\r?\n|$)/i;
10809
+ function toAdmonition(blockquote) {
10810
+ const firstBlock = blockquote.children?.[0];
10811
+ if (!firstBlock || firstBlock.type !== "paragraph") return null;
10812
+ const inlines = firstBlock.children;
10813
+ const firstInline = inlines?.[0];
10814
+ if (!firstInline || firstInline.type !== "text" || typeof firstInline.value !== "string") {
10815
+ return null;
10816
+ }
10817
+ const match = MARKER.exec(firstInline.value);
10818
+ if (!match) return null;
10819
+ const consumedNewline = match[2] !== "";
10820
+ if (!consumedNewline && (inlines?.length ?? 0) > 1) return null;
10821
+ const type = match[1].toLowerCase();
10822
+ const rest = firstInline.value.slice(match[0].length);
10823
+ if (rest.length === 0) {
10824
+ inlines.shift();
10825
+ if (inlines.length === 0) blockquote.children.shift();
10826
+ } else {
10827
+ firstInline.value = rest;
10828
+ }
10829
+ return {
10830
+ type: "mdxJsxFlowElement",
10831
+ name: "Admonition",
10832
+ attributes: [{ type: "mdxJsxAttribute", name: "type", value: type }],
10833
+ children: blockquote.children ?? []
10834
+ };
10835
+ }
10836
+ function walk2(node2) {
10837
+ const children = node2.children;
10838
+ if (!Array.isArray(children)) return;
10839
+ for (let i = 0; i < children.length; i++) {
10840
+ const child = children[i];
10841
+ if (child.type === "blockquote") {
10842
+ const converted = toAdmonition(child);
10843
+ if (converted) {
10844
+ children[i] = converted;
10845
+ walk2(converted);
10846
+ continue;
10847
+ }
10848
+ }
10849
+ walk2(child);
10850
+ }
10851
+ }
10852
+ var remarkAdmonitions = () => (tree) => {
10853
+ walk2(tree);
10854
+ };
10855
+ var remarkAdmonitions_default = remarkAdmonitions;
10674
10856
  export {
10675
10857
  fromMarkdown,
10676
10858
  gfm,
10677
10859
  gfmFromMarkdown,
10678
10860
  mdxJsx,
10679
- mdxJsxFromMarkdown
10861
+ mdxJsxFromMarkdown,
10862
+ remarkAdmonitions_default as remarkAdmonitions,
10863
+ remarkHeadingAnchors_default as remarkHeadingAnchors,
10864
+ remarkWikiLinks_default as remarkWikiLinks
10680
10865
  };
@@ -31,27 +31,36 @@ __export(parseSafeMdast_exports, {
31
31
  parseSafeMdast: () => parseSafeMdast
32
32
  });
33
33
  module.exports = __toCommonJS(parseSafeMdast_exports);
34
- var import_mdx_plugins = require("@immediately-run/mdx-plugins");
35
34
  let depsPromise = null;
36
35
  function loadDeps() {
37
36
  if (!depsPromise) {
38
- depsPromise = import("./mdastDeps").then(
39
- (m) => ({
40
- fromMarkdown: m.fromMarkdown,
41
- mdxJsx: m.mdxJsx,
42
- mdxJsxFromMarkdown: m.mdxJsxFromMarkdown,
43
- gfm: m.gfm,
44
- gfmFromMarkdown: m.gfmFromMarkdown
45
- })
46
- );
37
+ depsPromise = import("./mdastDeps").then((m) => {
38
+ const d = m;
39
+ return {
40
+ fromMarkdown: d.fromMarkdown,
41
+ mdxJsx: d.mdxJsx,
42
+ mdxJsxFromMarkdown: d.mdxJsxFromMarkdown,
43
+ gfm: d.gfm,
44
+ gfmFromMarkdown: d.gfmFromMarkdown,
45
+ remarkAdmonitions: d.remarkAdmonitions,
46
+ remarkWikiLinks: d.remarkWikiLinks,
47
+ remarkHeadingAnchors: d.remarkHeadingAnchors
48
+ };
49
+ });
47
50
  }
48
51
  return depsPromise;
49
52
  }
50
- const admonitions = import_mdx_plugins.remarkAdmonitions;
51
- const wikiLinks = import_mdx_plugins.remarkWikiLinks;
52
- const headingAnchors = import_mdx_plugins.remarkHeadingAnchors;
53
53
  async function parseSafeMdast(source, options = {}) {
54
- const { fromMarkdown, mdxJsx, mdxJsxFromMarkdown, gfm, gfmFromMarkdown } = await loadDeps();
54
+ const {
55
+ fromMarkdown,
56
+ mdxJsx,
57
+ mdxJsxFromMarkdown,
58
+ gfm,
59
+ gfmFromMarkdown,
60
+ remarkAdmonitions,
61
+ remarkWikiLinks,
62
+ remarkHeadingAnchors
63
+ } = await loadDeps();
55
64
  const tree = fromMarkdown(source, {
56
65
  // `mdxJsx()` WITHOUT an acorn option → JSX tags + literal attrs; expressions are
57
66
  // raw strings, never estree. The mdx *expression* extension is intentionally
@@ -59,9 +68,9 @@ async function parseSafeMdast(source, options = {}) {
59
68
  extensions: [mdxJsx(), gfm()],
60
69
  mdastExtensions: [mdxJsxFromMarkdown(), gfmFromMarkdown()]
61
70
  });
62
- admonitions()(tree);
63
- wikiLinks()(tree);
64
- headingAnchors({ sectionIds: options.sectionIds !== false })(tree);
71
+ remarkAdmonitions()(tree);
72
+ remarkWikiLinks()(tree);
73
+ remarkHeadingAnchors({ sectionIds: options.sectionIds !== false })(tree);
65
74
  return tree;
66
75
  }
67
76
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/safeContent/parseSafeMdast.ts"],"sourcesContent":["// The no-acorn parse pipeline for the safe content renderer (TRUST_MODES_SPEC §5.1,\n// empirically verified 2026-07-07 against `@mdx-js/mdx` v3 / `micromark-extension-\n// mdx-jsx`). This is the load-bearing half of the fail-safe: `<Component/>` syntax\n// parses to an element node with **literal** attributes, and every expression\n// (`n={1+1}`, `f={fetch(\"/x\")}`, `{...spread}`) is captured as an **inert raw string\n// with no estree** — because we pass **NO acorn option** to `micromark-extension-mdx-\n// jsx`. There is therefore no evaluator anywhere in the pipeline (fail-safe), unlike\n// `@mdx-js/mdx`'s `compile({format:'mdx'})` which always wires acorn.\n//\n// The §5.1 residual guarantees are also here: the expression micromark extension is\n// **not** enabled (body `{…}` stays literal text), and **no `rehype-raw`** / raw-HTML\n// passthrough exists — raw HTML blocks arrive as inert `html` mdast nodes the renderer\n// prints as text, never injected.\n//\n// `micromark`/`mdast` are ESM-only. They are loaded with a memoised dynamic `import()`\n// (the transpiler's `compile.ts` pattern) so this module sits in the package's CJS\n// build too — a CJS consumer that never renders untrusted content never `require()`s\n// an ESM-only package, and one that does gets it via Node's ESM-from-CJS import. The\n// dynamic load changes only *when* the deps resolve, never the produced tree.\n//\n// The dynamic import targets `./mdastDeps` — a SINGLE self-contained artifact that a\n// dedicated build pass (`scripts/build-safecontent-deps.mjs`) inlines the whole ESM tree\n// into (see `mdastDeps.ts` for the WHY). This keeps the `import()` boundary (a consumer\n// that never renders safe content never loads the ~300KB parser) while making the imported\n// target one already-bundled file the immediately.run sandbox resolver can fetch without\n// walking the unified/micromark conditional-exports tree — the R3-213 on-host packaging\n// gap. In jest/ts-jest and the e2e bundle the same `./mdastDeps` resolves to the source\n// re-export module, which pulls the real deps from node_modules; the produced tree is\n// identical either way.\n\nimport {\n remarkAdmonitions,\n remarkWikiLinks,\n remarkHeadingAnchors,\n type HeadingAnchorOptions,\n} from '@immediately-run/mdx-plugins';\n\n// A minimal structural mdast shape — we deliberately avoid a type dependency on the\n// ESM-only `mdast`/`unist` packages (which would break the CJS build's type surface).\nexport interface SafeMdastNode {\n type: string;\n value?: string;\n name?: string | null;\n url?: string;\n alt?: string | null;\n title?: string | null;\n depth?: number;\n ordered?: boolean;\n lang?: string | null;\n children?: SafeMdastNode[];\n attributes?: SafeMdxAttribute[];\n [key: string]: unknown;\n}\n\nexport interface SafeMdxAttribute {\n type: 'mdxJsxAttribute' | 'mdxJsxExpressionAttribute';\n name?: string;\n // A literal attribute carries a string; an expression attribute carries an\n // `mdxJsxAttributeValueExpression` object (a raw string, NO estree) or a string.\n value?: string | { type: string; value?: string } | null;\n}\n\ntype Deps = {\n fromMarkdown: (\n value: string,\n options: { extensions: unknown[]; mdastExtensions: unknown[] },\n ) => SafeMdastNode;\n mdxJsx: () => unknown;\n mdxJsxFromMarkdown: () => unknown;\n gfm: () => unknown;\n gfmFromMarkdown: () => unknown;\n};\n\nlet depsPromise: Promise<Deps> | null = null;\n\nfunction loadDeps(): Promise<Deps> {\n if (!depsPromise) {\n // ONE dynamic import of the pre-inlined artifact (see the header note + `mdastDeps.ts`)\n // instead of five bare ESM specifiers the sandbox resolver can't walk on-host.\n depsPromise = import('./mdastDeps').then(\n (m) =>\n ({\n fromMarkdown: (m as unknown as { fromMarkdown: Deps['fromMarkdown'] }).fromMarkdown,\n mdxJsx: (m as unknown as { mdxJsx: Deps['mdxJsx'] }).mdxJsx,\n mdxJsxFromMarkdown: (m as unknown as { mdxJsxFromMarkdown: Deps['mdxJsxFromMarkdown'] })\n .mdxJsxFromMarkdown,\n gfm: (m as unknown as { gfm: Deps['gfm'] }).gfm,\n gfmFromMarkdown: (m as unknown as { gfmFromMarkdown: Deps['gfmFromMarkdown'] }).gfmFromMarkdown,\n }) as Deps,\n );\n }\n return depsPromise;\n}\n\nexport interface ParseSafeMdastOptions {\n /** `false` ⇒ headings use plain text-slug ids (the R3-186 base; no `sec-…` section\n * ids, no `data-slug`) — the `sectionIds:false` frontmatter opt-out, matching the\n * compiled path. Default (undefined/true) ⇒ section-like headings get `sec-…` ids\n * (R3-211). */\n sectionIds?: boolean;\n}\n\n// The three kernel remark plugins for the MDX *safe subset* — the SAME source the\n// compiled path (transpiler `compileMdx`) runs, imported from the shared package so the\n// two render standards can't drift (TRUST_MODES_SPEC §5 / §5.1, R3-213). They are pure\n// mdast transforms: `(options?) => (tree) => void`. `unified`'s `Plugin` type widens the\n// return to `Transformer | void`; here we invoke the transformer directly on the tree,\n// so narrow it to a plain in-place mutator.\ntype MdastMutator = (tree: SafeMdastNode) => void;\nconst admonitions = remarkAdmonitions as unknown as () => MdastMutator;\nconst wikiLinks = remarkWikiLinks as unknown as () => MdastMutator;\nconst headingAnchors = remarkHeadingAnchors as unknown as (o?: HeadingAnchorOptions) => MdastMutator;\n\n/**\n * Parse untrusted Markdown/MDX-syntax source to an mdast tree with **no evaluator in\n * the pipeline**: JSX-as-data (no acorn), GFM on, the expression extension OFF, no\n * raw-HTML re-parse. The returned tree is safe to hand to `renderMdast` — expression\n * attributes are inert strings and raw HTML is inert `html` nodes.\n *\n * After the no-acorn parse it runs the SHARED kernel remark plugins — in the SAME order\n * as the compiled path's `compile.ts` (admonitions §12 → wiki-links §13 → heading/section\n * anchors §15/R3-211; GFM is already applied via the micromark extension above) — so the\n * safe subset renders identically in both standards. The plugins only emit element nodes\n * with LITERAL attributes and set `data.hProperties.id` on headings; they add no evaluator\n * and no acorn, preserving the §5.1 fail-safe.\n */\nexport async function parseSafeMdast(\n source: string,\n options: ParseSafeMdastOptions = {},\n): Promise<SafeMdastNode> {\n const { fromMarkdown, mdxJsx, mdxJsxFromMarkdown, gfm, gfmFromMarkdown } = await loadDeps();\n const tree = fromMarkdown(source, {\n // `mdxJsx()` WITHOUT an acorn option → JSX tags + literal attrs; expressions are\n // raw strings, never estree. The mdx *expression* extension is intentionally\n // absent, so `{…}` in body text stays literal. GFM for tables/task-lists.\n extensions: [mdxJsx(), gfm()],\n mdastExtensions: [mdxJsxFromMarkdown(), gfmFromMarkdown()],\n });\n admonitions()(tree);\n wikiLinks()(tree);\n headingAnchors({ sectionIds: options.sectionIds !== false })(tree);\n return tree;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA8BA,yBAKO;AAsCP,IAAI,cAAoC;AAExC,SAAS,WAA0B;AACjC,MAAI,CAAC,aAAa;AAGhB,kBAAc,OAAO,aAAa,EAAE;AAAA,MAClC,CAAC,OACE;AAAA,QACC,cAAe,EAAwD;AAAA,QACvE,QAAS,EAA4C;AAAA,QACrD,oBAAqB,EAClB;AAAA,QACH,KAAM,EAAsC;AAAA,QAC5C,iBAAkB,EAA8D;AAAA,MAClF;AAAA,IACJ;AAAA,EACF;AACA,SAAO;AACT;AAiBA,MAAM,cAAc;AACpB,MAAM,YAAY;AAClB,MAAM,iBAAiB;AAevB,eAAsB,eACpB,QACA,UAAiC,CAAC,GACV;AACxB,QAAM,EAAE,cAAc,QAAQ,oBAAoB,KAAK,gBAAgB,IAAI,MAAM,SAAS;AAC1F,QAAM,OAAO,aAAa,QAAQ;AAAA;AAAA;AAAA;AAAA,IAIhC,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC;AAAA,IAC5B,iBAAiB,CAAC,mBAAmB,GAAG,gBAAgB,CAAC;AAAA,EAC3D,CAAC;AACD,cAAY,EAAE,IAAI;AAClB,YAAU,EAAE,IAAI;AAChB,iBAAe,EAAE,YAAY,QAAQ,eAAe,MAAM,CAAC,EAAE,IAAI;AACjE,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../src/safeContent/parseSafeMdast.ts"],"sourcesContent":["// The no-acorn parse pipeline for the safe content renderer (TRUST_MODES_SPEC §5.1,\n// empirically verified 2026-07-07 against `@mdx-js/mdx` v3 / `micromark-extension-\n// mdx-jsx`). This is the load-bearing half of the fail-safe: `<Component/>` syntax\n// parses to an element node with **literal** attributes, and every expression\n// (`n={1+1}`, `f={fetch(\"/x\")}`, `{...spread}`) is captured as an **inert raw string\n// with no estree** — because we pass **NO acorn option** to `micromark-extension-mdx-\n// jsx`. There is therefore no evaluator anywhere in the pipeline (fail-safe), unlike\n// `@mdx-js/mdx`'s `compile({format:'mdx'})` which always wires acorn.\n//\n// The §5.1 residual guarantees are also here: the expression micromark extension is\n// **not** enabled (body `{…}` stays literal text), and **no `rehype-raw`** / raw-HTML\n// passthrough exists — raw HTML blocks arrive as inert `html` mdast nodes the renderer\n// prints as text, never injected.\n//\n// `micromark`/`mdast` are ESM-only. They are loaded with a memoised dynamic `import()`\n// (the transpiler's `compile.ts` pattern) so this module sits in the package's CJS\n// build too — a CJS consumer that never renders untrusted content never `require()`s\n// an ESM-only package, and one that does gets it via Node's ESM-from-CJS import. The\n// dynamic load changes only *when* the deps resolve, never the produced tree.\n//\n// The dynamic import targets `./mdastDeps` — a SINGLE self-contained artifact that a\n// dedicated build pass (`scripts/build-safecontent-deps.mjs`) inlines the whole ESM tree\n// into (see `mdastDeps.ts` for the WHY). This keeps the `import()` boundary (a consumer\n// that never renders safe content never loads the ~300KB parser) while making the imported\n// target one already-bundled file the immediately.run sandbox resolver can fetch without\n// walking the unified/micromark conditional-exports tree — the R3-213 on-host packaging\n// gap. In jest/ts-jest and the e2e bundle the same `./mdastDeps` resolves to the source\n// re-export module, which pulls the real deps from node_modules; the produced tree is\n// identical either way.\n\n// Type-only — the plugin VALUES are re-exported from (and inlined by) `./mdastDeps`; a\n// value import here would put a bare `@immediately-run/mdx-plugins` specifier in the dist\n// the sandbox resolver can't resolve on-host. `import type` is fully erased at build.\nimport type { HeadingAnchorOptions } from '@immediately-run/mdx-plugins';\n\n// A minimal structural mdast shape — we deliberately avoid a type dependency on the\n// ESM-only `mdast`/`unist` packages (which would break the CJS build's type surface).\nexport interface SafeMdastNode {\n type: string;\n value?: string;\n name?: string | null;\n url?: string;\n alt?: string | null;\n title?: string | null;\n depth?: number;\n ordered?: boolean;\n lang?: string | null;\n children?: SafeMdastNode[];\n attributes?: SafeMdxAttribute[];\n [key: string]: unknown;\n}\n\nexport interface SafeMdxAttribute {\n type: 'mdxJsxAttribute' | 'mdxJsxExpressionAttribute';\n name?: string;\n // A literal attribute carries a string; an expression attribute carries an\n // `mdxJsxAttributeValueExpression` object (a raw string, NO estree) or a string.\n value?: string | { type: string; value?: string } | null;\n}\n\n// `unified`'s `Plugin` type widens the return to `Transformer | void`; the safe path\n// invokes each transformer directly on the tree, so narrow it to a plain in-place mutator.\ntype MdastMutator = (tree: SafeMdastNode) => void;\n\ntype Deps = {\n fromMarkdown: (\n value: string,\n options: { extensions: unknown[]; mdastExtensions: unknown[] },\n ) => SafeMdastNode;\n mdxJsx: () => unknown;\n mdxJsxFromMarkdown: () => unknown;\n gfm: () => unknown;\n gfmFromMarkdown: () => unknown;\n // The three shared kernel remark plugins, also inlined into `./mdastDeps` (see there).\n remarkAdmonitions: () => MdastMutator;\n remarkWikiLinks: () => MdastMutator;\n remarkHeadingAnchors: (o?: HeadingAnchorOptions) => MdastMutator;\n};\n\nlet depsPromise: Promise<Deps> | null = null;\n\nfunction loadDeps(): Promise<Deps> {\n if (!depsPromise) {\n // ONE dynamic import of the pre-inlined artifact (see the header note + `mdastDeps.ts`)\n // — the five ESM parser packages AND the shared remark plugins, none of which the\n // sandbox resolver can walk/resolve as bare specifiers on-host.\n depsPromise = import('./mdastDeps').then((m) => {\n const d = m as unknown as Deps;\n return {\n fromMarkdown: d.fromMarkdown,\n mdxJsx: d.mdxJsx,\n mdxJsxFromMarkdown: d.mdxJsxFromMarkdown,\n gfm: d.gfm,\n gfmFromMarkdown: d.gfmFromMarkdown,\n remarkAdmonitions: d.remarkAdmonitions,\n remarkWikiLinks: d.remarkWikiLinks,\n remarkHeadingAnchors: d.remarkHeadingAnchors,\n } as Deps;\n });\n }\n return depsPromise;\n}\n\nexport interface ParseSafeMdastOptions {\n /** `false` ⇒ headings use plain text-slug ids (the R3-186 base; no `sec-…` section\n * ids, no `data-slug`) — the `sectionIds:false` frontmatter opt-out, matching the\n * compiled path. Default (undefined/true) ⇒ section-like headings get `sec-…` ids\n * (R3-211). */\n sectionIds?: boolean;\n}\n\n/**\n * Parse untrusted Markdown/MDX-syntax source to an mdast tree with **no evaluator in\n * the pipeline**: JSX-as-data (no acorn), GFM on, the expression extension OFF, no\n * raw-HTML re-parse. The returned tree is safe to hand to `renderMdast` — expression\n * attributes are inert strings and raw HTML is inert `html` nodes.\n *\n * After the no-acorn parse it runs the SHARED kernel remark plugins — in the SAME order\n * as the compiled path's `compile.ts` (admonitions §12 → wiki-links §13 → heading/section\n * anchors §15/R3-211; GFM is already applied via the micromark extension above) — so the\n * safe subset renders identically in both standards. The plugins only emit element nodes\n * with LITERAL attributes and set `data.hProperties.id` on headings; they add no evaluator\n * and no acorn, preserving the §5.1 fail-safe.\n */\nexport async function parseSafeMdast(\n source: string,\n options: ParseSafeMdastOptions = {},\n): Promise<SafeMdastNode> {\n const {\n fromMarkdown,\n mdxJsx,\n mdxJsxFromMarkdown,\n gfm,\n gfmFromMarkdown,\n remarkAdmonitions,\n remarkWikiLinks,\n remarkHeadingAnchors,\n } = await loadDeps();\n const tree = fromMarkdown(source, {\n // `mdxJsx()` WITHOUT an acorn option → JSX tags + literal attrs; expressions are\n // raw strings, never estree. The mdx *expression* extension is intentionally\n // absent, so `{…}` in body text stays literal. GFM for tables/task-lists.\n extensions: [mdxJsx(), gfm()],\n mdastExtensions: [mdxJsxFromMarkdown(), gfmFromMarkdown()],\n });\n // The SHARED kernel remark plugins, in the SAME order as the compiled path's `compile.ts`\n // (admonitions §12 → wiki-links §13 → heading/section anchors §15/R3-211).\n remarkAdmonitions()(tree);\n remarkWikiLinks()(tree);\n remarkHeadingAnchors({ sectionIds: options.sectionIds !== false })(tree);\n return tree;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA+EA,IAAI,cAAoC;AAExC,SAAS,WAA0B;AACjC,MAAI,CAAC,aAAa;AAIhB,kBAAc,OAAO,aAAa,EAAE,KAAK,CAAC,MAAM;AAC9C,YAAM,IAAI;AACV,aAAO;AAAA,QACL,cAAc,EAAE;AAAA,QAChB,QAAQ,EAAE;AAAA,QACV,oBAAoB,EAAE;AAAA,QACtB,KAAK,EAAE;AAAA,QACP,iBAAiB,EAAE;AAAA,QACnB,mBAAmB,EAAE;AAAA,QACrB,iBAAiB,EAAE;AAAA,QACnB,sBAAsB,EAAE;AAAA,MAC1B;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAuBA,eAAsB,eACpB,QACA,UAAiC,CAAC,GACV;AACxB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,MAAM,SAAS;AACnB,QAAM,OAAO,aAAa,QAAQ;AAAA;AAAA;AAAA;AAAA,IAIhC,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC;AAAA,IAC5B,iBAAiB,CAAC,mBAAmB,GAAG,gBAAgB,CAAC;AAAA,EAC3D,CAAC;AAGD,oBAAkB,EAAE,IAAI;AACxB,kBAAgB,EAAE,IAAI;AACtB,uBAAqB,EAAE,YAAY,QAAQ,eAAe,MAAM,CAAC,EAAE,IAAI;AACvE,SAAO;AACT;","names":[]}
@@ -1,28 +1,34 @@
1
- import {
2
- remarkAdmonitions,
3
- remarkWikiLinks,
4
- remarkHeadingAnchors
5
- } from "@immediately-run/mdx-plugins";
1
+ import "../chunk-VHAA22YE.js";
6
2
  let depsPromise = null;
7
3
  function loadDeps() {
8
4
  if (!depsPromise) {
9
- depsPromise = import("./mdastDeps").then(
10
- (m) => ({
11
- fromMarkdown: m.fromMarkdown,
12
- mdxJsx: m.mdxJsx,
13
- mdxJsxFromMarkdown: m.mdxJsxFromMarkdown,
14
- gfm: m.gfm,
15
- gfmFromMarkdown: m.gfmFromMarkdown
16
- })
17
- );
5
+ depsPromise = import("./mdastDeps").then((m) => {
6
+ const d = m;
7
+ return {
8
+ fromMarkdown: d.fromMarkdown,
9
+ mdxJsx: d.mdxJsx,
10
+ mdxJsxFromMarkdown: d.mdxJsxFromMarkdown,
11
+ gfm: d.gfm,
12
+ gfmFromMarkdown: d.gfmFromMarkdown,
13
+ remarkAdmonitions: d.remarkAdmonitions,
14
+ remarkWikiLinks: d.remarkWikiLinks,
15
+ remarkHeadingAnchors: d.remarkHeadingAnchors
16
+ };
17
+ });
18
18
  }
19
19
  return depsPromise;
20
20
  }
21
- const admonitions = remarkAdmonitions;
22
- const wikiLinks = remarkWikiLinks;
23
- const headingAnchors = remarkHeadingAnchors;
24
21
  async function parseSafeMdast(source, options = {}) {
25
- const { fromMarkdown, mdxJsx, mdxJsxFromMarkdown, gfm, gfmFromMarkdown } = await loadDeps();
22
+ const {
23
+ fromMarkdown,
24
+ mdxJsx,
25
+ mdxJsxFromMarkdown,
26
+ gfm,
27
+ gfmFromMarkdown,
28
+ remarkAdmonitions,
29
+ remarkWikiLinks,
30
+ remarkHeadingAnchors
31
+ } = await loadDeps();
26
32
  const tree = fromMarkdown(source, {
27
33
  // `mdxJsx()` WITHOUT an acorn option → JSX tags + literal attrs; expressions are
28
34
  // raw strings, never estree. The mdx *expression* extension is intentionally
@@ -30,9 +36,9 @@ async function parseSafeMdast(source, options = {}) {
30
36
  extensions: [mdxJsx(), gfm()],
31
37
  mdastExtensions: [mdxJsxFromMarkdown(), gfmFromMarkdown()]
32
38
  });
33
- admonitions()(tree);
34
- wikiLinks()(tree);
35
- headingAnchors({ sectionIds: options.sectionIds !== false })(tree);
39
+ remarkAdmonitions()(tree);
40
+ remarkWikiLinks()(tree);
41
+ remarkHeadingAnchors({ sectionIds: options.sectionIds !== false })(tree);
36
42
  return tree;
37
43
  }
38
44
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/safeContent/parseSafeMdast.ts"],"sourcesContent":["// The no-acorn parse pipeline for the safe content renderer (TRUST_MODES_SPEC §5.1,\n// empirically verified 2026-07-07 against `@mdx-js/mdx` v3 / `micromark-extension-\n// mdx-jsx`). This is the load-bearing half of the fail-safe: `<Component/>` syntax\n// parses to an element node with **literal** attributes, and every expression\n// (`n={1+1}`, `f={fetch(\"/x\")}`, `{...spread}`) is captured as an **inert raw string\n// with no estree** — because we pass **NO acorn option** to `micromark-extension-mdx-\n// jsx`. There is therefore no evaluator anywhere in the pipeline (fail-safe), unlike\n// `@mdx-js/mdx`'s `compile({format:'mdx'})` which always wires acorn.\n//\n// The §5.1 residual guarantees are also here: the expression micromark extension is\n// **not** enabled (body `{…}` stays literal text), and **no `rehype-raw`** / raw-HTML\n// passthrough exists — raw HTML blocks arrive as inert `html` mdast nodes the renderer\n// prints as text, never injected.\n//\n// `micromark`/`mdast` are ESM-only. They are loaded with a memoised dynamic `import()`\n// (the transpiler's `compile.ts` pattern) so this module sits in the package's CJS\n// build too — a CJS consumer that never renders untrusted content never `require()`s\n// an ESM-only package, and one that does gets it via Node's ESM-from-CJS import. The\n// dynamic load changes only *when* the deps resolve, never the produced tree.\n//\n// The dynamic import targets `./mdastDeps` — a SINGLE self-contained artifact that a\n// dedicated build pass (`scripts/build-safecontent-deps.mjs`) inlines the whole ESM tree\n// into (see `mdastDeps.ts` for the WHY). This keeps the `import()` boundary (a consumer\n// that never renders safe content never loads the ~300KB parser) while making the imported\n// target one already-bundled file the immediately.run sandbox resolver can fetch without\n// walking the unified/micromark conditional-exports tree — the R3-213 on-host packaging\n// gap. In jest/ts-jest and the e2e bundle the same `./mdastDeps` resolves to the source\n// re-export module, which pulls the real deps from node_modules; the produced tree is\n// identical either way.\n\nimport {\n remarkAdmonitions,\n remarkWikiLinks,\n remarkHeadingAnchors,\n type HeadingAnchorOptions,\n} from '@immediately-run/mdx-plugins';\n\n// A minimal structural mdast shape — we deliberately avoid a type dependency on the\n// ESM-only `mdast`/`unist` packages (which would break the CJS build's type surface).\nexport interface SafeMdastNode {\n type: string;\n value?: string;\n name?: string | null;\n url?: string;\n alt?: string | null;\n title?: string | null;\n depth?: number;\n ordered?: boolean;\n lang?: string | null;\n children?: SafeMdastNode[];\n attributes?: SafeMdxAttribute[];\n [key: string]: unknown;\n}\n\nexport interface SafeMdxAttribute {\n type: 'mdxJsxAttribute' | 'mdxJsxExpressionAttribute';\n name?: string;\n // A literal attribute carries a string; an expression attribute carries an\n // `mdxJsxAttributeValueExpression` object (a raw string, NO estree) or a string.\n value?: string | { type: string; value?: string } | null;\n}\n\ntype Deps = {\n fromMarkdown: (\n value: string,\n options: { extensions: unknown[]; mdastExtensions: unknown[] },\n ) => SafeMdastNode;\n mdxJsx: () => unknown;\n mdxJsxFromMarkdown: () => unknown;\n gfm: () => unknown;\n gfmFromMarkdown: () => unknown;\n};\n\nlet depsPromise: Promise<Deps> | null = null;\n\nfunction loadDeps(): Promise<Deps> {\n if (!depsPromise) {\n // ONE dynamic import of the pre-inlined artifact (see the header note + `mdastDeps.ts`)\n // instead of five bare ESM specifiers the sandbox resolver can't walk on-host.\n depsPromise = import('./mdastDeps').then(\n (m) =>\n ({\n fromMarkdown: (m as unknown as { fromMarkdown: Deps['fromMarkdown'] }).fromMarkdown,\n mdxJsx: (m as unknown as { mdxJsx: Deps['mdxJsx'] }).mdxJsx,\n mdxJsxFromMarkdown: (m as unknown as { mdxJsxFromMarkdown: Deps['mdxJsxFromMarkdown'] })\n .mdxJsxFromMarkdown,\n gfm: (m as unknown as { gfm: Deps['gfm'] }).gfm,\n gfmFromMarkdown: (m as unknown as { gfmFromMarkdown: Deps['gfmFromMarkdown'] }).gfmFromMarkdown,\n }) as Deps,\n );\n }\n return depsPromise;\n}\n\nexport interface ParseSafeMdastOptions {\n /** `false` ⇒ headings use plain text-slug ids (the R3-186 base; no `sec-…` section\n * ids, no `data-slug`) — the `sectionIds:false` frontmatter opt-out, matching the\n * compiled path. Default (undefined/true) ⇒ section-like headings get `sec-…` ids\n * (R3-211). */\n sectionIds?: boolean;\n}\n\n// The three kernel remark plugins for the MDX *safe subset* — the SAME source the\n// compiled path (transpiler `compileMdx`) runs, imported from the shared package so the\n// two render standards can't drift (TRUST_MODES_SPEC §5 / §5.1, R3-213). They are pure\n// mdast transforms: `(options?) => (tree) => void`. `unified`'s `Plugin` type widens the\n// return to `Transformer | void`; here we invoke the transformer directly on the tree,\n// so narrow it to a plain in-place mutator.\ntype MdastMutator = (tree: SafeMdastNode) => void;\nconst admonitions = remarkAdmonitions as unknown as () => MdastMutator;\nconst wikiLinks = remarkWikiLinks as unknown as () => MdastMutator;\nconst headingAnchors = remarkHeadingAnchors as unknown as (o?: HeadingAnchorOptions) => MdastMutator;\n\n/**\n * Parse untrusted Markdown/MDX-syntax source to an mdast tree with **no evaluator in\n * the pipeline**: JSX-as-data (no acorn), GFM on, the expression extension OFF, no\n * raw-HTML re-parse. The returned tree is safe to hand to `renderMdast` — expression\n * attributes are inert strings and raw HTML is inert `html` nodes.\n *\n * After the no-acorn parse it runs the SHARED kernel remark plugins — in the SAME order\n * as the compiled path's `compile.ts` (admonitions §12 → wiki-links §13 → heading/section\n * anchors §15/R3-211; GFM is already applied via the micromark extension above) — so the\n * safe subset renders identically in both standards. The plugins only emit element nodes\n * with LITERAL attributes and set `data.hProperties.id` on headings; they add no evaluator\n * and no acorn, preserving the §5.1 fail-safe.\n */\nexport async function parseSafeMdast(\n source: string,\n options: ParseSafeMdastOptions = {},\n): Promise<SafeMdastNode> {\n const { fromMarkdown, mdxJsx, mdxJsxFromMarkdown, gfm, gfmFromMarkdown } = await loadDeps();\n const tree = fromMarkdown(source, {\n // `mdxJsx()` WITHOUT an acorn option → JSX tags + literal attrs; expressions are\n // raw strings, never estree. The mdx *expression* extension is intentionally\n // absent, so `{…}` in body text stays literal. GFM for tables/task-lists.\n extensions: [mdxJsx(), gfm()],\n mdastExtensions: [mdxJsxFromMarkdown(), gfmFromMarkdown()],\n });\n admonitions()(tree);\n wikiLinks()(tree);\n headingAnchors({ sectionIds: options.sectionIds !== false })(tree);\n return tree;\n}\n"],"mappings":"AA8BA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAsCP,IAAI,cAAoC;AAExC,SAAS,WAA0B;AACjC,MAAI,CAAC,aAAa;AAGhB,kBAAc,OAAO,aAAa,EAAE;AAAA,MAClC,CAAC,OACE;AAAA,QACC,cAAe,EAAwD;AAAA,QACvE,QAAS,EAA4C;AAAA,QACrD,oBAAqB,EAClB;AAAA,QACH,KAAM,EAAsC;AAAA,QAC5C,iBAAkB,EAA8D;AAAA,MAClF;AAAA,IACJ;AAAA,EACF;AACA,SAAO;AACT;AAiBA,MAAM,cAAc;AACpB,MAAM,YAAY;AAClB,MAAM,iBAAiB;AAevB,eAAsB,eACpB,QACA,UAAiC,CAAC,GACV;AACxB,QAAM,EAAE,cAAc,QAAQ,oBAAoB,KAAK,gBAAgB,IAAI,MAAM,SAAS;AAC1F,QAAM,OAAO,aAAa,QAAQ;AAAA;AAAA;AAAA;AAAA,IAIhC,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC;AAAA,IAC5B,iBAAiB,CAAC,mBAAmB,GAAG,gBAAgB,CAAC;AAAA,EAC3D,CAAC;AACD,cAAY,EAAE,IAAI;AAClB,YAAU,EAAE,IAAI;AAChB,iBAAe,EAAE,YAAY,QAAQ,eAAe,MAAM,CAAC,EAAE,IAAI;AACjE,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../src/safeContent/parseSafeMdast.ts"],"sourcesContent":["// The no-acorn parse pipeline for the safe content renderer (TRUST_MODES_SPEC §5.1,\n// empirically verified 2026-07-07 against `@mdx-js/mdx` v3 / `micromark-extension-\n// mdx-jsx`). This is the load-bearing half of the fail-safe: `<Component/>` syntax\n// parses to an element node with **literal** attributes, and every expression\n// (`n={1+1}`, `f={fetch(\"/x\")}`, `{...spread}`) is captured as an **inert raw string\n// with no estree** — because we pass **NO acorn option** to `micromark-extension-mdx-\n// jsx`. There is therefore no evaluator anywhere in the pipeline (fail-safe), unlike\n// `@mdx-js/mdx`'s `compile({format:'mdx'})` which always wires acorn.\n//\n// The §5.1 residual guarantees are also here: the expression micromark extension is\n// **not** enabled (body `{…}` stays literal text), and **no `rehype-raw`** / raw-HTML\n// passthrough exists — raw HTML blocks arrive as inert `html` mdast nodes the renderer\n// prints as text, never injected.\n//\n// `micromark`/`mdast` are ESM-only. They are loaded with a memoised dynamic `import()`\n// (the transpiler's `compile.ts` pattern) so this module sits in the package's CJS\n// build too — a CJS consumer that never renders untrusted content never `require()`s\n// an ESM-only package, and one that does gets it via Node's ESM-from-CJS import. The\n// dynamic load changes only *when* the deps resolve, never the produced tree.\n//\n// The dynamic import targets `./mdastDeps` — a SINGLE self-contained artifact that a\n// dedicated build pass (`scripts/build-safecontent-deps.mjs`) inlines the whole ESM tree\n// into (see `mdastDeps.ts` for the WHY). This keeps the `import()` boundary (a consumer\n// that never renders safe content never loads the ~300KB parser) while making the imported\n// target one already-bundled file the immediately.run sandbox resolver can fetch without\n// walking the unified/micromark conditional-exports tree — the R3-213 on-host packaging\n// gap. In jest/ts-jest and the e2e bundle the same `./mdastDeps` resolves to the source\n// re-export module, which pulls the real deps from node_modules; the produced tree is\n// identical either way.\n\n// Type-only — the plugin VALUES are re-exported from (and inlined by) `./mdastDeps`; a\n// value import here would put a bare `@immediately-run/mdx-plugins` specifier in the dist\n// the sandbox resolver can't resolve on-host. `import type` is fully erased at build.\nimport type { HeadingAnchorOptions } from '@immediately-run/mdx-plugins';\n\n// A minimal structural mdast shape — we deliberately avoid a type dependency on the\n// ESM-only `mdast`/`unist` packages (which would break the CJS build's type surface).\nexport interface SafeMdastNode {\n type: string;\n value?: string;\n name?: string | null;\n url?: string;\n alt?: string | null;\n title?: string | null;\n depth?: number;\n ordered?: boolean;\n lang?: string | null;\n children?: SafeMdastNode[];\n attributes?: SafeMdxAttribute[];\n [key: string]: unknown;\n}\n\nexport interface SafeMdxAttribute {\n type: 'mdxJsxAttribute' | 'mdxJsxExpressionAttribute';\n name?: string;\n // A literal attribute carries a string; an expression attribute carries an\n // `mdxJsxAttributeValueExpression` object (a raw string, NO estree) or a string.\n value?: string | { type: string; value?: string } | null;\n}\n\n// `unified`'s `Plugin` type widens the return to `Transformer | void`; the safe path\n// invokes each transformer directly on the tree, so narrow it to a plain in-place mutator.\ntype MdastMutator = (tree: SafeMdastNode) => void;\n\ntype Deps = {\n fromMarkdown: (\n value: string,\n options: { extensions: unknown[]; mdastExtensions: unknown[] },\n ) => SafeMdastNode;\n mdxJsx: () => unknown;\n mdxJsxFromMarkdown: () => unknown;\n gfm: () => unknown;\n gfmFromMarkdown: () => unknown;\n // The three shared kernel remark plugins, also inlined into `./mdastDeps` (see there).\n remarkAdmonitions: () => MdastMutator;\n remarkWikiLinks: () => MdastMutator;\n remarkHeadingAnchors: (o?: HeadingAnchorOptions) => MdastMutator;\n};\n\nlet depsPromise: Promise<Deps> | null = null;\n\nfunction loadDeps(): Promise<Deps> {\n if (!depsPromise) {\n // ONE dynamic import of the pre-inlined artifact (see the header note + `mdastDeps.ts`)\n // — the five ESM parser packages AND the shared remark plugins, none of which the\n // sandbox resolver can walk/resolve as bare specifiers on-host.\n depsPromise = import('./mdastDeps').then((m) => {\n const d = m as unknown as Deps;\n return {\n fromMarkdown: d.fromMarkdown,\n mdxJsx: d.mdxJsx,\n mdxJsxFromMarkdown: d.mdxJsxFromMarkdown,\n gfm: d.gfm,\n gfmFromMarkdown: d.gfmFromMarkdown,\n remarkAdmonitions: d.remarkAdmonitions,\n remarkWikiLinks: d.remarkWikiLinks,\n remarkHeadingAnchors: d.remarkHeadingAnchors,\n } as Deps;\n });\n }\n return depsPromise;\n}\n\nexport interface ParseSafeMdastOptions {\n /** `false` ⇒ headings use plain text-slug ids (the R3-186 base; no `sec-…` section\n * ids, no `data-slug`) — the `sectionIds:false` frontmatter opt-out, matching the\n * compiled path. Default (undefined/true) ⇒ section-like headings get `sec-…` ids\n * (R3-211). */\n sectionIds?: boolean;\n}\n\n/**\n * Parse untrusted Markdown/MDX-syntax source to an mdast tree with **no evaluator in\n * the pipeline**: JSX-as-data (no acorn), GFM on, the expression extension OFF, no\n * raw-HTML re-parse. The returned tree is safe to hand to `renderMdast` — expression\n * attributes are inert strings and raw HTML is inert `html` nodes.\n *\n * After the no-acorn parse it runs the SHARED kernel remark plugins — in the SAME order\n * as the compiled path's `compile.ts` (admonitions §12 → wiki-links §13 → heading/section\n * anchors §15/R3-211; GFM is already applied via the micromark extension above) — so the\n * safe subset renders identically in both standards. The plugins only emit element nodes\n * with LITERAL attributes and set `data.hProperties.id` on headings; they add no evaluator\n * and no acorn, preserving the §5.1 fail-safe.\n */\nexport async function parseSafeMdast(\n source: string,\n options: ParseSafeMdastOptions = {},\n): Promise<SafeMdastNode> {\n const {\n fromMarkdown,\n mdxJsx,\n mdxJsxFromMarkdown,\n gfm,\n gfmFromMarkdown,\n remarkAdmonitions,\n remarkWikiLinks,\n remarkHeadingAnchors,\n } = await loadDeps();\n const tree = fromMarkdown(source, {\n // `mdxJsx()` WITHOUT an acorn option → JSX tags + literal attrs; expressions are\n // raw strings, never estree. The mdx *expression* extension is intentionally\n // absent, so `{…}` in body text stays literal. GFM for tables/task-lists.\n extensions: [mdxJsx(), gfm()],\n mdastExtensions: [mdxJsxFromMarkdown(), gfmFromMarkdown()],\n });\n // The SHARED kernel remark plugins, in the SAME order as the compiled path's `compile.ts`\n // (admonitions §12 → wiki-links §13 → heading/section anchors §15/R3-211).\n remarkAdmonitions()(tree);\n remarkWikiLinks()(tree);\n remarkHeadingAnchors({ sectionIds: options.sectionIds !== false })(tree);\n return tree;\n}\n"],"mappings":";AA+EA,IAAI,cAAoC;AAExC,SAAS,WAA0B;AACjC,MAAI,CAAC,aAAa;AAIhB,kBAAc,OAAO,aAAa,EAAE,KAAK,CAAC,MAAM;AAC9C,YAAM,IAAI;AACV,aAAO;AAAA,QACL,cAAc,EAAE;AAAA,QAChB,QAAQ,EAAE;AAAA,QACV,oBAAoB,EAAE;AAAA,QACtB,KAAK,EAAE;AAAA,QACP,iBAAiB,EAAE;AAAA,QACnB,mBAAmB,EAAE;AAAA,QACrB,iBAAiB,EAAE;AAAA,QACnB,sBAAsB,EAAE;AAAA,MAC1B;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAuBA,eAAsB,eACpB,QACA,UAAiC,CAAC,GACV;AACxB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,MAAM,SAAS;AACnB,QAAM,OAAO,aAAa,QAAQ;AAAA;AAAA;AAAA;AAAA,IAIhC,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC;AAAA,IAC5B,iBAAiB,CAAC,mBAAmB,GAAG,gBAAgB,CAAC;AAAA,EAC3D,CAAC;AAGD,oBAAkB,EAAE,IAAI;AACxB,kBAAgB,EAAE,IAAI;AACtB,uBAAqB,EAAE,YAAY,QAAQ,eAAe,MAAM,CAAC,EAAE,IAAI;AACvE,SAAO;AACT;","names":[]}
@@ -1,3 +1,4 @@
1
+ import "../chunk-VHAA22YE.js";
1
2
  import { createElement, Fragment } from "react";
2
3
  import { sanitizeUrl } from "./sanitizeUrl";
3
4
  import { splitWikiLinks } from "./wikilink";