@burdenoff/website-sdk 2026.720.6 → 2026.720.8

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,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
+ import { Components } from 'react-markdown';
3
4
 
4
5
  interface ContentPageData {
5
6
  id: string;
@@ -79,8 +80,9 @@ declare function useContentPages(options?: {
79
80
  /**
80
81
  * Content renderer component.
81
82
  *
82
- * - `markdown` (default): converts to HTML via {@link renderMarkdown}
83
- * - `html`: rendered as-is (assumed already sanitized upstream)
83
+ * - `markdown` (default): renders with the shared {@link Markdown} component
84
+ * (react-markdown + remark-gfm + rehype-sanitize).
85
+ * - `html`: sanitized with DOMPurify before rendering.
84
86
  * - anything else: plain-text fallback
85
87
  *
86
88
  * @example
@@ -94,6 +96,26 @@ declare function ContentRenderer({ content, format, className, }: {
94
96
  className?: string;
95
97
  }): react_jsx_runtime.JSX.Element;
96
98
 
99
+ interface MarkdownProps {
100
+ /** Markdown source to render. */
101
+ children: string;
102
+ /** Additional classes for the wrapper element. */
103
+ className?: string;
104
+ /** Render without a wrapping block element, suitable for inline content. */
105
+ inline?: boolean;
106
+ /** Optional react-markdown component overrides. */
107
+ components?: Components;
108
+ }
109
+ /**
110
+ * Shared markdown renderer for website content.
111
+ *
112
+ * - Uses `react-markdown` for standards-compliant parsing.
113
+ * - Enables GitHub Flavored Markdown (tables, task lists, strikethrough, autolinks).
114
+ * - Sanitizes HTML via `rehype-sanitize` so raw markup in markdown is stripped.
115
+ * - External links open in a new tab with safe rel attributes.
116
+ */
117
+ declare function Markdown({ children, className, inline, components, }: MarkdownProps): ReactNode;
118
+
97
119
  interface BlogListPageProps {
98
120
  productName?: string;
99
121
  heroTitle?: string;
@@ -262,4 +284,4 @@ interface ContractsPageProps {
262
284
  }
263
285
  declare function ContractsPage(props: ContractsPageProps): react_jsx_runtime.JSX.Element;
264
286
 
265
- export { BlogListPage, type BlogListPageProps, BlogPostPage, type BlogPostPageProps, CaseStudiesListPage, type CaseStudiesListPageProps, CaseStudyPage, type CaseStudyPageProps, type ChangelogEntry, ChangelogPage, type ChangelogPageProps, type ContentPageData, type ContentPageListData, type ContentPageListItem, ContentRenderer, type ContractAsset, ContractsPage, type ContractsPageProps, type PressKitAsset, type PressKitAssetCategory, PressKitPage, type PressKitPageProps, type UseContentPageOptions, useContentPage, useContentPages };
287
+ export { BlogListPage, type BlogListPageProps, BlogPostPage, type BlogPostPageProps, CaseStudiesListPage, type CaseStudiesListPageProps, CaseStudyPage, type CaseStudyPageProps, type ChangelogEntry, ChangelogPage, type ChangelogPageProps, type ContentPageData, type ContentPageListData, type ContentPageListItem, ContentRenderer, type ContractAsset, ContractsPage, type ContractsPageProps, Markdown, type MarkdownProps, type PressKitAsset, type PressKitAssetCategory, PressKitPage, type PressKitPageProps, type UseContentPageOptions, useContentPage, useContentPages };
@@ -1,5 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
+ import { Components } from 'react-markdown';
3
4
 
4
5
  interface ContentPageData {
5
6
  id: string;
@@ -79,8 +80,9 @@ declare function useContentPages(options?: {
79
80
  /**
80
81
  * Content renderer component.
81
82
  *
82
- * - `markdown` (default): converts to HTML via {@link renderMarkdown}
83
- * - `html`: rendered as-is (assumed already sanitized upstream)
83
+ * - `markdown` (default): renders with the shared {@link Markdown} component
84
+ * (react-markdown + remark-gfm + rehype-sanitize).
85
+ * - `html`: sanitized with DOMPurify before rendering.
84
86
  * - anything else: plain-text fallback
85
87
  *
86
88
  * @example
@@ -94,6 +96,26 @@ declare function ContentRenderer({ content, format, className, }: {
94
96
  className?: string;
95
97
  }): react_jsx_runtime.JSX.Element;
96
98
 
99
+ interface MarkdownProps {
100
+ /** Markdown source to render. */
101
+ children: string;
102
+ /** Additional classes for the wrapper element. */
103
+ className?: string;
104
+ /** Render without a wrapping block element, suitable for inline content. */
105
+ inline?: boolean;
106
+ /** Optional react-markdown component overrides. */
107
+ components?: Components;
108
+ }
109
+ /**
110
+ * Shared markdown renderer for website content.
111
+ *
112
+ * - Uses `react-markdown` for standards-compliant parsing.
113
+ * - Enables GitHub Flavored Markdown (tables, task lists, strikethrough, autolinks).
114
+ * - Sanitizes HTML via `rehype-sanitize` so raw markup in markdown is stripped.
115
+ * - External links open in a new tab with safe rel attributes.
116
+ */
117
+ declare function Markdown({ children, className, inline, components, }: MarkdownProps): ReactNode;
118
+
97
119
  interface BlogListPageProps {
98
120
  productName?: string;
99
121
  heroTitle?: string;
@@ -262,4 +284,4 @@ interface ContractsPageProps {
262
284
  }
263
285
  declare function ContractsPage(props: ContractsPageProps): react_jsx_runtime.JSX.Element;
264
286
 
265
- export { BlogListPage, type BlogListPageProps, BlogPostPage, type BlogPostPageProps, CaseStudiesListPage, type CaseStudiesListPageProps, CaseStudyPage, type CaseStudyPageProps, type ChangelogEntry, ChangelogPage, type ChangelogPageProps, type ContentPageData, type ContentPageListData, type ContentPageListItem, ContentRenderer, type ContractAsset, ContractsPage, type ContractsPageProps, type PressKitAsset, type PressKitAssetCategory, PressKitPage, type PressKitPageProps, type UseContentPageOptions, useContentPage, useContentPages };
287
+ export { BlogListPage, type BlogListPageProps, BlogPostPage, type BlogPostPageProps, CaseStudiesListPage, type CaseStudiesListPageProps, CaseStudyPage, type CaseStudyPageProps, type ChangelogEntry, ChangelogPage, type ChangelogPageProps, type ContentPageData, type ContentPageListData, type ContentPageListItem, ContentRenderer, type ContractAsset, ContractsPage, type ContractsPageProps, Markdown, type MarkdownProps, type PressKitAsset, type PressKitAssetCategory, PressKitPage, type PressKitPageProps, type UseContentPageOptions, useContentPage, useContentPages };
@@ -1,6 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  var React = require('react');
4
+ var DOMPurify = require('isomorphic-dompurify');
5
+ var ReactMarkdown = require('react-markdown');
6
+ var rehypeSanitize = require('rehype-sanitize');
7
+ var remarkGfm = require('remark-gfm');
4
8
  var jsxRuntime = require('react/jsx-runtime');
5
9
  var reactHelmetAsync = require('react-helmet-async');
6
10
  var lucideReact = require('lucide-react');
@@ -9,6 +13,8 @@ var classVarianceAuthority = require('class-variance-authority');
9
13
  var clsx = require('clsx');
10
14
  var tailwindMerge = require('tailwind-merge');
11
15
 
16
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
17
+
12
18
  function _interopNamespace(e) {
13
19
  if (e && e.__esModule) return e;
14
20
  var n = Object.create(null);
@@ -28,10 +34,49 @@ function _interopNamespace(e) {
28
34
  }
29
35
 
30
36
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
37
+ var DOMPurify__default = /*#__PURE__*/_interopDefault(DOMPurify);
38
+ var ReactMarkdown__default = /*#__PURE__*/_interopDefault(ReactMarkdown);
39
+ var rehypeSanitize__default = /*#__PURE__*/_interopDefault(rehypeSanitize);
40
+ var remarkGfm__default = /*#__PURE__*/_interopDefault(remarkGfm);
31
41
 
32
42
  var __defProp = Object.defineProperty;
33
43
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
34
44
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
45
+ var defaultComponents = {
46
+ a: ({ href, children, ...props }) => {
47
+ const isExternal = typeof href === "string" && (href.startsWith("http://") || href.startsWith("https://"));
48
+ return /* @__PURE__ */ jsxRuntime.jsx(
49
+ "a",
50
+ {
51
+ href,
52
+ ...props,
53
+ ...isExternal ? { target: "_blank", rel: "noopener noreferrer" } : { rel: "noopener noreferrer" },
54
+ children
55
+ }
56
+ );
57
+ }
58
+ };
59
+ function Markdown({
60
+ children,
61
+ className,
62
+ inline,
63
+ components
64
+ }) {
65
+ const content = /* @__PURE__ */ jsxRuntime.jsx(
66
+ ReactMarkdown__default.default,
67
+ {
68
+ remarkPlugins: [remarkGfm__default.default],
69
+ rehypePlugins: [rehypeSanitize__default.default],
70
+ components: { ...defaultComponents, ...components },
71
+ ...inline ? { disallowedElements: ["p"], unwrapDisallowed: true } : {},
72
+ children
73
+ }
74
+ );
75
+ if (inline) {
76
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className, children: content });
77
+ }
78
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: content });
79
+ }
35
80
 
36
81
  // src/client/security.ts
37
82
  var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "::1"]);
@@ -384,64 +429,21 @@ function useContentPages(options) {
384
429
  }, [fetchPages]);
