@burdenoff/website-sdk 2026.720.6 → 2026.720.7

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,5 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import { createContext, useState, useCallback, useEffect, useMemo, useContext } from 'react';
3
+ import DOMPurify from 'isomorphic-dompurify';
4
+ import ReactMarkdown from 'react-markdown';
5
+ import rehypeSanitize from 'rehype-sanitize';
6
+ import remarkGfm from 'remark-gfm';
3
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
8
  import { Helmet } from 'react-helmet-async';
5
9
  import { History, Search, ChevronLeft, ChevronRight } from 'lucide-react';
@@ -11,6 +15,41 @@ import { twMerge } from 'tailwind-merge';
11
15
  var __defProp = Object.defineProperty;
12
16
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
17
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
18
+ var defaultComponents = {
19
+ a: ({ href, children, ...props }) => {
20
+ const isExternal = typeof href === "string" && (href.startsWith("http://") || href.startsWith("https://"));
21
+ return /* @__PURE__ */ jsx(
22
+ "a",
23
+ {
24
+ href,
25
+ ...props,
26
+ ...isExternal ? { target: "_blank", rel: "noopener noreferrer" } : { rel: "noopener noreferrer" },
27
+ children
28
+ }
29
+ );
30
+ }
31
+ };
32
+ function Markdown({
33
+ children,
34
+ className,
35
+ inline,
36
+ components
37
+ }) {
38
+ const content = /* @__PURE__ */ jsx(
39
+ ReactMarkdown,
40
+ {
41
+ remarkPlugins: [remarkGfm],
42
+ rehypePlugins: [rehypeSanitize],
43
+ components: { ...defaultComponents, ...components },
44
+ ...inline ? { disallowedElements: ["p"], unwrapDisallowed: true } : {},
45
+ children
46
+ }
47
+ );
48
+ if (inline) {
49
+ return /* @__PURE__ */ jsx("span", { className, children: content });
50
+ }
51
+ return /* @__PURE__ */ jsx("div", { className, children: content });
52
+ }
14
53
 
15
54
  // src/client/security.ts
16
55
  var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "::1"]);
@@ -363,64 +402,21 @@ function useContentPages(options) {
363
402
  }, [fetchPages]);
364
403
  return { data, loading, error, refetch: fetchPages };
365
404
  }
366
- function renderMarkdown(md) {
367
- let html = md;
368
- html = html.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
369
- html = html.replace(/```(\w*)\n([\s\S]*?)```/g, (_m, _lang, code) => {
370
- return `<pre><code>${code.trim()}</code></pre>`;
371
- });
372
- html = html.replace(/`([^`]+)`/g, "<code>$1</code>");
373
- html = html.replace(/^###### (.+)$/gm, "<h6>$1</h6>");
374
- html = html.replace(/^##### (.+)$/gm, "<h5>$1</h5>");
375
- html = html.replace(/^#### (.+)$/gm, "<h4>$1</h4>");
376
- html = html.replace(/^### (.+)$/gm, "<h3>$1</h3>");
377
- html = html.replace(/^## (.+)$/gm, "<h2>$1</h2>");
378
- html = html.replace(/^# (.+)$/gm, "<h1>$1</h1>");
379
- html = html.replace(/\*\*\*(.+?)\*\*\*/g, "<strong><em>$1</em></strong>");
380
- html = html.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>");
381
- html = html.replace(/\*(.+?)\*/g, "<em>$1</em>");
382
- html = html.replace(
383
- /\[([^\]]+)\]\(([^)]+)\)/g,
384
- '<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'
385
- );
386
- html = html.replace(/^&gt; (.+)$/gm, "<blockquote>$1</blockquote>");
387
- html = html.replace(/(^- .+$(\n^- .+$)*)/gm, (block) => {
388
- const items = block.split("\n").map((line) => `<li>${line.replace(/^- /, "")}</li>`).join("");
389
- return `<ul>${items}</ul>`;
390
- });
391
- html = html.replace(/(^\d+\. .+$(\n^\d+\. .+$)*)/gm, (block) => {
392
- const items = block.split("\n").map((line) => `<li>${line.replace(/^\d+\. /, "")}</li>`).join("");
393
- return `<ol>${items}</ol>`;
394
- });
395
- html = html.replace(/^---$/gm, "<hr />");
396
- html = html.split(/\n\n+/).map((block) => {
397
- const trimmed = block.trim();
398
- if (!trimmed) return "";
399
- if (/^<(h[1-6]|ul|ol|pre|blockquote|hr)/.test(trimmed)) return trimmed;
400
- return `<p>${trimmed.replace(/\n/g, "<br />")}</p>`;
401
- }).join("\n");
402
- return html;
403
- }
404
405
  function ContentRenderer({
405
406
  content,
406
407
  format = "markdown",
407
408
  className
408
409
  }) {
409
410
  if (format === "markdown") {
410
- return /* @__PURE__ */ jsx(
411
- "div",
412
- {
413
- className,
414
- dangerouslySetInnerHTML: { __html: renderMarkdown(content) }
415
- }
416
- );
411
+ return /* @__PURE__ */ jsx(Markdown, { className, children: content });
417
412
  }
418
413
  if (format === "html") {
414
+ const sanitized = DOMPurify.sanitize(content);
419
415
  return /* @__PURE__ */ jsx(
420
416
  "div",
421
417
  {
422
418
  className,
423
- dangerouslySetInnerHTML: { __html: content }
419
+ dangerouslySetInnerHTML: { __html: sanitized }
424
420
  }
425
421
  );
426
422
  }
@@ -2863,6 +2859,6 @@ function ContractsPage(props) {
2863
2859
  ] });
2864
2860
  }
2865
2861
 
2866
- export { BlogListPage, BlogPostPage, CaseStudiesListPage, CaseStudyPage, ChangelogPage, ContentRenderer, ContractsPage, PressKitPage, useContentPage, useContentPages };
2862
+ export { BlogListPage, BlogPostPage, CaseStudiesListPage, CaseStudyPage, ChangelogPage, ContentRenderer, ContractsPage, Markdown, PressKitPage, useContentPage, useContentPages };
2867
2863
  //# sourceMappingURL=index.mjs.map
2868
2864
  //# sourceMappingURL=index.mjs.map