385
430
  return { data, loading, error, refetch: fetchPages };
386
431
  }
387
- function renderMarkdown(md) {
388
- let html = md;
389
- html = html.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
390
- html = html.replace(/```(\w*)\n([\s\S]*?)```/g, (_m, _lang, code) => {
391
- return `<pre><code>${code.trim()}</code></pre>`;
392
- });
393
- html = html.replace(/`([^`]+)`/g, "<code>$1</code>");
394
- html = html.replace(/^###### (.+)$/gm, "<h6>$1</h6>");
395
- html = html.replace(/^##### (.+)$/gm, "<h5>$1</h5>");
396
- html = html.replace(/^#### (.+)$/gm, "<h4>$1</h4>");
397
- html = html.replace(/^### (.+)$/gm, "<h3>$1</h3>");
398
- html = html.replace(/^## (.+)$/gm, "<h2>$1</h2>");
399
- html = html.replace(/^# (.+)$/gm, "<h1>$1</h1>");
400
- html = html.replace(/\*\*\*(.+?)\*\*\*/g, "<strong><em>$1</em></strong>");
401
- html = html.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>");
402
- html = html.replace(/\*(.+?)\*/g, "<em>$1</em>");
403
- html = html.replace(
404
- /\[([^\]]+)\]\(([^)]+)\)/g,
405
- '<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'
406
- );
407
- html = html.replace(/^&gt; (.+)$/gm, "<blockquote>$1</blockquote>");
408
- html = html.replace(/(^- .+$(\n^- .+$)*)/gm, (block) => {
409
- const items = block.split("\n").map((line) => `<li>${line.replace(/^- /, "")}</li>`).join("");
410
- return `<ul>${items}</ul>`;
411
- });
412
- html = html.replace(/(^\d+\. .+$(\n^\d+\. .+$)*)/gm, (block) => {
413
- const items = block.split("\n").map((line) => `<li>${line.replace(/^\d+\. /, "")}</li>`).join("");
414
- return `<ol>${items}</ol>`;
415
- });
416
- html = html.replace(/^---$/gm, "<hr />");
417
- html = html.split(/\n\n+/).map((block) => {
418
- const trimmed = block.trim();
419
- if (!trimmed) return "";
420
- if (/^<(h[1-6]|ul|ol|pre|blockquote|hr)/.test(trimmed)) return trimmed;
421
- return `<p>${trimmed.replace(/\n/g, "<br />")}</p>`;
422
- }).join("\n");
423
- return html;
424
- }
425
432
  function ContentRenderer({
426
433
  content,
427
434
  format = "markdown",
428
435
  className
429
436
  }) {
430
437
  if (format === "markdown") {
431
- return /* @__PURE__ */ jsxRuntime.jsx(
432
- "div",
433
- {
434
- className,
435
- dangerouslySetInnerHTML: { __html: renderMarkdown(content) }
436
- }
437
- );
438
+ return /* @__PURE__ */ jsxRuntime.jsx(Markdown, { className, children: content });
438
439
  }
439
440
  if (format === "html") {
441
+ const sanitized = DOMPurify__default.default.sanitize(content);
440
442
  return /* @__PURE__ */ jsxRuntime.jsx(
441
443
  "div",
442
444
  {
443
445
  className,
444
- dangerouslySetInnerHTML: { __html: content }
446
+ dangerouslySetInnerHTML: { __html: sanitized }
445
447
  }
446
448
  );
447
449
  }
@@ -2891,6 +2893,7 @@ exports.CaseStudyPage = CaseStudyPage;
2891
2893
  exports.ChangelogPage = ChangelogPage;
2892
2894
  exports.ContentRenderer = ContentRenderer;
2893
2895
  exports.ContractsPage = ContractsPage;
2896
+ exports.Markdown = Markdown;
2894
2897
  exports.PressKitPage = PressKitPage;
2895
2898
  exports.useContentPage = useContentPage;
2896
2899
  exports.useContentPages = useContentPages;